bash – 如何确定openssl.cnf的默认位置?

背景

我正在编写一个bash脚本,它将使用openssl生成一个证书签名请求,其中包含符合X509v3扩展名的主题替代名称.

由于没有针对此的命令行选项,因此a solution已将-config选项与-reqexts选项结合使用,方法是将SAN值内联添加配置文件中.

openssl req -new -sha256 -key domain.key -subj "/C=US/ST=CA/O=Acme,Inc./CN=example.com" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:example.com,DNS:www.example.com")) -out domain.csr

我的问题是可移植性.虽然a similar question向我保证这可以在我的Ubuntu环境中运行,因为认的配置文件是/etc/ssl/openssl.cnf,遗憾的是这在任何地方都不起作用,Windows就是一个明显的例子.

如何以编程方式确定openssl配置文件的完整路径?

我试过的

documentation一个明显的暗示

-config filename
this allows an alternative configuration file to be specified,this overrides the compile time filename or any specified in the OPENSSL_CONF environment variable.

我已经阅读了config documentation搜索source code,但是我无法找到它从何处加载“编译时”配置文件的机制.如果我能找到它,那么我宁愿将其作为变量加载到脚本而不是硬编码路径中.

而且,我的$OPENSSL_CONF变量是空的.

不良选择

目前我的脚本检查这些条件,并使用第一个评估为true的条件:

> $OPENSSL_CONF变量已填充,文件存在
> /etc/ssl/openssl.cnf存在

如果这些都不是真的,那么它包括标准配置的副本.这是不合需要的,因为它实际上会覆盖客户端建立的自定义设置.我想完全使用环境条件,只需添加SAN部分作为附录.

我可以用通常的嫌疑人的路径甚至系统搜索进一步扩展这个链.但是如果存在多个,那么我无法保证openssl实际上将其用作认值.

How do I programmatically determine the full path to the openssl default configuration file?

以编程方式,它就像使用opensslconf.h中的OPENSSLDIR宏一样简单:

$cat /usr/local/ssl/darwin/include/openssl/opensslconf.h | grep OPENSSLDIR
#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
#define OPENSSLDIR "/usr/local/ssl/darwin"

How to determine the default location for openssl.cnf?

这里有更多信息可以帮助填补其他Stack Overflow问题的空白.这取决于您使用的OpenSSL安装.

这是简短的答案……图书馆和程序在OPENSSLDIR中寻找openssl.cnf. OPENSSLDIR是一个配置选项,其设置为–openssldir.

我在MacBook上有3种不同的OpenSSL(Apple,MacPort和我建的):

# Apple    
$/usr/bin/openssl version -a | grep OPENSSLDIR
OPENSSLDIR: "/System/Library/OpenSSL"

# MacPorts
$/opt/local/bin/openssl version -a | grep OPENSSLDIR
OPENSSLDIR: "/opt/local/etc/openssl"

# My build of OpenSSL
$openssl version -a | grep OPENSSLDIR
OPENSSLDIR: "/usr/local/ssl/darwin"

这是更长的答案……它有点埋没在apps.c,load_config的OpenSSL源代码中,当cnf为NULL时会发生什么(即,没有-config选项或OPENSSL_CONF envar).当cnf为NULL且没有覆盖时,则使用OPENSSLDIR.

int load_config(BIO *err,CONF *cnf)
{
    static int load_config_called = 0;
    if (load_config_called)
        return 1;
    load_config_called = 1;
    if (!cnf)
        cnf = config;
    if (!cnf)
        return 1;

    OPENSSL_load_builtin_modules();

    if (CONF_modules_load(cnf,NULL,0) <= 0) {
        BIO_printf(err,"Error configuring OpenSSL\n");
        ERR_print_errors(err);
        return 0;
    }
    return 1;
}

… this works in my Ubuntu environment because the default configuration file is /etc/ssl/openssl.cnf,unfortunately this won’t work everywhere,with Windows being the obvIoUs example.

在Windows上,这可能仍然是一个问题.如果您自己从源代码构建OpenSSL,那么您应该没问题.模块化他们在Windows中的长文件名处理(也见Issue #4490: “nmake install” fails “Destination must be a directory at .\util\copy.pl line 39” on).

Shinning Light and Win32 OpenSSL这样的人提供了安装程序,OpenSSL可能没有安装在打包器所设想的目录中.我甚至在Windows机器上看到过像/usr/local这样的Unix目录.

对于Windows,您最安全的选择可能是设置OPENSSL_CONF环境变量来覆盖损坏的路径和路径处理错误.

另外,我不知道在运行时为您提供有效目录的CONF_ *或NCONF_ * API调用.这里,有效目录将是配置目录以及OPENSSL_CONF覆盖等内容.现在在OpenSSL用户列表中打开:Get effective OPENSSLDIR path at runtime?

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...