From 6c9478b2ed406da8ae3aa836fb05b59892be49e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BCller?= Date: Sat, 26 Sep 2026 10:27:10 +0200 Subject: [PATCH 1/3] x509_crt: accept empty AuthorityKeyIdentifier sequence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All fields of AuthorityKeyIdentifier are OPTIONAL, so an empty SEQUENCE (30 00) is syntactically valid. It was rejected with MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_OUT_OF_DATA, because mbedtls_asn1_get_tag() reports OUT_OF_DATA rather than UNEXPECTED_TAG when there is nothing left to parse. Check for the empty sequence explicitly instead of treating OUT_OF_DATA as an absent keyIdentifier: OUT_OF_DATA is also returned for a [0] tag with a missing or truncated length, which must still be rejected. Fixes #10253. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Christopher Müller --- library/x509_crt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/x509_crt.c b/library/x509_crt.c index a6fcd1b4e6..2309e37de0 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -638,6 +638,11 @@ static int x509_get_authority_key_id(unsigned char **p, MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); } + /* All fields are OPTIONAL, so an empty SEQUENCE is valid. */ + if (*p == end) { + return 0; + } + ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONTEXT_SPECIFIC); From 10e40b70add1b11918eb7366c2125d33d198f892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BCller?= Date: Sat, 26 Sep 2026 10:27:11 +0200 Subject: [PATCH 2/3] tests: x509parse: add empty and truncated AuthorityKeyIdentifier tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An empty AuthorityKeyIdentifier SEQUENCE must parse. A [0] tag without a length must still be rejected; that case already passed before the fix and guards against loosening the check too much. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Christopher Müller --- tests/suites/test_suite_x509parse.data | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index 6a8e30f524..855139e76a 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -3471,6 +3471,30 @@ X509 CRT parse Authority Key Id - Wrong Issuer sequence depends_on:PSA_WANT_ALG_MD5:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY x509_crt_parse_authoritykeyid:"../framework/data_files/clusterfuzz-testcase-minimized-fuzz_x509crt-6666050834661376.crt.der":"":"":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_OUT_OF_DATA) +# Self-signed certificate whose AuthorityKeyIdentifier is an empty SEQUENCE (30 00). +# All fields of AuthorityKeyIdentifier are OPTIONAL in the ASN.1 module (RFC 5280, +# Appendix A.2), so this is syntactically valid; some antivirus products install +# such a root for HTTPS scanning. Generated with Python cryptography: +# key = ec.generate_private_key(ec.SECP256R1()) +# name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "Test")]) +# cert = (x509.CertificateBuilder().subject_name(name).issuer_name(name) +# .public_key(key.public_key()).serial_number(1) +# .not_valid_before(datetime.datetime(2025, 1, 1)) +# .not_valid_after(datetime.datetime(2035, 1, 1)) +# .add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True) +# .add_extension(x509.UnrecognizedExtension(ObjectIdentifier("2.5.29.35"), +# b"\x30\x00"), critical=False) +# .sign(key, hashes.SHA256())) +X509 CRT parse Authority Key Id - Empty sequence +depends_on:PSA_HAVE_ALG_SOME_ECDSA:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3082012b3081d1a003020102020101300a06082a8648ce3d040302300f310d300b06035504030c0454657374301e170d3235303130313030303030305a170d3335303130313030303030305a300f310d300b06035504030c04546573743059301306072a8648ce3d020106082a8648ce3d03010703420004f8cf6bd9eb57f5fdc8771103e9f75becb6a865b1a5de8492b3233170f49e1ff388d25d24376d130c86a8acb5b0478d7c49b83f07ffbd0684c26a0da42c752256a31e301c300f0603551d130101ff040530030101ff30090603551d2304023000300a06082a8648ce3d0403020349003046022100cffb50bdb73287649de96d4c48fcbb5d6e1eb468c72c5016776a9fdf0dc3d295022100e1b4b7ecba9ca1b43882a688c6fd93ffc99112247cf3ebb852b07f09d7c76be2":"cert. version \: 3\nserial number \: 01\nissuer name \: CN=Test\nsubject name \: CN=Test\nissued on \: 2025-01-01 00\:00\:00\nexpires on \: 2035-01-01 00\:00\:00\nsigned using \: ECDSA with SHA256\nEC key size \: 256 bits\nbasic constraints \: CA=true\n":0 + +# Generated the same way as above, with extension value b"\x30\x01\x80": +# a [0] tag without a length. This must still be rejected. +X509 CRT parse Authority Key Id - Truncated keyIdentifier +depends_on:PSA_HAVE_ALG_SOME_ECDSA:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +x509parse_crt:"3082012b3081d2a003020102020101300a06082a8648ce3d040302300f310d300b06035504030c0454657374301e170d3235303130313030303030305a170d3335303130313030303030305a300f310d300b06035504030c04546573743059301306072a8648ce3d020106082a8648ce3d03010703420004eba1e439f91038837190c4da3703001dff24411b90bf6998f56cba76c753c19ca9158f3c243ccb2118f8b6a78b6eb507962e855bf7c13dbafc314dc56d5d27d8a31f301d300f0603551d130101ff040530030101ff300a0603551d230403300180300a06082a8648ce3d040302034800304502205443c61342f55d3d4cec26df92b7614a5e67177f057efd4f6fb9d7a1a47f5d110221008f05c4c193e203d78a322455132f1b4428388904874dd329fc60a68a37a559b4":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_OUT_OF_DATA) + OID get numeric string - hardware module name oid_get_numeric_string:"2B06010505070804":0:"1.3.6.1.5.5.7.8.4" From 16bd0ff4c6326c70580b482d11e6a53bf74eaa6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BCller?= Date: Sat, 26 Sep 2026 10:27:11 +0200 Subject: [PATCH 3/3] Add ChangeLog entry for empty AuthorityKeyIdentifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Signed-off-by: Christopher Müller --- ChangeLog.d/x509-empty-authority-key-id.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 ChangeLog.d/x509-empty-authority-key-id.txt diff --git a/ChangeLog.d/x509-empty-authority-key-id.txt b/ChangeLog.d/x509-empty-authority-key-id.txt new file mode 100644 index 0000000000..a3c5d99096 --- /dev/null +++ b/ChangeLog.d/x509-empty-authority-key-id.txt @@ -0,0 +1,7 @@ +Bugfix + * Accept X.509 certificates whose AuthorityKeyIdentifier extension is an + empty SEQUENCE. All of its fields are optional, so such certificates + are syntactically valid, but they were rejected with + MBEDTLS_ERR_X509_INVALID_EXTENSIONS. This affected, for example, the + root certificate that some antivirus products install for HTTPS + scanning. Reported by CodingMarkus. Fixes #10253.