diff options
Diffstat (limited to 'security/nss/lib/pki/pkistore.c')
-rw-r--r-- | security/nss/lib/pki/pkistore.c | 96 |
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; } |