diff options
Diffstat (limited to 'security/nss')
-rw-r--r-- | security/nss/cmd/lib/SECerrs.h | 5 | ||||
-rw-r--r-- | security/nss/lib/base/errorval.c | 1 | ||||
-rw-r--r-- | security/nss/lib/certdb/stanpcertdb.c | 15 | ||||
-rw-r--r-- | security/nss/lib/dev/devtoken.c | 29 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11cert.c | 7 | ||||
-rw-r--r-- | security/nss/lib/pkcs12/p12d.c | 2 | ||||
-rw-r--r-- | security/nss/lib/util/secerr.h | 3 |
7 files changed, 60 insertions, 2 deletions
diff --git a/security/nss/cmd/lib/SECerrs.h b/security/nss/cmd/lib/SECerrs.h index 4481cb838..9496b74e5 100644 --- a/security/nss/cmd/lib/SECerrs.h +++ b/security/nss/cmd/lib/SECerrs.h @@ -455,3 +455,8 @@ ER3(SEC_ERROR_BAD_TEMPLATE, (SEC_ERROR_BASE + 136), ER3(SEC_ERROR_CRL_NOT_FOUND, (SEC_ERROR_BASE + 137), "No matching CRL was found.") + +ER3(SEC_ERROR_REUSED_ISSUER_AND_SERIAL, (SEC_ERROR_BASE + 138), +"You are attempting to import a cert with the same issuer/serial as \ +an existing cert, but that is not the same cert.") + diff --git a/security/nss/lib/base/errorval.c b/security/nss/lib/base/errorval.c index 7a4017dff..7a5892d92 100644 --- a/security/nss/lib/base/errorval.c +++ b/security/nss/lib/base/errorval.c @@ -87,4 +87,5 @@ const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE = 32; const NSSError NSS_ERROR_HASH_COLLISION = 33; const NSSError NSS_ERROR_DEVICE_ERROR = 34; +const NSSError NSS_ERROR_INVALID_CERTIFICATE = 35; diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c index cd7487f1c..cddfbc816 100644 --- a/security/nss/lib/certdb/stanpcertdb.c +++ b/security/nss/lib/certdb/stanpcertdb.c @@ -140,6 +140,8 @@ CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert, return rv; } +extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; + SECStatus __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, CERTCertTrust *trust) @@ -183,6 +185,9 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, PR_TRUE); PK11_FreeSlot(slot); if (!permInstance) { + if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) { + PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); + } return SECFailure; } nssPKIObject_AddInstance(&c->object, permInstance); @@ -230,6 +235,16 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, /* Then, see if it is already a perm cert */ c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle, &encoding); + /* actually, that search ends up going by issuer/serial, + * so it is still possible to return a cert with the same + * issuer/serial but a different encoding, and we're + * going to reject that + */ + if (c && !nssItem_Equal(&c->encoding, &encoding, NULL)) { + nssCertificate_Destroy(c); + PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); + return NULL; + } } if (c) { return STAN_GetCERTCertificate(c); diff --git a/security/nss/lib/dev/devtoken.c b/security/nss/lib/dev/devtoken.c index 564a34c28..efc05d1fa 100644 --- a/security/nss/lib/dev/devtoken.c +++ b/security/nss/lib/dev/devtoken.c @@ -537,6 +537,8 @@ find_objects_by_template return objects; } +extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; + NSS_IMPLEMENT nssCryptokiObject * nssToken_ImportCertificate ( @@ -553,6 +555,7 @@ nssToken_ImportCertificate PRBool asTokenObject ) { + PRStatus status; CK_CERTIFICATE_TYPE cert_type; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE cert_tmpl[10]; @@ -593,10 +596,36 @@ nssToken_ImportCertificate searchType, NULL); if (rvObject) { + NSSItem existingDER; NSSSlot *slot = nssToken_GetSlot(tok); nssSession *session = nssSlot_CreateSession(slot, NULL, PR_TRUE); if (!session) { nssCryptokiObject_Destroy(rvObject); + nssSlot_Destroy(slot); + return (nssCryptokiObject *)NULL; + } + /* Reject any attempt to import a new cert that has the same + * issuer/serial as an existing cert, but does not have the + * same encoding + */ + NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); + NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); + NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); + status = nssCKObject_GetAttributes(rvObject->handle, + cert_tmpl, ctsize, NULL, + session, slot); + NSS_CK_ATTRIBUTE_TO_ITEM(cert_tmpl, &existingDER); + if (status == PR_SUCCESS) { + if (!nssItem_Equal(encoding, &existingDER, NULL)) { + nss_SetError(NSS_ERROR_INVALID_CERTIFICATE); + status = PR_FAILURE; + } + nss_ZFreeIf(existingDER.data); + } + if (status == PR_FAILURE) { + nssCryptokiObject_Destroy(rvObject); + nssSession_Destroy(session); + nssSlot_Destroy(slot); return (nssCryptokiObject *)NULL; } /* according to PKCS#11, label, ID, issuer, and serial number diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index c51f38a2c..abc8e55df 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -1576,6 +1576,8 @@ PK11_MakeIDFromPubKey(SECItem *pubKeyData) { return certCKA_ID; } +extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; + /* * Write the cert into the token. */ @@ -1800,6 +1802,11 @@ done: emailAddr, PR_TRUE); if (!certobj) { + if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) { + PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); + SECITEM_FreeItem(keyID,PR_TRUE); + return SECFailure; + } goto loser; } /* add the new instance to the cert, force an update of the diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c index c05f9af40..420dc2203 100644 --- a/security/nss/lib/pkcs12/p12d.c +++ b/security/nss/lib/pkcs12/p12d.c @@ -2337,7 +2337,7 @@ sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx) derCert, NULL, PR_FALSE, PR_FALSE); if(!newCert) { if(nickName) SECITEM_ZfreeItem(nickName, PR_TRUE); - cert->error = SEC_ERROR_NO_MEMORY; + cert->error = PORT_GetError(); cert->problem = PR_TRUE; return SECFailure; } diff --git a/security/nss/lib/util/secerr.h b/security/nss/lib/util/secerr.h index 829dcf708..525ed513b 100644 --- a/security/nss/lib/util/secerr.h +++ b/security/nss/lib/util/secerr.h @@ -182,7 +182,8 @@ SEC_ERROR_DIGEST_NOT_FOUND = (SEC_ERROR_BASE + 133), SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE = (SEC_ERROR_BASE + 134), SEC_ERROR_MODULE_STUCK = (SEC_ERROR_BASE + 135), SEC_ERROR_BAD_TEMPLATE = (SEC_ERROR_BASE + 136), -SEC_ERROR_CRL_NOT_FOUND = (SEC_ERROR_BASE + 137) +SEC_ERROR_CRL_NOT_FOUND = (SEC_ERROR_BASE + 137), +SEC_ERROR_REUSED_ISSUER_AND_SERIAL = (SEC_ERROR_BASE + 138) } SECErrorCodes; #endif /* NO_SECURITY_ERROR_ENUM */ |