【问题标题】:C++ and OpenSSL Library: How can I set subjectAltName (SAN) from code?C++ 和 OpenSSL 库:如何从代码中设置 subjectAltName (SAN)?
【发布时间】:2019-01-25 05:05:02
【问题描述】:

我正在尝试使用 c++ 代码中的 subjectAltName 创建自签名请求(尝试将 this 等动态自签名证书实现为 OpenResty 的实际版本,但没有针对 subjectAltName 的解决方案)。

请提供一些从 C++/OpenSSL 代码设置 SAN 的示例。我尝试了一些这样的:

    X509_EXTENSION  *ext;
    STACK_OF (X509_EXTENSION) * extlist;
    char *ext_name = "subjectAltName";
    char *ext_value = "DNS:lohsport.com";

    extlist = sk_X509_EXTENSION_new_null ();
    ext = X509V3_EXT_conf (NULL, NULL, ext_name, ext_value);
    if(ext == NULL)
    {
        *err = "Error creating subjectAltName extension";
        goto failed;
    }
    sk_X509_EXTENSION_push (extlist, ext);

    if (!X509_REQ_add_extensions (x509_req, extlist)){
        *err = "Error adding subjectAltName to the request";
        goto failed;
    }
    sk_X509_EXTENSION_pop_free (extlist, X509_EXTENSION_free);

编译成功但不工作。 如果有任何帮助,我将不胜感激。

更新 现在我尝试在 OpenSSL 库的 selfsing.c 演示中工作:

1) 我定义了一个向 CSR 添加扩展的函数:

int add_ext(STACK_OF(X509_EXTENSION) *sk, int nid, char *value)
{
X509_EXTENSION *ex;
ex = X509V3_EXT_conf_nid(NULL, NULL, nid, value);
if (!ex)
    return 0;
sk_X509_EXTENSION_push(sk, ex);

return 1;
}

2) 将此块添加到生成 CSR 的函数中:

   char Buffer[512];
    // Format the value
    sprintf (Buffer, "DNS:%s", info->common_name);
    xts = sk_X509_EXTENSION_new_null();
    add_ext(exts, NID_subject_alt_name, Buffer);

    if(X509_REQ_add_extensions(x509_req, exts) != 1) {
        *err = "X509_REQ_add_extensions() failed";
        goto failed;
    }
    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);

代码再次正确编译,即时生成证书,但替代名称仍然不起作用,并且我在浏览器中收到错误:

NET :: ERR_CERT_COMMON_NAME_INVALID

我没有在证书详细信息中看到备用名称信息。

对于 SAN 问题还有哪些其他解决方案?如果有帮助,我可以在 githab 上提供所有代码。

【问题讨论】:

    标签: c++ openssl self-signed-certificate


    【解决方案1】:

    你好,我做过类似的事情(但我正在使用 X509 对象而不是 X509_REQ 对象,就像你一样:

    static int cs_cert_set_subject_alt_name(X509 *x509_cert)
    {
        char *subject_alt_name = "IP: 192.168.1.1";
        X509_EXTENSION *extension_san = NULL;
        ASN1_OCTET_STRING *subject_alt_name_ASN1 = NULL;
        int ret = -1;
    
        subject_alt_name_ASN1 = ASN1_OCTET_STRING_new();
        if (!subject_alt_name_ASN1) {
            goto err;
        }
        ASN1_OCTET_STRING_set(subject_alt_name_ASN1, (unsigned char*) subject_alt_name, strlen(subject_alt_name));
        if (!X509_EXTENSION_create_by_NID(&extension_san, NID_subject_alt_name, 0, subject_alt_name_ASN1)) {
            goto err;
        }
        ASN1_OCTET_STRING_free(subject_alt_name_ASN1);
        ret = X509_add_ext(x509_cert, extension_san, -1);
        if (!ret) {
            goto err;
        }
        X509_EXTENSION_free(extension_san);
    
    err:
        if (subject_alt_name_ASN1) ASN1_OCTET_STRING_free(subject_alt_name_ASN1);
        if (extension_san) X509_EXTENSION_free(extension_san);
        return -1;
    }
    

    目前它对我有用,当我想用​​新的主题 alt 名称(因为新的 IP 地址)更新已经存在的证书时,我仍然遇到了一些麻烦。

    查看结果并检查是否创建了主题替代名称:

    $ openssl x509 -text -in cert.pem 
    

    【讨论】:

      【解决方案2】:

      尝试使用 X509V3_EXT_conf_nid 函数代替 X509V3_EXT_conf 函数,在该函数中传递 NID 而不是名称。

      ext = X509V3_EXT_conf (NULL, NULL, ext_name, ext_value);
      

      可以

      ext = X509V3_EXT_conf_nid(NULL, NULL, NID_subject_alt_name, ext_value);
      

      您的代码可能无法正常工作,因为您的扩展名可能与 OpenSSL 代码中的扩展名不完全匹配。

      【讨论】:

      • 感谢您的帮助。据我了解,您的评论是正确的,但不幸的是,这并没有解决问题。添加了对新代码问题的更新,该代码也不起作用:(
      猜你喜欢
      • 1970-01-01
      • 2020-11-06
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-20
      相关资源
      最近更新 更多