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