下面所分析的 openssl
源码的版本是 tag: OpenSSL_1_1_1d
。
在调试 openssl
的加解密引擎时,每次修改完相关代码后,都要重新编译和安装,但安装这一步比较费时。经过一番调研后,发现可以在测试时指定引擎的加载目录,不需要安装引擎相关的动态库。
在 openssl
实现中,"dynamic"
引擎是一个特殊的引擎,在测试时,openssl
会先加载 "dynamic"
引擎,然后由该引擎加载用户使用到的其他引擎。"dynamic"
引擎通过 dlopen()
加载动态库的形式来加载其他引擎,因此,在调用 dlopen()
之前,"dynamic"
引擎需要知道其他引擎的加载目录。
阅读源码可知,在 crypto/engine/eng_dyn.c
文件中 struct st_dynamic_data_ctx
结构体的 dirs
成员存放了 "dynamic"
引擎在加载其他引擎时所用到的查找目录,如下所示:
struct st_dynamic_data_ctx {/* The DSO object we load that supplies the ENGINE code */DSO *dynamic_dso;.../** Whether to never use 'dirs', use 'dirs' as a fallback, or only use* 'dirs' for loading. Default is to use 'dirs' as a fallback.*/int dir_load;/* A stack of directories from which ENGINEs could be loaded */STACK_OF(OPENSSL_STRING) *dirs;
}
同时,在 crypto/engine/eng_dyn.c
文件中指定了 "dynamic"
引擎所支持的命令,如下所示:
static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
...{DYNAMIC_CMD_DIR_ADD,"DIR_ADD", "Adds a directory from which ENGINEs can be loaded",ENGINE_CMD_FLAG_STRING},
...
};
其中,"DIR_ADD"
命令用来指定其他引擎的加载目录。
在 crypto/engine/eng_list.c
文件的 ENGINE_by_id()
中使用了 "DIR_ADD"
命令,为 "dynamic"
引擎添加了其他引擎的加载目录,如下所示:
ENGINE *ENGINE_by_id(const char *id)
{
...if (strcmp(id, "dynamic")) {if ((load_dir = ossl_safe_getenv("OPENSSL_ENGINES")) == NULL)load_dir = ENGINESDIR;iterator = ENGINE_by_id("dynamic");if (!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||!ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||!ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",load_dir, 0) ||!ENGINE_ctrl_cmd_string(iterator, "LIST_ADD", "1", 0) ||!ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))goto notfound;return iterator;}
...
}
从上面可以看到,load_dir
变量指定了"dynamic"
引擎所用到的查找目录,它的取值有两种情况,首先读取环境变量 OPENSSL_ENGINES
,如果读取成功,就使用该环境变量的值,如果没有读取成功,则使用的是 Makefile 中指定的引擎加载目录:ENGINESDIR
,如下所示:
# Do not edit these manually. Use Configure with --prefix or --openssldir
# to change this! Short explanation in the top comment in Configure
INSTALLTOP=/usr/local
OPENSSLDIR=/usr/local/ssl
LIBDIR=lib
# $(libdir) is chosen to be compatible with the GNU coding standards
libdir=$(INSTALLTOP)/$(LIBDIR)
ENGINESDIR=$(libdir)/engines-1.1
由上可知,如果没有指定环境变量 OPENSSL_ENGINES
,则默认的引擎加载目录是:/usr/local/lib/engines-1.1
。
综上所述,在 openssl
测试时可以通过设置 OPENSSL_ENGINES
环境变量来指定引擎的加载目录。