Bug Summary

File:root/firefox-clang/security/nss/lib/pk11wrap/pk11pars.c
Warning:line 485, column 9
Excessive padding in 'algListsDef' (8 padding bytes, where 0 is optimal). Optimal fields order: list, description, entries, allowEmpty, consider reordering the fields or adding explicit padding members

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name pk11pars.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/security/nss/lib/pk11wrap/pk11wrap_pk11wrap -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/security/nss/lib/pk11wrap/pk11wrap_pk11wrap -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG -D SHLIB_SUFFIX="so" -D SHLIB_PREFIX="lib" -D NSS_SHLIB_VERSION="3" -D SOFTOKEN_SHLIB_VERSION="3" -D NSS_FIPS_DISABLED -D NSS_NO_INIT_SUPPORT -D NSS_X86_OR_X64 -D NSS_X64 -D NSS_USE_64 -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -D LINUX2_1 -D LINUX -D linux -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D HAVE_STRERROR -D XP_UNIX -D _REENTRANT -D NSS_DISABLE_DBM -D NSS_DISABLE_LIBPKIX -D NSS_USE_PKCS5_PBKD2_PARAMS2_ONLY -D SOFTOKEN_USE_PKCS5_PBKD2_PARAMS2_ONLY -I /root/firefox-clang/security/nss/lib/pk11wrap -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/security/nss/lib/pk11wrap/pk11wrap_pk11wrap -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/private/nss -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c /root/firefox-clang/security/nss/lib/pk11wrap/pk11pars.c
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#include "pk11pub.h"
21
22/* create a new module */
23static SECMODModule *
24secmod_NewModule(void)
25{
26 SECMODModule *newMod;
27 PLArenaPool *arena;
28
29 /* create an arena in which dllName and commonName can be
30 * allocated.
31 */
32 arena = PORT_NewArenaPORT_NewArena_Util(512);
33 if (arena == NULL((void*)0)) {
34 return NULL((void*)0);
35 }
36
37 newMod = (SECMODModule *)PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, sizeof(SECMODModule));
38 if (newMod == NULL((void*)0)) {
39 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
40 return NULL((void*)0);
41 }
42
43 /*
44 * initialize of the fields of the module
45 */
46 newMod->arena = arena;
47 newMod->internal = PR_FALSE0;
48 newMod->loaded = PR_FALSE0;
49 newMod->isFIPS = PR_FALSE0;
50 newMod->dllName = NULL((void*)0);
51 newMod->commonName = NULL((void*)0);
52 newMod->library = NULL((void*)0);
53 newMod->functionList = NULL((void*)0);
54 newMod->slotCount = 0;
55 newMod->slots = NULL((void*)0);
56 newMod->slotInfo = NULL((void*)0);
57 newMod->slotInfoCount = 0;
58 newMod->refCount = 1;
59 newMod->ssl[0] = 0;
60 newMod->ssl[1] = 0;
61 newMod->libraryParams = NULL((void*)0);
62 newMod->moduleDBFunc = NULL((void*)0);
63 newMod->parent = NULL((void*)0);
64 newMod->isCritical = PR_FALSE0;
65 newMod->isModuleDB = PR_FALSE0;
66 newMod->moduleDBOnly = PR_FALSE0;
67 newMod->trustOrder = 0;
68 newMod->cipherOrder = 0;
69 newMod->evControlMask = 0;
70 newMod->refLock = PR_NewLock();
71 if (newMod->refLock == NULL((void*)0)) {
72 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
73 return NULL((void*)0);
74 }
75 return newMod;
76}
77
78/* private flags for isModuleDB (field in SECMODModule). */
79/* The meaing of these flags is as follows:
80 *
81 * SECMOD_FLAG_MODULE_DB_IS_MODULE_DB - This is a module that accesses the
82 * database of other modules to load. Module DBs are loadable modules that
83 * tells NSS which PKCS #11 modules to load and when. These module DBs are
84 * chainable. That is, one module DB can load another one. NSS system init
85 * design takes advantage of this feature. In system NSS, a fixed system
86 * module DB loads the system defined libraries, then chains out to the
87 * traditional module DBs to load any system or user configured modules
88 * (like smart cards). This bit is the same as the already existing meaning
89 * of isModuleDB = PR_TRUE. None of the other module db flags should be set
90 * if this flag isn't on.
91 *
92 * SECMOD_FLAG_MODULE_DB_SKIP_FIRST - This flag tells NSS to skip the first
93 * PKCS #11 module presented by a module DB. This allows the OS to load a
94 * softoken from the system module, then ask the existing module DB code to
95 * load the other PKCS #11 modules in that module DB (skipping it's request
96 * to load softoken). This gives the system init finer control over the
97 * configuration of that softoken module.
98 *
99 * SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB - This flag allows system init to mark a
100 * different module DB as the 'default' module DB (the one in which
101 * 'Add module' changes will go). Without this flag NSS takes the first
102 * module as the default Module DB, but in system NSS, that first module
103 * is the system module, which is likely read only (at least to the user).
104 * This allows system NSS to delegate those changes to the user's module DB,
105 * preserving the user's ability to load new PKCS #11 modules (which only
106 * affect him), from existing applications like Firefox.
107 */
108#define SECMOD_FLAG_MODULE_DB_IS_MODULE_DB0x01 0x01 /* must be set if any of the \
109 *other flags are set */
110#define SECMOD_FLAG_MODULE_DB_SKIP_FIRST0x02 0x02
111#define SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB0x04 0x04
112#define SECMOD_FLAG_MODULE_DB_POLICY_ONLY0x08 0x08
113
114/* private flags for internal (field in SECMODModule). */
115/* The meaing of these flags is as follows:
116 *
117 * SECMOD_FLAG_INTERNAL_IS_INTERNAL - This is a marks the the module is
118 * the internal module (that is, softoken). This bit is the same as the
119 * already existing meaning of internal = PR_TRUE. None of the other
120 * internal flags should be set if this flag isn't on.
121 *
122 * SECMOD_FLAG_MODULE_INTERNAL_KEY_SLOT - This flag allows system init to mark
123 * a different slot returned byt PK11_GetInternalKeySlot(). The 'primary'
124 * slot defined by this module will be the new internal key slot.
125 */
126#define SECMOD_FLAG_INTERNAL_IS_INTERNAL0x01 0x01 /* must be set if any of \
127 *the other flags are set */
128#define SECMOD_FLAG_INTERNAL_KEY_SLOT0x02 0x02
129
130/* private flags for policy check. */
131#define SECMOD_FLAG_POLICY_CHECK_IDENTIFIER0x01 0x01
132#define SECMOD_FLAG_POLICY_CHECK_VALUE0x02 0x02
133
134/*
135 * for 3.4 we continue to use the old SECMODModule structure
136 */
137SECMODModule *
138SECMOD_CreateModule(const char *library, const char *moduleName,
139 const char *parameters, const char *nss)
140{
141 return SECMOD_CreateModuleEx(library, moduleName, parameters, nss, NULL((void*)0));
142}
143
144/*
145 * NSS config options format:
146 *
147 * The specified ciphers will be allowed by policy, but an application
148 * may allow more by policy explicitly:
149 * config="allow=curve1:curve2:hash1:hash2:rsa-1024..."
150 *
151 * Only the specified hashes and curves will be allowed:
152 * config="disallow=all allow=sha1:sha256:secp256r1:secp384r1"
153 *
154 * Only the specified hashes and curves will be allowed, and
155 * RSA keys of 2048 or more will be accepted, and DH key exchange
156 * with 1024-bit primes or more:
157 * config="disallow=all allow=sha1:sha256:secp256r1:secp384r1:min-rsa=2048:min-dh=1024"
158 *
159 * A policy that enables the AES ciphersuites and the SECP256/384 curves:
160 * config="allow=aes128-cbc:aes128-gcm:TLS1.0:TLS1.2:TLS1.1:HMAC-SHA1:SHA1:SHA256:SHA384:RSA:ECDHE-RSA:SECP256R1:SECP384R1"
161 *
162 * Disallow values are parsed first, then allow values, independent of the
163 * order they appear.
164 *
165 * flags: turn on the following flags:
166 * policy-lock: turn off the ability for applications to change policy with
167 * the call NSS_SetAlgorithmPolicy or the other system policy
168 * calls (SSL_SetPolicy, etc.)
169 * ssl-lock: turn off the ability to change the ssl defaults.
170 *
171 * The following only apply to ssl cipher suites (future smime)
172 *
173 * enable: turn on ciphersuites by default.
174 * disable: turn off ciphersuites by default without disallowing them by policy.
175 *
176 *
177 */
178
179typedef struct {
180 const char *name;
181 unsigned name_size;
182 SECOidTag oid;
183 PRUint32 val;
184} oidValDef;
185
186typedef struct {
187 const char *name;
188 unsigned name_size;
189 PRInt32 option;
190} optionFreeDef;
191
192typedef struct {
193 const char *name;
194 unsigned name_size;
195 PRUint32 flag;
196} policyFlagDef;
197
198/*
199 * This table should be merged with the SECOID table.
200 */
201#define CIPHER_NAME(x)x, (sizeof(x) - 1) x, (sizeof(x) - 1)
202static const oidValDef curveOptList[] = {
203 /* Curves */
204 { CIPHER_NAME("PRIME192V1")"PRIME192V1", (sizeof("PRIME192V1") - 1), SEC_OID_ANSIX962_EC_PRIME192V1,
205 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
206 { CIPHER_NAME("PRIME192V2")"PRIME192V2", (sizeof("PRIME192V2") - 1), SEC_OID_ANSIX962_EC_PRIME192V2,
207 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
208 { CIPHER_NAME("PRIME192V3")"PRIME192V3", (sizeof("PRIME192V3") - 1), SEC_OID_ANSIX962_EC_PRIME192V3,
209 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
210 { CIPHER_NAME("PRIME239V1")"PRIME239V1", (sizeof("PRIME239V1") - 1), SEC_OID_ANSIX962_EC_PRIME239V1,
211 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
212 { CIPHER_NAME("PRIME239V2")"PRIME239V2", (sizeof("PRIME239V2") - 1), SEC_OID_ANSIX962_EC_PRIME239V2,
213 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
214 { CIPHER_NAME("PRIME239V3")"PRIME239V3", (sizeof("PRIME239V3") - 1), SEC_OID_ANSIX962_EC_PRIME239V3,
215 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
216 { CIPHER_NAME("PRIME256V1")"PRIME256V1", (sizeof("PRIME256V1") - 1), SEC_OID_ANSIX962_EC_PRIME256V1,
217 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
218 { CIPHER_NAME("SECP112R1")"SECP112R1", (sizeof("SECP112R1") - 1), SEC_OID_SECG_EC_SECP112R1,
219 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
220 { CIPHER_NAME("SECP112R2")"SECP112R2", (sizeof("SECP112R2") - 1), SEC_OID_SECG_EC_SECP112R2,
221 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
222 { CIPHER_NAME("SECP128R1")"SECP128R1", (sizeof("SECP128R1") - 1), SEC_OID_SECG_EC_SECP128R1,
223 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
224 { CIPHER_NAME("SECP128R2")"SECP128R2", (sizeof("SECP128R2") - 1), SEC_OID_SECG_EC_SECP128R2,
225 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
226 { CIPHER_NAME("SECP160K1")"SECP160K1", (sizeof("SECP160K1") - 1), SEC_OID_SECG_EC_SECP160K1,
227 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
228 { CIPHER_NAME("SECP160R1")"SECP160R1", (sizeof("SECP160R1") - 1), SEC_OID_SECG_EC_SECP160R1,
229 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
230 { CIPHER_NAME("SECP160R2")"SECP160R2", (sizeof("SECP160R2") - 1), SEC_OID_SECG_EC_SECP160R2,
231 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
232 { CIPHER_NAME("SECP192K1")"SECP192K1", (sizeof("SECP192K1") - 1), SEC_OID_SECG_EC_SECP192K1,
233 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
234 { CIPHER_NAME("SECP192R1")"SECP192R1", (sizeof("SECP192R1") - 1), SEC_OID_ANSIX962_EC_PRIME192V1,
235 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
236 { CIPHER_NAME("SECP224K1")"SECP224K1", (sizeof("SECP224K1") - 1), SEC_OID_SECG_EC_SECP224K1,
237 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
238 { CIPHER_NAME("SECP256K1")"SECP256K1", (sizeof("SECP256K1") - 1), SEC_OID_SECG_EC_SECP256K1,
239 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
240 { CIPHER_NAME("SECP256R1")"SECP256R1", (sizeof("SECP256R1") - 1), SEC_OID_ANSIX962_EC_PRIME256V1,
241 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
242 { CIPHER_NAME("SECP384R1")"SECP384R1", (sizeof("SECP384R1") - 1), SEC_OID_SECG_EC_SECP384R1,
243 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
244 { CIPHER_NAME("SECP521R1")"SECP521R1", (sizeof("SECP521R1") - 1), SEC_OID_SECG_EC_SECP521R1,
245 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
246 { CIPHER_NAME("CURVE25519")"CURVE25519", (sizeof("CURVE25519") - 1), SEC_OID_CURVE25519,
247 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
248 /* NOTE, don't use '0' to indicate default off. Setting '0'
249 * makes this entry unmanagable by the policy code (including
250 * turning the entry off. If you want an entry off by default
251 * simply explictly flip the bits in SECOID_Init()
252 * (util/secoid.c) */
253 { CIPHER_NAME("XYBER768D00")"XYBER768D00", (sizeof("XYBER768D00") - 1), SEC_OID_XYBER768D00,
254 NSS_USE_ALG_IN_SSL_KX0x00000004 },
255 { CIPHER_NAME("X25519MLKEM768")"X25519MLKEM768", (sizeof("X25519MLKEM768") - 1), SEC_OID_MLKEM768X25519,
256 NSS_USE_ALG_IN_SSL_KX0x00000004 },
257 { CIPHER_NAME("SECP256R1MLKEM768")"SECP256R1MLKEM768", (sizeof("SECP256R1MLKEM768") - 1), SEC_OID_SECP256R1MLKEM768,
258 NSS_USE_ALG_IN_SSL_KX0x00000004 },
259 { CIPHER_NAME("SECP384R1MLKEM1024")"SECP384R1MLKEM1024", (sizeof("SECP384R1MLKEM1024") - 1), SEC_OID_SECP384R1MLKEM1024,
260 NSS_USE_ALG_IN_SSL_KX0x00000004 },
261 { CIPHER_NAME("MLKEM768X25519")"MLKEM768X25519", (sizeof("MLKEM768X25519") - 1), SEC_OID_MLKEM768X25519,
262 NSS_USE_ALG_IN_SSL_KX0x00000004 },
263 /* ANSI X9.62 named elliptic curves (characteristic two field) */
264 { CIPHER_NAME("C2PNB163V1")"C2PNB163V1", (sizeof("C2PNB163V1") - 1), SEC_OID_ANSIX962_EC_C2PNB163V1,
265 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
266 { CIPHER_NAME("C2PNB163V2")"C2PNB163V2", (sizeof("C2PNB163V2") - 1), SEC_OID_ANSIX962_EC_C2PNB163V2,
267 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
268 { CIPHER_NAME("C2PNB163V3")"C2PNB163V3", (sizeof("C2PNB163V3") - 1), SEC_OID_ANSIX962_EC_C2PNB163V3,
269 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
270 { CIPHER_NAME("C2PNB176V1")"C2PNB176V1", (sizeof("C2PNB176V1") - 1), SEC_OID_ANSIX962_EC_C2PNB176V1,
271 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
272 { CIPHER_NAME("C2TNB191V1")"C2TNB191V1", (sizeof("C2TNB191V1") - 1), SEC_OID_ANSIX962_EC_C2TNB191V1,
273 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
274 { CIPHER_NAME("C2TNB191V2")"C2TNB191V2", (sizeof("C2TNB191V2") - 1), SEC_OID_ANSIX962_EC_C2TNB191V2,
275 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
276 { CIPHER_NAME("C2TNB191V3")"C2TNB191V3", (sizeof("C2TNB191V3") - 1), SEC_OID_ANSIX962_EC_C2TNB191V3,
277 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
278 { CIPHER_NAME("C2ONB191V4")"C2ONB191V4", (sizeof("C2ONB191V4") - 1), SEC_OID_ANSIX962_EC_C2ONB191V4,
279 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
280 { CIPHER_NAME("C2ONB191V5")"C2ONB191V5", (sizeof("C2ONB191V5") - 1), SEC_OID_ANSIX962_EC_C2ONB191V5,
281 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
282 { CIPHER_NAME("C2PNB208W1")"C2PNB208W1", (sizeof("C2PNB208W1") - 1), SEC_OID_ANSIX962_EC_C2PNB208W1,
283 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
284 { CIPHER_NAME("C2TNB239V1")"C2TNB239V1", (sizeof("C2TNB239V1") - 1), SEC_OID_ANSIX962_EC_C2TNB239V1,
285 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
286 { CIPHER_NAME("C2TNB239V2")"C2TNB239V2", (sizeof("C2TNB239V2") - 1), SEC_OID_ANSIX962_EC_C2TNB239V2,
287 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
288 { CIPHER_NAME("C2TNB239V3")"C2TNB239V3", (sizeof("C2TNB239V3") - 1), SEC_OID_ANSIX962_EC_C2TNB239V3,
289 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
290 { CIPHER_NAME("C2ONB239V4")"C2ONB239V4", (sizeof("C2ONB239V4") - 1), SEC_OID_ANSIX962_EC_C2ONB239V4,
291 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
292 { CIPHER_NAME("C2ONB239V5")"C2ONB239V5", (sizeof("C2ONB239V5") - 1), SEC_OID_ANSIX962_EC_C2ONB239V5,
293 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
294 { CIPHER_NAME("C2PNB272W1")"C2PNB272W1", (sizeof("C2PNB272W1") - 1), SEC_OID_ANSIX962_EC_C2PNB272W1,
295 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
296 { CIPHER_NAME("C2PNB304W1")"C2PNB304W1", (sizeof("C2PNB304W1") - 1), SEC_OID_ANSIX962_EC_C2PNB304W1,
297 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
298 { CIPHER_NAME("C2TNB359V1")"C2TNB359V1", (sizeof("C2TNB359V1") - 1), SEC_OID_ANSIX962_EC_C2TNB359V1,
299 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
300 { CIPHER_NAME("C2PNB368W1")"C2PNB368W1", (sizeof("C2PNB368W1") - 1), SEC_OID_ANSIX962_EC_C2PNB368W1,
301 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
302 { CIPHER_NAME("C2TNB431R1")"C2TNB431R1", (sizeof("C2TNB431R1") - 1), SEC_OID_ANSIX962_EC_C2TNB431R1,
303 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
304 /* SECG named elliptic curves (characteristic two field) */
305 { CIPHER_NAME("SECT113R1")"SECT113R1", (sizeof("SECT113R1") - 1), SEC_OID_SECG_EC_SECT113R1,
306 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
307 { CIPHER_NAME("SECT131R1")"SECT131R1", (sizeof("SECT131R1") - 1), SEC_OID_SECG_EC_SECT113R2,
308 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
309 { CIPHER_NAME("SECT131R1")"SECT131R1", (sizeof("SECT131R1") - 1), SEC_OID_SECG_EC_SECT131R1,
310 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
311 { CIPHER_NAME("SECT131R2")"SECT131R2", (sizeof("SECT131R2") - 1), SEC_OID_SECG_EC_SECT131R2,
312 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
313 { CIPHER_NAME("SECT163K1")"SECT163K1", (sizeof("SECT163K1") - 1), SEC_OID_SECG_EC_SECT163K1,
314 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
315 { CIPHER_NAME("SECT163R1")"SECT163R1", (sizeof("SECT163R1") - 1), SEC_OID_SECG_EC_SECT163R1,
316 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
317 { CIPHER_NAME("SECT163R2")"SECT163R2", (sizeof("SECT163R2") - 1), SEC_OID_SECG_EC_SECT163R2,
318 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
319 { CIPHER_NAME("SECT193R1")"SECT193R1", (sizeof("SECT193R1") - 1), SEC_OID_SECG_EC_SECT193R1,
320 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
321 { CIPHER_NAME("SECT193R2")"SECT193R2", (sizeof("SECT193R2") - 1), SEC_OID_SECG_EC_SECT193R2,
322 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
323 { CIPHER_NAME("SECT233K1")"SECT233K1", (sizeof("SECT233K1") - 1), SEC_OID_SECG_EC_SECT233K1,
324 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
325 { CIPHER_NAME("SECT233R1")"SECT233R1", (sizeof("SECT233R1") - 1), SEC_OID_SECG_EC_SECT233R1,
326 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
327 { CIPHER_NAME("SECT239K1")"SECT239K1", (sizeof("SECT239K1") - 1), SEC_OID_SECG_EC_SECT239K1,
328 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
329 { CIPHER_NAME("SECT283K1")"SECT283K1", (sizeof("SECT283K1") - 1), SEC_OID_SECG_EC_SECT283K1,
330 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
331 { CIPHER_NAME("SECT283R1")"SECT283R1", (sizeof("SECT283R1") - 1), SEC_OID_SECG_EC_SECT283R1,
332 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
333 { CIPHER_NAME("SECT409K1")"SECT409K1", (sizeof("SECT409K1") - 1), SEC_OID_SECG_EC_SECT409K1,
334 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
335 { CIPHER_NAME("SECT409R1")"SECT409R1", (sizeof("SECT409R1") - 1), SEC_OID_SECG_EC_SECT409R1,
336 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
337 { CIPHER_NAME("SECT571K1")"SECT571K1", (sizeof("SECT571K1") - 1), SEC_OID_SECG_EC_SECT571K1,
338 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
339 { CIPHER_NAME("SECT571R1")"SECT571R1", (sizeof("SECT571R1") - 1), SEC_OID_SECG_EC_SECT571R1,
340 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
341};
342
343static const oidValDef hashOptList[] = {
344 /* Hashes */
345 { CIPHER_NAME("MD2")"MD2", (sizeof("MD2") - 1), SEC_OID_MD2,
346 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
347 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
348 { CIPHER_NAME("MD4")"MD4", (sizeof("MD4") - 1), SEC_OID_MD4,
349 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
350 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
351 { CIPHER_NAME("MD5")"MD5", (sizeof("MD5") - 1), SEC_OID_MD5,
352 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
353 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
354 { CIPHER_NAME("SHA1")"SHA1", (sizeof("SHA1") - 1), SEC_OID_SHA1,
355 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
356 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
357 { CIPHER_NAME("SHA224")"SHA224", (sizeof("SHA224") - 1), SEC_OID_SHA224,
358 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
359 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
360 { CIPHER_NAME("SHA256")"SHA256", (sizeof("SHA256") - 1), SEC_OID_SHA256,
361 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
362 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
363 { CIPHER_NAME("SHA384")"SHA384", (sizeof("SHA384") - 1), SEC_OID_SHA384,
364 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
365 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
366 { CIPHER_NAME("SHA512")"SHA512", (sizeof("SHA512") - 1), SEC_OID_SHA512,
367 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
368 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
369 { CIPHER_NAME("SHA3-224")"SHA3-224", (sizeof("SHA3-224") - 1), SEC_OID_SHA3_224,
370 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
371 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
372 { CIPHER_NAME("SHA3-256")"SHA3-256", (sizeof("SHA3-256") - 1), SEC_OID_SHA3_256,
373 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
374 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
375 { CIPHER_NAME("SHA3-384")"SHA3-384", (sizeof("SHA3-384") - 1), SEC_OID_SHA3_384,
376 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
377 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
378 { CIPHER_NAME("SHA3-512")"SHA3-512", (sizeof("SHA3-512") - 1), SEC_OID_SHA3_512,
379 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
380 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) }
381};
382
383static const oidValDef macOptList[] = {
384 /* MACs */
385 { CIPHER_NAME("HMAC-MD5")"HMAC-MD5", (sizeof("HMAC-MD5") - 1), SEC_OID_HMAC_MD5,
386 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
387 { CIPHER_NAME("HMAC-SHA1")"HMAC-SHA1", (sizeof("HMAC-SHA1") - 1), SEC_OID_HMAC_SHA1,
388 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
389 { CIPHER_NAME("HMAC-SHA224")"HMAC-SHA224", (sizeof("HMAC-SHA224") - 1), SEC_OID_HMAC_SHA224,
390 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
391 { CIPHER_NAME("HMAC-SHA256")"HMAC-SHA256", (sizeof("HMAC-SHA256") - 1), SEC_OID_HMAC_SHA256,
392 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
393 { CIPHER_NAME("HMAC-SHA384")"HMAC-SHA384", (sizeof("HMAC-SHA384") - 1), SEC_OID_HMAC_SHA384,
394 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
395 { CIPHER_NAME("HMAC-SHA512")"HMAC-SHA512", (sizeof("HMAC-SHA512") - 1), SEC_OID_HMAC_SHA512,
396 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
397 { CIPHER_NAME("HMAC-SHA3-224")"HMAC-SHA3-224", (sizeof("HMAC-SHA3-224") - 1), SEC_OID_HMAC_SHA3_224,
398 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
399 { CIPHER_NAME("HMAC-SHA3-256")"HMAC-SHA3-256", (sizeof("HMAC-SHA3-256") - 1), SEC_OID_HMAC_SHA3_256,
400 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
401 { CIPHER_NAME("HMAC-SHA3-384")"HMAC-SHA3-384", (sizeof("HMAC-SHA3-384") - 1), SEC_OID_HMAC_SHA3_384,
402 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
403 { CIPHER_NAME("HMAC-SHA3-512")"HMAC-SHA3-512", (sizeof("HMAC-SHA3-512") - 1), SEC_OID_HMAC_SHA3_512,
404 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
405};
406
407static const oidValDef cipherOptList[] = {
408 /* Ciphers */
409 { CIPHER_NAME("AES128-CBC")"AES128-CBC", (sizeof("AES128-CBC") - 1), SEC_OID_AES_128_CBC,
410 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
411 { CIPHER_NAME("AES192-CBC")"AES192-CBC", (sizeof("AES192-CBC") - 1), SEC_OID_AES_192_CBC,
412 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
413 { CIPHER_NAME("AES256-CBC")"AES256-CBC", (sizeof("AES256-CBC") - 1), SEC_OID_AES_256_CBC,
414 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
415 { CIPHER_NAME("AES128-GCM")"AES128-GCM", (sizeof("AES128-GCM") - 1), SEC_OID_AES_128_GCM, NSS_USE_ALG_IN_SSL0x00000008 },
416 { CIPHER_NAME("AES192-GCM")"AES192-GCM", (sizeof("AES192-GCM") - 1), SEC_OID_AES_192_GCM, NSS_USE_ALG_IN_SSL0x00000008 },
417 { CIPHER_NAME("AES256-GCM")"AES256-GCM", (sizeof("AES256-GCM") - 1), SEC_OID_AES_256_GCM, NSS_USE_ALG_IN_SSL0x00000008 },
418 { CIPHER_NAME("CAMELLIA128-CBC")"CAMELLIA128-CBC", (sizeof("CAMELLIA128-CBC") - 1), SEC_OID_CAMELLIA_128_CBC,
419 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
420 { CIPHER_NAME("CAMELLIA192-CBC")"CAMELLIA192-CBC", (sizeof("CAMELLIA192-CBC") - 1), SEC_OID_CAMELLIA_192_CBC,
421 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
422 { CIPHER_NAME("CAMELLIA256-CBC")"CAMELLIA256-CBC", (sizeof("CAMELLIA256-CBC") - 1), SEC_OID_CAMELLIA_256_CBC,
423 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
424 { CIPHER_NAME("CHACHA20-POLY1305")"CHACHA20-POLY1305", (sizeof("CHACHA20-POLY1305") - 1), SEC_OID_CHACHA20_POLY1305, NSS_USE_ALG_IN_SSL0x00000008 },
425 { CIPHER_NAME("SEED-CBC")"SEED-CBC", (sizeof("SEED-CBC") - 1), SEC_OID_SEED_CBC,
426 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
427 { CIPHER_NAME("DES-EDE3-CBC")"DES-EDE3-CBC", (sizeof("DES-EDE3-CBC") - 1), SEC_OID_DES_EDE3_CBC,
428 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
429 { CIPHER_NAME("DES-40-CBC")"DES-40-CBC", (sizeof("DES-40-CBC") - 1), SEC_OID_DES_40_CBC,
430 NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
431 { CIPHER_NAME("DES-CBC")"DES-CBC", (sizeof("DES-CBC") - 1), SEC_OID_DES_CBC, NSS_USE_ALG_IN_SSL0x00000008 },
432 { CIPHER_NAME("NULL-CIPHER")"NULL-CIPHER", (sizeof("NULL-CIPHER") - 1), SEC_OID_NULL_CIPHER, NSS_USE_ALG_IN_SSL0x00000008 },
433 { CIPHER_NAME("RC2")"RC2", (sizeof("RC2") - 1), SEC_OID_RC2_CBC, NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
434 { CIPHER_NAME("RC2-40-CBC")"RC2-40-CBC", (sizeof("RC2-40-CBC") - 1), SEC_OID_RC2_40_CBC, NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) },
435 { CIPHER_NAME("RC2-64-CBC")"RC2-64-CBC", (sizeof("RC2-64-CBC") - 1), SEC_OID_RC2_64_CBC, NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) },
436 { CIPHER_NAME("RC2-128-CBC")"RC2-128-CBC", (sizeof("RC2-128-CBC") - 1), SEC_OID_RC2_128_CBC, NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) },
437 { CIPHER_NAME("RC4")"RC4", (sizeof("RC4") - 1), SEC_OID_RC4, NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
438 { CIPHER_NAME("IDEA")"IDEA", (sizeof("IDEA") - 1), SEC_OID_IDEA_CBC, NSS_USE_ALG_IN_SSL0x00000008 },
439};
440
441static const oidValDef kxOptList[] = {
442 /* Key exchange */
443 { CIPHER_NAME("RSA")"RSA", (sizeof("RSA") - 1), SEC_OID_TLS_RSA, NSS_USE_ALG_IN_SSL_KX0x00000004 },
444 { CIPHER_NAME("RSA-EXPORT")"RSA-EXPORT", (sizeof("RSA-EXPORT") - 1), SEC_OID_TLS_RSA_EXPORT, NSS_USE_ALG_IN_SSL_KX0x00000004 },
445 { CIPHER_NAME("DHE-RSA")"DHE-RSA", (sizeof("DHE-RSA") - 1), SEC_OID_TLS_DHE_RSA, NSS_USE_ALG_IN_SSL_KX0x00000004 },
446 { CIPHER_NAME("DHE-DSS")"DHE-DSS", (sizeof("DHE-DSS") - 1), SEC_OID_TLS_DHE_DSS, NSS_USE_ALG_IN_SSL_KX0x00000004 },
447 { CIPHER_NAME("DH-RSA")"DH-RSA", (sizeof("DH-RSA") - 1), SEC_OID_TLS_DH_RSA, NSS_USE_ALG_IN_SSL_KX0x00000004 },
448 { CIPHER_NAME("DH-DSS")"DH-DSS", (sizeof("DH-DSS") - 1), SEC_OID_TLS_DH_DSS, NSS_USE_ALG_IN_SSL_KX0x00000004 },
449 { CIPHER_NAME("ECDHE-ECDSA")"ECDHE-ECDSA", (sizeof("ECDHE-ECDSA") - 1), SEC_OID_TLS_ECDHE_ECDSA, NSS_USE_ALG_IN_SSL_KX0x00000004 },
450 { CIPHER_NAME("ECDHE-RSA")"ECDHE-RSA", (sizeof("ECDHE-RSA") - 1), SEC_OID_TLS_ECDHE_RSA, NSS_USE_ALG_IN_SSL_KX0x00000004 },
451 { CIPHER_NAME("ECDH-ECDSA")"ECDH-ECDSA", (sizeof("ECDH-ECDSA") - 1), SEC_OID_TLS_ECDH_ECDSA, NSS_USE_ALG_IN_SSL_KX0x00000004 },
452 { CIPHER_NAME("ECDH-RSA")"ECDH-RSA", (sizeof("ECDH-RSA") - 1), SEC_OID_TLS_ECDH_RSA, NSS_USE_ALG_IN_SSL_KX0x00000004 },
453 { CIPHER_NAME("TLS-REQUIRE-EMS")"TLS-REQUIRE-EMS", (sizeof("TLS-REQUIRE-EMS") - 1), SEC_OID_TLS_REQUIRE_EMS, NSS_USE_ALG_IN_SSL_KX0x00000004 },
454
455};
456
457static const oidValDef smimeKxOptList[] = {
458 /* Key exchange */
459 { CIPHER_NAME("RSA-PKCS")"RSA-PKCS", (sizeof("RSA-PKCS") - 1), SEC_OID_PKCS1_RSA_ENCRYPTION, NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
460 { CIPHER_NAME("RSA-OAEP")"RSA-OAEP", (sizeof("RSA-OAEP") - 1), SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION, NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
461 { CIPHER_NAME("ECDH")"ECDH", (sizeof("ECDH") - 1), SEC_OID_ECDH_KEA, NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
462 { CIPHER_NAME("DH")"DH", (sizeof("DH") - 1), SEC_OID_X942_DIFFIE_HELMAN_KEY, NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
463};
464
465static const oidValDef signOptList[] = {
466 /* Signatures */
467 { CIPHER_NAME("DSA")"DSA", (sizeof("DSA") - 1), SEC_OID_ANSIX9_DSA_SIGNATURE,
468 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
469 { CIPHER_NAME("RSA-PKCS")"RSA-PKCS", (sizeof("RSA-PKCS") - 1), SEC_OID_PKCS1_RSA_ENCRYPTION,
470 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
471 { CIPHER_NAME("RSA-PSS")"RSA-PSS", (sizeof("RSA-PSS") - 1), SEC_OID_PKCS1_RSA_PSS_SIGNATURE,
472 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
473 { CIPHER_NAME("ECDSA")"ECDSA", (sizeof("ECDSA") - 1), SEC_OID_ANSIX962_EC_PUBLIC_KEY,
474 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
475 { CIPHER_NAME("ED25519")"ED25519", (sizeof("ED25519") - 1), SEC_OID_ED25519_PUBLIC_KEY,
476 NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
477 { CIPHER_NAME("ML-DSA-44")"ML-DSA-44", (sizeof("ML-DSA-44") - 1), SEC_OID_ML_DSA_44,
478 NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
479 { CIPHER_NAME("ML-DSA-65")"ML-DSA-65", (sizeof("ML-DSA-65") - 1), SEC_OID_ML_DSA_65,
480 NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
481 { CIPHER_NAME("ML-DSA-87")"ML-DSA-87", (sizeof("ML-DSA-87") - 1), SEC_OID_ML_DSA_87,
482 NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
483};
484
485typedef struct {
Excessive padding in 'algListsDef' (8 padding bytes, where 0 is optimal). Optimal fields order: list, description, entries, allowEmpty, consider reordering the fields or adding explicit padding members
486 const oidValDef *list;
487 PRUint32 entries;
488 const char *description;
489 PRBool allowEmpty;
490} algListsDef;
491
492static const algListsDef algOptLists[] = {
493 { curveOptList, PR_ARRAY_SIZE(curveOptList)(sizeof(curveOptList) / sizeof((curveOptList)[0])), "ECC", PR_FALSE0 },
494 { hashOptList, PR_ARRAY_SIZE(hashOptList)(sizeof(hashOptList) / sizeof((hashOptList)[0])), "HASH", PR_FALSE0 },
495 { macOptList, PR_ARRAY_SIZE(macOptList)(sizeof(macOptList) / sizeof((macOptList)[0])), "MAC", PR_FALSE0 },
496 { cipherOptList, PR_ARRAY_SIZE(cipherOptList)(sizeof(cipherOptList) / sizeof((cipherOptList)[0])), "CIPHER", PR_FALSE0 },
497 { kxOptList, PR_ARRAY_SIZE(kxOptList)(sizeof(kxOptList) / sizeof((kxOptList)[0])), "SSL-KX", PR_FALSE0 },
498 { smimeKxOptList, PR_ARRAY_SIZE(smimeKxOptList)(sizeof(smimeKxOptList) / sizeof((smimeKxOptList)[0])), "SMIME-KX", PR_TRUE1 },
499 { signOptList, PR_ARRAY_SIZE(signOptList)(sizeof(signOptList) / sizeof((signOptList)[0])), "OTHER-SIGN", PR_FALSE0 },
500};
501
502static const optionFreeDef sslOptList[] = {
503 /* Versions */
504 { CIPHER_NAME("SSL2.0")"SSL2.0", (sizeof("SSL2.0") - 1), 0x002 },
505 { CIPHER_NAME("SSL3.0")"SSL3.0", (sizeof("SSL3.0") - 1), 0x300 },
506 { CIPHER_NAME("SSL3.1")"SSL3.1", (sizeof("SSL3.1") - 1), 0x301 },
507 { CIPHER_NAME("TLS1.0")"TLS1.0", (sizeof("TLS1.0") - 1), 0x301 },
508 { CIPHER_NAME("TLS1.1")"TLS1.1", (sizeof("TLS1.1") - 1), 0x302 },
509 { CIPHER_NAME("TLS1.2")"TLS1.2", (sizeof("TLS1.2") - 1), 0x303 },
510 { CIPHER_NAME("TLS1.3")"TLS1.3", (sizeof("TLS1.3") - 1), 0x304 },
511 { CIPHER_NAME("DTLS1.0")"DTLS1.0", (sizeof("DTLS1.0") - 1), 0x302 },
512 { CIPHER_NAME("DTLS1.1")"DTLS1.1", (sizeof("DTLS1.1") - 1), 0x302 },
513 { CIPHER_NAME("DTLS1.2")"DTLS1.2", (sizeof("DTLS1.2") - 1), 0x303 },
514 { CIPHER_NAME("DTLS1.3")"DTLS1.3", (sizeof("DTLS1.3") - 1), 0x304 },
515};
516
517static const optionFreeDef keySizeFlagsList[] = {
518 { CIPHER_NAME("KEY-SIZE-SSL")"KEY-SIZE-SSL", (sizeof("KEY-SIZE-SSL") - 1), NSS_KEY_SIZE_POLICY_SSL_FLAG1 },
519 { CIPHER_NAME("KEY-SIZE-SIGN")"KEY-SIZE-SIGN", (sizeof("KEY-SIZE-SIGN") - 1), NSS_KEY_SIZE_POLICY_SIGN_FLAG4 },
520 { CIPHER_NAME("KEY-SIZE-VERIFY")"KEY-SIZE-VERIFY", (sizeof("KEY-SIZE-VERIFY") - 1), NSS_KEY_SIZE_POLICY_VERIFY_FLAG2 },
521 { CIPHER_NAME("KEY-SIZE-SMIME")"KEY-SIZE-SMIME", (sizeof("KEY-SIZE-SMIME") - 1), NSS_KEY_SIZE_POLICY_SMIME_FLAG8 },
522 { CIPHER_NAME("KEY-SIZE-ALL")"KEY-SIZE-ALL", (sizeof("KEY-SIZE-ALL") - 1), NSS_KEY_SIZE_POLICY_ALL_FLAGS0x0f },
523};
524
525static const optionFreeDef freeOptList[] = {
526
527 /* Restrictions for asymetric keys */
528 { CIPHER_NAME("RSA-MIN")"RSA-MIN", (sizeof("RSA-MIN") - 1), NSS_RSA_MIN_KEY_SIZE0x001 },
529 { CIPHER_NAME("DH-MIN")"DH-MIN", (sizeof("DH-MIN") - 1), NSS_DH_MIN_KEY_SIZE0x002 },
530 { CIPHER_NAME("DSA-MIN")"DSA-MIN", (sizeof("DSA-MIN") - 1), NSS_DSA_MIN_KEY_SIZE0x004 },
531 { CIPHER_NAME("ECC-MIN")"ECC-MIN", (sizeof("ECC-MIN") - 1), NSS_ECC_MIN_KEY_SIZE0x011 },
532 /* what operations doe the key size apply to */
533 { CIPHER_NAME("KEY-SIZE-FLAGS")"KEY-SIZE-FLAGS", (sizeof("KEY-SIZE-FLAGS") - 1), NSS_KEY_SIZE_POLICY_FLAGS0x00e },
534 /* constraints on SSL Protocols */
535 { CIPHER_NAME("TLS-VERSION-MIN")"TLS-VERSION-MIN", (sizeof("TLS-VERSION-MIN") - 1), NSS_TLS_VERSION_MIN_POLICY0x008 },
536 { CIPHER_NAME("TLS-VERSION-MAX")"TLS-VERSION-MAX", (sizeof("TLS-VERSION-MAX") - 1), NSS_TLS_VERSION_MAX_POLICY0x009 },
537 /* constraints on DTLS Protocols */
538 { CIPHER_NAME("DTLS-VERSION-MIN")"DTLS-VERSION-MIN", (sizeof("DTLS-VERSION-MIN") - 1), NSS_DTLS_VERSION_MIN_POLICY0x00a },
539 { CIPHER_NAME("DTLS-VERSION-MAX")"DTLS-VERSION-MAX", (sizeof("DTLS-VERSION-MAX") - 1), NSS_DTLS_VERSION_MAX_POLICY0x00b }
540};
541
542static const policyFlagDef policyFlagList[] = {
543 { CIPHER_NAME("SSL")"SSL", (sizeof("SSL") - 1), NSS_USE_ALG_IN_SSL0x00000008 },
544 { CIPHER_NAME("SSL-KEY-EXCHANGE")"SSL-KEY-EXCHANGE", (sizeof("SSL-KEY-EXCHANGE") - 1), NSS_USE_ALG_IN_SSL_KX0x00000004 },
545 /* add other key exhanges in the future */
546 { CIPHER_NAME("KEY-EXCHANGE")"KEY-EXCHANGE", (sizeof("KEY-EXCHANGE") - 1), NSS_USE_ALG_IN_KEY_EXCHANGE((0x00000400 | 0x00000800) | 0x00000004) },
547 { CIPHER_NAME("CERT-SIGNATURE")"CERT-SIGNATURE", (sizeof("CERT-SIGNATURE") - 1), NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
548 { CIPHER_NAME("CMS-SIGNATURE")"CMS-SIGNATURE", (sizeof("CMS-SIGNATURE") - 1), NSS_USE_ALG_IN_SMIME_SIGNATURE0x00000002 },
549 { CIPHER_NAME("SMIME-SIGNATURE")"SMIME-SIGNATURE", (sizeof("SMIME-SIGNATURE") - 1), NSS_USE_ALG_IN_SMIME_SIGNATURE0x00000002 },
550 { CIPHER_NAME("ALL-SIGNATURE")"ALL-SIGNATURE", (sizeof("ALL-SIGNATURE") - 1), NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
551 { CIPHER_NAME("PKCS12")"PKCS12", (sizeof("PKCS12") - 1), NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
552 /* only use in allow */
553 { CIPHER_NAME("PKCS12-LEGACY")"PKCS12-LEGACY", (sizeof("PKCS12-LEGACY") - 1), NSS_USE_ALG_IN_PKCS12_DECRYPT0x00000040 },
554 /* only use in disallow */
555 { CIPHER_NAME("PKCS12-ENCRYPT")"PKCS12-ENCRYPT", (sizeof("PKCS12-ENCRYPT") - 1), NSS_USE_ALG_IN_PKCS12_ENCRYPT0x00000080 },
556 { CIPHER_NAME("SMIME")"SMIME", (sizeof("SMIME") - 1), NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) },
557 /* only use in allow, enable */
558 { CIPHER_NAME("SMIME-LEGACY")"SMIME-LEGACY", (sizeof("SMIME-LEGACY") - 1), NSS_USE_ALG_IN_SMIME_LEGACY0x00000100 },
559 /* only use in disallow, disable */
560 { CIPHER_NAME("SMIME-ENCRYPT")"SMIME-ENCRYPT", (sizeof("SMIME-ENCRYPT") - 1), NSS_USE_ALG_IN_SMIME_ENCRYPT0x00000200 },
561 { CIPHER_NAME("SMIME-KEY-EXCHANGE")"SMIME-KEY-EXCHANGE", (sizeof("SMIME-KEY-EXCHANGE") - 1), NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
562 /* only use in allow */
563 { CIPHER_NAME("SMIME-KEY-EXCHANGE-LEGACY")"SMIME-KEY-EXCHANGE-LEGACY", (sizeof("SMIME-KEY-EXCHANGE-LEGACY"
) - 1)
, NSS_USE_ALG_IN_SMIME_KX_LEGACY0x00000400 },
564 /* only use in disallow */
565 { CIPHER_NAME("SMIME-KEY-EXCHANGE-ENCRYPT")"SMIME-KEY-EXCHANGE-ENCRYPT", (sizeof("SMIME-KEY-EXCHANGE-ENCRYPT"
) - 1)
, NSS_USE_ALG_IN_SMIME_KX_ENCRYPT0x00000800 },
566 /* sign turns off all signatures, but doesn't change the
567 * allowance for specific signatures... for example:
568 * disallow=sha256/all allow=sha256/signature
569 * doesn't allow cert-signatures or sime-signatures, where
570 * disallow=sha256/all allow=sha256/all-signature
571 * does. however,
572 * disallow=sha256/signature
573 * and
574 * disallow=sha256/all-signature
575 * are equivalent in effect */
576 { CIPHER_NAME("SIGNATURE")"SIGNATURE", (sizeof("SIGNATURE") - 1), NSS_USE_ALG_IN_ANY_SIGNATURE0x00000020 },
577 /* enable/allow algorithms for legacy (read/verify)operations */
578 { CIPHER_NAME("LEGACY")"LEGACY", (sizeof("LEGACY") - 1), NSS_USE_ALG_IN_PKCS12_DECRYPT0x00000040 |
579 NSS_USE_ALG_IN_SMIME_LEGACY0x00000100 |
580 NSS_USE_ALG_IN_SMIME_KX_LEGACY0x00000400 },
581 /* enable/disable everything */
582 { CIPHER_NAME("ALL")"ALL", (sizeof("ALL") - 1), NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_SSL_KX0x00000004 |
583 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
584 NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) |
585 NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
586 { CIPHER_NAME("NONE")"NONE", (sizeof("NONE") - 1), 0 }
587};
588
589/*
590 * Get the next cipher on the list. point to the next one in 'next'.
591 * return the length;
592 */
593static const char *
594secmod_ArgGetSubValue(const char *cipher, char sep1, char sep2,
595 int *len, const char **next)
596{
597 const char *start = cipher;
598
599 if (start == NULL((void*)0)) {
600 *len = 0;
601 *next = NULL((void*)0);
602 return start;
603 }
604
605 for (; *cipher && *cipher != sep2; cipher++) {
606 if (*cipher == sep1) {
607 *next = cipher + 1;
608 *len = cipher - start;
609 return start;
610 }
611 }
612 *next = NULL((void*)0);
613 *len = cipher - start;
614 return start;
615}
616
617static PRUint32
618secmod_parsePolicyValue(const char *policyFlags, int policyLength,
619 PRBool printPolicyFeedback, PRUint32 policyCheckFlags)
620{
621 const char *flag, *currentString;
622 PRUint32 flags = 0;
623 int i;
624
625 for (currentString = policyFlags; currentString &&
626 currentString < policyFlags + policyLength;) {
627 int length;
628 PRBool unknown = PR_TRUE1;
629 flag = secmod_ArgGetSubValue(currentString, ',', ':', &length,
630 &currentString);
631 if (length == 0) {
632 continue;
633 }
634 for (i = 0; i < PR_ARRAY_SIZE(policyFlagList)(sizeof(policyFlagList) / sizeof((policyFlagList)[0])); i++) {
635 const policyFlagDef *policy = &policyFlagList[i];
636 unsigned name_size = policy->name_size;
637 if ((policy->name_size == length) &&
638 PORT_StrncasecmpPL_strncasecmp(policy->name, flag, name_size) == 0) {
639 flags |= policy->flag;
640 unknown = PR_FALSE0;
641 break;
642 }
643 }
644 if (unknown && printPolicyFeedback &&
645 (policyCheckFlags & SECMOD_FLAG_POLICY_CHECK_VALUE0x02)) {
646 PR_SetEnv("NSS_POLICY_FAIL=1");
647 fprintf(stderrstderr, "NSS-POLICY-FAIL %.*s: unknown value: %.*s\n",
648 policyLength, policyFlags, length, flag);
649 }
650 }
651 return flags;
652}
653
654/* allow symbolic names for values. The only ones currently defines or
655 * SSL protocol versions. */
656static SECStatus
657secmod_getPolicyOptValue(const char *policyValue, int policyValueLength,
658 PRInt32 *result)
659{
660 PRInt32 val = atoi(policyValue);
661 int i;
662
663 if ((val != 0) || (*policyValue == '0')) {
664 *result = val;
665 return SECSuccess;
666 }
667 if (policyValueLength == 0) {
668 return SECFailure;
669 }
670 /* handle any ssl strings */
671 for (i = 0; i < PR_ARRAY_SIZE(sslOptList)(sizeof(sslOptList) / sizeof((sslOptList)[0])); i++) {
672 if (policyValueLength == sslOptList[i].name_size &&
673 PORT_StrncasecmpPL_strncasecmp(sslOptList[i].name, policyValue,
674 sslOptList[i].name_size) == 0) {
675 *result = sslOptList[i].option;
676 return SECSuccess;
677 }
678 }
679 /* handle key_size flags. Each flag represents a bit, which
680 * gets or'd together. They can be separated by , | or + */
681 val = 0;
682 while (policyValueLength > 0) {
683 PRBool found = PR_FALSE0;
684 for (i = 0; i < PR_ARRAY_SIZE(keySizeFlagsList)(sizeof(keySizeFlagsList) / sizeof((keySizeFlagsList)[0])); i++) {
685 if (PORT_StrncasecmpPL_strncasecmp(keySizeFlagsList[i].name, policyValue,
686 keySizeFlagsList[i].name_size) == 0) {
687 val |= keySizeFlagsList[i].option;
688 found = PR_TRUE1;
689 policyValue += keySizeFlagsList[i].name_size;
690 policyValueLength -= keySizeFlagsList[i].name_size;
691 break;
692 }
693 }
694 if (!found) {
695 return SECFailure;
696 }
697 if (*policyValue == ',' || *policyValue == '|' || *policyValue == '+') {
698 policyValue++;
699 policyValueLength--;
700 }
701 }
702 *result = val;
703 return SECSuccess;
704}
705
706/* Policy operations:
707 * Disallow: operation is disallowed by policy. Implies disabled.
708 * Allow: operation is allowed by policy (but could be disabled).
709 * Disable: operation is turned off by default (but could be allowed).
710 * Enable: operation is enabled by default. Implies allowed.
711 */
712typedef enum {
713 NSS_DISALLOW,
714 NSS_ALLOW,
715 NSS_DISABLE,
716 NSS_ENABLE
717} NSSPolicyOperation;
718
719/* Enable/Disable only apply to SSL cipher suites and S/MIME symetric algorithms.
720 * Enable/Disable is implemented by clearing the DEFAULT_NOT_VALID
721 * flag, then setting the NSS_USE_DEFAULT_SSL_ENABLE and
722 * NSS_USE_DEFAULT_SMIME_ENABLE flags to the correct value. The ssl
723 * policy code will then sort out what to set based on ciphers and
724 * cipher suite values and the smime policy code will sort
725 * out which ciphers to include in capabilities based on these values */
726static SECStatus
727secmod_setDefault(SECOidTag oid, NSSPolicyOperation operation,
728 PRUint32 value)
729{
730 SECStatus rv = SECSuccess;
731 PRUint32 policy;
732 PRUint32 useDefault = 0;
733 PRUint32 set = 0;
734 /* we always clear the default not valid flag as this operation will
735 * make the defaults valid */
736 PRUint32 clear = NSS_USE_DEFAULT_NOT_VALID0x80000000;
737
738 /* what values are we trying to change */
739 /* if either SSL or SSL_KX is set, enable SSL */
740 if (value & (NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_SSL_KX0x00000004)) {
741 useDefault |= NSS_USE_DEFAULT_SSL_ENABLE0x40000000;
742 }
743 /* only bulk ciphers are configured as enable in S/MIME, only
744 * enable them if both SMIME bits are set */
745 if ((value & NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200)) == NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200)) {
746 useDefault |= NSS_USE_DEFAULT_SMIME_ENABLE0x20000000;
747 }
748
749 /* on disable we clear, on enable we set */
750 if (operation == NSS_DISABLE) {
751 clear |= useDefault;
752 } else {
753 /* we also turn the cipher on by policy if we enable it,
754 * so include the policy bits */
755 set |= value | useDefault;
756 }
757
758 /* if we haven't set the not valid flag yet, then we need to
759 * clear any of the other bits we aren't actually setting as well.
760 */
761 rv = NSS_GetAlgorithmPolicy(oid, &policy);
762 if (rv != SECSuccess) {
763 return rv;
764 }
765 if (policy & NSS_USE_DEFAULT_NOT_VALID0x80000000) {
766 clear |= ((NSS_USE_DEFAULT_SSL_ENABLE0x40000000 | NSS_USE_DEFAULT_SMIME_ENABLE0x20000000) &
767 ~set);
768 }
769 return NSS_SetAlgorithmPolicy(oid, set, clear);
770}
771
772/* apply the operator specific policy */
773SECStatus
774secmod_setPolicyOperation(SECOidTag oid, NSSPolicyOperation operation,
775 PRUint32 value)
776{
777 SECStatus rv = SECSuccess;
778 switch (operation) {
779 case NSS_DISALLOW:
780 /* clear the requested policy bits */
781 rv = NSS_SetAlgorithmPolicy(oid, 0, value);
782 break;
783 case NSS_ALLOW:
784 /* set the requested policy bits */
785 rv = NSS_SetAlgorithmPolicy(oid, value, 0);
786 break;
787 case NSS_DISABLE:
788 case NSS_ENABLE:
789 rv = secmod_setDefault(oid, operation, value);
790 break;
791 default:
792 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE);
793 rv = SECFailure;
794 break;
795 }
796 return rv;
797}
798
799const char *
800secmod_getOperationString(NSSPolicyOperation operation)
801{
802 switch (operation) {
803 case NSS_DISALLOW:
804 return "disallow";
805 case NSS_ALLOW:
806 return "allow";
807 case NSS_DISABLE:
808 return "disable";
809 case NSS_ENABLE:
810 return "enable";
811 default:
812 break;
813 }
814 return "invalid";
815}
816
817/* Allow external applications fetch the policy oid based on the internal
818 * string mapping used by the configuration system. The search can be
819 * narrowed by supplying the name of the table (list) that the policy
820 * is on. The value 'Any' allows the policy to be searched on all lists */
821SECOidTag
822SECMOD_PolicyStringToOid(const char *policy, const char *list)
823{
824 PRBool any = (PORT_StrcasecmpPL_strcasecmp(list, "Any") == 0) ? PR_TRUE1 : PR_FALSE0;
825 int len = PORT_Strlen(policy)strlen(policy);
826 int i, j;
827
828 for (i = 0; i < PR_ARRAY_SIZE(algOptLists)(sizeof(algOptLists) / sizeof((algOptLists)[0])); i++) {
829 const algListsDef *algOptList = &algOptLists[i];
830 if (any || (PORT_StrcasecmpPL_strcasecmp(algOptList->description, list) == 0)) {
831 for (j = 0; j < algOptList->entries; j++) {
832 const oidValDef *algOpt = &algOptList->list[j];
833 unsigned name_size = algOpt->name_size;
834 if (len == name_size &&
835 PORT_StrcasecmpPL_strcasecmp(algOpt->name, policy) == 0) {
836 return algOpt->oid;
837 }
838 }
839 }
840 }
841 return SEC_OID_UNKNOWN;
842}
843
844/* Allow external applications fetch the NSS option based on the internal
845 * string mapping used by the configuration system. */
846PRUint32
847SECMOD_PolicyStringToOpt(const char *policy)
848{
849 int len = PORT_Strlen(policy)strlen(policy);
850 int i;
851
852 for (i = 0; i < PR_ARRAY_SIZE(freeOptList)(sizeof(freeOptList) / sizeof((freeOptList)[0])); i++) {
853 const optionFreeDef *freeOpt = &freeOptList[i];
854 unsigned name_size = freeOpt->name_size;
855 if (len == name_size &&
856 PORT_StrcasecmpPL_strcasecmp(freeOpt->name, policy) == 0) {
857 return freeOpt->option;
858 }
859 }
860 return 0;
861}
862
863/* Allow external applications map policy flags to their string equivalance.
864 * Some strings represent more than one flag. If more than one flag is included
865 * the returned string is the string that contains any of the
866 * supplied flags unless exact is specified. If exact is specified, then the
867 * returned value matches all the included flags and only those flags. For
868 * Example: 'ALL-SIGNATURE' has the bits NSS_USE_ALG_IN_CERTSIGNATURE|
869 * NSS_USE_ALG_IN_SMIME_SIGNATURE|NSS_USE_ALG_IN_ANY_SIGNATURE. If you ask for
870 * NSS_USE_ALG_IN_CERT_SIGNATURE|NSS_USE_ALG_IN_SMIME_SIGNATURE and don't set
871 * exact, this function will return 'ALL-SIGNATURE' if you do set exact, you must
872 * include all three bits in value to get 'All-SIGNATURE'*/
873const char *
874SECMOD_FlagsToPolicyString(PRUint32 val, PRBool exact)
875{
876 int i;
877
878 for (i = 0; i < PR_ARRAY_SIZE(policyFlagList)(sizeof(policyFlagList) / sizeof((policyFlagList)[0])); i++) {
879 const policyFlagDef *policy = &policyFlagList[i];
880 if (exact && (policy->flag == val)) {
881 return policy->name;
882 }
883 if (!exact && ((policy->flag & val) == policy->flag)) {
884 return policy->name;
885 }
886 }
887 return NULL((void*)0);
888}
889
890static SECStatus
891secmod_applyCryptoPolicy(const char *policyString, NSSPolicyOperation operation,
892 PRBool printPolicyFeedback, PRUint32 policyCheckFlags)
893{
894 const char *cipher, *currentString;
895 unsigned i, j;
896 SECStatus rv = SECSuccess;
897 PRBool unknown;
898
899 if (policyString == NULL((void*)0) || policyString[0] == 0) {
900 return SECSuccess; /* do nothing */
901 }
902
903 /* if we change any of these, make sure it gets applied in ssl as well */
904 NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL0x00000010, 0);
905
906 for (currentString = policyString; currentString;) {
907 int length;
908 PRBool newValue = PR_FALSE0;
909
910 cipher = secmod_ArgGetSubValue(currentString, ':', 0, &length,
911 &currentString);
912 unknown = PR_TRUE1;
913 if (length >= 3 && cipher[3] == '/') {
914 newValue = PR_TRUE1;
915 }
916 if ((newValue || (length == 3)) && PORT_StrncasecmpPL_strncasecmp(cipher, "all", 3) == 0) {
917 /* disable or enable all options by default */
918 PRUint32 value = 0;
919 if (newValue) {
920 value = secmod_parsePolicyValue(&cipher[3] + 1, length - 3 - 1, printPolicyFeedback, policyCheckFlags);
921 }
922 for (i = 0; i < PR_ARRAY_SIZE(algOptLists)(sizeof(algOptLists) / sizeof((algOptLists)[0])); i++) {
923 const algListsDef *algOptList = &algOptLists[i];
924 for (j = 0; j < algOptList->entries; j++) {
925 if (!newValue) {
926 value = algOptList->list[j].val;
927 }
928 secmod_setPolicyOperation(algOptList->list[j].oid, operation, value);
929 }
930 }
931 continue;
932 }
933
934 for (i = 0; i < PR_ARRAY_SIZE(algOptLists)(sizeof(algOptLists) / sizeof((algOptLists)[0])); i++) {
935 const algListsDef *algOptList = &algOptLists[i];
936 for (j = 0; j < algOptList->entries; j++) {
937 const oidValDef *algOpt = &algOptList->list[j];
938 unsigned name_size = algOpt->name_size;
939 PRBool newOption = PR_FALSE0;
940
941 if ((length >= name_size) && (cipher[name_size] == '/')) {
942 newOption = PR_TRUE1;
943 }
944 if ((newOption || algOpt->name_size == length) &&
945 PORT_StrncasecmpPL_strncasecmp(algOpt->name, cipher, name_size) == 0) {
946 PRUint32 value = algOpt->val;
947 if (newOption) {
948 value = secmod_parsePolicyValue(&cipher[name_size] + 1,
949 length - name_size - 1,
950 printPolicyFeedback,
951 policyCheckFlags);
952 }
953 rv = secmod_setPolicyOperation(algOptList->list[j].oid, operation, value);
954 if (rv != SECSuccess) {
955 /* could not enable option */
956 /* NSS_SetAlgorithPolicy should have set the error code */
957 return SECFailure;
958 }
959 unknown = PR_FALSE0;
960 break;
961 }
962 }
963 }
964 if (!unknown) {
965 continue;
966 }
967
968 for (i = 0; i < PR_ARRAY_SIZE(freeOptList)(sizeof(freeOptList) / sizeof((freeOptList)[0])); i++) {
969 const optionFreeDef *freeOpt = &freeOptList[i];
970 unsigned name_size = freeOpt->name_size;
971
972 if ((length > name_size) && cipher[name_size] == '=' &&
973 PORT_StrncasecmpPL_strncasecmp(freeOpt->name, cipher, name_size) == 0) {
974 PRInt32 val;
975 const char *policyValue = &cipher[name_size + 1];
976 int policyValueLength = length - name_size - 1;
977 rv = secmod_getPolicyOptValue(policyValue, policyValueLength,
978 &val);
979 if (rv != SECSuccess) {
980 if (printPolicyFeedback &&
981 (policyCheckFlags & SECMOD_FLAG_POLICY_CHECK_VALUE0x02)) {
982 PR_SetEnv("NSS_POLICY_FAIL=1");
983 fprintf(stderrstderr, "NSS-POLICY-FAIL %.*s: unknown value: %.*s\n",
984 length, cipher, policyValueLength, policyValue);
985 }
986 return SECFailure;
987 }
988 rv = NSS_OptionSet(freeOpt->option, val);
989 if (rv != SECSuccess) {
990 /* could not enable option */
991 /* NSS_OptionSet should have set the error code */
992 return SECFailure;
993 }
994 /* to allow the policy to expand in the future. ignore ciphers
995 * we don't understand */
996 unknown = PR_FALSE0;
997 break;
998 }
999 }
1000
1001 if (unknown && printPolicyFeedback &&
1002 (policyCheckFlags & SECMOD_FLAG_POLICY_CHECK_IDENTIFIER0x01)) {
1003 PR_SetEnv("NSS_POLICY_FAIL=1");
1004 fprintf(stderrstderr, "NSS-POLICY-FAIL %s: unknown identifier: %.*s\n",
1005 secmod_getOperationString(operation), length, cipher);
1006 }
1007 }
1008 return rv;
1009}
1010
1011static void
1012secmod_sanityCheckCryptoPolicy(void)
1013{
1014 unsigned i, j;
1015 SECStatus rv = SECSuccess;
1016 unsigned num_kx_enabled = 0;
1017 unsigned num_ssl_enabled = 0;
1018 unsigned num_sig_enabled = 0;
1019 unsigned enabledCount[PR_ARRAY_SIZE(algOptLists)(sizeof(algOptLists) / sizeof((algOptLists)[0]))];
1020 const char *sWarn = "WARN";
1021 const char *sInfo = "INFO";
1022 PRBool haveWarning = PR_FALSE0;
1023
1024 for (i = 0; i < PR_ARRAY_SIZE(algOptLists)(sizeof(algOptLists) / sizeof((algOptLists)[0])); i++) {
1025 const algListsDef *algOptList = &algOptLists[i];
1026 enabledCount[i] = 0;
1027 for (j = 0; j < algOptList->entries; j++) {
1028 const oidValDef *algOpt = &algOptList->list[j];
1029 PRUint32 value;
1030 PRBool anyEnabled = PR_FALSE0;
1031 rv = NSS_GetAlgorithmPolicy(algOpt->oid, &value);
1032 if (rv != SECSuccess) {
1033 PR_SetEnv("NSS_POLICY_FAIL=1");
1034 fprintf(stderrstderr, "NSS-POLICY-FAIL: internal failure with NSS_GetAlgorithmPolicy at %u\n", i);
1035 return;
1036 }
1037
1038 if ((algOpt->val & NSS_USE_ALG_IN_SSL_KX0x00000004) && (value & NSS_USE_ALG_IN_SSL_KX0x00000004)) {
1039 ++num_kx_enabled;
1040 anyEnabled = PR_TRUE1;
1041 fprintf(stderrstderr, "NSS-POLICY-INFO: %s is enabled for SSL-KX\n", algOpt->name);
1042 }
1043 if ((algOpt->val & NSS_USE_ALG_IN_SSL0x00000008) && (value & NSS_USE_ALG_IN_SSL0x00000008)) {
1044 ++num_ssl_enabled;
1045 anyEnabled = PR_TRUE1;
1046 fprintf(stderrstderr, "NSS-POLICY-INFO: %s is enabled for SSL\n", algOpt->name);
1047 }
1048 if ((algOpt->val & NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001) &&
1049 ((value & NSS_USE_CERT_SIGNATURE_OK(0x00000001 | 0x00000020)) == NSS_USE_CERT_SIGNATURE_OK(0x00000001 | 0x00000020))) {
1050 ++num_sig_enabled;
1051 anyEnabled = PR_TRUE1;
1052 fprintf(stderrstderr, "NSS-POLICY-INFO: %s is enabled for CERT-SIGNATURE\n", algOpt->name);
1053 }
1054 if (anyEnabled) {
1055 ++enabledCount[i];
1056 }
1057 }
1058 }
1059 fprintf(stderrstderr, "NSS-POLICY-%s: NUMBER-OF-SSL-ALG-KX: %u\n", num_kx_enabled ? sInfo : sWarn, num_kx_enabled);
1060 fprintf(stderrstderr, "NSS-POLICY-%s: NUMBER-OF-SSL-ALG: %u\n", num_ssl_enabled ? sInfo : sWarn, num_ssl_enabled);
1061 fprintf(stderrstderr, "NSS-POLICY-%s: NUMBER-OF-CERT-SIG: %u\n", num_sig_enabled ? sInfo : sWarn, num_sig_enabled);
1062 if (!num_kx_enabled || !num_ssl_enabled || !num_sig_enabled) {
1063 haveWarning = PR_TRUE1;
1064 }
1065 for (i = 0; i < PR_ARRAY_SIZE(algOptLists)(sizeof(algOptLists) / sizeof((algOptLists)[0])); i++) {
1066 const algListsDef *algOptList = &algOptLists[i];
1067 fprintf(stderrstderr, "NSS-POLICY-%s: NUMBER-OF-%s: %u\n", enabledCount[i] ? sInfo : sWarn, algOptList->description, enabledCount[i]);
1068 if (!enabledCount[i] && !algOptList->allowEmpty) {
1069 haveWarning = PR_TRUE1;
1070 }
1071 }
1072 if (haveWarning) {
1073 PR_SetEnv("NSS_POLICY_WARN=1");
1074 }
1075}
1076
1077static SECStatus
1078secmod_parseCryptoPolicy(const char *policyConfig, PRBool printPolicyFeedback,
1079 PRUint32 policyCheckFlags)
1080{
1081 char *args;
1082 SECStatus rv;
1083
1084 if (policyConfig == NULL((void*)0)) {
1085 return SECSuccess; /* no policy given */
1086 }
1087 /* make sure we initialize the oid table and set all the default policy
1088 * values first so we can override them here */
1089 rv = SECOID_Init();
1090 if (rv != SECSuccess) {
1091 return rv;
1092 }
1093 args = NSSUTIL_ArgGetParamValue("disallow", policyConfig);
1094 rv = secmod_applyCryptoPolicy(args, NSS_DISALLOW, printPolicyFeedback,
1095 policyCheckFlags);
1096 if (args)
1097 PORT_FreePORT_Free_Util(args);
1098 if (rv != SECSuccess) {
1099 return rv;
1100 }
1101 args = NSSUTIL_ArgGetParamValue("allow", policyConfig);
1102 rv = secmod_applyCryptoPolicy(args, NSS_ALLOW, printPolicyFeedback,
1103 policyCheckFlags);
1104 if (args)
1105 PORT_FreePORT_Free_Util(args);
1106 if (rv != SECSuccess) {
1107 return rv;
1108 }
1109 args = NSSUTIL_ArgGetParamValue("disable", policyConfig);
1110 rv = secmod_applyCryptoPolicy(args, NSS_DISABLE, printPolicyFeedback,
1111 policyCheckFlags);
1112 if (args)
1113 PORT_FreePORT_Free_Util(args);
1114 if (rv != SECSuccess) {
1115 return rv;
1116 }
1117 args = NSSUTIL_ArgGetParamValue("enable", policyConfig);
1118 rv = secmod_applyCryptoPolicy(args, NSS_ENABLE, printPolicyFeedback,
1119 policyCheckFlags);
1120 if (args)
1121 PORT_FreePORT_Free_Util(args);
1122 if (rv != SECSuccess) {
1123 return rv;
1124 }
1125 /* this has to be last. Everything after this will be a noop */
1126 if (NSSUTIL_ArgHasFlag("flags", "ssl-lock", policyConfig)) {
1127 PRInt32 locks;
1128 /* don't overwrite other (future) lock flags */
1129 rv = NSS_OptionGet(NSS_DEFAULT_LOCKS0x00d, &locks);
1130 if (rv == SECSuccess) {
1131 rv = NSS_OptionSet(NSS_DEFAULT_LOCKS0x00d, locks | NSS_DEFAULT_SSL_LOCK1);
1132 }
1133 if (rv != SECSuccess) {
1134 return rv;
1135 }
1136 }
1137 if (NSSUTIL_ArgHasFlag("flags", "policy-lock", policyConfig)) {
1138 NSS_LockPolicy();
1139 }
1140 if (printPolicyFeedback) {
1141 /* This helps to distinguish configurations that don't contain any
1142 * policy config= statement. */
1143 PR_SetEnv("NSS_POLICY_LOADED=1");
1144 fprintf(stderrstderr, "NSS-POLICY-INFO: LOADED-SUCCESSFULLY\n");
1145 secmod_sanityCheckCryptoPolicy();
1146 }
1147 return rv;
1148}
1149
1150static PRUint32
1151secmod_parsePolicyCheckFlags(const char *nss)
1152{
1153 PRUint32 policyCheckFlags = 0;
1154
1155 if (NSSUTIL_ArgHasFlag("flags", "policyCheckIdentifier", nss)) {
1156 policyCheckFlags |= SECMOD_FLAG_POLICY_CHECK_IDENTIFIER0x01;
1157 }
1158
1159 if (NSSUTIL_ArgHasFlag("flags", "policyCheckValue", nss)) {
1160 policyCheckFlags |= SECMOD_FLAG_POLICY_CHECK_VALUE0x02;
1161 }
1162
1163 return policyCheckFlags;
1164}
1165
1166/*
1167 * for 3.4 we continue to use the old SECMODModule structure
1168 */
1169SECMODModule *
1170SECMOD_CreateModuleEx(const char *library, const char *moduleName,
1171 const char *parameters, const char *nss,
1172 const char *config)
1173{
1174 SECMODModule *mod;
1175 SECStatus rv;
1176 char *slotParams, *ciphers;
1177 PRBool printPolicyFeedback = NSSUTIL_ArgHasFlag("flags", "printPolicyFeedback", nss);
1178 PRUint32 policyCheckFlags = secmod_parsePolicyCheckFlags(nss);
1179
1180 rv = secmod_parseCryptoPolicy(config, printPolicyFeedback, policyCheckFlags);
1181
1182 /* do not load the module if policy parsing fails */
1183 if (rv != SECSuccess) {
1184 if (printPolicyFeedback) {
1185 PR_SetEnv("NSS_POLICY_FAIL=1");
1186 fprintf(stderrstderr, "NSS-POLICY-FAIL: policy config parsing failed, not loading module %s\n", moduleName);
1187 }
1188 return NULL((void*)0);
1189 }
1190
1191 mod = secmod_NewModule();
1192 if (mod == NULL((void*)0))
1193 return NULL((void*)0);
1194
1195 mod->commonName = PORT_ArenaStrdupPORT_ArenaStrdup_Util(mod->arena, moduleName ? moduleName : "");
1196 if (library) {
1197 mod->dllName = PORT_ArenaStrdupPORT_ArenaStrdup_Util(mod->arena, library);
1198 }
1199 /* new field */
1200 if (parameters) {
1201 mod->libraryParams = PORT_ArenaStrdupPORT_ArenaStrdup_Util(mod->arena, parameters);
1202 }
1203
1204 mod->internal = NSSUTIL_ArgHasFlag("flags", "internal", nss);
1205 mod->isFIPS = NSSUTIL_ArgHasFlag("flags", "FIPS", nss);
1206 /* if the system FIPS mode is enabled, force FIPS to be on */
1207 if (SECMOD_GetSystemFIPSEnabled()) {
1208 mod->isFIPS = PR_TRUE1;
1209 }
1210 mod->isCritical = NSSUTIL_ArgHasFlag("flags", "critical", nss);
1211 slotParams = NSSUTIL_ArgGetParamValue("slotParams", nss);
1212 mod->slotInfo = NSSUTIL_ArgParseSlotInfo(mod->arena, slotParams,
1213 &mod->slotInfoCount);
1214 if (slotParams)
1215 PORT_FreePORT_Free_Util(slotParams);
1216 /* new field */
1217 mod->trustOrder = NSSUTIL_ArgReadLong("trustOrder", nss,
1218 NSSUTIL_DEFAULT_TRUST_ORDER50, NULL((void*)0));
1219 /* new field */
1220 mod->cipherOrder = NSSUTIL_ArgReadLong("cipherOrder", nss,
1221 NSSUTIL_DEFAULT_CIPHER_ORDER0, NULL((void*)0));
1222 /* new field */
1223 mod->isModuleDB = NSSUTIL_ArgHasFlag("flags", "moduleDB", nss);
1224 mod->moduleDBOnly = NSSUTIL_ArgHasFlag("flags", "moduleDBOnly", nss);
1225 if (mod->moduleDBOnly)
1226 mod->isModuleDB = PR_TRUE1;
1227
1228 /* we need more bits, but we also want to preserve binary compatibility
1229 * so we overload the isModuleDB PRBool with additional flags.
1230 * These flags are only valid if mod->isModuleDB is already set.
1231 * NOTE: this depends on the fact that PRBool is at least a char on
1232 * all platforms. These flags are only valid if moduleDB is set, so
1233 * code checking if (mod->isModuleDB) will continue to work correctly. */
1234 if (mod->isModuleDB) {
1235 char flags = SECMOD_FLAG_MODULE_DB_IS_MODULE_DB0x01;
1236 if (NSSUTIL_ArgHasFlag("flags", "skipFirst", nss)) {
1237 flags |= SECMOD_FLAG_MODULE_DB_SKIP_FIRST0x02;
1238 }
1239 if (NSSUTIL_ArgHasFlag("flags", "defaultModDB", nss)) {
1240 flags |= SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB0x04;
1241 }
1242 if (NSSUTIL_ArgHasFlag("flags", "policyOnly", nss)) {
1243 flags |= SECMOD_FLAG_MODULE_DB_POLICY_ONLY0x08;
1244 }
1245 /* additional moduleDB flags could be added here in the future */
1246 mod->isModuleDB = (PRBool)flags;
1247 }
1248
1249 if (mod->internal) {
1250 char flags = SECMOD_FLAG_INTERNAL_IS_INTERNAL0x01;
1251
1252 if (NSSUTIL_ArgHasFlag("flags", "internalKeySlot", nss)) {
1253 flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT0x02;
1254 }
1255 mod->internal = (PRBool)flags;
1256 }
1257
1258 ciphers = NSSUTIL_ArgGetParamValue("ciphers", nss);
1259 NSSUTIL_ArgParseCipherFlags(&mod->ssl[0], ciphers);
1260 if (ciphers)
1261 PORT_FreePORT_Free_Util(ciphers);
1262
1263 secmod_PrivateModuleCount++;
1264
1265 return mod;
1266}
1267
1268PRBool
1269SECMOD_GetSkipFirstFlag(SECMODModule *mod)
1270{
1271 char flags = (char)mod->isModuleDB;
1272
1273 return (flags & SECMOD_FLAG_MODULE_DB_SKIP_FIRST0x02) ? PR_TRUE1 : PR_FALSE0;
1274}
1275
1276PRBool
1277SECMOD_GetDefaultModDBFlag(SECMODModule *mod)
1278{
1279 char flags = (char)mod->isModuleDB;
1280
1281 return (flags & SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB0x04) ? PR_TRUE1 : PR_FALSE0;
1282}
1283
1284PRBool
1285secmod_PolicyOnly(SECMODModule *mod)
1286{
1287 char flags = (char)mod->isModuleDB;
1288
1289 return (flags & SECMOD_FLAG_MODULE_DB_POLICY_ONLY0x08) ? PR_TRUE1 : PR_FALSE0;
1290}
1291
1292PRBool
1293secmod_IsInternalKeySlot(SECMODModule *mod)
1294{
1295 char flags = (char)mod->internal;
1296
1297 return (flags & SECMOD_FLAG_INTERNAL_KEY_SLOT0x02) ? PR_TRUE1 : PR_FALSE0;
1298}
1299
1300void
1301secmod_SetInternalKeySlotFlag(SECMODModule *mod, PRBool val)
1302{
1303 char flags = (char)mod->internal;
1304
1305 if (val) {
1306 flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT0x02;
1307 } else {
1308 flags &= ~SECMOD_FLAG_INTERNAL_KEY_SLOT0x02;
1309 }
1310 mod->internal = flags;
1311}
1312
1313/*
1314 * copy desc and value into target. Target is known to be big enough to
1315 * hold desc +2 +value, which is good because the result of this will be
1316 * *desc"*value". We may, however, have to add some escapes for special
1317 * characters imbedded into value (rare). This string potentially comes from
1318 * a user, so we don't want the user overflowing the target buffer by using
1319 * excessive escapes. To prevent this we count the escapes we need to add and
1320 * try to expand the buffer with Realloc.
1321 */
1322static char *
1323secmod_doDescCopy(char *target, char **base, int *baseLen,
1324 const char *desc, int descLen, char *value)
1325{
1326 int diff, esc_len;
1327
1328 esc_len = NSSUTIL_EscapeSize(value, '\"') - 1;
1329 diff = esc_len - strlen(value);
1330 if (diff > 0) {
1331 /* we need to escape... expand newSpecPtr as well to make sure
1332 * we don't overflow it */
1333 int offset = target - *base;
1334 char *newPtr = PORT_ReallocPORT_Realloc_Util(*base, *baseLen + diff);
1335 if (!newPtr) {
1336 return target; /* not enough space, just drop the whole copy */
1337 }
1338 *baseLen += diff;
1339 target = newPtr + offset;
1340 *base = newPtr;
1341 value = NSSUTIL_Escape(value, '\"');
1342 if (value == NULL((void*)0)) {
1343 return target; /* couldn't escape value, just drop the copy */
1344 }
1345 }
1346 PORT_Memcpymemcpy(target, desc, descLen);
1347 target += descLen;
1348 *target++ = '\"';
1349 PORT_Memcpymemcpy(target, value, esc_len);
1350 target += esc_len;
1351 *target++ = '\"';
1352 if (diff > 0) {
1353 PORT_FreePORT_Free_Util(value);
1354 }
1355 return target;
1356}
1357
1358#define SECMOD_SPEC_COPY(new, start, end)if (end > start) { int _cnt = end - start; memcpy(new, start
, _cnt); new += _cnt; }
\
1359 if (end > start) { \
1360 int _cnt = end - start; \
1361 PORT_Memcpymemcpy(new, start, _cnt); \
1362 new += _cnt; \
1363 }
1364#define SECMOD_TOKEN_DESCRIPTION"tokenDescription=" "tokenDescription="
1365#define SECMOD_SLOT_DESCRIPTION"slotDescription=" "slotDescription="
1366
1367/*
1368 * Find any tokens= values in the module spec.
1369 * Always return a new spec which does not have any tokens= arguments.
1370 * If tokens= arguments are found, Split the the various tokens defined into
1371 * an array of child specs to return.
1372 *
1373 * Caller is responsible for freeing the child spec and the new token
1374 * spec.
1375 */
1376char *
1377secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
1378 const char *moduleSpec, char ***children,
1379 CK_SLOT_ID **ids)
1380{
1381 int newSpecLen = PORT_Strlen(moduleSpec)strlen(moduleSpec) + 2;
1382 char *newSpec = PORT_AllocPORT_Alloc_Util(newSpecLen);
1383 char *newSpecPtr = newSpec;
1384 const char *modulePrev = moduleSpec;
1385 char *target = NULL((void*)0);
1386 char *tmp = NULL((void*)0);
1387 char **childArray = NULL((void*)0);
1388 const char *tokenIndex;
1389 CK_SLOT_ID *idArray = NULL((void*)0);
1390 int tokenCount = 0;
1391 int i;
1392
1393 if (newSpec == NULL((void*)0)) {
1394 return NULL((void*)0);
1395 }
1396
1397 *children = NULL((void*)0);
1398 if (ids) {
1399 *ids = NULL((void*)0);
1400 }
1401 moduleSpec = NSSUTIL_ArgStrip(moduleSpec);
1402 SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec)if (moduleSpec > modulePrev) { int _cnt = moduleSpec - modulePrev
; memcpy(newSpecPtr, modulePrev, _cnt); newSpecPtr += _cnt; }
;
1403
1404 /* Notes on 'convert' and 'isFIPS' flags: The base parameters for opening
1405 * a new softoken module takes the following parameters to name the
1406 * various tokens:
1407 *
1408 * cryptoTokenDescription: name of the non-fips crypto token.
1409 * cryptoSlotDescription: name of the non-fips crypto slot.
1410 * dbTokenDescription: name of the non-fips db token.
1411 * dbSlotDescription: name of the non-fips db slot.
1412 * FIPSTokenDescription: name of the fips db/crypto token.
1413 * FIPSSlotDescription: name of the fips db/crypto slot.
1414 *
1415 * if we are opening a new slot, we need to have the following
1416 * parameters:
1417 * tokenDescription: name of the token.
1418 * slotDescription: name of the slot.
1419 *
1420 *
1421 * The convert flag tells us to drop the unnecessary *TokenDescription
1422 * and *SlotDescription arguments and convert the appropriate pair
1423 * (either db or FIPS based on the isFIPS flag) to tokenDescription and
1424 * slotDescription).
1425 */
1426 /*
1427 * walk down the list. if we find a tokens= argument, save it,
1428 * otherise copy the argument.
1429 */
1430 while (*moduleSpec) {
1431 int next;
1432 modulePrev = moduleSpec;
1433 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, target, "tokens=",if (PL_strncasecmp(moduleSpec, "tokens=", sizeof("tokens=") -
1) == 0) { moduleSpec += sizeof("tokens=") - 1; if (target) PORT_Free_Util
(target); target = NSSUTIL_ArgFetchValue(moduleSpec, &next
); moduleSpec += next; modulePrev = moduleSpec;; } else
1434 modulePrev = moduleSpec;if (PL_strncasecmp(moduleSpec, "tokens=", sizeof("tokens=") -
1) == 0) { moduleSpec += sizeof("tokens=") - 1; if (target) PORT_Free_Util
(target); target = NSSUTIL_ArgFetchValue(moduleSpec, &next
); moduleSpec += next; modulePrev = moduleSpec;; } else
1435 /* skip copying */)if (PL_strncasecmp(moduleSpec, "tokens=", sizeof("tokens=") -
1) == 0) { moduleSpec += sizeof("tokens=") - 1; if (target) PORT_Free_Util
(target); target = NSSUTIL_ArgFetchValue(moduleSpec, &next
); moduleSpec += next; modulePrev = moduleSpec;; } else
1436 NSSUTIL_HANDLE_STRING_ARG(if (PL_strncasecmp(moduleSpec, "cryptoTokenDescription=", sizeof
("cryptoTokenDescription=") - 1) == 0) { moduleSpec += sizeof
("cryptoTokenDescription=") - 1; if (tmp) PORT_Free_Util(tmp)
; tmp = NSSUTIL_ArgFetchValue(moduleSpec, &next); moduleSpec
+= next; if (convert) { modulePrev = moduleSpec; }; } else
1437 moduleSpec, tmp, "cryptoTokenDescription=",if (PL_strncasecmp(moduleSpec, "cryptoTokenDescription=", sizeof
("cryptoTokenDescription=") - 1) == 0) { moduleSpec += sizeof
("cryptoTokenDescription=") - 1; if (tmp) PORT_Free_Util(tmp)
; tmp = NSSUTIL_ArgFetchValue(moduleSpec, &next); moduleSpec
+= next; if (convert) { modulePrev = moduleSpec; }; } else
1438 if (convert) { modulePrev = moduleSpec; })if (PL_strncasecmp(moduleSpec, "cryptoTokenDescription=", sizeof
("cryptoTokenDescription=") - 1) == 0) { moduleSpec += sizeof
("cryptoTokenDescription=") - 1; if (tmp) PORT_Free_Util(tmp)
; tmp = NSSUTIL_ArgFetchValue(moduleSpec, &next); moduleSpec
+= next; if (convert) { modulePrev = moduleSpec; }; } else
1439 NSSUTIL_HANDLE_STRING_ARG(if (PL_strncasecmp(moduleSpec, "cryptoSlotDescription=", sizeof
("cryptoSlotDescription=") - 1) == 0) { moduleSpec += sizeof(
"cryptoSlotDescription=") - 1; if (tmp) PORT_Free_Util(tmp); tmp
= NSSUTIL_ArgFetchValue(moduleSpec, &next); moduleSpec +=
next; if (convert) { modulePrev = moduleSpec; }; } else
1440 moduleSpec, tmp, "cryptoSlotDescription=",if (PL_strncasecmp(moduleSpec, "cryptoSlotDescription=", sizeof
("cryptoSlotDescription=") - 1) == 0) { moduleSpec += sizeof(
"cryptoSlotDescription=") - 1; if (tmp) PORT_Free_Util(tmp); tmp
= NSSUTIL_ArgFetchValue(moduleSpec, &next); moduleSpec +=
next; if (convert) { modulePrev = moduleSpec; }; } else
1441 if (convert) { modulePrev = moduleSpec; })if (PL_strncasecmp(moduleSpec, "cryptoSlotDescription=", sizeof
("cryptoSlotDescription=") - 1) == 0) { moduleSpec += sizeof(
"cryptoSlotDescription=") - 1; if (tmp) PORT_Free_Util(tmp); tmp
= NSSUTIL_ArgFetchValue(moduleSpec, &next); moduleSpec +=
next; if (convert) { modulePrev = moduleSpec; }; } else
1442 NSSUTIL_HANDLE_STRING_ARG(if (PL_strncasecmp(moduleSpec, "dbTokenDescription=", sizeof(
"dbTokenDescription=") - 1) == 0) { moduleSpec += sizeof("dbTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(
newSpecPtr, &newSpec, &newSpecLen, "tokenDescription="
, sizeof("tokenDescription=") - 1, tmp); } }; } else
1443 moduleSpec, tmp, "dbTokenDescription=",if (PL_strncasecmp(moduleSpec, "dbTokenDescription=", sizeof(
"dbTokenDescription=") - 1) == 0) { moduleSpec += sizeof("dbTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(
newSpecPtr, &newSpec, &newSpecLen, "tokenDescription="
, sizeof("tokenDescription=") - 1, tmp); } }; } else
1444 if (convert) {if (PL_strncasecmp(moduleSpec, "dbTokenDescription=", sizeof(
"dbTokenDescription=") - 1) == 0) { moduleSpec += sizeof("dbTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(
newSpecPtr, &newSpec, &newSpecLen, "tokenDescription="
, sizeof("tokenDescription=") - 1, tmp); } }; } else
1445 modulePrev = moduleSpec;if (PL_strncasecmp(moduleSpec, "dbTokenDescription=", sizeof(
"dbTokenDescription=") - 1) == 0) { moduleSpec += sizeof("dbTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(
newSpecPtr, &newSpec, &newSpecLen, "tokenDescription="
, sizeof("tokenDescription=") - 1, tmp); } }; } else
1446 if (!isFIPS) {if (PL_strncasecmp(moduleSpec, "dbTokenDescription=", sizeof(
"dbTokenDescription=") - 1) == 0) { moduleSpec += sizeof("dbTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(
newSpecPtr, &newSpec, &newSpecLen, "tokenDescription="
, sizeof("tokenDescription=") - 1, tmp); } }; } else
1447 newSpecPtr = secmod_doDescCopy(newSpecPtr,if (PL_strncasecmp(moduleSpec, "dbTokenDescription=", sizeof(
"dbTokenDescription=") - 1) == 0) { moduleSpec += sizeof("dbTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(
newSpecPtr, &newSpec, &newSpecLen, "tokenDescription="
, sizeof("tokenDescription=") - 1, tmp); } }; } else
1448 &newSpec, &newSpecLen,if (PL_strncasecmp(moduleSpec, "dbTokenDescription=", sizeof(
"dbTokenDescription=") - 1) == 0) { moduleSpec += sizeof("dbTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(
newSpecPtr, &newSpec, &newSpecLen, "tokenDescription="
, sizeof("tokenDescription=") - 1, tmp); } }; } else
1449 SECMOD_TOKEN_DESCRIPTION,if (PL_strncasecmp(moduleSpec, "dbTokenDescription=", sizeof(
"dbTokenDescription=") - 1) == 0) { moduleSpec += sizeof("dbTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(
newSpecPtr, &newSpec, &newSpecLen, "tokenDescription="
, sizeof("tokenDescription=") - 1, tmp); } }; } else
1450 sizeof(SECMOD_TOKEN_DESCRIPTION) - 1,if (PL_strncasecmp(moduleSpec, "dbTokenDescription=", sizeof(
"dbTokenDescription=") - 1) == 0) { moduleSpec += sizeof("dbTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(
newSpecPtr, &newSpec, &newSpecLen, "tokenDescription="
, sizeof("tokenDescription=") - 1, tmp); } }; } else
1451 tmp);if (PL_strncasecmp(moduleSpec, "dbTokenDescription=", sizeof(
"dbTokenDescription=") - 1) == 0) { moduleSpec += sizeof("dbTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(
newSpecPtr, &newSpec, &newSpecLen, "tokenDescription="
, sizeof("tokenDescription=") - 1, tmp); } }; } else
1452 }if (PL_strncasecmp(moduleSpec, "dbTokenDescription=", sizeof(
"dbTokenDescription=") - 1) == 0) { moduleSpec += sizeof("dbTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(
newSpecPtr, &newSpec, &newSpecLen, "tokenDescription="
, sizeof("tokenDescription=") - 1, tmp); } }; } else
1453 })if (PL_strncasecmp(moduleSpec, "dbTokenDescription=", sizeof(
"dbTokenDescription=") - 1) == 0) { moduleSpec += sizeof("dbTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(
newSpecPtr, &newSpec, &newSpecLen, "tokenDescription="
, sizeof("tokenDescription=") - 1, tmp); } }; } else
1454 NSSUTIL_HANDLE_STRING_ARG(if (PL_strncasecmp(moduleSpec, "dbSlotDescription=", sizeof("dbSlotDescription="
) - 1) == 0) { moduleSpec += sizeof("dbSlotDescription=") - 1
; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue(moduleSpec
, &next); moduleSpec += next; if (convert) { modulePrev =
moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1455 moduleSpec, tmp, "dbSlotDescription=",if (PL_strncasecmp(moduleSpec, "dbSlotDescription=", sizeof("dbSlotDescription="
) - 1) == 0) { moduleSpec += sizeof("dbSlotDescription=") - 1
; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue(moduleSpec
, &next); moduleSpec += next; if (convert) { modulePrev =
moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1456 if (convert) {if (PL_strncasecmp(moduleSpec, "dbSlotDescription=", sizeof("dbSlotDescription="
) - 1) == 0) { moduleSpec += sizeof("dbSlotDescription=") - 1
; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue(moduleSpec
, &next); moduleSpec += next; if (convert) { modulePrev =
moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1457 modulePrev = moduleSpec; /* skip copying */if (PL_strncasecmp(moduleSpec, "dbSlotDescription=", sizeof("dbSlotDescription="
) - 1) == 0) { moduleSpec += sizeof("dbSlotDescription=") - 1
; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue(moduleSpec
, &next); moduleSpec += next; if (convert) { modulePrev =
moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1458 if (!isFIPS) {if (PL_strncasecmp(moduleSpec, "dbSlotDescription=", sizeof("dbSlotDescription="
) - 1) == 0) { moduleSpec += sizeof("dbSlotDescription=") - 1
; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue(moduleSpec
, &next); moduleSpec += next; if (convert) { modulePrev =
moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1459 newSpecPtr = secmod_doDescCopy(newSpecPtr,if (PL_strncasecmp(moduleSpec, "dbSlotDescription=", sizeof("dbSlotDescription="
) - 1) == 0) { moduleSpec += sizeof("dbSlotDescription=") - 1
; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue(moduleSpec
, &next); moduleSpec += next; if (convert) { modulePrev =
moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1460 &newSpec, &newSpecLen,if (PL_strncasecmp(moduleSpec, "dbSlotDescription=", sizeof("dbSlotDescription="
) - 1) == 0) { moduleSpec += sizeof("dbSlotDescription=") - 1
; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue(moduleSpec
, &next); moduleSpec += next; if (convert) { modulePrev =
moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1461 SECMOD_SLOT_DESCRIPTION,if (PL_strncasecmp(moduleSpec, "dbSlotDescription=", sizeof("dbSlotDescription="
) - 1) == 0) { moduleSpec += sizeof("dbSlotDescription=") - 1
; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue(moduleSpec
, &next); moduleSpec += next; if (convert) { modulePrev =
moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1462 sizeof(SECMOD_SLOT_DESCRIPTION) - 1,if (PL_strncasecmp(moduleSpec, "dbSlotDescription=", sizeof("dbSlotDescription="
) - 1) == 0) { moduleSpec += sizeof("dbSlotDescription=") - 1
; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue(moduleSpec
, &next); moduleSpec += next; if (convert) { modulePrev =
moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1463 tmp);if (PL_strncasecmp(moduleSpec, "dbSlotDescription=", sizeof("dbSlotDescription="
) - 1) == 0) { moduleSpec += sizeof("dbSlotDescription=") - 1
; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue(moduleSpec
, &next); moduleSpec += next; if (convert) { modulePrev =
moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1464 }if (PL_strncasecmp(moduleSpec, "dbSlotDescription=", sizeof("dbSlotDescription="
) - 1) == 0) { moduleSpec += sizeof("dbSlotDescription=") - 1
; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue(moduleSpec
, &next); moduleSpec += next; if (convert) { modulePrev =
moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1465 })if (PL_strncasecmp(moduleSpec, "dbSlotDescription=", sizeof("dbSlotDescription="
) - 1) == 0) { moduleSpec += sizeof("dbSlotDescription=") - 1
; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue(moduleSpec
, &next); moduleSpec += next; if (convert) { modulePrev =
moduleSpec; if (!isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1466 NSSUTIL_HANDLE_STRING_ARG(if (PL_strncasecmp(moduleSpec, "FIPSTokenDescription=", sizeof
("FIPSTokenDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "tokenDescription=", sizeof(
"tokenDescription=") - 1, tmp); } }; } else
1467 moduleSpec, tmp, "FIPSTokenDescription=",if (PL_strncasecmp(moduleSpec, "FIPSTokenDescription=", sizeof
("FIPSTokenDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "tokenDescription=", sizeof(
"tokenDescription=") - 1, tmp); } }; } else
1468 if (convert) {if (PL_strncasecmp(moduleSpec, "FIPSTokenDescription=", sizeof
("FIPSTokenDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "tokenDescription=", sizeof(
"tokenDescription=") - 1, tmp); } }; } else
1469 modulePrev = moduleSpec; /* skip copying */if (PL_strncasecmp(moduleSpec, "FIPSTokenDescription=", sizeof
("FIPSTokenDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "tokenDescription=", sizeof(
"tokenDescription=") - 1, tmp); } }; } else
1470 if (isFIPS) {if (PL_strncasecmp(moduleSpec, "FIPSTokenDescription=", sizeof
("FIPSTokenDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "tokenDescription=", sizeof(
"tokenDescription=") - 1, tmp); } }; } else
1471 newSpecPtr = secmod_doDescCopy(newSpecPtr,if (PL_strncasecmp(moduleSpec, "FIPSTokenDescription=", sizeof
("FIPSTokenDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "tokenDescription=", sizeof(
"tokenDescription=") - 1, tmp); } }; } else
1472 &newSpec, &newSpecLen,if (PL_strncasecmp(moduleSpec, "FIPSTokenDescription=", sizeof
("FIPSTokenDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "tokenDescription=", sizeof(
"tokenDescription=") - 1, tmp); } }; } else
1473 SECMOD_TOKEN_DESCRIPTION,if (PL_strncasecmp(moduleSpec, "FIPSTokenDescription=", sizeof
("FIPSTokenDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "tokenDescription=", sizeof(
"tokenDescription=") - 1, tmp); } }; } else
1474 sizeof(SECMOD_TOKEN_DESCRIPTION) - 1,if (PL_strncasecmp(moduleSpec, "FIPSTokenDescription=", sizeof
("FIPSTokenDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "tokenDescription=", sizeof(
"tokenDescription=") - 1, tmp); } }; } else
1475 tmp);if (PL_strncasecmp(moduleSpec, "FIPSTokenDescription=", sizeof
("FIPSTokenDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "tokenDescription=", sizeof(
"tokenDescription=") - 1, tmp); } }; } else
1476 }if (PL_strncasecmp(moduleSpec, "FIPSTokenDescription=", sizeof
("FIPSTokenDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "tokenDescription=", sizeof(
"tokenDescription=") - 1, tmp); } }; } else
1477 })if (PL_strncasecmp(moduleSpec, "FIPSTokenDescription=", sizeof
("FIPSTokenDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSTokenDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "tokenDescription=", sizeof(
"tokenDescription=") - 1, tmp); } }; } else
1478 NSSUTIL_HANDLE_STRING_ARG(if (PL_strncasecmp(moduleSpec, "FIPSSlotDescription=", sizeof
("FIPSSlotDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSSlotDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1479 moduleSpec, tmp, "FIPSSlotDescription=",if (PL_strncasecmp(moduleSpec, "FIPSSlotDescription=", sizeof
("FIPSSlotDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSSlotDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1480 if (convert) {if (PL_strncasecmp(moduleSpec, "FIPSSlotDescription=", sizeof
("FIPSSlotDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSSlotDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1481 modulePrev = moduleSpec; /* skip copying */if (PL_strncasecmp(moduleSpec, "FIPSSlotDescription=", sizeof
("FIPSSlotDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSSlotDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1482 if (isFIPS) {if (PL_strncasecmp(moduleSpec, "FIPSSlotDescription=", sizeof
("FIPSSlotDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSSlotDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1483 newSpecPtr = secmod_doDescCopy(newSpecPtr,if (PL_strncasecmp(moduleSpec, "FIPSSlotDescription=", sizeof
("FIPSSlotDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSSlotDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1484 &newSpec, &newSpecLen,if (PL_strncasecmp(moduleSpec, "FIPSSlotDescription=", sizeof
("FIPSSlotDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSSlotDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1485 SECMOD_SLOT_DESCRIPTION,if (PL_strncasecmp(moduleSpec, "FIPSSlotDescription=", sizeof
("FIPSSlotDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSSlotDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1486 sizeof(SECMOD_SLOT_DESCRIPTION) - 1,if (PL_strncasecmp(moduleSpec, "FIPSSlotDescription=", sizeof
("FIPSSlotDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSSlotDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1487 tmp);if (PL_strncasecmp(moduleSpec, "FIPSSlotDescription=", sizeof
("FIPSSlotDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSSlotDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1488 }if (PL_strncasecmp(moduleSpec, "FIPSSlotDescription=", sizeof
("FIPSSlotDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSSlotDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1489 })if (PL_strncasecmp(moduleSpec, "FIPSSlotDescription=", sizeof
("FIPSSlotDescription=") - 1) == 0) { moduleSpec += sizeof("FIPSSlotDescription="
) - 1; if (tmp) PORT_Free_Util(tmp); tmp = NSSUTIL_ArgFetchValue
(moduleSpec, &next); moduleSpec += next; if (convert) { modulePrev
= moduleSpec; if (isFIPS) { newSpecPtr = secmod_doDescCopy(newSpecPtr
, &newSpec, &newSpecLen, "slotDescription=", sizeof("slotDescription="
) - 1, tmp); } }; } else
1490 NSSUTIL_HANDLE_FINAL_ARG(moduleSpec){ moduleSpec = NSSUTIL_ArgSkipParameter(moduleSpec); } moduleSpec
= NSSUTIL_ArgStrip(moduleSpec);
1491 SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec)if (moduleSpec > modulePrev) { int _cnt = moduleSpec - modulePrev
; memcpy(newSpecPtr, modulePrev, _cnt); newSpecPtr += _cnt; }
;
1492 }
1493 if (tmp) {
1494 PORT_FreePORT_Free_Util(tmp);
1495 tmp = NULL((void*)0);
1496 }
1497 *newSpecPtr = 0;
1498
1499 /* no target found, return the newSpec */
1500 if (target == NULL((void*)0)) {
1501 return newSpec;
1502 }
1503
1504 /* now build the child array from target */
1505 /*first count them */
1506 for (tokenIndex = NSSUTIL_ArgStrip(target); *tokenIndex;
1507 tokenIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(tokenIndex))) {
1508 tokenCount++;
1509 }
1510
1511 childArray = PORT_NewArray(char *, tokenCount + 1)(char * *)PORT_Alloc_Util(sizeof(char *) * (tokenCount + 1));
1512 if (childArray == NULL((void*)0)) {
1513 /* just return the spec as is then */
1514 PORT_FreePORT_Free_Util(target);
1515 return newSpec;
1516 }
1517 if (ids) {
1518 idArray = PORT_NewArray(CK_SLOT_ID, tokenCount + 1)(CK_SLOT_ID *)PORT_Alloc_Util(sizeof(CK_SLOT_ID) * (tokenCount
+ 1))
;
1519 if (idArray == NULL((void*)0)) {
1520 PORT_FreePORT_Free_Util(childArray);
1521 PORT_FreePORT_Free_Util(target);
1522 return newSpec;
1523 }
1524 }
1525
1526 /* now fill them in */
1527 for (tokenIndex = NSSUTIL_ArgStrip(target), i = 0;
1528 *tokenIndex && (i < tokenCount);
1529 tokenIndex = NSSUTIL_ArgStrip(tokenIndex)) {
1530 int next;
1531 char *name = NSSUTIL_ArgGetLabel(tokenIndex, &next);
1532 tokenIndex += next;
1533
1534 if (idArray) {
1535 idArray[i] = NSSUTIL_ArgDecodeNumber(name);
1536 }
1537
1538 PORT_FreePORT_Free_Util(name); /* drop the explicit number */
1539
1540 /* if anything is left, copy the args to the child array */
1541 if (!NSSUTIL_ArgIsBlank(*tokenIndex)) {
1542 childArray[i++] = NSSUTIL_ArgFetchValue(tokenIndex, &next);
1543 tokenIndex += next;
1544 }
1545 }
1546
1547 PORT_FreePORT_Free_Util(target);
1548 childArray[i] = 0;
1549 if (idArray) {
1550 idArray[i] = 0;
1551 }
1552
1553 /* return it */
1554 *children = childArray;
1555 if (ids) {
1556 *ids = idArray;
1557 }
1558 return newSpec;
1559}
1560
1561/* get the database and flags from the spec */
1562static char *
1563secmod_getConfigDir(const char *spec, char **certPrefix, char **keyPrefix,
1564 PRBool *readOnly)
1565{
1566 char *config = NULL((void*)0);
1567
1568 *certPrefix = NULL((void*)0);
1569 *keyPrefix = NULL((void*)0);
1570 *readOnly = NSSUTIL_ArgHasFlag("flags", "readOnly", spec);
1571 if (NSSUTIL_ArgHasFlag("flags", "nocertdb", spec) ||
1572 NSSUTIL_ArgHasFlag("flags", "nokeydb", spec)) {
1573 return NULL((void*)0);
1574 }
1575
1576 spec = NSSUTIL_ArgStrip(spec);
1577 while (*spec) {
1578 int next;
1579 NSSUTIL_HANDLE_STRING_ARG(spec, config, "configdir=", ;)if (PL_strncasecmp(spec, "configdir=", sizeof("configdir=") -
1) == 0) { spec += sizeof("configdir=") - 1; if (config) PORT_Free_Util
(config); config = NSSUTIL_ArgFetchValue(spec, &next); spec
+= next; ;; } else
1580 NSSUTIL_HANDLE_STRING_ARG(spec, *certPrefix, "certPrefix=", ;)if (PL_strncasecmp(spec, "certPrefix=", sizeof("certPrefix=")
- 1) == 0) { spec += sizeof("certPrefix=") - 1; if (*certPrefix
) PORT_Free_Util(*certPrefix); *certPrefix = NSSUTIL_ArgFetchValue
(spec, &next); spec += next; ;; } else
1581 NSSUTIL_HANDLE_STRING_ARG(spec, *keyPrefix, "keyPrefix=", ;)if (PL_strncasecmp(spec, "keyPrefix=", sizeof("keyPrefix=") -
1) == 0) { spec += sizeof("keyPrefix=") - 1; if (*keyPrefix)
PORT_Free_Util(*keyPrefix); *keyPrefix = NSSUTIL_ArgFetchValue
(spec, &next); spec += next; ;; } else
1582 NSSUTIL_HANDLE_FINAL_ARG(spec){ spec = NSSUTIL_ArgSkipParameter(spec); } spec = NSSUTIL_ArgStrip
(spec);
1583 }
1584 return config;
1585}
1586
1587struct SECMODConfigListStr {
1588 char *config;
1589 char *certPrefix;
1590 char *keyPrefix;
1591 PRBool isReadOnly;
1592};
1593
1594/*
1595 * return an array of already openned databases from a spec list.
1596 */
1597SECMODConfigList *
1598secmod_GetConfigList(PRBool isFIPS, char *spec, int *count)
1599{
1600 char **children;
1601 CK_SLOT_ID *ids;
1602 char *strippedSpec;
1603 int childCount;
1604 SECMODConfigList *conflist = NULL((void*)0);
1605 int i;
1606
1607 strippedSpec = secmod_ParseModuleSpecForTokens(PR_TRUE1, isFIPS,
1608 spec, &children, &ids);
1609 if (strippedSpec == NULL((void*)0)) {
1610 return NULL((void*)0);
1611 }
1612
1613 for (childCount = 0; children && children[childCount]; childCount++)
1614 ;
1615 *count = childCount + 1; /* include strippedSpec */
1616 conflist = PORT_NewArray(SECMODConfigList, *count)(SECMODConfigList *)PORT_Alloc_Util(sizeof(SECMODConfigList) *
(*count))
;
1617 if (conflist == NULL((void*)0)) {
1618 *count = 0;
1619 goto loser;
1620 }
1621
1622 conflist[0].config = secmod_getConfigDir(strippedSpec,
1623 &conflist[0].certPrefix,
1624 &conflist[0].keyPrefix,
1625 &conflist[0].isReadOnly);
1626 for (i = 0; i < childCount; i++) {
1627 conflist[i + 1].config = secmod_getConfigDir(children[i],
1628 &conflist[i + 1].certPrefix,
1629 &conflist[i + 1].keyPrefix,
1630 &conflist[i + 1].isReadOnly);
1631 }
1632
1633loser:
1634 secmod_FreeChildren(children, ids);
1635 PORT_FreePORT_Free_Util(strippedSpec);
1636 return conflist;
1637}
1638
1639/*
1640 * determine if we are trying to open an old dbm database. For this test
1641 * RDB databases should return PR_FALSE.
1642 */
1643static PRBool
1644secmod_configIsDBM(char *configDir)
1645{
1646 char *env;
1647
1648 /* explicit dbm open */
1649 if (strncmp(configDir, "dbm:", 4) == 0) {
1650 return PR_TRUE1;
1651 }
1652 /* explicit open of a non-dbm database */
1653 if ((strncmp(configDir, "sql:", 4) == 0) ||
1654 (strncmp(configDir, "rdb:", 4) == 0) ||
1655 (strncmp(configDir, "extern:", 7) == 0)) {
1656 return PR_FALSE0;
1657 }
1658 env = PR_GetEnvSecure("NSS_DEFAULT_DB_TYPE");
1659 /* implicit dbm open */
1660 if ((env == NULL((void*)0)) || (strcmp(env, "dbm") == 0)) {
1661 return PR_TRUE1;
1662 }
1663 /* implicit non-dbm open */
1664 return PR_FALSE0;
1665}
1666
1667/*
1668 * match two prefixes. prefix may be NULL. NULL patches '\0'
1669 */
1670static PRBool
1671secmod_matchPrefix(char *prefix1, char *prefix2)
1672{
1673 if ((prefix1 == NULL((void*)0)) || (*prefix1 == 0)) {
1674 if ((prefix2 == NULL((void*)0)) || (*prefix2 == 0)) {
1675 return PR_TRUE1;
1676 }
1677 return PR_FALSE0;
1678 }
1679 if (strcmp(prefix1, prefix2) == 0) {
1680 return PR_TRUE1;
1681 }
1682 return PR_FALSE0;
1683}
1684
1685/* do two config paramters match? Not all callers are compariing
1686 * SECMODConfigLists directly, so this function breaks them out to their
1687 * components. */
1688static PRBool
1689secmod_matchConfig(char *configDir1, char *configDir2,
1690 char *certPrefix1, char *certPrefix2,
1691 char *keyPrefix1, char *keyPrefix2,
1692 PRBool isReadOnly1, PRBool isReadOnly2)
1693{
1694 /* TODO: Document the answer to the question:
1695 * "Why not allow them to match if they are both NULL?"
1696 * See: https://bugzilla.mozilla.org/show_bug.cgi?id=1318633#c1
1697 */
1698 if ((configDir1 == NULL((void*)0)) || (configDir2 == NULL((void*)0))) {
1699 return PR_FALSE0;
1700 }
1701 if (strcmp(configDir1, configDir2) != 0) {
1702 return PR_FALSE0;
1703 }
1704 if (!secmod_matchPrefix(certPrefix1, certPrefix2)) {
1705 return PR_FALSE0;
1706 }
1707 if (!secmod_matchPrefix(keyPrefix1, keyPrefix2)) {
1708 return PR_FALSE0;
1709 }
1710 /* these last test -- if we just need the DB open read only,
1711 * than any open will suffice, but if we requested it read/write
1712 * and it's only open read only, we need to open it again */
1713 if (isReadOnly1) {
1714 return PR_TRUE1;
1715 }
1716 if (isReadOnly2) { /* isReadonly1 == PR_FALSE */
1717 return PR_FALSE0;
1718 }
1719 return PR_TRUE1;
1720}
1721
1722/*
1723 * return true if we are requesting a database that is already openned.
1724 */
1725PRBool
1726secmod_MatchConfigList(const char *spec, SECMODConfigList *conflist, int count)
1727{
1728 char *config;
1729 char *certPrefix;
1730 char *keyPrefix;
1731 PRBool isReadOnly;
1732 PRBool ret = PR_FALSE0;
1733 int i;
1734
1735 config = secmod_getConfigDir(spec, &certPrefix, &keyPrefix, &isReadOnly);
1736 if (!config) {
1737 goto done;
1738 }
1739
1740 /* NOTE: we dbm isn't multiple open safe. If we open the same database
1741 * twice from two different locations, then we can corrupt our database
1742 * (the cache will be inconsistent). Protect against this by claiming
1743 * for comparison only that we are always openning dbm databases read only.
1744 */
1745 if (secmod_configIsDBM(config)) {
1746 isReadOnly = 1;
1747 }
1748 for (i = 0; i < count; i++) {
1749 if (secmod_matchConfig(config, conflist[i].config, certPrefix,
1750 conflist[i].certPrefix, keyPrefix,
1751 conflist[i].keyPrefix, isReadOnly,
1752 conflist[i].isReadOnly)) {
1753 ret = PR_TRUE1;
1754 goto done;
1755 }
1756 }
1757
1758 ret = PR_FALSE0;
1759done:
1760 PORT_FreePORT_Free_Util(config);
1761 PORT_FreePORT_Free_Util(certPrefix);
1762 PORT_FreePORT_Free_Util(keyPrefix);
1763 return ret;
1764}
1765
1766/*
1767 * Find the slot id from the module spec. If the slot is the database slot, we
1768 * can get the slot id from the default database slot.
1769 */
1770CK_SLOT_ID
1771secmod_GetSlotIDFromModuleSpec(const char *moduleSpec, SECMODModule *module)
1772{
1773 char *tmp_spec = NULL((void*)0);
1774 char **children, **thisChild;
1775 CK_SLOT_ID *ids, *thisID, slotID = -1;
1776 char *inConfig = NULL((void*)0), *thisConfig = NULL((void*)0);
1777 char *inCertPrefix = NULL((void*)0), *thisCertPrefix = NULL((void*)0);
1778 char *inKeyPrefix = NULL((void*)0), *thisKeyPrefix = NULL((void*)0);
1779 PRBool inReadOnly, thisReadOnly;
1780
1781 inConfig = secmod_getConfigDir(moduleSpec, &inCertPrefix, &inKeyPrefix,
1782 &inReadOnly);
1783 if (!inConfig) {
1784 goto done;
1785 }
1786
1787 if (secmod_configIsDBM(inConfig)) {
1788 inReadOnly = 1;
1789 }
1790
1791 tmp_spec = secmod_ParseModuleSpecForTokens(PR_TRUE1, module->isFIPS,
1792 module->libraryParams, &children, &ids);
1793 if (tmp_spec == NULL((void*)0)) {
1794 goto done;
1795 }
1796
1797 /* first check to see if the parent is the database */
1798 thisConfig = secmod_getConfigDir(tmp_spec, &thisCertPrefix, &thisKeyPrefix,
1799 &thisReadOnly);
1800 if (!thisConfig) {
1801 goto done;
1802 }
1803 if (secmod_matchConfig(inConfig, thisConfig, inCertPrefix, thisCertPrefix,
1804 inKeyPrefix, thisKeyPrefix, inReadOnly, thisReadOnly)) {
1805 /* yup it's the default key slot, get the id for it */
1806 PK11SlotInfo *slot = PK11_GetInternalKeySlot();
1807 if (slot) {
1808 slotID = slot->slotID;
1809 PK11_FreeSlot(slot);
1810 }
1811 goto done;
1812 }
1813
1814 /* find id of the token */
1815 for (thisChild = children, thisID = ids; thisChild && *thisChild; thisChild++, thisID++) {
1816 PORT_FreePORT_Free_Util(thisConfig);
1817 PORT_FreePORT_Free_Util(thisCertPrefix);
1818 PORT_FreePORT_Free_Util(thisKeyPrefix);
1819 thisConfig = secmod_getConfigDir(*thisChild, &thisCertPrefix,
1820 &thisKeyPrefix, &thisReadOnly);
1821 if (thisConfig == NULL((void*)0)) {
1822 continue;
1823 }
1824 if (secmod_matchConfig(inConfig, thisConfig, inCertPrefix, thisCertPrefix,
1825 inKeyPrefix, thisKeyPrefix, inReadOnly, thisReadOnly)) {
1826 slotID = *thisID;
1827 break;
1828 }
1829 }
1830
1831done:
1832 PORT_FreePORT_Free_Util(inConfig);
1833 PORT_FreePORT_Free_Util(inCertPrefix);
1834 PORT_FreePORT_Free_Util(inKeyPrefix);
1835 PORT_FreePORT_Free_Util(thisConfig);
1836 PORT_FreePORT_Free_Util(thisCertPrefix);
1837 PORT_FreePORT_Free_Util(thisKeyPrefix);
1838 if (tmp_spec) {
1839 secmod_FreeChildren(children, ids);
1840 PORT_FreePORT_Free_Util(tmp_spec);
1841 }
1842 return slotID;
1843}
1844
1845void
1846secmod_FreeConfigList(SECMODConfigList *conflist, int count)
1847{
1848 int i;
1849 for (i = 0; i < count; i++) {
1850 PORT_FreePORT_Free_Util(conflist[i].config);
1851 PORT_FreePORT_Free_Util(conflist[i].certPrefix);
1852 PORT_FreePORT_Free_Util(conflist[i].keyPrefix);
1853 }
1854 PORT_FreePORT_Free_Util(conflist);
1855}
1856
1857void
1858secmod_FreeChildren(char **children, CK_SLOT_ID *ids)
1859{
1860 char **thisChild;
1861
1862 if (!children) {
1863 return;
1864 }
1865
1866 for (thisChild = children; thisChild && *thisChild; thisChild++) {
1867 PORT_FreePORT_Free_Util(*thisChild);
1868 }
1869 PORT_FreePORT_Free_Util(children);
1870 if (ids) {
1871 PORT_FreePORT_Free_Util(ids);
1872 }
1873 return;
1874}
1875
1876/*
1877 * caclulate the length of each child record:
1878 * " 0x{id}=<{escaped_child}>"
1879 */
1880static int
1881secmod_getChildLength(char *child, CK_SLOT_ID id)
1882{
1883 int length = NSSUTIL_DoubleEscapeSize(child, '>', ']');
1884 if (id == 0) {
1885 length++;
1886 }
1887 while (id) {
1888 length++;
1889 id = id >> 4;
1890 }
1891 length += 6; /* {sp}0x[id]=<{child}> */
1892 return length;
1893}
1894
1895/*
1896 * Build a child record:
1897 * " 0x{id}=<{escaped_child}>"
1898 */
1899static SECStatus
1900secmod_mkTokenChild(char **next, int *length, char *child, CK_SLOT_ID id)
1901{
1902 int len;
1903 char *escSpec;
1904
1905 len = PR_snprintf(*next, *length, " 0x%x=<", id);
1906 if (len < 0) {
1907 return SECFailure;
1908 }
1909 *next += len;
1910 *length -= len;
1911 escSpec = NSSUTIL_DoubleEscape(child, '>', ']');
1912 if (escSpec == NULL((void*)0)) {
1913 return SECFailure;
1914 }
1915 if (*child && (*escSpec == 0)) {
1916 PORT_FreePORT_Free_Util(escSpec);
1917 return SECFailure;
1918 }
1919 len = strlen(escSpec);
1920 if (len + 1 > *length) {
1921 PORT_FreePORT_Free_Util(escSpec);
1922 return SECFailure;
1923 }
1924 PORT_Memcpymemcpy(*next, escSpec, len);
1925 *next += len;
1926 *length -= len;
1927 PORT_FreePORT_Free_Util(escSpec);
1928 **next = '>';
1929 (*next)++;
1930 (*length)--;
1931 return SECSuccess;
1932}
1933
1934#define TOKEN_STRING" tokens=[" " tokens=["
1935
1936char *
1937secmod_MkAppendTokensList(PLArenaPool *arena, char *oldParam, char *newToken,
1938 CK_SLOT_ID newID, char **children, CK_SLOT_ID *ids)
1939{
1940 char *rawParam = NULL((void*)0); /* oldParam with tokens stripped off */
1941 char *newParam = NULL((void*)0); /* space for the return parameter */
1942 char *nextParam = NULL((void*)0); /* current end of the new parameter */
1943 char **oldChildren = NULL((void*)0);
1944 CK_SLOT_ID *oldIds = NULL((void*)0);
1945 void *mark = NULL((void*)0); /* mark the arena pool in case we need
1946 * to release it */
1947 int length, i, tmpLen;
1948 SECStatus rv;
1949
1950 /* first strip out and save the old tokenlist */
1951 rawParam = secmod_ParseModuleSpecForTokens(PR_FALSE0, PR_FALSE0,
1952 oldParam, &oldChildren, &oldIds);
1953 if (!rawParam) {
1954 goto loser;
1955 }
1956
1957 /* now calculate the total length of the new buffer */
1958 /* First the 'fixed stuff', length of rawparam (does not include a NULL),
1959 * length of the token string (does include the NULL), closing bracket */
1960 length = strlen(rawParam) + sizeof(TOKEN_STRING" tokens=[") + 1;
1961 /* now add then length of all the old children */
1962 for (i = 0; oldChildren && oldChildren[i]; i++) {
1963 length += secmod_getChildLength(oldChildren[i], oldIds[i]);
1964 }
1965
1966 /* add the new token */
1967 length += secmod_getChildLength(newToken, newID);
1968
1969 /* and it's new children */
1970 for (i = 0; children && children[i]; i++) {
1971 if (ids[i] == -1) {
1972 continue;
1973 }
1974 length += secmod_getChildLength(children[i], ids[i]);
1975 }
1976
1977 /* now allocate and build the string */
1978 mark = PORT_ArenaMarkPORT_ArenaMark_Util(arena);
1979 if (!mark) {
1980 goto loser;
1981 }
1982 newParam = PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, length);
1983 if (!newParam) {
1984 goto loser;
1985 }
1986
1987 PORT_Strcpystrcpy(newParam, rawParam);
1988 tmpLen = strlen(rawParam);
1989 nextParam = newParam + tmpLen;
1990 length -= tmpLen;
1991 PORT_Memcpymemcpy(nextParam, TOKEN_STRING" tokens=[", sizeof(TOKEN_STRING" tokens=[") - 1);
1992 nextParam += sizeof(TOKEN_STRING" tokens=[") - 1;
1993 length -= sizeof(TOKEN_STRING" tokens=[") - 1;
1994
1995 for (i = 0; oldChildren && oldChildren[i]; i++) {
1996 rv = secmod_mkTokenChild(&nextParam, &length, oldChildren[i], oldIds[i]);
1997 if (rv != SECSuccess) {
1998 goto loser;
1999 }
2000 }
2001
2002 rv = secmod_mkTokenChild(&nextParam, &length, newToken, newID);
2003 if (rv != SECSuccess) {
2004 goto loser;
2005 }
2006
2007 for (i = 0; children && children[i]; i++) {
2008 if (ids[i] == -1) {
2009 continue;
2010 }
2011 rv = secmod_mkTokenChild(&nextParam, &length, children[i], ids[i]);
2012 if (rv != SECSuccess) {
2013 goto loser;
2014 }
2015 }
2016
2017 if (length < 2) {
2018 goto loser;
2019 }
2020
2021 *nextParam++ = ']';
2022 *nextParam++ = 0;
2023
2024 /* we are going to return newParam now, don't release the mark */
2025 PORT_ArenaUnmarkPORT_ArenaUnmark_Util(arena, mark);
2026 mark = NULL((void*)0);
2027
2028loser:
2029 if (mark) {
2030 PORT_ArenaReleasePORT_ArenaRelease_Util(arena, mark);
2031 newParam = NULL((void*)0); /* if the mark is still active,
2032 * don't return the param */
2033 }
2034 if (rawParam) {
2035 PORT_FreePORT_Free_Util(rawParam);
2036 }
2037 if (oldChildren) {
2038 secmod_FreeChildren(oldChildren, oldIds);
2039 }
2040 return newParam;
2041}
2042
2043static char *
2044secmod_mkModuleSpec(SECMODModule *module)
2045{
2046 char *nss = NULL((void*)0), *modSpec = NULL((void*)0), **slotStrings = NULL((void*)0);
2047 int slotCount, i, si;
2048 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
2049
2050 /* allocate target slot info strings */
2051 slotCount = 0;
2052
2053 SECMOD_GetReadLock(moduleLock);
2054 if (module->slotCount) {
2055 for (i = 0; i < module->slotCount; i++) {
2056 if (module->slots[i]->defaultFlags != 0) {
2057 slotCount++;
2058 }
2059 }
2060 } else {
2061 slotCount = module->slotInfoCount;
2062 }
2063
2064 slotStrings = (char **)PORT_ZAllocPORT_ZAlloc_Util(slotCount * sizeof(char *));
2065 if (slotStrings == NULL((void*)0)) {
2066 SECMOD_ReleaseReadLock(moduleLock);
2067 goto loser;
2068 }
2069
2070 /* build the slot info strings */
2071 if (module->slotCount) {
2072 for (i = 0, si = 0; i < module->slotCount; i++) {
2073 if (module->slots[i]->defaultFlags) {
2074 PORT_Assert(si < slotCount)((si < slotCount) ? ((void)0) : PR_Assert("si < slotCount"
, "/root/firefox-clang/security/nss/lib/pk11wrap/pk11pars.c",
2074))
;
2075 if (si >= slotCount)
2076 break;
2077 slotStrings[si] = NSSUTIL_MkSlotString(module->slots[i]->slotID,
2078 module->slots[i]->defaultFlags,
2079 module->slots[i]->timeout,
2080 module->slots[i]->askpw,
2081 module->slots[i]->hasRootCerts,
2082 module->slots[i]->hasRootTrust);
2083 si++;
2084 }
2085 }
2086 } else {
2087 for (i = 0; i < slotCount; i++) {
2088 slotStrings[i] = NSSUTIL_MkSlotString(
2089 module->slotInfo[i].slotID,
2090 module->slotInfo[i].defaultFlags,
2091 module->slotInfo[i].timeout,
2092 module->slotInfo[i].askpw,
2093 module->slotInfo[i].hasRootCerts,
2094 module->slotInfo[i].hasRootTrust);
2095 }
2096 }
2097
2098 SECMOD_ReleaseReadLock(moduleLock);
2099 nss = NSSUTIL_MkNSSString(slotStrings, slotCount, module->internal,
2100 module->isFIPS, module->isModuleDB,
2101 module->moduleDBOnly, module->isCritical,
2102 module->trustOrder, module->cipherOrder,
2103 module->ssl[0], module->ssl[1]);
2104 modSpec = NSSUTIL_MkModuleSpec(module->dllName, module->commonName,
2105 module->libraryParams, nss);
2106 PORT_FreePORT_Free_Util(slotStrings);
2107 PR_smprintf_free(nss);
2108loser:
2109 return (modSpec);
2110}
2111
2112char **
2113SECMOD_GetModuleSpecList(SECMODModule *module)
2114{
2115 SECMODModuleDBFunc func = (SECMODModuleDBFunc)module->moduleDBFunc;
2116 if (func) {
2117 return (*func)(SECMOD_MODULE_DB_FUNCTION_FIND0,
2118 module->libraryParams, NULL((void*)0));
2119 }
2120 return NULL((void*)0);
2121}
2122
2123SECStatus
2124SECMOD_AddPermDB(SECMODModule *module)
2125{
2126 SECMODModuleDBFunc func;
2127 char *moduleSpec;
2128 char **retString;
2129
2130 if (module->parent == NULL((void*)0))
2131 return SECFailure;
2132
2133 func = (SECMODModuleDBFunc)module->parent->moduleDBFunc;
2134 if (func) {
2135 moduleSpec = secmod_mkModuleSpec(module);
2136 retString = (*func)(SECMOD_MODULE_DB_FUNCTION_ADD1,
2137 module->parent->libraryParams, moduleSpec);
2138 PORT_FreePORT_Free_Util(moduleSpec);
2139 if (retString != NULL((void*)0))
2140 return SECSuccess;
2141 }
2142 return SECFailure;
2143}
2144
2145SECStatus
2146SECMOD_DeletePermDB(SECMODModule *module)
2147{
2148 SECMODModuleDBFunc func;
2149 char *moduleSpec;
2150 char **retString;
2151
2152 if (module->parent == NULL((void*)0))
2153 return SECFailure;
2154
2155 func = (SECMODModuleDBFunc)module->parent->moduleDBFunc;
2156 if (func) {
2157 moduleSpec = secmod_mkModuleSpec(module);
2158 retString = (*func)(SECMOD_MODULE_DB_FUNCTION_DEL2,
2159 module->parent->libraryParams, moduleSpec);
2160 PORT_FreePORT_Free_Util(moduleSpec);
2161 if (retString != NULL((void*)0))
2162 return SECSuccess;
2163 }
2164 return SECFailure;
2165}
2166
2167SECStatus
2168SECMOD_FreeModuleSpecList(SECMODModule *module, char **moduleSpecList)
2169{
2170 SECMODModuleDBFunc func = (SECMODModuleDBFunc)module->moduleDBFunc;
2171 char **retString;
2172 if (func) {
2173 retString = (*func)(SECMOD_MODULE_DB_FUNCTION_RELEASE3,
2174 module->libraryParams, moduleSpecList);
2175 if (retString != NULL((void*)0))
2176 return SECSuccess;
2177 }
2178 return SECFailure;
2179}
2180
2181/*
2182 * load a PKCS#11 module but do not add it to the default NSS trust domain
2183 */
2184SECMODModule *
2185SECMOD_LoadModule(char *modulespec, SECMODModule *parent, PRBool recurse)
2186{
2187 char *library = NULL((void*)0), *moduleName = NULL((void*)0), *parameters = NULL((void*)0), *nss = NULL((void*)0);
2188 char *config = NULL((void*)0);
2189 SECStatus status;
2190 SECMODModule *module = NULL((void*)0);
2191 SECMODModule *oldModule = NULL((void*)0);
2192 SECStatus rv;
2193 PRBool forwardPolicyFeedback = PR_FALSE0;
2194 PRUint32 forwardPolicyCheckFlags;
2195
2196 /* initialize the underlying module structures */
2197 SECMOD_Init();
2198
2199 status = NSSUTIL_ArgParseModuleSpecEx(modulespec, &library, &moduleName,
2200 &parameters, &nss,
2201 &config);
2202 if (status != SECSuccess) {
2203 goto loser;
2204 }
2205
2206 module = SECMOD_CreateModuleEx(library, moduleName, parameters, nss, config);
2207 forwardPolicyFeedback = NSSUTIL_ArgHasFlag("flags", "printPolicyFeedback", nss);
2208 forwardPolicyCheckFlags = secmod_parsePolicyCheckFlags(nss);
2209
2210 if (library)
2211 PORT_FreePORT_Free_Util(library);
2212 if (moduleName)
2213 PORT_FreePORT_Free_Util(moduleName);
2214 if (parameters)
2215 PORT_FreePORT_Free_Util(parameters);
2216 if (nss)
2217 PORT_FreePORT_Free_Util(nss);
2218 if (config)
2219 PORT_FreePORT_Free_Util(config);
2220 if (!module) {
2221 goto loser;
2222 }
2223
2224 /* a policy only stanza doesn't actually get 'loaded'. policy has already
2225 * been parsed as a side effect of the CreateModuleEx call */
2226 if (secmod_PolicyOnly(module)) {
2227 return module;
2228 }
2229 if (parent) {
2230 module->parent = SECMOD_ReferenceModule(parent);
2231 if (module->internal && secmod_IsInternalKeySlot(parent)) {
2232 module->internal = parent->internal;
2233 }
2234 }
2235
2236 /* load it */
2237 rv = secmod_LoadPKCS11Module(module, &oldModule);
2238 if (rv != SECSuccess) {
2239 goto loser;
2240 }
2241
2242 /* if we just reload an old module, no need to add it to any lists.
2243 * we simple release all our references */
2244 if (oldModule) {
2245 /* This module already exists, don't link it anywhere. This
2246 * will probably destroy this module */
2247 SECMOD_DestroyModule(module);
2248 return oldModule;
2249 }
2250
2251 if (recurse && module->isModuleDB) {
2252 char **moduleSpecList;
2253 PORT_SetErrorPORT_SetError_Util(0);
2254
2255 moduleSpecList = SECMOD_GetModuleSpecList(module);
2256 if (moduleSpecList) {
2257 char **index;
2258
2259 index = moduleSpecList;
2260 if (*index && SECMOD_GetSkipFirstFlag(module)) {
2261 index++;
2262 }
2263
2264 for (; *index; index++) {
2265 SECMODModule *child;
2266 if (0 == PORT_Strcmpstrcmp(*index, modulespec)) {
2267 /* avoid trivial infinite recursion */
2268 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_NO_MODULE);
2269 rv = SECFailure;
2270 break;
2271 }
2272 if (!forwardPolicyFeedback) {
2273 child = SECMOD_LoadModule(*index, module, PR_TRUE1);
2274 } else {
2275 /* Add printPolicyFeedback to the nss flags */
2276 char *specWithForwards =
2277 NSSUTIL_AddNSSFlagToModuleSpec(*index, "printPolicyFeedback");
2278 char *tmp;
2279 if (forwardPolicyCheckFlags & SECMOD_FLAG_POLICY_CHECK_IDENTIFIER0x01) {
2280 tmp = NSSUTIL_AddNSSFlagToModuleSpec(specWithForwards, "policyCheckIdentifier");
2281 PORT_FreePORT_Free_Util(specWithForwards);
2282 specWithForwards = tmp;
2283 }
2284 if (forwardPolicyCheckFlags & SECMOD_FLAG_POLICY_CHECK_VALUE0x02) {
2285 tmp = NSSUTIL_AddNSSFlagToModuleSpec(specWithForwards, "policyCheckValue");
2286 PORT_FreePORT_Free_Util(specWithForwards);
2287 specWithForwards = tmp;
2288 }
2289 child = SECMOD_LoadModule(specWithForwards, module, PR_TRUE1);
2290 PORT_FreePORT_Free_Util(specWithForwards);
2291 }
2292 if (!child)
2293 break;
2294 if (child->isCritical && !child->loaded) {
2295 int err = PORT_GetErrorPORT_GetError_Util();
2296 if (!err)
2297 err = SEC_ERROR_NO_MODULE;
2298 SECMOD_DestroyModule(child);
2299 PORT_SetErrorPORT_SetError_Util(err);
2300 rv = SECFailure;
2301 break;
2302 }
2303 SECMOD_DestroyModule(child);
2304 }
2305 SECMOD_FreeModuleSpecList(module, moduleSpecList);
2306 } else {
2307 if (!PORT_GetErrorPORT_GetError_Util())
2308 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_NO_MODULE);
2309 rv = SECFailure;
2310 }
2311 }
2312
2313 if (rv != SECSuccess) {
2314 goto loser;
2315 }
2316
2317 /* inherit the reference */
2318 if (!module->moduleDBOnly) {
2319 SECMOD_AddModuleToList(module);
2320 } else {
2321 SECMOD_AddModuleToDBOnlyList(module);
2322 }
2323
2324 /* handle any additional work here */
2325 return module;
2326
2327loser:
2328 if (module) {
2329 if (module->loaded) {
2330 SECMOD_UnloadModule(module);
2331 }
2332 SECMOD_AddModuleToUnloadList(module);
2333 }
2334 return module;
2335}
2336
2337SECMODModule *
2338SECMOD_LoadModuleWithFunction(const char *moduleName, CK_C_GetFunctionList fentry)
2339{
2340 SECMODModule *module = NULL((void*)0);
2341 SECMODModule *oldModule = NULL((void*)0);
2342 SECStatus rv;
2343
2344 /* initialize the underlying module structures */
2345 SECMOD_Init();
2346
2347 module = secmod_NewModule();
2348 if (module == NULL((void*)0)) {
2349 goto loser;
2350 }
2351
2352 module->commonName = PORT_ArenaStrdupPORT_ArenaStrdup_Util(module->arena, moduleName ? moduleName : "");
2353 module->internal = PR_FALSE0;
2354 module->isFIPS = PR_FALSE0;
2355 /* if the system FIPS mode is enabled, force FIPS to be on */
2356 if (SECMOD_GetSystemFIPSEnabled()) {
2357 module->isFIPS = PR_TRUE1;
2358 }
2359
2360 module->isCritical = PR_FALSE0;
2361 /* new field */
2362 module->trustOrder = NSSUTIL_DEFAULT_TRUST_ORDER50;
2363 /* new field */
2364 module->cipherOrder = NSSUTIL_DEFAULT_CIPHER_ORDER0;
2365 /* new field */
2366 module->isModuleDB = PR_FALSE0;
2367 module->moduleDBOnly = PR_FALSE0;
2368
2369 module->ssl[0] = 0;
2370 module->ssl[1] = 0;
2371
2372 secmod_PrivateModuleCount++;
2373
2374 /* load it */
2375 rv = secmod_LoadPKCS11ModuleFromFunction(module, &oldModule, fentry);
2376 if (rv != SECSuccess) {
2377 goto loser;
2378 }
2379
2380 /* if we just reload an old module, no need to add it to any lists.
2381 * we simple release all our references */
2382 if (oldModule) {
2383 /* This module already exists, don't link it anywhere. This
2384 * will probably destroy this module */
2385 SECMOD_DestroyModule(module);
2386 return oldModule;
2387 }
2388
2389 SECMOD_AddModuleToList(module);
2390 /* handle any additional work here */
2391 return module;
2392
2393loser:
2394 if (module) {
2395 if (module->loaded) {
2396 SECMOD_UnloadModule(module);
2397 }
2398 SECMOD_AddModuleToUnloadList(module);
2399 }
2400 return module;
2401}
2402
2403/*
2404 * load a PKCS#11 module and add it to the default NSS trust domain
2405 */
2406SECMODModule *
2407SECMOD_LoadUserModule(char *modulespec, SECMODModule *parent, PRBool recurse)
2408{
2409 SECStatus rv = SECSuccess;
2410 SECMODModule *newmod = SECMOD_LoadModule(modulespec, parent, recurse);
2411 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
2412
2413 if (newmod) {
2414 SECMOD_GetReadLock(moduleLock);
2415 rv = STAN_AddModuleToDefaultTrustDomain(newmod);
2416 SECMOD_ReleaseReadLock(moduleLock);
2417 if (SECSuccess != rv) {
2418 SECMOD_DestroyModule(newmod);
2419 return NULL((void*)0);
2420 }
2421 }
2422 return newmod;
2423}
2424
2425SECMODModule *
2426SECMOD_LoadUserModuleWithFunction(const char *moduleName, CK_C_GetFunctionList fentry)
2427{
2428 SECStatus rv = SECSuccess;
2429 SECMODModule *newmod = SECMOD_LoadModuleWithFunction(moduleName, fentry);
2430 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
2431
2432 if (newmod) {
2433 SECMOD_GetReadLock(moduleLock);
2434 rv = STAN_AddModuleToDefaultTrustDomain(newmod);
2435 SECMOD_ReleaseReadLock(moduleLock);
2436 if (SECSuccess != rv) {
2437 SECMOD_DestroyModule(newmod);
2438 return NULL((void*)0);
2439 }
2440 }
2441 return newmod;
2442}
2443
2444/*
2445 * remove the PKCS#11 module from the default NSS trust domain, call
2446 * C_Finalize, and destroy the module structure
2447 */
2448SECStatus
2449SECMOD_UnloadUserModule(SECMODModule *mod)
2450{
2451 SECStatus rv = SECSuccess;
2452 int atype = 0;
2453 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
2454 if (!mod) {
2455 return SECFailure;
2456 }
2457
2458 SECMOD_GetReadLock(moduleLock);
2459 rv = STAN_RemoveModuleFromDefaultTrustDomain(mod);
2460 SECMOD_ReleaseReadLock(moduleLock);
2461 if (SECSuccess != rv) {
2462 return SECFailure;
2463 }
2464 return SECMOD_DeleteModuleEx(NULL((void*)0), mod, &atype, PR_FALSE0);
2465}