Add x.509 ext critical check

This commit is contained in:
Zhi Guan
2026-06-17 09:14:03 +08:00
parent f45919d0f7
commit 1bf47fea14
4 changed files with 43 additions and 4 deletions

View File

@@ -818,7 +818,7 @@ endif()
# #
set(CPACK_PACKAGE_NAME "GmSSL") set(CPACK_PACKAGE_NAME "GmSSL")
set(CPACK_PACKAGE_VENDOR "GmSSL develop team") set(CPACK_PACKAGE_VENDOR "GmSSL develop team")
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1070") set(CPACK_PACKAGE_VERSION "3.2.0-dev.1071")
set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md) set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md)
set(CPACK_NSIS_MODIFY_PATH ON) set(CPACK_NSIS_MODIFY_PATH ON)
include(CPack) include(CPack)

View File

@@ -18,7 +18,7 @@ extern "C" {
#define GMSSL_VERSION_NUM 30200 #define GMSSL_VERSION_NUM 30200
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1070" #define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1071"
int gmssl_version_num(void); int gmssl_version_num(void);
const char *gmssl_version_str(void); const char *gmssl_version_str(void);

View File

@@ -605,6 +605,7 @@ NetscapeCertComment ::= IA5String
*/ */
int x509_netscape_cert_type_print(FILE *fp, int fmt, int ind, const char *label, int bits); int x509_netscape_cert_type_print(FILE *fp, int fmt, int ind, const char *label, int bits);
int x509_ext_check_critical(int oid, int is_ca, int critical);
int x509_exts_check(const uint8_t *exts, size_t extslen, int cert_type, int x509_exts_check(const uint8_t *exts, size_t extslen, int cert_type,
int *path_len_constraints); int *path_len_constraints);

View File

@@ -72,7 +72,6 @@ static const ASN1_OID_INFO x509_ext_ids[] = {
{ OID_pe_authority_info_access, "AuthorityInformationAccess", oid_pe_authority_info_access, sizeof(oid_pe_authority_info_access)/sizeof(int) }, { OID_pe_authority_info_access, "AuthorityInformationAccess", oid_pe_authority_info_access, sizeof(oid_pe_authority_info_access)/sizeof(int) },
{ OID_ct_precertificate_scts, "CT-PrecertificateSCTs", oid_ct_precertificate_scts, sizeof(oid_ct_precertificate_scts)/sizeof(int) }, { OID_ct_precertificate_scts, "CT-PrecertificateSCTs", oid_ct_precertificate_scts, sizeof(oid_ct_precertificate_scts)/sizeof(int) },
}; };
static const int x509_ext_ids_count = static const int x509_ext_ids_count =
sizeof(x509_ext_ids)/sizeof(x509_ext_ids[0]); sizeof(x509_ext_ids)/sizeof(x509_ext_ids[0]);
@@ -127,6 +126,41 @@ int x509_ext_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uin
return 1; return 1;
} }
typedef struct {
int oid;
int only_critical_for_ca_certs;
} X509_EXT_CRITICAL;
#define X509_EXT_ONLY_CRITICAL_FOR_CA_CERTS 1
static const X509_EXT_CRITICAL x509_ext_critical[] = {
{ OID_ce_basic_constraints, X509_EXT_ONLY_CRITICAL_FOR_CA_CERTS },
{ OID_ce_name_constraints, 0 },
{ OID_ce_policy_constraints, 0 },
{ OID_ce_inhibit_any_policy, 0 },
};
static const size_t x509_ext_critical_cnt =
sizeof(x509_ext_critical)/sizeof(x509_ext_critical[0]);
int x509_ext_check_critical(int oid, int is_ca, int critical)
{
size_t i;
for (i = 0; i < x509_ext_critical_cnt; i++) {
if (oid == x509_ext_critical[i].oid) {
if (x509_ext_critical[i].only_critical_for_ca_certs && !is_ca) {
return 1;
}
if (critical != X509_critical) {
error_print();
return -1;
}
return 1;
}
}
return 1;
}
int x509_ext_to_der(int oid, int critical, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen) int x509_ext_to_der(int oid, int critical, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen)
{ {
size_t len = 0; size_t len = 0;
@@ -2839,6 +2873,7 @@ int x509_exts_check(const uint8_t *exts, size_t extslen, int cert_type,
int key_usage; int key_usage;
int ext_key_usages[X509_MAX_KEY_PURPOSES]; int ext_key_usages[X509_MAX_KEY_PURPOSES];
size_t ext_key_usages_cnt; size_t ext_key_usages_cnt;
int is_ca = (cert_type == X509_cert_ca || cert_type == X509_cert_root_ca) ? 1 : 0;
*path_len_constraint = -1; *path_len_constraint = -1;
@@ -2847,6 +2882,10 @@ int x509_exts_check(const uint8_t *exts, size_t extslen, int cert_type,
error_print(); error_print();
return -1; return -1;
} }
if (x509_ext_check_critical(oid, is_ca, critical) != 1) {
error_print();
return -1;
}
switch (oid) { switch (oid) {
case OID_ce_authority_key_identifier: case OID_ce_authority_key_identifier:
@@ -2935,7 +2974,6 @@ int x509_exts_check(const uint8_t *exts, size_t extslen, int cert_type,
case OID_ce_crl_distribution_points: case OID_ce_crl_distribution_points:
case OID_ce_inhibit_any_policy: case OID_ce_inhibit_any_policy:
case OID_ce_freshest_crl: case OID_ce_freshest_crl:
break; break;
default: default:
if (critical == X509_critical) { if (critical == X509_critical) {