michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: /* michael@0: * pkix_lifecycle.c michael@0: * michael@0: * Top level initialize and shutdown functions michael@0: * michael@0: */ michael@0: michael@0: #include "pkix_lifecycle.h" michael@0: michael@0: static PKIX_Boolean pkixIsInitialized; michael@0: michael@0: /* Lock used by Logger - is reentrant by the same thread */ michael@0: extern PKIX_PL_MonitorLock *pkixLoggerLock; michael@0: michael@0: /* michael@0: * Following pkix_* variables are for debugging purpose. They should be taken michael@0: * out eventually. The purpose is to verify cache tables usage (via debugger). michael@0: */ michael@0: int pkix_ccAddCount = 0; michael@0: int pkix_ccLookupCount = 0; michael@0: int pkix_ccRemoveCount = 0; michael@0: int pkix_cAddCount = 0; michael@0: int pkix_cLookupCount = 0; michael@0: int pkix_cRemoveCount = 0; michael@0: int pkix_ceAddCount = 0; michael@0: int pkix_ceLookupCount = 0; michael@0: michael@0: PKIX_PL_HashTable *cachedCrlSigTable = NULL; michael@0: PKIX_PL_HashTable *cachedCertSigTable = NULL; michael@0: PKIX_PL_HashTable *cachedCertChainTable = NULL; michael@0: PKIX_PL_HashTable *cachedCertTable = NULL; michael@0: PKIX_PL_HashTable *cachedCrlEntryTable = NULL; michael@0: PKIX_PL_HashTable *aiaConnectionCache = NULL; michael@0: PKIX_PL_HashTable *httpSocketCache = NULL; michael@0: michael@0: extern PKIX_List *pkixLoggers; michael@0: extern PKIX_List *pkixLoggersErrors; michael@0: extern PKIX_List *pkixLoggersDebugTrace; michael@0: michael@0: /* --Public-Functions--------------------------------------------- */ michael@0: michael@0: /* michael@0: * FUNCTION: PKIX_Initialize (see comments in pkix.h) michael@0: */ michael@0: PKIX_Error * michael@0: PKIX_Initialize( michael@0: PKIX_Boolean platformInitNeeded, michael@0: PKIX_UInt32 desiredMajorVersion, michael@0: PKIX_UInt32 minDesiredMinorVersion, michael@0: PKIX_UInt32 maxDesiredMinorVersion, michael@0: PKIX_UInt32 *pActualMinorVersion, michael@0: void **pPlContext) michael@0: { michael@0: void *plContext = NULL; michael@0: michael@0: PKIX_ENTER(LIFECYCLE, "PKIX_Initialize"); michael@0: PKIX_NULLCHECK_ONE(pPlContext); michael@0: michael@0: /* michael@0: * If we are called a second time other than in the situation handled michael@0: * above, we return a positive status. michael@0: */ michael@0: if (pkixIsInitialized){ michael@0: /* Already initialized */ michael@0: PKIX_RETURN(LIFECYCLE); michael@0: } michael@0: michael@0: PKIX_CHECK(PKIX_PL_Initialize michael@0: (platformInitNeeded, PKIX_FALSE, &plContext), michael@0: PKIX_INITIALIZEFAILED); michael@0: michael@0: *pPlContext = plContext; michael@0: michael@0: if (desiredMajorVersion != PKIX_MAJOR_VERSION){ michael@0: PKIX_ERROR(PKIX_MAJORVERSIONSDONTMATCH); michael@0: } michael@0: michael@0: if ((minDesiredMinorVersion > PKIX_MINOR_VERSION) || michael@0: (maxDesiredMinorVersion < PKIX_MINOR_VERSION)){ michael@0: PKIX_ERROR(PKIX_MINORVERSIONNOTBETWEENDESIREDMINANDMAX); michael@0: } michael@0: michael@0: *pActualMinorVersion = PKIX_MINOR_VERSION; michael@0: michael@0: /* Create Cache Tables michael@0: * Do not initialize hash tables for object leak test */ michael@0: #if !defined(PKIX_OBJECT_LEAK_TEST) michael@0: PKIX_CHECK(PKIX_PL_HashTable_Create michael@0: (32, 0, &cachedCertSigTable, plContext), michael@0: PKIX_HASHTABLECREATEFAILED); michael@0: michael@0: PKIX_CHECK(PKIX_PL_HashTable_Create michael@0: (32, 0, &cachedCrlSigTable, plContext), michael@0: PKIX_HASHTABLECREATEFAILED); michael@0: michael@0: PKIX_CHECK(PKIX_PL_HashTable_Create michael@0: (32, 10, &cachedCertChainTable, plContext), michael@0: PKIX_HASHTABLECREATEFAILED); michael@0: michael@0: PKIX_CHECK(PKIX_PL_HashTable_Create michael@0: (32, 10, &cachedCertTable, plContext), michael@0: PKIX_HASHTABLECREATEFAILED); michael@0: michael@0: PKIX_CHECK(PKIX_PL_HashTable_Create michael@0: (32, 10, &cachedCrlEntryTable, plContext), michael@0: PKIX_HASHTABLECREATEFAILED); michael@0: michael@0: PKIX_CHECK(PKIX_PL_HashTable_Create michael@0: (5, 5, &aiaConnectionCache, plContext), michael@0: PKIX_HASHTABLECREATEFAILED); michael@0: michael@0: #ifdef PKIX_SOCKETCACHE michael@0: PKIX_CHECK(PKIX_PL_HashTable_Create michael@0: (5, 5, &httpSocketCache, plContext), michael@0: PKIX_HASHTABLECREATEFAILED); michael@0: #endif michael@0: if (pkixLoggerLock == NULL) { michael@0: PKIX_CHECK(PKIX_PL_MonitorLock_Create michael@0: (&pkixLoggerLock, plContext), michael@0: PKIX_MONITORLOCKCREATEFAILED); michael@0: } michael@0: #else michael@0: fnInvTable = PL_NewHashTable(0, pkix_ErrorGen_Hash, michael@0: PL_CompareValues, michael@0: PL_CompareValues, NULL, NULL); michael@0: if (!fnInvTable) { michael@0: PKIX_ERROR(PKIX_HASHTABLECREATEFAILED); michael@0: } michael@0: michael@0: fnStackNameArr = PORT_ZNewArray(char*, MAX_STACK_DEPTH); michael@0: if (!fnStackNameArr) { michael@0: PKIX_ERROR(PKIX_HASHTABLECREATEFAILED); michael@0: } michael@0: michael@0: fnStackInvCountArr = PORT_ZNewArray(PKIX_UInt32, MAX_STACK_DEPTH); michael@0: if (!fnStackInvCountArr) { michael@0: PKIX_ERROR(PKIX_HASHTABLECREATEFAILED); michael@0: } michael@0: #endif /* PKIX_OBJECT_LEAK_TEST */ michael@0: michael@0: pkixIsInitialized = PKIX_TRUE; michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_RETURN(LIFECYCLE); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: PKIX_Shutdown (see comments in pkix.h) michael@0: */ michael@0: PKIX_Error * michael@0: PKIX_Shutdown(void *plContext) michael@0: { michael@0: PKIX_List *savedPkixLoggers = NULL; michael@0: PKIX_List *savedPkixLoggersErrors = NULL; michael@0: PKIX_List *savedPkixLoggersDebugTrace = NULL; michael@0: michael@0: PKIX_ENTER(LIFECYCLE, "PKIX_Shutdown"); michael@0: michael@0: if (!pkixIsInitialized){ michael@0: /* The library was not initialized */ michael@0: PKIX_RETURN(LIFECYCLE); michael@0: } michael@0: michael@0: pkixIsInitialized = PKIX_FALSE; michael@0: michael@0: if (pkixLoggers) { michael@0: savedPkixLoggers = pkixLoggers; michael@0: savedPkixLoggersErrors = pkixLoggersErrors; michael@0: savedPkixLoggersDebugTrace = pkixLoggersDebugTrace; michael@0: pkixLoggers = NULL; michael@0: pkixLoggersErrors = NULL; michael@0: pkixLoggersDebugTrace = NULL; michael@0: PKIX_DECREF(savedPkixLoggers); michael@0: PKIX_DECREF(savedPkixLoggersErrors); michael@0: PKIX_DECREF(savedPkixLoggersDebugTrace); michael@0: } michael@0: PKIX_DECREF(pkixLoggerLock); michael@0: michael@0: /* Destroy Cache Tables */ michael@0: PKIX_DECREF(cachedCertSigTable); michael@0: PKIX_DECREF(cachedCrlSigTable); michael@0: PKIX_DECREF(cachedCertChainTable); michael@0: PKIX_DECREF(cachedCertTable); michael@0: PKIX_DECREF(cachedCrlEntryTable); michael@0: PKIX_DECREF(aiaConnectionCache); michael@0: PKIX_DECREF(httpSocketCache); michael@0: michael@0: /* Clean up any temporary errors that happened during shutdown */ michael@0: if (pkixErrorList) { michael@0: PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorList, plContext); michael@0: pkixErrorList = NULL; michael@0: } michael@0: michael@0: PKIX_CHECK(PKIX_PL_Shutdown(plContext), michael@0: PKIX_SHUTDOWNFAILED); michael@0: michael@0: #ifdef PKIX_OBJECT_LEAK_TEST michael@0: PORT_Free(fnStackInvCountArr); michael@0: PORT_Free(fnStackNameArr); michael@0: PL_HashTableDestroy(fnInvTable); michael@0: #endif michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_RETURN(LIFECYCLE); michael@0: }