[PATCH v2] KEYS: X.509: Fix Basic Constraints CA flag parsing

wufan@kernel.org posted 1 patch 2 weeks, 2 days ago
crypto/asymmetric_keys/x509_cert_parser.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
[PATCH v2] KEYS: X.509: Fix Basic Constraints CA flag parsing
Posted by wufan@kernel.org 2 weeks, 2 days ago
From: Fan Wu <wufan@kernel.org>

Fix the X.509 Basic Constraints CA flag parsing to correctly handle
the ASN.1 DER encoded structure. The parser was incorrectly treating
the length field as the boolean value.

Per RFC 5280 section 4.1, X.509 certificates must use ASN.1 DER encoding.
According to ITU-T X.690, a DER-encoded BOOLEAN is represented as:

Tag (0x01), Length (0x01), Value (0x00 for FALSE, 0xFF for TRUE)

The basicConstraints extension with CA:TRUE is encoded as:

  SEQUENCE (0x30) | Length | BOOLEAN (0x01) | Length (0x01) | Value (0xFF)
                             ^-- v[2]         ^-- v[3]        ^-- v[4]

The parser was checking v[3] (the length field, always 0x01) instead
of v[4] (the actual boolean value, 0xFF for TRUE in DER encoding).

Also handle the case where the extension is an empty SEQUENCE (30 00),
which is valid for CA:FALSE when the default value is omitted as
required by DER encoding rules (X.690 section 11.5).

Per ITU-T X.690-0207:
- Section 11.5: Default values must be omitted in DER
- Section 11.1: DER requires TRUE to be encoded as 0xFF

Link: https://datatracker.ietf.org/doc/html/rfc5280
Link: https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
Fixes: 30eae2b037af ("KEYS: X.509: Parse Basic Constraints for CA")
Signed-off-by: Fan Wu <wufan@kernel.org>
---
 crypto/asymmetric_keys/x509_cert_parser.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 2ffe4ae90bea..8df3fa60a44f 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -610,11 +610,14 @@ int x509_process_extension(void *context, size_t hdrlen,
 		/*
 		 * Get hold of the basicConstraints
 		 * v[1] is the encoding size
-		 *	(Expect 0x2 or greater, making it 1 or more bytes)
+		 *	(Expect 0x00 for empty SEQUENCE with CA:FALSE, or
+		 *	0x03 or greater for non-empty SEQUENCE)
 		 * v[2] is the encoding type
 		 *	(Expect an ASN1_BOOL for the CA)
-		 * v[3] is the contents of the ASN1_BOOL
-		 *      (Expect 1 if the CA is TRUE)
+		 * v[3] is the length of the ASN1_BOOL
+		 *	(Expect 1 for a single byte boolean)
+		 * v[4] is the contents of the ASN1_BOOL
+		 *	(Expect 0xFF if the CA is TRUE)
 		 * vlen should match the entire extension size
 		 */
 		if (v[0] != (ASN1_CONS_BIT | ASN1_SEQ))
@@ -623,8 +626,13 @@ int x509_process_extension(void *context, size_t hdrlen,
 			return -EBADMSG;
 		if (v[1] != vlen - 2)
 			return -EBADMSG;
-		if (vlen >= 4 && v[1] != 0 && v[2] == ASN1_BOOL && v[3] == 1)
+		/* Empty SEQUENCE means CA:FALSE (default value omitted per DER) */
+		if (v[1] == 0)
+			return 0;
+		if (vlen >= 5 && v[2] == ASN1_BOOL && v[3] == 1 && v[4] == 0xFF)
 			ctx->cert->pub->key_eflags |= 1 << KEY_EFLAG_CA;
+		else
+			return -EBADMSG;
 		return 0;
 	}
 
-- 
2.51.0
Re: [PATCH v2] KEYS: X.509: Fix Basic Constraints CA flag parsing
Posted by Herbert Xu 4 days, 9 hours ago
On Mon, Sep 15, 2025 at 09:15:50PM +0000, wufan@kernel.org wrote:
> From: Fan Wu <wufan@kernel.org>
> 
> Fix the X.509 Basic Constraints CA flag parsing to correctly handle
> the ASN.1 DER encoded structure. The parser was incorrectly treating
> the length field as the boolean value.
> 
> Per RFC 5280 section 4.1, X.509 certificates must use ASN.1 DER encoding.
> According to ITU-T X.690, a DER-encoded BOOLEAN is represented as:
> 
> Tag (0x01), Length (0x01), Value (0x00 for FALSE, 0xFF for TRUE)
> 
> The basicConstraints extension with CA:TRUE is encoded as:
> 
>   SEQUENCE (0x30) | Length | BOOLEAN (0x01) | Length (0x01) | Value (0xFF)
>                              ^-- v[2]         ^-- v[3]        ^-- v[4]
> 
> The parser was checking v[3] (the length field, always 0x01) instead
> of v[4] (the actual boolean value, 0xFF for TRUE in DER encoding).
> 
> Also handle the case where the extension is an empty SEQUENCE (30 00),
> which is valid for CA:FALSE when the default value is omitted as
> required by DER encoding rules (X.690 section 11.5).
> 
> Per ITU-T X.690-0207:
> - Section 11.5: Default values must be omitted in DER
> - Section 11.1: DER requires TRUE to be encoded as 0xFF
> 
> Link: https://datatracker.ietf.org/doc/html/rfc5280
> Link: https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
> Fixes: 30eae2b037af ("KEYS: X.509: Parse Basic Constraints for CA")
> Signed-off-by: Fan Wu <wufan@kernel.org>
> ---
>  crypto/asymmetric_keys/x509_cert_parser.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)

Patch applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH v2] KEYS: X.509: Fix Basic Constraints CA flag parsing
Posted by Lukas Wunner 2 weeks, 1 day ago
On Mon, Sep 15, 2025 at 09:15:50PM +0000, wufan@kernel.org wrote:
> Fix the X.509 Basic Constraints CA flag parsing to correctly handle
> the ASN.1 DER encoded structure. The parser was incorrectly treating
> the length field as the boolean value.
[...]
> Link: https://datatracker.ietf.org/doc/html/rfc5280
> Link: https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
> Fixes: 30eae2b037af ("KEYS: X.509: Parse Basic Constraints for CA")
> Signed-off-by: Fan Wu <wufan@kernel.org>

Reviewed-by: Lukas Wunner <lukas@wunner.de>

> @@ -623,8 +626,13 @@ int x509_process_extension(void *context, size_t hdrlen,
>  			return -EBADMSG;
>  		if (v[1] != vlen - 2)
>  			return -EBADMSG;
> -		if (vlen >= 4 && v[1] != 0 && v[2] == ASN1_BOOL && v[3] == 1)
> +		/* Empty SEQUENCE means CA:FALSE (default value omitted per DER) */
> +		if (v[1] == 0)
> +			return 0;
> +		if (vlen >= 5 && v[2] == ASN1_BOOL && v[3] == 1 && v[4] == 0xFF)
>  			ctx->cert->pub->key_eflags |= 1 << KEY_EFLAG_CA;
> +		else
> +			return -EBADMSG;
>  		return 0;
>  	}

For anyone who didn't follow the discussion and/or isn't familiar
with ASN.1, the patch first checks for a well-formed "CA:FALSE",
then checks for a well-formed "CA:TRUE", finally rejects anything
else as malformed.

Thanks,

Lukas