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 |