Update root ca cert selection

This commit is contained in:
Zhi Guan
2026-06-18 23:11:23 +08:00
parent 19eb9165f3
commit 35a3455693
7 changed files with 196 additions and 90 deletions

View File

@@ -1902,8 +1902,8 @@ int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type,
size_t certlen;
const uint8_t *cacert;
size_t cacertlen;
const uint8_t *name;
size_t namelen;
int matched_root = 0;
int ret;
int path_len = 0;
int path_len_constraint;
@@ -1967,31 +1967,37 @@ int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type,
path_len++;
}
if (x509_cert_get_issuer(cert, certlen, &name, &namelen) != 1) {
error_print();
return -1;
}
// 函数提供了一组根证书,我们要从根证书中找到和被验证的证书链匹配的那个根证书
// 如果没有找到对应的根证书,那么就会出错
// 但是这个错误隐藏在这个函数中并不合适!这说明这个函数的接口有问题
//
if (x509_certs_get_cert_by_subject(rootcerts, rootcertslen, name, namelen,
&cacert, &cacertlen) != 1) {
error_print();
return -1;
while (rootcertslen) {
if (x509_cert_from_der(&cacert, &cacertlen, &rootcerts, &rootcertslen) != 1) {
error_print();
return -1;
}
if ((ret = x509_cert_is_signed_by_root_ca_cert(cert, certlen, cacert, cacertlen,
SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH)) < 0) {
error_print();
return -1;
}
if (ret == 0) {
continue;
}
if (x509_cert_check(cacert, cacertlen, X509_cert_ca, &path_len_constraint) != 1) {
error_print();
return -1;
}
if ((path_len_constraint >= 0 && path_len > path_len_constraint)
|| path_len > depth) {
error_print();
return -1;
}
matched_root = 1;
break;
}
if (x509_cert_check(cacert, cacertlen, X509_cert_ca, &path_len_constraint) != 1) {
error_print();
return -1;
}
if ((path_len_constraint >= 0 && path_len > path_len_constraint)
|| path_len > depth) {
error_print();
return -1;
}
if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
if (!matched_root) {
error_print();
return -1;
}

View File

@@ -870,17 +870,43 @@ err:
int x509_general_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
{
int ret;
const uint8_t *p;
size_t len;
if (dlen == 0) {
return 0;
}
switch (choice) {
case X509_gn_other_name:
case X509_gn_edi_party_name:
if ((ret = asn1_type_to_der(ASN1_TAG_EXPLICIT(choice), d, dlen, out, outlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
break;
case X509_gn_x400_address:
p = d;
len = dlen;
if (asn1_sequence_from_der(&d, &dlen, &p, &len) < 0) {
error_print();
return -1;
}
if ((ret = asn1_type_to_der(ASN1_TAG_EXPLICIT(choice), d, dlen, out, outlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
break;
case X509_gn_directory_name:
len = 0;
if (asn1_sequence_to_der(d, dlen, NULL, &len) != 1
|| asn1_explicit_header_to_der(choice, len, out, outlen) != 1
|| asn1_sequence_to_der(d, dlen, out, outlen) != 1) {
error_print();
return -1;
}
break;
case X509_gn_rfc822_name:
case X509_gn_dns_name:
case X509_gn_x400_address:
case X509_gn_directory_name:
case X509_gn_edi_party_name:
case X509_gn_uniform_resource_identifier:
case X509_gn_ip_address:
case X509_gn_registered_id:
@@ -900,20 +926,78 @@ int x509_general_name_from_der(int *choice, const uint8_t **d, size_t *dlen, con
{
int ret;
int tag;
const uint8_t *p;
size_t len;
if ((ret = asn1_any_type_from_der(&tag, d, dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
switch (tag) {
case ASN1_TAG_EXPLICIT(0): *choice = 0; break;
case ASN1_TAG_IMPLICIT(1): *choice = 1; break;
case ASN1_TAG_IMPLICIT(2): *choice = 2; break;
case ASN1_TAG_EXPLICIT(3): *choice = 3; break;
case ASN1_TAG_EXPLICIT(4): *choice = 4; break;
case ASN1_TAG_EXPLICIT(5): *choice = 5; break;
case ASN1_TAG_IMPLICIT(6): *choice = 6; break;
case ASN1_TAG_IMPLICIT(7): *choice = 7; break;
case ASN1_TAG_IMPLICIT(8): *choice = 8; break;
case ASN1_TAG_EXPLICIT(0):
*choice = 0;
if (*dlen && **d == ASN1_TAG_SEQUENCE) {
p = *d;
len = *dlen;
if (asn1_sequence_from_der(d, dlen, &p, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
}
break;
case ASN1_TAG_IMPLICIT(1):
*choice = 1;
break;
case ASN1_TAG_IMPLICIT(2):
*choice = 2;
break;
case ASN1_TAG_IMPLICIT(3):
case ASN1_TAG_EXPLICIT(3):
*choice = 3;
if (*dlen && **d == ASN1_TAG_SEQUENCE) {
p = *d;
len = *dlen;
if (asn1_sequence_from_der(d, dlen, &p, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
}
break;
case ASN1_TAG_IMPLICIT(4):
*choice = 4;
break;
case ASN1_TAG_EXPLICIT(4):
*choice = 4;
p = *d;
len = *dlen;
if (asn1_sequence_from_der(d, dlen, &p, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
break;
case ASN1_TAG_EXPLICIT(5):
*choice = 5;
if (*dlen && **d == ASN1_TAG_SEQUENCE) {
p = *d;
len = *dlen;
if (asn1_sequence_from_der(d, dlen, &p, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
}
break;
case ASN1_TAG_IMPLICIT(6):
*choice = 6;
break;
case ASN1_TAG_IMPLICIT(7):
*choice = 7;
break;
case ASN1_TAG_IMPLICIT(8):
*choice = 8;
break;
default:
fprintf(stderr, "%s %d: tag = %x\n", __FILE__, __LINE__, tag);
error_print();
@@ -932,15 +1016,17 @@ int x509_general_name_print(FILE *fp, int fmt, int ind, const char *label, int c
switch (choice) {
case 0:
case 3:
case 4:
case 5:
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
error_print();
return -1;
if (dlen && *d == ASN1_TAG_SEQUENCE) {
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
d = p;
dlen = len;
}
d = p;
dlen = len;
}
switch (choice) {
case 0: return x509_other_name_print(fp, fmt, ind, "otherName", d, dlen);

View File

@@ -62,48 +62,6 @@ static int x509_cert_get_authority_key_identifier_keyid(const uint8_t *cert, siz
return 1;
}
static int x509_general_names_match_directory_name(const uint8_t *general_names, size_t general_names_len,
const uint8_t *name, size_t name_len)
{
int tag;
const uint8_t *general_name;
size_t general_name_len;
const uint8_t *directory_name;
size_t directory_name_len;
if (!general_names || !general_names_len || !name || !name_len) {
error_print();
return -1;
}
while (general_names_len) {
if (asn1_any_type_from_der(&tag, &general_name, &general_name_len,
&general_names, &general_names_len) != 1) {
error_print();
return -1;
}
if (tag == ASN1_TAG_IMPLICIT(X509_gn_directory_name)) {
directory_name = general_name;
directory_name_len = general_name_len;
if (x509_name_equ(directory_name, directory_name_len, name, name_len) == 1) {
return 1;
}
} else if (tag == ASN1_TAG_EXPLICIT(X509_gn_directory_name)) {
if (asn1_sequence_from_der(&directory_name, &directory_name_len,
&general_name, &general_name_len) != 1
|| asn1_length_is_zero(general_name_len) != 1) {
error_print();
return -1;
}
if (x509_name_equ(directory_name, directory_name_len, name, name_len) == 1) {
return 1;
}
}
}
return 0;
}
static int x509_cert_get_subject_key_identifier(const uint8_t *cert, size_t certlen,
const uint8_t **keyid, size_t *keyid_len)
{
@@ -200,6 +158,8 @@ int x509_cert_is_signed_by_root_ca_cert(const uint8_t *cert, size_t certlen,
size_t ski_len;
const uint8_t *root_serial;
size_t root_serial_len;
const uint8_t *directory_name;
size_t directory_name_len;
int issuer_match;
X509_KEY public_key;
int ret;
@@ -253,11 +213,19 @@ int x509_cert_is_signed_by_root_ca_cert(const uint8_t *cert, size_t certlen,
// aki_issuer AKI 中的Issuer 是一个GeneralNames.directoryName == ROOTCACERT.subject
if ((ret = x509_general_names_match_directory_name(aki_issuer, aki_issuer_len,
subject, subject_len)) != 1) {
if ((ret = x509_general_names_get_first(aki_issuer, aki_issuer_len, NULL,
X509_gn_directory_name, &directory_name, &directory_name_len)) < 0) {
if (ret) error_print();
return ret;
}
if (ret == 0) {
return 0;
}
if ((issuer_match = x509_name_equ(directory_name, directory_name_len,
subject, subject_len)) != 1) {
if (issuer_match) error_print();
return issuer_match;
}
if (aki_serial_len != root_serial_len
|| memcmp(aki_serial, root_serial, root_serial_len) != 0) {