如有疑问,请阅读PHP的源代码!
$configargs 对幕后发生的事情相当不透明。也就是说,直到您实际查看`/ext/openssl/openssl.c`中的`php_openssl_parse_config()`。
SET_OPTIONAL_STRING_ARG("digest_alg", req->digest_name,
CONF_get_string(req->req_config, req->section_name, "default_md"));
SET_OPTIONAL_STRING_ARG("x509_extensions", req->extensions_section,
CONF_get_string(req->req_config, req->section_name, "x509_extensions"));
SET_OPTIONAL_STRING_ARG("req_extensions", req->request_extensions_section,
CONF_get_string(req->req_config, req->section_name, "req_extensions"));
SET_OPTIONAL_LONG_ARG("private_key_bits", req->priv_key_bits,
CONF_get_number(req->req_config, req->section_name, "default_bits"));
SET_OPTIONAL_LONG_ARG("private_key_type", req->priv_key_type, OPENSSL_KEYTYPE_DEFAULT);
在这里我们可以看到,大多数输入都调用了SET_OPTIONAL_STRING_ARG(),但对于'private_key_bits',则调用了SET_OPTIONAL_LONG_ARG()。这两个调用都是C宏,扩展到强制执行预期输入类型的代码。如果使用意外类型,生成的代码会忽略输入而不会发出警告/通知,而只使用配置文件中的默认值。这就是为什么使用字符串作为'private_key_bits'会导致意外行为的原因。
进一步检查同一函数中较早的初始化
SET_OPTIONAL_STRING_ARG("config", req->config_filename, default_ssl_conf_filename);
SET_OPTIONAL_STRING_ARG("config_section_name", req->section_name, "req");
req->global_config = CONF_load(NULL, default_ssl_conf_filename, NULL);
req->req_config = CONF_load(NULL, req->config_filename, NULL);
if (req->req_config == NULL) {
return FAILURE;
}
在另一个函数中的其他地方
/* 如果未设置环境变量,则默认为'openssl.cnf' */
if (config_filename == NULL) {
snprintf(default_ssl_conf_filename, sizeof(default_ssl_conf_filename), "%s/%s",
X509_get_default_cert_area(),
"openssl.cnf");
} else {
strlcpy(default_ssl_conf_filename, config_filename, sizeof(default_ssl_conf_filename));
}
显示$configargs中的'config'覆盖了其他地方的任何默认设置。这实际上否定了文档中的注释,该注释说“注意:此函数需要安装有效的openssl.cnf才能正常运行。有关更多信息,请参阅安装部分下的注释。”更正确的句子应该是“注意:此函数需要设置有效的openssl.cnf或使用$configargs指向有效的openssl.cnf文件才能正常运行。”
所有这些都表明,查看PHP源代码是弄清实际发生情况的唯一真正方法。这样做可以节省时间和精力。