如何验证证书是否具有 "CA=true" 基本约束?
How can I verify certificate has "CA=true" basic constraint?
我是 openssl 新手 API
当我通过以下命令使用 openssl APP 时:
openssl x509 -in mycert.crt -text -noout
形成它的输出我感兴趣的是:
...
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE <-- this section I want to validate in my code
...
我想使用 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);
我的问题:
迭代扩展的正确方法是什么,找到基本约束部分并 验证我的证书是 CA:TRUE
加分题:
你在 openssl API 中搜索方法
的方法是什么
bonus question: what is your method searching the openssl API for methods
遗憾的是,有时没有简单的方法。我将引导您完成我用来回答此类独特问题的步骤。
如果您知道要寻找什么,有时您可以使用 ctags 等符号浏览器。但是我不使用它;相反,我通常 grep 来源。
如果您听说过 OpenSSL 是 "self documenting",这就是它的缩影。
my question: what is the proper way to iterate over the extensions ,
find tthe basic constrains section and validate that my certificate is
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)))
...
从上面,我知道了一些事情。首先,v3_purp.c
是感兴趣的文件。其次,X509_get_ext_d2i(x, ...)
表示x
是一个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;
}
...
}
接下来,结帐 BASIC_CONSTRAINTS
。您需要 _st
因为这就是 OpenSSL 命名其结构的方式。
$ grep -IR BASIC_CONSTRAINTS * | grep _st
include/openssl/x509v3.h:typedef struct BASIC_CONSTRAINTS_st {
并快速浏览 BASIC_CONSTRAINTS_st
:
typedef struct BASIC_CONSTRAINTS_st {
int ca;
ASN1_INTEGER *pathlen;
} BASIC_CONSTRAINTS;
最后一个问题可能是,您如何获得 X509 *x
?好吧,你可以从:
SSL_get_peer_certificate
(来自 SSL 连接)
PEM_read_X509
(从 PEM 编码转换)
d2i_X509
(从 ASN.1/DER 编码转换)
- 等...
如果你已经有一个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;
...
我是 openssl 新手 API
当我通过以下命令使用 openssl APP 时:
openssl x509 -in mycert.crt -text -noout
形成它的输出我感兴趣的是:
...
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE <-- this section I want to validate in my code
...
我想使用 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);
我的问题: 迭代扩展的正确方法是什么,找到基本约束部分并 验证我的证书是 CA:TRUE
加分题: 你在 openssl API 中搜索方法
的方法是什么bonus question: what is your method searching the openssl API for methods
遗憾的是,有时没有简单的方法。我将引导您完成我用来回答此类独特问题的步骤。
如果您知道要寻找什么,有时您可以使用 ctags 等符号浏览器。但是我不使用它;相反,我通常 grep 来源。
如果您听说过 OpenSSL 是 "self documenting",这就是它的缩影。
my question: what is the proper way to iterate over the extensions , find tthe basic constrains section and validate that my certificate is 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)))
...
从上面,我知道了一些事情。首先,v3_purp.c
是感兴趣的文件。其次,X509_get_ext_d2i(x, ...)
表示x
是一个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;
}
...
}
接下来,结帐 BASIC_CONSTRAINTS
。您需要 _st
因为这就是 OpenSSL 命名其结构的方式。
$ grep -IR BASIC_CONSTRAINTS * | grep _st
include/openssl/x509v3.h:typedef struct BASIC_CONSTRAINTS_st {
并快速浏览 BASIC_CONSTRAINTS_st
:
typedef struct BASIC_CONSTRAINTS_st {
int ca;
ASN1_INTEGER *pathlen;
} BASIC_CONSTRAINTS;
最后一个问题可能是,您如何获得 X509 *x
?好吧,你可以从:
SSL_get_peer_certificate
(来自 SSL 连接)PEM_read_X509
(从 PEM 编码转换)d2i_X509
(从 ASN.1/DER 编码转换)- 等...
如果你已经有一个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;
...