Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: nss/lib/pk11wrap/pk11pars.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nss/lib/pk11wrap/pk11obj.c ('k') | nss/lib/pk11wrap/pk11pbe.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 * The following handles the loading, unloading and management of
6 * various PCKS #11 modules
7 */
8
9 #include <ctype.h>
10 #include <assert.h>
11 #include "pkcs11.h"
12 #include "seccomon.h"
13 #include "secmod.h"
14 #include "secmodi.h"
15 #include "secmodti.h"
16 #include "pki3hack.h"
17 #include "secerr.h"
18 #include "nss.h"
19 #include "utilpars.h"
20
21 /* create a new module */
22 static SECMODModule *
23 secmod_NewModule(void)
24 {
25 SECMODModule *newMod;
26 PLArenaPool *arena;
27
28
29 /* create an arena in which dllName and commonName can be
30 * allocated.
31 */
32 arena = PORT_NewArena(512);
33 if (arena == NULL) {
34 return NULL;
35 }
36
37 newMod = (SECMODModule *)PORT_ArenaAlloc(arena,sizeof (SECMODModule));
38 if (newMod == NULL) {
39 PORT_FreeArena(arena,PR_FALSE);
40 return NULL;
41 }
42
43 /*
44 * initialize of the fields of the module
45 */
46 newMod->arena = arena;
47 newMod->internal = PR_FALSE;
48 newMod->loaded = PR_FALSE;
49 newMod->isFIPS = PR_FALSE;
50 newMod->dllName = NULL;
51 newMod->commonName = NULL;
52 newMod->library = NULL;
53 newMod->functionList = NULL;
54 newMod->slotCount = 0;
55 newMod->slots = NULL;
56 newMod->slotInfo = NULL;
57 newMod->slotInfoCount = 0;
58 newMod->refCount = 1;
59 newMod->ssl[0] = 0;
60 newMod->ssl[1] = 0;
61 newMod->libraryParams = NULL;
62 newMod->moduleDBFunc = NULL;
63 newMod->parent = NULL;
64 newMod->isCritical = PR_FALSE;
65 newMod->isModuleDB = PR_FALSE;
66 newMod->moduleDBOnly = PR_FALSE;
67 newMod->trustOrder = 0;
68 newMod->cipherOrder = 0;
69 newMod->evControlMask = 0;
70 newMod->refLock = PZ_NewLock(nssILockRefLock);
71 if (newMod->refLock == NULL) {
72 PORT_FreeArena(arena,PR_FALSE);
73 return NULL;
74 }
75 return newMod;
76
77 }
78
79 /* private flags for isModuleDB (field in SECMODModule). */
80 /* The meaing of these flags is as follows:
81 *
82 * SECMOD_FLAG_MODULE_DB_IS_MODULE_DB - This is a module that accesses the
83 * database of other modules to load. Module DBs are loadable modules that
84 * tells NSS which PKCS #11 modules to load and when. These module DBs are
85 * chainable. That is, one module DB can load another one. NSS system init
86 * design takes advantage of this feature. In system NSS, a fixed system
87 * module DB loads the system defined libraries, then chains out to the
88 * traditional module DBs to load any system or user configured modules
89 * (like smart cards). This bit is the same as the already existing meaning
90 * of isModuleDB = PR_TRUE. None of the other module db flags should be set
91 * if this flag isn't on.
92 *
93 * SECMOD_FLAG_MODULE_DB_SKIP_FIRST - This flag tells NSS to skip the first
94 * PKCS #11 module presented by a module DB. This allows the OS to load a
95 * softoken from the system module, then ask the existing module DB code to
96 * load the other PKCS #11 modules in that module DB (skipping it's request
97 * to load softoken). This gives the system init finer control over the
98 * configuration of that softoken module.
99 *
100 * SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB - This flag allows system init to mark a
101 * different module DB as the 'default' module DB (the one in which
102 * 'Add module' changes will go). Without this flag NSS takes the first
103 * module as the default Module DB, but in system NSS, that first module
104 * is the system module, which is likely read only (at least to the user).
105 * This allows system NSS to delegate those changes to the user's module DB,
106 * preserving the user's ability to load new PKCS #11 modules (which only
107 * affect him), from existing applications like Firefox.
108 */
109 #define SECMOD_FLAG_MODULE_DB_IS_MODULE_DB 0x01 /* must be set if any of the
110 *other flags are set */
111 #define SECMOD_FLAG_MODULE_DB_SKIP_FIRST 0x02
112 #define SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB 0x04
113
114
115 /* private flags for internal (field in SECMODModule). */
116 /* The meaing of these flags is as follows:
117 *
118 * SECMOD_FLAG_INTERNAL_IS_INTERNAL - This is a marks the the module is
119 * the internal module (that is, softoken). This bit is the same as the
120 * already existing meaning of internal = PR_TRUE. None of the other
121 * internal flags should be set if this flag isn't on.
122 *
123 * SECMOD_FLAG_MODULE_INTERNAL_KEY_SLOT - This flag allows system init to mark
124 * a different slot returned byt PK11_GetInternalKeySlot(). The 'primary'
125 * slot defined by this module will be the new internal key slot.
126 */
127 #define SECMOD_FLAG_INTERNAL_IS_INTERNAL 0x01 /* must be set if any of
128 *the other flags are set */
129 #define SECMOD_FLAG_INTERNAL_KEY_SLOT 0x02
130
131 /*
132 * for 3.4 we continue to use the old SECMODModule structure
133 */
134 SECMODModule *
135 SECMOD_CreateModule(const char *library, const char *moduleName,
136 const char *parameters, const char *nss)
137 {
138 return SECMOD_CreateModuleEx(library, moduleName, parameters, nss, NULL);
139 }
140
141 /*
142 * NSS config options format:
143 *
144 * The specified ciphers will be allowed by policy, but an application
145 * may allow more by policy explicitly:
146 * config="allow=curve1:curve2:hash1:hash2:rsa-1024..."
147 *
148 * Only the specified hashes and curves will be allowed:
149 * config="disallow=all allow=sha1:sha256:secp256r1:secp384r1"
150 *
151 * Only the specified hashes and curves will be allowed, and
152 * RSA keys of 2048 or more will be accepted, and DH key exchange
153 * with 1024-bit primes or more:
154 * config="disallow=all allow=sha1:sha256:secp256r1:secp384r1:min-rsa=2048:min-d h=1024"
155 *
156 * A policy that enables the AES ciphersuites and the SECP256/384 curves:
157 * config="allow=aes128-cbc:aes128-gcm:TLS1.0:TLS1.2:TLS1.1:HMAC-SHA1:SHA1:SHA25 6:SHA384:RSA:ECDHE-RSA:SECP256R1:SECP384R1"
158 *
159 * Disallow values are parsed first, then allow values, independent of the
160 * order they appear.
161 *
162 * Future key words (not yet implemented):
163 * enable: turn on ciphersuites by default.
164 * disable: turn off ciphersuites by default without disallowing them by policy.
165 * flags: turn on the following flags:
166 * ssl-lock: turn off the ability for applications to change policy with
167 * the SSL_SetCipherPolicy (or SSL_SetPolicy).
168 * policy-lock: turn off the ability for applications to change policy with
169 * the call NSS_SetAlgorithmPolicy.
170 * ssl-default-lock: turn off the ability for applications to change cipher
171 * suite states with SSL_EnableCipher, SSL_DisableCipher.
172 *
173 */
174
175 typedef struct {
176 const char *name;
177 unsigned name_size;
178 SECOidTag oid;
179 PRUint32 val;
180 } oidValDef;
181
182 typedef struct {
183 const char *name;
184 unsigned name_size;
185 PRInt32 option;
186 } optionFreeDef;
187
188 typedef struct {
189 const char *name;
190 unsigned name_size;
191 PRUint32 flag;
192 } policyFlagDef;
193
194 /*
195 * This table should be merged with the SECOID table.
196 */
197 #define CIPHER_NAME(x) x,(sizeof(x)-1)
198 static const oidValDef algOptList[] = {
199 /* Curves */
200 {CIPHER_NAME("PRIME192V1"),SEC_OID_ANSIX962_EC_PRIME192V1,
201 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
202 {CIPHER_NAME("PRIME192V2"), SEC_OID_ANSIX962_EC_PRIME192V2,
203 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
204 {CIPHER_NAME("PRIME192V3"), SEC_OID_ANSIX962_EC_PRIME192V3,
205 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
206 {CIPHER_NAME("PRIME239V1"), SEC_OID_ANSIX962_EC_PRIME239V1,
207 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
208 {CIPHER_NAME("PRIME239V2"), SEC_OID_ANSIX962_EC_PRIME239V2,
209 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
210 {CIPHER_NAME("PRIME239V3"), SEC_OID_ANSIX962_EC_PRIME239V3,
211 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
212 {CIPHER_NAME("PRIME256V1"), SEC_OID_ANSIX962_EC_PRIME256V1,
213 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
214 {CIPHER_NAME("SECP112R1"), SEC_OID_SECG_EC_SECP112R1,
215 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
216 {CIPHER_NAME("SECP112R2"), SEC_OID_SECG_EC_SECP112R2,
217 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
218 {CIPHER_NAME("SECP128R1"), SEC_OID_SECG_EC_SECP128R1,
219 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
220 {CIPHER_NAME("SECP128R2"), SEC_OID_SECG_EC_SECP128R2,
221 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
222 {CIPHER_NAME("SECP160K1"), SEC_OID_SECG_EC_SECP160K1,
223 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
224 {CIPHER_NAME("SECP160R1"), SEC_OID_SECG_EC_SECP160R1,
225 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
226 {CIPHER_NAME("SECP160R2"), SEC_OID_SECG_EC_SECP160R2,
227 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
228 {CIPHER_NAME("SECP192K1"), SEC_OID_SECG_EC_SECP192K1,
229 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
230 {CIPHER_NAME("SECP192R1"), SEC_OID_ANSIX962_EC_PRIME192V1,
231 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
232 {CIPHER_NAME("SECP224K1"), SEC_OID_SECG_EC_SECP224K1,
233 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
234 {CIPHER_NAME("SECP256K1"), SEC_OID_SECG_EC_SECP256K1,
235 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
236 {CIPHER_NAME("SECP256R1"), SEC_OID_ANSIX962_EC_PRIME256V1,
237 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
238 {CIPHER_NAME("SECP384R1"), SEC_OID_SECG_EC_SECP384R1,
239 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
240 {CIPHER_NAME("SECP521R1"), SEC_OID_SECG_EC_SECP521R1,
241 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
242 /* ANSI X9.62 named elliptic curves (characteristic two field) */
243 {CIPHER_NAME("C2PNB163V1"), SEC_OID_ANSIX962_EC_C2PNB163V1,
244 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
245 {CIPHER_NAME("C2PNB163V2"), SEC_OID_ANSIX962_EC_C2PNB163V2,
246 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
247 {CIPHER_NAME("C2PNB163V3"), SEC_OID_ANSIX962_EC_C2PNB163V3,
248 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
249 {CIPHER_NAME("C2PNB176V1"), SEC_OID_ANSIX962_EC_C2PNB176V1,
250 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
251 {CIPHER_NAME("C2TNB191V1"), SEC_OID_ANSIX962_EC_C2TNB191V1,
252 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
253 {CIPHER_NAME("C2TNB191V2"), SEC_OID_ANSIX962_EC_C2TNB191V2,
254 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
255 {CIPHER_NAME("C2TNB191V3"), SEC_OID_ANSIX962_EC_C2TNB191V3,
256 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
257 {CIPHER_NAME("C2ONB191V4"), SEC_OID_ANSIX962_EC_C2ONB191V4,
258 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
259 {CIPHER_NAME("C2ONB191V5"), SEC_OID_ANSIX962_EC_C2ONB191V5,
260 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
261 {CIPHER_NAME("C2PNB208W1"), SEC_OID_ANSIX962_EC_C2PNB208W1,
262 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
263 {CIPHER_NAME("C2TNB239V1"), SEC_OID_ANSIX962_EC_C2TNB239V1,
264 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
265 {CIPHER_NAME("C2TNB239V2"), SEC_OID_ANSIX962_EC_C2TNB239V2,
266 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
267 {CIPHER_NAME("C2TNB239V3"), SEC_OID_ANSIX962_EC_C2TNB239V3,
268 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
269 {CIPHER_NAME("C2ONB239V4"), SEC_OID_ANSIX962_EC_C2ONB239V4,
270 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
271 {CIPHER_NAME("C2ONB239V5"), SEC_OID_ANSIX962_EC_C2ONB239V5,
272 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
273 {CIPHER_NAME("C2PNB272W1"), SEC_OID_ANSIX962_EC_C2PNB272W1,
274 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
275 {CIPHER_NAME("C2PNB304W1"), SEC_OID_ANSIX962_EC_C2PNB304W1,
276 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
277 {CIPHER_NAME("C2TNB359V1"), SEC_OID_ANSIX962_EC_C2TNB359V1,
278 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
279 {CIPHER_NAME("C2PNB368W1"), SEC_OID_ANSIX962_EC_C2PNB368W1,
280 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
281 {CIPHER_NAME("C2TNB431R1"), SEC_OID_ANSIX962_EC_C2TNB431R1,
282 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
283 /* SECG named elliptic curves (characteristic two field) */
284 {CIPHER_NAME("SECT113R1"), SEC_OID_SECG_EC_SECT113R1,
285 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
286 {CIPHER_NAME("SECT131R1"), SEC_OID_SECG_EC_SECT113R2,
287 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
288 {CIPHER_NAME("SECT131R1"), SEC_OID_SECG_EC_SECT131R1,
289 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
290 {CIPHER_NAME("SECT131R2"), SEC_OID_SECG_EC_SECT131R2,
291 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
292 {CIPHER_NAME("SECT163K1"), SEC_OID_SECG_EC_SECT163K1,
293 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
294 {CIPHER_NAME("SECT163R1"), SEC_OID_SECG_EC_SECT163R1,
295 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
296 {CIPHER_NAME("SECT163R2"), SEC_OID_SECG_EC_SECT163R2,
297 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
298 {CIPHER_NAME("SECT193R1"), SEC_OID_SECG_EC_SECT193R1,
299 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
300 {CIPHER_NAME("SECT193R2"), SEC_OID_SECG_EC_SECT193R2,
301 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
302 {CIPHER_NAME("SECT233K1"), SEC_OID_SECG_EC_SECT233K1,
303 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
304 {CIPHER_NAME("SECT233R1"), SEC_OID_SECG_EC_SECT233R1,
305 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
306 {CIPHER_NAME("SECT239K1"), SEC_OID_SECG_EC_SECT239K1,
307 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
308 {CIPHER_NAME("SECT283K1"), SEC_OID_SECG_EC_SECT283K1,
309 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
310 {CIPHER_NAME("SECT283R1"), SEC_OID_SECG_EC_SECT283R1,
311 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
312 {CIPHER_NAME("SECT409K1"), SEC_OID_SECG_EC_SECT409K1,
313 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
314 {CIPHER_NAME("SECT409R1"), SEC_OID_SECG_EC_SECT409R1,
315 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
316 {CIPHER_NAME("SECT571K1"), SEC_OID_SECG_EC_SECT571K1,
317 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
318 {CIPHER_NAME("SECT571R1"), SEC_OID_SECG_EC_SECT571R1,
319 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
320
321 /* Hashes */
322 {CIPHER_NAME("MD2"), SEC_OID_MD2,
323 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
324 {CIPHER_NAME("MD4"), SEC_OID_MD4,
325 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
326 {CIPHER_NAME("MD5"), SEC_OID_MD5,
327 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
328 {CIPHER_NAME("SHA1"), SEC_OID_SHA1,
329 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
330 {CIPHER_NAME("SHA224"), SEC_OID_SHA224,
331 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
332 {CIPHER_NAME("SHA256"), SEC_OID_SHA256,
333 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
334 {CIPHER_NAME("SHA384"), SEC_OID_SHA384,
335 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
336 {CIPHER_NAME("SHA512"), SEC_OID_SHA512,
337 NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE},
338
339 /* MACs */
340 {CIPHER_NAME("HMAC-SHA1"), SEC_OID_HMAC_SHA1, NSS_USE_ALG_IN_SSL},
341 {CIPHER_NAME("HMAC-SHA224"), SEC_OID_HMAC_SHA224, NSS_USE_ALG_IN_SSL},
342 {CIPHER_NAME("HMAC-SHA256"), SEC_OID_HMAC_SHA256, NSS_USE_ALG_IN_SSL},
343 {CIPHER_NAME("HMAC-SHA384"), SEC_OID_HMAC_SHA384, NSS_USE_ALG_IN_SSL},
344 {CIPHER_NAME("HMAC-SHA512"), SEC_OID_HMAC_SHA512, NSS_USE_ALG_IN_SSL},
345 {CIPHER_NAME("HMAC-MD5"), SEC_OID_HMAC_MD5, NSS_USE_ALG_IN_SSL},
346
347 /* Ciphers */
348 {CIPHER_NAME("AES128-CBC"), SEC_OID_AES_128_CBC, NSS_USE_ALG_IN_SSL},
349 {CIPHER_NAME("AES192-CBC"), SEC_OID_AES_192_CBC, NSS_USE_ALG_IN_SSL},
350 {CIPHER_NAME("AES256-CBC"), SEC_OID_AES_256_CBC, NSS_USE_ALG_IN_SSL},
351 {CIPHER_NAME("AES128-GCM"), SEC_OID_AES_128_GCM, NSS_USE_ALG_IN_SSL},
352 {CIPHER_NAME("AES192-GCM"), SEC_OID_AES_192_GCM, NSS_USE_ALG_IN_SSL},
353 {CIPHER_NAME("AES256-GCM"), SEC_OID_AES_256_GCM, NSS_USE_ALG_IN_SSL},
354 {CIPHER_NAME("CAMELLIA128-CBC"), SEC_OID_CAMELLIA_128_CBC, NSS_USE_ALG_IN_SS L},
355 {CIPHER_NAME("CAMELLIA192-CBC"), SEC_OID_CAMELLIA_192_CBC, NSS_USE_ALG_IN_SS L},
356 {CIPHER_NAME("CAMELLIA256-CBC"), SEC_OID_CAMELLIA_256_CBC, NSS_USE_ALG_IN_SS L},
357 {CIPHER_NAME("CHACHA20-POLY1305"), SEC_OID_CHACHA20_POLY1305, NSS_USE_ALG_IN _SSL},
358 {CIPHER_NAME("SEED-CBC"), SEC_OID_SEED_CBC, NSS_USE_ALG_IN_SSL},
359 {CIPHER_NAME("DES-EDE3-CBC"), SEC_OID_DES_EDE3_CBC, NSS_USE_ALG_IN_SSL},
360 {CIPHER_NAME("DES-40-CBC"), SEC_OID_DES_40_CBC, NSS_USE_ALG_IN_SSL},
361 {CIPHER_NAME("DES-CBC"), SEC_OID_DES_CBC, NSS_USE_ALG_IN_SSL},
362 {CIPHER_NAME("NULL-CIPHER"), SEC_OID_NULL_CIPHER, NSS_USE_ALG_IN_SSL},
363 {CIPHER_NAME("RC2"), SEC_OID_RC2_CBC, NSS_USE_ALG_IN_SSL},
364 {CIPHER_NAME("RC4"), SEC_OID_RC4, NSS_USE_ALG_IN_SSL},
365 {CIPHER_NAME("IDEA"), SEC_OID_IDEA_CBC, NSS_USE_ALG_IN_SSL},
366
367 /* Key exchange */
368 {CIPHER_NAME("RSA"), SEC_OID_TLS_RSA, NSS_USE_ALG_IN_SSL_KX},
369 {CIPHER_NAME("RSA-EXPORT"), SEC_OID_TLS_RSA_EXPORT, NSS_USE_ALG_IN_SSL_KX},
370 {CIPHER_NAME("DHE-RSA"), SEC_OID_TLS_DHE_RSA, NSS_USE_ALG_IN_SSL_KX},
371 {CIPHER_NAME("DHE-DSS"), SEC_OID_TLS_DHE_DSS, NSS_USE_ALG_IN_SSL_KX},
372 {CIPHER_NAME("DH-RSA"), SEC_OID_TLS_DH_RSA, NSS_USE_ALG_IN_SSL_KX},
373 {CIPHER_NAME("DH-DSS"), SEC_OID_TLS_DH_DSS, NSS_USE_ALG_IN_SSL_KX},
374 {CIPHER_NAME("ECDHE-ECDSA"), SEC_OID_TLS_ECDHE_ECDSA, NSS_USE_ALG_IN_SSL_KX} ,
375 {CIPHER_NAME("ECDHE-RSA"), SEC_OID_TLS_ECDHE_RSA, NSS_USE_ALG_IN_SSL_KX},
376 {CIPHER_NAME("ECDH-ECDSA"), SEC_OID_TLS_ECDH_ECDSA, NSS_USE_ALG_IN_SSL_KX},
377 {CIPHER_NAME("ECDH-RSA"), SEC_OID_TLS_ECDH_RSA, NSS_USE_ALG_IN_SSL_KX},
378 };
379
380 static const optionFreeDef sslOptList[] = {
381 /* Versions */
382 {CIPHER_NAME("SSL2.0"), 0x002},
383 {CIPHER_NAME("SSL3.0"), 0x300},
384 {CIPHER_NAME("SSL3.1"), 0x301},
385 {CIPHER_NAME("TLS1.0"), 0x301},
386 {CIPHER_NAME("TLS1.1"), 0x302},
387 {CIPHER_NAME("TLS1.2"), 0x303},
388 {CIPHER_NAME("TLS1.3"), 0x304},
389 {CIPHER_NAME("DTLS1.0"),0x302},
390 {CIPHER_NAME("DTLS1.1"),0x302},
391 {CIPHER_NAME("DTLS1.2"),0x303},
392 {CIPHER_NAME("DTLS1.3"),0x304},
393 };
394
395 static const optionFreeDef freeOptList[] = {
396
397 /* Restrictions for asymetric keys */
398 {CIPHER_NAME("RSA-MIN"), NSS_RSA_MIN_KEY_SIZE},
399 {CIPHER_NAME("DH-MIN"), NSS_DH_MIN_KEY_SIZE},
400 {CIPHER_NAME("DSA-MIN"), NSS_DSA_MIN_KEY_SIZE},
401 /* constraints on SSL Protocols */
402 {CIPHER_NAME("TLS-VERSION-MIN"), NSS_TLS_VERSION_MIN_POLICY},
403 {CIPHER_NAME("TLS-VERSION-MAX"), NSS_TLS_VERSION_MAX_POLICY},
404 /* constraints on DTLS Protocols */
405 {CIPHER_NAME("DTLS-VERSION-MIN"), NSS_DTLS_VERSION_MIN_POLICY},
406 {CIPHER_NAME("DTLS-VERSION-MAX"), NSS_DTLS_VERSION_MIN_POLICY}
407 };
408
409 static const policyFlagDef policyFlagList[] = {
410 {CIPHER_NAME("SSL"), NSS_USE_ALG_IN_SSL},
411 {CIPHER_NAME("SSL-KEY-EXCHANGE"), NSS_USE_ALG_IN_SSL_KX},
412 /* add other key exhanges in the future */
413 {CIPHER_NAME("KEY-EXCHANGE"), NSS_USE_ALG_IN_SSL_KX},
414 {CIPHER_NAME("CERT-SIGNATURE"), NSS_USE_ALG_IN_CERT_SIGNATURE},
415 /* add other signatures in the future */
416 {CIPHER_NAME("SIGNATURE"), NSS_USE_ALG_IN_CERT_SIGNATURE},
417 /* enable everything */
418 {CIPHER_NAME("ALL"), NSS_USE_ALG_IN_SSL|NSS_USE_ALG_IN_SSL_KX|
419 NSS_USE_ALG_IN_CERT_SIGNATURE},
420 {CIPHER_NAME("NONE"), 0}
421 };
422
423 /*
424 * Get the next cipher on the list. point to the next one in 'next'.
425 * return the length;
426 */
427 static const char *
428 secmod_ArgGetSubValue(const char *cipher, char sep1, char sep2,
429 int *len, const char **next)
430 {
431 const char *start = cipher;
432
433 if (start == NULL) {
434 *len = 0;
435 *next = NULL;
436 return start;
437 }
438
439 for (; *cipher && *cipher != sep2; cipher++) {
440 if (*cipher == sep1) {
441 *next = cipher+1;
442 *len = cipher - start;
443 return start;
444 }
445 }
446 *next = NULL;
447 *len = cipher-start;
448 return start;
449 }
450
451 static PRUint32
452 secmod_parsePolicyValue(const char *policyFlags, int policyLength)
453 {
454 const char *flag, *currentString;
455 PRUint32 flags = 0;
456 int i;
457
458 for (currentString = policyFlags; currentString
459 && currentString < policyFlags + policyLength; ) {
460 int length;
461 flag = secmod_ArgGetSubValue(currentString, ',', ':', &length,
462 &currentString);
463 if (length == 0) {
464 continue;
465 }
466 for (i = 0; i < PR_ARRAY_SIZE(policyFlagList); i++) {
467 const policyFlagDef *policy = &policyFlagList[i];
468 unsigned name_size = policy->name_size;
469 if ((policy->name_size == length) &&
470 PORT_Strncasecmp(policy->name, flag, name_size) == 0) {
471 flags |= policy->flag;
472 break;
473 }
474 }
475 }
476 return flags;
477 }
478
479
480 /* allow symbolic names for values. The only ones currently defines or
481 * SSL protocol versions. */
482 static PRInt32
483 secmod_getPolicyOptValue(const char *policyValue, int policyValueLength)
484 {
485 PRInt32 val = atoi(policyValue);
486 int i;
487
488
489 if ((val != 0) || (*policyValue == '0')) {
490 return val;
491 }
492 for (i = 0; i < PR_ARRAY_SIZE(sslOptList); i++) {
493 if (policyValueLength == sslOptList[i].name_size &&
494 PORT_Strncasecmp(sslOptList[i].name, policyValue,
495 sslOptList[i].name_size) == 0 ) {
496 val = sslOptList[i].option;
497 break;
498 }
499 }
500 return val;
501 }
502
503 static SECStatus secmod_applyCryptoPolicy(const char *policyString,
504 PRBool allow)
505 {
506 const char *cipher, *currentString;
507 unsigned i;
508 SECStatus rv = SECSuccess;
509 PRBool unknown;
510
511
512 if (policyString == NULL || policyString[0] == 0) {
513 return SECSuccess; /* do nothing */
514 }
515
516 /* if we change any of these, make sure it gets applied in ssl as well */
517 NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL, 0);
518
519 for (currentString = policyString; currentString; ) {
520 int length;
521 PRBool newValue = PR_FALSE;
522
523 cipher = secmod_ArgGetSubValue(currentString, ':', 0, &length,
524 &currentString);
525 unknown = PR_TRUE;
526 if (length >= 3 && cipher[3] == '/') {
527 newValue = PR_TRUE;
528 }
529 if ((newValue || (length == 3))
530 && PORT_Strncasecmp(cipher, "all", 3) == 0) {
531 /* disable or enable all options by default */
532 PRUint32 value = 0;
533 if (newValue) {
534 value = secmod_parsePolicyValue(&cipher[3]+1, length-3-1);
535 }
536 for (i = 0; i < PR_ARRAY_SIZE(algOptList); i++) {
537 PRUint32 enable, disable;
538 if (!newValue) {
539 value = algOptList[i].val;
540 }
541 if (allow) {
542 enable = value;
543 disable = 0;
544 } else {
545 enable = 0;
546 disable = value;
547 }
548 NSS_SetAlgorithmPolicy(algOptList[i].oid, enable, disable);
549 }
550 continue;
551 }
552
553 for (i = 0; i < PR_ARRAY_SIZE(algOptList); i++) {
554 const oidValDef *algOpt = &algOptList[i];
555 unsigned name_size = algOpt->name_size;
556 PRBool newValue = PR_FALSE;
557
558 if ((length >= name_size) && (cipher[name_size] == '/')) {
559 newValue = PR_TRUE;
560 }
561 if ( (newValue || algOpt->name_size == length) &&
562 PORT_Strncasecmp(algOpt->name, cipher, name_size) == 0) {
563 PRUint32 value = algOpt->val;
564 PRUint32 enable, disable;
565 if (newValue) {
566 value = secmod_parsePolicyValue(&cipher[name_size]+1,
567 length-name_size-1);
568 }
569 if (allow) {
570 enable = value;
571 disable = 0;
572 } else {
573 enable = 0;
574 disable = value;
575 }
576 rv = NSS_SetAlgorithmPolicy(algOpt->oid, enable, disable);
577 if (rv != SECSuccess) {
578 /* could not enable option */
579 /* NSS_SetAlgorithPolicy should have set the error code */
580 return SECFailure;
581 }
582 unknown = PR_FALSE;
583 break;
584 }
585 }
586 if (!unknown) {
587 continue;
588 }
589
590 for (i = 0; i < PR_ARRAY_SIZE(freeOptList); i++) {
591 const optionFreeDef *freeOpt = &freeOptList[i];
592 unsigned name_size = freeOpt->name_size;
593
594 if ((length > name_size) && cipher[name_size] == '=' &&
595 PORT_Strncasecmp(freeOpt->name, cipher, name_size) == 0 ) {
596 PRInt32 val = secmod_getPolicyOptValue( &cipher[name_size+1],
597 length-name_size-1);
598
599 rv = NSS_OptionSet(freeOpt->option, val);
600 if (rv != SECSuccess) {
601 /* could not enable option */
602 /* NSS_OptionSet should have set the error code */
603 return SECFailure;
604 }
605 /* to allow the policy to expand in the future. ignore ciphers
606 * we don't understand */
607 unknown = PR_FALSE;
608 break;
609 }
610 }
611 }
612 return rv;
613 }
614
615 static SECStatus
616 secmod_parseCryptoPolicy(const char *policyConfig)
617 {
618 char *disallow, *allow;
619 SECStatus rv;
620
621 if (policyConfig == NULL) {
622 return SECSuccess; /* no policy given */
623 }
624 /* make sure we initialize the oid table and set all the default policy
625 * values first so we can override them here */
626 rv = SECOID_Init();
627 if (rv != SECSuccess) {
628 return rv;
629 }
630 disallow = NSSUTIL_ArgGetParamValue("disallow",policyConfig);
631 rv = secmod_applyCryptoPolicy(disallow, PR_FALSE);
632 if (disallow) PORT_Free(disallow);
633 if (rv != SECSuccess) {
634 return rv;
635 }
636 allow = NSSUTIL_ArgGetParamValue("allow",policyConfig);
637 rv = secmod_applyCryptoPolicy(allow, PR_TRUE);
638 if (allow) PORT_Free(allow);
639 return rv;
640 }
641
642 /*
643 * for 3.4 we continue to use the old SECMODModule structure
644 */
645 SECMODModule *
646 SECMOD_CreateModuleEx(const char *library, const char *moduleName,
647 const char *parameters, const char *nss,
648 const char *config)
649 {
650 SECMODModule *mod;
651 SECStatus rv;
652 char *slotParams,*ciphers;
653 /* pk11pars.h still does not have const char * interfaces */
654 char *nssc = (char *)nss;
655
656 rv = secmod_parseCryptoPolicy(config);
657
658 /* do not load the module if policy parsing fails */
659 if (rv != SECSuccess) {
660 return NULL;
661 }
662
663 mod = secmod_NewModule();
664 if (mod == NULL) return NULL;
665
666 mod->commonName = PORT_ArenaStrdup(mod->arena,moduleName ? moduleName : "");
667 if (library) {
668 mod->dllName = PORT_ArenaStrdup(mod->arena,library);
669 }
670 /* new field */
671 if (parameters) {
672 mod->libraryParams = PORT_ArenaStrdup(mod->arena,parameters);
673 }
674
675 mod->internal = NSSUTIL_ArgHasFlag("flags","internal",nssc);
676 mod->isFIPS = NSSUTIL_ArgHasFlag("flags","FIPS",nssc);
677 mod->isCritical = NSSUTIL_ArgHasFlag("flags","critical",nssc);
678 slotParams = NSSUTIL_ArgGetParamValue("slotParams",nssc);
679 mod->slotInfo = NSSUTIL_ArgParseSlotInfo(mod->arena,slotParams,
680 &mod->slotInfoCount);
681 if (slotParams) PORT_Free(slotParams);
682 /* new field */
683 mod->trustOrder = NSSUTIL_ArgReadLong("trustOrder",nssc,
684 NSSUTIL_DEFAULT_TRUST_ORDER,NULL);
685 /* new field */
686 mod->cipherOrder = NSSUTIL_ArgReadLong("cipherOrder",nssc,
687 NSSUTIL_DEFAULT_CIPHER_ORDER,NULL);
688 /* new field */
689 mod->isModuleDB = NSSUTIL_ArgHasFlag("flags","moduleDB",nssc);
690 mod->moduleDBOnly = NSSUTIL_ArgHasFlag("flags","moduleDBOnly",nssc);
691 if (mod->moduleDBOnly) mod->isModuleDB = PR_TRUE;
692
693 /* we need more bits, but we also want to preserve binary compatibility
694 * so we overload the isModuleDB PRBool with additional flags.
695 * These flags are only valid if mod->isModuleDB is already set.
696 * NOTE: this depends on the fact that PRBool is at least a char on
697 * all platforms. These flags are only valid if moduleDB is set, so
698 * code checking if (mod->isModuleDB) will continue to work correctly. */
699 if (mod->isModuleDB) {
700 char flags = SECMOD_FLAG_MODULE_DB_IS_MODULE_DB;
701 if (NSSUTIL_ArgHasFlag("flags","skipFirst",nssc)) {
702 flags |= SECMOD_FLAG_MODULE_DB_SKIP_FIRST;
703 }
704 if (NSSUTIL_ArgHasFlag("flags","defaultModDB",nssc)) {
705 flags |= SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB;
706 }
707 /* additional moduleDB flags could be added here in the future */
708 mod->isModuleDB = (PRBool) flags;
709 }
710
711 if (mod->internal) {
712 char flags = SECMOD_FLAG_INTERNAL_IS_INTERNAL;
713
714 if (NSSUTIL_ArgHasFlag("flags", "internalKeySlot", nssc)) {
715 flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT;
716 }
717 mod->internal = (PRBool) flags;
718 }
719
720 ciphers = NSSUTIL_ArgGetParamValue("ciphers",nssc);
721 NSSUTIL_ArgParseCipherFlags(&mod->ssl[0],ciphers);
722 if (ciphers) PORT_Free(ciphers);
723
724 secmod_PrivateModuleCount++;
725
726 return mod;
727 }
728
729 PRBool
730 SECMOD_GetSkipFirstFlag(SECMODModule *mod)
731 {
732 char flags = (char) mod->isModuleDB;
733
734 return (flags & SECMOD_FLAG_MODULE_DB_SKIP_FIRST) ? PR_TRUE : PR_FALSE;
735 }
736
737 PRBool
738 SECMOD_GetDefaultModDBFlag(SECMODModule *mod)
739 {
740 char flags = (char) mod->isModuleDB;
741
742 return (flags & SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB) ? PR_TRUE : PR_FALSE;
743 }
744
745 PRBool
746 secmod_IsInternalKeySlot(SECMODModule *mod)
747 {
748 char flags = (char) mod->internal;
749
750 return (flags & SECMOD_FLAG_INTERNAL_KEY_SLOT) ? PR_TRUE : PR_FALSE;
751 }
752
753 void
754 secmod_SetInternalKeySlotFlag(SECMODModule *mod, PRBool val)
755 {
756 char flags = (char) mod->internal;
757
758 if (val) {
759 flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT;
760 } else {
761 flags &= ~SECMOD_FLAG_INTERNAL_KEY_SLOT;
762 }
763 mod->internal = flags;
764 }
765
766 /*
767 * copy desc and value into target. Target is known to be big enough to
768 * hold desc +2 +value, which is good because the result of this will be
769 * *desc"*value". We may, however, have to add some escapes for special
770 * characters imbedded into value (rare). This string potentially comes from
771 * a user, so we don't want the user overflowing the target buffer by using
772 * excessive escapes. To prevent this we count the escapes we need to add and
773 * try to expand the buffer with Realloc.
774 */
775 static char *
776 secmod_doDescCopy(char *target, int *targetLen, const char *desc,
777 int descLen, char *value)
778 {
779 int diff, esc_len;
780
781 esc_len = NSSUTIL_EscapeSize(value, '\"') - 1;
782 diff = esc_len - strlen(value);
783 if (diff > 0) {
784 /* we need to escape... expand newSpecPtr as well to make sure
785 * we don't overflow it */
786 char *newPtr = PORT_Realloc(target, *targetLen * diff);
787 if (!newPtr) {
788 return target; /* not enough space, just drop the whole copy */
789 }
790 *targetLen += diff;
791 target = newPtr;
792 value = NSSUTIL_Escape(value, '\"');
793 if (value == NULL) {
794 return target; /* couldn't escape value, just drop the copy */
795 }
796 }
797 PORT_Memcpy(target, desc, descLen);
798 target += descLen;
799 *target++='\"';
800 PORT_Memcpy(target, value, esc_len);
801 target += esc_len;
802 *target++='\"';
803 if (diff > 0) {
804 PORT_Free(value);
805 }
806 return target;
807 }
808
809 #define SECMOD_SPEC_COPY(new, start, end) \
810 if (end > start) { \
811 int _cnt = end - start; \
812 PORT_Memcpy(new, start, _cnt); \
813 new += _cnt; \
814 }
815 #define SECMOD_TOKEN_DESCRIPTION "tokenDescription="
816 #define SECMOD_SLOT_DESCRIPTION "slotDescription="
817
818
819 /*
820 * Find any tokens= values in the module spec.
821 * Always return a new spec which does not have any tokens= arguments.
822 * If tokens= arguments are found, Split the the various tokens defined into
823 * an array of child specs to return.
824 *
825 * Caller is responsible for freeing the child spec and the new token
826 * spec.
827 */
828 char *
829 secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
830 const char *moduleSpec, char ***children,
831 CK_SLOT_ID **ids)
832 {
833 int newSpecLen = PORT_Strlen(moduleSpec)+2;
834 char *newSpec = PORT_Alloc(newSpecLen);
835 char *newSpecPtr = newSpec;
836 const char *modulePrev = moduleSpec;
837 char *target = NULL;
838 char *tmp = NULL;
839 char **childArray = NULL;
840 const char *tokenIndex;
841 CK_SLOT_ID *idArray = NULL;
842 int tokenCount = 0;
843 int i;
844
845 if (newSpec == NULL) {
846 return NULL;
847 }
848
849 *children = NULL;
850 if (ids) {
851 *ids = NULL;
852 }
853 moduleSpec = NSSUTIL_ArgStrip(moduleSpec);
854 SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec);
855
856 /* Notes on 'convert' and 'isFIPS' flags: The base parameters for opening
857 * a new softoken module takes the following parameters to name the
858 * various tokens:
859 *
860 * cryptoTokenDescription: name of the non-fips crypto token.
861 * cryptoSlotDescription: name of the non-fips crypto slot.
862 * dbTokenDescription: name of the non-fips db token.
863 * dbSlotDescription: name of the non-fips db slot.
864 * FIPSTokenDescription: name of the fips db/crypto token.
865 * FIPSSlotDescription: name of the fips db/crypto slot.
866 *
867 * if we are opening a new slot, we need to have the following
868 * parameters:
869 * tokenDescription: name of the token.
870 * slotDescription: name of the slot.
871 *
872 *
873 * The convert flag tells us to drop the unnecessary *TokenDescription
874 * and *SlotDescription arguments and convert the appropriate pair
875 * (either db or FIPS based on the isFIPS flag) to tokenDescription and
876 * slotDescription).
877 */
878 /*
879 * walk down the list. if we find a tokens= argument, save it,
880 * otherise copy the argument.
881 */
882 while (*moduleSpec) {
883 int next;
884 modulePrev = moduleSpec;
885 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, target, "tokens=",
886 modulePrev = moduleSpec; /* skip copying */ )
887 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoTokenDescription=",
888 if (convert) { modulePrev = moduleSpec; } );
889 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoSlotDescription=",
890 if (convert) { modulePrev = moduleSpec; } );
891 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "dbTokenDescription=",
892 if (convert) {
893 modulePrev = moduleSpec;
894 if (!isFIPS) {
895 newSpecPtr = secmod_doDescCopy(newSpecPtr,
896 &newSpecLen, SECMOD_TOKEN_DESCRIPTION,
897 sizeof(SECMOD_TOKEN_DESCRIPTION)-1, tmp);
898 }
899 });
900 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "dbSlotDescription=",
901 if (convert) {
902 modulePrev = moduleSpec; /* skip copying */
903 if (!isFIPS) {
904 newSpecPtr = secmod_doDescCopy(newSpecPtr,
905 &newSpecLen, SECMOD_SLOT_DESCRIPTION,
906 sizeof(SECMOD_SLOT_DESCRIPTION)-1, tmp);
907 }
908 } );
909 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSTokenDescription=",
910 if (convert) {
911 modulePrev = moduleSpec; /* skip copying */
912 if (isFIPS) {
913 newSpecPtr = secmod_doDescCopy(newSpecPtr,
914 &newSpecLen, SECMOD_TOKEN_DESCRIPTION,
915 sizeof(SECMOD_TOKEN_DESCRIPTION)-1, tmp);
916 }
917 } );
918 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSSlotDescription=",
919 if (convert) {
920 modulePrev = moduleSpec; /* skip copying */
921 if (isFIPS) {
922 newSpecPtr = secmod_doDescCopy(newSpecPtr,
923 &newSpecLen, SECMOD_SLOT_DESCRIPTION,
924 sizeof(SECMOD_SLOT_DESCRIPTION)-1, tmp);
925 }
926 } );
927 NSSUTIL_HANDLE_FINAL_ARG(moduleSpec)
928 SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec);
929 }
930 if (tmp) {
931 PORT_Free(tmp);
932 tmp = NULL;
933 }
934 *newSpecPtr = 0;
935
936 /* no target found, return the newSpec */
937 if (target == NULL) {
938 return newSpec;
939 }
940
941 /* now build the child array from target */
942 /*first count them */
943 for (tokenIndex = NSSUTIL_ArgStrip(target); *tokenIndex;
944 tokenIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(tokenIndex))) {
945 tokenCount++;
946 }
947
948 childArray = PORT_NewArray(char *, tokenCount+1);
949 if (childArray == NULL) {
950 /* just return the spec as is then */
951 PORT_Free(target);
952 return newSpec;
953 }
954 if (ids) {
955 idArray = PORT_NewArray(CK_SLOT_ID, tokenCount+1);
956 if (idArray == NULL) {
957 PORT_Free(childArray);
958 PORT_Free(target);
959 return newSpec;
960 }
961 }
962
963 /* now fill them in */
964 for (tokenIndex = NSSUTIL_ArgStrip(target), i=0 ;
965 *tokenIndex && (i < tokenCount);
966 tokenIndex=NSSUTIL_ArgStrip(tokenIndex)) {
967 int next;
968 char *name = NSSUTIL_ArgGetLabel(tokenIndex, &next);
969 tokenIndex += next;
970
971 if (idArray) {
972 idArray[i] = NSSUTIL_ArgDecodeNumber(name);
973 }
974
975 PORT_Free(name); /* drop the explicit number */
976
977 /* if anything is left, copy the args to the child array */
978 if (!NSSUTIL_ArgIsBlank(*tokenIndex)) {
979 childArray[i++] = NSSUTIL_ArgFetchValue(tokenIndex, &next);
980 tokenIndex += next;
981 }
982 }
983
984 PORT_Free(target);
985 childArray[i] = 0;
986 if (idArray) {
987 idArray[i] = 0;
988 }
989
990 /* return it */
991 *children = childArray;
992 if (ids) {
993 *ids = idArray;
994 }
995 return newSpec;
996 }
997
998 /* get the database and flags from the spec */
999 static char *
1000 secmod_getConfigDir(const char *spec, char **certPrefix, char **keyPrefix,
1001 PRBool *readOnly)
1002 {
1003 char * config = NULL;
1004
1005 *certPrefix = NULL;
1006 *keyPrefix = NULL;
1007 *readOnly = NSSUTIL_ArgHasFlag("flags","readOnly",spec);
1008
1009 spec = NSSUTIL_ArgStrip(spec);
1010 while (*spec) {
1011 int next;
1012 NSSUTIL_HANDLE_STRING_ARG(spec, config, "configdir=", ;)
1013 NSSUTIL_HANDLE_STRING_ARG(spec, *certPrefix, "certPrefix=", ;)
1014 NSSUTIL_HANDLE_STRING_ARG(spec, *keyPrefix, "keyPrefix=", ;)
1015 NSSUTIL_HANDLE_FINAL_ARG(spec)
1016 }
1017 return config;
1018 }
1019
1020 struct SECMODConfigListStr {
1021 char *config;
1022 char *certPrefix;
1023 char *keyPrefix;
1024 PRBool isReadOnly;
1025 };
1026
1027 /*
1028 * return an array of already openned databases from a spec list.
1029 */
1030 SECMODConfigList *
1031 secmod_GetConfigList(PRBool isFIPS, char *spec, int *count)
1032 {
1033 char **children;
1034 CK_SLOT_ID *ids;
1035 char *strippedSpec;
1036 int childCount;
1037 SECMODConfigList *conflist = NULL;
1038 int i;
1039
1040 strippedSpec = secmod_ParseModuleSpecForTokens(PR_TRUE, isFIPS,
1041 spec,&children,&ids);
1042 if (strippedSpec == NULL) {
1043 return NULL;
1044 }
1045
1046 for (childCount=0; children && children[childCount]; childCount++) ;
1047 *count = childCount+1; /* include strippedSpec */
1048 conflist = PORT_NewArray(SECMODConfigList,*count);
1049 if (conflist == NULL) {
1050 *count = 0;
1051 goto loser;
1052 }
1053
1054 conflist[0].config = secmod_getConfigDir(strippedSpec,
1055 &conflist[0].certPrefix,
1056 &conflist[0].keyPrefix,
1057 &conflist[0].isReadOnly);
1058 for (i=0; i < childCount; i++) {
1059 conflist[i+1].config = secmod_getConfigDir(children[i],
1060 &conflist[i+1].certPrefix,
1061 &conflist[i+1].keyPrefix,
1062 &conflist[i+1].isReadOnly);
1063 }
1064
1065 loser:
1066 secmod_FreeChildren(children, ids);
1067 PORT_Free(strippedSpec);
1068 return conflist;
1069 }
1070
1071 /*
1072 * determine if we are trying to open an old dbm database. For this test
1073 * RDB databases should return PR_FALSE.
1074 */
1075 static PRBool
1076 secmod_configIsDBM(char *configDir)
1077 {
1078 char *env;
1079
1080 /* explicit dbm open */
1081 if (strncmp(configDir, "dbm:", 4) == 0) {
1082 return PR_TRUE;
1083 }
1084 /* explicit open of a non-dbm database */
1085 if ((strncmp(configDir, "sql:",4) == 0)
1086 || (strncmp(configDir, "rdb:", 4) == 0)
1087 || (strncmp(configDir, "extern:", 7) == 0)) {
1088 return PR_FALSE;
1089 }
1090 env = PR_GetEnvSecure("NSS_DEFAULT_DB_TYPE");
1091 /* implicit dbm open */
1092 if ((env == NULL) || (strcmp(env,"dbm") == 0)) {
1093 return PR_TRUE;
1094 }
1095 /* implicit non-dbm open */
1096 return PR_FALSE;
1097 }
1098
1099 /*
1100 * match two prefixes. prefix may be NULL. NULL patches '\0'
1101 */
1102 static PRBool
1103 secmod_matchPrefix(char *prefix1, char *prefix2)
1104 {
1105 if ((prefix1 == NULL) || (*prefix1 == 0)) {
1106 if ((prefix2 == NULL) || (*prefix2 == 0)) {
1107 return PR_TRUE;
1108 }
1109 return PR_FALSE;
1110 }
1111 if (strcmp(prefix1, prefix2) == 0) {
1112 return PR_TRUE;
1113 }
1114 return PR_FALSE;
1115 }
1116
1117 /*
1118 * return true if we are requesting a database that is already openned.
1119 */
1120 PRBool
1121 secmod_MatchConfigList(char *spec, SECMODConfigList *conflist, int count)
1122 {
1123 char *config;
1124 char *certPrefix;
1125 char *keyPrefix;
1126 PRBool isReadOnly;
1127 PRBool ret=PR_FALSE;
1128 int i;
1129
1130 config = secmod_getConfigDir(spec, &certPrefix, &keyPrefix, &isReadOnly);
1131 if (!config) {
1132 ret=PR_TRUE;
1133 goto done;
1134 }
1135
1136 /* NOTE: we dbm isn't multiple open safe. If we open the same database
1137 * twice from two different locations, then we can corrupt our database
1138 * (the cache will be inconsistent). Protect against this by claiming
1139 * for comparison only that we are always openning dbm databases read only.
1140 */
1141 if (secmod_configIsDBM(config)) {
1142 isReadOnly = 1;
1143 }
1144 for (i=0; i < count; i++) {
1145 if ((strcmp(config,conflist[i].config) == 0) &&
1146 secmod_matchPrefix(certPrefix, conflist[i].certPrefix) &&
1147 secmod_matchPrefix(keyPrefix, conflist[i].keyPrefix) &&
1148 /* this last test -- if we just need the DB open read only,
1149 * than any open will suffice, but if we requested it read/write
1150 * and it's only open read only, we need to open it again */
1151 (isReadOnly || !conflist[i].isReadOnly)) {
1152 ret = PR_TRUE;
1153 goto done;
1154 }
1155 }
1156
1157 ret = PR_FALSE;
1158 done:
1159 PORT_Free(config);
1160 PORT_Free(certPrefix);
1161 PORT_Free(keyPrefix);
1162 return ret;
1163 }
1164
1165 void
1166 secmod_FreeConfigList(SECMODConfigList *conflist, int count)
1167 {
1168 int i;
1169 for (i=0; i < count; i++) {
1170 PORT_Free(conflist[i].config);
1171 PORT_Free(conflist[i].certPrefix);
1172 PORT_Free(conflist[i].keyPrefix);
1173 }
1174 PORT_Free(conflist);
1175 }
1176
1177 void
1178 secmod_FreeChildren(char **children, CK_SLOT_ID *ids)
1179 {
1180 char **thisChild;
1181
1182 if (!children) {
1183 return;
1184 }
1185
1186 for (thisChild = children; thisChild && *thisChild; thisChild++ ) {
1187 PORT_Free(*thisChild);
1188 }
1189 PORT_Free(children);
1190 if (ids) {
1191 PORT_Free(ids);
1192 }
1193 return;
1194 }
1195
1196 /*
1197 * caclulate the length of each child record:
1198 * " 0x{id}=<{escaped_child}>"
1199 */
1200 static int
1201 secmod_getChildLength(char *child, CK_SLOT_ID id)
1202 {
1203 int length = NSSUTIL_DoubleEscapeSize(child, '>', ']');
1204 if (id == 0) {
1205 length++;
1206 }
1207 while (id) {
1208 length++;
1209 id = id >> 4;
1210 }
1211 length += 6; /* {sp}0x[id]=<{child}> */
1212 return length;
1213 }
1214
1215 /*
1216 * Build a child record:
1217 * " 0x{id}=<{escaped_child}>"
1218 */
1219 static SECStatus
1220 secmod_mkTokenChild(char **next, int *length, char *child, CK_SLOT_ID id)
1221 {
1222 int len;
1223 char *escSpec;
1224
1225 len = PR_snprintf(*next, *length, " 0x%x=<",id);
1226 if (len < 0) {
1227 return SECFailure;
1228 }
1229 *next += len;
1230 *length -= len;
1231 escSpec = NSSUTIL_DoubleEscape(child, '>', ']');
1232 if (escSpec == NULL) {
1233 return SECFailure;
1234 }
1235 if (*child && (*escSpec == 0)) {
1236 PORT_Free(escSpec);
1237 return SECFailure;
1238 }
1239 len = strlen(escSpec);
1240 if (len+1 > *length) {
1241 PORT_Free(escSpec);
1242 return SECFailure;
1243 }
1244 PORT_Memcpy(*next,escSpec, len);
1245 *next += len;
1246 *length -= len;
1247 PORT_Free(escSpec);
1248 **next = '>';
1249 (*next)++;
1250 (*length)--;
1251 return SECSuccess;
1252 }
1253
1254 #define TOKEN_STRING " tokens=["
1255
1256 char *
1257 secmod_MkAppendTokensList(PLArenaPool *arena, char *oldParam, char *newToken,
1258 CK_SLOT_ID newID, char **children, CK_SLOT_ID *ids)
1259 {
1260 char *rawParam = NULL; /* oldParam with tokens stripped off */
1261 char *newParam = NULL; /* space for the return parameter */
1262 char *nextParam = NULL; /* current end of the new parameter */
1263 char **oldChildren = NULL;
1264 CK_SLOT_ID *oldIds = NULL;
1265 void *mark = NULL; /* mark the arena pool in case we need
1266 * to release it */
1267 int length, i, tmpLen;
1268 SECStatus rv;
1269
1270 /* first strip out and save the old tokenlist */
1271 rawParam = secmod_ParseModuleSpecForTokens(PR_FALSE,PR_FALSE,
1272 oldParam,&oldChildren,&oldIds);
1273 if (!rawParam) {
1274 goto loser;
1275 }
1276
1277 /* now calculate the total length of the new buffer */
1278 /* First the 'fixed stuff', length of rawparam (does not include a NULL),
1279 * length of the token string (does include the NULL), closing bracket */
1280 length = strlen(rawParam) + sizeof(TOKEN_STRING) + 1;
1281 /* now add then length of all the old children */
1282 for (i=0; oldChildren && oldChildren[i]; i++) {
1283 length += secmod_getChildLength(oldChildren[i], oldIds[i]);
1284 }
1285
1286 /* add the new token */
1287 length += secmod_getChildLength(newToken, newID);
1288
1289 /* and it's new children */
1290 for (i=0; children && children[i]; i++) {
1291 if (ids[i] == -1) {
1292 continue;
1293 }
1294 length += secmod_getChildLength(children[i], ids[i]);
1295 }
1296
1297 /* now allocate and build the string */
1298 mark = PORT_ArenaMark(arena);
1299 if (!mark) {
1300 goto loser;
1301 }
1302 newParam = PORT_ArenaAlloc(arena,length);
1303 if (!newParam) {
1304 goto loser;
1305 }
1306
1307 PORT_Strcpy(newParam, oldParam);
1308 tmpLen = strlen(oldParam);
1309 nextParam = newParam + tmpLen;
1310 length -= tmpLen;
1311 PORT_Memcpy(nextParam, TOKEN_STRING, sizeof(TOKEN_STRING)-1);
1312 nextParam += sizeof(TOKEN_STRING)-1;
1313 length -= sizeof(TOKEN_STRING)-1;
1314
1315 for (i=0; oldChildren && oldChildren[i]; i++) {
1316 rv = secmod_mkTokenChild(&nextParam,&length,oldChildren[i],oldIds[i]);
1317 if (rv != SECSuccess) {
1318 goto loser;
1319 }
1320 }
1321
1322 rv = secmod_mkTokenChild(&nextParam, &length, newToken, newID);
1323 if (rv != SECSuccess) {
1324 goto loser;
1325 }
1326
1327 for (i=0; children && children[i]; i++) {
1328 if (ids[i] == -1) {
1329 continue;
1330 }
1331 rv = secmod_mkTokenChild(&nextParam, &length, children[i], ids[i]);
1332 if (rv != SECSuccess) {
1333 goto loser;
1334 }
1335 }
1336
1337 if (length < 2) {
1338 goto loser;
1339 }
1340
1341 *nextParam++ = ']';
1342 *nextParam++ = 0;
1343
1344 /* we are going to return newParam now, don't release the mark */
1345 PORT_ArenaUnmark(arena, mark);
1346 mark = NULL;
1347
1348 loser:
1349 if (mark) {
1350 PORT_ArenaRelease(arena, mark);
1351 newParam = NULL; /* if the mark is still active,
1352 * don't return the param */
1353 }
1354 if (rawParam) {
1355 PORT_Free(rawParam);
1356 }
1357 if (oldChildren) {
1358 secmod_FreeChildren(oldChildren, oldIds);
1359 }
1360 return newParam;
1361 }
1362
1363 static char *
1364 secmod_mkModuleSpec(SECMODModule * module)
1365 {
1366 char *nss = NULL, *modSpec = NULL, **slotStrings = NULL;
1367 int slotCount, i, si;
1368 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
1369
1370 /* allocate target slot info strings */
1371 slotCount = 0;
1372
1373 SECMOD_GetReadLock(moduleLock);
1374 if (module->slotCount) {
1375 for (i=0; i < module->slotCount; i++) {
1376 if (module->slots[i]->defaultFlags !=0) {
1377 slotCount++;
1378 }
1379 }
1380 } else {
1381 slotCount = module->slotInfoCount;
1382 }
1383
1384 slotStrings = (char **)PORT_ZAlloc(slotCount*sizeof(char *));
1385 if (slotStrings == NULL) {
1386 SECMOD_ReleaseReadLock(moduleLock);
1387 goto loser;
1388 }
1389
1390
1391 /* build the slot info strings */
1392 if (module->slotCount) {
1393 for (i=0, si= 0; i < module->slotCount; i++) {
1394 if (module->slots[i]->defaultFlags) {
1395 PORT_Assert(si < slotCount);
1396 if (si >= slotCount) break;
1397 slotStrings[si] = NSSUTIL_MkSlotString(module->slots[i]->slotID,
1398 module->slots[i]->defaultFlags,
1399 module->slots[i]->timeout,
1400 module->slots[i]->askpw,
1401 module->slots[i]->hasRootCerts,
1402 module->slots[i]->hasRootTrust);
1403 si++;
1404 }
1405 }
1406 } else {
1407 for (i=0; i < slotCount; i++) {
1408 slotStrings[i] = NSSUTIL_MkSlotString(
1409 module->slotInfo[i].slotID,
1410 module->slotInfo[i].defaultFlags,
1411 module->slotInfo[i].timeout,
1412 module->slotInfo[i].askpw,
1413 module->slotInfo[i].hasRootCerts,
1414 module->slotInfo[i].hasRootTrust);
1415 }
1416 }
1417
1418 SECMOD_ReleaseReadLock(moduleLock);
1419 nss = NSSUTIL_MkNSSString(slotStrings,slotCount,module->internal,
1420 module->isFIPS, module->isModuleDB,
1421 module->moduleDBOnly, module->isCritical,
1422 module->trustOrder, module->cipherOrder,
1423 module->ssl[0],module->ssl[1]);
1424 modSpec= NSSUTIL_MkModuleSpec(module->dllName,module->commonName,
1425 module->libraryParams,nss);
1426 PORT_Free(slotStrings);
1427 PR_smprintf_free(nss);
1428 loser:
1429 return (modSpec);
1430 }
1431
1432
1433 char **
1434 SECMOD_GetModuleSpecList(SECMODModule *module)
1435 {
1436 SECMODModuleDBFunc func = (SECMODModuleDBFunc) module->moduleDBFunc;
1437 if (func) {
1438 return (*func)(SECMOD_MODULE_DB_FUNCTION_FIND,
1439 module->libraryParams,NULL);
1440 }
1441 return NULL;
1442 }
1443
1444 SECStatus
1445 SECMOD_AddPermDB(SECMODModule *module)
1446 {
1447 SECMODModuleDBFunc func;
1448 char *moduleSpec;
1449 char **retString;
1450
1451 if (module->parent == NULL) return SECFailure;
1452
1453 func = (SECMODModuleDBFunc) module->parent->moduleDBFunc;
1454 if (func) {
1455 moduleSpec = secmod_mkModuleSpec(module);
1456 retString = (*func)(SECMOD_MODULE_DB_FUNCTION_ADD,
1457 module->parent->libraryParams,moduleSpec);
1458 PORT_Free(moduleSpec);
1459 if (retString != NULL) return SECSuccess;
1460 }
1461 return SECFailure;
1462 }
1463
1464 SECStatus
1465 SECMOD_DeletePermDB(SECMODModule *module)
1466 {
1467 SECMODModuleDBFunc func;
1468 char *moduleSpec;
1469 char **retString;
1470
1471 if (module->parent == NULL) return SECFailure;
1472
1473 func = (SECMODModuleDBFunc) module->parent->moduleDBFunc;
1474 if (func) {
1475 moduleSpec = secmod_mkModuleSpec(module);
1476 retString = (*func)(SECMOD_MODULE_DB_FUNCTION_DEL,
1477 module->parent->libraryParams,moduleSpec);
1478 PORT_Free(moduleSpec);
1479 if (retString != NULL) return SECSuccess;
1480 }
1481 return SECFailure;
1482 }
1483
1484 SECStatus
1485 SECMOD_FreeModuleSpecList(SECMODModule *module, char **moduleSpecList)
1486 {
1487 SECMODModuleDBFunc func = (SECMODModuleDBFunc) module->moduleDBFunc;
1488 char **retString;
1489 if (func) {
1490 retString = (*func)(SECMOD_MODULE_DB_FUNCTION_RELEASE,
1491 module->libraryParams,moduleSpecList);
1492 if (retString != NULL) return SECSuccess;
1493 }
1494 return SECFailure;
1495 }
1496
1497 /*
1498 * load a PKCS#11 module but do not add it to the default NSS trust domain
1499 */
1500 SECMODModule *
1501 SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse)
1502 {
1503 char *library = NULL, *moduleName = NULL, *parameters = NULL, *nss= NULL;
1504 char *config = NULL;
1505 SECStatus status;
1506 SECMODModule *module = NULL;
1507 SECMODModule *oldModule = NULL;
1508 SECStatus rv;
1509
1510 /* initialize the underlying module structures */
1511 SECMOD_Init();
1512
1513 status = NSSUTIL_ArgParseModuleSpecEx(modulespec, &library, &moduleName,
1514 &parameters, &nss,
1515 &config);
1516 if (status != SECSuccess) {
1517 goto loser;
1518 }
1519
1520 module = SECMOD_CreateModuleEx(library, moduleName, parameters, nss, config) ;
1521 if (library) PORT_Free(library);
1522 if (moduleName) PORT_Free(moduleName);
1523 if (parameters) PORT_Free(parameters);
1524 if (nss) PORT_Free(nss);
1525 if (config) PORT_Free(config);
1526 if (!module) {
1527 goto loser;
1528 }
1529 if (parent) {
1530 module->parent = SECMOD_ReferenceModule(parent);
1531 if (module->internal && secmod_IsInternalKeySlot(parent)) {
1532 module->internal = parent->internal;
1533 }
1534 }
1535
1536 /* load it */
1537 rv = secmod_LoadPKCS11Module(module, &oldModule);
1538 if (rv != SECSuccess) {
1539 goto loser;
1540 }
1541
1542 /* if we just reload an old module, no need to add it to any lists.
1543 * we simple release all our references */
1544 if (oldModule) {
1545 /* This module already exists, don't link it anywhere. This
1546 * will probably destroy this module */
1547 SECMOD_DestroyModule(module);
1548 return oldModule;
1549 }
1550
1551 if (recurse && module->isModuleDB) {
1552 char ** moduleSpecList;
1553 PORT_SetError(0);
1554
1555 moduleSpecList = SECMOD_GetModuleSpecList(module);
1556 if (moduleSpecList) {
1557 char **index;
1558
1559 index = moduleSpecList;
1560 if (*index && SECMOD_GetSkipFirstFlag(module)) {
1561 index++;
1562 }
1563
1564 for (; *index; index++) {
1565 SECMODModule *child;
1566 if (0 == PORT_Strcmp(*index, modulespec)) {
1567 /* avoid trivial infinite recursion */
1568 PORT_SetError(SEC_ERROR_NO_MODULE);
1569 rv = SECFailure;
1570 break;
1571 }
1572 child = SECMOD_LoadModule(*index,module,PR_TRUE);
1573 if (!child) break;
1574 if (child->isCritical && !child->loaded) {
1575 int err = PORT_GetError();
1576 if (!err)
1577 err = SEC_ERROR_NO_MODULE;
1578 SECMOD_DestroyModule(child);
1579 PORT_SetError(err);
1580 rv = SECFailure;
1581 break;
1582 }
1583 SECMOD_DestroyModule(child);
1584 }
1585 SECMOD_FreeModuleSpecList(module,moduleSpecList);
1586 } else {
1587 if (!PORT_GetError())
1588 PORT_SetError(SEC_ERROR_NO_MODULE);
1589 rv = SECFailure;
1590 }
1591 }
1592
1593 if (rv != SECSuccess) {
1594 goto loser;
1595 }
1596
1597
1598 /* inherit the reference */
1599 if (!module->moduleDBOnly) {
1600 SECMOD_AddModuleToList(module);
1601 } else {
1602 SECMOD_AddModuleToDBOnlyList(module);
1603 }
1604
1605 /* handle any additional work here */
1606 return module;
1607
1608 loser:
1609 if (module) {
1610 if (module->loaded) {
1611 SECMOD_UnloadModule(module);
1612 }
1613 SECMOD_AddModuleToUnloadList(module);
1614 }
1615 return module;
1616 }
1617
1618 /*
1619 * load a PKCS#11 module and add it to the default NSS trust domain
1620 */
1621 SECMODModule *
1622 SECMOD_LoadUserModule(char *modulespec,SECMODModule *parent, PRBool recurse)
1623 {
1624 SECStatus rv = SECSuccess;
1625 SECMODModule * newmod = SECMOD_LoadModule(modulespec, parent, recurse);
1626 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
1627
1628 if (newmod) {
1629 SECMOD_GetReadLock(moduleLock);
1630 rv = STAN_AddModuleToDefaultTrustDomain(newmod);
1631 SECMOD_ReleaseReadLock(moduleLock);
1632 if (SECSuccess != rv) {
1633 SECMOD_DestroyModule(newmod);
1634 return NULL;
1635 }
1636 }
1637 return newmod;
1638 }
1639
1640 /*
1641 * remove the PKCS#11 module from the default NSS trust domain, call
1642 * C_Finalize, and destroy the module structure
1643 */
1644 SECStatus SECMOD_UnloadUserModule(SECMODModule *mod)
1645 {
1646 SECStatus rv = SECSuccess;
1647 int atype = 0;
1648 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
1649 if (!mod) {
1650 return SECFailure;
1651 }
1652
1653 SECMOD_GetReadLock(moduleLock);
1654 rv = STAN_RemoveModuleFromDefaultTrustDomain(mod);
1655 SECMOD_ReleaseReadLock(moduleLock);
1656 if (SECSuccess != rv) {
1657 return SECFailure;
1658 }
1659 return SECMOD_DeleteModuleEx(NULL, mod, &atype, PR_FALSE);
1660 }
1661
OLDNEW
« no previous file with comments | « nss/lib/pk11wrap/pk11obj.c ('k') | nss/lib/pk11wrap/pk11pbe.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698