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