/security/nss/lib/libpkix/pkix/util/pkix_tools.c
C | 1552 lines | 777 code | 205 blank | 570 comment | 79 complexity | 93549263314e07b9f59400cc6c8a245c MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, AGPL-1.0, LGPL-2.1, BSD-3-Clause, GPL-2.0, JSON, Apache-2.0, 0BSD
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the PKIX-C library.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are
- * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
- *
- * Contributor(s):
- * Sun Microsystems, Inc.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
- /*
- * pkix_tools.c
- *
- * Private Utility Functions
- *
- */
- #include "pkix_tools.h"
- #define CACHE_ITEM_PERIOD_SECONDS (3600) /* one hour */
- /*
- * This cahce period is only for CertCache. A Cert from a trusted CertStore
- * should be checked more frequently for update new arrival, etc.
- */
- #define CACHE_TRUST_ITEM_PERIOD_SECONDS (CACHE_ITEM_PERIOD_SECONDS/10)
- extern PKIX_PL_HashTable *cachedCertChainTable;
- extern PKIX_PL_HashTable *cachedCertTable;
- extern PKIX_PL_HashTable *cachedCrlEntryTable;
- /* Following variables are used to checked cache hits - can be taken out */
- extern int pkix_ccAddCount;
- extern int pkix_ccLookupCount;
- extern int pkix_ccRemoveCount;
- extern int pkix_cAddCount;
- extern int pkix_cLookupCount;
- extern int pkix_cRemoveCount;
- extern int pkix_ceAddCount;
- extern int pkix_ceLookupCount;
- #ifdef PKIX_OBJECT_LEAK_TEST
- /* Following variables are used for object leak test */
- char *nonNullValue = "Non Empty Value";
- PKIX_Boolean noErrorState = PKIX_TRUE;
- PKIX_Boolean runningLeakTest;
- PKIX_Boolean errorGenerated;
- PKIX_UInt32 stackPosition;
- PKIX_UInt32 *fnStackInvCountArr;
- char **fnStackNameArr;
- PLHashTable *fnInvTable;
- PKIX_UInt32 testStartFnStackPosition;
- char *errorFnStackString;
- #endif /* PKIX_OBJECT_LEAK_TEST */
- /* --Private-Functions-------------------------------------------- */
- #ifdef PKIX_OBJECT_LEAK_TEST
- /*
- * FUNCTION: pkix_ErrorGen_Hash
- * DESCRIPTION:
- *
- * Hash function to be used in object leak test hash table.
- *
- */
- PLHashNumber PR_CALLBACK
- pkix_ErrorGen_Hash (const void *key)
- {
- char *str = NULL;
- PLHashNumber rv = (*(PRUint8*)key) << 5;
- PRUint32 i, counter = 0;
- PRUint8 *rvc = (PRUint8 *)&rv;
- while ((str = fnStackNameArr[counter++]) != NULL) {
- PRUint32 len = strlen(str);
- for( i = 0; i < len; i++ ) {
- rvc[ i % sizeof(rv) ] ^= *str;
- str++;
- }
- }
- return rv;
- }
- #endif /* PKIX_OBJECT_LEAK_TEST */
- /*
- * FUNCTION: pkix_IsCertSelfIssued
- * DESCRIPTION:
- *
- * Checks whether the Cert pointed to by "cert" is self-issued and stores the
- * Boolean result at "pSelfIssued". A Cert is considered self-issued if the
- * Cert's issuer matches the Cert's subject. If the subject or issuer is
- * not specified, a PKIX_FALSE is returned.
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert used to determine whether Cert is self-issued.
- * Must be non-NULL.
- * "pSelfIssued"
- * Address where Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- PKIX_Error *
- pkix_IsCertSelfIssued(
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pSelfIssued,
- void *plContext)
- {
- PKIX_PL_X500Name *subject = NULL;
- PKIX_PL_X500Name *issuer = NULL;
- PKIX_ENTER(CERT, "pkix_IsCertSelfIssued");
- PKIX_NULLCHECK_TWO(cert, pSelfIssued);
- PKIX_CHECK(PKIX_PL_Cert_GetSubject(cert, &subject, plContext),
- PKIX_CERTGETSUBJECTFAILED);
- PKIX_CHECK(PKIX_PL_Cert_GetIssuer(cert, &issuer, plContext),
- PKIX_CERTGETISSUERFAILED);
- if (subject == NULL || issuer == NULL) {
- *pSelfIssued = PKIX_FALSE;
- } else {
- PKIX_CHECK(PKIX_PL_X500Name_Match
- (subject, issuer, pSelfIssued, plContext),
- PKIX_X500NAMEMATCHFAILED);
- }
- cleanup:
- PKIX_DECREF(subject);
- PKIX_DECREF(issuer);
- PKIX_RETURN(CERT);
- }
- /*
- * FUNCTION: pkix_Throw
- * DESCRIPTION:
- *
- * Creates an Error using the value of "errorCode", the character array
- * pointed to by "funcName", the character array pointed to by "errorText",
- * and the Error pointed to by "cause" (if any), and stores it at "pError".
- *
- * If "cause" is not NULL and has an errorCode of "PKIX_FATAL_ERROR",
- * then there is no point creating a new Error object. Rather, we simply
- * store "cause" at "pError".
- *
- * PARAMETERS:
- * "errorCode"
- * Value of error code.
- * "funcName"
- * Address of EscASCII array representing name of function throwing error.
- * Must be non-NULL.
- * "errnum"
- * PKIX_ERRMSGNUM of error description for new error.
- * "cause"
- * Address of Error representing error's cause.
- * "pError"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- PKIX_Error *
- pkix_Throw(
- PKIX_ERRORCLASS errorClass,
- const char *funcName,
- PKIX_ERRORCODE errorCode,
- PKIX_ERRORCLASS overrideClass,
- PKIX_Error *cause,
- PKIX_Error **pError,
- void *plContext)
- {
- PKIX_Error *error = NULL;
- PKIX_ENTER(ERROR, "pkix_Throw");
- PKIX_NULLCHECK_TWO(funcName, pError);
- *pError = NULL;
- #ifdef PKIX_OBJECT_LEAK_TEST
- noErrorState = PKIX_TRUE;
- if (pkixLog) {
- #ifdef PKIX_ERROR_DESCRIPTION
- PR_LOG(pkixLog, 4, ("Error in function \"%s\":\"%s\" with cause \"%s\"\n",
- funcName, PKIX_ErrorText[errorCode],
- (cause ? PKIX_ErrorText[cause->errCode] : "null")));
- #else
- PR_LOG(pkixLog, 4, ("Error in function \"%s\": error code \"%d\"\n",
- funcName, errorCode));
- #endif /* PKIX_ERROR_DESCRIPTION */
- PORT_Assert(strcmp(funcName, "PKIX_PL_Object_DecRef"));
- }
- #endif /* PKIX_OBJECT_LEAK_TEST */
- /* if cause has error class of PKIX_FATAL_ERROR, return immediately */
- if (cause) {
- if (cause->errClass == PKIX_FATAL_ERROR){
- PKIX_INCREF(cause);
- *pError = cause;
- goto cleanup;
- }
- }
-
- if (overrideClass == PKIX_FATAL_ERROR){
- errorClass = overrideClass;
- }
- pkixTempResult = PKIX_Error_Create(errorClass, cause, NULL,
- errorCode, &error, plContext);
-
- if (!pkixTempResult) {
- /* Setting plErr error code:
- * get it from PORT_GetError if it is a leaf error and
- * default error code does not exist(eq 0) */
- if (!cause && !error->plErr) {
- error->plErr = PKIX_PL_GetPLErrorCode();
- }
- }
- *pError = error;
- cleanup:
- PKIX_DEBUG_EXIT(ERROR);
- pkixErrorClass = 0;
- #ifdef PKIX_OBJECT_LEAK_TEST
- noErrorState = PKIX_FALSE;
- if (runningLeakTest && fnStackNameArr) {
- PR_LOG(pkixLog, 5,
- ("%s%*s<- %s(%d) - %s\n", (errorGenerated ? "*" : " "),
- stackPosition, " ", fnStackNameArr[stackPosition],
- stackPosition, myFuncName));
- fnStackNameArr[stackPosition--] = NULL;
- }
- #endif /* PKIX_OBJECT_LEAK_TEST */
- return (pkixTempResult);
- }
- /*
- * FUNCTION: pkix_CheckTypes
- * DESCRIPTION:
- *
- * Checks that the types of the Object pointed to by "first" and the Object
- * pointed to by "second" are both equal to the value of "type". If they
- * are not equal, a PKIX_Error is returned.
- *
- * PARAMETERS:
- * "first"
- * Address of first Object. Must be non-NULL.
- * "second"
- * Address of second Object. Must be non-NULL.
- * "type"
- * Value of type to check against.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- PKIX_Error *
- pkix_CheckTypes(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_UInt32 type,
- void *plContext)
- {
- PKIX_UInt32 firstType, secondType;
- PKIX_ENTER(OBJECT, "pkix_CheckTypes");
- PKIX_NULLCHECK_TWO(first, second);
- PKIX_CHECK(PKIX_PL_Object_GetType(first, &firstType, plContext),
- PKIX_COULDNOTGETFIRSTOBJECTTYPE);
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETSECONDOBJECTTYPE);
- if ((firstType != type)||(firstType != secondType)) {
- PKIX_ERROR(PKIX_OBJECTTYPESDONOTMATCH);
- }
- cleanup:
- PKIX_RETURN(OBJECT);
- }
- /*
- * FUNCTION: pkix_CheckType
- * DESCRIPTION:
- *
- * Checks that the type of the Object pointed to by "object" is equal to the
- * value of "type". If it is not equal, a PKIX_Error is returned.
- *
- * PARAMETERS:
- * "object"
- * Address of Object. Must be non-NULL.
- * "type"
- * Value of type to check against.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- PKIX_Error *
- pkix_CheckType(
- PKIX_PL_Object *object,
- PKIX_UInt32 type,
- void *plContext)
- {
- return (pkix_CheckTypes(object, object, type, plContext));
- }
- /*
- * FUNCTION: pkix_hash
- * DESCRIPTION:
- *
- * Computes a hash value for "length" bytes starting at the array of bytes
- * pointed to by "bytes" and stores the result at "pHash".
- *
- * XXX To speed this up, we could probably read 32 bits at a time from
- * bytes (maybe even 64 bits on some platforms)
- *
- * PARAMETERS:
- * "bytes"
- * Address of array of bytes to hash. Must be non-NULL.
- * "length"
- * Number of bytes to hash.
- * "pHash"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- PKIX_Error *
- pkix_hash(
- const unsigned char *bytes,
- PKIX_UInt32 length,
- PKIX_UInt32 *pHash,
- void *plContext)
- {
- PKIX_UInt32 i;
- PKIX_UInt32 hash;
- PKIX_ENTER(OBJECT, "pkix_hash");
- if (length != 0) {
- PKIX_NULLCHECK_ONE(bytes);
- }
- PKIX_NULLCHECK_ONE(pHash);
- hash = 0;
- for (i = 0; i < length; i++) {
- /* hash = 31 * hash + bytes[i]; */
- hash = (hash << 5) - hash + bytes[i];
- }
- *pHash = hash;
- PKIX_RETURN(OBJECT);
- }
- /*
- * FUNCTION: pkix_countArray
- * DESCRIPTION:
- *
- * Counts the number of elements in the null-terminated array of pointers
- * pointed to by "array" and returns the result.
- *
- * PARAMETERS
- * "array"
- * Address of null-terminated array of pointers.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns the number of elements in the array.
- */
- PKIX_UInt32
- pkix_countArray(void **array)
- {
- PKIX_UInt32 count = 0;
- if (array) {
- while (*array++) {
- count++;
- }
- }
- return (count);
- }
- /*
- * FUNCTION: pkix_duplicateImmutable
- * DESCRIPTION:
- *
- * Convenience callback function used for duplicating immutable objects.
- * Since the objects can not be modified, this function simply increments the
- * reference count on the object, and returns a reference to that object.
- *
- * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
- */
- PKIX_Error *
- pkix_duplicateImmutable(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
- {
- PKIX_ENTER(OBJECT, "pkix_duplicateImmutable");
- PKIX_NULLCHECK_TWO(object, pNewObject);
- PKIX_INCREF(object);
- *pNewObject = object;
- cleanup:
- PKIX_RETURN(OBJECT);
- }
- /* --String-Encoding-Conversion-Functions------------------------ */
- /*
- * FUNCTION: pkix_hex2i
- * DESCRIPTION:
- *
- * Converts hexadecimal character "c" to its integer value and returns result.
- *
- * PARAMETERS
- * "c"
- * Character to convert to a hex value.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * The hexadecimal value of "c". Otherwise -1. (Unsigned 0xFFFFFFFF).
- */
- PKIX_UInt32
- pkix_hex2i(char c)
- {
- if ((c >= '0')&&(c <= '9'))
- return (c-'0');
- else if ((c >= 'a')&&(c <= 'f'))
- return (c-'a'+10);
- else if ((c >= 'A')&&(c <= 'F'))
- return (c-'A'+10);
- else
- return ((PKIX_UInt32)(-1));
- }
- /*
- * FUNCTION: pkix_i2hex
- * DESCRIPTION:
- *
- * Converts integer value "digit" to its ASCII hex value
- *
- * PARAMETERS
- * "digit"
- * Value of integer to convert to ASCII hex value. Must be 0-15.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * The ASCII hexadecimal value of "digit".
- */
- char
- pkix_i2hex(char digit)
- {
- if ((digit >= 0)&&(digit <= 9))
- return (digit+'0');
- else if ((digit >= 0xa)&&(digit <= 0xf))
- return (digit - 10 + 'a');
- else
- return (-1);
- }
- /*
- * FUNCTION: pkix_isPlaintext
- * DESCRIPTION:
- *
- * Returns whether character "c" is plaintext using EscASCII or EscASCII_Debug
- * depending on the value of "debug".
- *
- * In EscASCII, [01, 7E] except '&' are plaintext.
- * In EscASCII_Debug [20, 7E] except '&' are plaintext.
- *
- * PARAMETERS:
- * "c"
- * Character to check.
- * "debug"
- * Value of debug flag.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * True if "c" is plaintext.
- */
- PKIX_Boolean
- pkix_isPlaintext(unsigned char c, PKIX_Boolean debug) {
- return ((c >= 0x01)&&(c <= 0x7E)&&(c != '&')&&(!debug || (c >= 20)));
- }
- /* --Cache-Functions------------------------ */
- /*
- * FUNCTION: pkix_CacheCertChain_Lookup
- * DESCRIPTION:
- *
- * Look up CertChain Hash Table for a cached BuildResult based on "targetCert"
- * and "anchors" as the hash keys. If there is no item to match the key,
- * PKIX_FALSE is stored at "pFound". If an item is found, its cache time is
- * compared to "testDate". If expired, the item is removed and PKIX_FALSE is
- * stored at "pFound". Otherwise, PKIX_TRUE is stored at "pFound" and the
- * BuildResult is stored at "pBuildResult".
- * The hashtable is maintained in the following ways:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- * 2) A PKIX_PL_Date created with current time offset by constant
- * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
- * When an item is retrieved, this date is compared against "testDate" for
- * validity. If comparison indicates this item is expired, the item is
- * removed from the bucket.
- *
- * PARAMETERS:
- * "targetCert"
- * Address of Target Cert as key to retrieve this CertChain. Must be
- * non-NULL.
- * "anchors"
- * Address of PKIX_List of "anchors" is used as key to retrive CertChain.
- * Must be non-NULL.
- * "testDate"
- * Address of PKIX_PL_Date for verifying time validity and cache validity.
- * May be NULL. If testDate is NULL, this cache item will not be out-dated.
- * "pFound"
- * Address of PKIX_Boolean indicating valid data is found.
- * Must be non-NULL.
- * "pBuildResult"
- * Address where BuildResult will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- PKIX_Error *
- pkix_CacheCertChain_Lookup(
- PKIX_PL_Cert* targetCert,
- PKIX_List* anchors,
- PKIX_PL_Date *testDate,
- PKIX_Boolean *pFound,
- PKIX_BuildResult **pBuildResult,
- void *plContext)
- {
- PKIX_List *cachedValues = NULL;
- PKIX_List *cachedKeys = NULL;
- PKIX_Error *cachedCertChainError = NULL;
- PKIX_PL_Date *cacheValidUntilDate = NULL;
- PKIX_PL_Date *validityDate = NULL;
- PKIX_Int32 cmpValidTimeResult = 0;
- PKIX_Int32 cmpCacheTimeResult = 0;
- PKIX_ENTER(BUILD, "pkix_CacheCertChain_Lookup");
- PKIX_NULLCHECK_FOUR(targetCert, anchors, pFound, pBuildResult);
- *pFound = PKIX_FALSE;
- /* use trust anchors and target cert as hash key */
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys,
- (PKIX_PL_Object *)targetCert,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys,
- (PKIX_PL_Object *)anchors,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- cachedCertChainError = PKIX_PL_HashTable_Lookup
- (cachedCertChainTable,
- (PKIX_PL_Object *) cachedKeys,
- (PKIX_PL_Object **) &cachedValues,
- plContext);
- pkix_ccLookupCount++;
- /* retrieve data from hashed value list */
- if (cachedValues != NULL && cachedCertChainError == NULL) {
- PKIX_CHECK(PKIX_List_GetItem
- (cachedValues,
- 0,
- (PKIX_PL_Object **) &cacheValidUntilDate,
- plContext),
- PKIX_LISTGETITEMFAILED);
- /* check validity time and cache age time */
- PKIX_CHECK(PKIX_List_GetItem
- (cachedValues,
- 1,
- (PKIX_PL_Object **) &validityDate,
- plContext),
- PKIX_LISTGETITEMFAILED);
- /* if testDate is not set, this cache item is not out-dated */
- if (testDate) {
- PKIX_CHECK(PKIX_PL_Object_Compare
- ((PKIX_PL_Object *)testDate,
- (PKIX_PL_Object *)cacheValidUntilDate,
- &cmpCacheTimeResult,
- plContext),
- PKIX_OBJECTCOMPARATORFAILED);
- PKIX_CHECK(PKIX_PL_Object_Compare
- ((PKIX_PL_Object *)testDate,
- (PKIX_PL_Object *)validityDate,
- &cmpValidTimeResult,
- plContext),
- PKIX_OBJECTCOMPARATORFAILED);
- }
- /* certs' date are all valid and cache item is not old */
- if (cmpValidTimeResult <= 0 && cmpCacheTimeResult <=0) {
- PKIX_CHECK(PKIX_List_GetItem
- (cachedValues,
- 2,
- (PKIX_PL_Object **) pBuildResult,
- plContext),
- PKIX_LISTGETITEMFAILED);
- *pFound = PKIX_TRUE;
- } else {
- pkix_ccRemoveCount++;
- *pFound = PKIX_FALSE;
- /* out-dated item, remove it from cache */
- PKIX_CHECK(PKIX_PL_HashTable_Remove
- (cachedCertChainTable,
- (PKIX_PL_Object *) cachedKeys,
- plContext),
- PKIX_HASHTABLEREMOVEFAILED);
- }
- }
- cleanup:
- PKIX_DECREF(cachedValues);
- PKIX_DECREF(cachedKeys);
- PKIX_DECREF(cachedCertChainError);
- PKIX_DECREF(cacheValidUntilDate);
- PKIX_DECREF(validityDate);
- PKIX_RETURN(BUILD);
- }
- /*
- * FUNCTION: pkix_CacheCertChain_Remove
- * DESCRIPTION:
- *
- * Remove CertChain Hash Table entry based on "targetCert" and "anchors"
- * as the hash keys. If there is no item to match the key, no action is
- * taken.
- * The hashtable is maintained in the following ways:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- * 2) A PKIX_PL_Date created with current time offset by constant
- * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
- * When an item is retrieved, this date is compared against "testDate" for
- * validity. If comparison indicates this item is expired, the item is
- * removed from the bucket.
- *
- * PARAMETERS:
- * "targetCert"
- * Address of Target Cert as key to retrieve this CertChain. Must be
- * non-NULL.
- * "anchors"
- * Address of PKIX_List of "anchors" is used as key to retrive CertChain.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- PKIX_Error *
- pkix_CacheCertChain_Remove(
- PKIX_PL_Cert* targetCert,
- PKIX_List* anchors,
- void *plContext)
- {
- PKIX_List *cachedKeys = NULL;
- PKIX_ENTER(BUILD, "pkix_CacheCertChain_Remove");
- PKIX_NULLCHECK_TWO(targetCert, anchors);
- /* use trust anchors and target cert as hash key */
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys,
- (PKIX_PL_Object *)targetCert,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys,
- (PKIX_PL_Object *)anchors,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK_ONLY_FATAL(PKIX_PL_HashTable_Remove
- (cachedCertChainTable,
- (PKIX_PL_Object *) cachedKeys,
- plContext),
- PKIX_HASHTABLEREMOVEFAILED);
- pkix_ccRemoveCount++;
- cleanup:
- PKIX_DECREF(cachedKeys);
- PKIX_RETURN(BUILD);
- }
- /*
- * FUNCTION: pkix_CacheCertChain_Add
- * DESCRIPTION:
- *
- * Add a BuildResult to the CertChain Hash Table for a "buildResult" with
- * "targetCert" and "anchors" as the hash keys.
- * "validityDate" is the most restricted notAfter date of all Certs in
- * this CertChain and is verified when this BuildChain is retrieved.
- * The hashtable is maintained in the following ways:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- * 2) A PKIX_PL_Date created with current time offset by constant
- * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
- * When an item is retrieved, this date is compared against "testDate" for
- * validity. If comparison indicates this item is expired, the item is
- * removed from the bucket.
- *
- * PARAMETERS:
- * "targetCert"
- * Address of Target Cert as key to retrieve this CertChain. Must be
- * non-NULL.
- * "anchors"
- * Address of PKIX_List of "anchors" is used as key to retrive CertChain.
- * Must be non-NULL.
- * "validityDate"
- * Address of PKIX_PL_Date contains the most restriced notAfter time of
- * all "certs". Must be non-NULL.
- * Address of PKIX_Boolean indicating valid data is found.
- * Must be non-NULL.
- * "buildResult"
- * Address of BuildResult to be cached. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- PKIX_Error *
- pkix_CacheCertChain_Add(
- PKIX_PL_Cert* targetCert,
- PKIX_List* anchors,
- PKIX_PL_Date *validityDate,
- PKIX_BuildResult *buildResult,
- void *plContext)
- {
- PKIX_List *cachedValues = NULL;
- PKIX_List *cachedKeys = NULL;
- PKIX_Error *cachedCertChainError = NULL;
- PKIX_PL_Date *cacheValidUntilDate = NULL;
- PKIX_ENTER(BUILD, "pkix_CacheCertChain_Add");
- PKIX_NULLCHECK_FOUR(targetCert, anchors, validityDate, buildResult);
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)targetCert, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)anchors, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_List_Create(&cachedValues, plContext),
- PKIX_LISTCREATEFAILED);
- PKIX_CHECK(PKIX_PL_Date_Create_CurrentOffBySeconds
- (CACHE_ITEM_PERIOD_SECONDS,
- &cacheValidUntilDate,
- plContext),
- PKIX_DATECREATECURRENTOFFBYSECONDSFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedValues,
- (PKIX_PL_Object *)cacheValidUntilDate,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedValues, (PKIX_PL_Object *)validityDate, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedValues, (PKIX_PL_Object *)buildResult, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- cachedCertChainError = PKIX_PL_HashTable_Add
- (cachedCertChainTable,
- (PKIX_PL_Object *) cachedKeys,
- (PKIX_PL_Object *) cachedValues,
- plContext);
- pkix_ccAddCount++;
- if (cachedCertChainError != NULL) {
- PKIX_DEBUG("PKIX_PL_HashTable_Add for CertChain skipped: "
- "entry existed\n");
- }
- cleanup:
- PKIX_DECREF(cachedValues);
- PKIX_DECREF(cachedKeys);
- PKIX_DECREF(cachedCertChainError);
- PKIX_DECREF(cacheValidUntilDate);
- PKIX_RETURN(BUILD);
- }
- /*
- * FUNCTION: pkix_CacheCert_Lookup
- * DESCRIPTION:
- *
- * Look up Cert Hash Table for a cached item based on "store" and Subject in
- * "certSelParams" as the hash keys and returns values Certs in "pCerts".
- * If there isn't an item to match the key, a PKIX_FALSE is returned at
- * "pFound". The item's cache time is verified with "testDate". If out-dated,
- * this item is removed and PKIX_FALSE is returned at "pFound".
- * This hashtable is maintained in the following ways:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- * 2) A PKIX_PL_Date created with current time offset by constant
- * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
- * If the CertStore this Cert is from is a trusted one, the cache period is
- * shorter so cache can be updated more frequently.
- * When an item is retrieved, this date is compared against "testDate" for
- * validity. If comparison indicates this item is expired, the item is
- * removed from the bucket.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore as key to retrieve this CertChain. Must be
- * non-NULL.
- * "certSelParams"
- * Address of ComCertSelParams that its subject is used as key to retrieve
- * this CertChain. Must be non-NULL.
- * "testDate"
- * Address of PKIX_PL_Date for verifying time cache validity.
- * Must be non-NULL. If testDate is NULL, this cache item won't be out
- * dated.
- * "pFound"
- * Address of KPKIX_Boolean indicating valid data is found.
- * Must be non-NULL.
- * "pCerts"
- * Address PKIX_List where the CertChain will be stored. Must be no-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- PKIX_Error *
- pkix_CacheCert_Lookup(
- PKIX_CertStore *store,
- PKIX_ComCertSelParams *certSelParams,
- PKIX_PL_Date *testDate,
- PKIX_Boolean *pFound,
- PKIX_List** pCerts,
- void *plContext)
- {
- PKIX_PL_Cert *cert = NULL;
- PKIX_List *cachedKeys = NULL;
- PKIX_List *cachedValues = NULL;
- PKIX_List *cachedCertList = NULL;
- PKIX_List *selCertList = NULL;
- PKIX_PL_X500Name *subject = NULL;
- PKIX_PL_Date *invalidAfterDate = NULL;
- PKIX_PL_Date *cacheValidUntilDate = NULL;
- PKIX_CertSelector *certSel = NULL;
- PKIX_Error *cachedCertError = NULL;
- PKIX_Error *selectorError = NULL;
- PKIX_CertSelector_MatchCallback selectorMatch = NULL;
- PKIX_Int32 cmpValidTimeResult = PKIX_FALSE;
- PKIX_Int32 cmpCacheTimeResult = 0;
- PKIX_UInt32 numItems = 0;
- PKIX_UInt32 i;
- PKIX_ENTER(BUILD, "pkix_CacheCert_Lookup");
- PKIX_NULLCHECK_TWO(store, certSelParams);
- PKIX_NULLCHECK_TWO(pFound, pCerts);
- *pFound = PKIX_FALSE;
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)store, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
- (certSelParams, &subject, plContext),
- PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
- PKIX_NULLCHECK_ONE(subject);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)subject, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- cachedCertError = PKIX_PL_HashTable_Lookup
- (cachedCertTable,
- (PKIX_PL_Object *) cachedKeys,
- (PKIX_PL_Object **) &cachedValues,
- plContext);
- pkix_cLookupCount++;
- if (cachedValues != NULL && cachedCertError == NULL) {
- PKIX_CHECK(PKIX_List_GetItem
- (cachedValues,
- 0,
- (PKIX_PL_Object **) &cacheValidUntilDate,
- plContext),
- PKIX_LISTGETITEMFAILED);
- if (testDate) {
- PKIX_CHECK(PKIX_PL_Object_Compare
- ((PKIX_PL_Object *)testDate,
- (PKIX_PL_Object *)cacheValidUntilDate,
- &cmpCacheTimeResult,
- plContext),
- PKIX_OBJECTCOMPARATORFAILED);
- }
- if (cmpCacheTimeResult <= 0) {
- PKIX_CHECK(PKIX_List_GetItem
- (cachedValues,
- 1,
- (PKIX_PL_Object **) &cachedCertList,
- plContext),
- PKIX_LISTGETITEMFAILED);
- /*
- * Certs put on cache satifies only for Subject,
- * user selector and ComCertSelParams to filter.
- */
- PKIX_CHECK(PKIX_CertSelector_Create
- (NULL, NULL, &certSel, plContext),
- PKIX_CERTSELECTORCREATEFAILED);
- PKIX_CHECK(PKIX_CertSelector_SetCommonCertSelectorParams
- (certSel, certSelParams, plContext),
- PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED);
- PKIX_CHECK(PKIX_CertSelector_GetMatchCallback
- (certSel, &selectorMatch, plContext),
- PKIX_CERTSELECTORGETMATCHCALLBACKFAILED);
- PKIX_CHECK(PKIX_List_Create(&selCertList, plContext),
- PKIX_LISTCREATEFAILED);
- /*
- * If any of the Cert on the list is out-dated, invalidate
- * this cache item.
- */
- PKIX_CHECK(PKIX_List_GetLength
- (cachedCertList, &numItems, plContext),
- PKIX_LISTGETLENGTHFAILED);
- for (i = 0; i < numItems; i++){
- PKIX_CHECK(PKIX_List_GetItem
- (cachedCertList,
- i,
- (PKIX_PL_Object **)&cert,
- plContext),
- PKIX_LISTGETITEMFAILED);
- PKIX_CHECK(PKIX_PL_Cert_GetValidityNotAfter
- (cert, &invalidAfterDate, plContext),
- PKIX_CERTGETVALIDITYNOTAFTERFAILED);
- if (testDate) {
- PKIX_CHECK(PKIX_PL_Object_Compare
- ((PKIX_PL_Object *)invalidAfterDate,
- (PKIX_PL_Object *)testDate,
- &cmpValidTimeResult,
- plContext),
- PKIX_OBJECTCOMPARATORFAILED);
- }
- if (cmpValidTimeResult < 0) {
- pkix_cRemoveCount++;
- *pFound = PKIX_FALSE;
- /* one cert is out-dated, remove item from cache */
- PKIX_CHECK(PKIX_PL_HashTable_Remove
- (cachedCertTable,
- (PKIX_PL_Object *) cachedKeys,
- plContext),
- PKIX_HASHTABLEREMOVEFAILED);
- goto cleanup;
- }
- selectorError = selectorMatch(certSel, cert, plContext);
- if (!selectorError){
- /* put on the return list */
- PKIX_CHECK(PKIX_List_AppendItem
- (selCertList,
- (PKIX_PL_Object *)cert,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- } else {
- PKIX_DECREF(selectorError);
- }
- PKIX_DECREF(cert);
- PKIX_DECREF(invalidAfterDate);
- }
- if (*pFound) {
- PKIX_INCREF(selCertList);
- *pCerts = selCertList;
- }
- } else {
- pkix_cRemoveCount++;
- *pFound = PKIX_FALSE;
- /* cache item is out-dated, remove it from cache */
- PKIX_CHECK(PKIX_PL_HashTable_Remove
- (cachedCertTable,
- (PKIX_PL_Object *) cachedKeys,
- plContext),
- PKIX_HASHTABLEREMOVEFAILED);
- }
- }
- cleanup:
- PKIX_DECREF(subject);
- PKIX_DECREF(certSel);
- PKIX_DECREF(cachedKeys);
- PKIX_DECREF(cachedValues);
- PKIX_DECREF(cacheValidUntilDate);
- PKIX_DECREF(cert);
- PKIX_DECREF(cachedCertList);
- PKIX_DECREF(selCertList);
- PKIX_DECREF(invalidAfterDate);
- PKIX_DECREF(cachedCertError);
- PKIX_DECREF(selectorError);
- PKIX_RETURN(BUILD);
- }
- /*
- * FUNCTION: pkix_CacheCert_Add
- * DESCRIPTION:
- *
- * Add Cert Hash Table for a cached item based on "store" and Subject in
- * "certSelParams" as the hash keys and have "certs" as the key value.
- * This hashtable is maintained in the following ways:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- * 2) A PKIX_PL_Date created with current time offset by constant
- * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
- * If the CertStore this Cert is from is a trusted one, the cache period is
- * shorter so cache can be updated more frequently.
- * When an item is retrieved, this date is compared against "testDate" for
- * validity. If comparison indicates this item is expired, the item is
- * removed from the bucket.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore as key to retrieve this CertChain. Must be
- * non-NULL.
- * "certSelParams"
- * Address of ComCertSelParams that its subject is used as key to retrieve
- * this CertChain. Must be non-NULL.
- * "certs"
- * Address PKIX_List of Certs will be stored. Must be no-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- PKIX_Error *
- pkix_CacheCert_Add(
- PKIX_CertStore *store,
- PKIX_ComCertSelParams *certSelParams,
- PKIX_List* certs,
- void *plContext)
- {
- PKIX_List *cachedKeys = NULL;
- PKIX_List *cachedValues = NULL;
- PKIX_PL_Date *cacheValidUntilDate = NULL;
- PKIX_PL_X500Name *subject = NULL;
- PKIX_Error *cachedCertError = NULL;
- PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
- PKIX_UInt32 cachePeriod = CACHE_ITEM_PERIOD_SECONDS;
- PKIX_UInt32 numCerts = 0;
- PKIX_ENTER(BUILD, "pkix_CacheCert_Add");
- PKIX_NULLCHECK_THREE(store, certSelParams, certs);
- PKIX_CHECK(PKIX_List_GetLength(certs, &numCerts,
- plContext),
- PKIX_LISTGETLENGTHFAILED);
- if (numCerts == 0) {
- /* Don't want to add an empty list. */
- goto cleanup;
- }
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)store, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
- (certSelParams, &subject, plContext),
- PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
- PKIX_NULLCHECK_ONE(subject);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)subject, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_List_Create(&cachedValues, plContext),
- PKIX_LISTCREATEFAILED);
- PKIX_CHECK(PKIX_CertStore_GetTrustCallback
- (store, &trustCallback, plContext),
- PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
- if (trustCallback) {
- cachePeriod = CACHE_TRUST_ITEM_PERIOD_SECONDS;
- }
- PKIX_CHECK(PKIX_PL_Date_Create_CurrentOffBySeconds
- (cachePeriod, &cacheValidUntilDate, plContext),
- PKIX_DATECREATECURRENTOFFBYSECONDSFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedValues,
- (PKIX_PL_Object *)cacheValidUntilDate,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedValues,
- (PKIX_PL_Object *)certs,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- cachedCertError = PKIX_PL_HashTable_Add
- (cachedCertTable,
- (PKIX_PL_Object *) cachedKeys,
- (PKIX_PL_Object *) cachedValues,
- plContext);
- pkix_cAddCount++;
- if (cachedCertError != NULL) {
- PKIX_DEBUG("PKIX_PL_HashTable_Add for Certs skipped: "
- "entry existed\n");
- }
- cleanup:
- PKIX_DECREF(subject);
- PKIX_DECREF(cachedKeys);
- PKIX_DECREF(cachedValues);
- PKIX_DECREF(cacheValidUntilDate);
- PKIX_DECREF(cachedCertError);
- PKIX_RETURN(BUILD);
- }
- /*
- * FUNCTION: pkix_CacheCrlEntry_Lookup
- * DESCRIPTION:
- *
- * Look up CrlEntry Hash Table for a cached item based on "store",
- * "certIssuer" and "certSerialNumber" as the hash keys and returns values
- * "pCrls". If there isn't an item to match the key, a PKIX_FALSE is
- * returned at "pFound".
- * This hashtable is maintained in the following way:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore as key to retrieve this CertChain. Must be
- * non-NULL.
- * "certIssuer"
- * Address of X500Name that is used as key to retrieve the CRLEntries.
- * Must be non-NULL.
- * "certSerialNumber"
- * Address of BigInt that is used as key to retrieve the CRLEntries.
- * Must be non-NULL.
- * "pFound"
- * Address of KPKIX_Boolean indicating valid data is found.
- * Must be non-NULL.
- * "pCrls"
- * Address PKIX_List where the CRLEntry will be stored. Must be no-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- PKIX_Error *
- pkix_CacheCrlEntry_Lookup(
- PKIX_CertStore *store,
- PKIX_PL_X500Name *certIssuer,
- PKIX_PL_BigInt *certSerialNumber,
- PKIX_Boolean *pFound,
- PKIX_List** pCrls,
- void *plContext)
- {
- PKIX_List *cachedKeys = NULL;
- PKIX_List *cachedCrlEntryList = NULL;
- PKIX_Error *cachedCrlEntryError = NULL;
- PKIX_ENTER(BUILD, "pkix_CacheCrlEntry_Lookup");
- PKIX_NULLCHECK_THREE(store, certIssuer, certSerialNumber);
- PKIX_NULLCHECK_TWO(pFound, pCrls);
- *pFound = PKIX_FALSE;
- /* Find CrlEntry(s) by issuer and serial number */
-
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)store, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)certIssuer, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys,
- (PKIX_PL_Object *)certSerialNumber,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- cachedCrlEntryError = PKIX_PL_HashTable_Lookup
- (cachedCrlEntryTable,
- (PKIX_PL_Object *) cachedKeys,
- (PKIX_PL_Object **) &cachedCrlEntryList,
- plContext);
- pkix_ceLookupCount++;
- /*
- * We don't need check Date to invalidate this cache item,
- * the item is uniquely defined and won't be reverted. Let
- * the FIFO for cleaning up.
- */
- if (cachedCrlEntryList != NULL && cachedCrlEntryError == NULL ) {
- PKIX_INCREF(cachedCrlEntryList);
- *pCrls = cachedCrlEntryList;
- *pFound = PKIX_TRUE;
- } else {
- *pFound = PKIX_FALSE;
- }
- cleanup:
- PKIX_DECREF(cachedKeys);
- PKIX_DECREF(cachedCrlEntryList);
- PKIX_DECREF(cachedCrlEntryError);
- PKIX_RETURN(BUILD);
- }
- /*
- * FUNCTION: pkix_CacheCrlEntry_Add
- * DESCRIPTION:
- *
- * Look up CrlEntry Hash Table for a cached item based on "store",
- * "certIssuer" and "certSerialNumber" as the hash keys and have "pCrls" as
- * the hash value. If there isn't an item to match the key, a PKIX_FALSE is
- * returned at "pFound".
- * This hashtable is maintained in the following way:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore as key to retrieve this CertChain. Must be
- * non-NULL.
- * "certIssuer"
- * Address of X500Name that is used as key to retrieve the CRLEntries.
- * Must be non-NULL.
- * "certSerialNumber"
- * Address of BigInt that is used as key to retrieve the CRLEntries.
- * Must be non-NULL.
- * "crls"
- * Address PKIX_List where the CRLEntry is stored. Must be no-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- PKIX_Error *
- pkix_CacheCrlEntry_Add(
- PKIX_CertStore *store,
- PKIX_PL_X500Name *certIssuer,
- PKIX_PL_BigInt *certSerialNumber,
- PKIX_List* crls,
- void *plContext)
- {
- PKIX_List *cachedKeys = NULL;
- PKIX_Error *cachedCrlEntryError = NULL;
- PKIX_ENTER(BUILD, "pkix_CacheCrlEntry_Add");
- PKIX_NULLCHECK_THREE(store, certIssuer, certSerialNumber);
- PKIX_NULLCHECK_ONE(crls);
- /* Add CrlEntry(s) by issuer and serial number */
-
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)store, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)certIssuer, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys,
- (PKIX_PL_Object *)certSerialNumber,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- cachedCrlEntryError = PKIX_PL_HashTable_Add
- (cachedCrlEntryTable,
- (PKIX_PL_Object *) cachedKeys,
- (PKIX_PL_Object *) crls,
- plContext);
- pkix_ceAddCount++;
- cleanup:
- PKIX_DECREF(cachedKeys);
- PKIX_DECREF(cachedCrlEntryError);
- PKIX_RETURN(BUILD);
- }
- #ifdef PKIX_OBJECT_LEAK_TEST
- /* TEST_START_FN and testStartFnStackPosition define at what state
- * of the stack the object leak testing should begin. The condition
- * in pkix_CheckForGeneratedError works the following way: do leak
- * testing if at position testStartFnStackPosition in stack array
- * (fnStackNameArr) we have called function TEST_START_FN.
- * Note, that stack array get filled only when executing libpkix
- * functions.
- * */
- #define TEST_START_FN "PKIX_BuildChain"
- PKIX_Error*
- pkix_CheckForGeneratedError(PKIX_StdVars * stdVars,
- PKIX_ERRORCLASS errClass,
- char * fnName,
- PKIX_Boolean *errSetFlag,
- void * plContext)
- {
- PKIX_Error *genErr = NULL;
- PKIX_UInt32 pos = 0;
- PKIX_UInt32 strLen = 0;
- if (fnName) {
- if (fnStackNameArr[testStartFnStackPosition] == NULL ||
- strcmp(fnStackNameArr[testStartFnStackPosition], TEST_START_FN)
- ) {
- /* return with out error if not with in boundary */
- return NULL;
- }
- if (!strcmp(fnName, TEST_START_FN)) {
- *errSetFlag = PKIX_TRUE;
- noErrorState = PKIX_FALSE;
- errorGenerated = PKIX_FALSE;
- }
- }
- if (noErrorState || errorGenerated) return NULL;
- if (fnName && (
- !strcmp(fnName, "PKIX_PL_Object_DecRef") ||
- !strcmp(fnName, "PKIX_PL_Object_Unlock") ||
- !strcmp(fnName, "pkix_UnlockObject") ||
- !strcmp(fnName, "pkix_Throw") ||
- !strcmp(fnName, "pkix_trace_dump_cert") ||
- !strcmp(fnName, "PKIX_PL_Free"))) {
- /* do not generate error for this functions */
- noErrorState = PKIX_TRUE;
- *errSetFlag = PKIX_TRUE;
- return NULL;
- }
- if (PL_HashTableLookup(fnInvTable, &fnStackInvCountArr[stackPosition - 1])) {
- return NULL;
- }
- PL_HashTableAdd(fnInvTable, &fnStackInvCountArr[stackPosition - 1], nonNullValue);
- errorGenerated = PKIX_TRUE;
- noErrorState = PKIX_TRUE;
- genErr = PKIX_DoThrow(stdVars, errClass, PKIX_MEMLEAKGENERATEDERROR,
- errClass, plContext);
- while(fnStackNameArr[pos]) {
- strLen += PORT_Strlen(fnStackNameArr[pos++]) + 1;
- }
- strLen += 1; /* end of line. */
- pos = 0;
- errorFnStackString = PORT_ZAlloc(strLen);
- while(fnStackNameArr[pos]) {
- strcat(errorFnStackString, "/");
- strcat(errorFnStackString, fnStackNameArr[pos++]);
- }
- noErrorState = PKIX_FALSE;
-
- return genErr;
- }
- #endif /* PKIX_OBJECT_LEAK_TEST */