1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the PKIX-C library.
16 * The Initial Developer of the Original Code is
17 * Sun Microsystems, Inc.
18 * Portions created by the Initial Developer are
19 * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
22 * Sun Microsystems, Inc.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
40 * Lifecycle Functions for the PKIX PL library.
44 #include "pkix_pl_lifecycle.h"
46 PKIX_Boolean pkix_pl_initialized
= PKIX_FALSE
;
47 pkix_ClassTable_Entry systemClasses
[PKIX_NUMTYPES
];
48 PRLock
*classTableLock
;
49 PRLogModuleInfo
*pkixLog
= NULL
;
52 * PKIX_ALLOC_ERROR is a special error object hard-coded into the
53 * pkix_error.o object file. It is thrown if system memory cannot be
54 * allocated. PKIX_ALLOC_ERROR is immutable.
55 * IncRef, DecRef, and Settor functions cannot be called.
58 /* Keep this structure definition here for its is used only once here */
59 struct PKIX_Alloc_Error_ObjectStruct
{
60 PKIX_PL_Object header
;
63 typedef struct PKIX_Alloc_Error_ObjectStruct PKIX_Alloc_Error_Object
;
65 static PKIX_Alloc_Error_Object pkix_Alloc_Error_Data
= {
67 (PKIX_UInt32
)PKIX_MAGIC_HEADER
, /* PKIX_UInt32 magicHeader */
68 (PKIX_UInt32
)PKIX_ERROR_TYPE
, /* PKIX_UInt32 type */
69 (PKIX_UInt32
)1, /* PKIX_UInt32 references */
70 /* Warning! Cannot Ref Count with NULL lock */
71 (void *)0, /* PRLock *lock */
72 (PKIX_PL_String
*)0, /* PKIX_PL_String *stringRep */
73 (PKIX_UInt32
)0, /* PKIX_UInt32 hashcode */
74 (PKIX_Boolean
)PKIX_FALSE
, /* PKIX_Boolean hashcodeCached */
76 (PKIX_ERRORCODE
)0, /* PKIX_ERRORCODE errCode; */
77 (PKIX_ERRORCLASS
)PKIX_FATAL_ERROR
,/* PKIX_ERRORCLASS errClass */
78 (PKIX_UInt32
)SEC_ERROR_LIBPKIX_INTERNAL
, /* default PL Error Code */
79 (PKIX_Error
*)0, /* PKIX_Error *cause */
80 (PKIX_PL_Object
*)0, /* PKIX_PL_Object *info */
84 PKIX_Error
* PKIX_ALLOC_ERROR(void)
86 return &pkix_Alloc_Error_Data
.error
;
89 #ifdef PKIX_OBJECT_LEAK_TEST
91 pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable
)
95 for (; typeCounter
< PKIX_NUMTYPES
; typeCounter
++) {
96 pkix_ClassTable_Entry
*entry
= &systemClasses
[typeCounter
];
98 objCountTable
[typeCounter
] = entry
->objCounter
;
103 #endif /* PKIX_OBJECT_LEAK_TEST */
107 pkix_pl_lifecycle_ObjectLeakCheck(int *initObjCountTable
)
110 PKIX_UInt32 numObjects
= 0;
111 char classNameBuff
[128];
112 char *className
= NULL
;
114 for (; typeCounter
< PKIX_NUMTYPES
; typeCounter
++) {
115 pkix_ClassTable_Entry
*entry
= &systemClasses
[typeCounter
];
116 PKIX_UInt32 objCountDiff
= entry
->objCounter
;
118 if (initObjCountTable
) {
119 PKIX_UInt32 initialCount
= initObjCountTable
[typeCounter
];
120 objCountDiff
= (entry
->objCounter
> initialCount
) ?
121 entry
->objCounter
- initialCount
: 0;
124 numObjects
+= objCountDiff
;
126 if (!pkixLog
|| !objCountDiff
) {
129 className
= entry
->description
;
131 className
= classNameBuff
;
132 sprintf(className
, "Unknown(ref %d)",
136 PR_LOG(pkixLog
, 1, ("Class %s leaked %d objects of "
137 "size %d bytes, total = %d bytes\n", className
,
138 objCountDiff
, entry
->typeObjectSize
,
139 objCountDiff
* entry
->typeObjectSize
));
146 * PKIX_PL_Initialize (see comments in pkix_pl_system.h)
150 PKIX_Boolean platformInitNeeded
,
151 PKIX_Boolean useArenas
,
154 void *plContext
= NULL
;
156 PKIX_ENTER(OBJECT
, "PKIX_PL_Initialize");
159 * This function can only be called once. If it has already been
160 * called, we return a positive status.
162 if (pkix_pl_initialized
) {
166 classTableLock
= PR_NewLock();
167 if (classTableLock
== NULL
) {
168 return PKIX_ALLOC_ERROR();
171 if (PR_GetEnv("NSS_STRICT_SHUTDOWN")) {
172 pkixLog
= PR_NewLogModule("pkix");
175 * Register Object, it is the base object of all other objects.
177 pkix_pl_Object_RegisterSelf(plContext
);
180 * Register Error and String, since they will be needed if
181 * there is a problem in registering any other type.
183 pkix_Error_RegisterSelf(plContext
);
184 pkix_pl_String_RegisterSelf(plContext
);
188 * We register all other system types
189 * (They don't need to be in order, but it's
190 * easier to keep track of what types are registered
191 * if we register them in the same order as their
192 * numbers, defined in pkixt.h.
194 pkix_pl_BigInt_RegisterSelf(plContext
); /* 1-10 */
195 pkix_pl_ByteArray_RegisterSelf(plContext
);
196 pkix_pl_HashTable_RegisterSelf(plContext
);
197 pkix_List_RegisterSelf(plContext
);
198 pkix_Logger_RegisterSelf(plContext
);
199 pkix_pl_Mutex_RegisterSelf(plContext
);
200 pkix_pl_OID_RegisterSelf(plContext
);
201 pkix_pl_RWLock_RegisterSelf(plContext
);
203 pkix_pl_CertBasicConstraints_RegisterSelf(plContext
); /* 11-20 */
204 pkix_pl_Cert_RegisterSelf(plContext
);
205 pkix_pl_CRL_RegisterSelf(plContext
);
206 pkix_pl_CRLEntry_RegisterSelf(plContext
);
207 pkix_pl_Date_RegisterSelf(plContext
);
208 pkix_pl_GeneralName_RegisterSelf(plContext
);
209 pkix_pl_CertNameConstraints_RegisterSelf(plContext
);
210 pkix_pl_PublicKey_RegisterSelf(plContext
);
211 pkix_TrustAnchor_RegisterSelf(plContext
);
213 pkix_pl_X500Name_RegisterSelf(plContext
); /* 21-30 */
214 pkix_pl_HttpCertStoreContext_RegisterSelf(plContext
);
215 pkix_BuildResult_RegisterSelf(plContext
);
216 pkix_ProcessingParams_RegisterSelf(plContext
);
217 pkix_ValidateParams_RegisterSelf(plContext
);
218 pkix_ValidateResult_RegisterSelf(plContext
);
219 pkix_CertStore_RegisterSelf(plContext
);
220 pkix_CertChainChecker_RegisterSelf(plContext
);
221 pkix_RevocationChecker_RegisterSelf(plContext
);
222 pkix_CertSelector_RegisterSelf(plContext
);
224 pkix_ComCertSelParams_RegisterSelf(plContext
); /* 31-40 */
225 pkix_CRLSelector_RegisterSelf(plContext
);
226 pkix_ComCRLSelParams_RegisterSelf(plContext
);
227 pkix_pl_CertPolicyInfo_RegisterSelf(plContext
);
228 pkix_pl_CertPolicyQualifier_RegisterSelf(plContext
);
229 pkix_pl_CertPolicyMap_RegisterSelf(plContext
);
230 pkix_PolicyNode_RegisterSelf(plContext
);
231 pkix_TargetCertCheckerState_RegisterSelf(plContext
);
232 pkix_BasicConstraintsCheckerState_RegisterSelf(plContext
);
233 pkix_PolicyCheckerState_RegisterSelf(plContext
);
235 pkix_pl_CollectionCertStoreContext_RegisterSelf(plContext
); /* 41-50 */
236 pkix_DefaultCRLCheckerState_RegisterSelf(plContext
);
237 pkix_ForwardBuilderState_RegisterSelf(plContext
);
238 pkix_SignatureCheckerState_RegisterSelf(plContext
);
239 pkix_NameConstraintsCheckerState_RegisterSelf(plContext
);
240 pkix_DefaultRevocationChecker_RegisterSelf(plContext
);
241 pkix_pl_LdapRequest_RegisterSelf(plContext
);
242 pkix_pl_LdapResponse_RegisterSelf(plContext
);
243 pkix_pl_LdapDefaultClient_RegisterSelf(plContext
);
244 pkix_pl_Socket_RegisterSelf(plContext
);
246 pkix_ResourceLimits_RegisterSelf(plContext
); /* 51-59 */
247 pkix_pl_MonitorLock_RegisterSelf(plContext
);
248 pkix_pl_InfoAccess_RegisterSelf(plContext
);
249 pkix_pl_AIAMgr_RegisterSelf(plContext
);
250 pkix_OcspChecker_RegisterSelf(plContext
);
251 pkix_pl_OcspCertID_RegisterSelf(plContext
);
252 pkix_pl_OcspRequest_RegisterSelf(plContext
);
253 pkix_pl_OcspResponse_RegisterSelf(plContext
);
254 pkix_pl_HttpDefaultClient_RegisterSelf(plContext
);
255 pkix_VerifyNode_RegisterSelf(plContext
);
256 pkix_pl_EkuChecker_RegisterSelf(plContext
);
259 PKIX_CHECK(PKIX_PL_NssContext_Create
260 (0, useArenas
, NULL
, &plContext
),
261 PKIX_NSSCONTEXTCREATEFAILED
);
263 *pPlContext
= plContext
;
266 pkix_pl_initialized
= PKIX_TRUE
;
274 * PKIX_PL_Shutdown (see comments in pkix_pl_system.h)
277 PKIX_PL_Shutdown(void *plContext
)
279 PKIX_UInt32 numLeakedObjects
= 0;
281 PKIX_ENTER(OBJECT
, "PKIX_PL_Shutdown");
283 if (!pkix_pl_initialized
) {
284 /* The library was not initilized */
288 PR_DestroyLock(classTableLock
);
290 pkix_pl_HttpCertStore_Shutdown(plContext
);
292 numLeakedObjects
= pkix_pl_lifecycle_ObjectLeakCheck(NULL
);
293 if (PR_GetEnv("NSS_STRICT_SHUTDOWN")) {
294 PORT_Assert(numLeakedObjects
== 0);
297 if (plContext
!= NULL
) {
298 PKIX_PL_NssContext_Destroy(plContext
);
301 pkix_pl_initialized
= PKIX_FALSE
;