如有疑问,请阅读 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 源代码是真正了解实际发生情况的唯一方法。这样做可以节省时间和精力。