如何验证证书具有“CA=true”基本约束?

Lor*_*aka 5 c ssl openssl x509

我是 openssl API 的新手

当我通过以下命令使用 openssl APP 时:

openssl x509 -in mycert.crt -text -noout
Run Code Online (Sandbox Code Playgroud)

形式它的输出我的兴趣是:

    ...
    X509v3 extensions:
        X509v3 Basic Constraints: critical
            CA:TRUE <-- this section I want to validate in my code
    ...
Run Code Online (Sandbox Code Playgroud)

我想使用 OpenSSL c API 验证 CA 部分,但不知道如何验证。我已经深入了解了 APP src 代码,但当我到达时却迷失了方向

openssl/crypto/ct/ct_prn:102

BIO_printf(out, "\n%*sExtensions: ", indent + 4, "");
if (sct->ext_len == 0)
    BIO_printf(out, "none");
else
    BIO_hex_string(out, indent + 16, 16, sct->ext, sct->ext_len);
Run Code Online (Sandbox Code Playgroud)

我的问题: 迭代扩展、找到基本约束部分并验证我的证书是否为 CA:TRUE 的正确方法是什么

额外问题: 您在 openssl API 中搜索方法的方法是什么

jww*_*jww 3

额外问题:您在 openssl API 中搜索方法的方法是什么

遗憾的是,有时没有简单的方法。我将引导您完成用于回答此类独特问题的步骤。

如果您知道要查找什么,有时可以使用 ctags 等符号浏览器。不过我不使用它;相反,我通常会 grep 来源。

如果您听说过 OpenSSL 是“自文档化”,那么这就是它的缩影。


我的问题:迭代扩展、找到基本约束部分并验证我的证书是否为 CA:TRUE 的正确方法是什么

过了一段时间,你就会感受到一些有趣的东西。从下面的 grep 中,我知道它是NID_basic_constraints.

openssl-1.1.0b$ grep -iR basic * | grep constraint
crypto/objects/obj_dat.h:    0x55,0x1D,0x13,                                /* [  505] OBJ_basic_constraints */
crypto/objects/obj_dat.h:    {"basicConstraints", "X509v3 Basic Constraints", NID_basic_constraints, 3, &so[505]},
crypto/objects/obj_dat.h:      87,    /* OBJ_basic_constraints            2 5 29 19 */
crypto/objects/obj_mac.num:basic_constraints        87
crypto/objects/objects.txt:!Cname basic-constraints
crypto/x509v3/v3_bcons.c:    NID_basic_constraints, 0,
crypto/x509v3/v3_purp.c:        NID_basic_constraints,  /* 87 */
crypto/x509v3/v3_purp.c:    /* Handle basic constraints */
crypto/x509v3/v3_purp.c:    if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL)))
...
Run Code Online (Sandbox Code Playgroud)

从上面我知道了一些事情。首先,v3_purp.c是感兴趣的文件。其次,X509_get_ext_d2i(x, ...)手段x是a X509*。第三,NID_basic_constraints是感兴趣的项目。

这是函数的头部以及感兴趣的部分。BASIC_CONSTRAINTS两者bs->ca看起来都很有趣。

static void x509v3_cache_extensions(X509 *x)
{
    BASIC_CONSTRAINTS *bs;
    PROXY_CERT_INFO_EXTENSION *pci;
    ASN1_BIT_STRING *usage;
    ASN1_BIT_STRING *ns;
    EXTENDED_KEY_USAGE *extusage;
    X509_EXTENSION *ex;

    int i;
    if (x->ex_flags & EXFLAG_SET)
        return;
    X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
    /* V1 should mean no extensions ... */
    if (!X509_get_version(x))
        x->ex_flags |= EXFLAG_V1;
    /* Handle basic constraints */
    if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
        if (bs->ca)
            x->ex_flags |= EXFLAG_CA;
        if (bs->pathlen) {
            if ((bs->pathlen->type == V_ASN1_NEG_INTEGER)
                || !bs->ca) {
                x->ex_flags |= EXFLAG_INVALID;
                x->ex_pathlen = 0;
            } else
                x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
        } else
            x->ex_pathlen = -1;
        BASIC_CONSTRAINTS_free(bs);
        x->ex_flags |= EXFLAG_BCONS;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

接下来,结账BASIC_CONSTRAINTS。您需要 ,_st因为 OpenSSL 就是这样命名其结构的。

$ grep -IR BASIC_CONSTRAINTS * | grep _st
include/openssl/x509v3.h:typedef struct BASIC_CONSTRAINTS_st {
Run Code Online (Sandbox Code Playgroud)

快速浏览一下BASIC_CONSTRAINTS_st:

typedef struct BASIC_CONSTRAINTS_st {
    int ca;
    ASN1_INTEGER *pathlen;
} BASIC_CONSTRAINTS;
Run Code Online (Sandbox Code Playgroud)

最后一个问题可能是,如何获得X509 *x?好吧,你可以从以下地方得到:

  • SSL_get_peer_certificate(来自 SSL 连接)
  • PEM_read_X509(从PEM编码转换)
  • d2i_X509(从 ASN.1/DER 编码转换)
  • ETC...

如果您已经有了X509* x,看起来您只需要测试一下即可x->ex_flags & EXFLAG_V1。

起泡沫,冲洗,重复EXFLAG_V1和X509_st:

$ grep -IR EXFLAG_V1 * | grep define
crypto/x509v3/v3_purp.c:#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
include/openssl/x509v3.h:# define EXFLAG_V1               0x40

$ grep -IR X509 * | grep _st | grep typedef
crypto/x509v3/pcy_int.h:typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
include/openssl/ossl_typ.h:typedef struct x509_st X509;
include/openssl/ossl_typ.h:typedef struct X509_algor_st X509_ALGOR;
include/openssl/ossl_typ.h:typedef struct X509_crl_st X509_CRL;
...
Run Code Online (Sandbox Code Playgroud)