diff options
Diffstat (limited to 'security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c')
-rwxr-xr-x | security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c new file mode 100755 index 000000000..70ed25d72 --- /dev/null +++ b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c @@ -0,0 +1,279 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* + * pkix_pl_lifecycle.c + * + * Lifecycle Functions for the PKIX PL library. + * + */ + +#include "pkix_pl_lifecycle.h" + +PKIX_Boolean pkix_pl_initialized = PKIX_FALSE; +pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; +PRLock *classTableLock; +PRLogModuleInfo *pkixLog = NULL; + +/* + * PKIX_ALLOC_ERROR is a special error object hard-coded into the + * pkix_error.o object file. It is thrown if system memory cannot be + * allocated. PKIX_ALLOC_ERROR is immutable. + * IncRef, DecRef, and Settor functions cannot be called. + */ + +/* Keep this structure definition here for its is used only once here */ +struct PKIX_Alloc_Error_ObjectStruct { + PKIX_PL_Object header; + PKIX_Error error; +}; +typedef struct PKIX_Alloc_Error_ObjectStruct PKIX_Alloc_Error_Object; + +static const PKIX_Alloc_Error_Object pkix_Alloc_Error_Data = { + { + PKIX_MAGIC_HEADER, /* PRUint64 magicHeader */ + (PKIX_UInt32)PKIX_ERROR_TYPE, /* PKIX_UInt32 type */ + (PKIX_UInt32)1, /* PKIX_UInt32 references */ + /* Warning! Cannot Ref Count with NULL lock */ + (void *)0, /* PRLock *lock */ + (PKIX_PL_String *)0, /* PKIX_PL_String *stringRep */ + (PKIX_UInt32)0, /* PKIX_UInt32 hashcode */ + (PKIX_Boolean)PKIX_FALSE, /* PKIX_Boolean hashcodeCached */ + }, { + (PKIX_ERRORCODE)0, /* PKIX_ERRORCODE errCode; */ + (PKIX_ERRORCLASS)PKIX_FATAL_ERROR,/* PKIX_ERRORCLASS errClass */ + (PKIX_UInt32)SEC_ERROR_LIBPKIX_INTERNAL, /* default PL Error Code */ + (PKIX_Error *)0, /* PKIX_Error *cause */ + (PKIX_PL_Object *)0, /* PKIX_PL_Object *info */ + } +}; + +PKIX_Error* PKIX_ALLOC_ERROR(void) +{ + return (PKIX_Error *)&pkix_Alloc_Error_Data.error; +} + +#ifdef PKIX_OBJECT_LEAK_TEST +SECStatus +pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable) +{ + int typeCounter = 0; + + for (; typeCounter < PKIX_NUMTYPES; typeCounter++) { + pkix_ClassTable_Entry *entry = &systemClasses[typeCounter]; + + objCountTable[typeCounter] = entry->objCounter; + } + + return SECSuccess; +} +#endif /* PKIX_OBJECT_LEAK_TEST */ + + +PKIX_UInt32 +pkix_pl_lifecycle_ObjectLeakCheck(int *initObjCountTable) +{ + unsigned int typeCounter = 0; + PKIX_UInt32 numObjects = 0; + char classNameBuff[128]; + char *className = NULL; + + for (; typeCounter < PKIX_NUMTYPES; typeCounter++) { + pkix_ClassTable_Entry *entry = &systemClasses[typeCounter]; + PKIX_UInt32 objCountDiff = entry->objCounter; + + if (initObjCountTable) { + PKIX_UInt32 initialCount = initObjCountTable[typeCounter]; + objCountDiff = (entry->objCounter > initialCount) ? + entry->objCounter - initialCount : 0; + } + + numObjects += objCountDiff; + + if (!pkixLog || !objCountDiff) { + continue; + } + className = entry->description; + if (!className) { + className = classNameBuff; + PR_snprintf(className, 128, "Unknown(ref %d)", + entry->objCounter); + } + + PR_LOG(pkixLog, 1, ("Class %s leaked %d objects of " + "size %d bytes, total = %d bytes\n", className, + objCountDiff, entry->typeObjectSize, + objCountDiff * entry->typeObjectSize)); + } + + return numObjects; +} + +/* + * PKIX_PL_Initialize (see comments in pkix_pl_system.h) + */ +PKIX_Error * +PKIX_PL_Initialize( + PKIX_Boolean platformInitNeeded, + PKIX_Boolean useArenas, + void **pPlContext) +{ + void *plContext = NULL; + + PKIX_ENTER(OBJECT, "PKIX_PL_Initialize"); + + /* + * This function can only be called once. If it has already been + * called, we return a positive status. + */ + if (pkix_pl_initialized) { + PKIX_RETURN(OBJECT); + } + + classTableLock = PR_NewLock(); + if (classTableLock == NULL) { + return PKIX_ALLOC_ERROR(); + } + + if (PR_GetEnvSecure("NSS_STRICT_SHUTDOWN")) { + pkixLog = PR_NewLogModule("pkix"); + } + /* + * Register Object, it is the base object of all other objects. + */ + pkix_pl_Object_RegisterSelf(plContext); + + /* + * Register Error and String, since they will be needed if + * there is a problem in registering any other type. + */ + pkix_Error_RegisterSelf(plContext); + pkix_pl_String_RegisterSelf(plContext); + + + /* + * We register all other system types + * (They don't need to be in order, but it's + * easier to keep track of what types are registered + * if we register them in the same order as their + * numbers, defined in pkixt.h. + */ + pkix_pl_BigInt_RegisterSelf(plContext); /* 1-10 */ + pkix_pl_ByteArray_RegisterSelf(plContext); + pkix_pl_HashTable_RegisterSelf(plContext); + pkix_List_RegisterSelf(plContext); + pkix_Logger_RegisterSelf(plContext); + pkix_pl_Mutex_RegisterSelf(plContext); + pkix_pl_OID_RegisterSelf(plContext); + pkix_pl_RWLock_RegisterSelf(plContext); + + pkix_pl_CertBasicConstraints_RegisterSelf(plContext); /* 11-20 */ + pkix_pl_Cert_RegisterSelf(plContext); + pkix_pl_CRL_RegisterSelf(plContext); + pkix_pl_CRLEntry_RegisterSelf(plContext); + pkix_pl_Date_RegisterSelf(plContext); + pkix_pl_GeneralName_RegisterSelf(plContext); + pkix_pl_CertNameConstraints_RegisterSelf(plContext); + pkix_pl_PublicKey_RegisterSelf(plContext); + pkix_TrustAnchor_RegisterSelf(plContext); + + pkix_pl_X500Name_RegisterSelf(plContext); /* 21-30 */ + pkix_pl_HttpCertStoreContext_RegisterSelf(plContext); + pkix_BuildResult_RegisterSelf(plContext); + pkix_ProcessingParams_RegisterSelf(plContext); + pkix_ValidateParams_RegisterSelf(plContext); + pkix_ValidateResult_RegisterSelf(plContext); + pkix_CertStore_RegisterSelf(plContext); + pkix_CertChainChecker_RegisterSelf(plContext); + pkix_RevocationChecker_RegisterSelf(plContext); + pkix_CertSelector_RegisterSelf(plContext); + + pkix_ComCertSelParams_RegisterSelf(plContext); /* 31-40 */ + pkix_CRLSelector_RegisterSelf(plContext); + pkix_ComCRLSelParams_RegisterSelf(plContext); + pkix_pl_CertPolicyInfo_RegisterSelf(plContext); + pkix_pl_CertPolicyQualifier_RegisterSelf(plContext); + pkix_pl_CertPolicyMap_RegisterSelf(plContext); + pkix_PolicyNode_RegisterSelf(plContext); + pkix_TargetCertCheckerState_RegisterSelf(plContext); + pkix_BasicConstraintsCheckerState_RegisterSelf(plContext); + pkix_PolicyCheckerState_RegisterSelf(plContext); + + pkix_pl_CollectionCertStoreContext_RegisterSelf(plContext); /* 41-50 */ + pkix_CrlChecker_RegisterSelf(plContext); + pkix_ForwardBuilderState_RegisterSelf(plContext); + pkix_SignatureCheckerState_RegisterSelf(plContext); + pkix_NameConstraintsCheckerState_RegisterSelf(plContext); +#ifndef NSS_PKIX_NO_LDAP + pkix_pl_LdapRequest_RegisterSelf(plContext); + pkix_pl_LdapResponse_RegisterSelf(plContext); + pkix_pl_LdapDefaultClient_RegisterSelf(plContext); +#endif + pkix_pl_Socket_RegisterSelf(plContext); + + pkix_ResourceLimits_RegisterSelf(plContext); /* 51-59 */ + pkix_pl_MonitorLock_RegisterSelf(plContext); + pkix_pl_InfoAccess_RegisterSelf(plContext); + pkix_pl_AIAMgr_RegisterSelf(plContext); + pkix_OcspChecker_RegisterSelf(plContext); + pkix_pl_OcspCertID_RegisterSelf(plContext); + pkix_pl_OcspRequest_RegisterSelf(plContext); + pkix_pl_OcspResponse_RegisterSelf(plContext); + pkix_pl_HttpDefaultClient_RegisterSelf(plContext); + pkix_VerifyNode_RegisterSelf(plContext); + pkix_EkuChecker_RegisterSelf(plContext); + pkix_pl_CrlDp_RegisterSelf(plContext); + + if (pPlContext) { + PKIX_CHECK(PKIX_PL_NssContext_Create + (0, useArenas, NULL, &plContext), + PKIX_NSSCONTEXTCREATEFAILED); + + *pPlContext = plContext; + } + + pkix_pl_initialized = PKIX_TRUE; + +cleanup: + + PKIX_RETURN(OBJECT); +} + +/* + * PKIX_PL_Shutdown (see comments in pkix_pl_system.h) + */ +PKIX_Error * +PKIX_PL_Shutdown(void *plContext) +{ +#ifdef DEBUG + PKIX_UInt32 numLeakedObjects = 0; +#endif + + PKIX_ENTER(OBJECT, "PKIX_PL_Shutdown"); + + if (!pkix_pl_initialized) { + /* The library was not initilized */ + PKIX_RETURN(OBJECT); + } + + PR_DestroyLock(classTableLock); + + pkix_pl_HttpCertStore_Shutdown(plContext); + +#ifdef DEBUG + numLeakedObjects = pkix_pl_lifecycle_ObjectLeakCheck(NULL); + if (PR_GetEnvSecure("NSS_STRICT_SHUTDOWN")) { + PORT_Assert(numLeakedObjects == 0); + } +#else + pkix_pl_lifecycle_ObjectLeakCheck(NULL); +#endif + + if (plContext != NULL) { + PKIX_PL_NssContext_Destroy(plContext); + } + + pkix_pl_initialized = PKIX_FALSE; + + PKIX_RETURN(OBJECT); +} |