| OLD | NEW |
| (Empty) |
| 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 } | |
| OLD | NEW |