mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2026-10-28 18:07:34 +08:00
Merge 26dc074328d9bdbfc206285e70cc7c5f6aec509e into 03e1438089654fb884ac48e0f3cd0049cfe2c102
This commit is contained in:
commit
d937fe556f
18
ChangeLog.d/register-name-constraints.txt
Normal file
18
ChangeLog.d/register-name-constraints.txt
Normal file
@ -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().
|
||||
@ -1 +1 @@
|
||||
Subproject commit ced31491c5ec907a6be533512f19dc1779230ac1
|
||||
Subproject commit aefd6fb35097b00259c2ebdb181dff88cfa9ee14
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
128
library/x509.c
128
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;
|
||||
/*
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user