diff --git a/ChangeLog.d/register-name-constraints.txt b/ChangeLog.d/register-name-constraints.txt new file mode 100644 index 0000000000..4a2a2631dc --- /dev/null +++ b/ChangeLog.d/register-name-constraints.txt @@ -0,0 +1,18 @@ +Default behavior changes + * A non-critical Name Constraints extension used to be ignored, and is + now enforced like a critical one, as required by RFC 5280. + +Features + * Parse the Name Constraints certificate extension. Certificates of CAs + with a critical Name Constraints extension used to be rejected by the + parser with MBEDTLS_ERR_X509_INVALID_EXTENSIONS. Fixes #8759. + * Enforce Name Constraints during certificate chain verification: the + subject and subject alternative names of each certificate below a + constrained CA are checked against its permitted and excluded subtrees + for the dNSName, rfc822Name, iPAddress and directoryName forms. A name + of any other form that a CA constrains is rejected. Violations are + reported with the new verification flag + MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS. + * Show Name Constraints in mbedtls_x509_crt_info(). + * Handle the Other Name form of General Name as opaque data. + * Show BundleEID Other Names in mbedtls_x509_crt_info(). diff --git a/framework b/framework index ced31491c5..aefd6fb350 160000 --- a/framework +++ b/framework @@ -1 +1 @@ -Subproject commit ced31491c5ec907a6be533512f19dc1779230ac1 +Subproject commit aefd6fb35097b00259c2ebdb181dff88cfa9ee14 diff --git a/include/mbedtls/oid.h b/include/mbedtls/oid.h index dc70d32674..2c9faea6fe 100644 --- a/include/mbedtls/oid.h +++ b/include/mbedtls/oid.h @@ -169,6 +169,7 @@ #define MBEDTLS_OID_ON MBEDTLS_OID_PKIX "\x08" /**< id-on OBJECT IDENTIFIER ::= { id-pkix 8 } */ #define MBEDTLS_OID_ON_HW_MODULE_NAME MBEDTLS_OID_ON "\x04" /**< id-on-hardwareModuleName OBJECT IDENTIFIER ::= { id-on 4 } */ +#define MBEDTLS_OID_ON_BUNDLE_EID MBEDTLS_OID_ON "\x0b" /**< id-on-bundleEID OBJECT IDENTIFIER ::= { id-on 11 } (RFC 9174) */ /* * PKCS definition OIDs diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h index 130c427c4f..689bd5ab3e 100644 --- a/include/mbedtls/x509.h +++ b/include/mbedtls/x509.h @@ -104,6 +104,7 @@ #define MBEDTLS_X509_BADCRL_BAD_MD 0x020000 /**< The CRL is signed with an unacceptable hash. */ #define MBEDTLS_X509_BADCRL_BAD_PK 0x040000 /**< The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA). */ #define MBEDTLS_X509_BADCRL_BAD_KEY 0x080000 /**< The CRL is signed with an unacceptable key (eg bad curve, RSA too short). */ +#define MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS 0x100000 /**< A name of the certificate violates the Name Constraints of a CA in the chain. */ /** \} name X509 Verify codes */ /** \} addtogroup x509_module */ @@ -130,6 +131,9 @@ #define MBEDTLS_X509_SAN_IP_ADDRESS 7 #define MBEDTLS_X509_SAN_REGISTERED_ID 8 +#define MBEDTLS_X509_NAME_CONST_INCL 0 +#define MBEDTLS_X509_NAME_CONST_EXCL 1 + /* * X.509 v3 Key Usage Extension flags * Reminder: update mbedtls_x509_info_key_usage() when adding new flags. @@ -270,6 +274,9 @@ typedef struct mbedtls_x509_san_other_name { mbedtls_x509_buf val; /**< The named value. */ } hardware_module_name; + /** Raw source value for non-constructed types. + */ + mbedtls_x509_buf raw; } value; } diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h index 0a7b532404..3fd026c9ce 100644 --- a/include/mbedtls/x509_crt.h +++ b/include/mbedtls/x509_crt.h @@ -66,6 +66,9 @@ typedef struct mbedtls_x509_crt { mbedtls_x509_buf subject_key_id; /**< Optional X.509 v3 extension subject key identifier. */ mbedtls_x509_authority authority_key_id; /**< Optional X.509 v3 extension authority key identifier. */ + mbedtls_x509_sequence name_constraints_incl; /**< Optional list of the bases of the permittedSubtrees of the Name Constraints extension, as raw GeneralName entries like subject_alt_names. An iPAddress entry is an address followed by a mask. */ + mbedtls_x509_sequence name_constraints_excl; /**< Optional list of the bases of the excludedSubtrees of the Name Constraints extension, in the same format as name_constraints_incl. */ + mbedtls_x509_sequence certificate_policies; /**< Optional list of certificate policies (Only anyPolicy is printed and enforced, however the rest of the policies are still listed). */ int MBEDTLS_PRIVATE(ext_types); /**< Bit string containing detected and parsed extensions */ @@ -213,7 +216,10 @@ mbedtls_x509_crt_profile; "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA).") \ X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCRL_BAD_KEY, \ "MBEDTLS_X509_BADCRL_BAD_KEY", \ - "The CRL is signed with an unacceptable key (eg bad curve, RSA too short).") + "The CRL is signed with an unacceptable key (eg bad curve, RSA too short).") \ + X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS, \ + "MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS", \ + "A name violates the Name Constraints of a CA in the chain.") /** * Container for writing a certificate (CRT) diff --git a/library/x509.c b/library/x509.c index d7bc5d2dfb..294936c71d 100644 --- a/library/x509.c +++ b/library/x509.c @@ -1194,6 +1194,7 @@ int mbedtls_x509_time_is_future(const mbedtls_x509_time *from) * * NOTE: we currently only parse and use otherName of type HwModuleName, * as defined in RFC 4108. + * Other type-ids are kept as raw, undecoded ASN.1 bytes. */ static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name, mbedtls_x509_san_other_name *other_name) @@ -1222,12 +1223,7 @@ static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name, cur_oid.p = p; cur_oid.len = len; - /* - * Only HwModuleName is currently supported. - */ - if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid) != 0) { - return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; - } + /* Value context-specific tag */ other_name->type_id = cur_oid; p += len; @@ -1242,38 +1238,64 @@ static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name, MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); } - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + /* + * HwModuleName + */ + if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid) == 0) { + if ((ret = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + if (end != p + len) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID; + other_name->value.hardware_module_name.oid.p = p; + other_name->value.hardware_module_name.oid.len = len; + + p += len; + if ((ret = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_OCTET_STRING)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING; + other_name->value.hardware_module_name.val.p = p; + other_name->value.hardware_module_name.val.len = len; + p += len; + if (p != end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + } + /* Arbitrary raw value */ + else { + if (p >= end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_OUT_OF_DATA); + } + other_name->value.raw.tag = *p; + p++; + + if ((ret = mbedtls_asn1_get_len(&p, end, &len)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + other_name->value.raw.p = p; + other_name->value.raw.len = len; + p += len; + if (p != end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } } - if (end != p + len) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID; - other_name->value.hardware_module_name.oid.p = p; - other_name->value.hardware_module_name.oid.len = len; - - p += len; - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING; - other_name->value.hardware_module_name.val.p = p; - other_name->value.hardware_module_name.val.len = len; - p += len; - if (p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } return 0; } @@ -1644,6 +1666,40 @@ int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size, MBEDTLS_X509_SAFE_SNPRINTF; } }/* MBEDTLS_OID_ON_HW_MODULE_NAME */ + else if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_BUNDLE_EID, + &other_name->type_id) == 0) { + int len = 0; + const char *str = NULL; + if (other_name->value.raw.tag == MBEDTLS_ASN1_IA5_STRING) { + len = other_name->value.raw.len; + str = (char *) other_name->value.raw.p; + } + + ret = mbedtls_snprintf(p, n, "\n%s BundleEID : %.*s", prefix, + len, str); + MBEDTLS_X509_SAFE_SNPRINTF; + }/* MBEDTLS_OID_ON_BUNDLE_EID */ + else { + /* Show type OID */ + ret = mbedtls_snprintf(p, n, "\n%s type-id : ", prefix); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_oid_get_numeric_string(p, + n, + &other_name->type_id); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_snprintf(p, n, "\n%s value : ", prefix); + MBEDTLS_X509_SAFE_SNPRINTF; + + for (i = 0; i < other_name->value.raw.len; i++) { + ret = mbedtls_snprintf(p, + n, + "%02X", + other_name->value.raw.p[i]); + MBEDTLS_X509_SAFE_SNPRINTF; + } + } } break; /* diff --git a/library/x509_crt.c b/library/x509_crt.c index 5cf413b800..4c3706e351 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -585,6 +585,194 @@ static int x509_get_ext_key_usage(unsigned char **p, return 0; } +/* + * Check the base of a GeneralSubtree in a Name Constraints extension. + * + * iPAddress is an address followed by a mask (8 bytes for IPv4, 32 bytes for + * IPv6), so it can't be checked with mbedtls_x509_parse_subject_alt_name(). + * Name forms that mbedtls_x509_parse_subject_alt_name() doesn't support are + * accepted here: they can't be enforced, so certificates with names of such + * a form fail verification under this CA (see x509_crt_check_name_constraints()). + */ +static int x509_check_general_subtree_base(const mbedtls_x509_buf *base) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_x509_subject_alternative_name name; + + if ((base->tag & MBEDTLS_ASN1_TAG_CLASS_MASK) != MBEDTLS_ASN1_CONTEXT_SPECIFIC) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); + } + + if ((base->tag & MBEDTLS_ASN1_TAG_VALUE_MASK) == MBEDTLS_X509_SAN_IP_ADDRESS) { + if (base->len != 8 && base->len != 32) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_INVALID_LENGTH); + } + return 0; + } + + memset(&name, 0, sizeof(name)); + ret = mbedtls_x509_parse_subject_alt_name(base, &name); + mbedtls_x509_free_subject_alt_name(&name); + if (ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) { + return 0; + } + + return ret; +} + +/* + * GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree + * + * GeneralSubtree ::= SEQUENCE { + * base GeneralName, + * minimum [0] BaseDistance DEFAULT 0, + * maximum [1] BaseDistance OPTIONAL } + * + * BaseDistance ::= INTEGER (0..MAX) + * + * RFC 5280 requires minimum to be zero and maximum to be absent. DER omits a + * zero minimum, but an explicitly encoded zero is accepted too. Each base is + * stored as a raw GeneralName, like the entries of subject_alt_names. + */ +static int x509_get_general_subtrees(unsigned char **p, + const unsigned char *end, + mbedtls_x509_sequence *subtrees) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len; + const unsigned char *subtree_end; + mbedtls_x509_buf base; + mbedtls_x509_sequence *cur = subtrees; + + if (*p == end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_INVALID_LENGTH); + } + + while (*p < end) { + if ((ret = mbedtls_asn1_get_tag(p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + subtree_end = *p + len; + + if (*p == subtree_end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_OUT_OF_DATA); + } + base.tag = **p; + (*p)++; + if ((ret = mbedtls_asn1_get_len(p, subtree_end, &base.len)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + base.p = *p; + *p += base.len; + + if ((ret = x509_check_general_subtree_base(&base)) != 0) { + return ret; + } + + /* minimum [0]: only zero is allowed */ + if (*p < subtree_end && **p == MBEDTLS_ASN1_CONTEXT_SPECIFIC) { + (*p)++; + if ((ret = mbedtls_asn1_get_len(p, subtree_end, &len)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + if (len != 1 || **p != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_INVALID_DATA); + } + *p += len; + } + + /* maximum [1] must be absent */ + if (*p != subtree_end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); + } + + if (cur->buf.p != NULL) { + if (cur->next != NULL) { + return MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + } + + cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence)); + if (cur->next == NULL) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_ALLOC_FAILED); + } + + cur = cur->next; + } + + cur->buf = base; + } + + return 0; +} + +/* + * NameConstraints ::= SEQUENCE { + * permittedSubtrees [0] GeneralSubtrees OPTIONAL, + * excludedSubtrees [1] GeneralSubtrees OPTIONAL } + * + * RFC 5280 section 4.2.1.10: at least one of the two must be present. + */ +static int x509_get_name_constraints(unsigned char **p, + const unsigned char *end, + mbedtls_x509_sequence *permitted, + mbedtls_x509_sequence *excluded) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len; + + if ((ret = mbedtls_asn1_get_tag(p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + if (*p + len != end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + if (*p == end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_INVALID_LENGTH); + } + + ret = mbedtls_asn1_get_tag(p, end, &len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_X509_NAME_CONST_INCL); + if (ret == 0) { + if ((ret = x509_get_general_subtrees(p, *p + len, permitted)) != 0) { + return ret; + } + } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + if (*p < end) { + if ((ret = mbedtls_asn1_get_tag(p, end, &len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_X509_NAME_CONST_EXCL)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + if ((ret = x509_get_general_subtrees(p, *p + len, excluded)) != 0) { + return ret; + } + } + + if (*p != end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + return 0; +} + /* * SubjectKeyIdentifier ::= KeyIdentifier * @@ -980,6 +1168,15 @@ static int x509_get_crt_ext(unsigned char **p, } break; + case MBEDTLS_X509_EXT_NAME_CONSTRAINTS: + /* Parse name constraints */ + if ((ret = x509_get_name_constraints(p, end_ext_octet, + &crt->name_constraints_incl, + &crt->name_constraints_excl)) != 0) { + return ret; + } + break; + case MBEDTLS_X509_EXT_KEY_USAGE: /* Parse key usage */ if ((ret = mbedtls_x509_get_key_usage(p, end_ext_octet, @@ -1674,6 +1871,57 @@ cleanup: #endif /* MBEDTLS_FS_IO */ #if !defined(MBEDTLS_X509_REMOVE_INFO) +/* + * Like mbedtls_x509_info_subject_alt_name(), but for the subtrees of a Name + * Constraints extension, where an iPAddress is an address and a mask. + */ +static int x509_info_general_subtrees(char **buf, size_t *size, + const mbedtls_x509_sequence *subtrees, + const char *prefix) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t i, half; + size_t n = *size; + char *p = *buf; + const mbedtls_x509_sequence *cur; + mbedtls_x509_sequence single; + + for (cur = subtrees; cur != NULL; cur = cur->next) { + if ((cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) != MBEDTLS_X509_SAN_IP_ADDRESS) { + single.buf = cur->buf; + single.next = NULL; + if ((ret = mbedtls_x509_info_subject_alt_name(&p, &n, &single, prefix)) != 0) { + return ret; + } + continue; + } + + ret = mbedtls_snprintf(p, n, "\n%s iPAddress : ", prefix); + MBEDTLS_X509_SAFE_SNPRINTF; + + /* address, then mask */ + half = cur->buf.len / 2; + for (i = 0; i < cur->buf.len; i++) { + if (half == 4) { + ret = mbedtls_snprintf(p, n, "%s%u", + i == 0 ? "" : i == half ? "/" : ".", + cur->buf.p[i]); + } else { + ret = mbedtls_snprintf(p, n, "%s%02X", + i == 0 ? "" : i == half ? "/" : + i % 2 == 0 ? ":" : "", + cur->buf.p[i]); + } + MBEDTLS_X509_SAFE_SNPRINTF; + } + } + + *size = n; + *buf = p; + + return 0; +} + #define PRINT_ITEM(i) \ do { \ ret = mbedtls_snprintf(p, n, "%s" i, sep); \ @@ -1880,6 +2128,29 @@ int mbedtls_x509_crt_info(char *buf, size_t size, const char *prefix, } } + if (crt->ext_types & MBEDTLS_X509_EXT_NAME_CONSTRAINTS) { + ret = mbedtls_snprintf(p, n, "\n%sname constraints :", prefix); + MBEDTLS_X509_SAFE_SNPRINTF; + + if (crt->name_constraints_incl.buf.p != NULL) { + ret = mbedtls_snprintf(p, n, "\n%s permitted :", prefix); + MBEDTLS_X509_SAFE_SNPRINTF; + if ((ret = x509_info_general_subtrees(&p, &n, &crt->name_constraints_incl, + prefix)) != 0) { + return ret; + } + } + + if (crt->name_constraints_excl.buf.p != NULL) { + ret = mbedtls_snprintf(p, n, "\n%s excluded :", prefix); + MBEDTLS_X509_SAFE_SNPRINTF; + if ((ret = x509_info_general_subtrees(&p, &n, &crt->name_constraints_excl, + prefix)) != 0) { + return ret; + } + } + } + if (crt->ext_types & MBEDTLS_X509_EXT_CERTIFICATE_POLICIES) { ret = mbedtls_snprintf(p, n, "\n%scertificate policies : ", prefix); MBEDTLS_X509_SAFE_SNPRINTF; @@ -2991,6 +3262,340 @@ static void x509_crt_verify_name(const mbedtls_x509_crt *crt, *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; } +/* + * Name Constraints, RFC 5280 sections 4.2.1.10 and 6.1. + * + * The match functions below return 0 if the name is within the subtree, + * X509_NC_NO_MATCH if it isn't and X509_NC_UNSUPPORTED if it can't be + * decided. Names that can't be decided are treated as violations, as RFC 5280 + * requires for constraints that the application doesn't process. + */ +#define X509_NC_NO_MATCH -1 +#define X509_NC_UNSUPPORTED -2 + +/* + * dNSName: "example.com" matches example.com and every name below it, + * ".example.com" only the names below it, and an empty base matches every + * name. Case-insensitive. A wildcard name such as "*.example.com" is + * compared as is, so it only matches if every name it stands for does. + */ +static int x509_nc_dns_match(const unsigned char *name, size_t name_len, + const unsigned char *base, size_t base_len) +{ + if (base_len == 0) { + return 0; + } + + if (name_len < base_len || + x509_memcasecmp(name + name_len - base_len, base, base_len) != 0) { + return X509_NC_NO_MATCH; + } + + if (base[0] == '.') { + return name_len > base_len ? 0 : X509_NC_NO_MATCH; + } + + if (name_len == base_len || name[name_len - base_len - 1] == '.') { + return 0; + } + + return X509_NC_NO_MATCH; +} + +/* + * Like x509_nc_dns_match(), but a wildcard name also matches if any name it + * stands for (see x509_check_wildcard()) is within the subtree. Used for + * excludedSubtrees. + */ +static int x509_nc_dns_match_any(const unsigned char *name, size_t name_len, + const unsigned char *base, size_t base_len) +{ + size_t domain_len; + + if (x509_nc_dns_match(name, name_len, base, base_len) == 0) { + return 0; + } + + if (name_len < 3 || name[0] != '*' || name[1] != '.' || base[0] == '.') { + return X509_NC_NO_MATCH; + } + + /* "*.example.com" can be "bad.example.com", one label to the left */ + domain_len = name_len - 1; + if (base_len > domain_len && + x509_memcasecmp(base + base_len - domain_len, name + 1, domain_len) == 0 && + memchr(base, '.', base_len - domain_len) == NULL) { + return 0; + } + + return X509_NC_NO_MATCH; +} + +/* + * rfc822Name: "user@example.com" matches that mailbox, "example.com" every + * mailbox on that host and ".example.com" every mailbox on a host below it. + * The local part is case-sensitive, the host isn't. + */ +static int x509_nc_email_match(const unsigned char *name, size_t name_len, + const unsigned char *base, size_t base_len) +{ + size_t at; + const unsigned char *host; + size_t host_len; + + for (at = name_len; at > 0 && name[at - 1] != '@'; at--) { + ; + } + if (at == 0) { + return X509_NC_UNSUPPORTED; + } + host = name + at; + host_len = name_len - at; + + if (base_len == 0) { + return 0; + } + + if (memchr(base, '@', base_len) != NULL) { + size_t base_at = (const unsigned char *) memchr(base, '@', base_len) - base + 1; + + return base_at == at && memcmp(name, base, at) == 0 && + host_len == base_len - base_at && + x509_memcasecmp(host, base + base_at, host_len) == 0 ? 0 : X509_NC_NO_MATCH; + } + + if (base[0] == '.') { + return host_len > base_len && + x509_memcasecmp(host + host_len - base_len, base, base_len) == 0 ? + 0 : X509_NC_NO_MATCH; + } + + return host_len == base_len && + x509_memcasecmp(host, base, base_len) == 0 ? 0 : X509_NC_NO_MATCH; +} + +/* + * iPAddress: the base is an address followed by a mask of the same length. + */ +static int x509_nc_ip_match(const mbedtls_x509_buf *name, const mbedtls_x509_buf *base) +{ + size_t i; + + if (base->len != 2 * name->len) { + return X509_NC_NO_MATCH; + } + + for (i = 0; i < name->len; i++) { + if (((name->p[i] ^ base->p[i]) & base->p[name->len + i]) != 0) { + return X509_NC_NO_MATCH; + } + } + + return 0; +} + +/* + * Parse the Name in the content of a directoryName GeneralName. + * The caller must free dn->next with mbedtls_asn1_free_named_data_list_shallow(). + */ +static int x509_nc_get_dn(const mbedtls_x509_buf *buf, mbedtls_x509_name *dn) +{ + unsigned char *p = buf->p; + size_t len; + + memset(dn, 0, sizeof(*dn)); + if (mbedtls_asn1_get_tag(&p, buf->p + buf->len, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0 || + mbedtls_x509_get_name(&p, p + len, dn) != 0) { + return X509_NC_UNSUPPORTED; + } + + return 0; +} + +/* + * directoryName: the base must be a prefix of the name, comparing RDNs like + * x509_name_cmp(). + */ +static int x509_nc_dn_match(const mbedtls_x509_name *name, const mbedtls_x509_buf *base_buf) +{ + int ret = 0; + mbedtls_x509_name base_dn; + const mbedtls_x509_name *base = &base_dn; + + if (x509_nc_get_dn(base_buf, &base_dn) != 0) { + mbedtls_asn1_free_named_data_list_shallow(base_dn.next); + return X509_NC_UNSUPPORTED; + } + + for (; base != NULL && ret == 0; base = base->next, name = name->next) { + if (name == NULL || + name->oid.tag != base->oid.tag || + name->oid.len != base->oid.len || + memcmp(name->oid.p, base->oid.p, base->oid.len) != 0 || + x509_string_cmp(&name->val, &base->val) != 0 || + name->next_merged != base->next_merged) { + ret = X509_NC_NO_MATCH; + } + } + + mbedtls_asn1_free_named_data_list_shallow(base_dn.next); + return ret; +} + +/* + * Match a name of the given form (MBEDTLS_X509_SAN_xxx) against a subtree + * base. For a directoryName, dn is the name and buf is unused. + */ +static int x509_nc_match(int form, const mbedtls_x509_buf *name, + const mbedtls_x509_name *dn, + const mbedtls_x509_buf *base, int excluded) +{ + switch (form) { + case MBEDTLS_X509_SAN_DNS_NAME: + return excluded ? + x509_nc_dns_match_any(name->p, name->len, base->p, base->len) : + x509_nc_dns_match(name->p, name->len, base->p, base->len); + case MBEDTLS_X509_SAN_RFC822_NAME: + return x509_nc_email_match(name->p, name->len, base->p, base->len); + case MBEDTLS_X509_SAN_IP_ADDRESS: + return x509_nc_ip_match(name, base); + case MBEDTLS_X509_SAN_DIRECTORY_NAME: + return x509_nc_dn_match(dn, base); + default: + return X509_NC_UNSUPPORTED; + } +} + +/* + * Check one name of a certificate against the Name Constraints of a CA. + * Return 0 if the name is allowed, -1 otherwise. + */ +static int x509_nc_check_name(const mbedtls_x509_crt *ca, int form, + const mbedtls_x509_buf *name, + const mbedtls_x509_name *dn) +{ + const mbedtls_x509_sequence *cur; + int has_permitted = 0; + + for (cur = &ca->name_constraints_excl; cur != NULL && cur->buf.p != NULL; + cur = cur->next) { + if ((cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) == form && + x509_nc_match(form, name, dn, &cur->buf, 1) != X509_NC_NO_MATCH) { + return -1; + } + } + + for (cur = &ca->name_constraints_incl; cur != NULL && cur->buf.p != NULL; + cur = cur->next) { + if ((cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) == form) { + if (x509_nc_match(form, name, dn, &cur->buf, 0) == 0) { + return 0; + } + has_permitted = 1; + } + } + + return has_permitted ? -1 : 0; +} + +/* + * Check all names of a certificate against the Name Constraints of a CA: + * the subject (as a directoryName, and its emailAddress attributes as + * rfc822Names) and every subjectAltName. Names of a form the CA constrains + * but that can't be checked here are rejected. + * + * x509_crt_verify_name() matches the CN of an end-entity certificate + * without subjectAltName against the expected hostname, so such CNs are + * checked as dNSNames. + * + * Return 0 if all names are allowed, -1 otherwise. + */ +static int x509_crt_check_name_constraints(const mbedtls_x509_crt *crt, + const mbedtls_x509_crt *ca, + int is_end_entity) +{ + const mbedtls_x509_name *name; + const mbedtls_x509_sequence *cur; + mbedtls_x509_name dn; + int ret; + + if (crt->subject.oid.p != NULL && + x509_nc_check_name(ca, MBEDTLS_X509_SAN_DIRECTORY_NAME, NULL, &crt->subject) != 0) { + return -1; + } + + for (name = &crt->subject; name != NULL; name = name->next) { + if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS9_EMAIL, &name->oid) == 0 && + x509_nc_check_name(ca, MBEDTLS_X509_SAN_RFC822_NAME, &name->val, NULL) != 0) { + return -1; + } + + if (is_end_entity && + (crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) == 0 && + MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0 && + x509_nc_check_name(ca, MBEDTLS_X509_SAN_DNS_NAME, &name->val, NULL) != 0) { + return -1; + } + } + + if ((crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) == 0) { + return 0; + } + + for (cur = &crt->subject_alt_names; cur != NULL; cur = cur->next) { + int form = cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK; + + if (form != MBEDTLS_X509_SAN_DIRECTORY_NAME) { + ret = x509_nc_check_name(ca, form, &cur->buf, NULL); + } else if (x509_nc_get_dn(&cur->buf, &dn) == 0) { + ret = x509_nc_check_name(ca, form, NULL, &dn); + } else { + ret = -1; + } + + if (form == MBEDTLS_X509_SAN_DIRECTORY_NAME) { + mbedtls_asn1_free_named_data_list_shallow(dn.next); + } + + if (ret != 0) { + return -1; + } + } + + return 0; +} + +/* + * Apply the Name Constraints of every CA in the chain to all certificates + * below it, except self-issued intermediate certificates. + * Violations are flagged on the constrained certificate. + */ +static void x509_crt_verify_name_constraints(mbedtls_x509_crt_verify_chain *ver_chain) +{ + unsigned i, j; + const mbedtls_x509_crt *ca; + const mbedtls_x509_crt *child; + + for (i = 1; i < ver_chain->len; i++) { + ca = ver_chain->items[i].crt; + if ((ca->ext_types & MBEDTLS_X509_EXT_NAME_CONSTRAINTS) == 0) { + continue; + } + + for (j = 0; j < i; j++) { + child = ver_chain->items[j].crt; + if (j != 0 && x509_name_cmp(&child->issuer, &child->subject) == 0) { + continue; + } + + if (x509_crt_check_name_constraints(child, ca, j == 0) != 0) { + ver_chain->items[j].flags |= MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS; + } + } + } +} + /* * Merge the flags for all certs in the chain, after calling callback */ @@ -3091,6 +3696,9 @@ static int x509_crt_verify_restartable_ca_cb(mbedtls_x509_crt *crt, goto exit; } + /* Check the Name Constraints of the CAs in the chain */ + x509_crt_verify_name_constraints(&ver_chain); + /* Merge end-entity flags */ ver_chain.items[0].flags |= ee_flags; @@ -3224,6 +3832,8 @@ void mbedtls_x509_crt_free(mbedtls_x509_crt *crt) mbedtls_asn1_free_named_data_list_shallow(cert_cur->subject.next); mbedtls_asn1_sequence_free(cert_cur->ext_key_usage.next); mbedtls_asn1_sequence_free(cert_cur->subject_alt_names.next); + mbedtls_asn1_sequence_free(cert_cur->name_constraints_incl.next); + mbedtls_asn1_sequence_free(cert_cur->name_constraints_excl.next); mbedtls_asn1_sequence_free(cert_cur->certificate_policies.next); mbedtls_asn1_sequence_free(cert_cur->authority_key_id.authorityCertIssuer.next); diff --git a/library/x509_oid.c b/library/x509_oid.c index 8c67cdfa1c..a3c98a7266 100644 --- a/library/x509_oid.c +++ b/library/x509_oid.c @@ -322,6 +322,12 @@ static const oid_x509_ext_t oid_x509_ext[] = "Authority Key Identifier"), MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER, }, + { + OID_DESCRIPTOR(MBEDTLS_OID_NAME_CONSTRAINTS, + "id-ce-nameConstraints", + "Name Constraints"), + MBEDTLS_X509_EXT_NAME_CONSTRAINTS, + }, { NULL_OID_DESCRIPTOR, 0, diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index a53790f281..28c5f072df 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -170,6 +170,10 @@ X509 CRT information, ECDSA Certificate unsupported policy depends_on:MBEDTLS_PEM_PARSE_C:PSA_HAVE_ALG_SOME_ECDSA:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_256 x509_cert_info:"../framework/data_files/parse_input/test-ca-unsupported_policy_ec.crt":"cert. version \: 3\nserial number \: 00\nissuer name \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nsubject name \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nissued on \: 2019-04-28 13\:00\:19\nexpires on \: 2029-04-28 13\:00\:19\nsigned using \: ECDSA with SHA256\nEC key size \: 384 bits\nbasic constraints \: CA=true\ncertificate policies \: ???\n" +X509 CRT information, ECDSA Certificate name constraints with DNSName +depends_on:MBEDTLS_PEM_PARSE_C:PSA_HAVE_ALG_SOME_ECDSA:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_256 +x509_cert_info:"../framework/data_files/parse_input/test-ca-name_constraints_dns_ec.crt":"cert. version \: 3\nserial number \: 00\nissuer name \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nsubject name \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nissued on \: 2025-01-10 16\:45\:33\nexpires on \: 2035-01-11 16\:45\:33\nsigned using \: ECDSA with SHA256\nEC key size \: 384 bits\nbasic constraints \: CA=true\nname constraints \:\n permitted \:\n dNSName \: .example.com\n excluded \:\n dNSName \: .bad.example.com\n" + X509 CRT information, Key Usage + Extended Key Usage depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 x509_cert_info:"../framework/data_files/parse_input/server1.ext_ku.crt":"cert. version \: 3\nserial number \: 21\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nissued on \: 2014-04-01 14\:44\:43\nexpires on \: 2024-03-29 14\:44\:43\nsigned using \: RSA with SHA-256\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\nkey usage \: Digital Signature, Non Repudiation, Key Encipherment\next key usage \: TLS Web Server Authentication\n" @@ -198,6 +202,10 @@ X509 SAN parsing otherName depends_on:PSA_HAVE_ALG_SOME_ECDSA:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 x509_parse_san:"../framework/data_files/parse_input/server5-othername.crt.der":"type \: 0\notherName \: hardware module name \: hardware type \: 1.3.6.1.4.1.17.3, hardware serial number \: 313233343536\n":0 +X509 SAN parsing BP EID otherName +depends_on:PSA_HAVE_ALG_SOME_ECDSA:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +x509_parse_san:"../framework/data_files/parse_input/server5-bp_eid.crt.der":"type \: 0\notherName \: BundleEID \: ipn\:977000.100.0\n":0 + X509 SAN parsing binary otherName depends_on:PSA_HAVE_ALG_SOME_ECDSA:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 x509_parse_san:"../framework/data_files/parse_input/server5-nonprintable_othername.crt.der":"type \: 0\notherName \: hardware module name \: hardware type \: 1.3.6.1.4.1.17.3, hardware serial number \: 3132338081008180333231\n":0 @@ -228,7 +236,7 @@ x509_parse_san:"../framework/data_files/parse_input/server4.crt":"":0 X509 SAN parsing, unsupported otherName name depends_on:PSA_HAVE_ALG_SOME_ECDSA:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -x509_parse_san:"../framework/data_files/parse_input/server5-unsupported_othername.crt.der":"":0 +x509_parse_san:"../framework/data_files/parse_input/server5-unsupported_othername.crt.der":"type \: 0\notherName \: raw \: type-id \: 1.2.3.4 value \: 736F6D65206F74686572206964656E746966696572\n":0 X509 SAN parsing rfc822Name depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 @@ -1027,6 +1035,138 @@ X509 CRT verification #99 (Revoked Cert, revocation date in the future, _without depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_1:PSA_HAVE_ALG_SOME_RSA_VERIFY:!MBEDTLS_HAVE_TIME_DATE x509_verify:"../framework/data_files/server1.crt":"../framework/data_files/test-ca.crt":"../framework/data_files/crl-futureRevocationDate.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_REVOKED:"compat":"NULL" +X509 CRT verification: Name Constraints, dNSName permitted, real-world CA +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-ok.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"input-sibox-1-a.encoder.dev.cdn.dszn.cz":0:0:"":"NULL" + +X509 CRT verification: Name Constraints, dNSName permitted, case-insensitive +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-case.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":0:0:"":"NULL" + +X509 CRT verification: Name Constraints, dNSName not permitted +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-bad.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, dNSName not permitted, matching suffix but not label +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-suffix.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, dNSName leading dot, subdomain +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-dot-ok.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":0:0:"":"NULL" + +X509 CRT verification: Name Constraints, dNSName leading dot, domain itself +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-dot-bad.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, dNSName excluded wins over permitted +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-excl.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, dNSName wildcard within permitted +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-wild-ok.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":0:0:"":"NULL" + +X509 CRT verification: Name Constraints, dNSName wildcard covering excluded +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-wild-bad.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, no SAN, CN permitted +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-cn-ok.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"www.dszn.cz":0:0:"":"NULL" + +X509 CRT verification: Name Constraints, no SAN, CN not permitted +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-cn-bad.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, dNSName permitted, unconstrained iPAddress +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-ip.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":0:0:"":"NULL" + +X509 CRT verification: Name Constraints, non-critical, permitted +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dnsnc-ok.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":0:0:"":"NULL" + +X509 CRT verification: Name Constraints, non-critical, not permitted +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dnsnc-bad.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, iPAddress permitted, IPv4 and IPv6 +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-ip-ok.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":0:0:"":"NULL" + +X509 CRT verification: Name Constraints, iPAddress not permitted, IPv4 +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-ip-bad4.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, iPAddress not permitted, IPv6 +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-ip-bad6.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, iPAddress excluded +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-ip-excl.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, rfc822Name permitted +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-email-ok.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":0:0:"":"NULL" + +X509 CRT verification: Name Constraints, rfc822Name host not in subdomain constraint +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-email-bad.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, rfc822Name excluded +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-email-excl.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, emailAddress in subject not permitted +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-email-subj.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, directoryName permitted +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dirname-ok.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":0:0:"":"NULL" + +X509 CRT verification: Name Constraints, directoryName not permitted +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dirname-bad.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, directoryName excluded +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dirname-excl.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, directoryName SAN not permitted +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dirname-san-bad.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, URI constrained, no URI in certificate +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-uri-dns.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":0:0:"":"NULL" + +X509 CRT verification: Name Constraints, URI constrained, unsupported, fail closed +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-uri-bad.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, nested CAs, both permit +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-cdn-ok.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":0:0:"":"NULL" + +X509 CRT verification: Name Constraints, nested CAs, outer CA forbids +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-cdn-bad-outer.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, nested CAs, inner CA forbids +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-cdn-bad-inner.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:"":"NULL" + +X509 CRT verification: Name Constraints, wrong hostname is still reported +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-ok.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"www.example.net":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_CN_MISMATCH:"":"NULL" + +X509 CRT verification: Name Constraints, violation and wrong hostname +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify:"../framework/data_files/nc-dns-bad.crt":"../framework/data_files/nc-root.crt":"../framework/data_files/crl-ec-sha256.pem":"www.example.org":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS | MBEDTLS_X509_BADCERT_CN_MISMATCH:"":"NULL" + X509 CRT verification: domain identical to IPv4 in SubjectAltName depends_on:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_256:PSA_HAVE_ALG_SOME_RSA_VERIFY x509_verify:"../framework/data_files/server5-tricky-ip-san.crt.der":"../framework/data_files/server5-tricky-ip-san.crt.der":"../framework/data_files/crl_sha256.pem":"abcd":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_CN_MISMATCH:"":"NULL" @@ -2272,6 +2412,66 @@ X509 CRT ASN1 (TBS, inv v3Ext, SubjectAltName repeated) depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 x509parse_crt:"3081dc3081c6a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D01010105000319003016021100ffffffffffffffffffffffffffffffff020103a100a200a340303e301d0603551d11041630148208666f6f2e7465737482086261722e74657374301d0603551d11041630148208666f6f2e7465737482086261722e74657374300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS +X509 CRT ASN1 (TBS, NameConstraints, all supported forms) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"308201663082014fa0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a381cc3081c93081c60603551d1e0101ff0481bb3081b8a065300d820b6578616d706c652e636f6d300e820c2e6578616d706c652e6e65743012811075736572406578616d706c652e6f7267300a8708c0a80000ffff00003024a4223020310b300906035504060c024e4c3111300f060355040a0c08506f6c617253534ca14f3022872020010db8000000000000000000000000ffffffff000000000000000000000000301281102e6261642e6578616d706c652e6f72673015861368747470733a2f2f6261642e6578616d706c65300d06092a864886f70d01010b0500030200ff":"cert. version \: 3\nserial number \: DE\:AD\:BE\:EF\nissuer name \: ??=Test\nsubject name \: ??=Test\nissued on \: 2009-01-01 00\:00\:00\nexpires on \: 2009-12-31 23\:59\:59\nsigned using \: RSA with SHA-256\nRSA key size \: 128 bits\nname constraints \:\n permitted \:\n dNSName \: example.com\n dNSName \: .example.net\n rfc822Name \: user@example.org\n iPAddress \: 192.168.0.0/255.255.0.0\n directoryName \: C=NL, O=PolarSSL\n excluded \:\n iPAddress \: 2001\:0DB8\:0000\:0000\:0000\:0000\:0000\:0000/FFFF\:FFFF\:0000\:0000\:0000\:0000\:0000\:0000\n rfc822Name \: .bad.example.org\n uniformResourceIdentifier \: https\://bad.example\n":0 + +X509 CRT ASN1 (TBS, NameConstraints, excluded only, not critical) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081b63081a0a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a31e301c301a0603551d1e04133011a10f300d820b6261642e6578616d706c65300d06092a864886f70d01010b0500030200ff":"cert. version \: 3\nserial number \: DE\:AD\:BE\:EF\nissuer name \: ??=Test\nsubject name \: ??=Test\nissued on \: 2009-01-01 00\:00\:00\nexpires on \: 2009-12-31 23\:59\:59\nsigned using \: RSA with SHA-256\nRSA key size \: 128 bits\nname constraints \:\n excluded \:\n dNSName \: bad.example\n":0 + +X509 CRT ASN1 (TBS, NameConstraints, explicit minimum 0) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081bc3081a6a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a324302230200603551d1e0101ff04163014a0123010820b6578616d706c652e636f6d800100300d06092a864886f70d01010b0500030200ff":"cert. version \: 3\nserial number \: DE\:AD\:BE\:EF\nissuer name \: ??=Test\nsubject name \: ??=Test\nissued on \: 2009-01-01 00\:00\:00\nexpires on \: 2009-12-31 23\:59\:59\nsigned using \: RSA with SHA-256\nRSA key size \: 128 bits\nname constraints \:\n permitted \:\n dNSName \: example.com\n":0 + +X509 CRT ASN1 (TBS, NameConstraints, empty) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081a8308192a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a310300e300c0603551d1e0101ff04023000300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_INVALID_LENGTH) + +X509 CRT ASN1 (TBS, NameConstraints, empty permittedSubtrees) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081aa308194a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a3123010300e0603551d1e0101ff04043002a000300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_INVALID_LENGTH) + +X509 CRT ASN1 (TBS, NameConstraints, empty excludedSubtrees) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081aa308194a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a3123010300e0603551d1e0101ff04043002a100300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_INVALID_LENGTH) + +X509 CRT ASN1 (TBS, NameConstraints, empty GeneralSubtree) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081ac308196a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a314301230100603551d1e0101ff04063004a0023000300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_OUT_OF_DATA) + +X509 CRT ASN1 (TBS, NameConstraints, minimum 1) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081bc3081a6a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a324302230200603551d1e0101ff04163014a0123010820b6578616d706c652e636f6d800101300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_INVALID_DATA) + +X509 CRT ASN1 (TBS, NameConstraints, maximum present) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081bc3081a6a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a324302230200603551d1e0101ff04163014a0123010820b6578616d706c652e636f6d810100300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) + +X509 CRT ASN1 (TBS, NameConstraints, iPAddress 4 bytes) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081b230819ca0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a31a301830160603551d1e0101ff040c300aa00830068704c0a80000300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_INVALID_LENGTH) + +X509 CRT ASN1 (TBS, NameConstraints, iPAddress 16 bytes) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081be3081a8a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a326302430220603551d1e0101ff04183016a0143012871020010db8000000000000000000000000300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_INVALID_LENGTH) + +X509 CRT ASN1 (TBS, NameConstraints, base not context-specific) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081b93081a3a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a321301f301d0603551d1e0101ff04133011a00f300d160b6578616d706c652e636f6d300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) + +X509 CRT ASN1 (TBS, NameConstraints, excluded before permitted) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081c63081b0a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a32e302c302a0603551d1e0101ff0420301ea10d300b8209612e6578616d706c65a00d300b8209622e6578616d706c65300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) + +X509 CRT ASN1 (TBS, NameConstraints, trailing data) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081b93081a3a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a321301f301d0603551d1e0101ff04133011a00d300b8209612e6578616d706c650500300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) + +X509 CRT ASN1 (TBS, NameConstraints, not a SEQUENCE) +depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3081b73081a1a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d01010105000319003016021100ffffffffffffffffffffffffffffffff020103a31f301d301b0603551d1e0101ff0411310fa00d300b8209612e6578616d706c65300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) + X509 CRT ASN1 (TBS, inv v3Ext, ExtKeyUsage repeated) depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256 x509parse_crt:"3081dc3081c6a0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D01010105000319003016021100ffffffffffffffffffffffffffffffff020103a100a200a340303e301d0603551d250416301406082b0601050507030106082b06010505070302301d0603551d250416301406082b0601050507030106082b06010505070302300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS @@ -3414,6 +3614,18 @@ X509 CRT verify restart: one int, int badsign, max_ops=500 depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384:PSA_HAVE_ALG_SOME_RSA_VERIFY x509_verify_restart:"../framework/data_files/server10_int3-bs.pem":"../framework/data_files/test-int-ca2.crt":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NOT_TRUSTED:500:25:100 +X509 CRT verify restart: Name Constraints violation, max_ops=0 (disabled) +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify_restart:"../framework/data_files/nc-dns-bad.crt":"../framework/data_files/nc-root.crt":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:0:0:0 + +X509 CRT verify restart: Name Constraints violation, max_ops=500 +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify_restart:"../framework/data_files/nc-dns-bad.crt":"../framework/data_files/nc-root.crt":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NAME_CONSTRAINTS:500:1:1000 + +X509 CRT verify restart: Name Constraints satisfied, max_ops=500 +depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 +x509_verify_restart:"../framework/data_files/nc-dns-ok.crt":"../framework/data_files/nc-root.crt":0:0:500:1:1000 + X509 ext types accessor: ext type present depends_on:MBEDTLS_X509_CRT_PARSE_C x509_accessor_ext_types:MBEDTLS_X509_EXT_KEY_USAGE:MBEDTLS_X509_EXT_KEY_USAGE diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index d59fc2b2e2..fc4d3153fd 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -274,8 +274,42 @@ static int verify_parse_san(mbedtls_x509_subject_alternative_name *san, san->san.other_name.value.hardware_module_name.val.p[i]); MBEDTLS_X509_SAFE_SNPRINTF; } + }/* MBEDTLS_OID_ON_HW_MODULE_NAME */ + else if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_BUNDLE_EID, + &san->san.other_name.type_id) == 0) { + int len = 0; + const char *str = NULL; + if (san->san.other_name.value.raw.tag == MBEDTLS_ASN1_IA5_STRING) { + len = san->san.other_name.value.raw.len; + str = (char*)san->san.other_name.value.raw.p; + } + + ret = mbedtls_snprintf(p, n, " BundleEID : %.*s", len, str); + MBEDTLS_X509_SAFE_SNPRINTF; + }/* MBEDTLS_OID_ON_BUNDLE_EID */ + else { + ret = mbedtls_snprintf(p, n, " raw :"); + MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_snprintf(p, n, " type-id : "); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_oid_get_numeric_string(p, + n, + &san->san.other_name.type_id); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_snprintf(p, n, " value : "); + MBEDTLS_X509_SAFE_SNPRINTF; + + for (i = 0; i < san->san.other_name.value.raw.len; i++) { + ret = mbedtls_snprintf(p, + n, + "%02X", + san->san.other_name.value.raw.p[i]); + MBEDTLS_X509_SAFE_SNPRINTF; + } } - break;/* MBEDTLS_OID_ON_HW_MODULE_NAME */ + break;/* MBEDTLS_X509_SAN_OTHER_NAME */ case (MBEDTLS_X509_SAN_DNS_NAME): ret = mbedtls_snprintf(p, n, "\ndNSName : "); MBEDTLS_X509_SAFE_SNPRINTF;