Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(773)

Side by Side Diff: nss/lib/libpkix/pkix/util/pkix_tools.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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_tools.c
6 *
7 * Private Utility Functions
8 *
9 */
10
11 #include "pkix_tools.h"
12
13 #define CACHE_ITEM_PERIOD_SECONDS (3600) /* one hour */
14
15 /*
16 * This cahce period is only for CertCache. A Cert from a trusted CertStore
17 * should be checked more frequently for update new arrival, etc.
18 */
19 #define CACHE_TRUST_ITEM_PERIOD_SECONDS (CACHE_ITEM_PERIOD_SECONDS/10)
20
21 extern PKIX_PL_HashTable *cachedCertChainTable;
22 extern PKIX_PL_HashTable *cachedCertTable;
23 extern PKIX_PL_HashTable *cachedCrlEntryTable;
24
25 /* Following variables are used to checked cache hits - can be taken out */
26 extern int pkix_ccAddCount;
27 extern int pkix_ccLookupCount;
28 extern int pkix_ccRemoveCount;
29 extern int pkix_cAddCount;
30 extern int pkix_cLookupCount;
31 extern int pkix_cRemoveCount;
32 extern int pkix_ceAddCount;
33 extern int pkix_ceLookupCount;
34
35 #ifdef PKIX_OBJECT_LEAK_TEST
36 /* Following variables are used for object leak test */
37 char *nonNullValue = "Non Empty Value";
38 PKIX_Boolean noErrorState = PKIX_TRUE;
39 PKIX_Boolean runningLeakTest;
40 PKIX_Boolean errorGenerated;
41 PKIX_UInt32 stackPosition;
42 PKIX_UInt32 *fnStackInvCountArr;
43 char **fnStackNameArr;
44 PLHashTable *fnInvTable;
45 PKIX_UInt32 testStartFnStackPosition;
46 char *errorFnStackString;
47 #endif /* PKIX_OBJECT_LEAK_TEST */
48
49 /* --Private-Functions-------------------------------------------- */
50
51 #ifdef PKIX_OBJECT_LEAK_TEST
52 /*
53 * FUNCTION: pkix_ErrorGen_Hash
54 * DESCRIPTION:
55 *
56 * Hash function to be used in object leak test hash table.
57 *
58 */
59 PLHashNumber PR_CALLBACK
60 pkix_ErrorGen_Hash (const void *key)
61 {
62 char *str = NULL;
63 PLHashNumber rv = (*(PRUint8*)key) << 5;
64 PRUint32 i, counter = 0;
65 PRUint8 *rvc = (PRUint8 *)&rv;
66
67 while ((str = fnStackNameArr[counter++]) != NULL) {
68 PRUint32 len = strlen(str);
69 for( i = 0; i < len; i++ ) {
70 rvc[ i % sizeof(rv) ] ^= *str;
71 str++;
72 }
73 }
74
75 return rv;
76 }
77
78 #endif /* PKIX_OBJECT_LEAK_TEST */
79
80 /*
81 * FUNCTION: pkix_IsCertSelfIssued
82 * DESCRIPTION:
83 *
84 * Checks whether the Cert pointed to by "cert" is self-issued and stores the
85 * Boolean result at "pSelfIssued". A Cert is considered self-issued if the
86 * Cert's issuer matches the Cert's subject. If the subject or issuer is
87 * not specified, a PKIX_FALSE is returned.
88 *
89 * PARAMETERS:
90 * "cert"
91 * Address of Cert used to determine whether Cert is self-issued.
92 * Must be non-NULL.
93 * "pSelfIssued"
94 * Address where Boolean will be stored. Must be non-NULL.
95 * "plContext"
96 * Platform-specific context pointer.
97 * THREAD SAFETY:
98 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
99 * RETURNS:
100 * Returns NULL if the function succeeds.
101 * Returns a Cert Error if the function fails in a non-fatal way.
102 * Returns a Fatal Error if the function fails in an unrecoverable way.
103 */
104 PKIX_Error *
105 pkix_IsCertSelfIssued(
106 PKIX_PL_Cert *cert,
107 PKIX_Boolean *pSelfIssued,
108 void *plContext)
109 {
110 PKIX_PL_X500Name *subject = NULL;
111 PKIX_PL_X500Name *issuer = NULL;
112
113 PKIX_ENTER(CERT, "pkix_IsCertSelfIssued");
114 PKIX_NULLCHECK_TWO(cert, pSelfIssued);
115
116 PKIX_CHECK(PKIX_PL_Cert_GetSubject(cert, &subject, plContext),
117 PKIX_CERTGETSUBJECTFAILED);
118
119 PKIX_CHECK(PKIX_PL_Cert_GetIssuer(cert, &issuer, plContext),
120 PKIX_CERTGETISSUERFAILED);
121
122 if (subject == NULL || issuer == NULL) {
123 *pSelfIssued = PKIX_FALSE;
124 } else {
125
126 PKIX_CHECK(PKIX_PL_X500Name_Match
127 (subject, issuer, pSelfIssued, plContext),
128 PKIX_X500NAMEMATCHFAILED);
129 }
130
131 cleanup:
132 PKIX_DECREF(subject);
133 PKIX_DECREF(issuer);
134
135 PKIX_RETURN(CERT);
136 }
137
138 /*
139 * FUNCTION: pkix_Throw
140 * DESCRIPTION:
141 *
142 * Creates an Error using the value of "errorCode", the character array
143 * pointed to by "funcName", the character array pointed to by "errorText",
144 * and the Error pointed to by "cause" (if any), and stores it at "pError".
145 *
146 * If "cause" is not NULL and has an errorCode of "PKIX_FATAL_ERROR",
147 * then there is no point creating a new Error object. Rather, we simply
148 * store "cause" at "pError".
149 *
150 * PARAMETERS:
151 * "errorCode"
152 * Value of error code.
153 * "funcName"
154 * Address of EscASCII array representing name of function throwing error.
155 * Must be non-NULL.
156 * "errnum"
157 * PKIX_ERRMSGNUM of error description for new error.
158 * "cause"
159 * Address of Error representing error's cause.
160 * "pError"
161 * Address where object pointer will be stored. Must be non-NULL.
162 * "plContext"
163 * Platform-specific context pointer.
164 * THREAD SAFETY:
165 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
166 * RETURNS:
167 * Returns NULL if the function succeeds.
168 * Returns an Error Error if the function fails in a non-fatal way.
169 * Returns a Fatal Error if the function fails in an unrecoverable way.
170 */
171 PKIX_Error *
172 pkix_Throw(
173 PKIX_ERRORCLASS errorClass,
174 const char *funcName,
175 PKIX_ERRORCODE errorCode,
176 PKIX_ERRORCLASS overrideClass,
177 PKIX_Error *cause,
178 PKIX_Error **pError,
179 void *plContext)
180 {
181 PKIX_Error *error = NULL;
182
183 PKIX_ENTER(ERROR, "pkix_Throw");
184 PKIX_NULLCHECK_TWO(funcName, pError);
185
186 *pError = NULL;
187
188 #ifdef PKIX_OBJECT_LEAK_TEST
189 noErrorState = PKIX_TRUE;
190 if (pkixLog) {
191 #ifdef PKIX_ERROR_DESCRIPTION
192 PR_LOG(pkixLog, 4, ("Error in function \"%s\":\"%s\" with cause \"%s \"\n",
193 funcName, PKIX_ErrorText[errorCode],
194 (cause ? PKIX_ErrorText[cause->errCode] : "null" )));
195 #else
196 PR_LOG(pkixLog, 4, ("Error in function \"%s\": error code \"%d\"\n",
197 funcName, errorCode));
198 #endif /* PKIX_ERROR_DESCRIPTION */
199 PORT_Assert(strcmp(funcName, "PKIX_PL_Object_DecRef"));
200 }
201 #endif /* PKIX_OBJECT_LEAK_TEST */
202
203 /* if cause has error class of PKIX_FATAL_ERROR, return immediately */
204 if (cause) {
205 if (cause->errClass == PKIX_FATAL_ERROR){
206 PKIX_INCREF(cause);
207 *pError = cause;
208 goto cleanup;
209 }
210 }
211
212 if (overrideClass == PKIX_FATAL_ERROR){
213 errorClass = overrideClass;
214 }
215
216 pkixTempResult = PKIX_Error_Create(errorClass, cause, NULL,
217 errorCode, &error, plContext);
218
219 if (!pkixTempResult) {
220 /* Setting plErr error code:
221 * get it from PORT_GetError if it is a leaf error and
222 * default error code does not exist(eq 0) */
223 if (!cause && !error->plErr) {
224 error->plErr = PKIX_PL_GetPLErrorCode();
225 }
226 }
227
228 *pError = error;
229
230 cleanup:
231
232 PKIX_DEBUG_EXIT(ERROR);
233 pkixErrorClass = 0;
234 #ifdef PKIX_OBJECT_LEAK_TEST
235 noErrorState = PKIX_FALSE;
236
237 if (runningLeakTest && fnStackNameArr) {
238 PR_LOG(pkixLog, 5,
239 ("%s%*s<- %s(%d) - %s\n", (errorGenerated ? "*" : " "),
240 stackPosition, " ", fnStackNameArr[stackPosition],
241 stackPosition, myFuncName));
242 fnStackNameArr[stackPosition--] = NULL;
243 }
244 #endif /* PKIX_OBJECT_LEAK_TEST */
245 return (pkixTempResult);
246 }
247
248 /*
249 * FUNCTION: pkix_CheckTypes
250 * DESCRIPTION:
251 *
252 * Checks that the types of the Object pointed to by "first" and the Object
253 * pointed to by "second" are both equal to the value of "type". If they
254 * are not equal, a PKIX_Error is returned.
255 *
256 * PARAMETERS:
257 * "first"
258 * Address of first Object. Must be non-NULL.
259 * "second"
260 * Address of second Object. Must be non-NULL.
261 * "type"
262 * Value of type to check against.
263 * "plContext"
264 * Platform-specific context pointer.
265 * THREAD SAFETY:
266 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
267 * RETURNS:
268 * Returns NULL if the function succeeds.
269 * Returns an Error Error if the function fails in a non-fatal way.
270 * Returns a Fatal Error if the function fails in an unrecoverable way.
271 */
272 PKIX_Error *
273 pkix_CheckTypes(
274 PKIX_PL_Object *first,
275 PKIX_PL_Object *second,
276 PKIX_UInt32 type,
277 void *plContext)
278 {
279 PKIX_UInt32 firstType, secondType;
280
281 PKIX_ENTER(OBJECT, "pkix_CheckTypes");
282 PKIX_NULLCHECK_TWO(first, second);
283
284 PKIX_CHECK(PKIX_PL_Object_GetType(first, &firstType, plContext),
285 PKIX_COULDNOTGETFIRSTOBJECTTYPE);
286
287 PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
288 PKIX_COULDNOTGETSECONDOBJECTTYPE);
289
290 if ((firstType != type)||(firstType != secondType)) {
291 PKIX_ERROR(PKIX_OBJECTTYPESDONOTMATCH);
292 }
293
294 cleanup:
295
296 PKIX_RETURN(OBJECT);
297 }
298
299 /*
300 * FUNCTION: pkix_CheckType
301 * DESCRIPTION:
302 *
303 * Checks that the type of the Object pointed to by "object" is equal to the
304 * value of "type". If it is not equal, a PKIX_Error is returned.
305 *
306 * PARAMETERS:
307 * "object"
308 * Address of Object. Must be non-NULL.
309 * "type"
310 * Value of type to check against.
311 * "plContext"
312 * Platform-specific context pointer.
313 * THREAD SAFETY:
314 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
315 * RETURNS:
316 * Returns NULL if the function succeeds.
317 * Returns an Error Error if the function fails in a non-fatal way.
318 * Returns a Fatal Error if the function fails in an unrecoverable way.
319 */
320 PKIX_Error *
321 pkix_CheckType(
322 PKIX_PL_Object *object,
323 PKIX_UInt32 type,
324 void *plContext)
325 {
326 return (pkix_CheckTypes(object, object, type, plContext));
327 }
328
329 /*
330 * FUNCTION: pkix_hash
331 * DESCRIPTION:
332 *
333 * Computes a hash value for "length" bytes starting at the array of bytes
334 * pointed to by "bytes" and stores the result at "pHash".
335 *
336 * XXX To speed this up, we could probably read 32 bits at a time from
337 * bytes (maybe even 64 bits on some platforms)
338 *
339 * PARAMETERS:
340 * "bytes"
341 * Address of array of bytes to hash. Must be non-NULL.
342 * "length"
343 * Number of bytes to hash.
344 * "pHash"
345 * Address where object pointer will be stored. Must be non-NULL.
346 * "plContext"
347 * Platform-specific context pointer.
348 * THREAD SAFETY:
349 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
350 * RETURNS:
351 * Returns NULL if the function succeeds.
352 * Returns a Fatal Error if the function fails in an unrecoverable way.
353 */
354 PKIX_Error *
355 pkix_hash(
356 const unsigned char *bytes,
357 PKIX_UInt32 length,
358 PKIX_UInt32 *pHash,
359 void *plContext)
360 {
361 PKIX_UInt32 i;
362 PKIX_UInt32 hash;
363
364 PKIX_ENTER(OBJECT, "pkix_hash");
365 if (length != 0) {
366 PKIX_NULLCHECK_ONE(bytes);
367 }
368 PKIX_NULLCHECK_ONE(pHash);
369
370 hash = 0;
371 for (i = 0; i < length; i++) {
372 /* hash = 31 * hash + bytes[i]; */
373 hash = (hash << 5) - hash + bytes[i];
374 }
375
376 *pHash = hash;
377
378 PKIX_RETURN(OBJECT);
379 }
380
381 /*
382 * FUNCTION: pkix_countArray
383 * DESCRIPTION:
384 *
385 * Counts the number of elements in the null-terminated array of pointers
386 * pointed to by "array" and returns the result.
387 *
388 * PARAMETERS
389 * "array"
390 * Address of null-terminated array of pointers.
391 * THREAD SAFETY:
392 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
393 * RETURNS:
394 * Returns the number of elements in the array.
395 */
396 PKIX_UInt32
397 pkix_countArray(void **array)
398 {
399 PKIX_UInt32 count = 0;
400
401 if (array) {
402 while (*array++) {
403 count++;
404 }
405 }
406 return (count);
407 }
408
409 /*
410 * FUNCTION: pkix_duplicateImmutable
411 * DESCRIPTION:
412 *
413 * Convenience callback function used for duplicating immutable objects.
414 * Since the objects can not be modified, this function simply increments the
415 * reference count on the object, and returns a reference to that object.
416 *
417 * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
418 */
419 PKIX_Error *
420 pkix_duplicateImmutable(
421 PKIX_PL_Object *object,
422 PKIX_PL_Object **pNewObject,
423 void *plContext)
424 {
425 PKIX_ENTER(OBJECT, "pkix_duplicateImmutable");
426 PKIX_NULLCHECK_TWO(object, pNewObject);
427
428 PKIX_INCREF(object);
429
430 *pNewObject = object;
431
432 cleanup:
433 PKIX_RETURN(OBJECT);
434 }
435
436 /* --String-Encoding-Conversion-Functions------------------------ */
437
438 /*
439 * FUNCTION: pkix_hex2i
440 * DESCRIPTION:
441 *
442 * Converts hexadecimal character "c" to its integer value and returns result.
443 *
444 * PARAMETERS
445 * "c"
446 * Character to convert to a hex value.
447 * THREAD SAFETY:
448 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
449 * RETURNS:
450 * The hexadecimal value of "c". Otherwise -1. (Unsigned 0xFFFFFFFF).
451 */
452 PKIX_UInt32
453 pkix_hex2i(char c)
454 {
455 if ((c >= '0')&&(c <= '9'))
456 return (c-'0');
457 else if ((c >= 'a')&&(c <= 'f'))
458 return (c-'a'+10);
459 else if ((c >= 'A')&&(c <= 'F'))
460 return (c-'A'+10);
461 else
462 return ((PKIX_UInt32)(-1));
463 }
464
465 /*
466 * FUNCTION: pkix_i2hex
467 * DESCRIPTION:
468 *
469 * Converts integer value "digit" to its ASCII hex value
470 *
471 * PARAMETERS
472 * "digit"
473 * Value of integer to convert to ASCII hex value. Must be 0-15.
474 * THREAD SAFETY:
475 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
476 * RETURNS:
477 * The ASCII hexadecimal value of "digit".
478 */
479 char
480 pkix_i2hex(char digit)
481 {
482 if ((digit >= 0)&&(digit <= 9))
483 return (digit+'0');
484 else if ((digit >= 0xa)&&(digit <= 0xf))
485 return (digit - 10 + 'a');
486 else
487 return (-1);
488 }
489
490 /*
491 * FUNCTION: pkix_isPlaintext
492 * DESCRIPTION:
493 *
494 * Returns whether character "c" is plaintext using EscASCII or EscASCII_Debug
495 * depending on the value of "debug".
496 *
497 * In EscASCII, [01, 7E] except '&' are plaintext.
498 * In EscASCII_Debug [20, 7E] except '&' are plaintext.
499 *
500 * PARAMETERS:
501 * "c"
502 * Character to check.
503 * "debug"
504 * Value of debug flag.
505 * THREAD SAFETY:
506 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
507 * RETURNS:
508 * True if "c" is plaintext.
509 */
510 PKIX_Boolean
511 pkix_isPlaintext(unsigned char c, PKIX_Boolean debug) {
512 return ((c >= 0x01)&&(c <= 0x7E)&&(c != '&')&&(!debug || (c >= 20)));
513 }
514
515 /* --Cache-Functions------------------------ */
516
517 /*
518 * FUNCTION: pkix_CacheCertChain_Lookup
519 * DESCRIPTION:
520 *
521 * Look up CertChain Hash Table for a cached BuildResult based on "targetCert"
522 * and "anchors" as the hash keys. If there is no item to match the key,
523 * PKIX_FALSE is stored at "pFound". If an item is found, its cache time is
524 * compared to "testDate". If expired, the item is removed and PKIX_FALSE is
525 * stored at "pFound". Otherwise, PKIX_TRUE is stored at "pFound" and the
526 * BuildResult is stored at "pBuildResult".
527 * The hashtable is maintained in the following ways:
528 * 1) When creating the hashtable, maximum bucket size can be specified (0 for
529 * unlimited). If items in a bucket reaches its full size, an new addition
530 * will trigger the removal of the old as FIFO sequence.
531 * 2) A PKIX_PL_Date created with current time offset by constant
532 * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
533 * When an item is retrieved, this date is compared against "testDate" for
534 * validity. If comparison indicates this item is expired, the item is
535 * removed from the bucket.
536 *
537 * PARAMETERS:
538 * "targetCert"
539 * Address of Target Cert as key to retrieve this CertChain. Must be
540 * non-NULL.
541 * "anchors"
542 * Address of PKIX_List of "anchors" is used as key to retrive CertChain.
543 * Must be non-NULL.
544 * "testDate"
545 * Address of PKIX_PL_Date for verifying time validity and cache validity.
546 * May be NULL. If testDate is NULL, this cache item will not be out-dated.
547 * "pFound"
548 * Address of PKIX_Boolean indicating valid data is found.
549 * Must be non-NULL.
550 * "pBuildResult"
551 * Address where BuildResult will be stored. Must be non-NULL.
552 * "plContext"
553 * Platform-specific context pointer.
554 * THREAD SAFETY:
555 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
556 * RETURNS:
557 * Returns NULL if the function succeeds.
558 * Returns an Error Error if the function fails in a non-fatal way.
559 * Returns a Fatal Error if the function fails in an unrecoverable way.
560 */
561 PKIX_Error *
562 pkix_CacheCertChain_Lookup(
563 PKIX_PL_Cert* targetCert,
564 PKIX_List* anchors,
565 PKIX_PL_Date *testDate,
566 PKIX_Boolean *pFound,
567 PKIX_BuildResult **pBuildResult,
568 void *plContext)
569 {
570 PKIX_List *cachedValues = NULL;
571 PKIX_List *cachedKeys = NULL;
572 PKIX_Error *cachedCertChainError = NULL;
573 PKIX_PL_Date *cacheValidUntilDate = NULL;
574 PKIX_PL_Date *validityDate = NULL;
575 PKIX_Int32 cmpValidTimeResult = 0;
576 PKIX_Int32 cmpCacheTimeResult = 0;
577
578 PKIX_ENTER(BUILD, "pkix_CacheCertChain_Lookup");
579
580 PKIX_NULLCHECK_FOUR(targetCert, anchors, pFound, pBuildResult);
581
582 *pFound = PKIX_FALSE;
583
584 /* use trust anchors and target cert as hash key */
585
586 PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
587 PKIX_LISTCREATEFAILED);
588
589 PKIX_CHECK(PKIX_List_AppendItem
590 (cachedKeys,
591 (PKIX_PL_Object *)targetCert,
592 plContext),
593 PKIX_LISTAPPENDITEMFAILED);
594
595 PKIX_CHECK(PKIX_List_AppendItem
596 (cachedKeys,
597 (PKIX_PL_Object *)anchors,
598 plContext),
599 PKIX_LISTAPPENDITEMFAILED);
600
601 cachedCertChainError = PKIX_PL_HashTable_Lookup
602 (cachedCertChainTable,
603 (PKIX_PL_Object *) cachedKeys,
604 (PKIX_PL_Object **) &cachedValues,
605 plContext);
606
607 pkix_ccLookupCount++;
608
609 /* retrieve data from hashed value list */
610
611 if (cachedValues != NULL && cachedCertChainError == NULL) {
612
613 PKIX_CHECK(PKIX_List_GetItem
614 (cachedValues,
615 0,
616 (PKIX_PL_Object **) &cacheValidUntilDate,
617 plContext),
618 PKIX_LISTGETITEMFAILED);
619
620 /* check validity time and cache age time */
621 PKIX_CHECK(PKIX_List_GetItem
622 (cachedValues,
623 1,
624 (PKIX_PL_Object **) &validityDate,
625 plContext),
626 PKIX_LISTGETITEMFAILED);
627
628 /* if testDate is not set, this cache item is not out-dated */
629 if (testDate) {
630
631 PKIX_CHECK(PKIX_PL_Object_Compare
632 ((PKIX_PL_Object *)testDate,
633 (PKIX_PL_Object *)cacheValidUntilDate,
634 &cmpCacheTimeResult,
635 plContext),
636 PKIX_OBJECTCOMPARATORFAILED);
637
638 PKIX_CHECK(PKIX_PL_Object_Compare
639 ((PKIX_PL_Object *)testDate,
640 (PKIX_PL_Object *)validityDate,
641 &cmpValidTimeResult,
642 plContext),
643 PKIX_OBJECTCOMPARATORFAILED);
644 }
645
646 /* certs' date are all valid and cache item is not old */
647 if (cmpValidTimeResult <= 0 && cmpCacheTimeResult <=0) {
648
649 PKIX_CHECK(PKIX_List_GetItem
650 (cachedValues,
651 2,
652 (PKIX_PL_Object **) pBuildResult,
653 plContext),
654 PKIX_LISTGETITEMFAILED);
655
656 *pFound = PKIX_TRUE;
657
658 } else {
659
660 pkix_ccRemoveCount++;
661 *pFound = PKIX_FALSE;
662
663 /* out-dated item, remove it from cache */
664 PKIX_CHECK(PKIX_PL_HashTable_Remove
665 (cachedCertChainTable,
666 (PKIX_PL_Object *) cachedKeys,
667 plContext),
668 PKIX_HASHTABLEREMOVEFAILED);
669 }
670 }
671
672 cleanup:
673
674 PKIX_DECREF(cachedValues);
675 PKIX_DECREF(cachedKeys);
676 PKIX_DECREF(cachedCertChainError);
677 PKIX_DECREF(cacheValidUntilDate);
678 PKIX_DECREF(validityDate);
679
680 PKIX_RETURN(BUILD);
681
682 }
683
684 /*
685 * FUNCTION: pkix_CacheCertChain_Remove
686 * DESCRIPTION:
687 *
688 * Remove CertChain Hash Table entry based on "targetCert" and "anchors"
689 * as the hash keys. If there is no item to match the key, no action is
690 * taken.
691 * The hashtable is maintained in the following ways:
692 * 1) When creating the hashtable, maximum bucket size can be specified (0 for
693 * unlimited). If items in a bucket reaches its full size, an new addition
694 * will trigger the removal of the old as FIFO sequence.
695 * 2) A PKIX_PL_Date created with current time offset by constant
696 * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
697 * When an item is retrieved, this date is compared against "testDate" for
698 * validity. If comparison indicates this item is expired, the item is
699 * removed from the bucket.
700 *
701 * PARAMETERS:
702 * "targetCert"
703 * Address of Target Cert as key to retrieve this CertChain. Must be
704 * non-NULL.
705 * "anchors"
706 * Address of PKIX_List of "anchors" is used as key to retrive CertChain.
707 * Must be non-NULL.
708 * "plContext"
709 * Platform-specific context pointer.
710 * THREAD SAFETY:
711 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
712 * RETURNS:
713 * Returns NULL if the function succeeds.
714 * Returns an Error Error if the function fails in a non-fatal way.
715 * Returns a Fatal Error if the function fails in an unrecoverable way.
716 */
717 PKIX_Error *
718 pkix_CacheCertChain_Remove(
719 PKIX_PL_Cert* targetCert,
720 PKIX_List* anchors,
721 void *plContext)
722 {
723 PKIX_List *cachedKeys = NULL;
724
725 PKIX_ENTER(BUILD, "pkix_CacheCertChain_Remove");
726 PKIX_NULLCHECK_TWO(targetCert, anchors);
727
728 /* use trust anchors and target cert as hash key */
729
730 PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
731 PKIX_LISTCREATEFAILED);
732
733 PKIX_CHECK(PKIX_List_AppendItem
734 (cachedKeys,
735 (PKIX_PL_Object *)targetCert,
736 plContext),
737 PKIX_LISTAPPENDITEMFAILED);
738
739 PKIX_CHECK(PKIX_List_AppendItem
740 (cachedKeys,
741 (PKIX_PL_Object *)anchors,
742 plContext),
743 PKIX_LISTAPPENDITEMFAILED);
744
745 PKIX_CHECK_ONLY_FATAL(PKIX_PL_HashTable_Remove
746 (cachedCertChainTable,
747 (PKIX_PL_Object *) cachedKeys,
748 plContext),
749 PKIX_HASHTABLEREMOVEFAILED);
750
751 pkix_ccRemoveCount++;
752
753 cleanup:
754
755 PKIX_DECREF(cachedKeys);
756
757 PKIX_RETURN(BUILD);
758
759 }
760
761 /*
762 * FUNCTION: pkix_CacheCertChain_Add
763 * DESCRIPTION:
764 *
765 * Add a BuildResult to the CertChain Hash Table for a "buildResult" with
766 * "targetCert" and "anchors" as the hash keys.
767 * "validityDate" is the most restricted notAfter date of all Certs in
768 * this CertChain and is verified when this BuildChain is retrieved.
769 * The hashtable is maintained in the following ways:
770 * 1) When creating the hashtable, maximum bucket size can be specified (0 for
771 * unlimited). If items in a bucket reaches its full size, an new addition
772 * will trigger the removal of the old as FIFO sequence.
773 * 2) A PKIX_PL_Date created with current time offset by constant
774 * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
775 * When an item is retrieved, this date is compared against "testDate" for
776 * validity. If comparison indicates this item is expired, the item is
777 * removed from the bucket.
778 *
779 * PARAMETERS:
780 * "targetCert"
781 * Address of Target Cert as key to retrieve this CertChain. Must be
782 * non-NULL.
783 * "anchors"
784 * Address of PKIX_List of "anchors" is used as key to retrive CertChain.
785 * Must be non-NULL.
786 * "validityDate"
787 * Address of PKIX_PL_Date contains the most restriced notAfter time of
788 * all "certs". Must be non-NULL.
789 * Address of PKIX_Boolean indicating valid data is found.
790 * Must be non-NULL.
791 * "buildResult"
792 * Address of BuildResult to be cached. Must be non-NULL.
793 * "plContext"
794 * Platform-specific context pointer.
795 * THREAD SAFETY:
796 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
797 * RETURNS:
798 * Returns NULL if the function succeeds.
799 * Returns an Error Error if the function fails in a non-fatal way.
800 * Returns a Fatal Error if the function fails in an unrecoverable way.
801 */
802 PKIX_Error *
803 pkix_CacheCertChain_Add(
804 PKIX_PL_Cert* targetCert,
805 PKIX_List* anchors,
806 PKIX_PL_Date *validityDate,
807 PKIX_BuildResult *buildResult,
808 void *plContext)
809 {
810 PKIX_List *cachedValues = NULL;
811 PKIX_List *cachedKeys = NULL;
812 PKIX_Error *cachedCertChainError = NULL;
813 PKIX_PL_Date *cacheValidUntilDate = NULL;
814
815 PKIX_ENTER(BUILD, "pkix_CacheCertChain_Add");
816
817 PKIX_NULLCHECK_FOUR(targetCert, anchors, validityDate, buildResult);
818
819 PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
820 PKIX_LISTCREATEFAILED);
821
822 PKIX_CHECK(PKIX_List_AppendItem
823 (cachedKeys, (PKIX_PL_Object *)targetCert, plContext),
824 PKIX_LISTAPPENDITEMFAILED);
825
826 PKIX_CHECK(PKIX_List_AppendItem
827 (cachedKeys, (PKIX_PL_Object *)anchors, plContext),
828 PKIX_LISTAPPENDITEMFAILED);
829
830 PKIX_CHECK(PKIX_List_Create(&cachedValues, plContext),
831 PKIX_LISTCREATEFAILED);
832
833 PKIX_CHECK(PKIX_PL_Date_Create_CurrentOffBySeconds
834 (CACHE_ITEM_PERIOD_SECONDS,
835 &cacheValidUntilDate,
836 plContext),
837 PKIX_DATECREATECURRENTOFFBYSECONDSFAILED);
838
839 PKIX_CHECK(PKIX_List_AppendItem
840 (cachedValues,
841 (PKIX_PL_Object *)cacheValidUntilDate,
842 plContext),
843 PKIX_LISTAPPENDITEMFAILED);
844
845 PKIX_CHECK(PKIX_List_AppendItem
846 (cachedValues, (PKIX_PL_Object *)validityDate, plContext),
847 PKIX_LISTAPPENDITEMFAILED);
848
849 PKIX_CHECK(PKIX_List_AppendItem
850 (cachedValues, (PKIX_PL_Object *)buildResult, plContext),
851 PKIX_LISTAPPENDITEMFAILED);
852
853 cachedCertChainError = PKIX_PL_HashTable_Add
854 (cachedCertChainTable,
855 (PKIX_PL_Object *) cachedKeys,
856 (PKIX_PL_Object *) cachedValues,
857 plContext);
858
859 pkix_ccAddCount++;
860
861 if (cachedCertChainError != NULL) {
862 PKIX_DEBUG("PKIX_PL_HashTable_Add for CertChain skipped: "
863 "entry existed\n");
864 }
865
866 cleanup:
867
868 PKIX_DECREF(cachedValues);
869 PKIX_DECREF(cachedKeys);
870 PKIX_DECREF(cachedCertChainError);
871 PKIX_DECREF(cacheValidUntilDate);
872
873 PKIX_RETURN(BUILD);
874 }
875
876 /*
877 * FUNCTION: pkix_CacheCert_Lookup
878 * DESCRIPTION:
879 *
880 * Look up Cert Hash Table for a cached item based on "store" and Subject in
881 * "certSelParams" as the hash keys and returns values Certs in "pCerts".
882 * If there isn't an item to match the key, a PKIX_FALSE is returned at
883 * "pFound". The item's cache time is verified with "testDate". If out-dated,
884 * this item is removed and PKIX_FALSE is returned at "pFound".
885 * This hashtable is maintained in the following ways:
886 * 1) When creating the hashtable, maximum bucket size can be specified (0 for
887 * unlimited). If items in a bucket reaches its full size, an new addition
888 * will trigger the removal of the old as FIFO sequence.
889 * 2) A PKIX_PL_Date created with current time offset by constant
890 * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
891 * If the CertStore this Cert is from is a trusted one, the cache period is
892 * shorter so cache can be updated more frequently.
893 * When an item is retrieved, this date is compared against "testDate" for
894 * validity. If comparison indicates this item is expired, the item is
895 * removed from the bucket.
896 *
897 * PARAMETERS:
898 * "store"
899 * Address of CertStore as key to retrieve this CertChain. Must be
900 * non-NULL.
901 * "certSelParams"
902 * Address of ComCertSelParams that its subject is used as key to retrieve
903 * this CertChain. Must be non-NULL.
904 * "testDate"
905 * Address of PKIX_PL_Date for verifying time cache validity.
906 * Must be non-NULL. If testDate is NULL, this cache item won't be out
907 * dated.
908 * "pFound"
909 * Address of KPKIX_Boolean indicating valid data is found.
910 * Must be non-NULL.
911 * "pCerts"
912 * Address PKIX_List where the CertChain will be stored. Must be no-NULL.
913 * "plContext"
914 * Platform-specific context pointer.
915 * THREAD SAFETY:
916 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
917 * RETURNS:
918 * Returns NULL if the function succeeds.
919 * Returns an Error Error if the function fails in a non-fatal way.
920 * Returns a Fatal Error if the function fails in an unrecoverable way.
921 */
922 PKIX_Error *
923 pkix_CacheCert_Lookup(
924 PKIX_CertStore *store,
925 PKIX_ComCertSelParams *certSelParams,
926 PKIX_PL_Date *testDate,
927 PKIX_Boolean *pFound,
928 PKIX_List** pCerts,
929 void *plContext)
930 {
931 PKIX_PL_Cert *cert = NULL;
932 PKIX_List *cachedKeys = NULL;
933 PKIX_List *cachedValues = NULL;
934 PKIX_List *cachedCertList = NULL;
935 PKIX_List *selCertList = NULL;
936 PKIX_PL_X500Name *subject = NULL;
937 PKIX_PL_Date *invalidAfterDate = NULL;
938 PKIX_PL_Date *cacheValidUntilDate = NULL;
939 PKIX_CertSelector *certSel = NULL;
940 PKIX_Error *cachedCertError = NULL;
941 PKIX_Error *selectorError = NULL;
942 PKIX_CertSelector_MatchCallback selectorMatch = NULL;
943 PKIX_Int32 cmpValidTimeResult = PKIX_FALSE;
944 PKIX_Int32 cmpCacheTimeResult = 0;
945 PKIX_UInt32 numItems = 0;
946 PKIX_UInt32 i;
947
948 PKIX_ENTER(BUILD, "pkix_CacheCert_Lookup");
949 PKIX_NULLCHECK_TWO(store, certSelParams);
950 PKIX_NULLCHECK_TWO(pFound, pCerts);
951
952 *pFound = PKIX_FALSE;
953
954 PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
955 PKIX_LISTCREATEFAILED);
956
957 PKIX_CHECK(PKIX_List_AppendItem
958 (cachedKeys, (PKIX_PL_Object *)store, plContext),
959 PKIX_LISTAPPENDITEMFAILED);
960
961 PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
962 (certSelParams, &subject, plContext),
963 PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
964
965 PKIX_NULLCHECK_ONE(subject);
966
967 PKIX_CHECK(PKIX_List_AppendItem
968 (cachedKeys, (PKIX_PL_Object *)subject, plContext),
969 PKIX_LISTAPPENDITEMFAILED);
970
971 cachedCertError = PKIX_PL_HashTable_Lookup
972 (cachedCertTable,
973 (PKIX_PL_Object *) cachedKeys,
974 (PKIX_PL_Object **) &cachedValues,
975 plContext);
976 pkix_cLookupCount++;
977
978 if (cachedValues != NULL && cachedCertError == NULL) {
979
980 PKIX_CHECK(PKIX_List_GetItem
981 (cachedValues,
982 0,
983 (PKIX_PL_Object **) &cacheValidUntilDate,
984 plContext),
985 PKIX_LISTGETITEMFAILED);
986
987 if (testDate) {
988 PKIX_CHECK(PKIX_PL_Object_Compare
989 ((PKIX_PL_Object *)testDate,
990 (PKIX_PL_Object *)cacheValidUntilDate,
991 &cmpCacheTimeResult,
992 plContext),
993 PKIX_OBJECTCOMPARATORFAILED);
994 }
995
996 if (cmpCacheTimeResult <= 0) {
997
998 PKIX_CHECK(PKIX_List_GetItem
999 (cachedValues,
1000 1,
1001 (PKIX_PL_Object **) &cachedCertList,
1002 plContext),
1003 PKIX_LISTGETITEMFAILED);
1004
1005 /*
1006 * Certs put on cache satifies only for Subject,
1007 * user selector and ComCertSelParams to filter.
1008 */
1009 PKIX_CHECK(PKIX_CertSelector_Create
1010 (NULL, NULL, &certSel, plContext),
1011 PKIX_CERTSELECTORCREATEFAILED);
1012
1013 PKIX_CHECK(PKIX_CertSelector_SetCommonCertSelectorParams
1014 (certSel, certSelParams, plContext),
1015 PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED);
1016
1017 PKIX_CHECK(PKIX_CertSelector_GetMatchCallback
1018 (certSel, &selectorMatch, plContext),
1019 PKIX_CERTSELECTORGETMATCHCALLBACKFAILED);
1020
1021 PKIX_CHECK(PKIX_List_Create(&selCertList, plContext),
1022 PKIX_LISTCREATEFAILED);
1023
1024 /*
1025 * If any of the Cert on the list is out-dated, invalidate
1026 * this cache item.
1027 */
1028 PKIX_CHECK(PKIX_List_GetLength
1029 (cachedCertList, &numItems, plContext),
1030 PKIX_LISTGETLENGTHFAILED);
1031
1032 for (i = 0; i < numItems; i++){
1033
1034 PKIX_CHECK(PKIX_List_GetItem
1035 (cachedCertList,
1036 i,
1037 (PKIX_PL_Object **)&cert,
1038 plContext),
1039 PKIX_LISTGETITEMFAILED);
1040
1041 PKIX_CHECK(PKIX_PL_Cert_GetValidityNotAfter
1042 (cert, &invalidAfterDate, plContext),
1043 PKIX_CERTGETVALIDITYNOTAFTERFAILED);
1044
1045 if (testDate) {
1046 PKIX_CHECK(PKIX_PL_Object_Compare
1047 ((PKIX_PL_Object *)invalidAfterDate,
1048 (PKIX_PL_Object *)testDate,
1049 &cmpValidTimeResult,
1050 plContext),
1051 PKIX_OBJECTCOMPARATORFAILED);
1052 }
1053
1054 if (cmpValidTimeResult < 0) {
1055
1056 pkix_cRemoveCount++;
1057 *pFound = PKIX_FALSE;
1058
1059 /* one cert is out-dated, remove item from cache */
1060 PKIX_CHECK(PKIX_PL_HashTable_Remove
1061 (cachedCertTable,
1062 (PKIX_PL_Object *) cachedKeys,
1063 plContext),
1064 PKIX_HASHTABLEREMOVEFAILED);
1065 goto cleanup;
1066 }
1067
1068 selectorError = selectorMatch(certSel, cert, plContext);
1069 if (!selectorError){
1070 /* put on the return list */
1071 PKIX_CHECK(PKIX_List_AppendItem
1072 (selCertList,
1073 (PKIX_PL_Object *)cert,
1074 plContext),
1075 PKIX_LISTAPPENDITEMFAILED);
1076 } else {
1077 PKIX_DECREF(selectorError);
1078 }
1079
1080 PKIX_DECREF(cert);
1081 PKIX_DECREF(invalidAfterDate);
1082
1083 }
1084
1085 if (*pFound) {
1086 PKIX_INCREF(selCertList);
1087 *pCerts = selCertList;
1088 }
1089
1090 } else {
1091
1092 pkix_cRemoveCount++;
1093 *pFound = PKIX_FALSE;
1094 /* cache item is out-dated, remove it from cache */
1095 PKIX_CHECK(PKIX_PL_HashTable_Remove
1096 (cachedCertTable,
1097 (PKIX_PL_Object *) cachedKeys,
1098 plContext),
1099 PKIX_HASHTABLEREMOVEFAILED);
1100 }
1101
1102 }
1103
1104 cleanup:
1105
1106 PKIX_DECREF(subject);
1107 PKIX_DECREF(certSel);
1108 PKIX_DECREF(cachedKeys);
1109 PKIX_DECREF(cachedValues);
1110 PKIX_DECREF(cacheValidUntilDate);
1111 PKIX_DECREF(cert);
1112 PKIX_DECREF(cachedCertList);
1113 PKIX_DECREF(selCertList);
1114 PKIX_DECREF(invalidAfterDate);
1115 PKIX_DECREF(cachedCertError);
1116 PKIX_DECREF(selectorError);
1117
1118 PKIX_RETURN(BUILD);
1119 }
1120
1121 /*
1122 * FUNCTION: pkix_CacheCert_Add
1123 * DESCRIPTION:
1124 *
1125 * Add Cert Hash Table for a cached item based on "store" and Subject in
1126 * "certSelParams" as the hash keys and have "certs" as the key value.
1127 * This hashtable is maintained in the following ways:
1128 * 1) When creating the hashtable, maximum bucket size can be specified (0 for
1129 * unlimited). If items in a bucket reaches its full size, an new addition
1130 * will trigger the removal of the old as FIFO sequence.
1131 * 2) A PKIX_PL_Date created with current time offset by constant
1132 * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
1133 * If the CertStore this Cert is from is a trusted one, the cache period is
1134 * shorter so cache can be updated more frequently.
1135 * When an item is retrieved, this date is compared against "testDate" for
1136 * validity. If comparison indicates this item is expired, the item is
1137 * removed from the bucket.
1138 *
1139 * PARAMETERS:
1140 * "store"
1141 * Address of CertStore as key to retrieve this CertChain. Must be
1142 * non-NULL.
1143 * "certSelParams"
1144 * Address of ComCertSelParams that its subject is used as key to retrieve
1145 * this CertChain. Must be non-NULL.
1146 * "certs"
1147 * Address PKIX_List of Certs will be stored. Must be no-NULL.
1148 * "plContext"
1149 * Platform-specific context pointer.
1150 * THREAD SAFETY:
1151 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1152 * RETURNS:
1153 * Returns NULL if the function succeeds.
1154 * Returns an Error Error if the function fails in a non-fatal way.
1155 * Returns a Fatal Error if the function fails in an unrecoverable way.
1156 */
1157 PKIX_Error *
1158 pkix_CacheCert_Add(
1159 PKIX_CertStore *store,
1160 PKIX_ComCertSelParams *certSelParams,
1161 PKIX_List* certs,
1162 void *plContext)
1163 {
1164 PKIX_List *cachedKeys = NULL;
1165 PKIX_List *cachedValues = NULL;
1166 PKIX_PL_Date *cacheValidUntilDate = NULL;
1167 PKIX_PL_X500Name *subject = NULL;
1168 PKIX_Error *cachedCertError = NULL;
1169 PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
1170 PKIX_UInt32 cachePeriod = CACHE_ITEM_PERIOD_SECONDS;
1171 PKIX_UInt32 numCerts = 0;
1172
1173 PKIX_ENTER(BUILD, "pkix_CacheCert_Add");
1174 PKIX_NULLCHECK_THREE(store, certSelParams, certs);
1175
1176 PKIX_CHECK(PKIX_List_GetLength(certs, &numCerts,
1177 plContext),
1178 PKIX_LISTGETLENGTHFAILED);
1179 if (numCerts == 0) {
1180 /* Don't want to add an empty list. */
1181 goto cleanup;
1182 }
1183
1184 PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
1185 PKIX_LISTCREATEFAILED);
1186
1187 PKIX_CHECK(PKIX_List_AppendItem
1188 (cachedKeys, (PKIX_PL_Object *)store, plContext),
1189 PKIX_LISTAPPENDITEMFAILED);
1190
1191 PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
1192 (certSelParams, &subject, plContext),
1193 PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
1194
1195 PKIX_NULLCHECK_ONE(subject);
1196
1197 PKIX_CHECK(PKIX_List_AppendItem
1198 (cachedKeys, (PKIX_PL_Object *)subject, plContext),
1199 PKIX_LISTAPPENDITEMFAILED);
1200
1201 PKIX_CHECK(PKIX_List_Create(&cachedValues, plContext),
1202 PKIX_LISTCREATEFAILED);
1203
1204 PKIX_CHECK(PKIX_CertStore_GetTrustCallback
1205 (store, &trustCallback, plContext),
1206 PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
1207
1208 if (trustCallback) {
1209 cachePeriod = CACHE_TRUST_ITEM_PERIOD_SECONDS;
1210 }
1211
1212 PKIX_CHECK(PKIX_PL_Date_Create_CurrentOffBySeconds
1213 (cachePeriod, &cacheValidUntilDate, plContext),
1214 PKIX_DATECREATECURRENTOFFBYSECONDSFAILED);
1215
1216 PKIX_CHECK(PKIX_List_AppendItem
1217 (cachedValues,
1218 (PKIX_PL_Object *)cacheValidUntilDate,
1219 plContext),
1220 PKIX_LISTAPPENDITEMFAILED);
1221
1222 PKIX_CHECK(PKIX_List_AppendItem
1223 (cachedValues,
1224 (PKIX_PL_Object *)certs,
1225 plContext),
1226 PKIX_LISTAPPENDITEMFAILED);
1227
1228 cachedCertError = PKIX_PL_HashTable_Add
1229 (cachedCertTable,
1230 (PKIX_PL_Object *) cachedKeys,
1231 (PKIX_PL_Object *) cachedValues,
1232 plContext);
1233
1234 pkix_cAddCount++;
1235
1236 if (cachedCertError != NULL) {
1237 PKIX_DEBUG("PKIX_PL_HashTable_Add for Certs skipped: "
1238 "entry existed\n");
1239 }
1240
1241 cleanup:
1242
1243 PKIX_DECREF(subject);
1244 PKIX_DECREF(cachedKeys);
1245 PKIX_DECREF(cachedValues);
1246 PKIX_DECREF(cacheValidUntilDate);
1247 PKIX_DECREF(cachedCertError);
1248
1249 PKIX_RETURN(BUILD);
1250 }
1251
1252 /*
1253 * FUNCTION: pkix_CacheCrlEntry_Lookup
1254 * DESCRIPTION:
1255 *
1256 * Look up CrlEntry Hash Table for a cached item based on "store",
1257 * "certIssuer" and "certSerialNumber" as the hash keys and returns values
1258 * "pCrls". If there isn't an item to match the key, a PKIX_FALSE is
1259 * returned at "pFound".
1260 * This hashtable is maintained in the following way:
1261 * 1) When creating the hashtable, maximum bucket size can be specified (0 for
1262 * unlimited). If items in a bucket reaches its full size, an new addition
1263 * will trigger the removal of the old as FIFO sequence.
1264 *
1265 * PARAMETERS:
1266 * "store"
1267 * Address of CertStore as key to retrieve this CertChain. Must be
1268 * non-NULL.
1269 * "certIssuer"
1270 * Address of X500Name that is used as key to retrieve the CRLEntries.
1271 * Must be non-NULL.
1272 * "certSerialNumber"
1273 * Address of BigInt that is used as key to retrieve the CRLEntries.
1274 * Must be non-NULL.
1275 * "pFound"
1276 * Address of KPKIX_Boolean indicating valid data is found.
1277 * Must be non-NULL.
1278 * "pCrls"
1279 * Address PKIX_List where the CRLEntry will be stored. Must be no-NULL.
1280 * "plContext"
1281 * Platform-specific context pointer.
1282 * THREAD SAFETY:
1283 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1284 * RETURNS:
1285 * Returns NULL if the function succeeds.
1286 * Returns an Error Error if the function fails in a non-fatal way.
1287 * Returns a Fatal Error if the function fails in an unrecoverable way.
1288 */
1289 PKIX_Error *
1290 pkix_CacheCrlEntry_Lookup(
1291 PKIX_CertStore *store,
1292 PKIX_PL_X500Name *certIssuer,
1293 PKIX_PL_BigInt *certSerialNumber,
1294 PKIX_Boolean *pFound,
1295 PKIX_List** pCrls,
1296 void *plContext)
1297 {
1298 PKIX_List *cachedKeys = NULL;
1299 PKIX_List *cachedCrlEntryList = NULL;
1300 PKIX_Error *cachedCrlEntryError = NULL;
1301
1302 PKIX_ENTER(BUILD, "pkix_CacheCrlEntry_Lookup");
1303 PKIX_NULLCHECK_THREE(store, certIssuer, certSerialNumber);
1304 PKIX_NULLCHECK_TWO(pFound, pCrls);
1305
1306 *pFound = PKIX_FALSE;
1307
1308 /* Find CrlEntry(s) by issuer and serial number */
1309
1310 PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
1311 PKIX_LISTCREATEFAILED);
1312
1313 PKIX_CHECK(PKIX_List_AppendItem
1314 (cachedKeys, (PKIX_PL_Object *)store, plContext),
1315 PKIX_LISTAPPENDITEMFAILED);
1316
1317 PKIX_CHECK(PKIX_List_AppendItem
1318 (cachedKeys, (PKIX_PL_Object *)certIssuer, plContext),
1319 PKIX_LISTAPPENDITEMFAILED);
1320
1321 PKIX_CHECK(PKIX_List_AppendItem
1322 (cachedKeys,
1323 (PKIX_PL_Object *)certSerialNumber,
1324 plContext),
1325 PKIX_LISTAPPENDITEMFAILED);
1326
1327 cachedCrlEntryError = PKIX_PL_HashTable_Lookup
1328 (cachedCrlEntryTable,
1329 (PKIX_PL_Object *) cachedKeys,
1330 (PKIX_PL_Object **) &cachedCrlEntryList,
1331 plContext);
1332 pkix_ceLookupCount++;
1333
1334 /*
1335 * We don't need check Date to invalidate this cache item,
1336 * the item is uniquely defined and won't be reverted. Let
1337 * the FIFO for cleaning up.
1338 */
1339
1340 if (cachedCrlEntryList != NULL && cachedCrlEntryError == NULL ) {
1341
1342 PKIX_INCREF(cachedCrlEntryList);
1343 *pCrls = cachedCrlEntryList;
1344
1345 *pFound = PKIX_TRUE;
1346
1347 } else {
1348
1349 *pFound = PKIX_FALSE;
1350 }
1351
1352 cleanup:
1353
1354 PKIX_DECREF(cachedKeys);
1355 PKIX_DECREF(cachedCrlEntryList);
1356 PKIX_DECREF(cachedCrlEntryError);
1357
1358 PKIX_RETURN(BUILD);
1359 }
1360
1361 /*
1362 * FUNCTION: pkix_CacheCrlEntry_Add
1363 * DESCRIPTION:
1364 *
1365 * Look up CrlEntry Hash Table for a cached item based on "store",
1366 * "certIssuer" and "certSerialNumber" as the hash keys and have "pCrls" as
1367 * the hash value. If there isn't an item to match the key, a PKIX_FALSE is
1368 * returned at "pFound".
1369 * This hashtable is maintained in the following way:
1370 * 1) When creating the hashtable, maximum bucket size can be specified (0 for
1371 * unlimited). If items in a bucket reaches its full size, an new addition
1372 * will trigger the removal of the old as FIFO sequence.
1373 *
1374 * PARAMETERS:
1375 * "store"
1376 * Address of CertStore as key to retrieve this CertChain. Must be
1377 * non-NULL.
1378 * "certIssuer"
1379 * Address of X500Name that is used as key to retrieve the CRLEntries.
1380 * Must be non-NULL.
1381 * "certSerialNumber"
1382 * Address of BigInt that is used as key to retrieve the CRLEntries.
1383 * Must be non-NULL.
1384 * "crls"
1385 * Address PKIX_List where the CRLEntry is stored. Must be no-NULL.
1386 * "plContext"
1387 * Platform-specific context pointer.
1388 * THREAD SAFETY:
1389 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1390 * RETURNS:
1391 * Returns NULL if the function succeeds.
1392 * Returns an Error Error if the function fails in a non-fatal way.
1393 * Returns a Fatal Error if the function fails in an unrecoverable way.
1394 */
1395 PKIX_Error *
1396 pkix_CacheCrlEntry_Add(
1397 PKIX_CertStore *store,
1398 PKIX_PL_X500Name *certIssuer,
1399 PKIX_PL_BigInt *certSerialNumber,
1400 PKIX_List* crls,
1401 void *plContext)
1402 {
1403 PKIX_List *cachedKeys = NULL;
1404 PKIX_Error *cachedCrlEntryError = NULL;
1405
1406 PKIX_ENTER(BUILD, "pkix_CacheCrlEntry_Add");
1407 PKIX_NULLCHECK_THREE(store, certIssuer, certSerialNumber);
1408 PKIX_NULLCHECK_ONE(crls);
1409
1410 /* Add CrlEntry(s) by issuer and serial number */
1411
1412 PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
1413 PKIX_LISTCREATEFAILED);
1414
1415 PKIX_CHECK(PKIX_List_AppendItem
1416 (cachedKeys, (PKIX_PL_Object *)store, plContext),
1417 PKIX_LISTAPPENDITEMFAILED);
1418
1419 PKIX_CHECK(PKIX_List_AppendItem
1420 (cachedKeys, (PKIX_PL_Object *)certIssuer, plContext),
1421 PKIX_LISTAPPENDITEMFAILED);
1422
1423 PKIX_CHECK(PKIX_List_AppendItem
1424 (cachedKeys,
1425 (PKIX_PL_Object *)certSerialNumber,
1426 plContext),
1427 PKIX_LISTAPPENDITEMFAILED);
1428
1429 cachedCrlEntryError = PKIX_PL_HashTable_Add
1430 (cachedCrlEntryTable,
1431 (PKIX_PL_Object *) cachedKeys,
1432 (PKIX_PL_Object *) crls,
1433 plContext);
1434 pkix_ceAddCount++;
1435
1436 cleanup:
1437
1438 PKIX_DECREF(cachedKeys);
1439 PKIX_DECREF(cachedCrlEntryError);
1440
1441 PKIX_RETURN(BUILD);
1442 }
1443
1444 #ifdef PKIX_OBJECT_LEAK_TEST
1445
1446 /* TEST_START_FN and testStartFnStackPosition define at what state
1447 * of the stack the object leak testing should begin. The condition
1448 * in pkix_CheckForGeneratedError works the following way: do leak
1449 * testing if at position testStartFnStackPosition in stack array
1450 * (fnStackNameArr) we have called function TEST_START_FN.
1451 * Note, that stack array get filled only when executing libpkix
1452 * functions.
1453 * */
1454 #define TEST_START_FN "PKIX_BuildChain"
1455
1456 PKIX_Error*
1457 pkix_CheckForGeneratedError(PKIX_StdVars * stdVars,
1458 PKIX_ERRORCLASS errClass,
1459 char * fnName,
1460 PKIX_Boolean *errSetFlag,
1461 void * plContext)
1462 {
1463 PKIX_Error *genErr = NULL;
1464 PKIX_UInt32 pos = 0;
1465 PKIX_UInt32 strLen = 0;
1466
1467 if (fnName) {
1468 if (fnStackNameArr[testStartFnStackPosition] == NULL ||
1469 strcmp(fnStackNameArr[testStartFnStackPosition], TEST_START_FN)
1470 ) {
1471 /* return with out error if not with in boundary */
1472 return NULL;
1473 }
1474 if (!strcmp(fnName, TEST_START_FN)) {
1475 *errSetFlag = PKIX_TRUE;
1476 noErrorState = PKIX_FALSE;
1477 errorGenerated = PKIX_FALSE;
1478 }
1479 }
1480
1481 if (noErrorState || errorGenerated) return NULL;
1482
1483 if (fnName && (
1484 !strcmp(fnName, "PKIX_PL_Object_DecRef") ||
1485 !strcmp(fnName, "PKIX_PL_Object_Unlock") ||
1486 !strcmp(fnName, "pkix_UnlockObject") ||
1487 !strcmp(fnName, "pkix_Throw") ||
1488 !strcmp(fnName, "pkix_trace_dump_cert") ||
1489 !strcmp(fnName, "PKIX_PL_Free"))) {
1490 /* do not generate error for this functions */
1491 noErrorState = PKIX_TRUE;
1492 *errSetFlag = PKIX_TRUE;
1493 return NULL;
1494 }
1495
1496 if (PL_HashTableLookup(fnInvTable, &fnStackInvCountArr[stackPosition - 1])) {
1497 return NULL;
1498 }
1499
1500 PL_HashTableAdd(fnInvTable, &fnStackInvCountArr[stackPosition - 1], nonNullV alue);
1501 errorGenerated = PKIX_TRUE;
1502 noErrorState = PKIX_TRUE;
1503 genErr = PKIX_DoThrow(stdVars, errClass, PKIX_MEMLEAKGENERATEDERROR,
1504 errClass, plContext);
1505 while(fnStackNameArr[pos]) {
1506 strLen += PORT_Strlen(fnStackNameArr[pos++]) + 1;
1507 }
1508 strLen += 1; /* end of line. */
1509 pos = 0;
1510 errorFnStackString = PORT_ZAlloc(strLen);
1511 while(fnStackNameArr[pos]) {
1512 strcat(errorFnStackString, "/");
1513 strcat(errorFnStackString, fnStackNameArr[pos++]);
1514 }
1515 noErrorState = PKIX_FALSE;
1516
1517 return genErr;
1518 }
1519 #endif /* PKIX_OBJECT_LEAK_TEST */
OLDNEW
« no previous file with comments | « nss/lib/libpkix/pkix/util/pkix_tools.h ('k') | nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698