Mercurial > trustbridge > nss-cmake-static
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 } |