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_crlentry.c | |
6 * | |
7 * CRLENTRY Function Definitions | |
8 * | |
9 */ | |
10 | |
11 #include "pkix_pl_crlentry.h" | |
12 | |
13 /* --Private-CRLEntry-Functions------------------------------------- */ | |
14 | |
15 /* | |
16 * FUNCTION: pkix_pl_CRLEntry_Destroy | |
17 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |
18 */ | |
19 static PKIX_Error * | |
20 pkix_pl_CRLEntry_Destroy( | |
21 PKIX_PL_Object *object, | |
22 void *plContext) | |
23 { | |
24 PKIX_PL_CRLEntry *crlEntry = NULL; | |
25 | |
26 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Destroy"); | |
27 PKIX_NULLCHECK_ONE(object); | |
28 | |
29 PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext), | |
30 PKIX_OBJECTNOTCRLENTRY); | |
31 | |
32 crlEntry = (PKIX_PL_CRLEntry*)object; | |
33 | |
34 /* crlEntry->nssCrlEntry is freed by NSS when freeing CRL */ | |
35 crlEntry->userReasonCode = 0; | |
36 crlEntry->userReasonCodeAbsent = PKIX_FALSE; | |
37 crlEntry->nssCrlEntry = NULL; | |
38 PKIX_DECREF(crlEntry->serialNumber); | |
39 PKIX_DECREF(crlEntry->critExtOids); | |
40 | |
41 cleanup: | |
42 | |
43 PKIX_RETURN(CRLENTRY); | |
44 } | |
45 | |
46 /* | |
47 * FUNCTION: pkix_pl_CRLEntry_ToString_Helper | |
48 * | |
49 * DESCRIPTION: | |
50 * Helper function that creates a string representation of the CRLEntry | |
51 * pointed to by "crlEntry" and stores it at "pString". | |
52 * | |
53 * PARAMETERS | |
54 * "crlEntry" | |
55 * Address of CRLEntry whose string representation is desired. | |
56 * Must be non-NULL. | |
57 * "pString" | |
58 * Address where object pointer will be stored. Must be non-NULL. | |
59 * "plContext" | |
60 * Platform-specific context pointer. | |
61 * THREAD SAFETY: | |
62 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
63 * RETURNS: | |
64 * Returns NULL if the function succeeds. | |
65 * Returns a CRLEntry Error if the function fails in a non-fatal way. | |
66 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
67 */ | |
68 PKIX_Error * | |
69 pkix_pl_CRLEntry_ToString_Helper( | |
70 PKIX_PL_CRLEntry *crlEntry, | |
71 PKIX_PL_String **pString, | |
72 void *plContext) | |
73 { | |
74 char *asciiFormat = NULL; | |
75 PKIX_List *critExtOIDs = NULL; | |
76 PKIX_PL_String *crlEntryString = NULL; | |
77 PKIX_PL_String *formatString = NULL; | |
78 PKIX_PL_String *crlSerialNumberString = NULL; | |
79 PKIX_PL_String *crlRevocationDateString = NULL; | |
80 PKIX_PL_String *critExtOIDsString = NULL; | |
81 PKIX_Int32 reasonCode = 0; | |
82 | |
83 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_ToString_Helper"); | |
84 PKIX_NULLCHECK_FOUR | |
85 (crlEntry, | |
86 crlEntry->serialNumber, | |
87 crlEntry->nssCrlEntry, | |
88 pString); | |
89 | |
90 asciiFormat = | |
91 "\n\t[\n" | |
92 "\tSerialNumber: %s\n" | |
93 "\tReasonCode: %d\n" | |
94 "\tRevocationDate: %s\n" | |
95 "\tCritExtOIDs: %s\n" | |
96 "\t]\n\t"; | |
97 | |
98 PKIX_CHECK(PKIX_PL_String_Create | |
99 (PKIX_ESCASCII, | |
100 asciiFormat, | |
101 0, | |
102 &formatString, | |
103 plContext), | |
104 PKIX_STRINGCREATEFAILED); | |
105 | |
106 /* SerialNumber */ | |
107 PKIX_CHECK(PKIX_PL_Object_ToString | |
108 ((PKIX_PL_Object *)crlEntry->serialNumber, | |
109 &crlSerialNumberString, | |
110 plContext), | |
111 PKIX_BIGINTTOSTRINGHELPERFAILED); | |
112 | |
113 /* RevocationDate - No Date object created, use nss data directly */ | |
114 PKIX_CHECK(pkix_pl_Date_ToString_Helper | |
115 (&(crlEntry->nssCrlEntry->revocationDate), | |
116 &crlRevocationDateString, | |
117 plContext), | |
118 PKIX_DATETOSTRINGHELPERFAILED); | |
119 | |
120 /* CriticalExtensionOIDs */ | |
121 PKIX_CHECK(PKIX_PL_CRLEntry_GetCriticalExtensionOIDs | |
122 (crlEntry, &critExtOIDs, plContext), | |
123 PKIX_CRLENTRYGETCRITICALEXTENSIONOIDSFAILED); | |
124 | |
125 PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext, | |
126 PKIX_LISTTOSTRINGFAILED); | |
127 | |
128 /* Revocation Reason Code */ | |
129 PKIX_CHECK(PKIX_PL_CRLEntry_GetCRLEntryReasonCode | |
130 (crlEntry, &reasonCode, plContext), | |
131 PKIX_CRLENTRYGETCRLENTRYREASONCODEFAILED); | |
132 | |
133 PKIX_CHECK(PKIX_PL_Sprintf | |
134 (&crlEntryString, | |
135 plContext, | |
136 formatString, | |
137 crlSerialNumberString, | |
138 reasonCode, | |
139 crlRevocationDateString, | |
140 critExtOIDsString), | |
141 PKIX_SPRINTFFAILED); | |
142 | |
143 *pString = crlEntryString; | |
144 | |
145 cleanup: | |
146 | |
147 PKIX_DECREF(critExtOIDs); | |
148 PKIX_DECREF(crlSerialNumberString); | |
149 PKIX_DECREF(crlRevocationDateString); | |
150 PKIX_DECREF(critExtOIDsString); | |
151 PKIX_DECREF(formatString); | |
152 | |
153 PKIX_RETURN(CRLENTRY); | |
154 } | |
155 | |
156 /* | |
157 * FUNCTION: pkix_pl_CRLEntry_ToString | |
158 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) | |
159 */ | |
160 static PKIX_Error * | |
161 pkix_pl_CRLEntry_ToString( | |
162 PKIX_PL_Object *object, | |
163 PKIX_PL_String **pString, | |
164 void *plContext) | |
165 { | |
166 PKIX_PL_String *crlEntryString = NULL; | |
167 PKIX_PL_CRLEntry *crlEntry = NULL; | |
168 | |
169 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_ToString"); | |
170 PKIX_NULLCHECK_TWO(object, pString); | |
171 | |
172 PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext), | |
173 PKIX_OBJECTNOTCRLENTRY); | |
174 | |
175 crlEntry = (PKIX_PL_CRLEntry *) object; | |
176 | |
177 PKIX_CHECK(pkix_pl_CRLEntry_ToString_Helper | |
178 (crlEntry, &crlEntryString, plContext), | |
179 PKIX_CRLENTRYTOSTRINGHELPERFAILED); | |
180 | |
181 *pString = crlEntryString; | |
182 | |
183 cleanup: | |
184 | |
185 PKIX_RETURN(CRLENTRY); | |
186 } | |
187 | |
188 /* | |
189 * FUNCTION: pkix_pl_CRLEntry_Extensions_Hashcode | |
190 * DESCRIPTION: | |
191 * | |
192 * For each CRL Entry extension stored at NSS structure CERTCertExtension, | |
193 * get its derbyte data and do the hash. | |
194 * | |
195 * PARAMETERS | |
196 * "extensions" | |
197 * Address of arrray of CERTCertExtension whose hash value is desired. | |
198 * Must be non-NULL. | |
199 * "pHashValue" | |
200 * Address where the final hash value is returned. Must be non-NULL. | |
201 * "plContext" | |
202 * Platform-specific context pointer. | |
203 * THREAD SAFETY: | |
204 * Conditional Thread Safe | |
205 * Though the value of extensions once created is not supposed to change, | |
206 * it may be de-allocated while we are accessing it. But since we are | |
207 * validating the object, it is unlikely we or someone is de-allocating | |
208 * at the moment. | |
209 * RETURNS: | |
210 * Returns NULL if the function succeeds. | |
211 * Returns an OID Error if the function fails in a non-fatal way. | |
212 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
213 */ | |
214 static PKIX_Error * | |
215 pkix_pl_CRLEntry_Extensions_Hashcode( | |
216 CERTCertExtension **extensions, | |
217 PKIX_UInt32 *pHashValue, | |
218 void *plContext) | |
219 { | |
220 CERTCertExtension *extension = NULL; | |
221 PLArenaPool *arena = NULL; | |
222 PKIX_UInt32 extHash = 0; | |
223 PKIX_UInt32 hashValue = 0; | |
224 SECItem *derBytes = NULL; | |
225 SECItem *resultSecItem = NULL; | |
226 | |
227 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Extensions_Hashcode"); | |
228 PKIX_NULLCHECK_TWO(extensions, pHashValue); | |
229 | |
230 if (extensions) { | |
231 | |
232 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_NewArena\n"); | |
233 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
234 if (arena == NULL) { | |
235 PKIX_ERROR(PKIX_OUTOFMEMORY); | |
236 } | |
237 | |
238 while (*extensions) { | |
239 | |
240 extension = *extensions++; | |
241 | |
242 PKIX_NULLCHECK_ONE(extension); | |
243 | |
244 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n"); | |
245 derBytes = PORT_ArenaZNew(arena, SECItem); | |
246 if (derBytes == NULL) { | |
247 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED); | |
248 } | |
249 | |
250 PKIX_CRLENTRY_DEBUG | |
251 ("\t\tCalling SEC_ASN1EncodeItem\n"); | |
252 resultSecItem = SEC_ASN1EncodeItem | |
253 (arena, | |
254 derBytes, | |
255 extension, | |
256 CERT_CertExtensionTemplate); | |
257 | |
258 if (resultSecItem == NULL){ | |
259 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED); | |
260 } | |
261 | |
262 PKIX_CHECK(pkix_hash | |
263 (derBytes->data, | |
264 derBytes->len, | |
265 &extHash, | |
266 plContext), | |
267 PKIX_HASHFAILED); | |
268 | |
269 hashValue += (extHash << 7); | |
270 | |
271 } | |
272 } | |
273 | |
274 *pHashValue = hashValue; | |
275 | |
276 cleanup: | |
277 | |
278 if (arena){ | |
279 /* Note that freeing the arena also frees derBytes */ | |
280 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_FreeArena\n"); | |
281 PORT_FreeArena(arena, PR_FALSE); | |
282 arena = NULL; | |
283 } | |
284 PKIX_RETURN(CRLENTRY); | |
285 } | |
286 | |
287 /* | |
288 * FUNCTION: pkix_pl_CRLEntry_Hashcode | |
289 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) | |
290 */ | |
291 static PKIX_Error * | |
292 pkix_pl_CRLEntry_Hashcode( | |
293 PKIX_PL_Object *object, | |
294 PKIX_UInt32 *pHashcode, | |
295 void *plContext) | |
296 { | |
297 SECItem *nssDate = NULL; | |
298 PKIX_PL_CRLEntry *crlEntry = NULL; | |
299 PKIX_UInt32 crlEntryHash; | |
300 PKIX_UInt32 hashValue; | |
301 PKIX_Int32 reasonCode = 0; | |
302 | |
303 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Hashcode"); | |
304 PKIX_NULLCHECK_TWO(object, pHashcode); | |
305 | |
306 PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext), | |
307 PKIX_OBJECTNOTCRLENTRY); | |
308 | |
309 crlEntry = (PKIX_PL_CRLEntry *)object; | |
310 | |
311 PKIX_NULLCHECK_ONE(crlEntry->nssCrlEntry); | |
312 nssDate = &(crlEntry->nssCrlEntry->revocationDate); | |
313 | |
314 PKIX_NULLCHECK_ONE(nssDate->data); | |
315 | |
316 PKIX_CHECK(pkix_hash | |
317 ((const unsigned char *)nssDate->data, | |
318 nssDate->len, | |
319 &crlEntryHash, | |
320 plContext), | |
321 PKIX_ERRORGETTINGHASHCODE); | |
322 | |
323 PKIX_CHECK(PKIX_PL_Object_Hashcode | |
324 ((PKIX_PL_Object *)crlEntry->serialNumber, | |
325 &hashValue, | |
326 plContext), | |
327 PKIX_OBJECTHASHCODEFAILED); | |
328 | |
329 crlEntryHash += (hashValue << 7); | |
330 | |
331 hashValue = 0; | |
332 | |
333 if (crlEntry->nssCrlEntry->extensions) { | |
334 | |
335 PKIX_CHECK(pkix_pl_CRLEntry_Extensions_Hashcode | |
336 (crlEntry->nssCrlEntry->extensions, &hashValue, plContext), | |
337 PKIX_CRLENTRYEXTENSIONSHASHCODEFAILED); | |
338 } | |
339 | |
340 crlEntryHash += (hashValue << 7); | |
341 | |
342 PKIX_CHECK(PKIX_PL_CRLEntry_GetCRLEntryReasonCode | |
343 (crlEntry, &reasonCode, plContext), | |
344 PKIX_CRLENTRYGETCRLENTRYREASONCODEFAILED); | |
345 | |
346 crlEntryHash += (reasonCode + 777) << 3; | |
347 | |
348 *pHashcode = crlEntryHash; | |
349 | |
350 cleanup: | |
351 | |
352 PKIX_RETURN(CRLENTRY); | |
353 } | |
354 | |
355 /* | |
356 * FUNCTION: pkix_pl_CRLENTRY_Extensions_Equals | |
357 * DESCRIPTION: | |
358 * | |
359 * Compare each extension's DERbyte data in "firstExtensions" with extension | |
360 * in "secondExtensions" in sequential order and store the result in | |
361 * "pResult". | |
362 * | |
363 * PARAMETERS | |
364 * "firstExtensions" | |
365 * Address of first NSS structure CERTCertExtension to be compared. | |
366 * Must be non-NULL. | |
367 * "secondExtensions" | |
368 * Address of second NSS structure CERTCertExtension to be compared. | |
369 * Must be non-NULL. | |
370 * "pResult" | |
371 * Address where the comparison result is returned. Must be non-NULL. | |
372 * "plContext" | |
373 * Platform-specific context pointer. | |
374 * THREAD SAFETY: | |
375 * Conditionally Thread Safe | |
376 * Though the value of extensions once created is not supposed to change, | |
377 * it may be de-allocated while we are accessing it. But since we are | |
378 * validating the object, it is unlikely we or someone is de-allocating | |
379 * at the moment. | |
380 * RETURNS: | |
381 * Returns NULL if the function succeeds. | |
382 * Returns an OID Error if the function fails in a non-fatal way. | |
383 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
384 */ | |
385 static PKIX_Error * | |
386 pkix_pl_CRLEntry_Extensions_Equals( | |
387 CERTCertExtension **extensions1, | |
388 CERTCertExtension **extensions2, | |
389 PKIX_Boolean *pResult, | |
390 void *plContext) | |
391 { | |
392 CERTCertExtension **firstExtensions; | |
393 CERTCertExtension **secondExtensions; | |
394 CERTCertExtension *firstExtension = NULL; | |
395 CERTCertExtension *secondExtension = NULL; | |
396 PLArenaPool *arena = NULL; | |
397 PKIX_Boolean cmpResult = PKIX_FALSE; | |
398 SECItem *firstDerBytes = NULL; | |
399 SECItem *secondDerBytes = NULL; | |
400 SECItem *firstResultSecItem = NULL; | |
401 SECItem *secondResultSecItem = NULL; | |
402 PKIX_UInt32 firstNumExt = 0; | |
403 PKIX_UInt32 secondNumExt = 0; | |
404 SECComparison secResult; | |
405 | |
406 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Extensions_Equals"); | |
407 PKIX_NULLCHECK_THREE(extensions1, extensions2, pResult); | |
408 | |
409 firstExtensions = extensions1; | |
410 secondExtensions = extensions2; | |
411 | |
412 if (firstExtensions) { | |
413 while (*firstExtensions) { | |
414 firstExtension = *firstExtensions++; | |
415 firstNumExt++; | |
416 } | |
417 } | |
418 | |
419 if (secondExtensions) { | |
420 while (*secondExtensions) { | |
421 secondExtension = *secondExtensions++; | |
422 secondNumExt++; | |
423 } | |
424 } | |
425 | |
426 if (firstNumExt != secondNumExt) { | |
427 *pResult = PKIX_FALSE; | |
428 goto cleanup; | |
429 } | |
430 | |
431 if (firstNumExt == 0 && secondNumExt == 0) { | |
432 *pResult = PKIX_TRUE; | |
433 goto cleanup; | |
434 } | |
435 | |
436 /* now have equal number, but non-zero extension items to compare */ | |
437 | |
438 firstExtensions = extensions1; | |
439 secondExtensions = extensions2; | |
440 | |
441 cmpResult = PKIX_TRUE; | |
442 | |
443 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_NewArena\n"); | |
444 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE*2); | |
445 if (arena == NULL) { | |
446 PKIX_ERROR(PKIX_OUTOFMEMORY); | |
447 } | |
448 | |
449 while (firstNumExt--) { | |
450 | |
451 firstExtension = *firstExtensions++; | |
452 secondExtension = *secondExtensions++; | |
453 | |
454 PKIX_NULLCHECK_TWO(firstExtension, secondExtension); | |
455 | |
456 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n"); | |
457 firstDerBytes = PORT_ArenaZNew(arena, SECItem); | |
458 if (firstDerBytes == NULL) { | |
459 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED); | |
460 } | |
461 | |
462 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n"); | |
463 secondDerBytes = PORT_ArenaZNew(arena, SECItem); | |
464 if (secondDerBytes == NULL) { | |
465 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED); | |
466 } | |
467 | |
468 PKIX_CRLENTRY_DEBUG | |
469 ("\t\tCalling SEC_ASN1EncodeItem\n"); | |
470 firstResultSecItem = SEC_ASN1EncodeItem | |
471 (arena, | |
472 firstDerBytes, | |
473 firstExtension, | |
474 CERT_CertExtensionTemplate); | |
475 | |
476 if (firstResultSecItem == NULL){ | |
477 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED); | |
478 } | |
479 | |
480 PKIX_CRLENTRY_DEBUG | |
481 ("\t\tCalling SEC_ASN1EncodeItem\n"); | |
482 secondResultSecItem = SEC_ASN1EncodeItem | |
483 (arena, | |
484 secondDerBytes, | |
485 secondExtension, | |
486 CERT_CertExtensionTemplate); | |
487 | |
488 if (secondResultSecItem == NULL){ | |
489 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED); | |
490 } | |
491 | |
492 PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n"); | |
493 secResult = SECITEM_CompareItem | |
494 (firstResultSecItem, secondResultSecItem); | |
495 | |
496 if (secResult != SECEqual) { | |
497 cmpResult = PKIX_FALSE; | |
498 break; | |
499 } | |
500 | |
501 } | |
502 | |
503 *pResult = cmpResult; | |
504 | |
505 cleanup: | |
506 | |
507 if (arena){ | |
508 /* Note that freeing the arena also frees derBytes */ | |
509 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_FreeArena\n"); | |
510 PORT_FreeArena(arena, PR_FALSE); | |
511 arena = NULL; | |
512 } | |
513 | |
514 PKIX_RETURN(CRLENTRY); | |
515 } | |
516 | |
517 /* | |
518 * FUNCTION: pkix_pl_CRLEntry_Equals | |
519 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) | |
520 */ | |
521 static PKIX_Error * | |
522 pkix_pl_CRLEntry_Equals( | |
523 PKIX_PL_Object *firstObject, | |
524 PKIX_PL_Object *secondObject, | |
525 PKIX_Boolean *pResult, | |
526 void *plContext) | |
527 { | |
528 PKIX_PL_CRLEntry *firstCrlEntry = NULL; | |
529 PKIX_PL_CRLEntry *secondCrlEntry = NULL; | |
530 PKIX_UInt32 secondType; | |
531 PKIX_Boolean cmpResult = PKIX_FALSE; | |
532 | |
533 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Equals"); | |
534 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); | |
535 | |
536 /* test that firstObject is a CRLEntry */ | |
537 PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CRLENTRY_TYPE, plContext), | |
538 PKIX_FIRSTOBJECTNOTCRLENTRY); | |
539 | |
540 firstCrlEntry = (PKIX_PL_CRLEntry *)firstObject; | |
541 secondCrlEntry = (PKIX_PL_CRLEntry *)secondObject; | |
542 | |
543 PKIX_NULLCHECK_TWO | |
544 (firstCrlEntry->nssCrlEntry, secondCrlEntry->nssCrlEntry); | |
545 | |
546 /* | |
547 * Since we know firstObject is a CRLEntry, if both references are | |
548 * identical, they must be equal | |
549 */ | |
550 if (firstCrlEntry == secondCrlEntry){ | |
551 *pResult = PKIX_TRUE; | |
552 goto cleanup; | |
553 } | |
554 | |
555 /* | |
556 * If secondCrlEntry isn't a CRL Entry, we don't throw an error. | |
557 * We simply return a Boolean result of FALSE | |
558 */ | |
559 *pResult = PKIX_FALSE; | |
560 PKIX_CHECK(PKIX_PL_Object_GetType | |
561 ((PKIX_PL_Object *)secondCrlEntry, &secondType, plContext), | |
562 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); | |
563 if (secondType != PKIX_CRLENTRY_TYPE) goto cleanup; | |
564 | |
565 /* Compare userSerialNumber */ | |
566 PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n"); | |
567 if (SECITEM_CompareItem( | |
568 &(((PKIX_PL_CRLEntry *)firstCrlEntry)->nssCrlEntry->serialNumber), | |
569 &(((PKIX_PL_CRLEntry *)secondCrlEntry)->nssCrlEntry->serialNumber)) | |
570 != SECEqual) { | |
571 *pResult = PKIX_FALSE; | |
572 goto cleanup; | |
573 } | |
574 | |
575 /* Compare revocationDate */ | |
576 PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n"); | |
577 if (SECITEM_CompareItem | |
578 (&(((PKIX_PL_CRLEntry *)firstCrlEntry)->nssCrlEntry-> | |
579 revocationDate), | |
580 &(((PKIX_PL_CRLEntry *)secondCrlEntry)->nssCrlEntry-> | |
581 revocationDate)) | |
582 != SECEqual) { | |
583 *pResult = PKIX_FALSE; | |
584 goto cleanup; | |
585 } | |
586 | |
587 /* Compare Critical Extension List */ | |
588 PKIX_CHECK(pkix_pl_CRLEntry_Extensions_Equals | |
589 (firstCrlEntry->nssCrlEntry->extensions, | |
590 secondCrlEntry->nssCrlEntry->extensions, | |
591 &cmpResult, | |
592 plContext), | |
593 PKIX_CRLENTRYEXTENSIONSEQUALSFAILED); | |
594 | |
595 if (cmpResult != PKIX_TRUE){ | |
596 *pResult = PKIX_FALSE; | |
597 goto cleanup; | |
598 } | |
599 | |
600 cmpResult = (firstCrlEntry->userReasonCode == | |
601 secondCrlEntry->userReasonCode); | |
602 | |
603 *pResult = cmpResult; | |
604 | |
605 cleanup: | |
606 | |
607 PKIX_RETURN(CRLENTRY); | |
608 } | |
609 | |
610 /* | |
611 * FUNCTION: pkix_pl_CRLEntry_RegisterSelf | |
612 * DESCRIPTION: | |
613 * Registers PKIX_CRLEntry_TYPE and its related functions with systemClasses[] | |
614 * THREAD SAFETY: | |
615 * Not Thread Safe - for performance and complexity reasons | |
616 * | |
617 * Since this function is only called by PKIX_PL_Initialize, which should | |
618 * only be called once, it is acceptable that this function is not | |
619 * thread-safe. | |
620 */ | |
621 PKIX_Error * | |
622 pkix_pl_CRLEntry_RegisterSelf(void *plContext) | |
623 { | |
624 | |
625 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |
626 pkix_ClassTable_Entry entry; | |
627 | |
628 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_RegisterSelf"); | |
629 | |
630 entry.description = "CRLEntry"; | |
631 entry.objCounter = 0; | |
632 entry.typeObjectSize = sizeof(PKIX_PL_CRLEntry); | |
633 entry.destructor = pkix_pl_CRLEntry_Destroy; | |
634 entry.equalsFunction = pkix_pl_CRLEntry_Equals; | |
635 entry.hashcodeFunction = pkix_pl_CRLEntry_Hashcode; | |
636 entry.toStringFunction = pkix_pl_CRLEntry_ToString; | |
637 entry.comparator = NULL; | |
638 entry.duplicateFunction = pkix_duplicateImmutable; | |
639 | |
640 systemClasses[PKIX_CRLENTRY_TYPE] = entry; | |
641 | |
642 PKIX_RETURN(CRLENTRY); | |
643 } | |
644 | |
645 /* | |
646 * FUNCTION: pkix_pl_CRLEntry_CreateEntry | |
647 * DESCRIPTION: | |
648 * | |
649 * Creates a new CRLEntry using the CertCrlEntry pointed to by "nssCrlEntry" | |
650 * and stores it at "pCrlEntry". Once created, a CRLEntry is immutable. | |
651 * | |
652 * revokedCertificates SEQUENCE OF SEQUENCE { | |
653 * userCertificate CertificateSerialNumber, | |
654 * revocationDate Time, | |
655 * crlEntryExtensions Extensions OPTIONAL | |
656 * -- if present, MUST be v2 | |
657 * | |
658 * PARAMETERS: | |
659 * "nssCrlEntry" | |
660 * Address of CERTCrlEntry representing an NSS CRL entry. | |
661 * Must be non-NULL. | |
662 * "pCrlEntry" | |
663 * Address where object pointer will be stored. Must be non-NULL. | |
664 * "plContext" | |
665 * Platform-specific context pointer. | |
666 * THREAD SAFETY: | |
667 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
668 * RETURNS: | |
669 * Returns NULL if the function succeeds. | |
670 * Returns a CRLEntry Error if the function fails in a non-fatal way. | |
671 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
672 */ | |
673 static PKIX_Error * | |
674 pkix_pl_CRLEntry_CreateEntry( | |
675 CERTCrlEntry *nssCrlEntry, /* entry data to be created from */ | |
676 PKIX_PL_CRLEntry **pCrlEntry, | |
677 void *plContext) | |
678 { | |
679 PKIX_PL_CRLEntry *crlEntry = NULL; | |
680 | |
681 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_CreateEntry"); | |
682 PKIX_NULLCHECK_TWO(nssCrlEntry, pCrlEntry); | |
683 | |
684 PKIX_CHECK(PKIX_PL_Object_Alloc | |
685 (PKIX_CRLENTRY_TYPE, | |
686 sizeof (PKIX_PL_CRLEntry), | |
687 (PKIX_PL_Object **)&crlEntry, | |
688 plContext), | |
689 PKIX_COULDNOTCREATECRLENTRYOBJECT); | |
690 | |
691 crlEntry->nssCrlEntry = nssCrlEntry; | |
692 crlEntry->serialNumber = NULL; | |
693 crlEntry->critExtOids = NULL; | |
694 crlEntry->userReasonCode = 0; | |
695 crlEntry->userReasonCodeAbsent = PKIX_FALSE; | |
696 | |
697 *pCrlEntry = crlEntry; | |
698 | |
699 cleanup: | |
700 | |
701 PKIX_RETURN(CRLENTRY); | |
702 } | |
703 | |
704 /* | |
705 * FUNCTION: pkix_pl_CRLEntry_Create | |
706 * DESCRIPTION: | |
707 * | |
708 * Creates a List of CRLEntries using the array of CERTCrlEntries pointed to | |
709 * by "nssCrlEntries" and stores it at "pCrlEntryList". If "nssCrlEntries" is | |
710 * NULL, this function stores an empty List at "pCrlEntryList". | |
711 * } | |
712 * PARAMETERS: | |
713 * "nssCrlEntries" | |
714 * Address of array of CERTCrlEntries representing NSS CRL entries. | |
715 * Can be NULL if CRL has no NSS CRL entries. | |
716 * "pCrlEntryList" | |
717 * Address where object pointer will be stored. Must be non-NULL. | |
718 * "plContext" | |
719 * Platform-specific context pointer. | |
720 * THREAD SAFETY: | |
721 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
722 * RETURNS: | |
723 * Returns NULL if the function succeeds. | |
724 * Returns a CRLEntry Error if the function fails in a non-fatal way. | |
725 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
726 */ | |
727 PKIX_Error * | |
728 pkix_pl_CRLEntry_Create( | |
729 CERTCrlEntry **nssCrlEntries, /* head of entry list */ | |
730 PKIX_List **pCrlEntryList, | |
731 void *plContext) | |
732 { | |
733 PKIX_List *entryList = NULL; | |
734 PKIX_PL_CRLEntry *crlEntry = NULL; | |
735 CERTCrlEntry **entries = NULL; | |
736 SECItem serialNumberItem; | |
737 PKIX_PL_BigInt *serialNumber; | |
738 char *bytes = NULL; | |
739 PKIX_UInt32 length; | |
740 | |
741 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Create"); | |
742 PKIX_NULLCHECK_ONE(pCrlEntryList); | |
743 | |
744 entries = nssCrlEntries; | |
745 | |
746 PKIX_CHECK(PKIX_List_Create(&entryList, plContext), | |
747 PKIX_LISTCREATEFAILED); | |
748 | |
749 if (entries) { | |
750 while (*entries){ | |
751 PKIX_CHECK(pkix_pl_CRLEntry_CreateEntry | |
752 (*entries, &crlEntry, plContext), | |
753 PKIX_COULDNOTCREATECRLENTRYOBJECT); | |
754 | |
755 /* Get Serial Number */ | |
756 serialNumberItem = (*entries)->serialNumber; | |
757 length = serialNumberItem.len; | |
758 bytes = (char *)serialNumberItem.data; | |
759 | |
760 PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes | |
761 (bytes, length, &serialNumber, plContext), | |
762 PKIX_BIGINTCREATEWITHBYTESFAILED); | |
763 | |
764 crlEntry->serialNumber = serialNumber; | |
765 crlEntry->nssCrlEntry = *entries; | |
766 | |
767 PKIX_CHECK(PKIX_List_AppendItem | |
768 (entryList, (PKIX_PL_Object *)crlEntry, plContext), | |
769 PKIX_LISTAPPENDITEMFAILED); | |
770 | |
771 PKIX_DECREF(crlEntry); | |
772 | |
773 entries++; | |
774 } | |
775 } | |
776 | |
777 *pCrlEntryList = entryList; | |
778 | |
779 cleanup: | |
780 PKIX_DECREF(crlEntry); | |
781 | |
782 if (PKIX_ERROR_RECEIVED){ | |
783 PKIX_DECREF(entryList); | |
784 } | |
785 | |
786 PKIX_RETURN(CRLENTRY); | |
787 } | |
788 | |
789 /* --Public-CRLENTRY-Functions------------------------------------- */ | |
790 | |
791 /* | |
792 * FUNCTION: PKIX_PL_CRLEntry_GetCRLEntryReasonCode | |
793 * (see comments in pkix_pl_pki.h) | |
794 */ | |
795 PKIX_Error * | |
796 PKIX_PL_CRLEntry_GetCRLEntryReasonCode ( | |
797 PKIX_PL_CRLEntry *crlEntry, | |
798 PKIX_Int32 *pReason, | |
799 void *plContext) | |
800 { | |
801 SECStatus status; | |
802 CERTCRLEntryReasonCode nssReasonCode; | |
803 | |
804 PKIX_ENTER(CRLENTRY, "PKIX_PL_CRLEntry_GetCRLEntryReasonCode"); | |
805 PKIX_NULLCHECK_TWO(crlEntry, pReason); | |
806 | |
807 if (!crlEntry->userReasonCodeAbsent && crlEntry->userReasonCode == 0) { | |
808 | |
809 PKIX_OBJECT_LOCK(crlEntry); | |
810 | |
811 if (!crlEntry->userReasonCodeAbsent && | |
812 crlEntry->userReasonCode == 0) { | |
813 | |
814 /* reason code has not been cached in */ | |
815 PKIX_CRLENTRY_DEBUG("\t\tCERT_FindCRLEntryReasonExten.\n"); | |
816 status = CERT_FindCRLEntryReasonExten | |
817 (crlEntry->nssCrlEntry, &nssReasonCode); | |
818 | |
819 if (status == SECSuccess) { | |
820 crlEntry->userReasonCode = (PKIX_Int32) nssReasonCode; | |
821 } else { | |
822 crlEntry->userReasonCodeAbsent = PKIX_TRUE; | |
823 } | |
824 } | |
825 | |
826 PKIX_OBJECT_UNLOCK(crlEntry); | |
827 | |
828 } | |
829 | |
830 *pReason = crlEntry->userReasonCode; | |
831 | |
832 cleanup: | |
833 | |
834 PKIX_RETURN(CRLENTRY); | |
835 } | |
836 | |
837 /* | |
838 * FUNCTION: PKIX_PL_CRLEntry_GetCriticalExtensionOIDs | |
839 * (see comments in pkix_pl_pki.h) | |
840 */ | |
841 PKIX_Error * | |
842 PKIX_PL_CRLEntry_GetCriticalExtensionOIDs ( | |
843 PKIX_PL_CRLEntry *crlEntry, | |
844 PKIX_List **pList, /* list of PKIX_PL_OID */ | |
845 void *plContext) | |
846 { | |
847 PKIX_List *oidsList = NULL; | |
848 CERTCertExtension **extensions; | |
849 | |
850 PKIX_ENTER(CRLENTRY, "PKIX_PL_CRLEntry_GetCriticalExtensionOIDs"); | |
851 PKIX_NULLCHECK_THREE(crlEntry, crlEntry->nssCrlEntry, pList); | |
852 | |
853 /* if we don't have a cached copy from before, we create one */ | |
854 if (crlEntry->critExtOids == NULL) { | |
855 | |
856 PKIX_OBJECT_LOCK(crlEntry); | |
857 | |
858 if (crlEntry->critExtOids == NULL) { | |
859 | |
860 extensions = crlEntry->nssCrlEntry->extensions; | |
861 | |
862 PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs | |
863 (extensions, &oidsList, plContext), | |
864 PKIX_GETCRITICALEXTENSIONOIDSFAILED); | |
865 | |
866 crlEntry->critExtOids = oidsList; | |
867 } | |
868 | |
869 PKIX_OBJECT_UNLOCK(crlEntry); | |
870 | |
871 } | |
872 | |
873 /* We should return a copy of the List since this list changes */ | |
874 PKIX_DUPLICATE(crlEntry->critExtOids, pList, plContext, | |
875 PKIX_OBJECTDUPLICATELISTFAILED); | |
876 | |
877 cleanup: | |
878 | |
879 PKIX_RETURN(CRLENTRY); | |
880 } | |
OLD | NEW |