| From a0541334a6394f8237a4393b7372693cd7e96f15 Mon Sep 17 00:00:00 2001 |
| From: Jouni Malinen <j@w1.fi> |
| Date: Sat, 13 Mar 2021 18:19:31 +0200 |
| Subject: [PATCH] ASN.1: Validate DigestAlgorithmIdentifier parameters |
| |
| The supported hash algorithms do not use AlgorithmIdentifier parameters. |
| However, there are implementations that include NULL parameters in |
| addition to ones that omit the parameters. Previous implementation did |
| not check the parameters value at all which supported both these cases, |
| but did not reject any other unexpected information. |
| |
| Use strict validation of digest algorithm parameters and reject any |
| unexpected value when validating a signature. This is needed to prevent |
| potential forging attacks. |
| |
| Signed-off-by: Jouni Malinen <j@w1.fi> |
| Signed-off-by: Peter Korsgaard <peter@korsgaard.com> |
| --- |
| src/tls/pkcs1.c | 21 +++++++++++++++++++++ |
| src/tls/x509v3.c | 20 ++++++++++++++++++++ |
| 2 files changed, 41 insertions(+) |
| |
| diff --git a/src/tls/pkcs1.c b/src/tls/pkcs1.c |
| index bbdb0d72d..5761dfed0 100644 |
| --- a/src/tls/pkcs1.c |
| +++ b/src/tls/pkcs1.c |
| @@ -244,6 +244,8 @@ int pkcs1_v15_sig_ver(struct crypto_public_key *pk, |
| os_free(decrypted); |
| return -1; |
| } |
| + wpa_hexdump(MSG_MSGDUMP, "PKCS #1: DigestInfo", |
| + hdr.payload, hdr.length); |
| |
| pos = hdr.payload; |
| end = pos + hdr.length; |
| @@ -265,6 +267,8 @@ int pkcs1_v15_sig_ver(struct crypto_public_key *pk, |
| os_free(decrypted); |
| return -1; |
| } |
| + wpa_hexdump(MSG_MSGDUMP, "PKCS #1: DigestAlgorithmIdentifier", |
| + hdr.payload, hdr.length); |
| da_end = hdr.payload + hdr.length; |
| |
| if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) { |
| @@ -273,6 +277,23 @@ int pkcs1_v15_sig_ver(struct crypto_public_key *pk, |
| os_free(decrypted); |
| return -1; |
| } |
| + wpa_hexdump(MSG_MSGDUMP, "PKCS #1: Digest algorithm parameters", |
| + next, da_end - next); |
| + |
| + /* |
| + * RFC 5754: The correct encoding for the SHA2 algorithms would be to |
| + * omit the parameters, but there are implementation that encode these |
| + * as a NULL element. Allow these two cases and reject anything else. |
| + */ |
| + if (da_end > next && |
| + (asn1_get_next(next, da_end - next, &hdr) < 0 || |
| + !asn1_is_null(&hdr) || |
| + hdr.payload + hdr.length != da_end)) { |
| + wpa_printf(MSG_DEBUG, |
| + "PKCS #1: Unexpected digest algorithm parameters"); |
| + os_free(decrypted); |
| + return -1; |
| + } |
| |
| if (!asn1_oid_equal(&oid, hash_alg)) { |
| char txt[100], txt2[100]; |
| diff --git a/src/tls/x509v3.c b/src/tls/x509v3.c |
| index a8944dd2f..df337ec4d 100644 |
| --- a/src/tls/x509v3.c |
| +++ b/src/tls/x509v3.c |
| @@ -1964,6 +1964,7 @@ int x509_check_signature(struct x509_certificate *issuer, |
| os_free(data); |
| return -1; |
| } |
| + wpa_hexdump(MSG_MSGDUMP, "X509: DigestInfo", hdr.payload, hdr.length); |
| |
| pos = hdr.payload; |
| end = pos + hdr.length; |
| @@ -1985,6 +1986,8 @@ int x509_check_signature(struct x509_certificate *issuer, |
| os_free(data); |
| return -1; |
| } |
| + wpa_hexdump(MSG_MSGDUMP, "X509: DigestAlgorithmIdentifier", |
| + hdr.payload, hdr.length); |
| da_end = hdr.payload + hdr.length; |
| |
| if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) { |
| @@ -1992,6 +1995,23 @@ int x509_check_signature(struct x509_certificate *issuer, |
| os_free(data); |
| return -1; |
| } |
| + wpa_hexdump(MSG_MSGDUMP, "X509: Digest algorithm parameters", |
| + next, da_end - next); |
| + |
| + /* |
| + * RFC 5754: The correct encoding for the SHA2 algorithms would be to |
| + * omit the parameters, but there are implementation that encode these |
| + * as a NULL element. Allow these two cases and reject anything else. |
| + */ |
| + if (da_end > next && |
| + (asn1_get_next(next, da_end - next, &hdr) < 0 || |
| + !asn1_is_null(&hdr) || |
| + hdr.payload + hdr.length != da_end)) { |
| + wpa_printf(MSG_DEBUG, |
| + "X509: Unexpected digest algorithm parameters"); |
| + os_free(data); |
| + return -1; |
| + } |
| |
| if (x509_sha1_oid(&oid)) { |
| if (signature->oid.oid[6] != 5 /* sha-1WithRSAEncryption */) { |
| -- |
| 2.20.1 |
| |