1From a0541334a6394f8237a4393b7372693cd7e96f15 Mon Sep 17 00:00:00 2001
2From: Jouni Malinen <j@w1.fi>
3Date: Sat, 13 Mar 2021 18:19:31 +0200
4Subject: [PATCH] ASN.1: Validate DigestAlgorithmIdentifier parameters
5
6The supported hash algorithms do not use AlgorithmIdentifier parameters.
7However, there are implementations that include NULL parameters in
8addition to ones that omit the parameters. Previous implementation did
9not check the parameters value at all which supported both these cases,
10but did not reject any other unexpected information.
11
12Use strict validation of digest algorithm parameters and reject any
13unexpected value when validating a signature. This is needed to prevent
14potential forging attacks.
15
16Signed-off-by: Jouni Malinen <j@w1.fi>
17Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
18---
19 src/tls/pkcs1.c  | 21 +++++++++++++++++++++
20 src/tls/x509v3.c | 20 ++++++++++++++++++++
21 2 files changed, 41 insertions(+)
22
23diff --git a/src/tls/pkcs1.c b/src/tls/pkcs1.c
24index bbdb0d72d..5761dfed0 100644
25--- a/src/tls/pkcs1.c
26+++ b/src/tls/pkcs1.c
27@@ -244,6 +244,8 @@ int pkcs1_v15_sig_ver(struct crypto_public_key *pk,
28 		os_free(decrypted);
29 		return -1;
30 	}
31+	wpa_hexdump(MSG_MSGDUMP, "PKCS #1: DigestInfo",
32+		    hdr.payload, hdr.length);
33
34 	pos = hdr.payload;
35 	end = pos + hdr.length;
36@@ -265,6 +267,8 @@ int pkcs1_v15_sig_ver(struct crypto_public_key *pk,
37 		os_free(decrypted);
38 		return -1;
39 	}
40+	wpa_hexdump(MSG_MSGDUMP, "PKCS #1: DigestAlgorithmIdentifier",
41+		    hdr.payload, hdr.length);
42 	da_end = hdr.payload + hdr.length;
43
44 	if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
45@@ -273,6 +277,23 @@ int pkcs1_v15_sig_ver(struct crypto_public_key *pk,
46 		os_free(decrypted);
47 		return -1;
48 	}
49+	wpa_hexdump(MSG_MSGDUMP, "PKCS #1: Digest algorithm parameters",
50+		    next, da_end - next);
51+
52+	/*
53+	 * RFC 5754: The correct encoding for the SHA2 algorithms would be to
54+	 * omit the parameters, but there are implementation that encode these
55+	 * as a NULL element. Allow these two cases and reject anything else.
56+	 */
57+	if (da_end > next &&
58+	    (asn1_get_next(next, da_end - next, &hdr) < 0 ||
59+	     !asn1_is_null(&hdr) ||
60+	     hdr.payload + hdr.length != da_end)) {
61+		wpa_printf(MSG_DEBUG,
62+			   "PKCS #1: Unexpected digest algorithm parameters");
63+		os_free(decrypted);
64+		return -1;
65+	}
66
67 	if (!asn1_oid_equal(&oid, hash_alg)) {
68 		char txt[100], txt2[100];
69diff --git a/src/tls/x509v3.c b/src/tls/x509v3.c
70index a8944dd2f..df337ec4d 100644
71--- a/src/tls/x509v3.c
72+++ b/src/tls/x509v3.c
73@@ -1964,6 +1964,7 @@ int x509_check_signature(struct x509_certificate *issuer,
74 		os_free(data);
75 		return -1;
76 	}
77+	wpa_hexdump(MSG_MSGDUMP, "X509: DigestInfo", hdr.payload, hdr.length);
78
79 	pos = hdr.payload;
80 	end = pos + hdr.length;
81@@ -1985,6 +1986,8 @@ int x509_check_signature(struct x509_certificate *issuer,
82 		os_free(data);
83 		return -1;
84 	}
85+	wpa_hexdump(MSG_MSGDUMP, "X509: DigestAlgorithmIdentifier",
86+		    hdr.payload, hdr.length);
87 	da_end = hdr.payload + hdr.length;
88
89 	if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
90@@ -1992,6 +1995,23 @@ int x509_check_signature(struct x509_certificate *issuer,
91 		os_free(data);
92 		return -1;
93 	}
94+	wpa_hexdump(MSG_MSGDUMP, "X509: Digest algorithm parameters",
95+		    next, da_end - next);
96+
97+	/*
98+	 * RFC 5754: The correct encoding for the SHA2 algorithms would be to
99+	 * omit the parameters, but there are implementation that encode these
100+	 * as a NULL element. Allow these two cases and reject anything else.
101+	 */
102+	if (da_end > next &&
103+	    (asn1_get_next(next, da_end - next, &hdr) < 0 ||
104+	     !asn1_is_null(&hdr) ||
105+	     hdr.payload + hdr.length != da_end)) {
106+		wpa_printf(MSG_DEBUG,
107+			   "X509: Unexpected digest algorithm parameters");
108+		os_free(data);
109+		return -1;
110+	}
111
112 	if (x509_sha1_oid(&oid)) {
113 		if (signature->oid.oid[6] != 5 /* sha-1WithRSAEncryption */) {
114--
1152.20.1
116
117