1diff -ur misc/nss-3.39/nss/lib/cryptohi/secvfy.c misc/build/nss-3.39/nss/lib/cryptohi/secvfy.c 2--- misc/nss-3.39/nss/lib/cryptohi/secvfy.c 2018-08-31 14:55:53.000000000 +0200 3+++ misc/build/nss-3.39/nss/lib/cryptohi/secvfy.c 2022-02-05 22:36:19.617132698 +0100 4@@ -164,6 +164,37 @@ 5 PR_FALSE /*XXX: unsafeAllowMissingParameters*/); 6 } 7 8+static unsigned int 9+checkedSignatureLen(const SECKEYPublicKey *pubk) 10+{ 11+ unsigned int sigLen = SECKEY_SignatureLen(pubk); 12+ unsigned int maxSigLen; 13+ if (sigLen == 0) { 14+ /* Error set by SECKEY_SignatureLen */ 15+ return sigLen; 16+ } 17+ switch (pubk->keyType) { 18+ case rsaKey: 19+ case rsaPssKey: 20+ maxSigLen = (RSA_MAX_MODULUS_BITS + 7) / 8; 21+ break; 22+ case dsaKey: 23+ maxSigLen = DSA_MAX_SIGNATURE_LEN; 24+ break; 25+ case ecKey: 26+ maxSigLen = 2 * MAX_ECKEY_LEN; 27+ break; 28+ default: 29+ PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); 30+ return 0; 31+ } 32+ if (sigLen > maxSigLen) { 33+ PORT_SetError(SEC_ERROR_INVALID_KEY); 34+ return 0; 35+ } 36+ return sigLen; 37+} 38+ 39 /* 40 * decode the ECDSA or DSA signature from it's DER wrapping. 41 * The unwrapped/raw signature is placed in the buffer pointed 42@@ -174,38 +205,38 @@ 43 unsigned int len) 44 { 45 SECItem *dsasig = NULL; /* also used for ECDSA */ 46- SECStatus rv = SECSuccess; 47 48- if ((algid != SEC_OID_ANSIX9_DSA_SIGNATURE) && 49- (algid != SEC_OID_ANSIX962_EC_PUBLIC_KEY)) { 50- if (sig->len != len) { 51- PORT_SetError(SEC_ERROR_BAD_DER); 52- return SECFailure; 53+ /* Safety: Ensure algId is as expected and that signature size is within maxmimums */ 54+ if (algid == SEC_OID_ANSIX9_DSA_SIGNATURE) { 55+ if (len > DSA_MAX_SIGNATURE_LEN) { 56+ goto loser; 57 } 58- 59- PORT_Memcpy(dsig, sig->data, sig->len); 60- return SECSuccess; 61- } 62- 63- if (algid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) { 64+ } else if (algid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) { 65 if (len > MAX_ECKEY_LEN * 2) { 66- PORT_SetError(SEC_ERROR_BAD_DER); 67- return SECFailure; 68+ goto loser; 69 } 70- } 71- dsasig = DSAU_DecodeDerSigToLen((SECItem *)sig, len); 72- 73- if ((dsasig == NULL) || (dsasig->len != len)) { 74- rv = SECFailure; 75 } else { 76- PORT_Memcpy(dsig, dsasig->data, dsasig->len); 77+ goto loser; 78 } 79 80- if (dsasig != NULL) 81+ /* Decode and pad to length */ 82+ dsasig = DSAU_DecodeDerSigToLen((SECItem *)sig, len); 83+ if (dsasig == NULL) { 84+ goto loser; 85+ } 86+ if (dsasig->len != len) { 87 SECITEM_FreeItem(dsasig, PR_TRUE); 88- if (rv == SECFailure) 89- PORT_SetError(SEC_ERROR_BAD_DER); 90- return rv; 91+ goto loser; 92+ } 93+ 94+ PORT_Memcpy(dsig, dsasig->data, len); 95+ SECITEM_FreeItem(dsasig, PR_TRUE); 96+ 97+ return SECSuccess; 98+ 99+loser: 100+ PORT_SetError(SEC_ERROR_BAD_DER); 101+ return SECFailure; 102 } 103 104 const SEC_ASN1Template hashParameterTemplate[] = 105@@ -231,7 +262,7 @@ 106 sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg, 107 const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg) 108 { 109- int len; 110+ unsigned int len; 111 PLArenaPool *arena; 112 SECStatus rv; 113 SECItem oid; 114@@ -458,48 +489,52 @@ 115 cx->pkcs1RSADigestInfo = NULL; 116 rv = SECSuccess; 117 if (sig) { 118- switch (type) { 119- case rsaKey: 120- rv = recoverPKCS1DigestInfo(hashAlg, &cx->hashAlg, 121- &cx->pkcs1RSADigestInfo, 122- &cx->pkcs1RSADigestInfoLen, 123- cx->key, 124- sig, wincx); 125- break; 126- case rsaPssKey: 127- sigLen = SECKEY_SignatureLen(key); 128- if (sigLen == 0) { 129- /* error set by SECKEY_SignatureLen */ 130- rv = SECFailure; 131+ rv = SECFailure; 132+ if (type == rsaKey) { 133+ rv = recoverPKCS1DigestInfo(hashAlg, &cx->hashAlg, 134+ &cx->pkcs1RSADigestInfo, 135+ &cx->pkcs1RSADigestInfoLen, 136+ cx->key, 137+ sig, wincx); 138+ } else { 139+ sigLen = checkedSignatureLen(key); 140+ /* Check signature length is within limits */ 141+ if (sigLen == 0) { 142+ /* error set by checkedSignatureLen */ 143+ rv = SECFailure; 144+ goto loser; 145+ } 146+ if (sigLen > sizeof(cx->u)) { 147+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 148+ rv = SECFailure; 149+ goto loser; 150+ } 151+ switch (type) { 152+ case rsaPssKey: 153+ if (sig->len != sigLen) { 154+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 155+ rv = SECFailure; 156+ goto loser; 157+ } 158+ PORT_Memcpy(cx->u.buffer, sig->data, sigLen); 159+ rv = SECSuccess; 160 break; 161- } 162- if (sig->len != sigLen) { 163- PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 164- rv = SECFailure; 165+ case ecKey: 166+ case dsaKey: 167+ /* decodeECorDSASignature will check sigLen == sig->len after padding */ 168+ rv = decodeECorDSASignature(encAlg, sig, cx->u.buffer, sigLen); 169 break; 170- } 171- PORT_Memcpy(cx->u.buffer, sig->data, sigLen); 172- break; 173- case dsaKey: 174- case ecKey: 175- sigLen = SECKEY_SignatureLen(key); 176- if (sigLen == 0) { 177- /* error set by SECKEY_SignatureLen */ 178+ default: 179+ /* Unreachable */ 180 rv = SECFailure; 181- break; 182- } 183- rv = decodeECorDSASignature(encAlg, sig, cx->u.buffer, sigLen); 184- break; 185- default: 186- rv = SECFailure; 187- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); 188- break; 189+ goto loser; 190+ } 191+ } 192+ if (rv != SECSuccess) { 193+ goto loser; 194 } 195 } 196 197- if (rv) 198- goto loser; 199- 200 /* check hash alg again, RSA may have changed it.*/ 201 if (HASH_GetHashTypeByOidTag(cx->hashAlg) == HASH_AlgNULL) { 202 /* error set by HASH_GetHashTypeByOidTag */ 203@@ -634,11 +669,16 @@ 204 switch (cx->key->keyType) { 205 case ecKey: 206 case dsaKey: 207- dsasig.data = cx->u.buffer; 208- dsasig.len = SECKEY_SignatureLen(cx->key); 209+ dsasig.len = checkedSignatureLen(cx->key); 210 if (dsasig.len == 0) { 211 return SECFailure; 212 } 213+ if (dsasig.len > sizeof(cx->u)) { 214+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 215+ return SECFailure; 216+ } 217+ dsasig.data = cx->u.buffer; 218+ 219 if (sig) { 220 rv = decodeECorDSASignature(cx->encAlg, sig, dsasig.data, 221 dsasig.len); 222@@ -680,8 +720,13 @@ 223 return SECFailure; 224 } 225 rsasig.data = cx->u.buffer; 226- rsasig.len = SECKEY_SignatureLen(cx->key); 227+ rsasig.len = checkedSignatureLen(cx->key); 228 if (rsasig.len == 0) { 229+ /* Error set by checkedSignatureLen */ 230+ return SECFailure; 231+ } 232+ if (rsasig.len > sizeof(cx->u)) { 233+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 234 return SECFailure; 235 } 236 if (sig) { 237@@ -743,7 +788,6 @@ 238 SECStatus rv; 239 VFYContext *cx; 240 SECItem dsasig; /* also used for ECDSA */ 241- 242 rv = SECFailure; 243 244 cx = vfy_CreateContext(key, sig, encAlg, hashAlg, NULL, wincx); 245@@ -751,19 +795,25 @@ 246 switch (key->keyType) { 247 case rsaKey: 248 rv = verifyPKCS1DigestInfo(cx, digest); 249+ /* Error (if any) set by verifyPKCS1DigestInfo */ 250 break; 251- case dsaKey: 252 case ecKey: 253+ case dsaKey: 254 dsasig.data = cx->u.buffer; 255- dsasig.len = SECKEY_SignatureLen(cx->key); 256+ dsasig.len = checkedSignatureLen(cx->key); 257 if (dsasig.len == 0) { 258+ /* Error set by checkedSignatureLen */ 259+ rv = SECFailure; 260 break; 261 } 262- if (PK11_Verify(cx->key, &dsasig, (SECItem *)digest, cx->wincx) != 263- SECSuccess) { 264+ if (dsasig.len > sizeof(cx->u)) { 265+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 266+ rv = SECFailure; 267+ break; 268+ } 269+ rv = PK11_Verify(cx->key, &dsasig, (SECItem *)digest, cx->wincx); 270+ if (rv != SECSuccess) { 271 PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 272- } else { 273- rv = SECSuccess; 274 } 275 break; 276 default: 277