diff options
author | dveditz%cruzio.com <devnull@localhost> | 2006-09-10 17:20:36 +0000 |
---|---|---|
committer | dveditz%cruzio.com <devnull@localhost> | 2006-09-10 17:20:36 +0000 |
commit | 6fafd1206b2d0d464ce89afb43ed78d1300c284f (patch) | |
tree | fd8ecc47e71fd0841079424eea60df28f2fbb708 | |
parent | 3005039d059c2919a405f9329e926580bdf77e9b (diff) | |
download | nss-hg-6fafd1206b2d0d464ce89afb43ed78d1300c284f.tar.gz |
Change DecryptSigBlock to return the parsed DigestInfo's length, so
the caller can check it. Patch by wtchang@redhat.com. r=nelson,rrelyea, a=schrep.
Bug 351848
-rw-r--r-- | security/nss/lib/cryptohi/secvfy.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/security/nss/lib/cryptohi/secvfy.c b/security/nss/lib/cryptohi/secvfy.c index 7310dfbbe..94a0b3563 100644 --- a/security/nss/lib/cryptohi/secvfy.c +++ b/security/nss/lib/cryptohi/secvfy.c @@ -54,10 +54,12 @@ ** Decrypt signature block using public key ** Store the hash algorithm oid tag in *tagp ** Store the digest in the digest buffer +** Store the digest length in *digestlen ** XXX this is assuming that the signature algorithm has WITH_RSA_ENCRYPTION */ static SECStatus -DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, unsigned int len, +DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, + unsigned int *digestlen, unsigned int maxdigestlen, SECKEYPublicKey *key, const SECItem *sig, char *wincx) { SGNDigestInfo *di = NULL; @@ -93,12 +95,13 @@ DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, unsigned int len, if (di->digestAlgorithm.parameters.len > 2) { goto sigloser; } - if (di->digest.len > len) { + if (di->digest.len > maxdigestlen) { PORT_SetError(SEC_ERROR_OUTPUT_LEN); goto loser; } PORT_Memcpy(digest, di->digest.data, di->digest.len); *tagp = tag; + *digestlen = di->digest.len; goto done; sigloser: @@ -139,6 +142,7 @@ struct VFYContextStr { /* the full ECDSA signature */ unsigned char ecdsasig[2 * MAX_ECKEY_LEN]; } u; + unsigned int rsadigestlen; void * wincx; void *hashcx; const SECHashObject *hashobj; @@ -336,9 +340,11 @@ vfy_CreateContextPrivate(const SECKEYPublicKey *key, const SECItem *sig, cx->key = SECKEY_CopyPublicKey((SECKEYPublicKey *)key); if (sig) { SECOidTag hashid = SEC_OID_UNKNOWN; - rv = DecryptSigBlock(&hashid, cx->u.buffer, + unsigned int digestlen = 0; + rv = DecryptSigBlock(&hashid, cx->u.buffer, &digestlen, HASH_LENGTH_MAX, cx->key, sig, (char*)wincx); cx->alg = hashid; + cx->rsadigestlen = digestlen; } else { rv = decodeSigAlg(algid, params, key, &cx->alg); } @@ -497,14 +503,15 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig) case VFY_RSA: if (sig) { SECOidTag hashid = SEC_OID_UNKNOWN; - rv = DecryptSigBlock(&hashid, cx->u.buffer, + rv = DecryptSigBlock(&hashid, cx->u.buffer, &cx->rsadigestlen, HASH_LENGTH_MAX, cx->key, sig, (char*)cx->wincx); if ((rv != SECSuccess) || (hashid != cx->alg)) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); return SECFailure; } } - if (PORT_Memcmp(final, cx->u.buffer, part)) { + if ((part != cx->rsadigestlen) || + PORT_Memcmp(final, cx->u.buffer, part)) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); return SECFailure; } @@ -543,7 +550,8 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig, if (cx != NULL) { switch (key->keyType) { case rsaKey: - if (PORT_Memcmp(digest->data, cx->u.buffer, digest->len)) { + if ((digest->len != cx->rsadigestlen) || + PORT_Memcmp(digest->data, cx->u.buffer, digest->len)) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); } else { rv = SECSuccess; |