summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordveditz%cruzio.com <devnull@localhost>2006-09-10 17:20:36 +0000
committerdveditz%cruzio.com <devnull@localhost>2006-09-10 17:20:36 +0000
commit6fafd1206b2d0d464ce89afb43ed78d1300c284f (patch)
treefd8ecc47e71fd0841079424eea60df28f2fbb708
parent3005039d059c2919a405f9329e926580bdf77e9b (diff)
downloadnss-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.c20
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;