summaryrefslogtreecommitdiff
path: root/security/nss/lib/pki/pkistore.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/pki/pkistore.c')
-rw-r--r--security/nss/lib/pki/pkistore.c96
1 files changed, 80 insertions, 16 deletions
diff --git a/security/nss/lib/pki/pkistore.c b/security/nss/lib/pki/pkistore.c
index ed35c9749..e44051b9e 100644
--- a/security/nss/lib/pki/pkistore.c
+++ b/security/nss/lib/pki/pkistore.c
@@ -89,6 +89,14 @@ struct certificate_hash_entry_str
nssSMIMEProfile *profile;
};
+/* forward static declarations */
+static NSSCertificate *
+nssCertStore_FindCertByIssuerAndSerialNumberLocked (
+ nssCertificateStore *store,
+ NSSDER *issuer,
+ NSSDER *serial
+);
+
NSS_IMPLEMENT nssCertificateStore *
nssCertificateStore_Create (
NSSArena *arenaOpt
@@ -225,29 +233,46 @@ remove_certificate_entry (
NSSCertificate *cert
);
-NSS_IMPLEMENT PRStatus
-nssCertificateStore_Add (
+/* Caller must hold store->lock */
+static PRStatus
+nssCertificateStore_AddLocked (
nssCertificateStore *store,
NSSCertificate *cert
)
{
- PRStatus nssrv;
- PZ_Lock(store->lock);
- if (nssHash_Exists(store->issuer_and_serial, cert)) {
- PZ_Unlock(store->lock);
- return PR_SUCCESS;
- }
- nssrv = add_certificate_entry(store, cert);
+ PRStatus nssrv = add_certificate_entry(store, cert);
if (nssrv == PR_SUCCESS) {
nssrv = add_subject_entry(store, cert);
if (nssrv == PR_FAILURE) {
remove_certificate_entry(store, cert);
}
}
- PZ_Unlock(store->lock);
return nssrv;
}
+
+NSS_IMPLEMENT NSSCertificate *
+nssCertificateStore_FindOrAdd (
+ nssCertificateStore *store,
+ NSSCertificate *c
+)
+{
+ PRStatus nssrv;
+ NSSCertificate *rvCert = NULL;
+
+ PZ_Lock(store->lock);
+ rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked(
+ store, &c->issuer, &c->serial);
+ if (!rvCert) {
+ nssrv = nssCertificateStore_AddLocked(store, c);
+ if (PR_SUCCESS == nssrv) {
+ rvCert = nssCertificate_AddRef(c);
+ }
+ }
+ PZ_Unlock(store->lock);
+ return rvCert;
+}
+
static void
remove_certificate_entry (
nssCertificateStore *store,
@@ -313,18 +338,41 @@ nssCertificateStore_RemoveCertLOCKED (
NSS_IMPLEMENT void
nssCertificateStore_Lock (
- nssCertificateStore *store
+ nssCertificateStore *store, nssCertificateStoreTrace* out
)
{
+#ifdef DEBUG
+ PORT_Assert(out);
+ out->store = store;
+ out->lock = store->lock;
+ out->locked = PR_TRUE;
+ PZ_Lock(out->lock);
+#else
PZ_Lock(store->lock);
+#endif
}
NSS_IMPLEMENT void
nssCertificateStore_Unlock (
- nssCertificateStore *store
+ nssCertificateStore *store, nssCertificateStoreTrace* in,
+ nssCertificateStoreTrace* out
)
{
+#ifdef DEBUG
+ PORT_Assert(in);
+ PORT_Assert(out);
+ out->store = store;
+ out->lock = store->lock;
+ out->unlocked = PR_TRUE;
+
+ PORT_Assert(in->store == out->store);
+ PORT_Assert(in->lock == out->lock);
+ PORT_Assert(in->locked);
+
+ PZ_Unlock(out->lock);
+#else
PZ_Unlock(store->lock);
+#endif
}
static NSSCertificate **
@@ -501,24 +549,40 @@ nssCertificateStore_FindCertificatesByEmail (
return rvArray;
}
-NSS_IMPLEMENT NSSCertificate *
-nssCertificateStore_FindCertificateByIssuerAndSerialNumber (
+/* Caller holds store->lock */
+static NSSCertificate *
+nssCertStore_FindCertByIssuerAndSerialNumberLocked (
nssCertificateStore *store,
NSSDER *issuer,
NSSDER *serial
)
{
certificate_hash_entry *entry;
- NSSCertificate index;
NSSCertificate *rvCert = NULL;
+ NSSCertificate index;
+
index.issuer = *issuer;
index.serial = *serial;
- PZ_Lock(store->lock);
entry = (certificate_hash_entry *)
nssHash_Lookup(store->issuer_and_serial, &index);
if (entry) {
rvCert = nssCertificate_AddRef(entry->cert);
}
+ return rvCert;
+}
+
+NSS_IMPLEMENT NSSCertificate *
+nssCertificateStore_FindCertificateByIssuerAndSerialNumber (
+ nssCertificateStore *store,
+ NSSDER *issuer,
+ NSSDER *serial
+)
+{
+ NSSCertificate *rvCert = NULL;
+
+ PZ_Lock(store->lock);
+ rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked (
+ store, issuer, serial);
PZ_Unlock(store->lock);
return rvCert;
}