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