diff options
author | nelsonb%netscape.com <devnull@localhost> | 2004-01-22 22:04:54 +0000 |
---|---|---|
committer | nelsonb%netscape.com <devnull@localhost> | 2004-01-22 22:04:54 +0000 |
commit | e46199d2130404d38c2e4082b8c2de9349c6741b (patch) | |
tree | 23bbd04035d975e3da151b0910e3a805e2a475c0 | |
parent | c1bfe9dc22e6325bb2537def583651c89b068882 (diff) | |
download | nss-hg-e46199d2130404d38c2e4082b8c2de9349c6741b.tar.gz |
Correct NSS's key usage tests for certs with non-RSA public keys.
Bug 221638. r=relyea.
-rw-r--r-- | security/nss/lib/certdb/certdb.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c index ac7cad6a4..84039ea99 100644 --- a/security/nss/lib/certdb/certdb.c +++ b/security/nss/lib/certdb/certdb.c @@ -1213,26 +1213,37 @@ CERT_CheckKeyUsage(CERTCertificate *cert, unsigned int requiredUsage) * type in cert */ if ( requiredUsage & KU_KEY_AGREEMENT_OR_ENCIPHERMENT ) { - SECKEYPublicKey *key = CERT_ExtractPublicKey(cert); - if (!key) - return SECFailure; - if ( ( key->keyType == keaKey ) || ( key->keyType == fortezzaKey ) || - ( key->keyType == dhKey ) ) { - requiredUsage |= KU_KEY_AGREEMENT; - } else { - requiredUsage |= KU_KEY_ENCIPHERMENT; - } - - /* now turn off the special bit */ + KeyType keyType = CERT_GetCertKeyType(&cert->subjectPublicKeyInfo); + /* turn off the special bit */ requiredUsage &= (~KU_KEY_AGREEMENT_OR_ENCIPHERMENT); - - SECKEY_DestroyPublicKey(key); - } - if ( ( cert->keyUsage & requiredUsage ) != requiredUsage ) { - return(SECFailure); + switch (keyType) { + case rsaKey: + requiredUsage |= KU_KEY_ENCIPHERMENT; + break; + case dsaKey: + requiredUsage |= KU_DIGITAL_SIGNATURE; + break; + case fortezzaKey: + case keaKey: + case dhKey: + requiredUsage |= KU_KEY_AGREEMENT; + break; + case ecKey: + /* Accept either signature or agreement. */ + if (!(cert->keyUsage & (KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT))) + goto loser; + break; + default: + goto loser; + } } - return(SECSuccess); + + if ( (cert->keyUsage & requiredUsage) == requiredUsage ) + return SECSuccess; +loser: + PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); + return SECFailure; } |