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

背景

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

由于没有命令行选项,因此解决方案是将-config选项与-reqexts选项一起使用, -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

我的问题是可移植性。 虽然类似的问题可以保证我的Ubuntu环境能够正常工作,因为默认的配置文件是/etc/ssl/openssl.cnf ,但不幸的是这种方式无法在任何地方使用,而Windows就是一个明显的例子。

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

我试过的

文件中有一个明显的提示

-config文件名
这允许指定备用配置文件,这将覆盖编译时间文件名或OPENSSL_CONF环境变量中指定的任何配置文件。

我读过配置文档并搜索了源代码,但是我无法发现它从何处加载“编译时”默认配置文件的机制。 如果我能找到,那么我宁愿将它作为变量加载到脚本中,而不是硬编码路径。

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

一个糟糕的选择

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

  • $OPENSSL_CONF变量被填充,并且文件存在
  • /etc/ssl/openssl.cnf存在
  • 如果这两个都不是真的,那么它包含一个标准配置的副本。 这是不受欢迎的,因为它实际上会覆盖由客户端建立的自定义设置。 我想完全使用环境条件,并简单地将SAN部分添加为附录。

    我可以用通常的嫌疑人的路径甚至系统搜索来进一步扩展这个链条。 但是,如果存在多个,那么我不能确定openssl事实上使用哪一个作为默认值。


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

    编程,它一样容易使用OPENSSLDIR从宏观opensslconf.h

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

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

    这里有更多的信息来帮助填补另一个堆栈溢出问题的空白。 这取决于您使用的OpenSSL安装。

    下面是简短的回答...图书馆和程序在OPENSSLDIR查找openssl.cnfOPENSSLDIR是一个配置选项,其设置为--openssldir

    我在一台带有3种不同OpenSSL(苹果,MacPort和我制造的)的MacBook上:

    # 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"
    

    这是更长的答案......它被埋在OpenSSL apps.cload_config源代码中,当cnfNULL (即no -config选项或OPENSSL_CONF envar)时会发生什么。 当cnfNULL且不覆盖时,则使用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 OpenSSLn");
            ERR_print_errors(err);
            return 0;
        }
        return 1;
    }
    

    ...这在我的Ubuntu环境中工作,因为默认的配置文件是/etc/ssl/openssl.cnf ,不幸的是这不会在任何地方工作,Windows是一个明显的例子。

    这在Windows上可能仍然是一个问题。 如果您自己从源创建OpenSSL,则应该可以; 以它们在Windows中的长文件名处理为模(也参见问题#4490:“nmake install”失败“目标必须是。 util copy.pl第39行”处的目录)。

    像Shinning Light和Win32 OpenSSL这样的人提供安装程序,并且OpenSSL可能不会安装在打包程序设想的目录中。 我甚至在Windows机器上看到了像/usr/local这样的Unix目录。

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


    另外,我不知道CONF_*NCONF_* API调用,它会在运行时为您提供有效的目录。 在这里,有效的目录将是配置目录加上OPENSSL_CONF覆盖之类的东西。 现在在OpenSSL用户列表中打开:在运行时获得有效的OPENSSLDIR路径?

    链接地址: http://www.djcxy.com/p/91563.html

    上一篇: How to determine the default location for openssl.cnf?

    下一篇: Is it important to use Characteristics.UNORDERED in Collectors when possible?