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) 2001
19
* the Initial Developer. All Rights Reserved.
23
* Alternatively, the contents of this file may be used under the terms of
24
* either the GNU General Public License Version 2 or later (the "GPL"), or
25
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26
* in which case the provisions of the GPL or the LGPL are applicable instead
27
* of those above. If you wish to allow use of your version of this file only
28
* under the terms of either the GPL or the LGPL, and not to allow others to
29
* use your version of this file under the terms of the MPL, indicate your
30
* decision by deleting the provisions above and replace them with the notice
31
* and other provisions required by the GPL or the LGPL. If you do not delete
32
* the provisions above, a recipient may use your version of this file under
33
* the terms of any one of the MPL, the GPL or the LGPL.
35
* ***** END LICENSE BLOCK ***** */
37
* The following handles the loading, unloading and management of
38
* various PCKS #11 modules
52
/* create a new module */
54
secmod_NewModule(void)
60
/* create an arena in which dllName and commonName can be
63
arena = PORT_NewArena(512);
68
newMod = (SECMODModule *)PORT_ArenaAlloc(arena,sizeof (SECMODModule));
70
PORT_FreeArena(arena,PR_FALSE);
75
* initialize of the fields of the module
77
newMod->arena = arena;
78
newMod->internal = PR_FALSE;
79
newMod->loaded = PR_FALSE;
80
newMod->isFIPS = PR_FALSE;
81
newMod->dllName = NULL;
82
newMod->commonName = NULL;
83
newMod->library = NULL;
84
newMod->functionList = NULL;
85
newMod->slotCount = 0;
87
newMod->slotInfo = NULL;
88
newMod->slotInfoCount = 0;
92
newMod->libraryParams = NULL;
93
newMod->moduleDBFunc = NULL;
94
newMod->parent = NULL;
95
newMod->isCritical = PR_FALSE;
96
newMod->isModuleDB = PR_FALSE;
97
newMod->moduleDBOnly = PR_FALSE;
98
newMod->trustOrder = 0;
99
newMod->cipherOrder = 0;
100
newMod->evControlMask = 0;
101
newMod->refLock = PZ_NewLock(nssILockRefLock);
102
if (newMod->refLock == NULL) {
103
PORT_FreeArena(arena,PR_FALSE);
111
* for 3.4 we continue to use the old SECMODModule structure
114
SECMOD_CreateModule(const char *library, const char *moduleName,
115
const char *parameters, const char *nss)
117
SECMODModule *mod = secmod_NewModule();
118
char *slotParams,*ciphers;
119
/* pk11pars.h still does not have const char * interfaces */
120
char *nssc = (char *)nss;
121
if (mod == NULL) return NULL;
123
mod->commonName = PORT_ArenaStrdup(mod->arena,moduleName ? moduleName : "");
125
mod->dllName = PORT_ArenaStrdup(mod->arena,library);
129
mod->libraryParams = PORT_ArenaStrdup(mod->arena,parameters);
131
mod->internal = secmod_argHasFlag("flags","internal",nssc);
132
mod->isFIPS = secmod_argHasFlag("flags","FIPS",nssc);
133
mod->isCritical = secmod_argHasFlag("flags","critical",nssc);
134
slotParams = secmod_argGetParamValue("slotParams",nssc);
135
mod->slotInfo = secmod_argParseSlotInfo(mod->arena,slotParams,
136
&mod->slotInfoCount);
137
if (slotParams) PORT_Free(slotParams);
139
mod->trustOrder = secmod_argReadLong("trustOrder",nssc,
140
SECMOD_DEFAULT_TRUST_ORDER,NULL);
142
mod->cipherOrder = secmod_argReadLong("cipherOrder",nssc,
143
SECMOD_DEFAULT_CIPHER_ORDER,NULL);
145
mod->isModuleDB = secmod_argHasFlag("flags","moduleDB",nssc);
146
mod->moduleDBOnly = secmod_argHasFlag("flags","moduleDBOnly",nssc);
147
if (mod->moduleDBOnly) mod->isModuleDB = PR_TRUE;
149
ciphers = secmod_argGetParamValue("ciphers",nssc);
150
secmod_argSetNewCipherFlags(&mod->ssl[0],ciphers);
151
if (ciphers) PORT_Free(ciphers);
153
secmod_PrivateModuleCount++;
159
secmod_mkModuleSpec(SECMODModule * module)
161
char *nss = NULL, *modSpec = NULL, **slotStrings = NULL;
162
int slotCount, i, si;
163
SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
165
/* allocate target slot info strings */
168
SECMOD_GetReadLock(moduleLock);
169
if (module->slotCount) {
170
for (i=0; i < module->slotCount; i++) {
171
if (module->slots[i]->defaultFlags !=0) {
176
slotCount = module->slotInfoCount;
179
slotStrings = (char **)PORT_ZAlloc(slotCount*sizeof(char *));
180
if (slotStrings == NULL) {
181
SECMOD_ReleaseReadLock(moduleLock);
186
/* build the slot info strings */
187
if (module->slotCount) {
188
for (i=0, si= 0; i < module->slotCount; i++) {
189
if (module->slots[i]->defaultFlags) {
190
PORT_Assert(si < slotCount);
191
if (si >= slotCount) break;
192
slotStrings[si] = secmod_mkSlotString(module->slots[i]->slotID,
193
module->slots[i]->defaultFlags,
194
module->slots[i]->timeout,
195
module->slots[i]->askpw,
196
module->slots[i]->hasRootCerts,
197
module->slots[i]->hasRootTrust);
202
for (i=0; i < slotCount; i++) {
203
slotStrings[i] = secmod_mkSlotString(module->slotInfo[i].slotID,
204
module->slotInfo[i].defaultFlags,
205
module->slotInfo[i].timeout,
206
module->slotInfo[i].askpw,
207
module->slotInfo[i].hasRootCerts,
208
module->slotInfo[i].hasRootTrust);
212
SECMOD_ReleaseReadLock(moduleLock);
213
nss = secmod_mkNSS(slotStrings,slotCount,module->internal, module->isFIPS,
214
module->isModuleDB, module->moduleDBOnly,
215
module->isCritical, module->trustOrder,
216
module->cipherOrder,module->ssl[0],module->ssl[1]);
217
modSpec= secmod_mkNewModuleSpec(module->dllName,module->commonName,
218
module->libraryParams,nss);
219
PORT_Free(slotStrings);
220
PR_smprintf_free(nss);
227
SECMOD_GetModuleSpecList(SECMODModule *module)
229
SECMODModuleDBFunc func = (SECMODModuleDBFunc) module->moduleDBFunc;
231
return (*func)(SECMOD_MODULE_DB_FUNCTION_FIND,
232
module->libraryParams,NULL);
238
SECMOD_AddPermDB(SECMODModule *module)
240
SECMODModuleDBFunc func;
244
if (module->parent == NULL) return SECFailure;
246
func = (SECMODModuleDBFunc) module->parent->moduleDBFunc;
248
moduleSpec = secmod_mkModuleSpec(module);
249
retString = (*func)(SECMOD_MODULE_DB_FUNCTION_ADD,
250
module->parent->libraryParams,moduleSpec);
251
PORT_Free(moduleSpec);
252
if (retString != NULL) return SECSuccess;
258
SECMOD_DeletePermDB(SECMODModule *module)
260
SECMODModuleDBFunc func;
264
if (module->parent == NULL) return SECFailure;
266
func = (SECMODModuleDBFunc) module->parent->moduleDBFunc;
268
moduleSpec = secmod_mkModuleSpec(module);
269
retString = (*func)(SECMOD_MODULE_DB_FUNCTION_DEL,
270
module->parent->libraryParams,moduleSpec);
271
PORT_Free(moduleSpec);
272
if (retString != NULL) return SECSuccess;
278
SECMOD_FreeModuleSpecList(SECMODModule *module, char **moduleSpecList)
280
SECMODModuleDBFunc func = (SECMODModuleDBFunc) module->moduleDBFunc;
283
retString = (*func)(SECMOD_MODULE_DB_FUNCTION_RELEASE,
284
module->libraryParams,moduleSpecList);
285
if (retString != NULL) return SECSuccess;
291
* load a PKCS#11 module but do not add it to the default NSS trust domain
294
SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse)
296
char *library = NULL, *moduleName = NULL, *parameters = NULL, *nss= NULL;
298
SECMODModule *module = NULL;
301
/* initialize the underlying module structures */
304
status = secmod_argParseModuleSpec(modulespec, &library, &moduleName,
306
if (status != SECSuccess) {
310
module = SECMOD_CreateModule(library, moduleName, parameters, nss);
311
if (library) PORT_Free(library);
312
if (moduleName) PORT_Free(moduleName);
313
if (parameters) PORT_Free(parameters);
314
if (nss) PORT_Free(nss);
319
module->parent = SECMOD_ReferenceModule(parent);
323
rv = SECMOD_LoadPKCS11Module(module);
324
if (rv != SECSuccess) {
328
if (recurse && module->isModuleDB) {
329
char ** moduleSpecList;
332
moduleSpecList = SECMOD_GetModuleSpecList(module);
333
if (moduleSpecList) {
336
for (index = moduleSpecList; *index; index++) {
338
child = SECMOD_LoadModule(*index,module,PR_TRUE);
340
if (child->isCritical && !child->loaded) {
341
int err = PORT_GetError();
343
err = SEC_ERROR_NO_MODULE;
344
SECMOD_DestroyModule(child);
349
SECMOD_DestroyModule(child);
351
SECMOD_FreeModuleSpecList(module,moduleSpecList);
353
if (!PORT_GetError())
354
PORT_SetError(SEC_ERROR_NO_MODULE);
359
if (rv != SECSuccess) {
364
/* inherit the reference */
365
if (!module->moduleDBOnly) {
366
SECMOD_AddModuleToList(module);
368
SECMOD_AddModuleToDBOnlyList(module);
371
/* handle any additional work here */
376
if (module->loaded) {
377
SECMOD_UnloadModule(module);
379
SECMOD_AddModuleToUnloadList(module);
385
* load a PKCS#11 module and add it to the default NSS trust domain
388
SECMOD_LoadUserModule(char *modulespec,SECMODModule *parent, PRBool recurse)
390
SECStatus rv = SECSuccess;
391
SECMODModule * newmod = SECMOD_LoadModule(modulespec, parent, recurse);
392
SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
395
SECMOD_GetReadLock(moduleLock);
396
rv = STAN_AddModuleToDefaultTrustDomain(newmod);
397
SECMOD_ReleaseReadLock(moduleLock);
398
if (SECSuccess != rv) {
399
SECMOD_DestroyModule(newmod);
407
* remove the PKCS#11 module from the default NSS trust domain, call
408
* C_Finalize, and destroy the module structure
410
SECStatus SECMOD_UnloadUserModule(SECMODModule *mod)
412
SECStatus rv = SECSuccess;
414
SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
419
SECMOD_GetReadLock(moduleLock);
420
rv = STAN_RemoveModuleFromDefaultTrustDomain(mod);
421
SECMOD_ReleaseReadLock(moduleLock);
422
if (SECSuccess != rv) {
425
return SECMOD_DeleteModuleEx(NULL, mod, &atype, PR_FALSE);