/src/nss/lib/pki/trustdomain.c
Line | Count | Source |
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 "dev3hack.h" |
15 | | #include "pki3hack.h" |
16 | | #include "pk11pub.h" |
17 | | #include "nssrwlk.h" |
18 | | #include "pk11priv.h" |
19 | | |
20 | 18 | #define NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE 32 |
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 | 18 | { |
31 | 18 | NSSArena *arena; |
32 | 18 | NSSTrustDomain *rvTD; |
33 | 18 | arena = NSSArena_Create(); |
34 | 18 | if (!arena) { |
35 | 0 | return (NSSTrustDomain *)NULL; |
36 | 0 | } |
37 | 18 | rvTD = nss_ZNEW(arena, NSSTrustDomain); |
38 | 18 | if (!rvTD) { |
39 | 0 | goto loser; |
40 | 0 | } |
41 | | /* protect the token list and the token iterator */ |
42 | 18 | rvTD->tokensLock = NSSRWLock_New(100, "tokens"); |
43 | 18 | if (!rvTD->tokensLock) { |
44 | 0 | goto loser; |
45 | 0 | } |
46 | 18 | nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE); |
47 | 18 | rvTD->arena = arena; |
48 | 18 | rvTD->refCount = 1; |
49 | 18 | rvTD->statusConfig = NULL; |
50 | 18 | return rvTD; |
51 | 0 | loser: |
52 | 0 | if (rvTD && rvTD->tokensLock) { |
53 | 0 | NSSRWLock_Destroy(rvTD->tokensLock); |
54 | 0 | } |
55 | 0 | nssArena_Destroy(arena); |
56 | 0 | return (NSSTrustDomain *)NULL; |
57 | 18 | } |
58 | | |
59 | | static void |
60 | | token_destructor(void *t) |
61 | 32 | { |
62 | 32 | NSSToken *tok = (NSSToken *)t; |
63 | | |
64 | | /* Signal that the slot should not give out any more references to the |
65 | | * token. Do this first, while |tok| (and its reference to the slot) is |
66 | | * still alive: the list may hold the last reference, in which case |
67 | | * nssToken_Destroy() below frees the arena that contains |tok|. */ |
68 | 32 | PK11Slot_SetNSSToken(tok->pk11slot, NULL); |
69 | | |
70 | | /* Remove the token list's reference to the token */ |
71 | 32 | (void)nssToken_Destroy(tok); |
72 | 32 | } |
73 | | |
74 | | NSS_IMPLEMENT PRStatus |
75 | | NSSTrustDomain_Destroy( |
76 | | NSSTrustDomain *td) |
77 | 16 | { |
78 | 16 | PRStatus status = PR_SUCCESS; |
79 | 16 | if (--td->refCount == 0) { |
80 | | /* Destroy each token in the list of tokens */ |
81 | 16 | if (td->tokens) { |
82 | 16 | nssListIterator_Destroy(td->tokens); |
83 | 16 | td->tokens = NULL; |
84 | 16 | } |
85 | 16 | if (td->tokenList) { |
86 | 16 | nssList_Clear(td->tokenList, token_destructor); |
87 | 16 | nssList_Destroy(td->tokenList); |
88 | 16 | td->tokenList = NULL; |
89 | 16 | } |
90 | 16 | NSSRWLock_Destroy(td->tokensLock); |
91 | 16 | td->tokensLock = NULL; |
92 | 16 | status = nssTrustDomain_DestroyCache(td); |
93 | 16 | if (status == PR_FAILURE) { |
94 | 0 | return status; |
95 | 0 | } |
96 | 16 | if (td->statusConfig) { |
97 | 0 | td->statusConfig->statusDestroy(td->statusConfig); |
98 | 0 | td->statusConfig = NULL; |
99 | 0 | } |
100 | | /* Destroy the trust domain */ |
101 | 16 | nssArena_Destroy(td->arena); |
102 | 16 | } |
103 | 16 | return status; |
104 | 16 | } |
105 | | |
106 | | /* XXX uses tokens until slot list is in place */ |
107 | | static NSSSlot ** |
108 | | nssTrustDomain_GetActiveSlots( |
109 | | NSSTrustDomain *td, |
110 | | nssUpdateLevel *updateLevel) |
111 | 320k | { |
112 | 320k | PRUint32 count; |
113 | 320k | NSSSlot **slots = NULL; |
114 | 320k | NSSToken **tp, **tokens; |
115 | 320k | *updateLevel = 1; |
116 | 320k | if (!td->tokenList) { |
117 | 0 | return NULL; |
118 | 0 | } |
119 | 320k | NSSRWLock_LockRead(td->tokensLock); |
120 | 320k | count = nssList_Count(td->tokenList); |
121 | 320k | tokens = nss_ZNEWARRAY(NULL, NSSToken *, count + 1); |
122 | 320k | if (!tokens) { |
123 | 0 | NSSRWLock_UnlockRead(td->tokensLock); |
124 | 0 | return NULL; |
125 | 0 | } |
126 | 320k | slots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1); |
127 | 320k | if (!slots) { |
128 | 0 | NSSRWLock_UnlockRead(td->tokensLock); |
129 | 0 | nss_ZFreeIf(tokens); |
130 | 0 | return NULL; |
131 | 0 | } |
132 | 320k | nssList_GetArray(td->tokenList, (void **)tokens, count); |
133 | 320k | count = 0; |
134 | 961k | for (tp = tokens; *tp; tp++) { |
135 | 641k | NSSSlot *slot = nssToken_GetSlot(*tp); |
136 | 641k | if (!PK11_IsDisabled(slot->pk11slot)) { |
137 | 641k | slots[count++] = slot; |
138 | 641k | } else { |
139 | 0 | nssSlot_Destroy(slot); |
140 | 0 | } |
141 | 641k | } |
142 | 320k | NSSRWLock_UnlockRead(td->tokensLock); |
143 | 320k | nss_ZFreeIf(tokens); |
144 | 320k | if (!count) { |
145 | 0 | nss_ZFreeIf(slots); |
146 | 0 | slots = NULL; |
147 | 0 | } |
148 | 320k | return slots; |
149 | 320k | } |
150 | | |
151 | | /* XXX */ |
152 | | static nssSession * |
153 | | nssTrustDomain_GetSessionForToken( |
154 | | NSSTrustDomain *td, |
155 | | NSSToken *token) |
156 | 189k | { |
157 | 189k | return nssToken_GetDefaultSession(token); |
158 | 189k | } |
159 | | |
160 | | NSS_IMPLEMENT NSSToken ** |
161 | | NSSTrustDomain_FindTokensByURI( |
162 | | NSSTrustDomain *td, |
163 | | PK11URI *uri) |
164 | 0 | { |
165 | 0 | NSSToken *tok = NULL; |
166 | 0 | PK11SlotInfo *slotinfo; |
167 | 0 | NSSToken **tokens; |
168 | 0 | int count, i = 0; |
169 | |
|
170 | 0 | NSSRWLock_LockRead(td->tokensLock); |
171 | 0 | count = nssList_Count(td->tokenList); |
172 | 0 | tokens = nss_ZNEWARRAY(NULL, NSSToken *, count + 1); |
173 | 0 | if (!tokens) { |
174 | 0 | NSSRWLock_UnlockRead(td->tokensLock); |
175 | 0 | return NULL; |
176 | 0 | } |
177 | 0 | for (tok = (NSSToken *)nssListIterator_Start(td->tokens); |
178 | 0 | tok != (NSSToken *)NULL && i < count; |
179 | 0 | tok = (NSSToken *)nssListIterator_Next(td->tokens)) { |
180 | 0 | if (nssToken_IsPresent(tok)) { |
181 | 0 | slotinfo = tok->pk11slot; |
182 | 0 | if (pk11_MatchUriTokenInfo(slotinfo, uri)) |
183 | 0 | tokens[i++] = nssToken_AddRef(tok); |
184 | 0 | } |
185 | 0 | } |
186 | 0 | tokens[i] = NULL; |
187 | 0 | nssListIterator_Finish(td->tokens); |
188 | 0 | NSSRWLock_UnlockRead(td->tokensLock); |
189 | 0 | return tokens; |
190 | 0 | } |
191 | | |
192 | | NSS_IMPLEMENT NSSToken * |
193 | | NSSTrustDomain_FindTokenByName( |
194 | | NSSTrustDomain *td, |
195 | | NSSUTF8 *tokenName) |
196 | 0 | { |
197 | 0 | PRStatus nssrv; |
198 | 0 | NSSUTF8 *myName; |
199 | 0 | NSSToken *tok = NULL; |
200 | 0 | NSSRWLock_LockRead(td->tokensLock); |
201 | 0 | for (tok = (NSSToken *)nssListIterator_Start(td->tokens); |
202 | 0 | tok != (NSSToken *)NULL; |
203 | 0 | tok = (NSSToken *)nssListIterator_Next(td->tokens)) { |
204 | 0 | if (nssToken_IsPresent(tok)) { |
205 | 0 | myName = nssToken_GetName(tok); |
206 | 0 | if (nssUTF8_Equal(tokenName, myName, &nssrv)) { |
207 | 0 | tok = nssToken_AddRef(tok); |
208 | 0 | break; |
209 | 0 | } |
210 | 0 | } |
211 | 0 | } |
212 | 0 | nssListIterator_Finish(td->tokens); |
213 | 0 | NSSRWLock_UnlockRead(td->tokensLock); |
214 | 0 | return tok; |
215 | 0 | } |
216 | | |
217 | | static NSSCertificate ** |
218 | | get_certs_from_list(nssList *list) |
219 | 12.8k | { |
220 | 12.8k | PRUint32 count = nssList_Count(list); |
221 | 12.8k | NSSCertificate **certs = NULL; |
222 | 12.8k | if (count > 0) { |
223 | 0 | certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1); |
224 | 0 | if (certs) { |
225 | 0 | nssList_GetArray(list, (void **)certs, count); |
226 | 0 | } |
227 | 0 | } |
228 | 12.8k | return certs; |
229 | 12.8k | } |
230 | | |
231 | | NSS_IMPLEMENT NSSCertificate ** |
232 | | nssTrustDomain_FindCertificatesBySubject( |
233 | | NSSTrustDomain *td, |
234 | | NSSDER *subject, |
235 | | NSSCertificate *rvOpt[], |
236 | | PRUint32 maximumOpt, /* 0 for no max */ |
237 | | NSSArena *arenaOpt) |
238 | 12.8k | { |
239 | 12.8k | NSSToken *token = NULL; |
240 | 12.8k | NSSSlot **slots = NULL; |
241 | 12.8k | NSSSlot **slotp; |
242 | 12.8k | NSSCertificate **rvCerts = NULL; |
243 | 12.8k | nssPKIObjectCollection *collection = NULL; |
244 | 12.8k | nssUpdateLevel updateLevel; |
245 | 12.8k | nssList *subjectList; |
246 | 12.8k | PRUint32 numRemaining = maximumOpt; |
247 | 12.8k | PRUint32 collectionCount = 0; |
248 | 12.8k | PRUint32 errors = 0; |
249 | | |
250 | | /* look in cache */ |
251 | 12.8k | subjectList = nssList_Create(NULL, PR_FALSE); |
252 | 12.8k | if (!subjectList) { |
253 | 0 | return NULL; |
254 | 0 | } |
255 | 12.8k | (void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList); |
256 | 12.8k | rvCerts = get_certs_from_list(subjectList); |
257 | 12.8k | collection = nssCertificateCollection_Create(td, rvCerts); |
258 | 12.8k | nssCertificateArray_Destroy(rvCerts); |
259 | 12.8k | nssList_Destroy(subjectList); |
260 | 12.8k | if (!collection) { |
261 | 0 | return (NSSCertificate **)NULL; |
262 | 0 | } |
263 | 12.8k | slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); |
264 | 12.8k | if (!slots) { |
265 | 0 | goto loser; |
266 | 0 | } |
267 | 38.4k | for (slotp = slots; *slotp; slotp++) { |
268 | 25.6k | token = nssSlot_GetToken(*slotp); |
269 | 25.6k | if (token) { |
270 | 25.6k | nssSession *session; |
271 | 25.6k | nssCryptokiObject **instances = NULL; |
272 | 25.6k | nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; |
273 | 25.6k | PRStatus status = PR_FAILURE; |
274 | | |
275 | 25.6k | session = nssTrustDomain_GetSessionForToken(td, token); |
276 | 25.6k | if (session) { |
277 | 25.6k | instances = nssToken_FindCertificatesBySubject(token, |
278 | 25.6k | session, |
279 | 25.6k | subject, |
280 | 25.6k | tokenOnly, |
281 | 25.6k | numRemaining, |
282 | 25.6k | &status); |
283 | 25.6k | } |
284 | 25.6k | (void)nssToken_Destroy(token); |
285 | 25.6k | if (status != PR_SUCCESS) { |
286 | 0 | errors++; |
287 | 0 | continue; |
288 | 0 | } |
289 | 25.6k | if (instances) { |
290 | 0 | status = nssPKIObjectCollection_AddInstances(collection, |
291 | 0 | instances, 0); |
292 | 0 | nss_ZFreeIf(instances); |
293 | 0 | if (status != PR_SUCCESS) { |
294 | 0 | errors++; |
295 | 0 | continue; |
296 | 0 | } |
297 | 0 | collectionCount = nssPKIObjectCollection_Count(collection); |
298 | 0 | if (maximumOpt > 0) { |
299 | 0 | if (collectionCount >= maximumOpt) |
300 | 0 | break; |
301 | 0 | numRemaining = maximumOpt - collectionCount; |
302 | 0 | } |
303 | 0 | } |
304 | 25.6k | } |
305 | 25.6k | } |
306 | 12.8k | if (!collectionCount && errors) |
307 | 0 | goto loser; |
308 | 12.8k | rvCerts = nssPKIObjectCollection_GetCertificates(collection, |
309 | 12.8k | rvOpt, maximumOpt, |
310 | 12.8k | arenaOpt); |
311 | 12.8k | nssPKIObjectCollection_Destroy(collection); |
312 | 12.8k | nssSlotArray_Destroy(slots); |
313 | 12.8k | return rvCerts; |
314 | 0 | loser: |
315 | 0 | if (slots) { |
316 | 0 | nssSlotArray_Destroy(slots); |
317 | 0 | } |
318 | 0 | if (collection) { |
319 | 0 | nssPKIObjectCollection_Destroy(collection); |
320 | 0 | } |
321 | 0 | return (NSSCertificate **)NULL; |
322 | 12.8k | } |
323 | | |
324 | | NSS_IMPLEMENT NSSCertificate ** |
325 | | NSSTrustDomain_FindCertificatesBySubject( |
326 | | NSSTrustDomain *td, |
327 | | NSSDER *subject, |
328 | | NSSCertificate *rvOpt[], |
329 | | PRUint32 maximumOpt, |
330 | | NSSArena *arenaOpt) |
331 | 0 | { |
332 | 0 | return nssTrustDomain_FindCertificatesBySubject(td, |
333 | 0 | subject, |
334 | 0 | rvOpt, |
335 | 0 | maximumOpt, |
336 | 0 | arenaOpt); |
337 | 0 | } |
338 | | |
339 | | NSS_IMPLEMENT NSSCertificate * |
340 | | nssTrustDomain_FindBestCertificateBySubject( |
341 | | NSSTrustDomain *td, |
342 | | NSSDER *subject, |
343 | | NSSTime *timeOpt, |
344 | | NSSUsage *usage, |
345 | | NSSPolicies *policiesOpt) |
346 | 0 | { |
347 | 0 | NSSCertificate **subjectCerts; |
348 | 0 | NSSCertificate *rvCert = NULL; |
349 | 0 | subjectCerts = nssTrustDomain_FindCertificatesBySubject(td, subject, |
350 | 0 | NULL, |
351 | 0 | 0, |
352 | 0 | NULL); |
353 | 0 | if (subjectCerts) { |
354 | 0 | rvCert = nssCertificateArray_FindBestCertificate(subjectCerts, |
355 | 0 | timeOpt, |
356 | 0 | usage, |
357 | 0 | policiesOpt); |
358 | 0 | nssCertificateArray_Destroy(subjectCerts); |
359 | 0 | } |
360 | 0 | return rvCert; |
361 | 0 | } |
362 | | |
363 | | NSS_IMPLEMENT NSSCertificate * |
364 | | NSSTrustDomain_FindBestCertificateBySubject( |
365 | | NSSTrustDomain *td, |
366 | | NSSDER *subject, |
367 | | NSSTime *timeOpt, |
368 | | NSSUsage *usage, |
369 | | NSSPolicies *policiesOpt) |
370 | 0 | { |
371 | 0 | return nssTrustDomain_FindBestCertificateBySubject(td, |
372 | 0 | subject, |
373 | 0 | timeOpt, |
374 | 0 | usage, |
375 | 0 | policiesOpt); |
376 | 0 | } |
377 | | |
378 | | /* This returns at most a single certificate, so it can stop the loop |
379 | | * when one is found. |
380 | | */ |
381 | | NSS_IMPLEMENT NSSCertificate * |
382 | | nssTrustDomain_FindCertificateByIssuerAndSerialNumber( |
383 | | NSSTrustDomain *td, |
384 | | NSSDER *issuer, |
385 | | NSSDER *serial) |
386 | 81.8k | { |
387 | 81.8k | NSSSlot **slots = NULL; |
388 | 81.8k | NSSSlot **slotp; |
389 | 81.8k | NSSCertificate *rvCert = NULL; |
390 | 81.8k | nssPKIObjectCollection *collection = NULL; |
391 | 81.8k | nssUpdateLevel updateLevel; |
392 | | |
393 | | /* see if this search is already cached */ |
394 | 81.8k | rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td, |
395 | 81.8k | issuer, |
396 | 81.8k | serial); |
397 | 81.8k | if (rvCert) { |
398 | 0 | return rvCert; |
399 | 0 | } |
400 | 81.8k | slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); |
401 | 81.8k | if (slots) { |
402 | 245k | for (slotp = slots; *slotp; slotp++) { |
403 | 163k | NSSToken *token = nssSlot_GetToken(*slotp); |
404 | 163k | nssSession *session; |
405 | 163k | nssCryptokiObject *instance; |
406 | 163k | nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; |
407 | 163k | PRStatus status = PR_FAILURE; |
408 | | |
409 | 163k | if (!token) |
410 | 0 | continue; |
411 | 163k | session = nssTrustDomain_GetSessionForToken(td, token); |
412 | 163k | if (session) { |
413 | 163k | instance = nssToken_FindCertificateByIssuerAndSerialNumber( |
414 | 163k | token, |
415 | 163k | session, |
416 | 163k | issuer, |
417 | 163k | serial, |
418 | 163k | tokenOnly, |
419 | 163k | &status); |
420 | 163k | } |
421 | 163k | (void)nssToken_Destroy(token); |
422 | 163k | if (status != PR_SUCCESS) { |
423 | 0 | continue; |
424 | 0 | } |
425 | 163k | if (instance) { |
426 | 0 | if (!collection) { |
427 | 0 | collection = nssCertificateCollection_Create(td, NULL); |
428 | 0 | if (!collection) { |
429 | 0 | break; /* don't keep looping if out if memory */ |
430 | 0 | } |
431 | 0 | } |
432 | 0 | status = nssPKIObjectCollection_AddInstances(collection, |
433 | 0 | &instance, 1); |
434 | 0 | if (status == PR_SUCCESS) { |
435 | 0 | (void)nssPKIObjectCollection_GetCertificates( |
436 | 0 | collection, &rvCert, 1, NULL); |
437 | 0 | } |
438 | 0 | if (rvCert) { |
439 | 0 | break; /* found one cert, all done */ |
440 | 0 | } |
441 | 0 | } |
442 | 163k | } |
443 | 81.8k | } |
444 | 81.8k | if (collection) { |
445 | 0 | nssPKIObjectCollection_Destroy(collection); |
446 | 0 | } |
447 | 81.8k | if (slots) { |
448 | 81.8k | nssSlotArray_Destroy(slots); |
449 | 81.8k | } |
450 | 81.8k | return rvCert; |
451 | 81.8k | } |
452 | | |
453 | | NSS_IMPLEMENT NSSCertificate * |
454 | | NSSTrustDomain_FindCertificateByIssuerAndSerialNumber( |
455 | | NSSTrustDomain *td, |
456 | | NSSDER *issuer, |
457 | | NSSDER *serial) |
458 | 0 | { |
459 | 0 | return nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td, |
460 | 0 | issuer, |
461 | 0 | serial); |
462 | 0 | } |
463 | | |
464 | | NSS_IMPLEMENT NSSCertificate * |
465 | | nssTrustDomain_FindCertificateByEncodedCertificate( |
466 | | NSSTrustDomain *td, |
467 | | NSSBER *ber) |
468 | 82.3k | { |
469 | 82.3k | PRStatus status; |
470 | 82.3k | NSSCertificate *rvCert = NULL; |
471 | 82.3k | NSSDER issuer = { 0 }; |
472 | 82.3k | NSSDER serial = { 0 }; |
473 | | /* XXX this is not generic... will any cert crack into issuer/serial? */ |
474 | 82.3k | status = nssPKIX509_GetIssuerAndSerialFromDER(ber, &issuer, &serial); |
475 | 82.3k | if (status != PR_SUCCESS) { |
476 | 533 | return NULL; |
477 | 533 | } |
478 | 81.8k | rvCert = nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td, |
479 | 81.8k | &issuer, |
480 | 81.8k | &serial); |
481 | 81.8k | PORT_Free(issuer.data); |
482 | 81.8k | PORT_Free(serial.data); |
483 | 81.8k | return rvCert; |
484 | 82.3k | } |
485 | | |
486 | | NSS_IMPLEMENT NSSCertificate * |
487 | | NSSTrustDomain_FindCertificateByEncodedCertificate( |
488 | | NSSTrustDomain *td, |
489 | | NSSBER *ber) |
490 | 82.3k | { |
491 | 82.3k | return nssTrustDomain_FindCertificateByEncodedCertificate(td, ber); |
492 | 82.3k | } |
493 | | |
494 | | static PRStatus |
495 | | collector(nssCryptokiObject *instance, void *arg) |
496 | 0 | { |
497 | 0 | nssPKIObjectCollection *collection = (nssPKIObjectCollection *)arg; |
498 | 0 | return nssPKIObjectCollection_AddInstanceAsObject(collection, instance); |
499 | 0 | } |
500 | | |
501 | | NSS_IMPLEMENT PRStatus * |
502 | | NSSTrustDomain_TraverseCertificates( |
503 | | NSSTrustDomain *td, |
504 | | PRStatus (*callback)(NSSCertificate *c, void *arg), |
505 | | void *arg) |
506 | 5 | { |
507 | 5 | NSSToken *token = NULL; |
508 | 5 | NSSSlot **slots = NULL; |
509 | 5 | NSSSlot **slotp; |
510 | 5 | nssPKIObjectCollection *collection = NULL; |
511 | 5 | nssPKIObjectCallback pkiCallback; |
512 | 5 | nssUpdateLevel updateLevel; |
513 | 5 | NSSCertificate **cached = NULL; |
514 | 5 | nssList *certList; |
515 | | |
516 | 5 | certList = nssList_Create(NULL, PR_FALSE); |
517 | 5 | if (!certList) |
518 | 0 | return NULL; |
519 | 5 | (void)nssTrustDomain_GetCertsFromCache(td, certList); |
520 | 5 | cached = get_certs_from_list(certList); |
521 | 5 | collection = nssCertificateCollection_Create(td, cached); |
522 | 5 | nssCertificateArray_Destroy(cached); |
523 | 5 | nssList_Destroy(certList); |
524 | 5 | if (!collection) { |
525 | 0 | return (PRStatus *)NULL; |
526 | 0 | } |
527 | | /* obtain the current set of active slots in the trust domain */ |
528 | 5 | slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); |
529 | 5 | if (!slots) { |
530 | 0 | goto loser; |
531 | 0 | } |
532 | | /* iterate over the slots */ |
533 | 15 | for (slotp = slots; *slotp; slotp++) { |
534 | | /* get the token for the slot, if present */ |
535 | 10 | token = nssSlot_GetToken(*slotp); |
536 | 10 | if (token) { |
537 | 10 | nssSession *session; |
538 | 10 | nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; |
539 | | /* get a session for the token */ |
540 | 10 | session = nssTrustDomain_GetSessionForToken(td, token); |
541 | 10 | if (session) { |
542 | | /* perform the traversal */ |
543 | 10 | (void)nssToken_TraverseCertificates(token, |
544 | 10 | session, |
545 | 10 | tokenOnly, |
546 | 10 | collector, |
547 | 10 | collection); |
548 | 10 | } |
549 | 10 | (void)nssToken_Destroy(token); |
550 | 10 | } |
551 | 10 | } |
552 | | |
553 | | /* Traverse the collection */ |
554 | 5 | pkiCallback.func.cert = callback; |
555 | 5 | pkiCallback.arg = arg; |
556 | 5 | (void)nssPKIObjectCollection_Traverse(collection, &pkiCallback); |
557 | 5 | loser: |
558 | 5 | if (slots) { |
559 | 5 | nssSlotArray_Destroy(slots); |
560 | 5 | } |
561 | 5 | if (collection) { |
562 | 5 | nssPKIObjectCollection_Destroy(collection); |
563 | 5 | } |
564 | 5 | return NULL; |
565 | 5 | } |
566 | | |
567 | | NSS_IMPLEMENT NSSTrust * |
568 | | nssTrustDomain_FindTrustForCertificate( |
569 | | NSSTrustDomain *td, |
570 | | NSSDER *encoding, |
571 | | NSSDER *issuer, |
572 | | NSSDER *serial) |
573 | 226k | { |
574 | 226k | NSSSlot **slots; |
575 | 226k | NSSSlot **slotp; |
576 | 226k | nssCryptokiObject *to = NULL; |
577 | 226k | nssPKIObject *pkio = NULL; |
578 | 226k | NSSTrust *rvt = NULL; |
579 | 226k | nssUpdateLevel updateLevel; |
580 | 226k | slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); |
581 | 226k | if (!slots) { |
582 | 0 | return (NSSTrust *)NULL; |
583 | 0 | } |
584 | 678k | for (slotp = slots; *slotp; slotp++) { |
585 | 452k | NSSToken *token = nssSlot_GetToken(*slotp); |
586 | | |
587 | 452k | if (token) { |
588 | 452k | to = nssToken_FindTrustForCertificate(token, NULL, |
589 | 452k | encoding, |
590 | 452k | issuer, |
591 | 452k | serial, |
592 | 452k | nssTokenSearchType_TokenOnly); |
593 | 452k | if (to) { |
594 | 0 | PRStatus status; |
595 | 0 | if (!pkio) { |
596 | 0 | pkio = nssPKIObject_Create(NULL, to, td, NULL, nssPKILock); |
597 | 0 | status = pkio ? PR_SUCCESS : PR_FAILURE; |
598 | 0 | } else { |
599 | 0 | status = nssPKIObject_AddInstance(pkio, to); |
600 | 0 | } |
601 | 0 | if (status != PR_SUCCESS) { |
602 | 0 | nssCryptokiObject_Destroy(to); |
603 | 0 | } |
604 | 0 | } |
605 | 452k | (void)nssToken_Destroy(token); |
606 | 452k | } |
607 | 452k | } |
608 | 226k | if (pkio) { |
609 | 0 | rvt = nssTrust_Create(pkio, encoding); |
610 | 0 | if (rvt) { |
611 | 0 | pkio = NULL; /* rvt object now owns the pkio reference */ |
612 | 0 | } |
613 | 0 | } |
614 | 226k | nssSlotArray_Destroy(slots); |
615 | 226k | if (pkio) { |
616 | 0 | nssPKIObject_Destroy(pkio); |
617 | 0 | } |
618 | 226k | return rvt; |
619 | 226k | } |
620 | | |
621 | | NSS_IMPLEMENT NSSCRL ** |
622 | | nssTrustDomain_FindCRLsBySubject( |
623 | | NSSTrustDomain *td, |
624 | | NSSDER *subject) |
625 | 0 | { |
626 | 0 | NSSSlot **slots; |
627 | 0 | NSSSlot **slotp; |
628 | 0 | NSSToken *token; |
629 | 0 | nssUpdateLevel updateLevel; |
630 | 0 | nssPKIObjectCollection *collection; |
631 | 0 | NSSCRL **rvCRLs = NULL; |
632 | 0 | collection = nssCRLCollection_Create(td, NULL); |
633 | 0 | if (!collection) { |
634 | 0 | return (NSSCRL **)NULL; |
635 | 0 | } |
636 | 0 | slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); |
637 | 0 | if (!slots) { |
638 | 0 | goto loser; |
639 | 0 | } |
640 | 0 | for (slotp = slots; *slotp; slotp++) { |
641 | 0 | token = nssSlot_GetToken(*slotp); |
642 | 0 | if (token) { |
643 | 0 | PRStatus status = PR_FAILURE; |
644 | 0 | nssSession *session; |
645 | 0 | nssCryptokiObject **instances = NULL; |
646 | 0 | nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; |
647 | | |
648 | | /* get a session for the token */ |
649 | 0 | session = nssTrustDomain_GetSessionForToken(td, token); |
650 | 0 | if (session) { |
651 | | /* perform the traversal */ |
652 | 0 | instances = nssToken_FindCRLsBySubject(token, session, subject, |
653 | 0 | tokenOnly, 0, &status); |
654 | 0 | } |
655 | 0 | (void)nssToken_Destroy(token); |
656 | 0 | if (status == PR_SUCCESS) { |
657 | | /* add the found CRL's to the collection */ |
658 | 0 | status = nssPKIObjectCollection_AddInstances(collection, |
659 | 0 | instances, 0); |
660 | 0 | } |
661 | 0 | nss_ZFreeIf(instances); |
662 | 0 | } |
663 | 0 | } |
664 | 0 | rvCRLs = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL); |
665 | 0 | loser: |
666 | 0 | nssPKIObjectCollection_Destroy(collection); |
667 | 0 | nssSlotArray_Destroy(slots); |
668 | 0 | return rvCRLs; |
669 | 0 | } |
670 | | |
671 | | NSS_IMPLEMENT NSSCryptoContext * |
672 | | nssTrustDomain_CreateCryptoContext( |
673 | | NSSTrustDomain *td, |
674 | | NSSCallback *uhhOpt) |
675 | 18 | { |
676 | 18 | return nssCryptoContext_Create(td, uhhOpt); |
677 | 18 | } |
678 | | |
679 | | NSS_IMPLEMENT NSSCryptoContext * |
680 | | NSSTrustDomain_CreateCryptoContext( |
681 | | NSSTrustDomain *td, |
682 | | NSSCallback *uhhOpt) |
683 | 18 | { |
684 | 18 | return nssTrustDomain_CreateCryptoContext(td, uhhOpt); |
685 | 18 | } |