Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(648)

Side by Side Diff: mozilla/security/nss/lib/pki/pkistore.c

Issue 14249009: Change the NSS and NSPR source tree to the new directory structure to be (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « mozilla/security/nss/lib/pki/pkistore.h ('k') | mozilla/security/nss/lib/pki/pkit.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #ifdef DEBUG
6 static const char CVS_ID[] = "@(#) $RCSfile: pkistore.c,v $ $Revision: 1.36 $ $D ate: 2012/05/17 21:39:40 $";
7 #endif /* DEBUG */
8
9 #ifndef PKIM_H
10 #include "pkim.h"
11 #endif /* PKIM_H */
12
13 #ifndef PKI_H
14 #include "pki.h"
15 #endif /* PKI_H */
16
17 #ifndef NSSPKI_H
18 #include "nsspki.h"
19 #endif /* NSSPKI_H */
20
21 #ifndef BASE_H
22 #include "base.h"
23 #endif /* BASE_H */
24
25 #ifndef PKISTORE_H
26 #include "pkistore.h"
27 #endif /* PKISTORE_H */
28
29 #include "cert.h"
30
31 #include "prbit.h"
32
33 /*
34 * Certificate Store
35 *
36 * This differs from the cache in that it is a true storage facility. Items
37 * stay in until they are explicitly removed. It is only used by crypto
38 * contexts at this time, but may be more generally useful...
39 *
40 */
41
42 struct nssCertificateStoreStr
43 {
44 PRBool i_alloced_arena;
45 NSSArena *arena;
46 PZLock *lock;
47 nssHash *subject;
48 nssHash *issuer_and_serial;
49 };
50
51 typedef struct certificate_hash_entry_str certificate_hash_entry;
52
53 struct certificate_hash_entry_str
54 {
55 NSSCertificate *cert;
56 NSSTrust *trust;
57 nssSMIMEProfile *profile;
58 };
59
60 /* forward static declarations */
61 static NSSCertificate *
62 nssCertStore_FindCertByIssuerAndSerialNumberLocked (
63 nssCertificateStore *store,
64 NSSDER *issuer,
65 NSSDER *serial
66 );
67
68 NSS_IMPLEMENT nssCertificateStore *
69 nssCertificateStore_Create (
70 NSSArena *arenaOpt
71 )
72 {
73 NSSArena *arena;
74 nssCertificateStore *store;
75 PRBool i_alloced_arena;
76 if (arenaOpt) {
77 arena = arenaOpt;
78 i_alloced_arena = PR_FALSE;
79 } else {
80 arena = nssArena_Create();
81 if (!arena) {
82 return NULL;
83 }
84 i_alloced_arena = PR_TRUE;
85 }
86 store = nss_ZNEW(arena, nssCertificateStore);
87 if (!store) {
88 goto loser;
89 }
90 store->lock = PZ_NewLock(nssILockOther);
91 if (!store->lock) {
92 goto loser;
93 }
94 /* Create the issuer/serial --> {cert, trust, S/MIME profile } hash */
95 store->issuer_and_serial = nssHash_CreateCertificate(arena, 0);
96 if (!store->issuer_and_serial) {
97 goto loser;
98 }
99 /* Create the subject DER --> subject list hash */
100 store->subject = nssHash_CreateItem(arena, 0);
101 if (!store->subject) {
102 goto loser;
103 }
104 store->arena = arena;
105 store->i_alloced_arena = i_alloced_arena;
106 return store;
107 loser:
108 if (store) {
109 if (store->lock) {
110 PZ_DestroyLock(store->lock);
111 }
112 if (store->issuer_and_serial) {
113 nssHash_Destroy(store->issuer_and_serial);
114 }
115 if (store->subject) {
116 nssHash_Destroy(store->subject);
117 }
118 }
119 if (i_alloced_arena) {
120 nssArena_Destroy(arena);
121 }
122 return NULL;
123 }
124
125 extern const NSSError NSS_ERROR_BUSY;
126
127 NSS_IMPLEMENT PRStatus
128 nssCertificateStore_Destroy (
129 nssCertificateStore *store
130 )
131 {
132 if (nssHash_Count(store->issuer_and_serial) > 0) {
133 nss_SetError(NSS_ERROR_BUSY);
134 return PR_FAILURE;
135 }
136 PZ_DestroyLock(store->lock);
137 nssHash_Destroy(store->issuer_and_serial);
138 nssHash_Destroy(store->subject);
139 if (store->i_alloced_arena) {
140 nssArena_Destroy(store->arena);
141 } else {
142 nss_ZFreeIf(store);
143 }
144 return PR_SUCCESS;
145 }
146
147 static PRStatus
148 add_certificate_entry (
149 nssCertificateStore *store,
150 NSSCertificate *cert
151 )
152 {
153 PRStatus nssrv;
154 certificate_hash_entry *entry;
155 entry = nss_ZNEW(cert->object.arena, certificate_hash_entry);
156 if (!entry) {
157 return PR_FAILURE;
158 }
159 entry->cert = cert;
160 nssrv = nssHash_Add(store->issuer_and_serial, cert, entry);
161 if (nssrv != PR_SUCCESS) {
162 nss_ZFreeIf(entry);
163 }
164 return nssrv;
165 }
166
167 static PRStatus
168 add_subject_entry (
169 nssCertificateStore *store,
170 NSSCertificate *cert
171 )
172 {
173 PRStatus nssrv;
174 nssList *subjectList;
175 subjectList = (nssList *)nssHash_Lookup(store->subject, &cert->subject);
176 if (subjectList) {
177 /* The subject is already in, add this cert to the list */
178 nssrv = nssList_AddUnique(subjectList, cert);
179 } else {
180 /* Create a new subject list for the subject */
181 subjectList = nssList_Create(NULL, PR_FALSE);
182 if (!subjectList) {
183 return PR_FAILURE;
184 }
185 nssList_SetSortFunction(subjectList, nssCertificate_SubjectListSort);
186 /* Add the cert entry to this list of subjects */
187 nssrv = nssList_Add(subjectList, cert);
188 if (nssrv != PR_SUCCESS) {
189 return nssrv;
190 }
191 /* Add the subject list to the cache */
192 nssrv = nssHash_Add(store->subject, &cert->subject, subjectList);
193 }
194 return nssrv;
195 }
196
197 /* declared below */
198 static void
199 remove_certificate_entry (
200 nssCertificateStore *store,
201 NSSCertificate *cert
202 );
203
204 /* Caller must hold store->lock */
205 static PRStatus
206 nssCertificateStore_AddLocked (
207 nssCertificateStore *store,
208 NSSCertificate *cert
209 )
210 {
211 PRStatus nssrv = add_certificate_entry(store, cert);
212 if (nssrv == PR_SUCCESS) {
213 nssrv = add_subject_entry(store, cert);
214 if (nssrv == PR_FAILURE) {
215 remove_certificate_entry(store, cert);
216 }
217 }
218 return nssrv;
219 }
220
221
222 NSS_IMPLEMENT NSSCertificate *
223 nssCertificateStore_FindOrAdd (
224 nssCertificateStore *store,
225 NSSCertificate *c
226 )
227 {
228 PRStatus nssrv;
229 NSSCertificate *rvCert = NULL;
230
231 PZ_Lock(store->lock);
232 rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked(
233 store, &c->issuer, &c->serial);
234 if (!rvCert) {
235 nssrv = nssCertificateStore_AddLocked(store, c);
236 if (PR_SUCCESS == nssrv) {
237 rvCert = nssCertificate_AddRef(c);
238 }
239 }
240 PZ_Unlock(store->lock);
241 return rvCert;
242 }
243
244 static void
245 remove_certificate_entry (
246 nssCertificateStore *store,
247 NSSCertificate *cert
248 )
249 {
250 certificate_hash_entry *entry;
251 entry = (certificate_hash_entry *)
252 nssHash_Lookup(store->issuer_and_serial, cert);
253 if (entry) {
254 nssHash_Remove(store->issuer_and_serial, cert);
255 if (entry->trust) {
256 nssTrust_Destroy(entry->trust);
257 }
258 if (entry->profile) {
259 nssSMIMEProfile_Destroy(entry->profile);
260 }
261 nss_ZFreeIf(entry);
262 }
263 }
264
265 static void
266 remove_subject_entry (
267 nssCertificateStore *store,
268 NSSCertificate *cert
269 )
270 {
271 nssList *subjectList;
272 /* Get the subject list for the cert's subject */
273 subjectList = (nssList *)nssHash_Lookup(store->subject, &cert->subject);
274 if (subjectList) {
275 /* Remove the cert from the subject hash */
276 nssList_Remove(subjectList, cert);
277 nssHash_Remove(store->subject, &cert->subject);
278 if (nssList_Count(subjectList) == 0) {
279 nssList_Destroy(subjectList);
280 } else {
281 /* The cert being released may have keyed the subject entry.
282 * Since there are still subject certs around, get another and
283 * rekey the entry just in case.
284 */
285 NSSCertificate *subjectCert;
286 (void)nssList_GetArray(subjectList, (void **)&subjectCert, 1);
287 nssHash_Add(store->subject, &subjectCert->subject, subjectList);
288 }
289 }
290 }
291
292 NSS_IMPLEMENT void
293 nssCertificateStore_RemoveCertLOCKED (
294 nssCertificateStore *store,
295 NSSCertificate *cert
296 )
297 {
298 certificate_hash_entry *entry;
299 entry = (certificate_hash_entry *)
300 nssHash_Lookup(store->issuer_and_serial, cert);
301 if (entry && entry->cert == cert) {
302 remove_certificate_entry(store, cert);
303 remove_subject_entry(store, cert);
304 }
305 }
306
307 NSS_IMPLEMENT void
308 nssCertificateStore_Lock (
309 nssCertificateStore *store, nssCertificateStoreTrace* out
310 )
311 {
312 #ifdef DEBUG
313 PORT_Assert(out);
314 out->store = store;
315 out->lock = store->lock;
316 out->locked = PR_TRUE;
317 PZ_Lock(out->lock);
318 #else
319 PZ_Lock(store->lock);
320 #endif
321 }
322
323 NSS_IMPLEMENT void
324 nssCertificateStore_Unlock (
325 nssCertificateStore *store, const nssCertificateStoreTrace* in,
326 nssCertificateStoreTrace* out
327 )
328 {
329 #ifdef DEBUG
330 PORT_Assert(in);
331 PORT_Assert(out);
332 out->store = store;
333 out->lock = store->lock;
334 PORT_Assert(!out->locked);
335 out->unlocked = PR_TRUE;
336
337 PORT_Assert(in->store == out->store);
338 PORT_Assert(in->lock == out->lock);
339 PORT_Assert(in->locked);
340 PORT_Assert(!in->unlocked);
341
342 PZ_Unlock(out->lock);
343 #else
344 PZ_Unlock(store->lock);
345 #endif
346 }
347
348 static NSSCertificate **
349 get_array_from_list (
350 nssList *certList,
351 NSSCertificate *rvOpt[],
352 PRUint32 maximumOpt,
353 NSSArena *arenaOpt
354 )
355 {
356 PRUint32 count;
357 NSSCertificate **rvArray = NULL;
358 count = nssList_Count(certList);
359 if (count == 0) {
360 return NULL;
361 }
362 if (maximumOpt > 0) {
363 count = PR_MIN(maximumOpt, count);
364 }
365 if (rvOpt) {
366 nssList_GetArray(certList, (void **)rvOpt, count);
367 } else {
368 rvArray = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
369 if (rvArray) {
370 nssList_GetArray(certList, (void **)rvArray, count);
371 }
372 }
373 return rvArray;
374 }
375
376 NSS_IMPLEMENT NSSCertificate **
377 nssCertificateStore_FindCertificatesBySubject (
378 nssCertificateStore *store,
379 NSSDER *subject,
380 NSSCertificate *rvOpt[],
381 PRUint32 maximumOpt,
382 NSSArena *arenaOpt
383 )
384 {
385 NSSCertificate **rvArray = NULL;
386 nssList *subjectList;
387 PZ_Lock(store->lock);
388 subjectList = (nssList *)nssHash_Lookup(store->subject, subject);
389 if (subjectList) {
390 nssCertificateList_AddReferences(subjectList);
391 rvArray = get_array_from_list(subjectList,
392 rvOpt, maximumOpt, arenaOpt);
393 }
394 PZ_Unlock(store->lock);
395 return rvArray;
396 }
397
398 /* Because only subject indexing is implemented, all other lookups require
399 * full traversal (unfortunately, PLHashTable doesn't allow you to exit
400 * early from the enumeration). The assumptions are that 1) lookups by
401 * fields other than subject will be rare, and 2) the hash will not have
402 * a large number of entries. These assumptions will be tested.
403 *
404 * XXX
405 * For NSS 3.4, it is worth consideration to do all forms of indexing,
406 * because the only crypto context is global and persistent.
407 */
408
409 struct nickname_template_str
410 {
411 NSSUTF8 *nickname;
412 nssList *subjectList;
413 };
414
415 static void match_nickname(const void *k, void *v, void *a)
416 {
417 PRStatus nssrv;
418 NSSCertificate *c;
419 NSSUTF8 *nickname;
420 nssList *subjectList = (nssList *)v;
421 struct nickname_template_str *nt = (struct nickname_template_str *)a;
422 nssrv = nssList_GetArray(subjectList, (void **)&c, 1);
423 nickname = nssCertificate_GetNickname(c, NULL);
424 if (nssrv == PR_SUCCESS && nickname &&
425 nssUTF8_Equal(nickname, nt->nickname, &nssrv))
426 {
427 nt->subjectList = subjectList;
428 }
429 nss_ZFreeIf(nickname);
430 }
431
432 /*
433 * Find all cached certs with this label.
434 */
435 NSS_IMPLEMENT NSSCertificate **
436 nssCertificateStore_FindCertificatesByNickname (
437 nssCertificateStore *store,
438 const NSSUTF8 *nickname,
439 NSSCertificate *rvOpt[],
440 PRUint32 maximumOpt,
441 NSSArena *arenaOpt
442 )
443 {
444 NSSCertificate **rvArray = NULL;
445 struct nickname_template_str nt;
446 nt.nickname = (char*) nickname;
447 nt.subjectList = NULL;
448 PZ_Lock(store->lock);
449 nssHash_Iterate(store->subject, match_nickname, &nt);
450 if (nt.subjectList) {
451 nssCertificateList_AddReferences(nt.subjectList);
452 rvArray = get_array_from_list(nt.subjectList,
453 rvOpt, maximumOpt, arenaOpt);
454 }
455 PZ_Unlock(store->lock);
456 return rvArray;
457 }
458
459 struct email_template_str
460 {
461 NSSASCII7 *email;
462 nssList *emailList;
463 };
464
465 static void match_email(const void *k, void *v, void *a)
466 {
467 PRStatus nssrv;
468 NSSCertificate *c;
469 nssList *subjectList = (nssList *)v;
470 struct email_template_str *et = (struct email_template_str *)a;
471 nssrv = nssList_GetArray(subjectList, (void **)&c, 1);
472 if (nssrv == PR_SUCCESS &&
473 nssUTF8_Equal(c->email, et->email, &nssrv))
474 {
475 nssListIterator *iter = nssList_CreateIterator(subjectList);
476 if (iter) {
477 for (c = (NSSCertificate *)nssListIterator_Start(iter);
478 c != (NSSCertificate *)NULL;
479 c = (NSSCertificate *)nssListIterator_Next(iter))
480 {
481 nssList_Add(et->emailList, c);
482 }
483 nssListIterator_Finish(iter);
484 nssListIterator_Destroy(iter);
485 }
486 }
487 }
488
489 /*
490 * Find all cached certs with this email address.
491 */
492 NSS_IMPLEMENT NSSCertificate **
493 nssCertificateStore_FindCertificatesByEmail (
494 nssCertificateStore *store,
495 NSSASCII7 *email,
496 NSSCertificate *rvOpt[],
497 PRUint32 maximumOpt,
498 NSSArena *arenaOpt
499 )
500 {
501 NSSCertificate **rvArray = NULL;
502 struct email_template_str et;
503 et.email = email;
504 et.emailList = nssList_Create(NULL, PR_FALSE);
505 if (!et.emailList) {
506 return NULL;
507 }
508 PZ_Lock(store->lock);
509 nssHash_Iterate(store->subject, match_email, &et);
510 if (et.emailList) {
511 /* get references before leaving the store's lock protection */
512 nssCertificateList_AddReferences(et.emailList);
513 }
514 PZ_Unlock(store->lock);
515 if (et.emailList) {
516 rvArray = get_array_from_list(et.emailList,
517 rvOpt, maximumOpt, arenaOpt);
518 nssList_Destroy(et.emailList);
519 }
520 return rvArray;
521 }
522
523 /* Caller holds store->lock */
524 static NSSCertificate *
525 nssCertStore_FindCertByIssuerAndSerialNumberLocked (
526 nssCertificateStore *store,
527 NSSDER *issuer,
528 NSSDER *serial
529 )
530 {
531 certificate_hash_entry *entry;
532 NSSCertificate *rvCert = NULL;
533 NSSCertificate index;
534
535 index.issuer = *issuer;
536 index.serial = *serial;
537 entry = (certificate_hash_entry *)
538 nssHash_Lookup(store->issuer_and_serial, &index);
539 if (entry) {
540 rvCert = nssCertificate_AddRef(entry->cert);
541 }
542 return rvCert;
543 }
544
545 NSS_IMPLEMENT NSSCertificate *
546 nssCertificateStore_FindCertificateByIssuerAndSerialNumber (
547 nssCertificateStore *store,
548 NSSDER *issuer,
549 NSSDER *serial
550 )
551 {
552 NSSCertificate *rvCert = NULL;
553
554 PZ_Lock(store->lock);
555 rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked (
556 store, issuer, serial);
557 PZ_Unlock(store->lock);
558 return rvCert;
559 }
560
561 static PRStatus
562 issuer_and_serial_from_encoding (
563 NSSBER *encoding,
564 NSSDER *issuer,
565 NSSDER *serial
566 )
567 {
568 SECItem derCert, derIssuer, derSerial;
569 SECStatus secrv;
570 derCert.data = (unsigned char *)encoding->data;
571 derCert.len = encoding->size;
572 secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer);
573 if (secrv != SECSuccess) {
574 return PR_FAILURE;
575 }
576 secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial);
577 if (secrv != SECSuccess) {
578 PORT_Free(derIssuer.data);
579 return PR_FAILURE;
580 }
581 issuer->data = derIssuer.data;
582 issuer->size = derIssuer.len;
583 serial->data = derSerial.data;
584 serial->size = derSerial.len;
585 return PR_SUCCESS;
586 }
587
588 NSS_IMPLEMENT NSSCertificate *
589 nssCertificateStore_FindCertificateByEncodedCertificate (
590 nssCertificateStore *store,
591 NSSDER *encoding
592 )
593 {
594 PRStatus nssrv = PR_FAILURE;
595 NSSDER issuer, serial;
596 NSSCertificate *rvCert = NULL;
597 nssrv = issuer_and_serial_from_encoding(encoding, &issuer, &serial);
598 if (nssrv != PR_SUCCESS) {
599 return NULL;
600 }
601 rvCert = nssCertificateStore_FindCertificateByIssuerAndSerialNumber(store,
602 &issuer,
603 &serial);
604 PORT_Free(issuer.data);
605 PORT_Free(serial.data);
606 return rvCert;
607 }
608
609 NSS_EXTERN PRStatus
610 nssCertificateStore_AddTrust (
611 nssCertificateStore *store,
612 NSSTrust *trust
613 )
614 {
615 NSSCertificate *cert;
616 certificate_hash_entry *entry;
617 cert = trust->certificate;
618 PZ_Lock(store->lock);
619 entry = (certificate_hash_entry *)
620 nssHash_Lookup(store->issuer_and_serial, cert);
621 if (entry) {
622 NSSTrust* newTrust = nssTrust_AddRef(trust);
623 if (entry->trust) {
624 nssTrust_Destroy(entry->trust);
625 }
626 entry->trust = newTrust;
627 }
628 PZ_Unlock(store->lock);
629 return (entry) ? PR_SUCCESS : PR_FAILURE;
630 }
631
632 NSS_IMPLEMENT NSSTrust *
633 nssCertificateStore_FindTrustForCertificate (
634 nssCertificateStore *store,
635 NSSCertificate *cert
636 )
637 {
638 certificate_hash_entry *entry;
639 NSSTrust *rvTrust = NULL;
640 PZ_Lock(store->lock);
641 entry = (certificate_hash_entry *)
642 nssHash_Lookup(store->issuer_and_serial, cert);
643 if (entry && entry->trust) {
644 rvTrust = nssTrust_AddRef(entry->trust);
645 }
646 PZ_Unlock(store->lock);
647 return rvTrust;
648 }
649
650 NSS_EXTERN PRStatus
651 nssCertificateStore_AddSMIMEProfile (
652 nssCertificateStore *store,
653 nssSMIMEProfile *profile
654 )
655 {
656 NSSCertificate *cert;
657 certificate_hash_entry *entry;
658 cert = profile->certificate;
659 PZ_Lock(store->lock);
660 entry = (certificate_hash_entry *)
661 nssHash_Lookup(store->issuer_and_serial, cert);
662 if (entry) {
663 nssSMIMEProfile* newProfile = nssSMIMEProfile_AddRef(profile);
664 if (entry->profile) {
665 nssSMIMEProfile_Destroy(entry->profile);
666 }
667 entry->profile = newProfile;
668 }
669 PZ_Unlock(store->lock);
670 return (entry) ? PR_SUCCESS : PR_FAILURE;
671 }
672
673 NSS_IMPLEMENT nssSMIMEProfile *
674 nssCertificateStore_FindSMIMEProfileForCertificate (
675 nssCertificateStore *store,
676 NSSCertificate *cert
677 )
678 {
679 certificate_hash_entry *entry;
680 nssSMIMEProfile *rvProfile = NULL;
681 PZ_Lock(store->lock);
682 entry = (certificate_hash_entry *)
683 nssHash_Lookup(store->issuer_and_serial, cert);
684 if (entry && entry->profile) {
685 rvProfile = nssSMIMEProfile_AddRef(entry->profile);
686 }
687 PZ_Unlock(store->lock);
688 return rvProfile;
689 }
690
691 /* XXX this is also used by cache and should be somewhere else */
692
693 static PLHashNumber
694 nss_certificate_hash (
695 const void *key
696 )
697 {
698 unsigned int i;
699 PLHashNumber h;
700 NSSCertificate *c = (NSSCertificate *)key;
701 h = 0;
702 for (i=0; i<c->issuer.size; i++)
703 h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)c->issuer.data)[i];
704 for (i=0; i<c->serial.size; i++)
705 h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)c->serial.data)[i];
706 return h;
707 }
708
709 static int
710 nss_compare_certs(const void *v1, const void *v2)
711 {
712 PRStatus ignore;
713 NSSCertificate *c1 = (NSSCertificate *)v1;
714 NSSCertificate *c2 = (NSSCertificate *)v2;
715 return (int)(nssItem_Equal(&c1->issuer, &c2->issuer, &ignore) &&
716 nssItem_Equal(&c1->serial, &c2->serial, &ignore));
717 }
718
719 NSS_IMPLEMENT nssHash *
720 nssHash_CreateCertificate (
721 NSSArena *arenaOpt,
722 PRUint32 numBuckets
723 )
724 {
725 return nssHash_Create(arenaOpt,
726 numBuckets,
727 nss_certificate_hash,
728 nss_compare_certs,
729 PL_CompareValues);
730 }
731
732 NSS_IMPLEMENT void
733 nssCertificateStore_DumpStoreInfo (
734 nssCertificateStore *store,
735 void (* cert_dump_iter)(const void *, void *, void *),
736 void *arg
737 )
738 {
739 PZ_Lock(store->lock);
740 nssHash_Iterate(store->issuer_and_serial, cert_dump_iter, arg);
741 PZ_Unlock(store->lock);
742 }
743
OLDNEW
« no previous file with comments | « mozilla/security/nss/lib/pki/pkistore.h ('k') | mozilla/security/nss/lib/pki/pkit.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698