summaryrefslogtreecommitdiff
path: root/security/nss
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss')
-rw-r--r--security/nss/cmd/lib/SECerrs.h5
-rw-r--r--security/nss/lib/base/errorval.c1
-rw-r--r--security/nss/lib/certdb/stanpcertdb.c15
-rw-r--r--security/nss/lib/dev/devtoken.c29
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c7
-rw-r--r--security/nss/lib/pkcs12/p12d.c2
-rw-r--r--security/nss/lib/util/secerr.h3
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 */