【问题标题】:OpenSSL x509 Certificate: Add Extension with X509_add1_ext_i2d()OpenSSL x509 证书:使用 X509_add1_ext_i2d() 添加扩展
【发布时间】:2016-06-07 14:39:18
【问题描述】:

上下文:

我正在使用 OpenSSL 中的 API 生成 x509 证书。我首先像这样创建 X509 结构:

X509 *x509 = X509_new();   // Assume no errors

我想要做什么:

现在我想为这个证书添加一个扩展。具体来说,我想将“扩展密钥用法”扩展设置为值serverAuth,clientAuth。为此,我尝试使用具有以下签名的 OpenSSL 函数 x509_add1_ext_i2d():

X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, unsigned long flags)

我正在调用该函数,为value 传递一个 C 字符串,我认为这是不正确的。这是我正在打的电话:

X509_add1_ext_i2d(x509, NID_ext_key_usage, "serverAuth,clientAuth", 0, 0)

发生了什么:

当那行代码运行时,我收到了EXC_BAD_ACCESS (code=EXC_i386_GPFLT) 异常。我假设这是因为我传入的 value 必须是某种特殊的东西(八位字节字符串?某种其他 OpenSSL 值?)


我需要什么:

为了将扩展名正确设置为字符串值serverAuth,clientAuth,我需要为value 参数传递什么?或者,为什么我会得到列出的异常?注意:如果我删除此行并尝试生成不带扩展名的证书(为简洁起见,我在此处排除了其他属性,例如名称、到期日期等),它工作得很好。

我花了一整天的时间研究 OpenSSL(非常糟糕)的文档和谷歌搜索。我能找到的所有内容都讨论了如何从命令行而不是在代码中向证书添加扩展。我无法追踪这个函数期望在value 参数中看到什么。

【问题讨论】:

  • 所以函数中的“i2d”显然意味着,在 OpenSSL 中,“在 DER 内部”,这意味着 value 参数应该是一些内部 OpenSSL 结构。我无法弄清楚的是......哪个结构? ASN1_Octet_String?试过了,好像没用。

标签: objective-c c ssl openssl x509certificate


【解决方案1】:

在深入了解 OpenSSL 的源代码之后,我偶然发现了 makecert.c 示例中的一个函数,该函数也执行此操作。我稍微清理了一下,就在这里。你传入你想要设置的扩展的 NID 和一个简单的字符串值。非常方便:

BOOL addExtension(X509 *cert, int nid, char *value)
{
    X509_EXTENSION *ex = NULL;
    X509V3_CTX ctx;

    // This sets the 'context' of the extensions. No configuration database
    X509V3_set_ctx_nodb(&ctx);

    // Issuer and subject certs: both the target since it is self signed, no request and no CRL
    X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
    ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
    if (!ex) {
        return NO;
    }

    int result = X509_add_ext(cert, ex, -1);

    X509_EXTENSION_free(ex);

    return (result == 0) ? YES : NO;
}

【讨论】:

    猜你喜欢
    • 2012-07-16
    • 2014-06-08
    • 2021-11-11
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多