2
* The contents of this file are subject to the Mozilla Public
3
* License Version 1.1 (the "License"); you may not use this file
4
* except in compliance with the License. You may obtain a copy of
5
* the License at http://www.mozilla.org/MPL/
7
* Software distributed under the License is distributed on an "AS
8
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9
* implied. See the License for the specific language governing
10
* rights and limitations under the License.
12
* The Original Code is the Netscape security libraries.
14
* The Initial Developer of the Original Code is Netscape
15
* Communications Corporation. Portions created by Netscape are
16
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
21
* Alternatively, the contents of this file may be used under the
22
* terms of the GNU General Public License Version 2 or later (the
23
* "GPL"), in which case the provisions of the GPL are applicable
24
* instead of those above. If you wish to allow use of your
25
* version of this file only under the terms of the GPL and not to
26
* allow others to use your version of this file under the MPL,
27
* indicate your decision by deleting the provisions above and
28
* replace them with the notice and other provisions required by
29
* the GPL. If you do not delete the provisions above, a recipient
30
* may use your version of this file under either the MPL or the
35
static const char CVS_ID[] = "@(#) $RCSfile: tdcache.c,v $ $Revision: 1.38 $ $Date: 2003/12/19 22:33:12 $ $Name: FIREFOX_1_0_RELEASE $";
56
#endif /* NSSBASE_H */
69
static PRLogModuleInfo *s_log = NULL;
73
static void log_item_dump(const char *msg, NSSItem *it)
77
for (i=0; i<10 && i<it->size; i++) {
78
sprintf(&buf[2*i], "%02X", ((PRUint8 *)it->data)[i]);
81
sprintf(&buf[2*i], "..");
83
for (j=it->size-1; i<=16 && j>10; i++, j--) {
84
sprintf(&buf[2*i], "%02X", ((PRUint8 *)it->data)[j]);
87
PR_LOG(s_log, PR_LOG_DEBUG, ("%s: %s", msg, buf));
92
static void log_cert_ref(const char *msg, NSSCertificate *c)
94
PR_LOG(s_log, PR_LOG_DEBUG, ("%s: %s", msg,
95
(c->nickname) ? c->nickname : c->email));
96
log_item_dump("\tserial", &c->serial);
97
log_item_dump("\tsubject", &c->subject);
101
/* Certificate cache routines */
104
* Locking is not handled well at all. A single, global lock with sub-locks
105
* in the collection types. Cleanup needed.
108
/* should it live in its own arena? */
109
struct nssTDCertificateCacheStr
113
nssHash *issuerAndSN;
119
struct cache_entry_str
122
NSSCertificate *cert;
132
typedef struct cache_entry_str cache_entry;
135
new_cache_entry(NSSArena *arena, void *value, PRBool ownArena)
137
cache_entry *ce = nss_ZNEW(arena, cache_entry);
139
ce->entry.value = value;
141
ce->lastHit = PR_Now();
150
/* sort the subject list from newest to oldest */
151
static PRIntn subject_list_sort(void *v1, void *v2)
153
NSSCertificate *c1 = (NSSCertificate *)v1;
154
NSSCertificate *c2 = (NSSCertificate *)v2;
155
nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1);
156
nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2);
157
if (dc1->isNewerThan(dc1, dc2)) {
164
/* this should not be exposed in a header, but is here to keep the above
165
* types/functions static
167
NSS_IMPLEMENT PRStatus
168
nssTrustDomain_InitializeCache (
174
nssTDCertificateCache *cache = td->cache;
176
s_log = PR_NewLogModule("nss_cache");
180
arena = nssArena_Create();
184
cache = nss_ZNEW(arena, nssTDCertificateCache);
186
nssArena_Destroy(arena);
189
cache->lock = PZ_NewLock(nssILockCache);
191
nssArena_Destroy(arena);
194
/* Create the issuer and serial DER --> certificate hash */
195
cache->issuerAndSN = nssHash_CreateCertificate(arena, cacheSize);
196
if (!cache->issuerAndSN) {
199
/* Create the subject DER --> subject list hash */
200
cache->subject = nssHash_CreateItem(arena, cacheSize);
201
if (!cache->subject) {
204
/* Create the nickname --> subject list hash */
205
cache->nickname = nssHash_CreateString(arena, cacheSize);
206
if (!cache->nickname) {
209
/* Create the email --> list of subject lists hash */
210
cache->email = nssHash_CreateString(arena, cacheSize);
214
cache->arena = arena;
217
PR_LOG(s_log, PR_LOG_DEBUG, ("Cache initialized."));
221
PZ_DestroyLock(cache->lock);
222
nssArena_Destroy(arena);
225
PR_LOG(s_log, PR_LOG_DEBUG, ("Cache initialization failed."));
230
/* The entries of the hashtable are currently dependent on the certificate(s)
231
* that produced them. That is, the entries will be freed when the cert is
232
* released from the cache. If there are certs in the cache at any time,
233
* including shutdown, the hash table entries will hold memory. In order for
234
* clean shutdown, it is necessary for there to be no certs in the cache.
237
extern const NSSError NSS_ERROR_INTERNAL_ERROR;
238
extern const NSSError NSS_ERROR_BUSY;
240
NSS_IMPLEMENT PRStatus
241
nssTrustDomain_DestroyCache (
246
nss_SetError(NSS_ERROR_INTERNAL_ERROR);
249
if (nssHash_Count(td->cache->issuerAndSN) > 0) {
250
nss_SetError(NSS_ERROR_BUSY);
253
PZ_DestroyLock(td->cache->lock);
254
nssHash_Destroy(td->cache->issuerAndSN);
255
nssHash_Destroy(td->cache->subject);
256
nssHash_Destroy(td->cache->nickname);
257
nssHash_Destroy(td->cache->email);
258
nssArena_Destroy(td->cache->arena);
261
PR_LOG(s_log, PR_LOG_DEBUG, ("Cache destroyed."));
267
remove_issuer_and_serial_entry (
268
nssTDCertificateCache *cache,
272
/* Remove the cert from the issuer/serial hash */
273
nssHash_Remove(cache->issuerAndSN, cert);
275
log_cert_ref("removed issuer/sn", cert);
281
remove_subject_entry (
282
nssTDCertificateCache *cache,
283
NSSCertificate *cert,
284
nssList **subjectList,
293
/* Get the subject list for the cert's subject */
294
ce = (cache_entry *)nssHash_Lookup(cache->subject, &cert->subject);
296
/* Remove the cert from the subject hash */
297
nssList_Remove(ce->entry.list, cert);
298
*subjectList = ce->entry.list;
299
*nickname = ce->nickname;
303
log_cert_ref("removed cert", cert);
304
log_item_dump("from subject list", &cert->subject);
313
remove_nickname_entry (
314
nssTDCertificateCache *cache,
321
nssHash_Remove(cache->nickname, nickname);
324
PR_LOG(s_log, PR_LOG_DEBUG, ("removed nickname %s", nickname));
334
nssTDCertificateCache *cache,
335
NSSCertificate *cert,
339
PRStatus nssrv = PR_FAILURE;
341
/* Find the subject list in the email hash */
343
ce = (cache_entry *)nssHash_Lookup(cache->email, cert->email);
345
nssList *subjects = ce->entry.list;
346
/* Remove the subject list from the email hash */
347
nssList_Remove(subjects, subjectList);
349
log_item_dump("removed subject list", &cert->subject);
350
PR_LOG(s_log, PR_LOG_DEBUG, ("for email %s", cert->email));
352
if (nssList_Count(subjects) == 0) {
353
/* No more subject lists for email, delete list and
356
(void)nssList_Destroy(subjects);
357
nssHash_Remove(cache->email, cert->email);
358
/* there are no entries left for this address, free space
359
* used for email entries
361
nssArena_Destroy(ce->arena);
363
PR_LOG(s_log, PR_LOG_DEBUG, ("removed email %s", cert->email));
373
nssTrustDomain_RemoveCertFromCacheLOCKED (
378
nssList *subjectList;
384
log_cert_ref("attempt to remove cert", cert);
386
ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, cert);
387
if (!ce || ce->entry.cert != cert) {
388
/* If it's not in the cache, or a different cert is (this is really
389
* for safety reasons, though it shouldn't happen), do nothing
392
PR_LOG(s_log, PR_LOG_DEBUG, ("but it wasn't in the cache"));
396
(void)remove_issuer_and_serial_entry(td->cache, cert);
397
(void)remove_subject_entry(td->cache, cert, &subjectList,
399
if (nssList_Count(subjectList) == 0) {
400
(void)remove_nickname_entry(td->cache, nickname, subjectList);
401
(void)remove_email_entry(td->cache, cert, subjectList);
402
(void)nssList_Destroy(subjectList);
403
nssHash_Remove(td->cache->subject, &cert->subject);
404
/* there are no entries left for this subject, free the space used
405
* for both the nickname and subject entries
408
nssArena_Destroy(arena);
414
nssTrustDomain_LockCertCache (
418
PZ_Lock(td->cache->lock);
422
nssTrustDomain_UnlockCertCache (
426
PZ_Unlock(td->cache->lock);
429
struct token_cert_dtor {
431
nssTDCertificateCache *cache;
432
NSSCertificate **certs;
433
PRUint32 numCerts, arrSize;
437
remove_token_certs(const void *k, void *v, void *a)
439
NSSCertificate *c = (NSSCertificate *)k;
440
nssPKIObject *object = &c->object;
441
struct token_cert_dtor *dtor = a;
443
PZ_Lock(object->lock);
444
for (i=0; i<object->numInstances; i++) {
445
if (object->instances[i]->token == dtor->token) {
446
nssCryptokiObject_Destroy(object->instances[i]);
447
object->instances[i] = object->instances[object->numInstances-1];
448
object->instances[object->numInstances-1] = NULL;
449
object->numInstances--;
450
dtor->certs[dtor->numCerts++] = c;
451
if (dtor->numCerts == dtor->arrSize) {
453
dtor->certs = nss_ZREALLOCARRAY(dtor->certs,
460
PZ_Unlock(object->lock);
465
* Remove all certs for the given token from the cache. This is
466
* needed if the token is removed.
468
NSS_IMPLEMENT PRStatus
469
nssTrustDomain_RemoveTokenCertsFromCache (
474
NSSCertificate **certs;
475
PRUint32 i, arrSize = 10;
476
struct token_cert_dtor dtor;
477
certs = nss_ZNEWARRAY(NULL, NSSCertificate *, arrSize);
481
dtor.cache = td->cache;
485
dtor.arrSize = arrSize;
486
PZ_Lock(td->cache->lock);
487
nssHash_Iterate(td->cache->issuerAndSN, remove_token_certs, (void *)&dtor);
488
for (i=0; i<dtor.numCerts; i++) {
489
if (dtor.certs[i]->object.numInstances == 0) {
490
nssTrustDomain_RemoveCertFromCacheLOCKED(td, dtor.certs[i]);
491
dtor.certs[i] = NULL; /* skip this cert in the second for loop */
494
PZ_Unlock(td->cache->lock);
495
for (i=0; i<dtor.numCerts; i++) {
497
STAN_ForceCERTCertificateUpdate(dtor.certs[i]);
500
nss_ZFreeIf(dtor.certs);
504
NSS_IMPLEMENT PRStatus
505
nssTrustDomain_UpdateCachedTokenCerts (
510
NSSCertificate **cp, **cached = NULL;
513
certList = nssList_Create(NULL, PR_FALSE);
514
if (!certList) return PR_FAILURE;
515
(void *)nssTrustDomain_GetCertsFromCache(td, certList);
516
count = nssList_Count(certList);
518
cached = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
522
nssList_GetArray(certList, (void **)cached, count);
523
nssList_Destroy(certList);
524
for (cp = cached; *cp; cp++) {
525
nssCryptokiObject *instance;
526
NSSCertificate *c = *cp;
527
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
528
instance = nssToken_FindCertificateByIssuerAndSerialNumber(
536
nssPKIObject_AddInstance(&c->object, instance);
537
STAN_ForceCERTCertificateUpdate(c);
540
nssCertificateArray_Destroy(cached);
546
add_issuer_and_serial_entry (
548
nssTDCertificateCache *cache,
553
ce = new_cache_entry(arena, (void *)cert, PR_FALSE);
555
log_cert_ref("added to issuer/sn", cert);
557
return nssHash_Add(cache->issuerAndSN, cert, (void *)ce);
563
nssTDCertificateCache *cache,
564
NSSCertificate *cert,
566
nssList **subjectList
572
*subjectList = NULL; /* this is only set if a new one is created */
573
ce = (cache_entry *)nssHash_Lookup(cache->subject, &cert->subject);
576
ce->lastHit = PR_Now();
577
/* The subject is already in, add this cert to the list */
578
nssrv = nssList_AddUnique(ce->entry.list, cert);
580
log_cert_ref("added to existing subject list", cert);
584
/* Create a new subject list for the subject */
585
list = nssList_Create(arena, PR_FALSE);
589
ce = new_cache_entry(arena, (void *)list, PR_TRUE);
594
ce->nickname = nssUTF8_Duplicate(nickname, arena);
596
nssList_SetSortFunction(list, subject_list_sort);
597
/* Add the cert entry to this list of subjects */
598
nssrv = nssList_AddUnique(list, cert);
599
if (nssrv != PR_SUCCESS) {
602
/* Add the subject list to the cache */
603
subject = nssItem_Duplicate(&cert->subject, arena, NULL);
607
nssrv = nssHash_Add(cache->subject, subject, ce);
608
if (nssrv != PR_SUCCESS) {
613
log_cert_ref("created subject list", cert);
622
nssTDCertificateCache *cache,
623
NSSUTF8 *certNickname,
627
PRStatus nssrv = PR_SUCCESS;
629
ce = (cache_entry *)nssHash_Lookup(cache->nickname, certNickname);
631
/* This is a collision. A nickname entry already exists for this
632
* subject, but a subject entry didn't. This would imply there are
633
* two subjects using the same nickname, which is not allowed.
638
ce = new_cache_entry(arena, subjectList, PR_FALSE);
642
nickname = nssUTF8_Duplicate(certNickname, arena);
646
nssrv = nssHash_Add(cache->nickname, nickname, ce);
648
log_cert_ref("created nickname for", cert);
656
nssTDCertificateCache *cache,
657
NSSCertificate *cert,
661
PRStatus nssrv = PR_SUCCESS;
664
ce = (cache_entry *)nssHash_Lookup(cache->email, cert->email);
666
/* Already have an entry for this email address, but not subject */
667
subjects = ce->entry.list;
668
nssrv = nssList_AddUnique(subjects, subjectList);
670
ce->lastHit = PR_Now();
672
log_cert_ref("added subject to email for", cert);
677
arena = nssArena_Create();
681
/* Create a new list of subject lists, add this subject */
682
subjects = nssList_Create(arena, PR_TRUE);
684
nssArena_Destroy(arena);
687
/* Add the new subject to the list */
688
nssrv = nssList_AddUnique(subjects, subjectList);
689
if (nssrv != PR_SUCCESS) {
690
nssArena_Destroy(arena);
693
/* Add the new entry to the cache */
694
ce = new_cache_entry(arena, (void *)subjects, PR_TRUE);
696
nssArena_Destroy(arena);
699
email = nssUTF8_Duplicate(cert->email, arena);
701
nssArena_Destroy(arena);
704
nssrv = nssHash_Add(cache->email, email, ce);
705
if (nssrv != PR_SUCCESS) {
706
nssArena_Destroy(arena);
710
log_cert_ref("created email for", cert);
716
extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE;
719
remove_object_instances (
720
nssPKIObject *object,
721
nssCryptokiObject **instances,
727
for (i = 0; i < numInstances; i++) {
728
nssPKIObject_RemoveInstanceForToken(object, instances[i]->token);
733
merge_object_instances (
738
nssCryptokiObject **instances, **ci;
740
SECStatus rv = SECSuccess;
742
instances = nssPKIObject_GetInstances(from);
743
if (instances == NULL) {
746
for (ci = instances, i = 0; *ci; ci++, i++) {
747
nssCryptokiObject *instance = nssCryptokiObject_Clone(*ci);
749
if (nssPKIObject_AddInstance(to, instance) == SECSuccess) {
752
nssCryptokiObject_Destroy(instance);
754
remove_object_instances(to, instances, i);
758
nssCryptokiObjectArray_Destroy(instances);
762
static NSSCertificate *
768
NSSArena *arena = NULL;
769
nssList *subjectList = NULL;
773
NSSCertificate *rvCert = NULL;
774
NSSUTF8 *certNickname = nssCertificate_GetNickname(cert, NULL);
776
PZ_Lock(td->cache->lock);
777
/* If it exists in the issuer/serial hash, it's already in all */
778
ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, cert);
781
ce->lastHit = PR_Now();
782
rvCert = nssCertificate_AddRef(ce->entry.cert);
784
log_cert_ref("attempted to add cert already in cache", cert);
786
PZ_Unlock(td->cache->lock);
787
/* collision - somebody else already added the cert
788
* to the cache before this thread got around to it.
790
/* merge the instances of the cert */
791
if (merge_object_instances(&rvCert->object, &cert->object)
793
nssCertificate_Destroy(rvCert);
796
STAN_ForceCERTCertificateUpdate(rvCert);
797
nssCertificate_Destroy(cert);
800
/* create a new cache entry for this cert within the cert's arena*/
801
nssrv = add_issuer_and_serial_entry(cert->object.arena, td->cache, cert);
802
if (nssrv != PR_SUCCESS) {
806
/* create an arena for the nickname and subject entries */
807
arena = nssArena_Create();
811
/* create a new subject list for this cert, or add to existing */
812
nssrv = add_subject_entry(arena, td->cache, cert,
813
certNickname, &subjectList);
814
if (nssrv != PR_SUCCESS) {
818
/* If a new subject entry was created, also need nickname and/or email */
819
if (subjectList != NULL) {
820
PRBool handle = PR_FALSE;
822
nssrv = add_nickname_entry(arena, td->cache,
823
certNickname, subjectList);
824
if (nssrv != PR_SUCCESS) {
831
nssrv = add_email_entry(td->cache, cert, subjectList);
832
if (nssrv != PR_SUCCESS) {
839
/* I think either a nickname or email address must be associated
840
* with the cert. However, certs are passed to NewTemp without
841
* either. This worked in the old code, so it must work now.
844
/* Require either nickname or email handle */
851
PZ_Unlock(td->cache->lock);
854
/* Remove any handles that have been created */
857
(void)remove_issuer_and_serial_entry(td->cache, cert);
860
(void)remove_subject_entry(td->cache, cert, &subjectList,
861
&certNickname, &arena);
863
if (added == 3 || added == 5) {
864
(void)remove_nickname_entry(td->cache, certNickname, subjectList);
867
(void)remove_email_entry(td->cache, cert, subjectList);
870
nssHash_Remove(td->cache->subject, &cert->subject);
871
nssList_Destroy(subjectList);
874
nssArena_Destroy(arena);
876
PZ_Unlock(td->cache->lock);
880
NSS_IMPLEMENT PRStatus
881
nssTrustDomain_AddCertsToCache (
883
NSSCertificate **certs,
889
for (i=0; i<numCerts && certs[i]; i++) {
890
c = add_cert_to_cache(td, certs[i]);
900
static NSSCertificate **
901
collect_subject_certs (
902
nssList *subjectList,
903
nssList *rvCertListOpt
907
NSSCertificate **rvArray = NULL;
909
nssCertificateList_AddReferences(subjectList);
911
nssListIterator *iter = nssList_CreateIterator(subjectList);
912
for (c = (NSSCertificate *)nssListIterator_Start(iter);
913
c != (NSSCertificate *)NULL;
914
c = (NSSCertificate *)nssListIterator_Next(iter)) {
915
nssList_Add(rvCertListOpt, c);
917
nssListIterator_Finish(iter);
918
nssListIterator_Destroy(iter);
920
count = nssList_Count(subjectList);
921
rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
923
return (NSSCertificate **)NULL;
925
nssList_GetArray(subjectList, (void **)rvArray, count);
931
* Find all cached certs with this subject.
933
NSS_IMPLEMENT NSSCertificate **
934
nssTrustDomain_GetCertsForSubjectFromCache (
940
NSSCertificate **rvArray = NULL;
943
log_item_dump("looking for cert by subject", subject);
945
PZ_Lock(td->cache->lock);
946
ce = (cache_entry *)nssHash_Lookup(td->cache->subject, subject);
949
ce->lastHit = PR_Now();
951
PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
953
rvArray = collect_subject_certs(ce->entry.list, certListOpt);
955
PZ_Unlock(td->cache->lock);
960
* Find all cached certs with this label.
962
NSS_IMPLEMENT NSSCertificate **
963
nssTrustDomain_GetCertsForNicknameFromCache (
969
NSSCertificate **rvArray = NULL;
972
PR_LOG(s_log, PR_LOG_DEBUG, ("looking for cert by nick %s", nickname));
974
PZ_Lock(td->cache->lock);
975
ce = (cache_entry *)nssHash_Lookup(td->cache->nickname, nickname);
978
ce->lastHit = PR_Now();
980
PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
982
rvArray = collect_subject_certs(ce->entry.list, certListOpt);
984
PZ_Unlock(td->cache->lock);
989
* Find all cached certs with this email address.
991
NSS_IMPLEMENT NSSCertificate **
992
nssTrustDomain_GetCertsForEmailAddressFromCache (
998
NSSCertificate **rvArray = NULL;
1000
nssList *collectList = NULL;
1001
nssListIterator *iter = NULL;
1002
nssList *subjectList;
1004
PR_LOG(s_log, PR_LOG_DEBUG, ("looking for cert by email %s", email));
1006
PZ_Lock(td->cache->lock);
1007
ce = (cache_entry *)nssHash_Lookup(td->cache->email, email);
1010
ce->lastHit = PR_Now();
1012
PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
1014
/* loop over subject lists and get refs for certs */
1016
collectList = certListOpt;
1018
collectList = nssList_Create(NULL, PR_FALSE);
1020
PZ_Unlock(td->cache->lock);
1024
iter = nssList_CreateIterator(ce->entry.list);
1026
PZ_Unlock(td->cache->lock);
1028
nssList_Destroy(collectList);
1032
for (subjectList = (nssList *)nssListIterator_Start(iter);
1033
subjectList != (nssList *)NULL;
1034
subjectList = (nssList *)nssListIterator_Next(iter)) {
1035
(void)collect_subject_certs(subjectList, collectList);
1037
nssListIterator_Finish(iter);
1038
nssListIterator_Destroy(iter);
1040
PZ_Unlock(td->cache->lock);
1041
if (!certListOpt && collectList) {
1042
PRUint32 count = nssList_Count(collectList);
1043
rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
1045
nssList_GetArray(collectList, (void **)rvArray, count);
1047
nssList_Destroy(collectList);
1053
* Look for a specific cert in the cache
1055
NSS_IMPLEMENT NSSCertificate *
1056
nssTrustDomain_GetCertForIssuerAndSNFromCache (
1062
NSSCertificate certkey;
1063
NSSCertificate *rvCert = NULL;
1065
certkey.issuer.data = issuer->data;
1066
certkey.issuer.size = issuer->size;
1067
certkey.serial.data = serial->data;
1068
certkey.serial.size = serial->size;
1070
log_item_dump("looking for cert by issuer/sn, issuer", issuer);
1071
log_item_dump(" serial", serial);
1073
PZ_Lock(td->cache->lock);
1074
ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, &certkey);
1077
ce->lastHit = PR_Now();
1078
rvCert = nssCertificate_AddRef(ce->entry.cert);
1080
PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
1083
PZ_Unlock(td->cache->lock);
1089
issuer_and_serial_from_encoding (
1095
SECItem derCert, derIssuer, derSerial;
1097
derCert.data = (unsigned char *)encoding->data;
1098
derCert.len = encoding->size;
1099
secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer);
1100
if (secrv != SECSuccess) {
1103
secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial);
1104
if (secrv != SECSuccess) {
1107
issuer->data = derIssuer.data;
1108
issuer->size = derIssuer.len;
1109
serial->data = derSerial.data;
1110
serial->size = derSerial.len;
1116
* Look for a specific cert in the cache
1118
NSS_IMPLEMENT NSSCertificate *
1119
nssTrustDomain_GetCertByDERFromCache (
1124
PRStatus nssrv = PR_FAILURE;
1125
NSSDER issuer, serial;
1126
NSSCertificate *rvCert;
1128
nssrv = issuer_and_serial_from_encoding(der, &issuer, &serial);
1130
if (nssrv != PR_SUCCESS) {
1134
log_item_dump("looking for cert by DER", der);
1136
rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
1139
PORT_Free(issuer.data);
1140
PORT_Free(serial.data);
1145
static void cert_iter(const void *k, void *v, void *a)
1147
nssList *certList = (nssList *)a;
1148
NSSCertificate *c = (NSSCertificate *)k;
1149
nssList_Add(certList, nssCertificate_AddRef(c));
1152
NSS_EXTERN NSSCertificate **
1153
nssTrustDomain_GetCertsFromCache (
1155
nssList *certListOpt
1158
NSSCertificate **rvArray = NULL;
1161
certList = certListOpt;
1163
certList = nssList_Create(NULL, PR_FALSE);
1165
PZ_Lock(td->cache->lock);
1166
nssHash_Iterate(td->cache->issuerAndSN, cert_iter, (void *)certList);
1167
PZ_Unlock(td->cache->lock);
1169
PRUint32 count = nssList_Count(certList);
1170
rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
1171
nssList_GetArray(certList, (void **)rvArray, count);
1172
/* array takes the references */
1173
nssList_Destroy(certList);
1179
nssTrustDomain_DumpCacheInfo (
1181
void (* cert_dump_iter)(const void *, void *, void *),
1185
PZ_Lock(td->cache->lock);
1186
nssHash_Iterate(td->cache->issuerAndSN, cert_dump_iter, arg);
1187
PZ_Unlock(td->cache->lock);