summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornelsonb%netscape.com <devnull@localhost>2004-01-22 22:04:54 +0000
committernelsonb%netscape.com <devnull@localhost>2004-01-22 22:04:54 +0000
commite46199d2130404d38c2e4082b8c2de9349c6741b (patch)
tree23bbd04035d975e3da151b0910e3a805e2a475c0
parentc1bfe9dc22e6325bb2537def583651c89b068882 (diff)
downloadnss-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.c45
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;
}