comparison nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /*
5 * pkix_pl_crl.c
6 *
7 * CRL Function Definitions
8 *
9 */
10
11 #include "pkix_pl_crl.h"
12 #include "certxutl.h"
13
14 extern PKIX_PL_HashTable *cachedCrlSigTable;
15
16 /* --Private-CRL-Functions------------------------------------- */
17
18 /*
19 * FUNCTION: pkix_pl_CRL_GetVersion
20 * DESCRIPTION:
21 *
22 * Retrieves the version of the CRL pointed to by "crl" and stores it at
23 * "pVersion". The version number will either be 0 or 1 (corresponding to
24 * v1 or v2, respectively).
25 *
26 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
27 *
28 * PARAMETERS:
29 * "crl"
30 * Address of CRL whose version is to be stored. Must be non-NULL.
31 * "pVersion"
32 * Address where a version will be stored. Must be non-NULL.
33 * "plContext"
34 * Platform-specific context pointer.
35 * THREAD SAFETY:
36 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
37 * RETURNS:
38 * Returns NULL if the function succeeds.
39 * Returns a CRL Error if the function fails in a non-fatal way.
40 * Returns a Fatal Error if the function fails in an unrecoverable way.
41 */
42 static PKIX_Error *
43 pkix_pl_CRL_GetVersion(
44 PKIX_PL_CRL *crl,
45 PKIX_UInt32 *pVersion,
46 void *plContext)
47 {
48 PKIX_UInt32 myVersion;
49
50 PKIX_ENTER(CRL, "pkix_pl_CRL_GetVersion");
51 PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pVersion);
52
53 PKIX_NULLCHECK_ONE(crl->nssSignedCrl->crl.version.data);
54
55 myVersion = *(crl->nssSignedCrl->crl.version.data);
56
57 if (myVersion > 1) {
58 PKIX_ERROR(PKIX_VERSIONVALUEMUSTBEV1ORV2);
59 }
60
61 *pVersion = myVersion;
62
63 cleanup:
64
65 PKIX_RETURN(CRL);
66 }
67
68 /*
69 * FUNCTION: PKIX_PL_CRL_GetCRLNumber (see comments in pkix_pl_pki.h)
70 */
71 PKIX_Error *
72 PKIX_PL_CRL_GetCRLNumber(
73 PKIX_PL_CRL *crl,
74 PKIX_PL_BigInt **pCrlNumber,
75 void *plContext)
76 {
77 PKIX_PL_BigInt *crlNumber = NULL;
78 SECItem nssCrlNumber;
79 PLArenaPool *arena = NULL;
80 SECStatus status;
81 PKIX_UInt32 length = 0;
82 char *bytes = NULL;
83
84 PKIX_ENTER(CRL, "PKIX_PL_CRL_GetCRLNumber");
85 PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pCrlNumber);
86
87 /* Can call this function only with der been adopted. */
88 PORT_Assert(crl->adoptedDerCrl);
89
90 if (!crl->crlNumberAbsent && crl->crlNumber == NULL) {
91
92 PKIX_OBJECT_LOCK(crl);
93
94 if (!crl->crlNumberAbsent && crl->crlNumber == NULL) {
95
96 nssCrlNumber.type = 0;
97 nssCrlNumber.len = 0;
98 nssCrlNumber.data = NULL;
99
100 PKIX_CRL_DEBUG("\t\tCalling PORT_NewArena).\n");
101 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
102 if (arena == NULL) {
103 PKIX_ERROR(PKIX_OUTOFMEMORY);
104 }
105
106 PKIX_CRL_DEBUG("\t\tCalling CERT_FindCRLNumberExten\n");
107 status = CERT_FindCRLNumberExten
108 (arena, &crl->nssSignedCrl->crl, &nssCrlNumber);
109
110 if (status == SECSuccess) {
111 /* Get data in bytes then convert to bigint */
112 length = nssCrlNumber.len;
113 bytes = (char *)nssCrlNumber.data;
114
115 PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes
116 (bytes, length, &crlNumber, plContext),
117 PKIX_BIGINTCREATEWITHBYTESFAILED);
118
119 /* arena release does the job
120 PKIX_CRL_DEBUG("\t\tCalling SECITEM_FreeItem\n");
121 SECITEM_FreeItem(&nssCrlNumber, PKIX_FALSE);
122 */
123 crl->crlNumber = crlNumber;
124
125 } else {
126
127 crl->crlNumberAbsent = PKIX_TRUE;
128 }
129 }
130
131 PKIX_OBJECT_UNLOCK(crl);
132
133 }
134
135 PKIX_INCREF(crl->crlNumber);
136
137 *pCrlNumber = crl->crlNumber;
138
139 cleanup:
140
141 if (arena){
142 PKIX_CRL_DEBUG("\t\tCalling PORT_FreeArena).\n");
143 PORT_FreeArena(arena, PR_FALSE);
144 }
145
146 PKIX_RETURN(CRL);
147 }
148
149 /*
150 * FUNCTION: pkix_pl_CRL_GetSignatureAlgId
151 *
152 * DESCRIPTION:
153 * Retrieves a pointer to the OID that represents the signature algorithm of
154 * the CRL pointed to by "crl" and stores it at "pSignatureAlgId".
155 *
156 * AlgorithmIdentifier ::= SEQUENCE {
157 * algorithm OBJECT IDENTIFIER,
158 * parameters ANY DEFINED BY algorithm OPTIONAL }
159 *
160 * PARAMETERS:
161 * "crl"
162 * Address of CRL whose signature algorithm OID is to be stored.
163 * Must be non-NULL.
164 * "pSignatureAlgId"
165 * Address where object pointer will be stored. Must be non-NULL.
166 * "plContext"
167 * Platform-specific context pointer.
168 * THREAD SAFETY:
169 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
170 * RETURNS:
171 * Returns NULL if the function succeeds.
172 * Returns a CRL Error if the function fails in a non-fatal way.
173 * Returns a Fatal Error if the function fails in an unrecoverable way.
174 */
175 static PKIX_Error *
176 pkix_pl_CRL_GetSignatureAlgId(
177 PKIX_PL_CRL *crl,
178 PKIX_PL_OID **pSignatureAlgId,
179 void *plContext)
180 {
181 PKIX_PL_OID *signatureAlgId = NULL;
182
183 PKIX_ENTER(CRL, "pkix_pl_CRL_GetSignatureAlgId");
184 PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pSignatureAlgId);
185
186 /* if we don't have a cached copy from before, we create one */
187 if (crl->signatureAlgId == NULL){
188 PKIX_OBJECT_LOCK(crl);
189 if (crl->signatureAlgId == NULL){
190 CERTCrl *nssCrl = &(crl->nssSignedCrl->crl);
191 SECAlgorithmID *algorithm = &nssCrl->signatureAlg;
192 SECItem *algBytes = &algorithm->algorithm;
193
194 if (!algBytes->data || !algBytes->len) {
195 PKIX_ERROR(PKIX_OIDBYTESLENGTH0);
196 }
197 PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
198 (algBytes, &signatureAlgId, plContext),
199 PKIX_OIDCREATEFAILED);
200
201 /* save a cached copy in case it is asked for again */
202 crl->signatureAlgId = signatureAlgId;
203 signatureAlgId = NULL;
204 }
205 PKIX_OBJECT_UNLOCK(crl);
206 }
207 PKIX_INCREF(crl->signatureAlgId);
208 *pSignatureAlgId = crl->signatureAlgId;
209 cleanup:
210 PKIX_DECREF(signatureAlgId);
211 PKIX_RETURN(CRL);
212 }
213
214 /*
215 * FUNCTION: pkix_pl_CRL_GetCRLEntries
216 * DESCRIPTION:
217 *
218 * Retrieves a pointer to the List of CRLEntries found in the CRL pointed to
219 * by "crl" and stores it at "pCRLEntries". If there are no CRLEntries,
220 * this functions stores NULL at "pCRLEntries".
221 *
222 * PARAMETERS:
223 * "crl"
224 * Address of CRL whose CRL Entries are to be retrieved. Must be non-NULL.
225 * "pCRLEntries"
226 * Address where object pointer will be stored. Must be non-NULL.
227 * "plContext"
228 * Platform-specific context pointer.
229 * THREAD SAFETY:
230 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
231 * RETURNS:
232 * Returns NULL if the function succeeds.
233 * Returns a CRL Error if the function fails in a non-fatal way.
234 * Returns a Fatal Error if the function fails in an unrecoverable way.
235 */
236 static PKIX_Error *
237 pkix_pl_CRL_GetCRLEntries(
238 PKIX_PL_CRL *crl,
239 PKIX_List **pCrlEntries,
240 void *plContext)
241 {
242 PKIX_List *entryList = NULL;
243 CERTCrl *nssCrl = NULL;
244
245 PKIX_ENTER(CRL, "pkix_pl_CRL_GetCRLEntries");
246 PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pCrlEntries);
247
248 /* if we don't have a cached copy from before, we create one */
249 if (crl->crlEntryList == NULL) {
250
251 PKIX_OBJECT_LOCK(crl);
252
253 if (crl->crlEntryList == NULL){
254
255 nssCrl = &(crl->nssSignedCrl->crl);
256
257 PKIX_CHECK(pkix_pl_CRLEntry_Create
258 (nssCrl->entries, &entryList, plContext),
259 PKIX_CRLENTRYCREATEFAILED);
260
261 PKIX_CHECK(PKIX_List_SetImmutable
262 (entryList, plContext),
263 PKIX_LISTSETIMMUTABLEFAILED);
264
265 crl->crlEntryList = entryList;
266 }
267
268 PKIX_OBJECT_UNLOCK(crl);
269
270 }
271
272 PKIX_INCREF(crl->crlEntryList);
273
274 *pCrlEntries = crl->crlEntryList;
275
276 cleanup:
277
278 PKIX_RETURN(CRL);
279 }
280
281 /*
282 * FUNCTION: pkix_pl_CRL_Destroy
283 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
284 */
285 static PKIX_Error *
286 pkix_pl_CRL_Destroy(
287 PKIX_PL_Object *object,
288 void *plContext)
289 {
290 PKIX_PL_CRL *crl = NULL;
291
292 PKIX_ENTER(CRL, "pkix_pl_CRL_Destroy");
293 PKIX_NULLCHECK_ONE(object);
294
295 PKIX_CHECK(pkix_CheckType(object, PKIX_CRL_TYPE, plContext),
296 PKIX_OBJECTNOTCRL);
297
298 crl = (PKIX_PL_CRL*)object;
299
300 PKIX_CRL_DEBUG("\t\tCalling CERT_DestroyCrl\n");
301 if (crl->nssSignedCrl) {
302 CERT_DestroyCrl(crl->nssSignedCrl);
303 }
304 if (crl->adoptedDerCrl) {
305 SECITEM_FreeItem(crl->adoptedDerCrl, PR_TRUE);
306 }
307 crl->nssSignedCrl = NULL;
308 crl->adoptedDerCrl = NULL;
309 crl->crlNumberAbsent = PKIX_FALSE;
310
311 PKIX_DECREF(crl->issuer);
312 PKIX_DECREF(crl->signatureAlgId);
313 PKIX_DECREF(crl->crlNumber);
314 PKIX_DECREF(crl->crlEntryList);
315 PKIX_DECREF(crl->critExtOids);
316 if (crl->derGenName) {
317 SECITEM_FreeItem(crl->derGenName, PR_TRUE);
318 }
319
320 cleanup:
321
322 PKIX_RETURN(CRL);
323 }
324
325 /*
326 * FUNCTION: pkix_pl_CRL_ToString_Helper
327 * DESCRIPTION:
328 *
329 * Helper function that creates a string representation of the CRL pointed
330 * to by "crl" and stores it at "pString".
331 *
332 * PARAMETERS
333 * "crl"
334 * Address of CRL whose string representation is desired.
335 * Must be non-NULL.
336 * "pString"
337 * Address where object pointer will be stored. Must be non-NULL.
338 * "plContext"
339 * Platform-specific context pointer.
340 * THREAD SAFETY:
341 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
342 * RETURNS:
343 * Returns NULL if the function succeeds.
344 * Returns a CRL Error if the function fails in a non-fatal way.
345 * Returns a Fatal Error if the function fails in an unrecoverable way.
346 */
347 static PKIX_Error *
348 pkix_pl_CRL_ToString_Helper(
349 PKIX_PL_CRL *crl,
350 PKIX_PL_String **pString,
351 void *plContext)
352 {
353 char *asciiFormat = NULL;
354 PKIX_UInt32 crlVersion;
355 PKIX_PL_X500Name *crlIssuer = NULL;
356 PKIX_PL_OID *nssSignatureAlgId = NULL;
357 PKIX_PL_BigInt *crlNumber = NULL;
358 PKIX_List *crlEntryList = NULL;
359 PKIX_List *critExtOIDs = NULL;
360 PKIX_PL_String *formatString = NULL;
361 PKIX_PL_String *crlIssuerString = NULL;
362 PKIX_PL_String *lastUpdateString = NULL;
363 PKIX_PL_String *nextUpdateString = NULL;
364 PKIX_PL_String *nssSignatureAlgIdString = NULL;
365 PKIX_PL_String *crlNumberString = NULL;
366 PKIX_PL_String *crlEntryListString = NULL;
367 PKIX_PL_String *critExtOIDsString = NULL;
368 PKIX_PL_String *crlString = NULL;
369
370 PKIX_ENTER(CRL, "pkix_pl_CRL_ToString_Helper");
371 PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pString);
372
373 asciiFormat =
374 "[\n"
375 "\tVersion: v%d\n"
376 "\tIssuer: %s\n"
377 "\tUpdate: [Last: %s\n"
378 "\t Next: %s]\n"
379 "\tSignatureAlgId: %s\n"
380 "\tCRL Number : %s\n"
381 "\n"
382 "\tEntry List: %s\n"
383 "\n"
384 "\tCritExtOIDs: %s\n"
385 "]\n";
386
387 PKIX_CHECK(PKIX_PL_String_Create
388 (PKIX_ESCASCII,
389 asciiFormat,
390 0,
391 &formatString,
392 plContext),
393 PKIX_STRINGCREATEFAILED);
394
395 /* Version */
396 PKIX_CHECK(pkix_pl_CRL_GetVersion(crl, &crlVersion, plContext),
397 PKIX_CRLGETVERSIONFAILED);
398
399 /* Issuer */
400 PKIX_CHECK(PKIX_PL_CRL_GetIssuer(crl, &crlIssuer, plContext),
401 PKIX_CRLGETISSUERFAILED);
402
403 PKIX_CHECK(PKIX_PL_Object_ToString
404 ((PKIX_PL_Object *)crlIssuer, &crlIssuerString, plContext),
405 PKIX_X500NAMETOSTRINGFAILED);
406
407 /* This update - No Date object created, use nss data directly */
408 PKIX_CHECK(pkix_pl_Date_ToString_Helper
409 (&(crl->nssSignedCrl->crl.lastUpdate),
410 &lastUpdateString,
411 plContext),
412 PKIX_DATETOSTRINGHELPERFAILED);
413
414 /* Next update - No Date object created, use nss data directly */
415 PKIX_CHECK(pkix_pl_Date_ToString_Helper
416 (&(crl->nssSignedCrl->crl.nextUpdate),
417 &nextUpdateString,
418 plContext),
419 PKIX_DATETOSTRINGHELPERFAILED);
420
421 /* Signature Algorithm Id */
422 PKIX_CHECK(pkix_pl_CRL_GetSignatureAlgId
423 (crl, &nssSignatureAlgId, plContext),
424 PKIX_CRLGETSIGNATUREALGIDFAILED);
425
426 PKIX_CHECK(PKIX_PL_Object_ToString
427 ((PKIX_PL_Object *)nssSignatureAlgId,
428 &nssSignatureAlgIdString,
429 plContext),
430 PKIX_OIDTOSTRINGFAILED);
431
432 /* CRL Number */
433 PKIX_CHECK(PKIX_PL_CRL_GetCRLNumber
434 (crl, &crlNumber, plContext),
435 PKIX_CRLGETCRLNUMBERFAILED);
436
437 PKIX_TOSTRING(crlNumber, &crlNumberString, plContext,
438 PKIX_BIGINTTOSTRINGFAILED);
439
440 /* CRL Entries */
441 PKIX_CHECK(pkix_pl_CRL_GetCRLEntries(crl, &crlEntryList, plContext),
442 PKIX_CRLGETCRLENTRIESFAILED);
443
444 PKIX_TOSTRING(crlEntryList, &crlEntryListString, plContext,
445 PKIX_LISTTOSTRINGFAILED);
446
447 /* CriticalExtensionOIDs */
448 PKIX_CHECK(PKIX_PL_CRL_GetCriticalExtensionOIDs
449 (crl, &critExtOIDs, plContext),
450 PKIX_CRLGETCRITICALEXTENSIONOIDSFAILED);
451
452 PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext,
453 PKIX_LISTTOSTRINGFAILED);
454
455 PKIX_CHECK(PKIX_PL_Sprintf
456 (&crlString,
457 plContext,
458 formatString,
459 crlVersion + 1,
460 crlIssuerString,
461 lastUpdateString,
462 nextUpdateString,
463 nssSignatureAlgIdString,
464 crlNumberString,
465 crlEntryListString,
466 critExtOIDsString),
467 PKIX_SPRINTFFAILED);
468
469 *pString = crlString;
470
471 cleanup:
472
473 PKIX_DECREF(crlIssuer);
474 PKIX_DECREF(nssSignatureAlgId);
475 PKIX_DECREF(crlNumber);
476 PKIX_DECREF(crlEntryList);
477 PKIX_DECREF(critExtOIDs);
478 PKIX_DECREF(crlIssuerString);
479 PKIX_DECREF(lastUpdateString);
480 PKIX_DECREF(nextUpdateString);
481 PKIX_DECREF(nssSignatureAlgIdString);
482 PKIX_DECREF(crlNumberString);
483 PKIX_DECREF(crlEntryListString);
484 PKIX_DECREF(critExtOIDsString);
485 PKIX_DECREF(formatString);
486
487 PKIX_RETURN(CRL);
488 }
489
490 /*
491 * FUNCTION: pkix_pl_CRL_ToString
492 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
493 */
494 static PKIX_Error *
495 pkix_pl_CRL_ToString(
496 PKIX_PL_Object *object,
497 PKIX_PL_String **pString,
498 void *plContext)
499 {
500 PKIX_PL_String *crlString = NULL;
501 PKIX_PL_CRL *crl = NULL;
502
503 PKIX_ENTER(CRL, "pkix_pl_CRL_ToString");
504 PKIX_NULLCHECK_TWO(object, pString);
505
506 PKIX_CHECK(pkix_CheckType(object, PKIX_CRL_TYPE, plContext),
507 PKIX_OBJECTNOTCRL);
508
509 crl = (PKIX_PL_CRL *) object;
510
511 PKIX_CHECK(pkix_pl_CRL_ToString_Helper(crl, &crlString, plContext),
512 PKIX_CRLTOSTRINGHELPERFAILED);
513
514 *pString = crlString;
515
516 cleanup:
517
518 PKIX_RETURN(CRL);
519 }
520
521 /*
522 * FUNCTION: pkix_pl_CRL_Hashcode
523 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
524 */
525 static PKIX_Error *
526 pkix_pl_CRL_Hashcode(
527 PKIX_PL_Object *object,
528 PKIX_UInt32 *pHashcode,
529 void *plContext)
530 {
531 PKIX_PL_CRL *crl = NULL;
532 PKIX_UInt32 certHash;
533 SECItem *crlDer = NULL;
534
535 PKIX_ENTER(CRL, "pkix_pl_CRL_Hashcode");
536 PKIX_NULLCHECK_TWO(object, pHashcode);
537
538 PKIX_CHECK(pkix_CheckType(object, PKIX_CRL_TYPE, plContext),
539 PKIX_OBJECTNOTCRL);
540
541 crl = (PKIX_PL_CRL *)object;
542 if (crl->adoptedDerCrl) {
543 crlDer = crl->adoptedDerCrl;
544 } else if (crl->nssSignedCrl && crl->nssSignedCrl->derCrl) {
545 crlDer = crl->nssSignedCrl->derCrl;
546 }
547 if (!crlDer || !crlDer->data) {
548 PKIX_ERROR(PKIX_CANNOTAQUIRECRLDER);
549 }
550
551 PKIX_CHECK(pkix_hash(crlDer->data, crlDer->len,
552 &certHash, plContext),
553 PKIX_ERRORINHASH);
554
555 *pHashcode = certHash;
556
557 cleanup:
558
559 PKIX_RETURN(CRL);
560 }
561
562 /*
563 * FUNCTION: pkix_pl_CRL_Equals
564 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
565 */
566 static PKIX_Error *
567 pkix_pl_CRL_Equals(
568 PKIX_PL_Object *firstObject,
569 PKIX_PL_Object *secondObject,
570 PKIX_Boolean *pResult,
571 void *plContext)
572 {
573 PKIX_PL_CRL *firstCrl = NULL;
574 PKIX_PL_CRL *secondCrl = NULL;
575 SECItem *crlDerOne = NULL, *crlDerTwo = NULL;
576 PKIX_UInt32 secondType;
577
578 PKIX_ENTER(CRL, "pkix_pl_CRL_Equals");
579 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
580
581 /* test that firstObject is a CRL */
582 PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CRL_TYPE, plContext),
583 PKIX_FIRSTOBJECTNOTCRL);
584
585 firstCrl = (PKIX_PL_CRL *)firstObject;
586 secondCrl = (PKIX_PL_CRL *)secondObject;
587
588 /*
589 * Since we know firstObject is a CRL, if both references are
590 * identical, they must be equal
591 */
592 if (firstCrl == secondCrl){
593 *pResult = PKIX_TRUE;
594 goto cleanup;
595 }
596
597 /*
598 * If secondCrl isn't a CRL, we don't throw an error.
599 * We simply return a Boolean result of FALSE
600 */
601 *pResult = PKIX_FALSE;
602 PKIX_CHECK(PKIX_PL_Object_GetType
603 ((PKIX_PL_Object *)secondCrl, &secondType, plContext),
604 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
605 if (secondType != PKIX_CRL_TYPE) goto cleanup;
606
607 if (firstCrl->adoptedDerCrl) {
608 crlDerOne = firstCrl->adoptedDerCrl;
609 } else if (firstCrl->nssSignedCrl && firstCrl->nssSignedCrl->derCrl) {
610 crlDerOne = firstCrl->nssSignedCrl->derCrl;
611 }
612
613 if (secondCrl->adoptedDerCrl) {
614 crlDerTwo = secondCrl->adoptedDerCrl;
615 } else if (secondCrl->nssSignedCrl && secondCrl->nssSignedCrl->derCrl) {
616 crlDerTwo = secondCrl->nssSignedCrl->derCrl;
617 }
618
619 if (SECITEM_CompareItem(crlDerOne, crlDerTwo) == SECEqual) {
620 *pResult = PKIX_TRUE;
621 }
622
623 cleanup:
624
625 PKIX_RETURN(CRL);
626 }
627
628 /*
629 * FUNCTION: pkix_pl_CRL_RegisterSelf
630 *
631 * DESCRIPTION:
632 * Registers PKIX_CRL_TYPE and its related functions with systemClasses[]
633 * THREAD SAFETY:
634 *
635 * Not Thread Safe - for performance and complexity reasons
636 *
637 * Since this function is only called by PKIX_PL_Initialize, which should
638 * only be called once, it is acceptable that this function is not
639 * thread-safe.
640 */
641 PKIX_Error *
642 pkix_pl_CRL_RegisterSelf(void *plContext)
643 {
644 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
645 pkix_ClassTable_Entry *entry = &systemClasses[PKIX_CRL_TYPE];
646
647 PKIX_ENTER(CRL, "pkix_pl_CRL_RegisterSelf");
648
649 entry->description = "CRL";
650 entry->typeObjectSize = sizeof(PKIX_PL_CRL);
651 entry->destructor = pkix_pl_CRL_Destroy;
652 entry->equalsFunction = pkix_pl_CRL_Equals;
653 entry->hashcodeFunction = pkix_pl_CRL_Hashcode;
654 entry->toStringFunction = pkix_pl_CRL_ToString;
655 entry->duplicateFunction = pkix_duplicateImmutable;
656
657 PKIX_RETURN(CRL);
658 }
659
660 /*
661 * FUNCTION: PKIX_PL_CRL_VerifyUpdateTime (see comments in pkix_pl_pki.h)
662 */
663 PKIX_Error *
664 PKIX_PL_CRL_VerifyUpdateTime(
665 PKIX_PL_CRL *crl,
666 PKIX_PL_Date *date,
667 PKIX_Boolean *pResult,
668 void *plContext)
669 {
670 PRTime timeToCheck;
671 PRTime nextUpdate;
672 PRTime lastUpdate;
673 SECStatus status;
674 CERTCrl *nssCrl = NULL;
675 SECItem *nextUpdateDer = NULL;
676 PKIX_Boolean haveNextUpdate = PR_FALSE;
677
678 PKIX_ENTER(CRL, "PKIX_PL_CRL_VerifyUpdateTime");
679 PKIX_NULLCHECK_FOUR(crl, crl->nssSignedCrl, date, pResult);
680
681 /* Can call this function only with der been adopted. */
682 PORT_Assert(crl->adoptedDerCrl);
683
684 nssCrl = &(crl->nssSignedCrl->crl);
685 timeToCheck = date->nssTime;
686
687 /* nextUpdate can be NULL. Checking before using it */
688 nextUpdateDer = &nssCrl->nextUpdate;
689 if (nextUpdateDer->data && nextUpdateDer->len) {
690 haveNextUpdate = PR_TRUE;
691 status = DER_DecodeTimeChoice(&nextUpdate, nextUpdateDer);
692 if (status != SECSuccess) {
693 PKIX_ERROR(PKIX_DERDECODETIMECHOICEFORNEXTUPDATEFAILED);
694 }
695 }
696
697 status = DER_DecodeTimeChoice(&lastUpdate, &(nssCrl->lastUpdate));
698 if (status != SECSuccess) {
699 PKIX_ERROR(PKIX_DERDECODETIMECHOICEFORLASTUPDATEFAILED);
700 }
701
702 if (!haveNextUpdate || nextUpdate < timeToCheck) {
703 *pResult = PKIX_FALSE;
704 goto cleanup;
705 }
706
707 if (lastUpdate <= timeToCheck) {
708 *pResult = PKIX_TRUE;
709 } else {
710 *pResult = PKIX_FALSE;
711 }
712
713 cleanup:
714
715 PKIX_RETURN(CRL);
716 }
717
718 /*
719 * FUNCTION: pkix_pl_CRL_CreateWithSignedCRL
720 * DESCRIPTION:
721 *
722 * Creates a new CRL using the CERTSignedCrl pointed to by "nssSignedCrl"
723 * and stores it at "pCRL". If the decoding of the CERTSignedCrl fails,
724 * a PKIX_Error is returned.
725 *
726 * PARAMETERS:
727 * "nssSignedCrl"
728 * Address of CERTSignedCrl. Must be non-NULL.
729 * "adoptedDerCrl"
730 * SECItem ponter that if not NULL is indicating that memory used
731 * for der should be adopted by crl that is about to be created.
732 * "pCRL"
733 * Address where object pointer will be stored. Must be non-NULL.
734 * "plContext"
735 * Platform-specific context pointer.
736 * THREAD SAFETY:
737 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
738 * RETURNS:
739 * Returns NULL if the function succeeds.
740 * Returns a CRL Error if the function fails in a non-fatal way.
741 * Returns a Fatal Error if the function fails in an unrecoverable way.
742 */
743 PKIX_Error *
744 pkix_pl_CRL_CreateWithSignedCRL(
745 CERTSignedCrl *nssSignedCrl,
746 SECItem *adoptedDerCrl,
747 SECItem *derGenName,
748 PKIX_PL_CRL **pCrl,
749 void *plContext)
750 {
751 PKIX_PL_CRL *crl = NULL;
752
753 PKIX_ENTER(CRL, "pkix_pl_CRL_CreateWithSignedCRL");
754 PKIX_NULLCHECK_ONE(pCrl);
755
756 /* create a PKIX_PL_CRL object */
757 PKIX_CHECK(PKIX_PL_Object_Alloc
758 (PKIX_CRL_TYPE,
759 sizeof (PKIX_PL_CRL),
760 (PKIX_PL_Object **)&crl,
761 plContext),
762 PKIX_COULDNOTCREATECRLOBJECT);
763
764 /* populate the nssSignedCrl field */
765 crl->nssSignedCrl = nssSignedCrl;
766 crl->adoptedDerCrl = adoptedDerCrl;
767 crl->issuer = NULL;
768 crl->signatureAlgId = NULL;
769 crl->crlNumber = NULL;
770 crl->crlNumberAbsent = PKIX_FALSE;
771 crl->crlEntryList = NULL;
772 crl->critExtOids = NULL;
773 if (derGenName) {
774 crl->derGenName =
775 SECITEM_DupItem(derGenName);
776 if (!crl->derGenName) {
777 PKIX_ERROR(PKIX_ALLOCERROR);
778 }
779 }
780
781 *pCrl = crl;
782
783 cleanup:
784
785 if (PKIX_ERROR_RECEIVED){
786 PKIX_DECREF(crl);
787 }
788
789 PKIX_RETURN(CRL);
790 }
791
792 /* --Public-CRL-Functions------------------------------------- */
793
794 /*
795 * FUNCTION: PKIX_PL_CRL_Create (see comments in pkix_pl_pki.h)
796 */
797 PKIX_Error *
798 PKIX_PL_CRL_Create(
799 PKIX_PL_ByteArray *byteArray,
800 PKIX_PL_CRL **pCrl,
801 void *plContext)
802 {
803 CERTSignedCrl *nssSignedCrl = NULL;
804 SECItem derItem, *derCrl = NULL;
805 PKIX_PL_CRL *crl = NULL;
806
807 PKIX_ENTER(CRL, "PKIX_PL_CRL_Create");
808 PKIX_NULLCHECK_TWO(byteArray, pCrl);
809
810 if (byteArray->length == 0){
811 PKIX_ERROR(PKIX_ZEROLENGTHBYTEARRAYFORCRLENCODING);
812 }
813 derItem.type = siBuffer;
814 derItem.data = byteArray->array;
815 derItem.len = byteArray->length;
816 derCrl = SECITEM_DupItem(&derItem);
817 if (!derCrl) {
818 PKIX_ERROR(PKIX_ALLOCERROR);
819 }
820 nssSignedCrl =
821 CERT_DecodeDERCrlWithFlags(NULL, derCrl, SEC_CRL_TYPE,
822 CRL_DECODE_DONT_COPY_DER |
823 CRL_DECODE_SKIP_ENTRIES);
824 if (!nssSignedCrl) {
825 PKIX_ERROR(PKIX_CERTDECODEDERCRLFAILED);
826 }
827 PKIX_CHECK(
828 pkix_pl_CRL_CreateWithSignedCRL(nssSignedCrl, derCrl, NULL,
829 &crl, plContext),
830 PKIX_CRLCREATEWITHSIGNEDCRLFAILED);
831 nssSignedCrl = NULL;
832 derCrl = NULL;
833 *pCrl = crl;
834
835 cleanup:
836 if (derCrl) {
837 SECITEM_FreeItem(derCrl, PR_TRUE);
838 }
839 if (nssSignedCrl) {
840 SEC_DestroyCrl(nssSignedCrl);
841 }
842
843 PKIX_RETURN(CRL);
844 }
845
846 /*
847 * FUNCTION: PKIX_PL_CRL_GetIssuer (see comments in pkix_pl_pki.h)
848 */
849 PKIX_Error *
850 PKIX_PL_CRL_GetIssuer(
851 PKIX_PL_CRL *crl,
852 PKIX_PL_X500Name **pCRLIssuer,
853 void *plContext)
854 {
855 PKIX_PL_String *crlString = NULL;
856 PKIX_PL_X500Name *issuer = NULL;
857 SECItem *derIssuerName = NULL;
858 CERTName *issuerName = NULL;
859
860 PKIX_ENTER(CRL, "PKIX_PL_CRL_GetIssuer");
861 PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pCRLIssuer);
862
863 /* Can call this function only with der been adopted. */
864 PORT_Assert(crl->adoptedDerCrl);
865
866 /* if we don't have a cached copy from before, we create one */
867 if (crl->issuer == NULL){
868
869 PKIX_OBJECT_LOCK(crl);
870
871 if (crl->issuer == NULL) {
872
873 issuerName = &crl->nssSignedCrl->crl.name;
874 derIssuerName = &crl->nssSignedCrl->crl.derName;
875
876 PKIX_CHECK(
877 PKIX_PL_X500Name_CreateFromCERTName(derIssuerName,
878 issuerName,
879 &issuer,
880 plContext),
881 PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
882
883 /* save a cached copy in case it is asked for again */
884 crl->issuer = issuer;
885 }
886
887 PKIX_OBJECT_UNLOCK(crl);
888
889 }
890
891 PKIX_INCREF(crl->issuer);
892
893 *pCRLIssuer = crl->issuer;
894
895 cleanup:
896
897 PKIX_DECREF(crlString);
898
899 PKIX_RETURN(CRL);
900 }
901
902
903 /*
904 * FUNCTION: PKIX_PL_CRL_GetCriticalExtensionOIDs
905 * (see comments in pkix_pl_pki.h)
906 */
907 PKIX_Error *
908 PKIX_PL_CRL_GetCriticalExtensionOIDs(
909 PKIX_PL_CRL *crl,
910 PKIX_List **pExtensions, /* list of PKIX_PL_OID */
911 void *plContext)
912 {
913 PKIX_List *oidsList = NULL;
914 CERTCertExtension **extensions = NULL;
915 CERTCrl *nssSignedCrl = NULL;
916
917 PKIX_ENTER(CRL, "PKIX_PL_CRL_GetCriticalExtensionOIDs");
918 PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pExtensions);
919
920 /* Can call this function only with der been adopted. */
921 PORT_Assert(crl->adoptedDerCrl);
922
923 /* if we don't have a cached copy from before, we create one */
924 if (crl->critExtOids == NULL) {
925
926 PKIX_OBJECT_LOCK(crl);
927
928 nssSignedCrl = &(crl->nssSignedCrl->crl);
929 extensions = nssSignedCrl->extensions;
930
931 if (crl->critExtOids == NULL) {
932
933 PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs
934 (extensions, &oidsList, plContext),
935 PKIX_GETCRITICALEXTENSIONOIDSFAILED);
936
937 crl->critExtOids = oidsList;
938 }
939
940 PKIX_OBJECT_UNLOCK(crl);
941
942 }
943
944 /* We should return a copy of the List since this list changes */
945 PKIX_DUPLICATE(crl->critExtOids, pExtensions, plContext,
946 PKIX_OBJECTDUPLICATELISTFAILED);
947
948 cleanup:
949
950 PKIX_RETURN(CRL);
951 }
952
953 /*
954 * FUNCTION: PKIX_PL_CRL_VerifySignature (see comments in pkix_pl_pki.h)
955 */
956 PKIX_Error *
957 PKIX_PL_CRL_VerifySignature(
958 PKIX_PL_CRL *crl,
959 PKIX_PL_PublicKey *pubKey,
960 void *plContext)
961 {
962 PKIX_PL_CRL *cachedCrl = NULL;
963 PKIX_Error *verifySig = NULL;
964 PKIX_Error *cachedSig = NULL;
965 PKIX_Boolean crlEqual = PKIX_FALSE;
966 PKIX_Boolean crlInHash= PKIX_FALSE;
967 CERTSignedCrl *nssSignedCrl = NULL;
968 SECKEYPublicKey *nssPubKey = NULL;
969 CERTSignedData *tbsCrl = NULL;
970 void* wincx = NULL;
971 SECStatus status;
972
973 PKIX_ENTER(CRL, "PKIX_PL_CRL_VerifySignature");
974 PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pubKey);
975
976 /* Can call this function only with der been adopted. */
977 PORT_Assert(crl->adoptedDerCrl);
978
979 verifySig = PKIX_PL_HashTable_Lookup
980 (cachedCrlSigTable,
981 (PKIX_PL_Object *) pubKey,
982 (PKIX_PL_Object **) &cachedCrl,
983 plContext);
984
985 if (cachedCrl != NULL && verifySig == NULL) {
986 /* Cached Signature Table lookup succeed */
987 PKIX_EQUALS(crl, cachedCrl, &crlEqual, plContext,
988 PKIX_OBJECTEQUALSFAILED);
989 if (crlEqual == PKIX_TRUE) {
990 goto cleanup;
991 }
992 /* Different PubKey may hash to same value, skip add */
993 crlInHash = PKIX_TRUE;
994 }
995
996 nssSignedCrl = crl->nssSignedCrl;
997 tbsCrl = &nssSignedCrl->signatureWrap;
998
999 PKIX_CRL_DEBUG("\t\tCalling SECKEY_ExtractPublicKey\n");
1000 nssPubKey = SECKEY_ExtractPublicKey(pubKey->nssSPKI);
1001 if (!nssPubKey){
1002 PKIX_ERROR(PKIX_SECKEYEXTRACTPUBLICKEYFAILED);
1003 }
1004
1005 PKIX_CHECK(pkix_pl_NssContext_GetWincx
1006 ((PKIX_PL_NssContext *)plContext, &wincx),
1007 PKIX_NSSCONTEXTGETWINCXFAILED);
1008
1009 PKIX_CRL_DEBUG("\t\tCalling CERT_VerifySignedDataWithPublicKey\n");
1010 status = CERT_VerifySignedDataWithPublicKey(tbsCrl, nssPubKey, wincx);
1011
1012 if (status != SECSuccess) {
1013 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1014 PKIX_ERROR(PKIX_SIGNATUREDIDNOTVERIFYWITHTHEPUBLICKEY);
1015 }
1016
1017 if (crlInHash == PKIX_FALSE) {
1018 cachedSig = PKIX_PL_HashTable_Add
1019 (cachedCrlSigTable,
1020 (PKIX_PL_Object *) pubKey,
1021 (PKIX_PL_Object *) crl,
1022 plContext);
1023
1024 if (cachedSig != NULL) {
1025 PKIX_DEBUG("PKIX_PL_HashTable_Add skipped: entry existed\n");
1026 }
1027 }
1028
1029 cleanup:
1030
1031 if (nssPubKey){
1032 PKIX_CRL_DEBUG("\t\tCalling SECKEY_DestroyPublicKey\n");
1033 SECKEY_DestroyPublicKey(nssPubKey);
1034 nssPubKey = NULL;
1035 }
1036
1037 PKIX_DECREF(cachedCrl);
1038 PKIX_DECREF(verifySig);
1039 PKIX_DECREF(cachedSig);
1040
1041 PKIX_RETURN(CRL);
1042 }
1043
1044 PKIX_Error*
1045 PKIX_PL_CRL_ReleaseDerCrl(PKIX_PL_CRL *crl,
1046 SECItem **derCrl,
1047 void *plContext)
1048 {
1049 PKIX_ENTER(CRL, "PKIX_PL_CRL_ReleaseDerCrl");
1050 *derCrl = crl->adoptedDerCrl;
1051 crl->adoptedDerCrl = NULL;
1052
1053 PKIX_RETURN(CRL);
1054 }
1055
1056 PKIX_Error*
1057 PKIX_PL_CRL_AdoptDerCrl(PKIX_PL_CRL *crl,
1058 SECItem *derCrl,
1059 void *plContext)
1060 {
1061 PKIX_ENTER(CRL, "PKIX_PL_CRL_AquireDerCrl");
1062 if (crl->adoptedDerCrl) {
1063 PKIX_ERROR(PKIX_CANNOTAQUIRECRLDER);
1064 }
1065 crl->adoptedDerCrl = derCrl;
1066 cleanup:
1067 PKIX_RETURN(CRL);
1068 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)