Merge pull request #11011 from v1rtu3x/fix-x509-basic-constraints-integer-first-3.6

Fix x509 basic constraints integer first 3.6
This commit is contained in:
Gilles Peskine 2026-10-21 15:07:35 +00:00 committed by GitHub
commit e7bbfb86ff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 52 additions and 7 deletions

View File

@ -0,0 +1,5 @@
Bugfix
* Accept a basicConstraints extension that omits cA and contains only
pathLenConstraint, interpreting it as cA=FALSE as specified by RFC 5280.
This restores compatibility with certificates emitted by some devices
without accepting them as CA certificates. Fixes #11006.

View File

@ -519,17 +519,19 @@ static int x509_get_basic_constraints(unsigned char **p,
}
if ((ret = mbedtls_asn1_get_bool(p, end, ca_istrue)) != 0) {
/* If the SEQUENCE starts with an INTEGER and not a BOOLEAN,
* according to RFC 5280, it's syntactically valid, but it's
* something that a CA MUST NOT produce. So we reject it.
/* cA is DEFAULT FALSE. If it is absent, the first element must
* be pathLenConstraint. Keep cA false and let the INTEGER parser
* below validate the element.
*
* Note: historically, from XySSL 0.9 to Mbed TLS 3.6.6/4.1.0,
* `SEQUENCE { INTEGER n }` was interpreted as cA=FALSE if n == 0
* and cA=TRUE if n != 0. This was dangerous since
* `SEQUENCE { INTEGER n }` should be parsed as cA=FALSE
* according to RFC 5280, so we stopped doing it.
* according to RFC 5280.
*/
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
}
}
/* `SEQUENCE { BOOLEAN FALSE }` is not DER since default-value fields
* must be omitted in DER. But it seems harmless, and Mbed TLS has

View File

@ -2070,11 +2070,27 @@ mbedtls_x509_crt_parse_file:"../framework/data_files/parse_input/server5.basic-c
X509 CRT ASN1: basicConstraints: no cA but pathLenConstraint (bad signature)
depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
mbedtls_x509_crt_parse_file:"../framework/data_files/parse_input/server5.basic-constraints-integer-first.badsign.crt":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG):0
mbedtls_x509_crt_parse_file:"../framework/data_files/parse_input/server5.basic-constraints-integer-first.badsign.crt":0:1
X509 CRT ASN1: basicConstraints: no cA, pathLenConstraint=1
depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
mbedtls_x509_get_ca_istrue:"../framework/data_files/parse_input/server5.basic-constraints-integer-first.badsign.crt":0
X509 CRT ASN1: basicConstraints: no cA but pathLenConstraint (good self signature)
depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
mbedtls_x509_crt_parse_file:"../framework/data_files/parse_input/server5.basic-constraints-integer-first.selfsigned.crt":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG):0
mbedtls_x509_crt_parse_file:"../framework/data_files/parse_input/server5.basic-constraints-integer-first.selfsigned.crt":0:1
X509 CRT ASN1: basicConstraints: no cA but pathLenConstraint=0
depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
x509_crt_parse_basic_constraints:"308201573081fea003020102020c53a2cb4b124ead837da894b2300a06082a8648ce3d040302300e310c300a06035504030c03457665301e170d3236303531323039353330345a170d3336303531323039353330345a300e310c300a06035504030c034576653059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa3423040300f0603551d130101ff04053003020100300e0603551d0f0101ff040403020780301d0603551d0e041604145061a58fd407d9d782010ce5657f8c6346a713be300a06082a8648ce3d0403020348003045022100d67d572af0aa540cd0f9d86d43788c178ca9501d8c0f4f6690c773f4b82c4b9a022011620feee62aca3944b8321636849030014ef80604550031312bb707b7f2bf04":0:0:0
X509 CRT ASN1: basicConstraints: invalid cA BOOLEAN length
depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
x509_crt_parse_basic_constraints:"308201573081fea003020102020c53a2cb4b124ead837da894b2300a06082a8648ce3d040302300e310c300a06035504030c03457665301e170d3236303531323039353330345a170d3336303531323039353330345a300e310c300a06035504030c034576653059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa3423040300f0603551d130101ff040530030100ff300e0603551d0f0101ff040403020780301d0603551d0e041604145061a58fd407d9d782010ce5657f8c6346a713be300a06082a8648ce3d0403020348003045022100d67d572af0aa540cd0f9d86d43788c178ca9501d8c0f4f6690c773f4b82c4b9a022011620feee62aca3944b8321636849030014ef80604550031312bb707b7f2bf04":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_INVALID_LENGTH):0:0
X509 CRT ASN1: basicConstraints: neither cA nor pathLenConstraint
depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
x509_crt_parse_basic_constraints:"308201573081fea003020102020c53a2cb4b124ead837da894b2300a06082a8648ce3d040302300e310c300a06035504030c03457665301e170d3236303531323039353330345a170d3336303531323039353330345a300e310c300a06035504030c034576653059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa3423040300f0603551d130101ff04053003050100300e0603551d0f0101ff040403020780301d0603551d0e041604145061a58fd407d9d782010ce5657f8c6346a713be300a06082a8648ce3d0403020348003045022100d67d572af0aa540cd0f9d86d43788c178ca9501d8c0f4f6690c773f4b82c4b9a022011620feee62aca3944b8321636849030014ef80604550031312bb707b7f2bf04":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG):0:0
X509 CRT ASN1 (TBS, inv extBasicConstraint, no pathlen length)
depends_on:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA256

View File

@ -1121,6 +1121,28 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
void x509_crt_parse_basic_constraints(data_t *buf, int result,
int ca_istrue, int path_len_constraint)
{
mbedtls_x509_crt crt;
mbedtls_x509_crt_init(&crt);
USE_PSA_INIT();
TEST_EQUAL(mbedtls_x509_crt_parse_der(&crt, buf->x, buf->len), result);
if (result == 0) {
TEST_EQUAL(mbedtls_x509_crt_get_ca_istrue(&crt), ca_istrue);
/* max_pathlen is 1 higher than pathLenConstraint. */
TEST_EQUAL(crt.max_pathlen, path_len_constraint + 1);
}
exit:
mbedtls_x509_crt_free(&crt);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
void x509parse_crt(data_t *buf, char *result_str, int result)
{