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