diff mbox series

[RESEND] keys: Handle missing Authority Key Identifier X509 extension

Message ID 20201013133939.1182462-1-andrew.zaborowski@intel.com (mailing list archive)
State Superseded
Headers show
Series [RESEND] keys: Handle missing Authority Key Identifier X509 extension | expand

Commit Message

Andrew Zaborowski Oct. 13, 2020, 1:39 p.m. UTC
In a self-signed certificate the subject and issuer are the same and so
the Authority Key Identifier X.509 v3 extension is explicitly made
optional in RFC5280 section 4.2.1.1.
crypto/asymmetric_keys/x509_cert_parser.c can't handle this and makes
(at least) the restrict.c functions refuse to work with certificates
that don't include the AKID.  Fix this by filling in the missing
cert->sig->auth_ids with the certificate's own IDs after parsing and
determinig the certificate is self-signed.

The asymmetric_key_generate_id return value is not checked because it's
already succeeded once at this point.

There are root X.509 v3 certificates in use where this is the case,
mostly oldish ones.

Signed-off-by: Andrew Zaborowski <andrew.zaborowski@intel.com>
---
 crypto/asymmetric_keys/x509_cert_parser.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

Comments

Jarkko Sakkinen Oct. 18, 2020, 8:22 p.m. UTC | #1
On Tue, Oct 13, 2020 at 03:39:38PM +0200, Andrew Zaborowski wrote:
> In a self-signed certificate the subject and issuer are the same and so
> the Authority Key Identifier X.509 v3 extension is explicitly made
> optional in RFC5280 section 4.2.1.1.
> crypto/asymmetric_keys/x509_cert_parser.c can't handle this and makes
> (at least) the restrict.c functions refuse to work with certificates
> that don't include the AKID.  Fix this by filling in the missing
> cert->sig->auth_ids with the certificate's own IDs after parsing and
> determinig the certificate is self-signed.
> 
> The asymmetric_key_generate_id return value is not checked because it's
> already succeeded once at this point.
> 
> There are root X.509 v3 certificates in use where this is the case,
> mostly oldish ones.
> 
> Signed-off-by: Andrew Zaborowski <andrew.zaborowski@intel.com>

Acked-by: Jarkko Sakkinen <jarkko@kernel.org>

> ---
>  crypto/asymmetric_keys/x509_cert_parser.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
> index 26ec20ef489..a5a2f93e242 100644
> --- a/crypto/asymmetric_keys/x509_cert_parser.c
> +++ b/crypto/asymmetric_keys/x509_cert_parser.c
> @@ -136,6 +136,25 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
>  	if (ret < 0)
>  		goto error_decode;
>  
> +	if (cert->self_signed) {
> +		if (!cert->sig->auth_ids[0]) {
> +			/* Duplicate cert->id */
> +			kid = asymmetric_key_generate_id(cert->raw_serial,
> +							 cert->raw_serial_size,
> +							 cert->raw_issuer,
> +							 cert->raw_issuer_size);
> +			cert->sig->auth_ids[0] = kid;
> +		}
> +
> +		if (!cert->sig->auth_ids[1] && cert->skid) {
> +			/* Duplicate cert->skid */
> +			kid = asymmetric_key_generate_id(cert->raw_skid,
> +							 cert->raw_skid_size,
> +							 "", 0);
> +			cert->sig->auth_ids[1] = kid;
> +		}
> +	}
> +
>  	kfree(ctx);
>  	return cert;
>  
> -- 
> 2.20.1
> 
> 

/Jarkko
diff mbox series

Patch

diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 26ec20ef489..a5a2f93e242 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -136,6 +136,25 @@  struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
 	if (ret < 0)
 		goto error_decode;
 
+	if (cert->self_signed) {
+		if (!cert->sig->auth_ids[0]) {
+			/* Duplicate cert->id */
+			kid = asymmetric_key_generate_id(cert->raw_serial,
+							 cert->raw_serial_size,
+							 cert->raw_issuer,
+							 cert->raw_issuer_size);
+			cert->sig->auth_ids[0] = kid;
+		}
+
+		if (!cert->sig->auth_ids[1] && cert->skid) {
+			/* Duplicate cert->skid */
+			kid = asymmetric_key_generate_id(cert->raw_skid,
+							 cert->raw_skid_size,
+							 "", 0);
+			cert->sig->auth_ids[1] = kid;
+		}
+	}
+
 	kfree(ctx);
 	return cert;