pkix_pl_lifecycle.c (9618B)
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_pl_lifecycle.c 6 * 7 * Lifecycle Functions for the PKIX PL library. 8 * 9 */ 10 11 #include "pkix_pl_lifecycle.h" 12 13 PKIX_Boolean pkix_pl_initialized = PKIX_FALSE; 14 pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; 15 PRLock *classTableLock; 16 PRLogModuleInfo *pkixLog = NULL; 17 18 /* 19 * PKIX_ALLOC_ERROR is a special error object hard-coded into the 20 * pkix_error.o object file. It is thrown if system memory cannot be 21 * allocated. PKIX_ALLOC_ERROR is immutable. 22 * IncRef, DecRef, and Settor functions cannot be called. 23 */ 24 25 /* Keep this structure definition here for its is used only once here */ 26 struct PKIX_Alloc_Error_ObjectStruct { 27 PKIX_PL_Object header; 28 PKIX_Error error; 29 }; 30 typedef struct PKIX_Alloc_Error_ObjectStruct PKIX_Alloc_Error_Object; 31 32 static const PKIX_Alloc_Error_Object pkix_Alloc_Error_Data = { 33 { 34 PKIX_MAGIC_HEADER, /* PRUint64 magicHeader */ 35 (PKIX_UInt32)PKIX_ERROR_TYPE, /* PKIX_UInt32 type */ 36 (PKIX_UInt32)1, /* PKIX_UInt32 references */ 37 /* Warning! Cannot Ref Count with NULL lock */ 38 (void *)0, /* PRLock *lock */ 39 (PKIX_PL_String *)0, /* PKIX_PL_String *stringRep */ 40 (PKIX_UInt32)0, /* PKIX_UInt32 hashcode */ 41 (PKIX_Boolean)PKIX_FALSE, /* PKIX_Boolean hashcodeCached */ 42 }, { 43 (PKIX_ERRORCODE)0, /* PKIX_ERRORCODE errCode; */ 44 (PKIX_ERRORCLASS)PKIX_FATAL_ERROR,/* PKIX_ERRORCLASS errClass */ 45 (PKIX_UInt32)SEC_ERROR_LIBPKIX_INTERNAL, /* default PL Error Code */ 46 (PKIX_Error *)0, /* PKIX_Error *cause */ 47 (PKIX_PL_Object *)0, /* PKIX_PL_Object *info */ 48 } 49 }; 50 51 PKIX_Error* PKIX_ALLOC_ERROR(void) 52 { 53 return (PKIX_Error *)&pkix_Alloc_Error_Data.error; 54 } 55 56 #ifdef PKIX_OBJECT_LEAK_TEST 57 SECStatus 58 pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable) 59 { 60 int typeCounter = 0; 61 62 for (; typeCounter < PKIX_NUMTYPES; typeCounter++) { 63 pkix_ClassTable_Entry *entry = &systemClasses[typeCounter]; 64 65 objCountTable[typeCounter] = entry->objCounter; 66 } 67 68 return SECSuccess; 69 } 70 #endif /* PKIX_OBJECT_LEAK_TEST */ 71 72 73 PKIX_UInt32 74 pkix_pl_lifecycle_ObjectLeakCheck(int *initObjCountTable) 75 { 76 unsigned int typeCounter = 0; 77 PKIX_UInt32 numObjects = 0; 78 char classNameBuff[128]; 79 char *className = NULL; 80 81 for (; typeCounter < PKIX_NUMTYPES; typeCounter++) { 82 pkix_ClassTable_Entry *entry = &systemClasses[typeCounter]; 83 PKIX_UInt32 objCountDiff = entry->objCounter; 84 85 if (initObjCountTable) { 86 PKIX_UInt32 initialCount = initObjCountTable[typeCounter]; 87 objCountDiff = (entry->objCounter > initialCount) ? 88 entry->objCounter - initialCount : 0; 89 } 90 91 numObjects += objCountDiff; 92 93 if (!pkixLog || !objCountDiff) { 94 continue; 95 } 96 className = entry->description; 97 if (!className) { 98 className = classNameBuff; 99 PR_snprintf(className, 128, "Unknown(ref %d)", 100 entry->objCounter); 101 } 102 103 PR_LOG(pkixLog, 1, ("Class %s leaked %d objects of " 104 "size %d bytes, total = %d bytes\n", className, 105 objCountDiff, entry->typeObjectSize, 106 objCountDiff * entry->typeObjectSize)); 107 } 108 109 return numObjects; 110 } 111 112 /* 113 * PKIX_PL_Initialize (see comments in pkix_pl_system.h) 114 */ 115 PKIX_Error * 116 PKIX_PL_Initialize( 117 PKIX_Boolean platformInitNeeded, 118 PKIX_Boolean useArenas, 119 void **pPlContext) 120 { 121 void *plContext = NULL; 122 123 PKIX_ENTER(OBJECT, "PKIX_PL_Initialize"); 124 125 /* 126 * This function can only be called once. If it has already been 127 * called, we return a positive status. 128 */ 129 if (pkix_pl_initialized) { 130 PKIX_RETURN(OBJECT); 131 } 132 133 classTableLock = PR_NewLock(); 134 if (classTableLock == NULL) { 135 return PKIX_ALLOC_ERROR(); 136 } 137 138 if (PR_GetEnvSecure("NSS_STRICT_SHUTDOWN")) { 139 pkixLog = PR_NewLogModule("pkix"); 140 } 141 /* 142 * Register Object, it is the base object of all other objects. 143 */ 144 pkix_pl_Object_RegisterSelf(plContext); 145 146 /* 147 * Register Error and String, since they will be needed if 148 * there is a problem in registering any other type. 149 */ 150 pkix_Error_RegisterSelf(plContext); 151 pkix_pl_String_RegisterSelf(plContext); 152 153 154 /* 155 * We register all other system types 156 * (They don't need to be in order, but it's 157 * easier to keep track of what types are registered 158 * if we register them in the same order as their 159 * numbers, defined in pkixt.h. 160 */ 161 pkix_pl_BigInt_RegisterSelf(plContext); /* 1-10 */ 162 pkix_pl_ByteArray_RegisterSelf(plContext); 163 pkix_pl_HashTable_RegisterSelf(plContext); 164 pkix_List_RegisterSelf(plContext); 165 pkix_Logger_RegisterSelf(plContext); 166 pkix_pl_Mutex_RegisterSelf(plContext); 167 pkix_pl_OID_RegisterSelf(plContext); 168 pkix_pl_RWLock_RegisterSelf(plContext); 169 170 pkix_pl_CertBasicConstraints_RegisterSelf(plContext); /* 11-20 */ 171 pkix_pl_Cert_RegisterSelf(plContext); 172 pkix_pl_CRL_RegisterSelf(plContext); 173 pkix_pl_CRLEntry_RegisterSelf(plContext); 174 pkix_pl_Date_RegisterSelf(plContext); 175 pkix_pl_GeneralName_RegisterSelf(plContext); 176 pkix_pl_CertNameConstraints_RegisterSelf(plContext); 177 pkix_pl_PublicKey_RegisterSelf(plContext); 178 pkix_TrustAnchor_RegisterSelf(plContext); 179 180 pkix_pl_X500Name_RegisterSelf(plContext); /* 21-30 */ 181 pkix_pl_HttpCertStoreContext_RegisterSelf(plContext); 182 pkix_BuildResult_RegisterSelf(plContext); 183 pkix_ProcessingParams_RegisterSelf(plContext); 184 pkix_ValidateParams_RegisterSelf(plContext); 185 pkix_ValidateResult_RegisterSelf(plContext); 186 pkix_CertStore_RegisterSelf(plContext); 187 pkix_CertChainChecker_RegisterSelf(plContext); 188 pkix_RevocationChecker_RegisterSelf(plContext); 189 pkix_CertSelector_RegisterSelf(plContext); 190 191 pkix_ComCertSelParams_RegisterSelf(plContext); /* 31-40 */ 192 pkix_CRLSelector_RegisterSelf(plContext); 193 pkix_ComCRLSelParams_RegisterSelf(plContext); 194 pkix_pl_CertPolicyInfo_RegisterSelf(plContext); 195 pkix_pl_CertPolicyQualifier_RegisterSelf(plContext); 196 pkix_pl_CertPolicyMap_RegisterSelf(plContext); 197 pkix_PolicyNode_RegisterSelf(plContext); 198 pkix_TargetCertCheckerState_RegisterSelf(plContext); 199 pkix_BasicConstraintsCheckerState_RegisterSelf(plContext); 200 pkix_PolicyCheckerState_RegisterSelf(plContext); 201 202 pkix_pl_CollectionCertStoreContext_RegisterSelf(plContext); /* 41-50 */ 203 pkix_CrlChecker_RegisterSelf(plContext); 204 pkix_ForwardBuilderState_RegisterSelf(plContext); 205 pkix_SignatureCheckerState_RegisterSelf(plContext); 206 pkix_NameConstraintsCheckerState_RegisterSelf(plContext); 207 #ifndef NSS_PKIX_NO_LDAP 208 pkix_pl_LdapRequest_RegisterSelf(plContext); 209 pkix_pl_LdapResponse_RegisterSelf(plContext); 210 pkix_pl_LdapDefaultClient_RegisterSelf(plContext); 211 #endif 212 pkix_pl_Socket_RegisterSelf(plContext); 213 214 pkix_ResourceLimits_RegisterSelf(plContext); /* 51-59 */ 215 pkix_pl_MonitorLock_RegisterSelf(plContext); 216 pkix_pl_InfoAccess_RegisterSelf(plContext); 217 pkix_pl_AIAMgr_RegisterSelf(plContext); 218 pkix_OcspChecker_RegisterSelf(plContext); 219 pkix_pl_OcspCertID_RegisterSelf(plContext); 220 pkix_pl_OcspRequest_RegisterSelf(plContext); 221 pkix_pl_OcspResponse_RegisterSelf(plContext); 222 pkix_pl_HttpDefaultClient_RegisterSelf(plContext); 223 pkix_VerifyNode_RegisterSelf(plContext); 224 pkix_EkuChecker_RegisterSelf(plContext); 225 pkix_pl_CrlDp_RegisterSelf(plContext); 226 227 if (pPlContext) { 228 PKIX_CHECK(PKIX_PL_NssContext_Create 229 (0, useArenas, NULL, &plContext), 230 PKIX_NSSCONTEXTCREATEFAILED); 231 232 *pPlContext = plContext; 233 } 234 235 pkix_pl_initialized = PKIX_TRUE; 236 237 cleanup: 238 239 PKIX_RETURN(OBJECT); 240 } 241 242 /* 243 * PKIX_PL_Shutdown (see comments in pkix_pl_system.h) 244 */ 245 PKIX_Error * 246 PKIX_PL_Shutdown(void *plContext) 247 { 248 #ifdef DEBUG 249 PKIX_UInt32 numLeakedObjects = 0; 250 #endif 251 252 PKIX_ENTER(OBJECT, "PKIX_PL_Shutdown"); 253 254 if (!pkix_pl_initialized) { 255 /* The library was not initilized */ 256 PKIX_RETURN(OBJECT); 257 } 258 259 PR_DestroyLock(classTableLock); 260 261 pkix_pl_HttpCertStore_Shutdown(plContext); 262 263 #ifdef DEBUG 264 numLeakedObjects = pkix_pl_lifecycle_ObjectLeakCheck(NULL); 265 if (PR_GetEnvSecure("NSS_STRICT_SHUTDOWN")) { 266 PORT_Assert(numLeakedObjects == 0); 267 } 268 #else 269 pkix_pl_lifecycle_ObjectLeakCheck(NULL); 270 #endif 271 272 if (plContext != NULL) { 273 PKIX_PL_NssContext_Destroy(plContext); 274 } 275 276 pkix_pl_initialized = PKIX_FALSE; 277 278 PKIX_RETURN(OBJECT); 279 }