Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/pki/trustdomain.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
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 #ifndef DEV_H | |
6 #include "dev.h" | |
7 #endif /* DEV_H */ | |
8 | |
9 #ifndef PKIM_H | |
10 #include "pkim.h" | |
11 #endif /* PKIM_H */ | |
12 | |
13 #include "cert.h" | |
14 #include "pki3hack.h" | |
15 #include "pk11pub.h" | |
16 #include "nssrwlk.h" | |
17 | |
18 #define NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE 32 | |
19 | |
20 extern const NSSError NSS_ERROR_NOT_FOUND; | |
21 | |
22 typedef PRUint32 nssUpdateLevel; | |
23 | |
24 NSS_IMPLEMENT NSSTrustDomain * | |
25 NSSTrustDomain_Create ( | |
26 NSSUTF8 *moduleOpt, | |
27 NSSUTF8 *uriOpt, | |
28 NSSUTF8 *opaqueOpt, | |
29 void *reserved | |
30 ) | |
31 { | |
32 NSSArena *arena; | |
33 NSSTrustDomain *rvTD; | |
34 arena = NSSArena_Create(); | |
35 if(!arena) { | |
36 return (NSSTrustDomain *)NULL; | |
37 } | |
38 rvTD = nss_ZNEW(arena, NSSTrustDomain); | |
39 if (!rvTD) { | |
40 goto loser; | |
41 } | |
42 /* protect the token list and the token iterator */ | |
43 rvTD->tokensLock = NSSRWLock_New(100, "tokens"); | |
44 if (!rvTD->tokensLock) { | |
45 goto loser; | |
46 } | |
47 nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE); | |
48 rvTD->arena = arena; | |
49 rvTD->refCount = 1; | |
50 rvTD->statusConfig = NULL; | |
51 return rvTD; | |
52 loser: | |
53 if (rvTD && rvTD->tokensLock) { | |
54 NSSRWLock_Destroy(rvTD->tokensLock); | |
55 } | |
56 nssArena_Destroy(arena); | |
57 return (NSSTrustDomain *)NULL; | |
58 } | |
59 | |
60 static void | |
61 token_destructor(void *t) | |
62 { | |
63 NSSToken *tok = (NSSToken *)t; | |
64 /* The token holds the first/last reference to the slot. | |
65 * When the token is actually destroyed (ref count == 0), | |
66 * the slot will also be destroyed. | |
67 */ | |
68 nssToken_Destroy(tok); | |
69 } | |
70 | |
71 NSS_IMPLEMENT PRStatus | |
72 NSSTrustDomain_Destroy ( | |
73 NSSTrustDomain *td | |
74 ) | |
75 { | |
76 PRStatus status = PR_SUCCESS; | |
77 if (--td->refCount == 0) { | |
78 /* Destroy each token in the list of tokens */ | |
79 if (td->tokens) { | |
80 nssListIterator_Destroy(td->tokens); | |
81 td->tokens = NULL; | |
82 } | |
83 if (td->tokenList) { | |
84 nssList_Clear(td->tokenList, token_destructor); | |
85 nssList_Destroy(td->tokenList); | |
86 td->tokenList = NULL; | |
87 } | |
88 NSSRWLock_Destroy(td->tokensLock); | |
89 td->tokensLock = NULL; | |
90 status = nssTrustDomain_DestroyCache(td); | |
91 if (status == PR_FAILURE) { | |
92 return status; | |
93 } | |
94 if (td->statusConfig) { | |
95 td->statusConfig->statusDestroy(td->statusConfig); | |
96 td->statusConfig = NULL; | |
97 } | |
98 /* Destroy the trust domain */ | |
99 nssArena_Destroy(td->arena); | |
100 } | |
101 return status; | |
102 } | |
103 | |
104 /* XXX uses tokens until slot list is in place */ | |
105 static NSSSlot ** | |
106 nssTrustDomain_GetActiveSlots ( | |
107 NSSTrustDomain *td, | |
108 nssUpdateLevel *updateLevel | |
109 ) | |
110 { | |
111 PRUint32 count; | |
112 NSSSlot **slots = NULL; | |
113 NSSToken **tp, **tokens; | |
114 *updateLevel = 1; | |
115 NSSRWLock_LockRead(td->tokensLock); | |
116 count = nssList_Count(td->tokenList); | |
117 tokens = nss_ZNEWARRAY(NULL, NSSToken *, count + 1); | |
118 if (!tokens) { | |
119 NSSRWLock_UnlockRead(td->tokensLock); | |
120 return NULL; | |
121 } | |
122 slots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1); | |
123 if (!slots) { | |
124 NSSRWLock_UnlockRead(td->tokensLock); | |
125 nss_ZFreeIf(tokens); | |
126 return NULL; | |
127 } | |
128 nssList_GetArray(td->tokenList, (void **)tokens, count); | |
129 NSSRWLock_UnlockRead(td->tokensLock); | |
130 count = 0; | |
131 for (tp = tokens; *tp; tp++) { | |
132 NSSSlot * slot = nssToken_GetSlot(*tp); | |
133 if (!PK11_IsDisabled(slot->pk11slot)) { | |
134 slots[count++] = slot; | |
135 } else { | |
136 nssSlot_Destroy(slot); | |
137 } | |
138 } | |
139 nss_ZFreeIf(tokens); | |
140 if (!count) { | |
141 nss_ZFreeIf(slots); | |
142 slots = NULL; | |
143 } | |
144 return slots; | |
145 } | |
146 | |
147 /* XXX */ | |
148 static nssSession * | |
149 nssTrustDomain_GetSessionForToken ( | |
150 NSSTrustDomain *td, | |
151 NSSToken *token | |
152 ) | |
153 { | |
154 return nssToken_GetDefaultSession(token); | |
155 } | |
156 | |
157 NSS_IMPLEMENT PRStatus | |
158 NSSTrustDomain_SetDefaultCallback ( | |
159 NSSTrustDomain *td, | |
160 NSSCallback *newCallback, | |
161 NSSCallback **oldCallbackOpt | |
162 ) | |
163 { | |
164 if (oldCallbackOpt) { | |
165 *oldCallbackOpt = td->defaultCallback; | |
166 } | |
167 td->defaultCallback = newCallback; | |
168 return PR_SUCCESS; | |
169 } | |
170 | |
171 NSS_IMPLEMENT NSSCallback * | |
172 nssTrustDomain_GetDefaultCallback ( | |
173 NSSTrustDomain *td, | |
174 PRStatus *statusOpt | |
175 ) | |
176 { | |
177 if (statusOpt) { | |
178 *statusOpt = PR_SUCCESS; | |
179 } | |
180 return td->defaultCallback; | |
181 } | |
182 | |
183 NSS_IMPLEMENT NSSCallback * | |
184 NSSTrustDomain_GetDefaultCallback ( | |
185 NSSTrustDomain *td, | |
186 PRStatus *statusOpt | |
187 ) | |
188 { | |
189 return nssTrustDomain_GetDefaultCallback(td, statusOpt); | |
190 } | |
191 | |
192 NSS_IMPLEMENT PRStatus | |
193 NSSTrustDomain_LoadModule ( | |
194 NSSTrustDomain *td, | |
195 NSSUTF8 *moduleOpt, | |
196 NSSUTF8 *uriOpt, | |
197 NSSUTF8 *opaqueOpt, | |
198 void *reserved | |
199 ) | |
200 { | |
201 return PR_FAILURE; | |
202 } | |
203 | |
204 NSS_IMPLEMENT PRStatus | |
205 NSSTrustDomain_DisableToken ( | |
206 NSSTrustDomain *td, | |
207 NSSToken *token, | |
208 NSSError why | |
209 ) | |
210 { | |
211 nss_SetError(NSS_ERROR_NOT_FOUND); | |
212 return PR_FAILURE; | |
213 } | |
214 | |
215 NSS_IMPLEMENT PRStatus | |
216 NSSTrustDomain_EnableToken ( | |
217 NSSTrustDomain *td, | |
218 NSSToken *token | |
219 ) | |
220 { | |
221 nss_SetError(NSS_ERROR_NOT_FOUND); | |
222 return PR_FAILURE; | |
223 } | |
224 | |
225 NSS_IMPLEMENT PRStatus | |
226 NSSTrustDomain_IsTokenEnabled ( | |
227 NSSTrustDomain *td, | |
228 NSSToken *token, | |
229 NSSError *whyOpt | |
230 ) | |
231 { | |
232 nss_SetError(NSS_ERROR_NOT_FOUND); | |
233 return PR_FAILURE; | |
234 } | |
235 | |
236 NSS_IMPLEMENT NSSSlot * | |
237 NSSTrustDomain_FindSlotByName ( | |
238 NSSTrustDomain *td, | |
239 NSSUTF8 *slotName | |
240 ) | |
241 { | |
242 nss_SetError(NSS_ERROR_NOT_FOUND); | |
243 return NULL; | |
244 } | |
245 | |
246 NSS_IMPLEMENT NSSToken * | |
247 NSSTrustDomain_FindTokenByName ( | |
248 NSSTrustDomain *td, | |
249 NSSUTF8 *tokenName | |
250 ) | |
251 { | |
252 PRStatus nssrv; | |
253 NSSUTF8 *myName; | |
254 NSSToken *tok = NULL; | |
255 NSSRWLock_LockRead(td->tokensLock); | |
256 for (tok = (NSSToken *)nssListIterator_Start(td->tokens); | |
257 tok != (NSSToken *)NULL; | |
258 tok = (NSSToken *)nssListIterator_Next(td->tokens)) | |
259 { | |
260 if (nssToken_IsPresent(tok)) { | |
261 myName = nssToken_GetName(tok); | |
262 if (nssUTF8_Equal(tokenName, myName, &nssrv)) break; | |
263 } | |
264 } | |
265 nssListIterator_Finish(td->tokens); | |
266 NSSRWLock_UnlockRead(td->tokensLock); | |
267 return tok; | |
268 } | |
269 | |
270 NSS_IMPLEMENT NSSToken * | |
271 NSSTrustDomain_FindTokenBySlotName ( | |
272 NSSTrustDomain *td, | |
273 NSSUTF8 *slotName | |
274 ) | |
275 { | |
276 nss_SetError(NSS_ERROR_NOT_FOUND); | |
277 return NULL; | |
278 } | |
279 | |
280 NSS_IMPLEMENT NSSToken * | |
281 NSSTrustDomain_FindTokenForAlgorithm ( | |
282 NSSTrustDomain *td, | |
283 NSSOID *algorithm | |
284 ) | |
285 { | |
286 nss_SetError(NSS_ERROR_NOT_FOUND); | |
287 return NULL; | |
288 } | |
289 | |
290 NSS_IMPLEMENT NSSToken * | |
291 NSSTrustDomain_FindBestTokenForAlgorithms ( | |
292 NSSTrustDomain *td, | |
293 NSSOID *algorithms[], /* may be null-terminated */ | |
294 PRUint32 nAlgorithmsOpt /* limits the array if nonzero */ | |
295 ) | |
296 { | |
297 nss_SetError(NSS_ERROR_NOT_FOUND); | |
298 return NULL; | |
299 } | |
300 | |
301 NSS_IMPLEMENT PRStatus | |
302 NSSTrustDomain_Login ( | |
303 NSSTrustDomain *td, | |
304 NSSCallback *uhhOpt | |
305 ) | |
306 { | |
307 nss_SetError(NSS_ERROR_NOT_FOUND); | |
308 return PR_FAILURE; | |
309 } | |
310 | |
311 NSS_IMPLEMENT PRStatus | |
312 NSSTrustDomain_Logout ( | |
313 NSSTrustDomain *td | |
314 ) | |
315 { | |
316 nss_SetError(NSS_ERROR_NOT_FOUND); | |
317 return PR_FAILURE; | |
318 } | |
319 | |
320 NSS_IMPLEMENT NSSCertificate * | |
321 NSSTrustDomain_ImportCertificate ( | |
322 NSSTrustDomain *td, | |
323 NSSCertificate *c | |
324 ) | |
325 { | |
326 nss_SetError(NSS_ERROR_NOT_FOUND); | |
327 return NULL; | |
328 } | |
329 | |
330 NSS_IMPLEMENT NSSCertificate * | |
331 NSSTrustDomain_ImportPKIXCertificate ( | |
332 NSSTrustDomain *td, | |
333 /* declared as a struct until these "data types" are defined */ | |
334 struct NSSPKIXCertificateStr *pc | |
335 ) | |
336 { | |
337 nss_SetError(NSS_ERROR_NOT_FOUND); | |
338 return NULL; | |
339 } | |
340 | |
341 NSS_IMPLEMENT NSSCertificate * | |
342 NSSTrustDomain_ImportEncodedCertificate ( | |
343 NSSTrustDomain *td, | |
344 NSSBER *ber | |
345 ) | |
346 { | |
347 nss_SetError(NSS_ERROR_NOT_FOUND); | |
348 return NULL; | |
349 } | |
350 | |
351 NSS_IMPLEMENT NSSCertificate ** | |
352 NSSTrustDomain_ImportEncodedCertificateChain ( | |
353 NSSTrustDomain *td, | |
354 NSSBER *ber, | |
355 NSSCertificate *rvOpt[], | |
356 PRUint32 maximumOpt, /* 0 for no max */ | |
357 NSSArena *arenaOpt | |
358 ) | |
359 { | |
360 nss_SetError(NSS_ERROR_NOT_FOUND); | |
361 return NULL; | |
362 } | |
363 | |
364 NSS_IMPLEMENT NSSPrivateKey * | |
365 NSSTrustDomain_ImportEncodedPrivateKey ( | |
366 NSSTrustDomain *td, | |
367 NSSBER *ber, | |
368 NSSItem *passwordOpt, /* NULL will cause a callback */ | |
369 NSSCallback *uhhOpt, | |
370 NSSToken *destination | |
371 ) | |
372 { | |
373 nss_SetError(NSS_ERROR_NOT_FOUND); | |
374 return NULL; | |
375 } | |
376 | |
377 NSS_IMPLEMENT NSSPublicKey * | |
378 NSSTrustDomain_ImportEncodedPublicKey ( | |
379 NSSTrustDomain *td, | |
380 NSSBER *ber | |
381 ) | |
382 { | |
383 nss_SetError(NSS_ERROR_NOT_FOUND); | |
384 return NULL; | |
385 } | |
386 | |
387 static NSSCertificate ** | |
388 get_certs_from_list(nssList *list) | |
389 { | |
390 PRUint32 count = nssList_Count(list); | |
391 NSSCertificate **certs = NULL; | |
392 if (count > 0) { | |
393 certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1); | |
394 if (certs) { | |
395 nssList_GetArray(list, (void **)certs, count); | |
396 } | |
397 } | |
398 return certs; | |
399 } | |
400 | |
401 NSS_IMPLEMENT NSSCertificate ** | |
402 nssTrustDomain_FindCertificatesByNickname ( | |
403 NSSTrustDomain *td, | |
404 const NSSUTF8 *name, | |
405 NSSCertificate *rvOpt[], | |
406 PRUint32 maximumOpt, /* 0 for no max */ | |
407 NSSArena *arenaOpt | |
408 ) | |
409 { | |
410 NSSToken *token = NULL; | |
411 NSSSlot **slots = NULL; | |
412 NSSSlot **slotp; | |
413 NSSCertificate **rvCerts = NULL; | |
414 nssPKIObjectCollection *collection = NULL; | |
415 nssUpdateLevel updateLevel; | |
416 nssList *nameList; | |
417 PRUint32 numRemaining = maximumOpt; | |
418 PRUint32 collectionCount = 0; | |
419 PRUint32 errors = 0; | |
420 | |
421 /* First, grab from the cache */ | |
422 nameList = nssList_Create(NULL, PR_FALSE); | |
423 if (!nameList) { | |
424 return NULL; | |
425 } | |
426 (void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList); | |
427 rvCerts = get_certs_from_list(nameList); | |
428 /* initialize the collection of token certificates with the set of | |
429 * cached certs (if any). | |
430 */ | |
431 collection = nssCertificateCollection_Create(td, rvCerts); | |
432 nssCertificateArray_Destroy(rvCerts); | |
433 nssList_Destroy(nameList); | |
434 if (!collection) { | |
435 return (NSSCertificate **)NULL; | |
436 } | |
437 /* obtain the current set of active slots in the trust domain */ | |
438 slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); | |
439 if (!slots) { | |
440 goto loser; | |
441 } | |
442 /* iterate over the slots */ | |
443 for (slotp = slots; *slotp; slotp++) { | |
444 token = nssSlot_GetToken(*slotp); | |
445 if (token) { | |
446 nssSession *session; | |
447 nssCryptokiObject **instances = NULL; | |
448 nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; | |
449 PRStatus status = PR_FAILURE; | |
450 | |
451 session = nssTrustDomain_GetSessionForToken(td, token); | |
452 if (session) { | |
453 instances = nssToken_FindCertificatesByNickname(token, | |
454 session, | |
455 name, | |
456 tokenOnly, | |
457 numRemaining, | |
458 &status); | |
459 } | |
460 nssToken_Destroy(token); | |
461 if (status != PR_SUCCESS) { | |
462 errors++; | |
463 continue; | |
464 } | |
465 if (instances) { | |
466 status = nssPKIObjectCollection_AddInstances(collection, | |
467 instances, 0); | |
468 nss_ZFreeIf(instances); | |
469 if (status != PR_SUCCESS) { | |
470 errors++; | |
471 continue; | |
472 } | |
473 collectionCount = nssPKIObjectCollection_Count(collection); | |
474 if (maximumOpt > 0) { | |
475 if (collectionCount >= maximumOpt) | |
476 break; | |
477 numRemaining = maximumOpt - collectionCount; | |
478 } | |
479 } | |
480 } | |
481 } | |
482 if (!collectionCount && errors) | |
483 goto loser; | |
484 /* Grab the certs collected in the search. */ | |
485 rvCerts = nssPKIObjectCollection_GetCertificates(collection, | |
486 rvOpt, maximumOpt, | |
487 arenaOpt); | |
488 /* clean up */ | |
489 nssPKIObjectCollection_Destroy(collection); | |
490 nssSlotArray_Destroy(slots); | |
491 return rvCerts; | |
492 loser: | |
493 if (slots) { | |
494 nssSlotArray_Destroy(slots); | |
495 } | |
496 if (collection) { | |
497 nssPKIObjectCollection_Destroy(collection); | |
498 } | |
499 return (NSSCertificate **)NULL; | |
500 } | |
501 | |
502 NSS_IMPLEMENT NSSCertificate ** | |
503 NSSTrustDomain_FindCertificatesByNickname ( | |
504 NSSTrustDomain *td, | |
505 NSSUTF8 *name, | |
506 NSSCertificate *rvOpt[], | |
507 PRUint32 maximumOpt, /* 0 for no max */ | |
508 NSSArena *arenaOpt | |
509 ) | |
510 { | |
511 return nssTrustDomain_FindCertificatesByNickname(td, | |
512 name, | |
513 rvOpt, | |
514 maximumOpt, | |
515 arenaOpt); | |
516 } | |
517 | |
518 NSS_IMPLEMENT NSSCertificate * | |
519 nssTrustDomain_FindBestCertificateByNickname ( | |
520 NSSTrustDomain *td, | |
521 const NSSUTF8 *name, | |
522 NSSTime *timeOpt, | |
523 NSSUsage *usage, | |
524 NSSPolicies *policiesOpt | |
525 ) | |
526 { | |
527 NSSCertificate **nicknameCerts; | |
528 NSSCertificate *rvCert = NULL; | |
529 nicknameCerts = nssTrustDomain_FindCertificatesByNickname(td, name, | |
530 NULL, | |
531 0, | |
532 NULL); | |
533 if (nicknameCerts) { | |
534 rvCert = nssCertificateArray_FindBestCertificate(nicknameCerts, | |
535 timeOpt, | |
536 usage, | |
537 policiesOpt); | |
538 nssCertificateArray_Destroy(nicknameCerts); | |
539 } | |
540 return rvCert; | |
541 } | |
542 | |
543 NSS_IMPLEMENT NSSCertificate * | |
544 NSSTrustDomain_FindBestCertificateByNickname ( | |
545 NSSTrustDomain *td, | |
546 const NSSUTF8 *name, | |
547 NSSTime *timeOpt, | |
548 NSSUsage *usage, | |
549 NSSPolicies *policiesOpt | |
550 ) | |
551 { | |
552 return nssTrustDomain_FindBestCertificateByNickname(td, | |
553 name, | |
554 timeOpt, | |
555 usage, | |
556 policiesOpt); | |
557 } | |
558 | |
559 NSS_IMPLEMENT NSSCertificate ** | |
560 nssTrustDomain_FindCertificatesBySubject ( | |
561 NSSTrustDomain *td, | |
562 NSSDER *subject, | |
563 NSSCertificate *rvOpt[], | |
564 PRUint32 maximumOpt, /* 0 for no max */ | |
565 NSSArena *arenaOpt | |
566 ) | |
567 { | |
568 NSSToken *token = NULL; | |
569 NSSSlot **slots = NULL; | |
570 NSSSlot **slotp; | |
571 NSSCertificate **rvCerts = NULL; | |
572 nssPKIObjectCollection *collection = NULL; | |
573 nssUpdateLevel updateLevel; | |
574 nssList *subjectList; | |
575 PRUint32 numRemaining = maximumOpt; | |
576 PRUint32 collectionCount = 0; | |
577 PRUint32 errors = 0; | |
578 | |
579 /* look in cache */ | |
580 subjectList = nssList_Create(NULL, PR_FALSE); | |
581 if (!subjectList) { | |
582 return NULL; | |
583 } | |
584 (void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList); | |
585 rvCerts = get_certs_from_list(subjectList); | |
586 collection = nssCertificateCollection_Create(td, rvCerts); | |
587 nssCertificateArray_Destroy(rvCerts); | |
588 nssList_Destroy(subjectList); | |
589 if (!collection) { | |
590 return (NSSCertificate **)NULL; | |
591 } | |
592 slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); | |
593 if (!slots) { | |
594 goto loser; | |
595 } | |
596 for (slotp = slots; *slotp; slotp++) { | |
597 token = nssSlot_GetToken(*slotp); | |
598 if (token) { | |
599 nssSession *session; | |
600 nssCryptokiObject **instances = NULL; | |
601 nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; | |
602 PRStatus status = PR_FAILURE; | |
603 | |
604 session = nssTrustDomain_GetSessionForToken(td, token); | |
605 if (session) { | |
606 instances = nssToken_FindCertificatesBySubject(token, | |
607 session, | |
608 subject, | |
609 tokenOnly, | |
610 numRemaining, | |
611 &status); | |
612 } | |
613 nssToken_Destroy(token); | |
614 if (status != PR_SUCCESS) { | |
615 errors++; | |
616 continue; | |
617 } | |
618 if (instances) { | |
619 status = nssPKIObjectCollection_AddInstances(collection, | |
620 instances, 0); | |
621 nss_ZFreeIf(instances); | |
622 if (status != PR_SUCCESS) { | |
623 errors++; | |
624 continue; | |
625 } | |
626 collectionCount = nssPKIObjectCollection_Count(collection); | |
627 if (maximumOpt > 0) { | |
628 if (collectionCount >= maximumOpt) | |
629 break; | |
630 numRemaining = maximumOpt - collectionCount; | |
631 } | |
632 } | |
633 } | |
634 } | |
635 if (!collectionCount && errors) | |
636 goto loser; | |
637 rvCerts = nssPKIObjectCollection_GetCertificates(collection, | |
638 rvOpt, maximumOpt, | |
639 arenaOpt); | |
640 nssPKIObjectCollection_Destroy(collection); | |
641 nssSlotArray_Destroy(slots); | |
642 return rvCerts; | |
643 loser: | |
644 if (slots) { | |
645 nssSlotArray_Destroy(slots); | |
646 } | |
647 if (collection) { | |
648 nssPKIObjectCollection_Destroy(collection); | |
649 } | |
650 return (NSSCertificate **)NULL; | |
651 } | |
652 | |
653 NSS_IMPLEMENT NSSCertificate ** | |
654 NSSTrustDomain_FindCertificatesBySubject ( | |
655 NSSTrustDomain *td, | |
656 NSSDER *subject, | |
657 NSSCertificate *rvOpt[], | |
658 PRUint32 maximumOpt, | |
659 NSSArena *arenaOpt | |
660 ) | |
661 { | |
662 return nssTrustDomain_FindCertificatesBySubject(td, | |
663 subject, | |
664 rvOpt, | |
665 maximumOpt, | |
666 arenaOpt); | |
667 } | |
668 | |
669 NSS_IMPLEMENT NSSCertificate * | |
670 nssTrustDomain_FindBestCertificateBySubject ( | |
671 NSSTrustDomain *td, | |
672 NSSDER *subject, | |
673 NSSTime *timeOpt, | |
674 NSSUsage *usage, | |
675 NSSPolicies *policiesOpt | |
676 ) | |
677 { | |
678 NSSCertificate **subjectCerts; | |
679 NSSCertificate *rvCert = NULL; | |
680 subjectCerts = nssTrustDomain_FindCertificatesBySubject(td, subject, | |
681 NULL, | |
682 0, | |
683 NULL); | |
684 if (subjectCerts) { | |
685 rvCert = nssCertificateArray_FindBestCertificate(subjectCerts, | |
686 timeOpt, | |
687 usage, | |
688 policiesOpt); | |
689 nssCertificateArray_Destroy(subjectCerts); | |
690 } | |
691 return rvCert; | |
692 } | |
693 | |
694 NSS_IMPLEMENT NSSCertificate * | |
695 NSSTrustDomain_FindBestCertificateBySubject ( | |
696 NSSTrustDomain *td, | |
697 NSSDER *subject, | |
698 NSSTime *timeOpt, | |
699 NSSUsage *usage, | |
700 NSSPolicies *policiesOpt | |
701 ) | |
702 { | |
703 return nssTrustDomain_FindBestCertificateBySubject(td, | |
704 subject, | |
705 timeOpt, | |
706 usage, | |
707 policiesOpt); | |
708 } | |
709 | |
710 NSS_IMPLEMENT NSSCertificate * | |
711 NSSTrustDomain_FindBestCertificateByNameComponents ( | |
712 NSSTrustDomain *td, | |
713 NSSUTF8 *nameComponents, | |
714 NSSTime *timeOpt, | |
715 NSSUsage *usage, | |
716 NSSPolicies *policiesOpt | |
717 ) | |
718 { | |
719 nss_SetError(NSS_ERROR_NOT_FOUND); | |
720 return NULL; | |
721 } | |
722 | |
723 NSS_IMPLEMENT NSSCertificate ** | |
724 NSSTrustDomain_FindCertificatesByNameComponents ( | |
725 NSSTrustDomain *td, | |
726 NSSUTF8 *nameComponents, | |
727 NSSCertificate *rvOpt[], | |
728 PRUint32 maximumOpt, /* 0 for no max */ | |
729 NSSArena *arenaOpt | |
730 ) | |
731 { | |
732 nss_SetError(NSS_ERROR_NOT_FOUND); | |
733 return NULL; | |
734 } | |
735 | |
736 /* This returns at most a single certificate, so it can stop the loop | |
737 * when one is found. | |
738 */ | |
739 NSS_IMPLEMENT NSSCertificate * | |
740 nssTrustDomain_FindCertificateByIssuerAndSerialNumber ( | |
741 NSSTrustDomain *td, | |
742 NSSDER *issuer, | |
743 NSSDER *serial | |
744 ) | |
745 { | |
746 NSSSlot **slots = NULL; | |
747 NSSSlot **slotp; | |
748 NSSCertificate *rvCert = NULL; | |
749 nssPKIObjectCollection *collection = NULL; | |
750 nssUpdateLevel updateLevel; | |
751 | |
752 /* see if this search is already cached */ | |
753 rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td, | |
754 issuer, | |
755 serial); | |
756 if (rvCert) { | |
757 return rvCert; | |
758 } | |
759 slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); | |
760 if (slots) { | |
761 for (slotp = slots; *slotp; slotp++) { | |
762 NSSToken *token = nssSlot_GetToken(*slotp); | |
763 nssSession *session; | |
764 nssCryptokiObject *instance; | |
765 nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; | |
766 PRStatus status = PR_FAILURE; | |
767 | |
768 if (!token) | |
769 continue; | |
770 session = nssTrustDomain_GetSessionForToken(td, token); | |
771 if (session) { | |
772 instance = nssToken_FindCertificateByIssuerAndSerialNumber( | |
773 token, | |
774 session, | |
775 issuer, | |
776 serial, | |
777 tokenOnly, | |
778 &status); | |
779 } | |
780 nssToken_Destroy(token); | |
781 if (status != PR_SUCCESS) { | |
782 continue; | |
783 } | |
784 if (instance) { | |
785 if (!collection) { | |
786 collection = nssCertificateCollection_Create(td, NULL); | |
787 if (!collection) { | |
788 break; /* don't keep looping if out if memory */ | |
789 } | |
790 } | |
791 status = nssPKIObjectCollection_AddInstances(collection, | |
792 &instance, 1); | |
793 if (status == PR_SUCCESS) { | |
794 (void)nssPKIObjectCollection_GetCertificates( | |
795 collection, &rvCert, 1, NULL); | |
796 } | |
797 if (rvCert) { | |
798 break; /* found one cert, all done */ | |
799 } | |
800 } | |
801 } | |
802 } | |
803 if (collection) { | |
804 nssPKIObjectCollection_Destroy(collection); | |
805 } | |
806 if (slots) { | |
807 nssSlotArray_Destroy(slots); | |
808 } | |
809 return rvCert; | |
810 } | |
811 | |
812 NSS_IMPLEMENT NSSCertificate * | |
813 NSSTrustDomain_FindCertificateByIssuerAndSerialNumber ( | |
814 NSSTrustDomain *td, | |
815 NSSDER *issuer, | |
816 NSSDER *serial | |
817 ) | |
818 { | |
819 return nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td, | |
820 issuer, | |
821 serial); | |
822 } | |
823 | |
824 NSS_IMPLEMENT NSSCertificate * | |
825 nssTrustDomain_FindCertificateByEncodedCertificate ( | |
826 NSSTrustDomain *td, | |
827 NSSBER *ber | |
828 ) | |
829 { | |
830 PRStatus status; | |
831 NSSCertificate *rvCert = NULL; | |
832 NSSDER issuer = { 0 }; | |
833 NSSDER serial = { 0 }; | |
834 NSSArena *arena = nssArena_Create(); | |
835 if (!arena) { | |
836 return (NSSCertificate *)NULL; | |
837 } | |
838 /* XXX this is not generic... will any cert crack into issuer/serial? */ | |
839 status = nssPKIX509_GetIssuerAndSerialFromDER(ber, arena, &issuer, &serial); | |
840 if (status != PR_SUCCESS) { | |
841 goto finish; | |
842 } | |
843 rvCert = nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td, | |
844 &issuer, | |
845 &serial); | |
846 finish: | |
847 nssArena_Destroy(arena); | |
848 return rvCert; | |
849 } | |
850 | |
851 NSS_IMPLEMENT NSSCertificate * | |
852 NSSTrustDomain_FindCertificateByEncodedCertificate ( | |
853 NSSTrustDomain *td, | |
854 NSSBER *ber | |
855 ) | |
856 { | |
857 return nssTrustDomain_FindCertificateByEncodedCertificate(td, ber); | |
858 } | |
859 | |
860 NSS_IMPLEMENT NSSCertificate * | |
861 NSSTrustDomain_FindBestCertificateByEmail ( | |
862 NSSTrustDomain *td, | |
863 NSSASCII7 *email, | |
864 NSSTime *timeOpt, | |
865 NSSUsage *usage, | |
866 NSSPolicies *policiesOpt | |
867 ) | |
868 { | |
869 return 0; | |
870 } | |
871 | |
872 NSS_IMPLEMENT NSSCertificate ** | |
873 NSSTrustDomain_FindCertificatesByEmail ( | |
874 NSSTrustDomain *td, | |
875 NSSASCII7 *email, | |
876 NSSCertificate *rvOpt[], | |
877 PRUint32 maximumOpt, /* 0 for no max */ | |
878 NSSArena *arenaOpt | |
879 ) | |
880 { | |
881 nss_SetError(NSS_ERROR_NOT_FOUND); | |
882 return NULL; | |
883 } | |
884 | |
885 NSS_IMPLEMENT NSSCertificate * | |
886 NSSTrustDomain_FindCertificateByOCSPHash ( | |
887 NSSTrustDomain *td, | |
888 NSSItem *hash | |
889 ) | |
890 { | |
891 nss_SetError(NSS_ERROR_NOT_FOUND); | |
892 return NULL; | |
893 } | |
894 | |
895 NSS_IMPLEMENT NSSCertificate * | |
896 NSSTrustDomain_FindBestUserCertificate ( | |
897 NSSTrustDomain *td, | |
898 NSSTime *timeOpt, | |
899 NSSUsage *usage, | |
900 NSSPolicies *policiesOpt | |
901 ) | |
902 { | |
903 nss_SetError(NSS_ERROR_NOT_FOUND); | |
904 return NULL; | |
905 } | |
906 | |
907 NSS_IMPLEMENT NSSCertificate ** | |
908 NSSTrustDomain_FindUserCertificates ( | |
909 NSSTrustDomain *td, | |
910 NSSTime *timeOpt, | |
911 NSSUsage *usageOpt, | |
912 NSSPolicies *policiesOpt, | |
913 NSSCertificate **rvOpt, | |
914 PRUint32 rvLimit, /* zero for no limit */ | |
915 NSSArena *arenaOpt | |
916 ) | |
917 { | |
918 nss_SetError(NSS_ERROR_NOT_FOUND); | |
919 return NULL; | |
920 } | |
921 | |
922 NSS_IMPLEMENT NSSCertificate * | |
923 NSSTrustDomain_FindBestUserCertificateForSSLClientAuth ( | |
924 NSSTrustDomain *td, | |
925 NSSUTF8 *sslHostOpt, | |
926 NSSDER *rootCAsOpt[], /* null pointer for none */ | |
927 PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */ | |
928 NSSAlgorithmAndParameters *apOpt, | |
929 NSSPolicies *policiesOpt | |
930 ) | |
931 { | |
932 nss_SetError(NSS_ERROR_NOT_FOUND); | |
933 return NULL; | |
934 } | |
935 | |
936 NSS_IMPLEMENT NSSCertificate ** | |
937 NSSTrustDomain_FindUserCertificatesForSSLClientAuth ( | |
938 NSSTrustDomain *td, | |
939 NSSUTF8 *sslHostOpt, | |
940 NSSDER *rootCAsOpt[], /* null pointer for none */ | |
941 PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */ | |
942 NSSAlgorithmAndParameters *apOpt, | |
943 NSSPolicies *policiesOpt, | |
944 NSSCertificate **rvOpt, | |
945 PRUint32 rvLimit, /* zero for no limit */ | |
946 NSSArena *arenaOpt | |
947 ) | |
948 { | |
949 nss_SetError(NSS_ERROR_NOT_FOUND); | |
950 return NULL; | |
951 } | |
952 | |
953 NSS_IMPLEMENT NSSCertificate * | |
954 NSSTrustDomain_FindBestUserCertificateForEmailSigning ( | |
955 NSSTrustDomain *td, | |
956 NSSASCII7 *signerOpt, | |
957 NSSASCII7 *recipientOpt, | |
958 /* anything more here? */ | |
959 NSSAlgorithmAndParameters *apOpt, | |
960 NSSPolicies *policiesOpt | |
961 ) | |
962 { | |
963 nss_SetError(NSS_ERROR_NOT_FOUND); | |
964 return NULL; | |
965 } | |
966 | |
967 NSS_IMPLEMENT NSSCertificate ** | |
968 NSSTrustDomain_FindUserCertificatesForEmailSigning ( | |
969 NSSTrustDomain *td, | |
970 NSSASCII7 *signerOpt, | |
971 NSSASCII7 *recipientOpt, | |
972 /* anything more here? */ | |
973 NSSAlgorithmAndParameters *apOpt, | |
974 NSSPolicies *policiesOpt, | |
975 NSSCertificate **rvOpt, | |
976 PRUint32 rvLimit, /* zero for no limit */ | |
977 NSSArena *arenaOpt | |
978 ) | |
979 { | |
980 nss_SetError(NSS_ERROR_NOT_FOUND); | |
981 return NULL; | |
982 } | |
983 | |
984 static PRStatus | |
985 collector(nssCryptokiObject *instance, void *arg) | |
986 { | |
987 nssPKIObjectCollection *collection = (nssPKIObjectCollection *)arg; | |
988 return nssPKIObjectCollection_AddInstanceAsObject(collection, instance); | |
989 } | |
990 | |
991 NSS_IMPLEMENT PRStatus * | |
992 NSSTrustDomain_TraverseCertificates ( | |
993 NSSTrustDomain *td, | |
994 PRStatus (*callback)(NSSCertificate *c, void *arg), | |
995 void *arg | |
996 ) | |
997 { | |
998 PRStatus status = PR_FAILURE; | |
999 NSSToken *token = NULL; | |
1000 NSSSlot **slots = NULL; | |
1001 NSSSlot **slotp; | |
1002 nssPKIObjectCollection *collection = NULL; | |
1003 nssPKIObjectCallback pkiCallback; | |
1004 nssUpdateLevel updateLevel; | |
1005 NSSCertificate **cached = NULL; | |
1006 nssList *certList; | |
1007 | |
1008 certList = nssList_Create(NULL, PR_FALSE); | |
1009 if (!certList) | |
1010 return NULL; | |
1011 (void)nssTrustDomain_GetCertsFromCache(td, certList); | |
1012 cached = get_certs_from_list(certList); | |
1013 collection = nssCertificateCollection_Create(td, cached); | |
1014 nssCertificateArray_Destroy(cached); | |
1015 nssList_Destroy(certList); | |
1016 if (!collection) { | |
1017 return (PRStatus *)NULL; | |
1018 } | |
1019 /* obtain the current set of active slots in the trust domain */ | |
1020 slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); | |
1021 if (!slots) { | |
1022 goto loser; | |
1023 } | |
1024 /* iterate over the slots */ | |
1025 for (slotp = slots; *slotp; slotp++) { | |
1026 /* get the token for the slot, if present */ | |
1027 token = nssSlot_GetToken(*slotp); | |
1028 if (token) { | |
1029 nssSession *session; | |
1030 nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; | |
1031 /* get a session for the token */ | |
1032 session = nssTrustDomain_GetSessionForToken(td, token); | |
1033 if (session) { | |
1034 /* perform the traversal */ | |
1035 status = nssToken_TraverseCertificates(token, | |
1036 session, | |
1037 tokenOnly, | |
1038 collector, | |
1039 collection); | |
1040 } | |
1041 nssToken_Destroy(token); | |
1042 } | |
1043 } | |
1044 | |
1045 /* Traverse the collection */ | |
1046 pkiCallback.func.cert = callback; | |
1047 pkiCallback.arg = arg; | |
1048 status = nssPKIObjectCollection_Traverse(collection, &pkiCallback); | |
1049 loser: | |
1050 if (slots) { | |
1051 nssSlotArray_Destroy(slots); | |
1052 } | |
1053 if (collection) { | |
1054 nssPKIObjectCollection_Destroy(collection); | |
1055 } | |
1056 return NULL; | |
1057 } | |
1058 | |
1059 | |
1060 NSS_IMPLEMENT NSSTrust * | |
1061 nssTrustDomain_FindTrustForCertificate ( | |
1062 NSSTrustDomain *td, | |
1063 NSSCertificate *c | |
1064 ) | |
1065 { | |
1066 NSSSlot **slots; | |
1067 NSSSlot **slotp; | |
1068 nssCryptokiObject *to = NULL; | |
1069 nssPKIObject *pkio = NULL; | |
1070 NSSTrust *rvt = NULL; | |
1071 nssUpdateLevel updateLevel; | |
1072 slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); | |
1073 if (!slots) { | |
1074 return (NSSTrust *)NULL; | |
1075 } | |
1076 for (slotp = slots; *slotp; slotp++) { | |
1077 NSSToken *token = nssSlot_GetToken(*slotp); | |
1078 | |
1079 if (token) { | |
1080 to = nssToken_FindTrustForCertificate(token, NULL, | |
1081 &c->encoding, | |
1082 &c->issuer, | |
1083 &c->serial, | |
1084 nssTokenSearchType_TokenOnly); | |
1085 if (to) { | |
1086 PRStatus status; | |
1087 if (!pkio) { | |
1088 pkio = nssPKIObject_Create(NULL, to, td, NULL, nssPKILock); | |
1089 status = pkio ? PR_SUCCESS : PR_FAILURE; | |
1090 } else { | |
1091 status = nssPKIObject_AddInstance(pkio, to); | |
1092 } | |
1093 if (status != PR_SUCCESS) { | |
1094 nssCryptokiObject_Destroy(to); | |
1095 } | |
1096 } | |
1097 nssToken_Destroy(token); | |
1098 } | |
1099 } | |
1100 if (pkio) { | |
1101 rvt = nssTrust_Create(pkio, &c->encoding); | |
1102 if (rvt) { | |
1103 pkio = NULL; /* rvt object now owns the pkio reference */ | |
1104 } | |
1105 } | |
1106 nssSlotArray_Destroy(slots); | |
1107 if (pkio) { | |
1108 nssPKIObject_Destroy(pkio); | |
1109 } | |
1110 return rvt; | |
1111 } | |
1112 | |
1113 NSS_IMPLEMENT NSSCRL ** | |
1114 nssTrustDomain_FindCRLsBySubject ( | |
1115 NSSTrustDomain *td, | |
1116 NSSDER *subject | |
1117 ) | |
1118 { | |
1119 NSSSlot **slots; | |
1120 NSSSlot **slotp; | |
1121 NSSToken *token; | |
1122 nssUpdateLevel updateLevel; | |
1123 nssPKIObjectCollection *collection; | |
1124 NSSCRL **rvCRLs = NULL; | |
1125 collection = nssCRLCollection_Create(td, NULL); | |
1126 if (!collection) { | |
1127 return (NSSCRL **)NULL; | |
1128 } | |
1129 slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); | |
1130 if (!slots) { | |
1131 goto loser; | |
1132 } | |
1133 for (slotp = slots; *slotp; slotp++) { | |
1134 token = nssSlot_GetToken(*slotp); | |
1135 if (token) { | |
1136 PRStatus status = PR_FAILURE; | |
1137 nssSession *session; | |
1138 nssCryptokiObject **instances = NULL; | |
1139 nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; | |
1140 | |
1141 /* get a session for the token */ | |
1142 session = nssTrustDomain_GetSessionForToken(td, token); | |
1143 if (session) { | |
1144 /* perform the traversal */ | |
1145 instances = nssToken_FindCRLsBySubject(token, session, subject, | |
1146 tokenOnly, 0, &status); | |
1147 } | |
1148 nssToken_Destroy(token); | |
1149 if (status == PR_SUCCESS) { | |
1150 /* add the found CRL's to the collection */ | |
1151 status = nssPKIObjectCollection_AddInstances(collection, | |
1152 instances, 0); | |
1153 } | |
1154 nss_ZFreeIf(instances); | |
1155 } | |
1156 } | |
1157 rvCRLs = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL); | |
1158 loser: | |
1159 nssPKIObjectCollection_Destroy(collection); | |
1160 nssSlotArray_Destroy(slots); | |
1161 return rvCRLs; | |
1162 } | |
1163 | |
1164 NSS_IMPLEMENT PRStatus | |
1165 NSSTrustDomain_GenerateKeyPair ( | |
1166 NSSTrustDomain *td, | |
1167 NSSAlgorithmAndParameters *ap, | |
1168 NSSPrivateKey **pvkOpt, | |
1169 NSSPublicKey **pbkOpt, | |
1170 PRBool privateKeyIsSensitive, | |
1171 NSSToken *destination, | |
1172 NSSCallback *uhhOpt | |
1173 ) | |
1174 { | |
1175 nss_SetError(NSS_ERROR_NOT_FOUND); | |
1176 return PR_FAILURE; | |
1177 } | |
1178 | |
1179 NSS_IMPLEMENT NSSSymmetricKey * | |
1180 NSSTrustDomain_GenerateSymmetricKey ( | |
1181 NSSTrustDomain *td, | |
1182 NSSAlgorithmAndParameters *ap, | |
1183 PRUint32 keysize, | |
1184 NSSToken *destination, | |
1185 NSSCallback *uhhOpt | |
1186 ) | |
1187 { | |
1188 nss_SetError(NSS_ERROR_NOT_FOUND); | |
1189 return NULL; | |
1190 } | |
1191 | |
1192 NSS_IMPLEMENT NSSSymmetricKey * | |
1193 NSSTrustDomain_GenerateSymmetricKeyFromPassword ( | |
1194 NSSTrustDomain *td, | |
1195 NSSAlgorithmAndParameters *ap, | |
1196 NSSUTF8 *passwordOpt, /* if null, prompt */ | |
1197 NSSToken *destinationOpt, | |
1198 NSSCallback *uhhOpt | |
1199 ) | |
1200 { | |
1201 nss_SetError(NSS_ERROR_NOT_FOUND); | |
1202 return NULL; | |
1203 } | |
1204 | |
1205 NSS_IMPLEMENT NSSSymmetricKey * | |
1206 NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID ( | |
1207 NSSTrustDomain *td, | |
1208 NSSOID *algorithm, | |
1209 NSSItem *keyID, | |
1210 NSSCallback *uhhOpt | |
1211 ) | |
1212 { | |
1213 nss_SetError(NSS_ERROR_NOT_FOUND); | |
1214 return NULL; | |
1215 } | |
1216 | |
1217 NSS_IMPLEMENT NSSCryptoContext * | |
1218 nssTrustDomain_CreateCryptoContext ( | |
1219 NSSTrustDomain *td, | |
1220 NSSCallback *uhhOpt | |
1221 ) | |
1222 { | |
1223 return nssCryptoContext_Create(td, uhhOpt); | |
1224 } | |
1225 | |
1226 NSS_IMPLEMENT NSSCryptoContext * | |
1227 NSSTrustDomain_CreateCryptoContext ( | |
1228 NSSTrustDomain *td, | |
1229 NSSCallback *uhhOpt | |
1230 ) | |
1231 { | |
1232 return nssTrustDomain_CreateCryptoContext(td, uhhOpt); | |
1233 } | |
1234 | |
1235 NSS_IMPLEMENT NSSCryptoContext * | |
1236 NSSTrustDomain_CreateCryptoContextForAlgorithm ( | |
1237 NSSTrustDomain *td, | |
1238 NSSOID *algorithm | |
1239 ) | |
1240 { | |
1241 nss_SetError(NSS_ERROR_NOT_FOUND); | |
1242 return NULL; | |
1243 } | |
1244 | |
1245 NSS_IMPLEMENT NSSCryptoContext * | |
1246 NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters ( | |
1247 NSSTrustDomain *td, | |
1248 NSSAlgorithmAndParameters *ap | |
1249 ) | |
1250 { | |
1251 nss_SetError(NSS_ERROR_NOT_FOUND); | |
1252 return NULL; | |
1253 } | |
1254 |