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 Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
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 extern char *pkix_PK11ConfigDir
;
47 PKIX_Boolean pkix_pl_initialized
= PKIX_FALSE
;
48 pkix_ClassTable_Entry systemClasses
[PKIX_NUMTYPES
];
49 PRLock
*classTableLock
;
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.
59 * This data looks like a UTF-16 string of "PKIX_ALLOC_ERROR".
60 * It is used to create a static PKIX_PL_String object, pkix_Alloc_Error_desc.
62 static const char pkix_Alloc_Error_Msg
[32] =
64 0, 'P', 0, 'K', 0, 'I', 0, 'X',
66 0, 'A', 0, 'L', 0, 'L', 0, 'O', 0, 'C',
68 0, 'E', 0, 'R', 0, 'R', 0, 'O', 0, 'R'
72 * This is raw data laid out to look like a PKIX_PL_String in memory
73 * XXX If PKIX_PL_StringStruct is changed, this will break.
75 static PKIX_PL_String pkix_Alloc_Error_Desc
= {
76 (void *)&pkix_Alloc_Error_Msg
, /* void *utf16String */
77 (PKIX_UInt32
)32, /* PKIX_UInt32 utf16Length */
78 (char *)NULL
, /* char *escAsciiString */
79 (PKIX_UInt32
)0 /* PKIX_UInt32 escAsciiLength */
82 /* Keep this structure definition here for its is used only once here */
83 struct PKIX_Alloc_Error_ObjectStruct
{
84 PKIX_PL_Object header
;
87 typedef struct PKIX_Alloc_Error_ObjectStruct PKIX_Alloc_Error_Object
;
89 static PKIX_Alloc_Error_Object pkix_Alloc_Error_Data
= {
91 (PKIX_UInt32
)PKIX_MAGIC_HEADER
, /* PKIX_UInt32 magicHeader */
92 (PKIX_UInt32
)PKIX_ERROR_TYPE
, /* PKIX_UInt32 type */
93 (PKIX_UInt32
)1, /* PKIX_UInt32 references */
94 /* Warning! Cannot Ref Count with NULL lock */
95 (void *)0, /* PRLock *lock */
96 (PKIX_PL_String
*)0, /* PKIX_PL_String *stringRep */
97 (PKIX_UInt32
)0, /* PKIX_UInt32 hashcode */
98 (PKIX_Boolean
)PKIX_FALSE
, /* PKIX_Boolean hashcodeCached */
100 PKIX_FATAL_ERROR
, /* PKIX_UInt32 code */
101 (PKIX_Error
*)0, /* PKIX_Error *cause */
102 (PKIX_PL_Object
*)0, /* PKIX_PL_Object *info */
103 &pkix_Alloc_Error_Desc
/* PKIX_PL_String *desc */
107 PKIX_Error
* PKIX_ALLOC_ERROR(void)
109 return &pkix_Alloc_Error_Data
.error
;
113 * PKIX_PL_Initialize (see comments in pkix_pl_system.h)
117 PKIX_Boolean platformInitNeeded
,
118 PKIX_Boolean useArenas
,
121 void *plContext
= NULL
;
123 pkix_ClassTable_Entry nullEntry
= {NULL
};
124 /* XXX currently using canned value for config dir; add to plContext */
126 PKIX_ENTER(OBJECT
, "PKIX_PL_Initialize");
129 * This function can only be called once. If it has already been
130 * called, we return a statically allocated error. Our technique works
131 * most of the time, but may not work if multiple threads call this
132 * function simultaneously. However, the function's documentation
133 * makes it clear that this is prohibited, so it's not our
137 if (pkix_pl_initialized
) return (PKIX_ALLOC_ERROR());
139 if (platformInitNeeded
) {
141 /* Initialize NSPR and NSS. */
142 PR_Init(PR_SYSTEM_THREAD
, PR_PRIORITY_NORMAL
, 1);
144 /* if using databases, use NSS_Init and not NSS_NoDB_Init */
145 if (pkix_PK11ConfigDir
) {
146 if (NSS_Init(pkix_PK11ConfigDir
) != SECSuccess
) {
147 return (PKIX_ALLOC_ERROR());
150 if (NSS_NoDB_Init(NULL
) != 0){
151 return (PKIX_ALLOC_ERROR());
156 PKIX_OBJECT_DEBUG("\tCalling PR_NewLock).\n");
157 classTableLock
= PR_NewLock();
158 if (classTableLock
== NULL
) return (PKIX_ALLOC_ERROR());
160 /* we don't need to register OBJECT */
161 systemClasses
[PKIX_OBJECT_TYPE
] = nullEntry
;
164 * Register Error and String, since they will be needed if
165 * there is a problem in registering any other type.
167 pkix_Error_RegisterSelf(plContext
);
168 (void) pkix_pl_String_RegisterSelf(plContext
);
172 * We register all other system types
173 * (They don't need to be in order, but it's
174 * easier to keep track of what types are registered
175 * if we register them in the same order as their
176 * numbers, defined in pkixt.h.
178 (void) pkix_pl_BigInt_RegisterSelf(plContext
); /* 1-10 */
179 (void) pkix_pl_ByteArray_RegisterSelf(plContext
);
180 /* already registered! pkix_Error_RegisterSelf(plContext); */
181 (void) pkix_pl_HashTable_RegisterSelf(plContext
);
182 pkix_List_RegisterSelf(plContext
);
183 pkix_Logger_RegisterSelf(plContext
);
184 (void) pkix_pl_Mutex_RegisterSelf(plContext
);
185 (void) pkix_pl_OID_RegisterSelf(plContext
);
186 (void) pkix_pl_RWLock_RegisterSelf(plContext
);
187 /* already registered! pkix_pl_String_RegisterSelf(plContext); */
189 pkix_pl_CertBasicConstraints_RegisterSelf(plContext
); /* 11-20 */
190 pkix_pl_Cert_RegisterSelf(plContext
);
191 /* pkix_HttpClient_RegisterSelf(plContext); */
192 pkix_pl_CRL_RegisterSelf(plContext
);
193 pkix_pl_CRLEntry_RegisterSelf(plContext
);
194 pkix_pl_Date_RegisterSelf(plContext
);
195 pkix_pl_GeneralName_RegisterSelf(plContext
);
196 pkix_pl_CertNameConstraints_RegisterSelf(plContext
);
197 pkix_pl_PublicKey_RegisterSelf(plContext
);
198 pkix_TrustAnchor_RegisterSelf(plContext
);
200 pkix_pl_X500Name_RegisterSelf(plContext
); /* 21-30 */
201 pkix_pl_HttpCertStoreContext_RegisterSelf(plContext
);
202 pkix_BuildResult_RegisterSelf(plContext
);
203 pkix_ProcessingParams_RegisterSelf(plContext
);
204 pkix_ValidateParams_RegisterSelf(plContext
);
205 pkix_ValidateResult_RegisterSelf(plContext
);
206 pkix_CertStore_RegisterSelf(plContext
);
207 pkix_CertChainChecker_RegisterSelf(plContext
);
208 pkix_RevocationChecker_RegisterSelf(plContext
);
209 pkix_CertSelector_RegisterSelf(plContext
);
211 pkix_ComCertSelParams_RegisterSelf(plContext
); /* 31-40 */
212 pkix_CRLSelector_RegisterSelf(plContext
);
213 pkix_ComCRLSelParams_RegisterSelf(plContext
);
214 pkix_pl_CertPolicyInfo_RegisterSelf(plContext
);
215 pkix_pl_CertPolicyQualifier_RegisterSelf(plContext
);
216 pkix_pl_CertPolicyMap_RegisterSelf(plContext
);
217 pkix_PolicyNode_RegisterSelf(plContext
);
218 pkix_TargetCertCheckerState_RegisterSelf(plContext
);
219 pkix_BasicConstraintsCheckerState_RegisterSelf(plContext
);
220 pkix_PolicyCheckerState_RegisterSelf(plContext
);
222 pkix_pl_CollectionCertStoreContext_RegisterSelf(plContext
); /* 41-50 */
223 pkix_DefaultCRLCheckerState_RegisterSelf(plContext
);
224 pkix_ForwardBuilderState_RegisterSelf(plContext
);
225 pkix_SignatureCheckerState_RegisterSelf(plContext
);
226 pkix_NameConstraintsCheckerState_RegisterSelf(plContext
);
227 pkix_DefaultRevocationChecker_RegisterSelf(plContext
);
228 pkix_pl_LdapRequest_RegisterSelf(plContext
);
229 pkix_pl_LdapResponse_RegisterSelf(plContext
);
230 pkix_pl_LdapDefaultClient_RegisterSelf(plContext
);
231 pkix_pl_Socket_RegisterSelf(plContext
);
233 pkix_ResourceLimits_RegisterSelf(plContext
); /* 51-59 */
234 (void) pkix_pl_MonitorLock_RegisterSelf(plContext
);
235 pkix_pl_InfoAccess_RegisterSelf(plContext
);
236 pkix_pl_AIAMgr_RegisterSelf(plContext
);
237 pkix_OcspChecker_RegisterSelf(plContext
);
238 pkix_pl_OcspRequest_RegisterSelf(plContext
);
239 pkix_pl_OcspResponse_RegisterSelf(plContext
);
240 pkix_pl_HttpDefaultClient_RegisterSelf(plContext
);
241 pkix_VerifyNode_RegisterSelf(plContext
);
243 PKIX_CHECK(PKIX_PL_NssContext_Create
244 (0x10, useArenas
, NULL
, &plContext
),
245 PKIX_NSSCONTEXTCREATEFAILED
);
247 *pPlContext
= plContext
;
249 pkix_pl_initialized
= PKIX_TRUE
;
257 * PKIX_PL_Shutdown (see comments in pkix_pl_system.h)
261 PKIX_Boolean platformInitNeeded
,
264 PKIX_ENTER(OBJECT
, "PKIX_PL_Shutdown");
266 if (!pkix_pl_initialized
) return (PKIX_ALLOC_ERROR());
268 if (plContext
!= NULL
) {
269 PKIX_PL_NssContext_Destroy(plContext
);
272 /* Shut down NSS only if we initialized it */
273 if (platformInitNeeded
) {
277 pkix_pl_initialized
= PKIX_FALSE
;