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 * pkix_pl_colcertstore.c | |
6 * | |
7 * CollectionCertStore Function Definitions | |
8 * | |
9 */ | |
10 | |
11 #include "pkix_pl_colcertstore.h" | |
12 | |
13 /* | |
14 * This Object is going to be taken out from libpkix SOON. The following | |
15 * function is copied from nss/cmd library, but not supported by NSS as | |
16 * public API. We use it since ColCertStore are read in Cert/Crl from | |
17 * files and need this support. | |
18 */ | |
19 | |
20 static SECStatus | |
21 SECU_FileToItem(SECItem *dst, PRFileDesc *src) | |
22 { | |
23 PRFileInfo info; | |
24 PRInt32 numBytes; | |
25 PRStatus prStatus; | |
26 | |
27 prStatus = PR_GetOpenFileInfo(src, &info); | |
28 | |
29 if (prStatus != PR_SUCCESS) { | |
30 PORT_SetError(SEC_ERROR_IO); | |
31 return SECFailure; | |
32 } | |
33 | |
34 /* XXX workaround for 3.1, not all utils zero dst before sending */ | |
35 dst->data = 0; | |
36 if (!SECITEM_AllocItem(NULL, dst, info.size)) | |
37 goto loser; | |
38 | |
39 numBytes = PR_Read(src, dst->data, info.size); | |
40 if (numBytes != info.size) { | |
41 PORT_SetError(SEC_ERROR_IO); | |
42 goto loser; | |
43 } | |
44 | |
45 return SECSuccess; | |
46 loser: | |
47 SECITEM_FreeItem(dst, PR_FALSE); | |
48 return SECFailure; | |
49 } | |
50 | |
51 static SECStatus | |
52 SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii) | |
53 { | |
54 SECStatus rv; | |
55 if (ascii) { | |
56 /* First convert ascii to binary */ | |
57 SECItem filedata; | |
58 char *asc, *body; | |
59 | |
60 /* Read in ascii data */ | |
61 rv = SECU_FileToItem(&filedata, inFile); | |
62 asc = (char *)filedata.data; | |
63 if (!asc) { | |
64 fprintf(stderr, "unable to read data from input file\n"); | |
65 return SECFailure; | |
66 } | |
67 | |
68 /* check for headers and trailers and remove them */ | |
69 if ((body = strstr(asc, "-----BEGIN")) != NULL) { | |
70 char *trailer = NULL; | |
71 asc = body; | |
72 body = PORT_Strchr(body, '\n'); | |
73 if (!body) | |
74 body = PORT_Strchr(asc, '\r'); /* maybe this is a MAC file */ | |
75 if (body) | |
76 trailer = strstr(++body, "-----END"); | |
77 if (trailer != NULL) { | |
78 *trailer = '\0'; | |
79 } else { | |
80 fprintf(stderr, "input has header but no trailer\n"); | |
81 PORT_Free(filedata.data); | |
82 return SECFailure; | |
83 } | |
84 } else { | |
85 body = asc; | |
86 } | |
87 | |
88 /* Convert to binary */ | |
89 rv = ATOB_ConvertAsciiToItem(der, body); | |
90 if (rv) { | |
91 return SECFailure; | |
92 } | |
93 | |
94 PORT_Free(filedata.data); | |
95 } else { | |
96 /* Read in binary der */ | |
97 rv = SECU_FileToItem(der, inFile); | |
98 if (rv) { | |
99 return SECFailure; | |
100 } | |
101 } | |
102 return SECSuccess; | |
103 } | |
104 | |
105 /* | |
106 * FUNCTION: PKIX_PL_CollectionCertStoreContext_Create | |
107 * DESCRIPTION: | |
108 * | |
109 * Creates a new CollectionCertStoreContext using the String pointed to | |
110 * by "storeDir" and stores it at "pColCertStoreContext". | |
111 * | |
112 * PARAMETERS: | |
113 * "storeDir" | |
114 * The absolute path where *.crl and *.crt files are located. | |
115 * "pColCertStoreContext" | |
116 * Address where object pointer will be stored. Must be non-NULL. | |
117 * "plContext" | |
118 * Platform-specific context pointer. | |
119 * THREAD SAFETY: | |
120 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
121 * RETURNS: | |
122 * Returns NULL if the function succeeds. | |
123 * Returns a CollectionCertStoreContext Error if the function fails in | |
124 * a non-fatal way. | |
125 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
126 */ | |
127 static PKIX_Error * | |
128 pkix_pl_CollectionCertStoreContext_Create( | |
129 PKIX_PL_String *storeDir, | |
130 PKIX_PL_CollectionCertStoreContext **pColCertStoreContext, | |
131 void *plContext) | |
132 { | |
133 PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL; | |
134 | |
135 PKIX_ENTER(COLLECTIONCERTSTORECONTEXT, | |
136 "pkix_pl_CollectionCertStoreContext_Create"); | |
137 PKIX_NULLCHECK_TWO(storeDir, pColCertStoreContext); | |
138 | |
139 PKIX_CHECK(PKIX_PL_Object_Alloc | |
140 (PKIX_COLLECTIONCERTSTORECONTEXT_TYPE, | |
141 sizeof (PKIX_PL_CollectionCertStoreContext), | |
142 (PKIX_PL_Object **)&colCertStoreContext, | |
143 plContext), | |
144 PKIX_COULDNOTCREATECOLLECTIONCERTSTORECONTEXTOBJECT); | |
145 | |
146 PKIX_INCREF(storeDir); | |
147 colCertStoreContext->storeDir = storeDir; | |
148 | |
149 colCertStoreContext->crlList = NULL; | |
150 colCertStoreContext->certList = NULL; | |
151 | |
152 *pColCertStoreContext = colCertStoreContext; | |
153 colCertStoreContext = NULL; | |
154 | |
155 cleanup: | |
156 | |
157 PKIX_DECREF(colCertStoreContext); | |
158 | |
159 PKIX_RETURN(COLLECTIONCERTSTORECONTEXT); | |
160 } | |
161 | |
162 /* | |
163 * FUNCTION: pkix_pl_CollectionCertStoreContext_Destroy | |
164 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |
165 */ | |
166 static PKIX_Error * | |
167 pkix_pl_CollectionCertStoreContext_Destroy( | |
168 PKIX_PL_Object *object, | |
169 void *plContext) | |
170 { | |
171 PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL; | |
172 | |
173 PKIX_ENTER(COLLECTIONCERTSTORECONTEXT, | |
174 "pkix_pl_CollectionCertStoreContext_Destroy"); | |
175 PKIX_NULLCHECK_ONE(object); | |
176 | |
177 PKIX_CHECK(pkix_CheckType | |
178 (object, PKIX_COLLECTIONCERTSTORECONTEXT_TYPE, plContext), | |
179 PKIX_OBJECTNOTCOLLECTIONCERTSTORECONTEXT); | |
180 | |
181 colCertStoreContext = (PKIX_PL_CollectionCertStoreContext *)object; | |
182 | |
183 PKIX_DECREF(colCertStoreContext->storeDir); | |
184 PKIX_DECREF(colCertStoreContext->crlList); | |
185 PKIX_DECREF(colCertStoreContext->certList); | |
186 | |
187 cleanup: | |
188 PKIX_RETURN(COLLECTIONCERTSTORECONTEXT); | |
189 } | |
190 | |
191 /* | |
192 * FUNCTION: pkix_pl_CollectionCertStoreContext_Hashcode | |
193 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) | |
194 */ | |
195 static PKIX_Error * | |
196 pkix_pl_CollectionCertStoreContext_Hashcode( | |
197 PKIX_PL_Object *object, | |
198 PKIX_UInt32 *pHashcode, | |
199 void *plContext) | |
200 { | |
201 PKIX_PL_CollectionCertStoreContext *collectionCSContext = NULL; | |
202 PKIX_UInt32 tempHash = 0; | |
203 | |
204 PKIX_ENTER(COLLECTIONCERTSTORECONTEXT, | |
205 "pkix_pl_CollectionCertStoreContext_Hashcode"); | |
206 PKIX_NULLCHECK_TWO(object, pHashcode); | |
207 | |
208 PKIX_CHECK(pkix_CheckType | |
209 (object, | |
210 PKIX_COLLECTIONCERTSTORECONTEXT_TYPE, | |
211 plContext), | |
212 PKIX_OBJECTNOTCOLLECTIONCERTSTORECONTEXT); | |
213 | |
214 collectionCSContext = (PKIX_PL_CollectionCertStoreContext *)object; | |
215 | |
216 PKIX_CHECK(PKIX_PL_Object_Hashcode | |
217 ((PKIX_PL_Object *) collectionCSContext->storeDir, | |
218 &tempHash, | |
219 plContext), | |
220 PKIX_STRINGHASHCODEFAILED); | |
221 | |
222 *pHashcode = tempHash << 7; | |
223 | |
224 /* should not hash on crlList and certList, values are dynamic */ | |
225 | |
226 cleanup: | |
227 PKIX_RETURN(COLLECTIONCERTSTORECONTEXT); | |
228 } | |
229 | |
230 /* | |
231 * FUNCTION: pkix_pl_CollectionCertStoreContext_Equals | |
232 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h) | |
233 */ | |
234 static PKIX_Error * | |
235 pkix_pl_CollectionCertStoreContext_Equals( | |
236 PKIX_PL_Object *firstObject, | |
237 PKIX_PL_Object *secondObject, | |
238 PKIX_Int32 *pResult, | |
239 void *plContext) | |
240 { | |
241 PKIX_PL_CollectionCertStoreContext *firstCCSContext = NULL; | |
242 PKIX_PL_CollectionCertStoreContext *secondCCSContext = NULL; | |
243 PKIX_Boolean cmpResult = 0; | |
244 | |
245 PKIX_ENTER(COLLECTIONCERTSTORECONTEXT, | |
246 "pkix_pl_CollectionCertStoreContext_Equals"); | |
247 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); | |
248 | |
249 PKIX_CHECK(pkix_CheckTypes | |
250 (firstObject, | |
251 secondObject, | |
252 PKIX_COLLECTIONCERTSTORECONTEXT_TYPE, | |
253 plContext), | |
254 PKIX_OBJECTNOTCOLLECTIONCERTSTORECONTEXT); | |
255 | |
256 firstCCSContext = (PKIX_PL_CollectionCertStoreContext *)firstObject; | |
257 secondCCSContext = (PKIX_PL_CollectionCertStoreContext *)secondObject; | |
258 | |
259 if (firstCCSContext->storeDir == secondCCSContext->storeDir) { | |
260 | |
261 cmpResult = PKIX_TRUE; | |
262 | |
263 } else { | |
264 | |
265 PKIX_CHECK(PKIX_PL_Object_Equals | |
266 ((PKIX_PL_Object *) firstCCSContext->storeDir, | |
267 (PKIX_PL_Object *) secondCCSContext->storeDir, | |
268 &cmpResult, | |
269 plContext), | |
270 PKIX_STRINGEQUALSFAILED); | |
271 } | |
272 | |
273 *pResult = cmpResult; | |
274 | |
275 /* should not check equal on crlList and certList, data are dynamic */ | |
276 | |
277 cleanup: | |
278 PKIX_RETURN(COLLECTIONCERTSTORECONTEXT); | |
279 } | |
280 | |
281 /* | |
282 * FUNCTION: pkix_pl_CollectionCertStore_CheckTrust | |
283 * DESCRIPTION: | |
284 * This function checks the trust status of this "cert" that was retrieved | |
285 * from the CertStore "store" and returns its trust status at "pTrusted". | |
286 * | |
287 * PARAMETERS: | |
288 * "store" | |
289 * Address of the CertStore. Must be non-NULL. | |
290 * "cert" | |
291 * Address of the Cert. Must be non-NULL. | |
292 * "pTrusted" | |
293 * Address of PKIX_Boolean where the "cert" trust status is returned. | |
294 * Must be non-NULL. | |
295 * "plContext" | |
296 * Platform-specific context pointer | |
297 * THREAD SAFETY: | |
298 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
299 * RETURNS: | |
300 * Returns NULL if the function succeeds. | |
301 * Returns a CertStore Error if the function fails in a non-fatal way. | |
302 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
303 */ | |
304 static PKIX_Error * | |
305 pkix_pl_CollectionCertStore_CheckTrust( | |
306 PKIX_CertStore *store, | |
307 PKIX_PL_Cert *cert, | |
308 PKIX_Boolean *pTrusted, | |
309 void *plContext) | |
310 { | |
311 PKIX_ENTER(CERTSTORE, "pkix_pl_CollectionCertStore_CheckTrust"); | |
312 PKIX_NULLCHECK_THREE(store, cert, pTrusted); | |
313 | |
314 *pTrusted = PKIX_TRUE; | |
315 | |
316 PKIX_RETURN(CERTSTORE); | |
317 } | |
318 | |
319 /* | |
320 * FUNCTION: pkix_pl_CollectionCertStoreContext_CreateCert | |
321 * DESCRIPTION: | |
322 * | |
323 * Creates Cert using data file path name pointed to by "certFileName" and | |
324 * stores it at "pCert". If the Cert can not be decoded, NULL is stored | |
325 * at "pCert". | |
326 * | |
327 * PARAMETERS | |
328 * "certFileName" - Address of Cert data file path name. Must be non-NULL. | |
329 * "pCert" - Address where object pointer will be stored. Must be non-NULL. | |
330 * "plContext" - Platform-specific context pointer. | |
331 * THREAD SAFETY: | |
332 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
333 * RETURNS: | |
334 * Returns NULL if the function succeeds. | |
335 * Returns a CollectionCertStoreContext Error if the function fails in | |
336 * a non-fatal way. | |
337 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
338 */ | |
339 static PKIX_Error * | |
340 pkix_pl_CollectionCertStoreContext_CreateCert( | |
341 const char *certFileName, | |
342 PKIX_PL_Cert **pCert, | |
343 void *plContext) | |
344 { | |
345 PKIX_PL_ByteArray *byteArray = NULL; | |
346 PKIX_PL_Cert *cert = NULL; | |
347 PRFileDesc *inFile = NULL; | |
348 SECItem certDER; | |
349 void *buf = NULL; | |
350 PKIX_UInt32 len; | |
351 SECStatus rv; | |
352 | |
353 PKIX_ENTER(COLLECTIONCERTSTORECONTEXT, | |
354 "pkix_pl_CollectionCertStoreContext_CreateCert"); | |
355 PKIX_NULLCHECK_TWO(certFileName, pCert); | |
356 | |
357 *pCert = NULL; | |
358 certDER.data = NULL; | |
359 | |
360 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_Open.\n"); | |
361 inFile = PR_Open(certFileName, PR_RDONLY, 0); | |
362 | |
363 if (!inFile){ | |
364 PKIX_ERROR(PKIX_UNABLETOOPENCERTFILE); | |
365 } else { | |
366 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
367 ("\t\t Calling SECU_ReadDerFromFile.\n"); | |
368 rv = SECU_ReadDERFromFile(&certDER, inFile, PR_FALSE); | |
369 if (!rv){ | |
370 buf = (void *)certDER.data; | |
371 len = certDER.len; | |
372 | |
373 PKIX_CHECK(PKIX_PL_ByteArray_Create | |
374 (buf, len, &byteArray, plContext), | |
375 PKIX_BYTEARRAYCREATEFAILED); | |
376 | |
377 PKIX_CHECK(PKIX_PL_Cert_Create | |
378 (byteArray, &cert, plContext), | |
379 PKIX_CERTCREATEFAILED); | |
380 | |
381 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
382 ("\t\t Calling SECITEM_FreeItem.\n"); | |
383 SECITEM_FreeItem(&certDER, PR_FALSE); | |
384 | |
385 } else { | |
386 PKIX_ERROR(PKIX_UNABLETOREADDERFROMCERTFILE); | |
387 } | |
388 } | |
389 | |
390 *pCert = cert; | |
391 | |
392 cleanup: | |
393 if (inFile){ | |
394 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
395 ("\t\t Calling PR_CloseDir.\n"); | |
396 PR_Close(inFile); | |
397 } | |
398 | |
399 if (PKIX_ERROR_RECEIVED){ | |
400 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
401 ("\t\t Calling SECITEM_FreeItem).\n"); | |
402 SECITEM_FreeItem(&certDER, PR_FALSE); | |
403 | |
404 PKIX_DECREF(cert); | |
405 } | |
406 PKIX_DECREF(byteArray); | |
407 PKIX_RETURN(COLLECTIONCERTSTORECONTEXT); | |
408 } | |
409 | |
410 | |
411 /* | |
412 * FUNCTION: pkix_pl_CollectionCertStoreContext_CreateCRL | |
413 * DESCRIPTION: | |
414 * | |
415 * Creates CRL using data file path name pointed to by "crlFileName" and | |
416 * stores it at "pCrl". If the CRL can not be decoded, NULL is stored | |
417 * at "pCrl". | |
418 * | |
419 * PARAMETERS | |
420 * "crlFileName" - Address of CRL data file path name. Must be non-NULL. | |
421 * "pCrl" - Address where object pointer will be stored. Must be non-NULL. | |
422 * "plContext" - Platform-specific context pointer. | |
423 * THREAD SAFETY: | |
424 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
425 * RETURNS: | |
426 * Returns NULL if the function succeeds. | |
427 * Returns a CollectionCertStoreContext Error if the function fails in | |
428 * a non-fatal way. | |
429 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
430 */ | |
431 static PKIX_Error * | |
432 pkix_pl_CollectionCertStoreContext_CreateCRL( | |
433 const char *crlFileName, | |
434 PKIX_PL_CRL **pCrl, | |
435 void *plContext) | |
436 { | |
437 PKIX_PL_ByteArray *byteArray = NULL; | |
438 PKIX_PL_CRL *crl = NULL; | |
439 PRFileDesc *inFile = NULL; | |
440 SECItem crlDER; | |
441 void *buf = NULL; | |
442 PKIX_UInt32 len; | |
443 SECStatus rv; | |
444 | |
445 PKIX_ENTER(COLLECTIONCERTSTORECONTEXT, | |
446 "pkix_pl_CollectionCertStoreContext_CreateCRL"); | |
447 PKIX_NULLCHECK_TWO(crlFileName, pCrl); | |
448 | |
449 *pCrl = NULL; | |
450 crlDER.data = NULL; | |
451 | |
452 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_Open.\n"); | |
453 inFile = PR_Open(crlFileName, PR_RDONLY, 0); | |
454 | |
455 if (!inFile){ | |
456 PKIX_ERROR(PKIX_UNABLETOOPENCRLFILE); | |
457 } else { | |
458 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
459 ("\t\t Calling SECU_ReadDerFromFile.\n"); | |
460 rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE); | |
461 if (!rv){ | |
462 buf = (void *)crlDER.data; | |
463 len = crlDER.len; | |
464 | |
465 PKIX_CHECK(PKIX_PL_ByteArray_Create | |
466 (buf, len, &byteArray, plContext), | |
467 PKIX_BYTEARRAYCREATEFAILED); | |
468 | |
469 PKIX_CHECK(PKIX_PL_CRL_Create | |
470 (byteArray, &crl, plContext), | |
471 PKIX_CRLCREATEFAILED); | |
472 | |
473 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
474 ("\t\t Calling SECITEM_FreeItem.\n"); | |
475 SECITEM_FreeItem(&crlDER, PR_FALSE); | |
476 | |
477 } else { | |
478 PKIX_ERROR(PKIX_UNABLETOREADDERFROMCRLFILE); | |
479 } | |
480 } | |
481 | |
482 *pCrl = crl; | |
483 | |
484 cleanup: | |
485 if (inFile){ | |
486 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
487 ("\t\t Calling PR_CloseDir.\n"); | |
488 PR_Close(inFile); | |
489 } | |
490 | |
491 if (PKIX_ERROR_RECEIVED){ | |
492 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
493 ("\t\t Calling SECITEM_FreeItem).\n"); | |
494 SECITEM_FreeItem(&crlDER, PR_FALSE); | |
495 | |
496 PKIX_DECREF(crl); | |
497 if (crlDER.data != NULL) { | |
498 SECITEM_FreeItem(&crlDER, PR_FALSE); | |
499 } | |
500 } | |
501 | |
502 PKIX_DECREF(byteArray); | |
503 | |
504 PKIX_RETURN(COLLECTIONCERTSTORECONTEXT); | |
505 } | |
506 | |
507 /* | |
508 * FUNCTION: pkix_pl_CollectionCertStoreContext_PopulateCert | |
509 * DESCRIPTION: | |
510 * | |
511 * Create list of Certs from *.crt files at directory specified in dirName, | |
512 * Not recursive to sub-directory. Also assume the directory contents are | |
513 * not changed dynamically. | |
514 * | |
515 * PARAMETERS | |
516 * "colCertStoreContext" - Address of CollectionCertStoreContext | |
517 * where the dirName is specified and where the return | |
518 * Certs are stored as a list. Must be non-NULL. | |
519 * "plContext" - Platform-specific context pointer. | |
520 * | |
521 * THREAD SAFETY: | |
522 * Not Thread Safe - A lock at top level is required. | |
523 * | |
524 * RETURNS: | |
525 * Returns NULL if the function succeeds. | |
526 * Returns a CollectionCertStoreContext Error if the function fails in | |
527 * a non-fatal way. | |
528 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
529 */ | |
530 static PKIX_Error * | |
531 pkix_pl_CollectionCertStoreContext_PopulateCert( | |
532 PKIX_PL_CollectionCertStoreContext *colCertStoreContext, | |
533 void *plContext) | |
534 { | |
535 PKIX_List *certList = NULL; | |
536 PKIX_PL_Cert *certItem = NULL; | |
537 char *dirName = NULL; | |
538 char *pathName = NULL; | |
539 PKIX_UInt32 dirNameLen = 0; | |
540 PRErrorCode prError = 0; | |
541 PRDir *dir = NULL; | |
542 PRDirEntry *dirEntry = NULL; | |
543 | |
544 PKIX_ENTER(COLLECTIONCERTSTORECONTEXT, | |
545 "pkix_pl_CollectionCertStoreContext_PopulateCert"); | |
546 PKIX_NULLCHECK_ONE(colCertStoreContext); | |
547 | |
548 /* convert directory to ascii */ | |
549 | |
550 PKIX_CHECK(PKIX_PL_String_GetEncoded | |
551 (colCertStoreContext->storeDir, | |
552 PKIX_ESCASCII, | |
553 (void **)&dirName, | |
554 &dirNameLen, | |
555 plContext), | |
556 PKIX_STRINGGETENCODEDFAILED); | |
557 | |
558 /* create cert list, if no cert file, should return an empty list */ | |
559 | |
560 PKIX_CHECK(PKIX_List_Create(&certList, plContext), | |
561 PKIX_LISTCREATEFAILED); | |
562 | |
563 /* open directory and read in .crt files */ | |
564 | |
565 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_OpenDir.\n"); | |
566 dir = PR_OpenDir(dirName); | |
567 | |
568 if (!dir) { | |
569 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG_ARG | |
570 ("\t\t Directory Name:%s\n", dirName); | |
571 PKIX_ERROR(PKIX_CANNOTOPENCOLLECTIONCERTSTORECONTEXTDIRECTORY); | |
572 } | |
573 | |
574 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_ReadDir.\n"); | |
575 dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH); | |
576 | |
577 if (!dirEntry) { | |
578 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
579 ("\t\t Empty directory.\n"); | |
580 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
581 ("\t\t Calling PR_GetError.\n"); | |
582 prError = PR_GetError(); | |
583 } | |
584 | |
585 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_SetError.\n"); | |
586 PR_SetError(0, 0); | |
587 | |
588 while (dirEntry != NULL && prError == 0) { | |
589 if (PL_strrstr(dirEntry->name, ".crt") == | |
590 dirEntry->name + PL_strlen(dirEntry->name) - 4) { | |
591 | |
592 PKIX_CHECK_ONLY_FATAL | |
593 (PKIX_PL_Malloc | |
594 (dirNameLen + PL_strlen(dirEntry->name) + 2, | |
595 (void **)&pathName, | |
596 plContext), | |
597 PKIX_MALLOCFAILED); | |
598 | |
599 if ((!PKIX_ERROR_RECEIVED) && (pathName != NULL)){ | |
600 | |
601 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
602 ("\t\t Calling PL_strcpy for dirName.\n"); | |
603 PL_strcpy(pathName, dirName); | |
604 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
605 ("\t\t Calling PL_strcat for dirName.\n"); | |
606 PL_strcat(pathName, "/"); | |
607 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
608 ("\t\t Calling PL_strcat for /.\n"); | |
609 PL_strcat(pathName, dirEntry->name); | |
610 | |
611 PKIX_CHECK_ONLY_FATAL | |
612 (pkix_pl_CollectionCertStoreContext_CreateCert | |
613 (pathName, &certItem, plContext), | |
614 PKIX_COLLECTIONCERTSTORECONTEXTCREATECERTFAILED); | |
615 | |
616 if (!PKIX_ERROR_RECEIVED){ | |
617 PKIX_CHECK_ONLY_FATAL | |
618 (PKIX_List_AppendItem | |
619 (certList, | |
620 (PKIX_PL_Object *)certItem, | |
621 plContext), | |
622 PKIX_LISTAPPENDITEMFAILED); | |
623 } | |
624 } | |
625 | |
626 PKIX_DECREF(certItem); | |
627 PKIX_FREE(pathName); | |
628 } | |
629 | |
630 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
631 ("\t\t Calling PR_SetError.\n"); | |
632 PR_SetError(0, 0); | |
633 | |
634 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
635 ("\t\t Calling PR_ReadDir.\n"); | |
636 dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH); | |
637 | |
638 if (!dirEntry) { | |
639 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
640 ("\t\t Calling PR_GetError.\n"); | |
641 prError = PR_GetError(); | |
642 } | |
643 } | |
644 | |
645 if ((prError != 0) && (prError != PR_NO_MORE_FILES_ERROR)) { | |
646 PKIX_ERROR(PKIX_COLLECTIONCERTSTOREPOPULATECERTFAILED); | |
647 } | |
648 | |
649 PKIX_CHECK(PKIX_List_SetImmutable(certList, plContext), | |
650 PKIX_LISTSETIMMUTABLEFAILED); | |
651 | |
652 PKIX_INCREF(certList); | |
653 colCertStoreContext->certList = certList; | |
654 | |
655 cleanup: | |
656 if (dir) { | |
657 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
658 ("\t\t Calling PR_CloseDir.\n"); | |
659 PR_CloseDir(dir); | |
660 } | |
661 | |
662 PKIX_FREE(pathName); | |
663 PKIX_FREE(dirName); | |
664 | |
665 if (PKIX_ERROR_RECEIVED){ | |
666 PKIX_DECREF(certList); | |
667 } | |
668 | |
669 PKIX_DECREF(certItem); | |
670 PKIX_DECREF(certList); | |
671 | |
672 PKIX_RETURN(COLLECTIONCERTSTORECONTEXT); | |
673 } | |
674 | |
675 /* | |
676 * FUNCTION: pkix_pl_CollectionCertStoreContext_PopulateCRL | |
677 * DESCRIPTION: | |
678 * | |
679 * Create list of CRLs from *.crl files at directory specified in dirName, | |
680 * Not recursive to sub-dirctory. Also assume the directory contents are | |
681 * not changed dynamically. | |
682 * | |
683 * PARAMETERS | |
684 * "colCertStoreContext" - Address of CollectionCertStoreContext | |
685 * where the dirName is specified and where the return | |
686 * CRLs are stored as a list. Must be non-NULL. | |
687 * "plContext" - Platform-specific context pointer. | |
688 * | |
689 * THREAD SAFETY: | |
690 * Not Thread Safe - A lock at top level is required. | |
691 * | |
692 * RETURNS: | |
693 * Returns NULL if the function succeeds. | |
694 * Returns a CollectionCertStoreContext Error if the function fails in | |
695 * a non-fatal way. | |
696 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
697 */ | |
698 static PKIX_Error * | |
699 pkix_pl_CollectionCertStoreContext_PopulateCRL( | |
700 PKIX_PL_CollectionCertStoreContext *colCertStoreContext, | |
701 void *plContext) | |
702 { | |
703 PKIX_List *crlList = NULL; | |
704 PKIX_PL_CRL *crlItem = NULL; | |
705 char *dirName = NULL; | |
706 char *pathName = NULL; | |
707 PKIX_UInt32 dirNameLen = 0; | |
708 PRErrorCode prError = 0; | |
709 PRDir *dir = NULL; | |
710 PRDirEntry *dirEntry = NULL; | |
711 | |
712 PKIX_ENTER(COLLECTIONCERTSTORECONTEXT, | |
713 "pkix_pl_CollectionCertStoreContext_PopulateCRL"); | |
714 PKIX_NULLCHECK_ONE(colCertStoreContext); | |
715 | |
716 /* convert directory to ascii */ | |
717 | |
718 PKIX_CHECK(PKIX_PL_String_GetEncoded | |
719 (colCertStoreContext->storeDir, | |
720 PKIX_ESCASCII, | |
721 (void **)&dirName, | |
722 &dirNameLen, | |
723 plContext), | |
724 PKIX_STRINGGETENCODEDFAILED); | |
725 | |
726 /* create CRL list, if no CRL file, should return an empty list */ | |
727 | |
728 PKIX_CHECK(PKIX_List_Create(&crlList, plContext), | |
729 PKIX_LISTCREATEFAILED); | |
730 | |
731 /* open directory and read in .crl files */ | |
732 | |
733 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_OpenDir.\n"); | |
734 dir = PR_OpenDir(dirName); | |
735 | |
736 if (!dir) { | |
737 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG_ARG | |
738 ("\t\t Directory Name:%s\n", dirName); | |
739 PKIX_ERROR(PKIX_CANNOTOPENCOLLECTIONCERTSTORECONTEXTDIRECTORY); | |
740 } | |
741 | |
742 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_ReadDir.\n"); | |
743 dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH); | |
744 | |
745 if (!dirEntry) { | |
746 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
747 ("\t\t Empty directory.\n"); | |
748 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
749 ("\t\t Calling PR_GetError.\n"); | |
750 prError = PR_GetError(); | |
751 } | |
752 | |
753 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_SetError.\n"); | |
754 PR_SetError(0, 0); | |
755 | |
756 while (dirEntry != NULL && prError == 0) { | |
757 if (PL_strrstr(dirEntry->name, ".crl") == | |
758 dirEntry->name + PL_strlen(dirEntry->name) - 4) { | |
759 | |
760 PKIX_CHECK_ONLY_FATAL | |
761 (PKIX_PL_Malloc | |
762 (dirNameLen + PL_strlen(dirEntry->name) + 2, | |
763 (void **)&pathName, | |
764 plContext), | |
765 PKIX_MALLOCFAILED); | |
766 | |
767 if ((!PKIX_ERROR_RECEIVED) && (pathName != NULL)){ | |
768 | |
769 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
770 ("\t\t Calling PL_strcpy for dirName.\n"); | |
771 PL_strcpy(pathName, dirName); | |
772 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
773 ("\t\t Calling PL_strcat for dirName.\n"); | |
774 PL_strcat(pathName, "/"); | |
775 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
776 ("\t\t Calling PL_strcat for /.\n"); | |
777 PL_strcat(pathName, dirEntry->name); | |
778 | |
779 PKIX_CHECK_ONLY_FATAL | |
780 (pkix_pl_CollectionCertStoreContext_CreateCRL | |
781 (pathName, &crlItem, plContext), | |
782 PKIX_COLLECTIONCERTSTORECONTEXTCREATECRLFAILED); | |
783 | |
784 if (!PKIX_ERROR_RECEIVED){ | |
785 PKIX_CHECK_ONLY_FATAL | |
786 (PKIX_List_AppendItem | |
787 (crlList, | |
788 (PKIX_PL_Object *)crlItem, | |
789 plContext), | |
790 PKIX_LISTAPPENDITEMFAILED); | |
791 } | |
792 } | |
793 | |
794 PKIX_DECREF(crlItem); | |
795 PKIX_FREE(pathName); | |
796 } | |
797 | |
798 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
799 ("\t\t Calling PR_SetError.\n"); | |
800 PR_SetError(0, 0); | |
801 | |
802 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
803 ("\t\t Calling PR_ReadDir.\n"); | |
804 dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH); | |
805 | |
806 if (!dirEntry) { | |
807 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
808 ("\t\t Calling PR_GetError.\n"); | |
809 prError = PR_GetError(); | |
810 } | |
811 } | |
812 | |
813 if ((prError != 0) && (prError != PR_NO_MORE_FILES_ERROR)) { | |
814 PKIX_ERROR(PKIX_COLLECTIONCERTSTORECONTEXTGETSELECTCRLFAILED); | |
815 } | |
816 | |
817 PKIX_CHECK(PKIX_List_SetImmutable(crlList, plContext), | |
818 PKIX_LISTSETIMMUTABLEFAILED); | |
819 | |
820 PKIX_INCREF(crlList); | |
821 colCertStoreContext->crlList = crlList; | |
822 | |
823 cleanup: | |
824 if (dir) { | |
825 PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG | |
826 ("\t\t Calling PR_CloseDir.\n"); | |
827 PR_CloseDir(dir); | |
828 } | |
829 | |
830 PKIX_FREE(pathName); | |
831 PKIX_FREE(dirName); | |
832 | |
833 if (PKIX_ERROR_RECEIVED){ | |
834 PKIX_DECREF(crlList); | |
835 } | |
836 | |
837 PKIX_DECREF(crlItem); | |
838 PKIX_DECREF(crlList); | |
839 | |
840 PKIX_RETURN(COLLECTIONCERTSTORECONTEXT); | |
841 } | |
842 | |
843 /* | |
844 * FUNCTION: pkix_pl_CollectionCertStoreContext_GetSelectedCert | |
845 * DESCRIPTION: | |
846 * | |
847 * Finds the Certs that match the criterion of the CertSelector pointed | |
848 * to by "selector" using the List of Certs pointed to by "certList" and | |
849 * stores the matching Certs at "pSelectedCertList". | |
850 * | |
851 * Not recursive to sub-directory. | |
852 * | |
853 * PARAMETERS | |
854 * "certList" - Address of List of Certs to be searched. Must be non-NULL. | |
855 * "colCertStoreContext" - Address of CollectionCertStoreContext | |
856 * where the cached Certs are stored. | |
857 * "selector" - CertSelector for chosing Cert based on Params set | |
858 * "pSelectedCertList" - Certs that qualified by selector. | |
859 * "plContext" - Platform-specific context pointer. | |
860 * | |
861 * THREAD SAFETY: | |
862 * Not Thread Safe - A lock at top level is required. | |
863 * | |
864 * RETURNS: | |
865 * Returns NULL if the function succeeds. | |
866 * Returns a CollectionCertStoreContext Error if the function fails in | |
867 * a non-fatal way. | |
868 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
869 */ | |
870 static PKIX_Error * | |
871 pkix_pl_CollectionCertStoreContext_GetSelectedCert( | |
872 PKIX_List *certList, | |
873 PKIX_CertSelector *selector, | |
874 PKIX_List **pSelectedCertList, | |
875 void *plContext) | |
876 { | |
877 PKIX_List *selectCertList = NULL; | |
878 PKIX_PL_Cert *certItem = NULL; | |
879 PKIX_CertSelector_MatchCallback certSelectorMatch = NULL; | |
880 PKIX_UInt32 numCerts = 0; | |
881 PKIX_UInt32 i = 0; | |
882 | |
883 PKIX_ENTER(COLLECTIONCERTSTORECONTEXT, | |
884 "pkix_pl_CollectionCertStoreContext_GetSelectedCert"); | |
885 PKIX_NULLCHECK_THREE(certList, selector, pSelectedCertList); | |
886 | |
887 PKIX_CHECK(PKIX_CertSelector_GetMatchCallback | |
888 (selector, &certSelectorMatch, plContext), | |
889 PKIX_CERTSELECTORGETMATCHCALLBACKFAILED); | |
890 | |
891 PKIX_CHECK(PKIX_List_GetLength(certList, &numCerts, plContext), | |
892 PKIX_LISTGETLENGTHFAILED); | |
893 | |
894 if (certSelectorMatch) { | |
895 | |
896 PKIX_CHECK(PKIX_List_Create(&selectCertList, plContext), | |
897 PKIX_LISTCREATEFAILED); | |
898 | |
899 for (i = 0; i < numCerts; i++) { | |
900 PKIX_CHECK_ONLY_FATAL | |
901 (PKIX_List_GetItem | |
902 (certList, | |
903 i, | |
904 (PKIX_PL_Object **) &certItem, | |
905 plContext), | |
906 PKIX_LISTGETITEMFAILED); | |
907 | |
908 if (!PKIX_ERROR_RECEIVED){ | |
909 PKIX_CHECK_ONLY_FATAL | |
910 (certSelectorMatch | |
911 (selector, certItem, plContext), | |
912 PKIX_CERTSELECTORMATCHFAILED); | |
913 | |
914 if (!PKIX_ERROR_RECEIVED){ | |
915 PKIX_CHECK_ONLY_FATAL | |
916 (PKIX_List_AppendItem | |
917 (selectCertList, | |
918 (PKIX_PL_Object *)certItem, | |
919 plContext), | |
920 PKIX_LISTAPPENDITEMFAILED); | |
921 } | |
922 } | |
923 | |
924 PKIX_DECREF(certItem); | |
925 } | |
926 | |
927 } else { | |
928 | |
929 PKIX_INCREF(certList); | |
930 | |
931 selectCertList = certList; | |
932 } | |
933 | |
934 *pSelectedCertList = selectCertList; | |
935 | |
936 cleanup: | |
937 PKIX_RETURN(COLLECTIONCERTSTORECONTEXT); | |
938 } | |
939 | |
940 /* | |
941 * FUNCTION: pkix_pl_CollectionCertStoreContext_GetSelectedCRL | |
942 * DESCRIPTION: | |
943 * | |
944 * Finds the CRLs that match the criterion of the CRLSelector pointed | |
945 * to by "selector" using the List of CRLs pointed to by "crlList" and | |
946 * stores the matching CRLs at "pSelectedCrlList". | |
947 * | |
948 * Not recursive to sub-directory. | |
949 * | |
950 * PARAMETERS | |
951 * "crlList" - Address of List of CRLs to be searched. Must be non-NULL | |
952 * "selector" - CRLSelector for chosing CRL based on Params set | |
953 * "pSelectedCrlList" - CRLs that qualified by selector. | |
954 * "plContext" - Platform-specific context pointer. | |
955 * | |
956 * THREAD SAFETY: | |
957 * Not Thread Safe - A lock at top level is required. | |
958 * | |
959 * RETURNS: | |
960 * Returns NULL if the function succeeds. | |
961 * Returns a CollectionCertStoreContext Error if the function fails in | |
962 * a non-fatal way. | |
963 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
964 */ | |
965 static PKIX_Error * | |
966 pkix_pl_CollectionCertStoreContext_GetSelectedCRL( | |
967 PKIX_List *crlList, | |
968 PKIX_CRLSelector *selector, | |
969 PKIX_List **pSelectedCrlList, | |
970 void *plContext) | |
971 { | |
972 PKIX_List *selectCrlList = NULL; | |
973 PKIX_PL_CRL *crlItem = NULL; | |
974 PKIX_CRLSelector_MatchCallback crlSelectorMatch = NULL; | |
975 PKIX_UInt32 numCrls = 0; | |
976 PKIX_UInt32 i = 0; | |
977 PKIX_Boolean match = PKIX_FALSE; | |
978 | |
979 PKIX_ENTER(COLLECTIONCERTSTORECONTEXT, | |
980 "pkix_pl_CollectionCertStoreContext_GetSelectedCRL"); | |
981 PKIX_NULLCHECK_THREE(crlList, selector, pSelectedCrlList); | |
982 | |
983 PKIX_CHECK(PKIX_CRLSelector_GetMatchCallback | |
984 (selector, &crlSelectorMatch, plContext), | |
985 PKIX_CRLSELECTORGETMATCHCALLBACKFAILED); | |
986 | |
987 PKIX_CHECK(PKIX_List_GetLength(crlList, &numCrls, plContext), | |
988 PKIX_LISTGETLENGTHFAILED); | |
989 | |
990 if (crlSelectorMatch) { | |
991 | |
992 PKIX_CHECK(PKIX_List_Create(&selectCrlList, plContext), | |
993 PKIX_LISTCREATEFAILED); | |
994 | |
995 for (i = 0; i < numCrls; i++) { | |
996 PKIX_CHECK_ONLY_FATAL(PKIX_List_GetItem | |
997 (crlList, | |
998 i, | |
999 (PKIX_PL_Object **) &crlItem, | |
1000 plContext), | |
1001 PKIX_LISTGETITEMFAILED); | |
1002 | |
1003 if (!PKIX_ERROR_RECEIVED){ | |
1004 PKIX_CHECK_ONLY_FATAL | |
1005 (crlSelectorMatch | |
1006 (selector, crlItem, &match, plContext), | |
1007 PKIX_CRLSELECTORMATCHFAILED); | |
1008 | |
1009 if (!(PKIX_ERROR_RECEIVED) && match) { | |
1010 PKIX_CHECK_ONLY_FATAL | |
1011 (PKIX_List_AppendItem | |
1012 (selectCrlList, | |
1013 (PKIX_PL_Object *)crlItem, | |
1014 plContext), | |
1015 PKIX_LISTAPPENDITEMFAILED); | |
1016 } | |
1017 } | |
1018 | |
1019 PKIX_DECREF(crlItem); | |
1020 } | |
1021 } else { | |
1022 | |
1023 PKIX_INCREF(crlList); | |
1024 | |
1025 selectCrlList = crlList; | |
1026 } | |
1027 | |
1028 /* Don't throw away the list if one CRL was bad! */ | |
1029 pkixTempErrorReceived = PKIX_FALSE; | |
1030 | |
1031 *pSelectedCrlList = selectCrlList; | |
1032 | |
1033 cleanup: | |
1034 PKIX_RETURN(COLLECTIONCERTSTORECONTEXT); | |
1035 } | |
1036 | |
1037 /* | |
1038 * FUNCTION: pkix_pl_CollectionCertStore_GetCert | |
1039 * DESCRIPTION: | |
1040 * | |
1041 * Retrieve Certs in a list of PKIX_PL_Cert object. | |
1042 * | |
1043 * PARAMETERS: | |
1044 * "colCertStoreContext" | |
1045 * The object CertStore is the object passed in by checker call. | |
1046 * "crlSelector" | |
1047 * CRLSelector specifies criteria for chosing CRL's | |
1048 * "pNBIOContext" | |
1049 * Address where platform-dependent information is returned for CertStores | |
1050 * that use non-blocking I/O. Must be non-NULL. | |
1051 * "pCertList" | |
1052 * Address where object pointer will be returned. Must be non-NULL. | |
1053 * "plContext" | |
1054 * Platform-specific context pointer. | |
1055 * THREAD SAFETY: | |
1056 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
1057 * RETURNS: | |
1058 * Returns NULL if the function succeeds. | |
1059 * Returns a CertStore Error if the function fails in | |
1060 * a non-fatal way. | |
1061 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
1062 */ | |
1063 PKIX_Error * | |
1064 pkix_pl_CollectionCertStore_GetCert( | |
1065 PKIX_CertStore *certStore, | |
1066 PKIX_CertSelector *selector, | |
1067 PKIX_VerifyNode *verifyNode, | |
1068 void **pNBIOContext, | |
1069 PKIX_List **pCerts, | |
1070 void *plContext) | |
1071 { | |
1072 PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL; | |
1073 PKIX_List *selectedCerts = NULL; | |
1074 | |
1075 PKIX_ENTER(CERTSTORE, "pkix_pl_CollectionCertStore_GetCert"); | |
1076 PKIX_NULLCHECK_FOUR(certStore, selector, pNBIOContext, pCerts); | |
1077 | |
1078 *pNBIOContext = NULL; /* We don't use non-blocking I/O */ | |
1079 | |
1080 PKIX_CHECK(PKIX_CertStore_GetCertStoreContext | |
1081 (certStore, | |
1082 (PKIX_PL_Object **) &colCertStoreContext, | |
1083 plContext), | |
1084 PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED); | |
1085 | |
1086 if (colCertStoreContext->certList == NULL) { | |
1087 | |
1088 PKIX_OBJECT_LOCK(colCertStoreContext); | |
1089 | |
1090 /* | |
1091 * Certs in the directory are cached based on the | |
1092 * assumption that the directory contents won't be | |
1093 * changed dynamically. | |
1094 */ | |
1095 if (colCertStoreContext->certList == NULL){ | |
1096 PKIX_CHECK(pkix_pl_CollectionCertStoreContext_PopulateCert | |
1097 (colCertStoreContext, plContext), | |
1098 PKIX_COLLECTIONCERTSTORECONTEXTPOPULATECERTFAILED); | |
1099 } | |
1100 | |
1101 PKIX_OBJECT_UNLOCK(colCertStoreContext); | |
1102 } | |
1103 | |
1104 PKIX_CHECK(pkix_pl_CollectionCertStoreContext_GetSelectedCert | |
1105 (colCertStoreContext->certList, | |
1106 selector, | |
1107 &selectedCerts, | |
1108 plContext), | |
1109 PKIX_COLLECTIONCERTSTORECONTEXTGETSELECTCERTFAILED); | |
1110 | |
1111 *pCerts = selectedCerts; | |
1112 | |
1113 cleanup: | |
1114 PKIX_OBJECT_UNLOCK(lockedObject); | |
1115 PKIX_DECREF(colCertStoreContext); | |
1116 PKIX_RETURN(CERTSTORE); | |
1117 } | |
1118 | |
1119 /* | |
1120 * FUNCTION: pkix_pl_CollectionCertStore_GetCRL | |
1121 * DESCRIPTION: | |
1122 * | |
1123 * Retrieve CRL's in a list of PKIX_PL_CRL object. | |
1124 * | |
1125 * PARAMETERS: | |
1126 * "colCertStoreContext" | |
1127 * The object CertStore is passed in by checker call. | |
1128 * "crlSelector" | |
1129 * CRLSelector specifies criteria for chosing CRL's | |
1130 * "pNBIOContext" | |
1131 * Address where platform-dependent information is returned for CertStores | |
1132 * that use non-blocking I/O. Must be non-NULL. | |
1133 * "pCrlList" | |
1134 * Address where object pointer will be returned. Must be non-NULL. | |
1135 * "plContext" | |
1136 * Platform-specific context pointer. | |
1137 * THREAD SAFETY: | |
1138 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
1139 * RETURNS: | |
1140 * Returns NULL if the function succeeds. | |
1141 * Returns a CertStore Error if the function fails in | |
1142 * a non-fatal way. | |
1143 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
1144 */ | |
1145 PKIX_Error * | |
1146 pkix_pl_CollectionCertStore_GetCRL( | |
1147 PKIX_CertStore *certStore, | |
1148 PKIX_CRLSelector *selector, | |
1149 void **pNBIOContext, | |
1150 PKIX_List **pCrlList, | |
1151 void *plContext) | |
1152 { | |
1153 PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL; | |
1154 PKIX_List *selectCrl = NULL; | |
1155 | |
1156 PKIX_ENTER(CERTSTORE, "pkix_pl_CollectionCertStore_GetCRL"); | |
1157 PKIX_NULLCHECK_FOUR(certStore, selector, pNBIOContext, pCrlList); | |
1158 | |
1159 *pNBIOContext = NULL; /* We don't use non-blocking I/O */ | |
1160 | |
1161 PKIX_CHECK(PKIX_CertStore_GetCertStoreContext | |
1162 (certStore, | |
1163 (PKIX_PL_Object **) &colCertStoreContext, | |
1164 plContext), | |
1165 PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED); | |
1166 | |
1167 if (colCertStoreContext->crlList == NULL) { | |
1168 | |
1169 PKIX_OBJECT_LOCK(colCertStoreContext); | |
1170 | |
1171 /* | |
1172 * CRLs in the directory are cached based on the | |
1173 * assumption that the directory contents won't be | |
1174 * changed dynamically. | |
1175 */ | |
1176 if (colCertStoreContext->crlList == NULL){ | |
1177 PKIX_CHECK(pkix_pl_CollectionCertStoreContext_PopulateCRL | |
1178 (colCertStoreContext, plContext), | |
1179 PKIX_COLLECTIONCERTSTORECONTEXTPOPULATECRLFAILED); | |
1180 } | |
1181 | |
1182 PKIX_OBJECT_UNLOCK(colCertStoreContext); | |
1183 | |
1184 } | |
1185 | |
1186 PKIX_CHECK(pkix_pl_CollectionCertStoreContext_GetSelectedCRL | |
1187 (colCertStoreContext->crlList, | |
1188 selector, | |
1189 &selectCrl, | |
1190 plContext), | |
1191 PKIX_COLLECTIONCERTSTORECONTEXTGETSELECTCRLFAILED); | |
1192 | |
1193 *pCrlList = selectCrl; | |
1194 | |
1195 cleanup: | |
1196 PKIX_OBJECT_UNLOCK(lockedObject); | |
1197 PKIX_DECREF(colCertStoreContext); | |
1198 PKIX_RETURN(CERTSTORE); | |
1199 } | |
1200 | |
1201 /* | |
1202 * FUNCTION: pkix_pl_CollectionCertStoreContext_RegisterSelf | |
1203 * DESCRIPTION: | |
1204 * | |
1205 * Registers PKIX_PL_COLLECTIONCERTSTORECONTEXT_TYPE and its related | |
1206 * functions with systemClasses[] | |
1207 * | |
1208 * THREAD SAFETY: | |
1209 * Not Thread Safe - for performance and complexity reasons | |
1210 * | |
1211 * Since this function is only called by PKIX_PL_Initialize, which should | |
1212 * only be called once, it is acceptable that this function is not | |
1213 * thread-safe. | |
1214 */ | |
1215 PKIX_Error * | |
1216 pkix_pl_CollectionCertStoreContext_RegisterSelf(void *plContext) | |
1217 { | |
1218 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |
1219 pkix_ClassTable_Entry entry; | |
1220 | |
1221 PKIX_ENTER(COLLECTIONCERTSTORECONTEXT, | |
1222 "pkix_pl_CollectionCertStoreContext_RegisterSelf"); | |
1223 | |
1224 entry.description = "CollectionCertStoreContext"; | |
1225 entry.objCounter = 0; | |
1226 entry.typeObjectSize = sizeof(PKIX_PL_CollectionCertStoreContext); | |
1227 entry.destructor = pkix_pl_CollectionCertStoreContext_Destroy; | |
1228 entry.equalsFunction = pkix_pl_CollectionCertStoreContext_Equals; | |
1229 entry.hashcodeFunction = pkix_pl_CollectionCertStoreContext_Hashcode; | |
1230 entry.toStringFunction = NULL; | |
1231 entry.comparator = NULL; | |
1232 entry.duplicateFunction = NULL; | |
1233 | |
1234 systemClasses[PKIX_COLLECTIONCERTSTORECONTEXT_TYPE] = entry; | |
1235 | |
1236 PKIX_RETURN(COLLECTIONCERTSTORECONTEXT); | |
1237 } | |
1238 | |
1239 /* --Public-CollectionCertStoreContext-Functions--------------------------- */ | |
1240 | |
1241 /* | |
1242 * FUNCTION: PKIX_PL_CollectionCertStore_Create | |
1243 * (see comments in pkix_samples_modules.h) | |
1244 */ | |
1245 PKIX_Error * | |
1246 PKIX_PL_CollectionCertStore_Create( | |
1247 PKIX_PL_String *storeDir, | |
1248 PKIX_CertStore **pCertStore, | |
1249 void *plContext) | |
1250 { | |
1251 PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL; | |
1252 PKIX_CertStore *certStore = NULL; | |
1253 | |
1254 PKIX_ENTER(CERTSTORE, "PKIX_PL_CollectionCertStore_Create"); | |
1255 PKIX_NULLCHECK_TWO(storeDir, pCertStore); | |
1256 | |
1257 PKIX_CHECK(pkix_pl_CollectionCertStoreContext_Create | |
1258 (storeDir, &colCertStoreContext, plContext), | |
1259 PKIX_COULDNOTCREATECOLLECTIONCERTSTORECONTEXTOBJECT); | |
1260 | |
1261 PKIX_CHECK(PKIX_CertStore_Create | |
1262 (pkix_pl_CollectionCertStore_GetCert, | |
1263 pkix_pl_CollectionCertStore_GetCRL, | |
1264 NULL, /* GetCertContinue */ | |
1265 NULL, /* GetCRLContinue */ | |
1266 pkix_pl_CollectionCertStore_CheckTrust, | |
1267 NULL, /* can not store crls */ | |
1268 NULL, /* can not do revocation check */ | |
1269 (PKIX_PL_Object *)colCertStoreContext, | |
1270 PKIX_TRUE, /* cache flag */ | |
1271 PKIX_TRUE, /* local - no network I/O */ | |
1272 &certStore, | |
1273 plContext), | |
1274 PKIX_CERTSTORECREATEFAILED); | |
1275 | |
1276 PKIX_DECREF(colCertStoreContext); | |
1277 | |
1278 *pCertStore = certStore; | |
1279 | |
1280 cleanup: | |
1281 PKIX_RETURN(CERTSTORE); | |
1282 } | |
OLD | NEW |