Bug Summary

File:root/firefox-clang/security/nss/lib/pk11wrap/pk11pars.c
Warning:line 491, 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-10-17-231001-351276-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 { CIPHER_NAME("MLKEM512")"MLKEM512", (sizeof("MLKEM512") - 1), SEC_OID_ML_KEM_512,
455 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
456 { CIPHER_NAME("MLKEM768")"MLKEM768", (sizeof("MLKEM768") - 1), SEC_OID_ML_KEM_768,
457 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
458 { CIPHER_NAME("MLKEM1024")"MLKEM1024", (sizeof("MLKEM1024") - 1), SEC_OID_ML_KEM_1024,
459 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
460
461};
462
463static const oidValDef smimeKxOptList[] = {
464 /* Key exchange */
465 { CIPHER_NAME("RSA-PKCS")"RSA-PKCS", (sizeof("RSA-PKCS") - 1), SEC_OID_PKCS1_RSA_ENCRYPTION, NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
466 { CIPHER_NAME("RSA-OAEP")"RSA-OAEP", (sizeof("RSA-OAEP") - 1), SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION, NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
467 { CIPHER_NAME("ECDH")"ECDH", (sizeof("ECDH") - 1), SEC_OID_ECDH_KEA, NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
468 { CIPHER_NAME("DH")"DH", (sizeof("DH") - 1), SEC_OID_X942_DIFFIE_HELMAN_KEY, NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
469};
470
471static const oidValDef signOptList[] = {
472 /* Signatures */
473 { CIPHER_NAME("DSA")"DSA", (sizeof("DSA") - 1), SEC_OID_ANSIX9_DSA_SIGNATURE,
474 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
475 { CIPHER_NAME("RSA-PKCS")"RSA-PKCS", (sizeof("RSA-PKCS") - 1), SEC_OID_PKCS1_RSA_ENCRYPTION,
476 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
477 { CIPHER_NAME("RSA-PSS")"RSA-PSS", (sizeof("RSA-PSS") - 1), SEC_OID_PKCS1_RSA_PSS_SIGNATURE,
478 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
479 { CIPHER_NAME("ECDSA")"ECDSA", (sizeof("ECDSA") - 1), SEC_OID_ANSIX962_EC_PUBLIC_KEY,
480 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
481 { CIPHER_NAME("ED25519")"ED25519", (sizeof("ED25519") - 1), SEC_OID_ED25519_PUBLIC_KEYSEC_OID_ED25519,
482 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
483 { CIPHER_NAME("ML-DSA-44")"ML-DSA-44", (sizeof("ML-DSA-44") - 1), SEC_OID_ML_DSA_44,
484 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
485 { CIPHER_NAME("ML-DSA-65")"ML-DSA-65", (sizeof("ML-DSA-65") - 1), SEC_OID_ML_DSA_65,
486 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
487 { CIPHER_NAME("ML-DSA-87")"ML-DSA-87", (sizeof("ML-DSA-87") - 1), SEC_OID_ML_DSA_87,
488 NSS_USE_ALG_IN_SSL_KX0x00000004 | NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
489};
490
491typedef 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
492 const oidValDef *list;
493 PRUint32 entries;
494 const char *description;
495 PRBool allowEmpty;
496} algListsDef;
497
498static const algListsDef algOptLists[] = {
499 { curveOptList, PR_ARRAY_SIZE(curveOptList)(sizeof(curveOptList) / sizeof((curveOptList)[0])), "ECC", PR_FALSE0 },
500 { hashOptList, PR_ARRAY_SIZE(hashOptList)(sizeof(hashOptList) / sizeof((hashOptList)[0])), "HASH", PR_FALSE0 },
501 { macOptList, PR_ARRAY_SIZE(macOptList)(sizeof(macOptList) / sizeof((macOptList)[0])), "MAC", PR_FALSE0 },
502 { cipherOptList, PR_ARRAY_SIZE(cipherOptList)(sizeof(cipherOptList) / sizeof((cipherOptList)[0])), "CIPHER", PR_FALSE0 },
503 { kxOptList, PR_ARRAY_SIZE(kxOptList)(sizeof(kxOptList) / sizeof((kxOptList)[0])), "SSL-KX", PR_FALSE0 },
504 { smimeKxOptList, PR_ARRAY_SIZE(smimeKxOptList)(sizeof(smimeKxOptList) / sizeof((smimeKxOptList)[0])), "SMIME-KX", PR_TRUE1 },
505 { signOptList, PR_ARRAY_SIZE(signOptList)(sizeof(signOptList) / sizeof((signOptList)[0])), "OTHER-SIGN", PR_FALSE0 },
506};
507
508static const optionFreeDef sslOptList[] = {
509 /* Versions */
510 { CIPHER_NAME("SSL2.0")"SSL2.0", (sizeof("SSL2.0") - 1), 0x002 },
511 { CIPHER_NAME("SSL3.0")"SSL3.0", (sizeof("SSL3.0") - 1), 0x300 },
512 { CIPHER_NAME("SSL3.1")"SSL3.1", (sizeof("SSL3.1") - 1), 0x301 },
513 { CIPHER_NAME("TLS1.0")"TLS1.0", (sizeof("TLS1.0") - 1), 0x301 },
514 { CIPHER_NAME("TLS1.1")"TLS1.1", (sizeof("TLS1.1") - 1), 0x302 },
515 { CIPHER_NAME("TLS1.2")"TLS1.2", (sizeof("TLS1.2") - 1), 0x303 },
516 { CIPHER_NAME("TLS1.3")"TLS1.3", (sizeof("TLS1.3") - 1), 0x304 },
517 { CIPHER_NAME("DTLS1.0")"DTLS1.0", (sizeof("DTLS1.0") - 1), 0x302 },
518 { CIPHER_NAME("DTLS1.1")"DTLS1.1", (sizeof("DTLS1.1") - 1), 0x302 },
519 { CIPHER_NAME("DTLS1.2")"DTLS1.2", (sizeof("DTLS1.2") - 1), 0x303 },
520 { CIPHER_NAME("DTLS1.3")"DTLS1.3", (sizeof("DTLS1.3") - 1), 0x304 },
521};
522
523static const optionFreeDef keySizeFlagsList[] = {
524 { CIPHER_NAME("KEY-SIZE-SSL")"KEY-SIZE-SSL", (sizeof("KEY-SIZE-SSL") - 1), NSS_KEY_SIZE_POLICY_SSL_FLAG1 },
525 { CIPHER_NAME("KEY-SIZE-SIGN")"KEY-SIZE-SIGN", (sizeof("KEY-SIZE-SIGN") - 1), NSS_KEY_SIZE_POLICY_SIGN_FLAG4 },
526 { CIPHER_NAME("KEY-SIZE-VERIFY")"KEY-SIZE-VERIFY", (sizeof("KEY-SIZE-VERIFY") - 1), NSS_KEY_SIZE_POLICY_VERIFY_FLAG2 },
527 { CIPHER_NAME("KEY-SIZE-SMIME")"KEY-SIZE-SMIME", (sizeof("KEY-SIZE-SMIME") - 1), NSS_KEY_SIZE_POLICY_SMIME_FLAG8 },
528 { CIPHER_NAME("KEY-SIZE-ALL")"KEY-SIZE-ALL", (sizeof("KEY-SIZE-ALL") - 1), NSS_KEY_SIZE_POLICY_ALL_FLAGS0x0f },
529};
530
531static const optionFreeDef freeOptList[] = {
532
533 /* Restrictions for asymetric keys */
534 { CIPHER_NAME("RSA-MIN")"RSA-MIN", (sizeof("RSA-MIN") - 1), NSS_RSA_MIN_KEY_SIZE0x001 },
535 { CIPHER_NAME("DH-MIN")"DH-MIN", (sizeof("DH-MIN") - 1), NSS_DH_MIN_KEY_SIZE0x002 },
536 { CIPHER_NAME("DSA-MIN")"DSA-MIN", (sizeof("DSA-MIN") - 1), NSS_DSA_MIN_KEY_SIZE0x004 },
537 { CIPHER_NAME("ECC-MIN")"ECC-MIN", (sizeof("ECC-MIN") - 1), NSS_ECC_MIN_KEY_SIZE0x011 },
538 /* what operations doe the key size apply to */
539 { CIPHER_NAME("KEY-SIZE-FLAGS")"KEY-SIZE-FLAGS", (sizeof("KEY-SIZE-FLAGS") - 1), NSS_KEY_SIZE_POLICY_FLAGS0x00e },
540 /* constraints on SSL Protocols */
541 { CIPHER_NAME("TLS-VERSION-MIN")"TLS-VERSION-MIN", (sizeof("TLS-VERSION-MIN") - 1), NSS_TLS_VERSION_MIN_POLICY0x008 },
542 { CIPHER_NAME("TLS-VERSION-MAX")"TLS-VERSION-MAX", (sizeof("TLS-VERSION-MAX") - 1), NSS_TLS_VERSION_MAX_POLICY0x009 },
543 /* constraints on DTLS Protocols */
544 { CIPHER_NAME("DTLS-VERSION-MIN")"DTLS-VERSION-MIN", (sizeof("DTLS-VERSION-MIN") - 1), NSS_DTLS_VERSION_MIN_POLICY0x00a },
545 { CIPHER_NAME("DTLS-VERSION-MAX")"DTLS-VERSION-MAX", (sizeof("DTLS-VERSION-MAX") - 1), NSS_DTLS_VERSION_MAX_POLICY0x00b }
546};
547
548static const policyFlagDef policyFlagList[] = {
549 { CIPHER_NAME("SSL")"SSL", (sizeof("SSL") - 1), NSS_USE_ALG_IN_SSL0x00000008 },
550 { CIPHER_NAME("SSL-KEY-EXCHANGE")"SSL-KEY-EXCHANGE", (sizeof("SSL-KEY-EXCHANGE") - 1), NSS_USE_ALG_IN_SSL_KX0x00000004 },
551 /* add other key exhanges in the future */
552 { CIPHER_NAME("KEY-EXCHANGE")"KEY-EXCHANGE", (sizeof("KEY-EXCHANGE") - 1), NSS_USE_ALG_IN_KEY_EXCHANGE((0x00000400 | 0x00000800) | 0x00000004) },
553 { CIPHER_NAME("CERT-SIGNATURE")"CERT-SIGNATURE", (sizeof("CERT-SIGNATURE") - 1), NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001 },
554 { CIPHER_NAME("CMS-SIGNATURE")"CMS-SIGNATURE", (sizeof("CMS-SIGNATURE") - 1), NSS_USE_ALG_IN_SMIME_SIGNATURE0x00000002 },
555 { CIPHER_NAME("SMIME-SIGNATURE")"SMIME-SIGNATURE", (sizeof("SMIME-SIGNATURE") - 1), NSS_USE_ALG_IN_SMIME_SIGNATURE0x00000002 },
556 { CIPHER_NAME("ALL-SIGNATURE")"ALL-SIGNATURE", (sizeof("ALL-SIGNATURE") - 1), NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) },
557 { CIPHER_NAME("PKCS12")"PKCS12", (sizeof("PKCS12") - 1), NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) },
558 /* only use in allow */
559 { CIPHER_NAME("PKCS12-LEGACY")"PKCS12-LEGACY", (sizeof("PKCS12-LEGACY") - 1), NSS_USE_ALG_IN_PKCS12_DECRYPT0x00000040 },
560 /* only use in disallow */
561 { CIPHER_NAME("PKCS12-ENCRYPT")"PKCS12-ENCRYPT", (sizeof("PKCS12-ENCRYPT") - 1), NSS_USE_ALG_IN_PKCS12_ENCRYPT0x00000080 },
562 { CIPHER_NAME("SMIME")"SMIME", (sizeof("SMIME") - 1), NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) },
563 /* only use in allow, enable */
564 { CIPHER_NAME("SMIME-LEGACY")"SMIME-LEGACY", (sizeof("SMIME-LEGACY") - 1), NSS_USE_ALG_IN_SMIME_LEGACY0x00000100 },
565 /* only use in disallow, disable */
566 { CIPHER_NAME("SMIME-ENCRYPT")"SMIME-ENCRYPT", (sizeof("SMIME-ENCRYPT") - 1), NSS_USE_ALG_IN_SMIME_ENCRYPT0x00000200 },
567 { CIPHER_NAME("SMIME-KEY-EXCHANGE")"SMIME-KEY-EXCHANGE", (sizeof("SMIME-KEY-EXCHANGE") - 1), NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
568 /* only use in allow */
569 { CIPHER_NAME("SMIME-KEY-EXCHANGE-LEGACY")"SMIME-KEY-EXCHANGE-LEGACY", (sizeof("SMIME-KEY-EXCHANGE-LEGACY"
) - 1)
, NSS_USE_ALG_IN_SMIME_KX_LEGACY0x00000400 },
570 /* only use in disallow */
571 { CIPHER_NAME("SMIME-KEY-EXCHANGE-ENCRYPT")"SMIME-KEY-EXCHANGE-ENCRYPT", (sizeof("SMIME-KEY-EXCHANGE-ENCRYPT"
) - 1)
, NSS_USE_ALG_IN_SMIME_KX_ENCRYPT0x00000800 },
572 /* sign turns off all signatures, but doesn't change the
573 * allowance for specific signatures... for example:
574 * disallow=sha256/all allow=sha256/signature
575 * doesn't allow cert-signatures or sime-signatures, where
576 * disallow=sha256/all allow=sha256/all-signature
577 * does. however,
578 * disallow=sha256/signature
579 * and
580 * disallow=sha256/all-signature
581 * are equivalent in effect */
582 { CIPHER_NAME("SIGNATURE")"SIGNATURE", (sizeof("SIGNATURE") - 1), NSS_USE_ALG_IN_ANY_SIGNATURE0x00000020 },
583 /* enable/allow algorithms for legacy (read/verify)operations */
584 { CIPHER_NAME("LEGACY")"LEGACY", (sizeof("LEGACY") - 1), NSS_USE_ALG_IN_PKCS12_DECRYPT0x00000040 |
585 NSS_USE_ALG_IN_SMIME_LEGACY0x00000100 |
586 NSS_USE_ALG_IN_SMIME_KX_LEGACY0x00000400 },
587 /* enable/disable everything */
588 { CIPHER_NAME("ALL")"ALL", (sizeof("ALL") - 1), NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_SSL_KX0x00000004 |
589 NSS_USE_ALG_IN_PKCS12(0x00000040 | 0x00000080) | NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200) |
590 NSS_USE_ALG_IN_SIGNATURE(0x00000001 | 0x00000002 | 0x00000020) |
591 NSS_USE_ALG_IN_SMIME_KX(0x00000400 | 0x00000800) },
592 { CIPHER_NAME("NONE")"NONE", (sizeof("NONE") - 1), 0 }
593};
594
595/*
596 * Get the next cipher on the list. point to the next one in 'next'.
597 * return the length;
598 */
599static const char *
600secmod_ArgGetSubValue(const char *cipher, char sep1, char sep2,
601 int *len, const char **next)
602{
603 const char *start = cipher;
604
605 if (start == NULL((void*)0)) {
606 *len = 0;
607 *next = NULL((void*)0);
608 return start;
609 }
610
611 for (; *cipher && *cipher != sep2; cipher++) {
612 if (*cipher == sep1) {
613 *next = cipher + 1;
614 *len = cipher - start;
615 return start;
616 }
617 }
618 *next = NULL((void*)0);
619 *len = cipher - start;
620 return start;
621}
622
623static PRUint32
624secmod_parsePolicyValue(const char *policyFlags, int policyLength,
625 PRBool printPolicyFeedback, PRUint32 policyCheckFlags)
626{
627 const char *flag, *currentString;
628 PRUint32 flags = 0;
629 int i;
630
631 for (currentString = policyFlags; currentString &&
632 currentString < policyFlags + policyLength;) {
633 int length;
634 PRBool unknown = PR_TRUE1;
635 flag = secmod_ArgGetSubValue(currentString, ',', ':', &length,
636 &currentString);
637 if (length == 0) {
638 continue;
639 }
640 for (i = 0; i < PR_ARRAY_SIZE(policyFlagList)(sizeof(policyFlagList) / sizeof((policyFlagList)[0])); i++) {
641 const policyFlagDef *policy = &policyFlagList[i];
642 unsigned name_size = policy->name_size;
643 if ((policy->name_size == length) &&
644 PORT_StrncasecmpPL_strncasecmp(policy->name, flag, name_size) == 0) {
645 flags |= policy->flag;
646 unknown = PR_FALSE0;
647 break;
648 }
649 }
650 if (unknown && printPolicyFeedback &&
651 (policyCheckFlags & SECMOD_FLAG_POLICY_CHECK_VALUE0x02)) {
652 PR_SetEnv("NSS_POLICY_FAIL=1");
653 fprintf(stderrstderr, "NSS-POLICY-FAIL %.*s: unknown value: %.*s\n",
654 policyLength, policyFlags, length, flag);
655 }
656 }
657 return flags;
658}
659
660/* allow symbolic names for values. The only ones currently defines or
661 * SSL protocol versions. */
662static SECStatus
663secmod_getPolicyOptValue(const char *policyValue, int policyValueLength,
664 PRInt32 *result)
665{
666 PRInt32 val = atoi(policyValue);
667 int i;
668
669 if ((val != 0) || (*policyValue == '0')) {
670 *result = val;
671 return SECSuccess;
672 }
673 if (policyValueLength == 0) {
674 return SECFailure;
675 }
676 /* handle any ssl strings */
677 for (i = 0; i < PR_ARRAY_SIZE(sslOptList)(sizeof(sslOptList) / sizeof((sslOptList)[0])); i++) {
678 if (policyValueLength == sslOptList[i].name_size &&
679 PORT_StrncasecmpPL_strncasecmp(sslOptList[i].name, policyValue,
680 sslOptList[i].name_size) == 0) {
681 *result = sslOptList[i].option;
682 return SECSuccess;
683 }
684 }
685 /* handle key_size flags. Each flag represents a bit, which
686 * gets or'd together. They can be separated by , | or + */
687 val = 0;
688 while (policyValueLength > 0) {
689 PRBool found = PR_FALSE0;
690 for (i = 0; i < PR_ARRAY_SIZE(keySizeFlagsList)(sizeof(keySizeFlagsList) / sizeof((keySizeFlagsList)[0])); i++) {
691 if (PORT_StrncasecmpPL_strncasecmp(keySizeFlagsList[i].name, policyValue,
692 keySizeFlagsList[i].name_size) == 0) {
693 val |= keySizeFlagsList[i].option;
694 found = PR_TRUE1;
695 policyValue += keySizeFlagsList[i].name_size;
696 policyValueLength -= keySizeFlagsList[i].name_size;
697 break;
698 }
699 }
700 if (!found) {
701 return SECFailure;
702 }
703 if (*policyValue == ',' || *policyValue == '|' || *policyValue == '+') {
704 policyValue++;
705 policyValueLength--;
706 }
707 }
708 *result = val;
709 return SECSuccess;
710}
711
712/* Policy operations:
713 * Disallow: operation is disallowed by policy. Implies disabled.
714 * Allow: operation is allowed by policy (but could be disabled).
715 * Disable: operation is turned off by default (but could be allowed).
716 * Enable: operation is enabled by default. Implies allowed.
717 */
718typedef enum {
719 NSS_DISALLOW,
720 NSS_ALLOW,
721 NSS_DISABLE,
722 NSS_ENABLE
723} NSSPolicyOperation;
724
725/* Enable/Disable only apply to SSL cipher suites and S/MIME symetric algorithms.
726 * Enable/Disable is implemented by clearing the DEFAULT_NOT_VALID
727 * flag, then setting the NSS_USE_DEFAULT_SSL_ENABLE and
728 * NSS_USE_DEFAULT_SMIME_ENABLE flags to the correct value. The ssl
729 * policy code will then sort out what to set based on ciphers and
730 * cipher suite values and the smime policy code will sort
731 * out which ciphers to include in capabilities based on these values */
732static SECStatus
733secmod_setDefault(SECOidTag oid, NSSPolicyOperation operation,
734 PRUint32 value)
735{
736 SECStatus rv = SECSuccess;
737 PRUint32 policy;
738 PRUint32 useDefault = 0;
739 PRUint32 set = 0;
740 /* we always clear the default not valid flag as this operation will
741 * make the defaults valid */
742 PRUint32 clear = NSS_USE_DEFAULT_NOT_VALID0x80000000;
743
744 /* what values are we trying to change */
745 /* if either SSL or SSL_KX is set, enable SSL */
746 if (value & (NSS_USE_ALG_IN_SSL0x00000008 | NSS_USE_ALG_IN_SSL_KX0x00000004)) {
747 useDefault |= NSS_USE_DEFAULT_SSL_ENABLE0x40000000;
748 }
749 /* only bulk ciphers are configured as enable in S/MIME, only
750 * enable them if both SMIME bits are set */
751 if ((value & NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200)) == NSS_USE_ALG_IN_SMIME(0x00000100 | 0x00000200)) {
752 useDefault |= NSS_USE_DEFAULT_SMIME_ENABLE0x20000000;
753 }
754
755 /* on disable we clear, on enable we set */
756 if (operation == NSS_DISABLE) {
757 clear |= useDefault;
758 } else {
759 /* we also turn the cipher on by policy if we enable it,
760 * so include the policy bits */
761 set |= value | useDefault;
762 }
763
764 /* if we haven't set the not valid flag yet, then we need to
765 * clear any of the other bits we aren't actually setting as well.
766 */
767 rv = NSS_GetAlgorithmPolicy(oid, &policy);
768 if (rv != SECSuccess) {
769 return rv;
770 }
771 if (policy & NSS_USE_DEFAULT_NOT_VALID0x80000000) {
772 clear |= ((NSS_USE_DEFAULT_SSL_ENABLE0x40000000 | NSS_USE_DEFAULT_SMIME_ENABLE0x20000000) &
773 ~set);
774 }
775 return NSS_SetAlgorithmPolicy(oid, set, clear);
776}
777
778/* apply the operator specific policy */
779SECStatus
780secmod_setPolicyOperation(SECOidTag oid, NSSPolicyOperation operation,
781 PRUint32 value)
782{
783 SECStatus rv = SECSuccess;
784 switch (operation) {
785 case NSS_DISALLOW:
786 /* clear the requested policy bits */
787 rv = NSS_SetAlgorithmPolicy(oid, 0, value);
788 break;
789 case NSS_ALLOW:
790 /* set the requested policy bits */
791 rv = NSS_SetAlgorithmPolicy(oid, value, 0);
792 break;
793 case NSS_DISABLE:
794 case NSS_ENABLE:
795 rv = secmod_setDefault(oid, operation, value);
796 break;
797 default:
798 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE);
799 rv = SECFailure;
800 break;
801 }
802 return rv;
803}
804
805const char *
806secmod_getOperationString(NSSPolicyOperation operation)
807{
808 switch (operation) {
809 case NSS_DISALLOW:
810 return "disallow";
811 case NSS_ALLOW:
812 return "allow";
813 case NSS_DISABLE:
814 return "disable";
815 case NSS_ENABLE:
816 return "enable";
817 default:
818 break;
819 }
820 return "invalid";
821}
822
823/* Allow external applications fetch the policy oid based on the internal
824 * string mapping used by the configuration system. The search can be
825 * narrowed by supplying the name of the table (list) that the policy
826 * is on. The value 'Any' allows the policy to be searched on all lists */
827SECOidTag
828SECMOD_PolicyStringToOid(const char *policy, const char *list)
829{
830 PRBool any = (PORT_StrcasecmpPL_strcasecmp(list, "Any") == 0) ? PR_TRUE1 : PR_FALSE0;
831 int len = PORT_Strlen(policy)strlen(policy);
832 int i, j;
833
834 for (i = 0; i < PR_ARRAY_SIZE(algOptLists)(sizeof(algOptLists) / sizeof((algOptLists)[0])); i++) {
835 const algListsDef *algOptList = &algOptLists[i];
836 if (any || (PORT_StrcasecmpPL_strcasecmp(algOptList->description, list) == 0)) {
837 for (j = 0; j < algOptList->entries; j++) {
838 const oidValDef *algOpt = &algOptList->list[j];
839 unsigned name_size = algOpt->name_size;
840 if (len == name_size &&
841 PORT_StrcasecmpPL_strcasecmp(algOpt->name, policy) == 0) {
842 return algOpt->oid;
843 }
844 }
845 }
846 }
847 return SEC_OID_UNKNOWN;
848}
849
850/* Allow external applications fetch the NSS option based on the internal
851 * string mapping used by the configuration system. */
852PRUint32
853SECMOD_PolicyStringToOpt(const char *policy)
854{
855 int len = PORT_Strlen(policy)strlen(policy);
856 int i;
857
858 for (i = 0; i < PR_ARRAY_SIZE(freeOptList)(sizeof(freeOptList) / sizeof((freeOptList)[0])); i++) {
859 const optionFreeDef *freeOpt = &freeOptList[i];
860 unsigned name_size = freeOpt->name_size;
861 if (len == name_size &&
862 PORT_StrcasecmpPL_strcasecmp(freeOpt->name, policy) == 0) {
863 return freeOpt->option;
864 }
865 }
866 return 0;
867}
868
869/* Allow external applications map policy flags to their string equivalance.
870 * Some strings represent more than one flag. If more than one flag is included
871 * the returned string is the string that contains any of the
872 * supplied flags unless exact is specified. If exact is specified, then the
873 * returned value matches all the included flags and only those flags. For
874 * Example: 'ALL-SIGNATURE' has the bits NSS_USE_ALG_IN_CERTSIGNATURE|
875 * NSS_USE_ALG_IN_SMIME_SIGNATURE|NSS_USE_ALG_IN_ANY_SIGNATURE. If you ask for
876 * NSS_USE_ALG_IN_CERT_SIGNATURE|NSS_USE_ALG_IN_SMIME_SIGNATURE and don't set
877 * exact, this function will return 'ALL-SIGNATURE' if you do set exact, you must
878 * include all three bits in value to get 'All-SIGNATURE'*/
879const char *
880SECMOD_FlagsToPolicyString(PRUint32 val, PRBool exact)
881{
882 int i;
883
884 for (i = 0; i < PR_ARRAY_SIZE(policyFlagList)(sizeof(policyFlagList) / sizeof((policyFlagList)[0])); i++) {
885 const policyFlagDef *policy = &policyFlagList[i];
886 if (exact && (policy->flag == val)) {
887 return policy->name;
888 }
889 if (!exact && ((policy->flag & val) == policy->flag)) {
890 return policy->name;
891 }
892 }
893 return NULL((void*)0);
894}
895
896static SECStatus
897secmod_applyCryptoPolicy(const char *policyString, NSSPolicyOperation operation,
898 PRBool printPolicyFeedback, PRUint32 policyCheckFlags)
899{
900 const char *cipher, *currentString;
901 unsigned i, j;
902 SECStatus rv = SECSuccess;
903 PRBool unknown;
904
905 if (policyString == NULL((void*)0) || policyString[0] == 0) {
906 return SECSuccess; /* do nothing */
907 }
908
909 /* if we change any of these, make sure it gets applied in ssl as well */
910 NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL0x00000010, 0);
911
912 for (currentString = policyString; currentString;) {
913 int length;
914 PRBool newValue = PR_FALSE0;
915
916 cipher = secmod_ArgGetSubValue(currentString, ':', 0, &length,
917 &currentString);
918 unknown = PR_TRUE1;
919 if (length >= 3 && cipher[3] == '/') {
920 newValue = PR_TRUE1;
921 }
922 if ((newValue || (length == 3)) && PORT_StrncasecmpPL_strncasecmp(cipher, "all", 3) == 0) {
923 /* disable or enable all options by default */
924 PRUint32 value = 0;
925 if (newValue) {
926 value = secmod_parsePolicyValue(&cipher[3] + 1, length - 3 - 1, printPolicyFeedback, policyCheckFlags);
927 }
928 for (i = 0; i < PR_ARRAY_SIZE(algOptLists)(sizeof(algOptLists) / sizeof((algOptLists)[0])); i++) {
929 const algListsDef *algOptList = &algOptLists[i];
930 for (j = 0; j < algOptList->entries; j++) {
931 if (!newValue) {
932 value = algOptList->list[j].val;
933 }
934 secmod_setPolicyOperation(algOptList->list[j].oid, operation, value);
935 }
936 }
937 continue;
938 }
939
940 for (i = 0; i < PR_ARRAY_SIZE(algOptLists)(sizeof(algOptLists) / sizeof((algOptLists)[0])); i++) {
941 const algListsDef *algOptList = &algOptLists[i];
942 for (j = 0; j < algOptList->entries; j++) {
943 const oidValDef *algOpt = &algOptList->list[j];
944 unsigned name_size = algOpt->name_size;
945 PRBool newOption = PR_FALSE0;
946
947 if ((length >= name_size) && (cipher[name_size] == '/')) {
948 newOption = PR_TRUE1;
949 }
950 if ((newOption || algOpt->name_size == length) &&
951 PORT_StrncasecmpPL_strncasecmp(algOpt->name, cipher, name_size) == 0) {
952 PRUint32 value = algOpt->val;
953 if (newOption) {
954 value = secmod_parsePolicyValue(&cipher[name_size] + 1,
955 length - name_size - 1,
956 printPolicyFeedback,
957 policyCheckFlags);
958 }
959 rv = secmod_setPolicyOperation(algOptList->list[j].oid, operation, value);
960 if (rv != SECSuccess) {
961 /* could not enable option */
962 /* NSS_SetAlgorithPolicy should have set the error code */
963 return SECFailure;
964 }
965 unknown = PR_FALSE0;
966 break;
967 }
968 }
969 }
970 if (!unknown) {
971 continue;
972 }
973
974 for (i = 0; i < PR_ARRAY_SIZE(freeOptList)(sizeof(freeOptList) / sizeof((freeOptList)[0])); i++) {
975 const optionFreeDef *freeOpt = &freeOptList[i];
976 unsigned name_size = freeOpt->name_size;
977
978 if ((length > name_size) && cipher[name_size] == '=' &&
979 PORT_StrncasecmpPL_strncasecmp(freeOpt->name, cipher, name_size) == 0) {
980 PRInt32 val;
981 const char *policyValue = &cipher[name_size + 1];
982 int policyValueLength = length - name_size - 1;
983 rv = secmod_getPolicyOptValue(policyValue, policyValueLength,
984 &val);
985 if (rv != SECSuccess) {
986 if (printPolicyFeedback &&
987 (policyCheckFlags & SECMOD_FLAG_POLICY_CHECK_VALUE0x02)) {
988 PR_SetEnv("NSS_POLICY_FAIL=1");
989 fprintf(stderrstderr, "NSS-POLICY-FAIL %.*s: unknown value: %.*s\n",
990 length, cipher, policyValueLength, policyValue);
991 }
992 return SECFailure;
993 }
994 rv = NSS_OptionSet(freeOpt->option, val);
995 if (rv != SECSuccess) {
996 /* could not enable option */
997 /* NSS_OptionSet should have set the error code */
998 return SECFailure;
999 }
1000 /* to allow the policy to expand in the future. ignore ciphers
1001 * we don't understand */
1002 unknown = PR_FALSE0;
1003 break;
1004 }
1005 }
1006
1007 if (unknown && printPolicyFeedback &&
1008 (policyCheckFlags & SECMOD_FLAG_POLICY_CHECK_IDENTIFIER0x01)) {
1009 PR_SetEnv("NSS_POLICY_FAIL=1");
1010 fprintf(stderrstderr, "NSS-POLICY-FAIL %s: unknown identifier: %.*s\n",
1011 secmod_getOperationString(operation), length, cipher);
1012 }
1013 }
1014 return rv;
1015}
1016
1017static void
1018secmod_sanityCheckCryptoPolicy(void)
1019{
1020 unsigned i, j;
1021 SECStatus rv = SECSuccess;
1022 unsigned num_kx_enabled = 0;
1023 unsigned num_ssl_enabled = 0;
1024 unsigned num_sig_enabled = 0;
1025 unsigned enabledCount[PR_ARRAY_SIZE(algOptLists)(sizeof(algOptLists) / sizeof((algOptLists)[0]))];
1026 const char *sWarn = "WARN";
1027 const char *sInfo = "INFO";
1028 PRBool haveWarning = PR_FALSE0;
1029
1030 for (i = 0; i < PR_ARRAY_SIZE(algOptLists)(sizeof(algOptLists) / sizeof((algOptLists)[0])); i++) {
1031 const algListsDef *algOptList = &algOptLists[i];
1032 enabledCount[i] = 0;
1033 for (j = 0; j < algOptList->entries; j++) {
1034 const oidValDef *algOpt = &algOptList->list[j];
1035 PRUint32 value;
1036 PRBool anyEnabled = PR_FALSE0;
1037 rv = NSS_GetAlgorithmPolicy(algOpt->oid, &value);
1038 if (rv != SECSuccess) {
1039 PR_SetEnv("NSS_POLICY_FAIL=1");
1040 fprintf(stderrstderr, "NSS-POLICY-FAIL: internal failure with NSS_GetAlgorithmPolicy at %u\n", i);
1041 return;
1042 }
1043
1044 if ((algOpt->val & NSS_USE_ALG_IN_SSL_KX0x00000004) && (value & NSS_USE_ALG_IN_SSL_KX0x00000004)) {
1045 ++num_kx_enabled;
1046 anyEnabled = PR_TRUE1;
1047 fprintf(stderrstderr, "NSS-POLICY-INFO: %s is enabled for SSL-KX\n", algOpt->name);
1048 }
1049 if ((algOpt->val & NSS_USE_ALG_IN_SSL0x00000008) && (value & NSS_USE_ALG_IN_SSL0x00000008)) {
1050 ++num_ssl_enabled;
1051 anyEnabled = PR_TRUE1;
1052 fprintf(stderrstderr, "NSS-POLICY-INFO: %s is enabled for SSL\n", algOpt->name);
1053 }
1054 if ((algOpt->val & NSS_USE_ALG_IN_CERT_SIGNATURE0x00000001) &&
1055 ((value & NSS_USE_CERT_SIGNATURE_OK(0x00000001 | 0x00000020)) == NSS_USE_CERT_SIGNATURE_OK(0x00000001 | 0x00000020))) {
1056 ++num_sig_enabled;
1057 anyEnabled = PR_TRUE1;
1058 fprintf(stderrstderr, "NSS-POLICY-INFO: %s is enabled for CERT-SIGNATURE\n", algOpt->name);
1059 }
1060 if (anyEnabled) {
1061 ++enabledCount[i];
1062 }
1063 }
1064 }
1065 fprintf(stderrstderr, "NSS-POLICY-%s: NUMBER-OF-SSL-ALG-KX: %u\n", num_kx_enabled ? sInfo : sWarn, num_kx_enabled);
1066 fprintf(stderrstderr, "NSS-POLICY-%s: NUMBER-OF-SSL-ALG: %u\n", num_ssl_enabled ? sInfo : sWarn, num_ssl_enabled);
1067 fprintf(stderrstderr, "NSS-POLICY-%s: NUMBER-OF-CERT-SIG: %u\n", num_sig_enabled ? sInfo : sWarn, num_sig_enabled);
1068 if (!num_kx_enabled || !num_ssl_enabled || !num_sig_enabled) {
1069 haveWarning = PR_TRUE1;
1070 }
1071 for (i = 0; i < PR_ARRAY_SIZE(algOptLists)(sizeof(algOptLists) / sizeof((algOptLists)[0])); i++) {
1072 const algListsDef *algOptList = &algOptLists[i];
1073 fprintf(stderrstderr, "NSS-POLICY-%s: NUMBER-OF-%s: %u\n", enabledCount[i] ? sInfo : sWarn, algOptList->description, enabledCount[i]);
1074 if (!enabledCount[i] && !algOptList->allowEmpty) {
1075 haveWarning = PR_TRUE1;
1076 }
1077 }
1078 if (haveWarning) {
1079 PR_SetEnv("NSS_POLICY_WARN=1");
1080 }
1081}
1082
1083static SECStatus
1084secmod_parseCryptoPolicy(const char *policyConfig, PRBool printPolicyFeedback,
1085 PRUint32 policyCheckFlags)
1086{
1087 char *args;
1088 SECStatus rv;
1089
1090 if (policyConfig == NULL((void*)0)) {
1091 return SECSuccess; /* no policy given */
1092 }
1093 /* make sure we initialize the oid table and set all the default policy
1094 * values first so we can override them here */
1095 rv = SECOID_Init();
1096 if (rv != SECSuccess) {
1097 return rv;
1098 }
1099 args = NSSUTIL_ArgGetParamValue("disallow", policyConfig);
1100 rv = secmod_applyCryptoPolicy(args, NSS_DISALLOW, printPolicyFeedback,
1101 policyCheckFlags);
1102 if (args)
1103 PORT_FreePORT_Free_Util(args);
1104 if (rv != SECSuccess) {
1105 return rv;
1106 }
1107 args = NSSUTIL_ArgGetParamValue("allow", policyConfig);
1108 rv = secmod_applyCryptoPolicy(args, NSS_ALLOW, printPolicyFeedback,
1109 policyCheckFlags);
1110 if (args)
1111 PORT_FreePORT_Free_Util(args);
1112 if (rv != SECSuccess) {
1113 return rv;
1114 }
1115 args = NSSUTIL_ArgGetParamValue("disable", policyConfig);
1116 rv = secmod_applyCryptoPolicy(args, NSS_DISABLE, printPolicyFeedback,
1117 policyCheckFlags);
1118 if (args)
1119 PORT_FreePORT_Free_Util(args);
1120 if (rv != SECSuccess) {
1121 return rv;
1122 }
1123 args = NSSUTIL_ArgGetParamValue("enable", policyConfig);
1124 rv = secmod_applyCryptoPolicy(args, NSS_ENABLE, printPolicyFeedback,
1125 policyCheckFlags);
1126 if (args)
1127 PORT_FreePORT_Free_Util(args);
1128 if (rv != SECSuccess) {
1129 return rv;
1130 }
1131 /* this has to be last. Everything after this will be a noop */
1132 if (NSSUTIL_ArgHasFlag("flags", "ssl-lock", policyConfig)) {
1133 PRInt32 locks;
1134 /* don't overwrite other (future) lock flags */
1135 rv = NSS_OptionGet(NSS_DEFAULT_LOCKS0x00d, &locks);
1136 if (rv == SECSuccess) {
1137 rv = NSS_OptionSet(NSS_DEFAULT_LOCKS0x00d, locks | NSS_DEFAULT_SSL_LOCK1);
1138 }
1139 if (rv != SECSuccess) {
1140 return rv;
1141 }
1142 }
1143 if (NSSUTIL_ArgHasFlag("flags", "policy-lock", policyConfig)) {
1144 NSS_LockPolicy();
1145 }
1146 if (printPolicyFeedback) {
1147 /* This helps to distinguish configurations that don't contain any
1148 * policy config= statement. */
1149 PR_SetEnv("NSS_POLICY_LOADED=1");
1150 fprintf(stderrstderr, "NSS-POLICY-INFO: LOADED-SUCCESSFULLY\n");
1151 secmod_sanityCheckCryptoPolicy();
1152 }
1153 return rv;
1154}
1155
1156static PRUint32
1157secmod_parsePolicyCheckFlags(const char *nss)
1158{
1159 PRUint32 policyCheckFlags = 0;
1160
1161 if (NSSUTIL_ArgHasFlag("flags", "policyCheckIdentifier", nss)) {
1162 policyCheckFlags |= SECMOD_FLAG_POLICY_CHECK_IDENTIFIER0x01;
1163 }
1164
1165 if (NSSUTIL_ArgHasFlag("flags", "policyCheckValue", nss)) {
1166 policyCheckFlags |= SECMOD_FLAG_POLICY_CHECK_VALUE0x02;
1167 }
1168
1169 return policyCheckFlags;
1170}
1171
1172/*
1173 * for 3.4 we continue to use the old SECMODModule structure
1174 */
1175SECMODModule *
1176SECMOD_CreateModuleEx(const char *library, const char *moduleName,
1177 const char *parameters, const char *nss,
1178 const char *config)
1179{
1180 SECMODModule *mod;
1181 SECStatus rv;
1182 char *slotParams, *ciphers;
1183 PRBool printPolicyFeedback = NSSUTIL_ArgHasFlag("flags", "printPolicyFeedback", nss);
1184 PRUint32 policyCheckFlags = secmod_parsePolicyCheckFlags(nss);
1185
1186 rv = secmod_parseCryptoPolicy(config, printPolicyFeedback, policyCheckFlags);
1187
1188 /* do not load the module if policy parsing fails */
1189 if (rv != SECSuccess) {
1190 if (printPolicyFeedback) {
1191 PR_SetEnv("NSS_POLICY_FAIL=1");
1192 fprintf(stderrstderr, "NSS-POLICY-FAIL: policy config parsing failed, not loading module %s\n", moduleName);
1193 }
1194 return NULL((void*)0);
1195 }
1196
1197 mod = secmod_NewModule();
1198 if (mod == NULL((void*)0))
1199 return NULL((void*)0);
1200
1201 mod->commonName = PORT_ArenaStrdupPORT_ArenaStrdup_Util(mod->arena, moduleName ? moduleName : "");
1202 if (library) {
1203 mod->dllName = PORT_ArenaStrdupPORT_ArenaStrdup_Util(mod->arena, library);
1204 }
1205 /* new field */
1206 if (parameters) {
1207 mod->libraryParams = PORT_ArenaStrdupPORT_ArenaStrdup_Util(mod->arena, parameters);
1208 }
1209
1210 mod->internal = NSSUTIL_ArgHasFlag("flags", "internal", nss);
1211 mod->isFIPS = NSSUTIL_ArgHasFlag("flags", "FIPS", nss);
1212 /* if the system FIPS mode is enabled, force FIPS to be on */
1213 if (SECMOD_GetSystemFIPSEnabled()) {
1214 mod->isFIPS = PR_TRUE1;
1215 }
1216 mod->isCritical = NSSUTIL_ArgHasFlag("flags", "critical", nss);
1217 slotParams = NSSUTIL_ArgGetParamValue("slotParams", nss);
1218 mod->slotInfo = NSSUTIL_ArgParseSlotInfo(mod->arena, slotParams,
1219 &mod->slotInfoCount);
1220 if (slotParams)
1221 PORT_FreePORT_Free_Util(slotParams);
1222 /* new field */
1223 mod->trustOrder = NSSUTIL_ArgReadLong("trustOrder", nss,
1224 NSSUTIL_DEFAULT_TRUST_ORDER50, NULL((void*)0));
1225 /* new field */
1226 mod->cipherOrder = NSSUTIL_ArgReadLong("cipherOrder", nss,
1227 NSSUTIL_DEFAULT_CIPHER_ORDER0, NULL((void*)0));
1228 /* new field */
1229 mod->isModuleDB = NSSUTIL_ArgHasFlag("flags", "moduleDB", nss);
1230 mod->moduleDBOnly = NSSUTIL_ArgHasFlag("flags", "moduleDBOnly", nss);
1231 if (mod->moduleDBOnly)
1232 mod->isModuleDB = PR_TRUE1;
1233
1234 /* we need more bits, but we also want to preserve binary compatibility
1235 * so we overload the isModuleDB PRBool with additional flags.
1236 * These flags are only valid if mod->isModuleDB is already set.
1237 * NOTE: this depends on the fact that PRBool is at least a char on
1238 * all platforms. These flags are only valid if moduleDB is set, so
1239 * code checking if (mod->isModuleDB) will continue to work correctly. */
1240 if (mod->isModuleDB) {
1241 char flags = SECMOD_FLAG_MODULE_DB_IS_MODULE_DB0x01;
1242 if (NSSUTIL_ArgHasFlag("flags", "skipFirst", nss)) {
1243 flags |= SECMOD_FLAG_MODULE_DB_SKIP_FIRST0x02;
1244 }
1245 if (NSSUTIL_ArgHasFlag("flags", "defaultModDB", nss)) {
1246 flags |= SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB0x04;
1247 }
1248 if (NSSUTIL_ArgHasFlag("flags", "policyOnly", nss)) {
1249 flags |= SECMOD_FLAG_MODULE_DB_POLICY_ONLY0x08;
1250 }
1251 /* additional moduleDB flags could be added here in the future */
1252 mod->isModuleDB = (PRBool)flags;
1253 }
1254
1255 if (mod->internal) {
1256 char flags = SECMOD_FLAG_INTERNAL_IS_INTERNAL0x01;
1257
1258 if (NSSUTIL_ArgHasFlag("flags", "internalKeySlot", nss)) {
1259 flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT0x02;
1260 }
1261 mod->internal = (PRBool)flags;
1262 }
1263
1264 ciphers = NSSUTIL_ArgGetParamValue("ciphers", nss);
1265 NSSUTIL_ArgParseCipherFlags(&mod->ssl[0], ciphers);
1266 if (ciphers)
1267 PORT_FreePORT_Free_Util(ciphers);
1268
1269 secmod_PrivateModuleCount++;
1270
1271 return mod;
1272}
1273
1274PRBool
1275SECMOD_GetSkipFirstFlag(SECMODModule *mod)
1276{
1277 char flags = (char)mod->isModuleDB;
1278
1279 return (flags & SECMOD_FLAG_MODULE_DB_SKIP_FIRST0x02) ? PR_TRUE1 : PR_FALSE0;
1280}
1281
1282PRBool
1283SECMOD_GetDefaultModDBFlag(SECMODModule *mod)
1284{
1285 char flags = (char)mod->isModuleDB;
1286
1287 return (flags & SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB0x04) ? PR_TRUE1 : PR_FALSE0;
1288}
1289
1290PRBool
1291secmod_PolicyOnly(SECMODModule *mod)
1292{
1293 char flags = (char)mod->isModuleDB;
1294
1295 return (flags & SECMOD_FLAG_MODULE_DB_POLICY_ONLY0x08) ? PR_TRUE1 : PR_FALSE0;
1296}
1297
1298PRBool
1299secmod_IsInternalKeySlot(SECMODModule *mod)
1300{
1301 char flags = (char)mod->internal;
1302
1303 return (flags & SECMOD_FLAG_INTERNAL_KEY_SLOT0x02) ? PR_TRUE1 : PR_FALSE0;
1304}
1305
1306void
1307secmod_SetInternalKeySlotFlag(SECMODModule *mod, PRBool val)
1308{
1309 char flags = (char)mod->internal;
1310
1311 if (val) {
1312 flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT0x02;
1313 } else {
1314 flags &= ~SECMOD_FLAG_INTERNAL_KEY_SLOT0x02;
1315 }
1316 mod->internal = flags;
1317}
1318
1319/*
1320 * copy desc and value into target. Target is known to be big enough to
1321 * hold desc +2 +value, which is good because the result of this will be
1322 * *desc"*value". We may, however, have to add some escapes for special
1323 * characters imbedded into value (rare). This string potentially comes from
1324 * a user, so we don't want the user overflowing the target buffer by using
1325 * excessive escapes. To prevent this we count the escapes we need to add and
1326 * try to expand the buffer with Realloc.
1327 */
1328static char *
1329secmod_doDescCopy(char *target, char **base, int *baseLen,
1330 const char *desc, int descLen, char *value)
1331{
1332 int diff, esc_len;
1333
1334 esc_len = NSSUTIL_EscapeSize(value, '\"') - 1;
1335 diff = esc_len - strlen(value);
1336 if (diff > 0) {
1337 /* we need to escape... expand newSpecPtr as well to make sure
1338 * we don't overflow it */
1339 int offset = target - *base;
1340 char *newPtr = PORT_ReallocPORT_Realloc_Util(*base, *baseLen + diff);
1341 if (!newPtr) {
1342 return target; /* not enough space, just drop the whole copy */
1343 }
1344 *baseLen += diff;
1345 target = newPtr + offset;
1346 *base = newPtr;
1347 value = NSSUTIL_Escape(value, '\"');
1348 if (value == NULL((void*)0)) {
1349 return target; /* couldn't escape value, just drop the copy */
1350 }
1351 }
1352 PORT_Memcpymemcpy(target, desc, descLen);
1353 target += descLen;
1354 *target++ = '\"';
1355 PORT_Memcpymemcpy(target, value, esc_len);
1356 target += esc_len;
1357 *target++ = '\"';
1358 if (diff > 0) {
1359 PORT_FreePORT_Free_Util(value);
1360 }
1361 return target;
1362}
1363
1364#define SECMOD_SPEC_COPY(new, start, end)if (end > start) { int _cnt = end - start; memcpy(new, start
, _cnt); new += _cnt; }
\
1365 if (end > start) { \
1366 int _cnt = end - start; \
1367 PORT_Memcpymemcpy(new, start, _cnt); \
1368 new += _cnt; \
1369 }
1370#define SECMOD_TOKEN_DESCRIPTION"tokenDescription=" "tokenDescription="
1371#define SECMOD_SLOT_DESCRIPTION"slotDescription=" "slotDescription="
1372
1373/*
1374 * Find any tokens= values in the module spec.
1375 * Always return a new spec which does not have any tokens= arguments.
1376 * If tokens= arguments are found, Split the the various tokens defined into
1377 * an array of child specs to return.
1378 *
1379 * Caller is responsible for freeing the child spec and the new token
1380 * spec.
1381 */
1382char *
1383secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
1384 const char *moduleSpec, char ***children,
1385 CK_SLOT_ID **ids)
1386{
1387 int newSpecLen = PORT_Strlen(moduleSpec)strlen(moduleSpec) + 2;
1388 char *newSpec = PORT_AllocPORT_Alloc_Util(newSpecLen);
1389 char *newSpecPtr = newSpec;
1390 const char *modulePrev = moduleSpec;
1391 char *target = NULL((void*)0);
1392 char *tmp = NULL((void*)0);
1393 char **childArray = NULL((void*)0);
1394 const char *tokenIndex;
1395 CK_SLOT_ID *idArray = NULL((void*)0);
1396 int tokenCount = 0;
1397 int i;
1398
1399 if (newSpec == NULL((void*)0)) {
1400 return NULL((void*)0);
1401 }
1402
1403 *children = NULL((void*)0);
1404 if (ids) {
1405 *ids = NULL((void*)0);
1406 }
1407 moduleSpec = NSSUTIL_ArgStrip(moduleSpec);
1408 SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec)if (moduleSpec > modulePrev) { int _cnt = moduleSpec - modulePrev
; memcpy(newSpecPtr, modulePrev, _cnt); newSpecPtr += _cnt; }
;
1409
1410 /* Notes on 'convert' and 'isFIPS' flags: The base parameters for opening
1411 * a new softoken module takes the following parameters to name the
1412 * various tokens:
1413 *
1414 * cryptoTokenDescription: name of the non-fips crypto token.
1415 * cryptoSlotDescription: name of the non-fips crypto slot.
1416 * dbTokenDescription: name of the non-fips db token.
1417 * dbSlotDescription: name of the non-fips db slot.
1418 * FIPSTokenDescription: name of the fips db/crypto token.
1419 * FIPSSlotDescription: name of the fips db/crypto slot.
1420 *
1421 * if we are opening a new slot, we need to have the following
1422 * parameters:
1423 * tokenDescription: name of the token.
1424 * slotDescription: name of the slot.
1425 *
1426 *
1427 * The convert flag tells us to drop the unnecessary *TokenDescription
1428 * and *SlotDescription arguments and convert the appropriate pair
1429 * (either db or FIPS based on the isFIPS flag) to tokenDescription and
1430 * slotDescription).
1431 */
1432 /*
1433 * walk down the list. if we find a tokens= argument, save it,
1434 * otherise copy the argument.
1435 */
1436 while (*moduleSpec) {
1437 int next;
1438 modulePrev = moduleSpec;
1439 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
1440 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
1441 /* 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
1442 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
1443 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
1444 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
1445 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
1446 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
1447 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
1448 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
1449 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
1450 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
1451 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
1452 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
1453 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
1454 &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
1455 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
1456 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
1457 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
1458 }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
1459 })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
1460 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
1461 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
1462 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
1463 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
1464 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
1465 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
1466 &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
1467 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
1468 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
1469 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
1470 }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
1471 })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
1472 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
1473 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
1474 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
1475 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
1476 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
1477 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
1478 &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
1479 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
1480 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
1481 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
1482 }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
1483 })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
1484 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
1485 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
1486 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
1487 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
1488 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
1489 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
1490 &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
1491 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
1492 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
1493 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
1494 }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
1495 })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
1496 NSSUTIL_HANDLE_FINAL_ARG(moduleSpec){ moduleSpec = NSSUTIL_ArgSkipParameter(moduleSpec); } moduleSpec
= NSSUTIL_ArgStrip(moduleSpec);
1497 SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec)if (moduleSpec > modulePrev) { int _cnt = moduleSpec - modulePrev
; memcpy(newSpecPtr, modulePrev, _cnt); newSpecPtr += _cnt; }
;
1498 }
1499 if (tmp) {
1500 PORT_FreePORT_Free_Util(tmp);
1501 tmp = NULL((void*)0);
1502 }
1503 *newSpecPtr = 0;
1504
1505 /* no target found, return the newSpec */
1506 if (target == NULL((void*)0)) {
1507 return newSpec;
1508 }
1509
1510 /* now build the child array from target */
1511 /*first count them */
1512 for (tokenIndex = NSSUTIL_ArgStrip(target); *tokenIndex;
1513 tokenIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(tokenIndex))) {
1514 tokenCount++;
1515 }
1516
1517 childArray = PORT_NewArray(char *, tokenCount + 1)(char * *)PORT_Alloc_Util(sizeof(char *) * (tokenCount + 1));
1518 if (childArray == NULL((void*)0)) {
1519 /* just return the spec as is then */
1520 PORT_FreePORT_Free_Util(target);
1521 return newSpec;
1522 }
1523 if (ids) {
1524 idArray = PORT_NewArray(CK_SLOT_ID, tokenCount + 1)(CK_SLOT_ID *)PORT_Alloc_Util(sizeof(CK_SLOT_ID) * (tokenCount
+ 1))
;
1525 if (idArray == NULL((void*)0)) {
1526 PORT_FreePORT_Free_Util(childArray);
1527 PORT_FreePORT_Free_Util(target);
1528 return newSpec;
1529 }
1530 }
1531
1532 /* now fill them in */
1533 for (tokenIndex = NSSUTIL_ArgStrip(target), i = 0;
1534 *tokenIndex && (i < tokenCount);
1535 tokenIndex = NSSUTIL_ArgStrip(tokenIndex)) {
1536 int next;
1537 char *name = NSSUTIL_ArgGetLabel(tokenIndex, &next);
1538 tokenIndex += next;
1539
1540 if (idArray) {
1541 idArray[i] = NSSUTIL_ArgDecodeNumber(name);
1542 }
1543
1544 PORT_FreePORT_Free_Util(name); /* drop the explicit number */
1545
1546 /* if anything is left, copy the args to the child array */
1547 if (!NSSUTIL_ArgIsBlank(*tokenIndex)) {
1548 childArray[i++] = NSSUTIL_ArgFetchValue(tokenIndex, &next);
1549 tokenIndex += next;
1550 }
1551 }
1552
1553 PORT_FreePORT_Free_Util(target);
1554 childArray[i] = 0;
1555 if (idArray) {
1556 idArray[i] = 0;
1557 }
1558
1559 /* return it */
1560 *children = childArray;
1561 if (ids) {
1562 *ids = idArray;
1563 }
1564 return newSpec;
1565}
1566
1567/* get the database and flags from the spec */
1568static char *
1569secmod_getConfigDir(const char *spec, char **certPrefix, char **keyPrefix,
1570 PRBool *readOnly)
1571{
1572 char *config = NULL((void*)0);
1573
1574 *certPrefix = NULL((void*)0);
1575 *keyPrefix = NULL((void*)0);
1576 *readOnly = NSSUTIL_ArgHasFlag("flags", "readOnly", spec);
1577 if (NSSUTIL_ArgHasFlag("flags", "nocertdb", spec) ||
1578 NSSUTIL_ArgHasFlag("flags", "nokeydb", spec)) {
1579 return NULL((void*)0);
1580 }
1581
1582 spec = NSSUTIL_ArgStrip(spec);
1583 while (*spec) {
1584 int next;
1585 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
1586 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
1587 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
1588 NSSUTIL_HANDLE_FINAL_ARG(spec){ spec = NSSUTIL_ArgSkipParameter(spec); } spec = NSSUTIL_ArgStrip
(spec);
1589 }
1590 return config;
1591}
1592
1593struct SECMODConfigListStr {
1594 char *config;
1595 char *certPrefix;
1596 char *keyPrefix;
1597 PRBool isReadOnly;
1598};
1599
1600/*
1601 * return an array of already openned databases from a spec list.
1602 */
1603SECMODConfigList *
1604secmod_GetConfigList(PRBool isFIPS, char *spec, int *count)
1605{
1606 char **children;
1607 CK_SLOT_ID *ids;
1608 char *strippedSpec;
1609 int childCount;
1610 SECMODConfigList *conflist = NULL((void*)0);
1611 int i;
1612
1613 strippedSpec = secmod_ParseModuleSpecForTokens(PR_TRUE1, isFIPS,
1614 spec, &children, &ids);
1615 if (strippedSpec == NULL((void*)0)) {
1616 return NULL((void*)0);
1617 }
1618
1619 for (childCount = 0; children && children[childCount]; childCount++)
1620 ;
1621 *count = childCount + 1; /* include strippedSpec */
1622 conflist = PORT_NewArray(SECMODConfigList, *count)(SECMODConfigList *)PORT_Alloc_Util(sizeof(SECMODConfigList) *
(*count))
;
1623 if (conflist == NULL((void*)0)) {
1624 *count = 0;
1625 goto loser;
1626 }
1627
1628 conflist[0].config = secmod_getConfigDir(strippedSpec,
1629 &conflist[0].certPrefix,
1630 &conflist[0].keyPrefix,
1631 &conflist[0].isReadOnly);
1632 for (i = 0; i < childCount; i++) {
1633 conflist[i + 1].config = secmod_getConfigDir(children[i],
1634 &conflist[i + 1].certPrefix,
1635 &conflist[i + 1].keyPrefix,
1636 &conflist[i + 1].isReadOnly);
1637 }
1638
1639loser:
1640 secmod_FreeChildren(children, ids);
1641 PORT_FreePORT_Free_Util(strippedSpec);
1642 return conflist;
1643}
1644
1645/*
1646 * determine if we are trying to open an old dbm database. For this test
1647 * RDB databases should return PR_FALSE.
1648 */
1649static PRBool
1650secmod_configIsDBM(char *configDir)
1651{
1652 char *env;
1653
1654 /* explicit dbm open */
1655 if (strncmp(configDir, "dbm:", 4) == 0) {
1656 return PR_TRUE1;
1657 }
1658 /* explicit open of a non-dbm database */
1659 if ((strncmp(configDir, "sql:", 4) == 0) ||
1660 (strncmp(configDir, "rdb:", 4) == 0) ||
1661 (strncmp(configDir, "extern:", 7) == 0)) {
1662 return PR_FALSE0;
1663 }
1664 env = PR_GetEnvSecure("NSS_DEFAULT_DB_TYPE");
1665 /* implicit dbm open */
1666 if ((env == NULL((void*)0)) || (strcmp(env, "dbm") == 0)) {
1667 return PR_TRUE1;
1668 }
1669 /* implicit non-dbm open */
1670 return PR_FALSE0;
1671}
1672
1673/*
1674 * match two prefixes. prefix may be NULL. NULL patches '\0'
1675 */
1676static PRBool
1677secmod_matchPrefix(char *prefix1, char *prefix2)
1678{
1679 if ((prefix1 == NULL((void*)0)) || (*prefix1 == 0)) {
1680 if ((prefix2 == NULL((void*)0)) || (*prefix2 == 0)) {
1681 return PR_TRUE1;
1682 }
1683 return PR_FALSE0;
1684 }
1685 if (strcmp(prefix1, prefix2) == 0) {
1686 return PR_TRUE1;
1687 }
1688 return PR_FALSE0;
1689}
1690
1691/* do two config paramters match? Not all callers are compariing
1692 * SECMODConfigLists directly, so this function breaks them out to their
1693 * components. */
1694static PRBool
1695secmod_matchConfig(char *configDir1, char *configDir2,
1696 char *certPrefix1, char *certPrefix2,
1697 char *keyPrefix1, char *keyPrefix2,
1698 PRBool isReadOnly1, PRBool isReadOnly2)
1699{
1700 /* TODO: Document the answer to the question:
1701 * "Why not allow them to match if they are both NULL?"
1702 * See: https://bugzilla.mozilla.org/show_bug.cgi?id=1318633#c1
1703 */
1704 if ((configDir1 == NULL((void*)0)) || (configDir2 == NULL((void*)0))) {
1705 return PR_FALSE0;
1706 }
1707 if (strcmp(configDir1, configDir2) != 0) {
1708 return PR_FALSE0;
1709 }
1710 if (!secmod_matchPrefix(certPrefix1, certPrefix2)) {
1711 return PR_FALSE0;
1712 }
1713 if (!secmod_matchPrefix(keyPrefix1, keyPrefix2)) {
1714 return PR_FALSE0;
1715 }
1716 /* these last test -- if we just need the DB open read only,
1717 * than any open will suffice, but if we requested it read/write
1718 * and it's only open read only, we need to open it again */
1719 if (isReadOnly1) {
1720 return PR_TRUE1;
1721 }
1722 if (isReadOnly2) { /* isReadonly1 == PR_FALSE */
1723 return PR_FALSE0;
1724 }
1725 return PR_TRUE1;
1726}
1727
1728/*
1729 * return true if we are requesting a database that is already openned.
1730 */
1731PRBool
1732secmod_MatchConfigList(const char *spec, SECMODConfigList *conflist, int count)
1733{
1734 char *config;
1735 char *certPrefix;
1736 char *keyPrefix;
1737 PRBool isReadOnly;
1738 PRBool ret = PR_FALSE0;
1739 int i;
1740
1741 config = secmod_getConfigDir(spec, &certPrefix, &keyPrefix, &isReadOnly);
1742 if (!config) {
1743 goto done;
1744 }
1745
1746 /* NOTE: we dbm isn't multiple open safe. If we open the same database
1747 * twice from two different locations, then we can corrupt our database
1748 * (the cache will be inconsistent). Protect against this by claiming
1749 * for comparison only that we are always openning dbm databases read only.
1750 */
1751 if (secmod_configIsDBM(config)) {
1752 isReadOnly = 1;
1753 }
1754 for (i = 0; i < count; i++) {
1755 if (secmod_matchConfig(config, conflist[i].config, certPrefix,
1756 conflist[i].certPrefix, keyPrefix,
1757 conflist[i].keyPrefix, isReadOnly,
1758 conflist[i].isReadOnly)) {
1759 ret = PR_TRUE1;
1760 goto done;
1761 }
1762 }
1763
1764 ret = PR_FALSE0;
1765done:
1766 PORT_FreePORT_Free_Util(config);
1767 PORT_FreePORT_Free_Util(certPrefix);
1768 PORT_FreePORT_Free_Util(keyPrefix);
1769 return ret;
1770}
1771
1772/*
1773 * Find the slot id from the module spec. If the slot is the database slot, we
1774 * can get the slot id from the default database slot.
1775 */
1776CK_SLOT_ID
1777secmod_GetSlotIDFromModuleSpec(const char *moduleSpec, SECMODModule *module)
1778{
1779 char *tmp_spec = NULL((void*)0);
1780 char **children, **thisChild;
1781 CK_SLOT_ID *ids, *thisID, slotID = -1;
1782 char *inConfig = NULL((void*)0), *thisConfig = NULL((void*)0);
1783 char *inCertPrefix = NULL((void*)0), *thisCertPrefix = NULL((void*)0);
1784 char *inKeyPrefix = NULL((void*)0), *thisKeyPrefix = NULL((void*)0);
1785 PRBool inReadOnly, thisReadOnly;
1786
1787 inConfig = secmod_getConfigDir(moduleSpec, &inCertPrefix, &inKeyPrefix,
1788 &inReadOnly);
1789 if (!inConfig) {
1790 goto done;
1791 }
1792
1793 if (secmod_configIsDBM(inConfig)) {
1794 inReadOnly = 1;
1795 }
1796
1797 tmp_spec = secmod_ParseModuleSpecForTokens(PR_TRUE1, module->isFIPS,
1798 module->libraryParams, &children, &ids);
1799 if (tmp_spec == NULL((void*)0)) {
1800 goto done;
1801 }
1802
1803 /* first check to see if the parent is the database */
1804 thisConfig = secmod_getConfigDir(tmp_spec, &thisCertPrefix, &thisKeyPrefix,
1805 &thisReadOnly);
1806 if (!thisConfig) {
1807 goto done;
1808 }
1809 if (secmod_matchConfig(inConfig, thisConfig, inCertPrefix, thisCertPrefix,
1810 inKeyPrefix, thisKeyPrefix, inReadOnly, thisReadOnly)) {
1811 /* yup it's the default key slot, get the id for it */
1812 PK11SlotInfo *slot = PK11_GetInternalKeySlot();
1813 if (slot) {
1814 slotID = slot->slotID;
1815 PK11_FreeSlot(slot);
1816 }
1817 goto done;
1818 }
1819
1820 /* find id of the token */
1821 for (thisChild = children, thisID = ids; thisChild && *thisChild; thisChild++, thisID++) {
1822 PORT_FreePORT_Free_Util(thisConfig);
1823 PORT_FreePORT_Free_Util(thisCertPrefix);
1824 PORT_FreePORT_Free_Util(thisKeyPrefix);
1825 thisConfig = secmod_getConfigDir(*thisChild, &thisCertPrefix,
1826 &thisKeyPrefix, &thisReadOnly);
1827 if (thisConfig == NULL((void*)0)) {
1828 continue;
1829 }
1830 if (secmod_matchConfig(inConfig, thisConfig, inCertPrefix, thisCertPrefix,
1831 inKeyPrefix, thisKeyPrefix, inReadOnly, thisReadOnly)) {
1832 slotID = *thisID;
1833 break;
1834 }
1835 }
1836
1837done:
1838 PORT_FreePORT_Free_Util(inConfig);
1839 PORT_FreePORT_Free_Util(inCertPrefix);
1840 PORT_FreePORT_Free_Util(inKeyPrefix);
1841 PORT_FreePORT_Free_Util(thisConfig);
1842 PORT_FreePORT_Free_Util(thisCertPrefix);
1843 PORT_FreePORT_Free_Util(thisKeyPrefix);
1844 if (tmp_spec) {
1845 secmod_FreeChildren(children, ids);
1846 PORT_FreePORT_Free_Util(tmp_spec);
1847 }
1848 return slotID;
1849}
1850
1851void
1852secmod_FreeConfigList(SECMODConfigList *conflist, int count)
1853{
1854 int i;
1855 for (i = 0; i < count; i++) {
1856 PORT_FreePORT_Free_Util(conflist[i].config);
1857 PORT_FreePORT_Free_Util(conflist[i].certPrefix);
1858 PORT_FreePORT_Free_Util(conflist[i].keyPrefix);
1859 }
1860 PORT_FreePORT_Free_Util(conflist);
1861}
1862
1863void
1864secmod_FreeChildren(char **children, CK_SLOT_ID *ids)
1865{
1866 char **thisChild;
1867
1868 if (!children) {
1869 return;
1870 }
1871
1872 for (thisChild = children; thisChild && *thisChild; thisChild++) {
1873 PORT_FreePORT_Free_Util(*thisChild);
1874 }
1875 PORT_FreePORT_Free_Util(children);
1876 if (ids) {
1877 PORT_FreePORT_Free_Util(ids);
1878 }
1879 return;
1880}
1881
1882/*
1883 * caclulate the length of each child record:
1884 * " 0x{id}=<{escaped_child}>"
1885 */
1886static int
1887secmod_getChildLength(char *child, CK_SLOT_ID id)
1888{
1889 int length = NSSUTIL_DoubleEscapeSize(child, '>', ']');
1890 if (id == 0) {
1891 length++;
1892 }
1893 while (id) {
1894 length++;
1895 id = id >> 4;
1896 }
1897 length += 6; /* {sp}0x[id]=<{child}> */
1898 return length;
1899}
1900
1901/*
1902 * Build a child record:
1903 * " 0x{id}=<{escaped_child}>"
1904 */
1905static SECStatus
1906secmod_mkTokenChild(char **next, int *length, char *child, CK_SLOT_ID id)
1907{
1908 int len;
1909 char *escSpec;
1910
1911 len = PR_snprintf(*next, *length, " 0x%x=<", id);
1912 if (len < 0) {
1913 return SECFailure;
1914 }
1915 *next += len;
1916 *length -= len;
1917 escSpec = NSSUTIL_DoubleEscape(child, '>', ']');
1918 if (escSpec == NULL((void*)0)) {
1919 return SECFailure;
1920 }
1921 if (*child && (*escSpec == 0)) {
1922 PORT_FreePORT_Free_Util(escSpec);
1923 return SECFailure;
1924 }
1925 len = strlen(escSpec);
1926 if (len + 1 > *length) {
1927 PORT_FreePORT_Free_Util(escSpec);
1928 return SECFailure;
1929 }
1930 PORT_Memcpymemcpy(*next, escSpec, len);
1931 *next += len;
1932 *length -= len;
1933 PORT_FreePORT_Free_Util(escSpec);
1934 **next = '>';
1935 (*next)++;
1936 (*length)--;
1937 return SECSuccess;
1938}
1939
1940#define TOKEN_STRING" tokens=[" " tokens=["
1941
1942char *
1943secmod_MkAppendTokensList(PLArenaPool *arena, char *oldParam, char *newToken,
1944 CK_SLOT_ID newID, char **children, CK_SLOT_ID *ids)
1945{
1946 char *rawParam = NULL((void*)0); /* oldParam with tokens stripped off */
1947 char *newParam = NULL((void*)0); /* space for the return parameter */
1948 char *nextParam = NULL((void*)0); /* current end of the new parameter */
1949 char **oldChildren = NULL((void*)0);
1950 CK_SLOT_ID *oldIds = NULL((void*)0);
1951 void *mark = NULL((void*)0); /* mark the arena pool in case we need
1952 * to release it */
1953 int length, i, tmpLen;
1954 SECStatus rv;
1955
1956 /* first strip out and save the old tokenlist */
1957 rawParam = secmod_ParseModuleSpecForTokens(PR_FALSE0, PR_FALSE0,
1958 oldParam, &oldChildren, &oldIds);
1959 if (!rawParam) {
1960 goto loser;
1961 }
1962
1963 /* now calculate the total length of the new buffer */
1964 /* First the 'fixed stuff', length of rawparam (does not include a NULL),
1965 * length of the token string (does include the NULL), closing bracket */
1966 length = strlen(rawParam) + sizeof(TOKEN_STRING" tokens=[") + 1;
1967 /* now add then length of all the old children */
1968 for (i = 0; oldChildren && oldChildren[i]; i++) {
1969 length += secmod_getChildLength(oldChildren[i], oldIds[i]);
1970 }
1971
1972 /* add the new token */
1973 length += secmod_getChildLength(newToken, newID);
1974
1975 /* and it's new children */
1976 for (i = 0; children && children[i]; i++) {
1977 if (ids[i] == -1) {
1978 continue;
1979 }
1980 length += secmod_getChildLength(children[i], ids[i]);
1981 }
1982
1983 /* now allocate and build the string */
1984 mark = PORT_ArenaMarkPORT_ArenaMark_Util(arena);
1985 if (!mark) {
1986 goto loser;
1987 }
1988 newParam = PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, length);
1989 if (!newParam) {
1990 goto loser;
1991 }
1992
1993 PORT_Strcpystrcpy(newParam, rawParam);
1994 tmpLen = strlen(rawParam);
1995 nextParam = newParam + tmpLen;
1996 length -= tmpLen;
1997 PORT_Memcpymemcpy(nextParam, TOKEN_STRING" tokens=[", sizeof(TOKEN_STRING" tokens=[") - 1);
1998 nextParam += sizeof(TOKEN_STRING" tokens=[") - 1;
1999 length -= sizeof(TOKEN_STRING" tokens=[") - 1;
2000
2001 for (i = 0; oldChildren && oldChildren[i]; i++) {
2002 rv = secmod_mkTokenChild(&nextParam, &length, oldChildren[i], oldIds[i]);
2003 if (rv != SECSuccess) {
2004 goto loser;
2005 }
2006 }
2007
2008 rv = secmod_mkTokenChild(&nextParam, &length, newToken, newID);
2009 if (rv != SECSuccess) {
2010 goto loser;
2011 }
2012
2013 for (i = 0; children && children[i]; i++) {
2014 if (ids[i] == -1) {
2015 continue;
2016 }
2017 rv = secmod_mkTokenChild(&nextParam, &length, children[i], ids[i]);
2018 if (rv != SECSuccess) {
2019 goto loser;
2020 }
2021 }
2022
2023 if (length < 2) {
2024 goto loser;
2025 }
2026
2027 *nextParam++ = ']';
2028 *nextParam++ = 0;
2029
2030 /* we are going to return newParam now, don't release the mark */
2031 PORT_ArenaUnmarkPORT_ArenaUnmark_Util(arena, mark);
2032 mark = NULL((void*)0);
2033
2034loser:
2035 if (mark) {
2036 PORT_ArenaReleasePORT_ArenaRelease_Util(arena, mark);
2037 newParam = NULL((void*)0); /* if the mark is still active,
2038 * don't return the param */
2039 }
2040 if (rawParam) {
2041 PORT_FreePORT_Free_Util(rawParam);
2042 }
2043 if (oldChildren) {
2044 secmod_FreeChildren(oldChildren, oldIds);
2045 }
2046 return newParam;
2047}
2048
2049static char *
2050secmod_mkModuleSpec(SECMODModule *module)
2051{
2052 char *nss = NULL((void*)0), *modSpec = NULL((void*)0), **slotStrings = NULL((void*)0);
2053 int slotCount, i, si;
2054 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
2055
2056 /* allocate target slot info strings */
2057 slotCount = 0;
2058
2059 SECMOD_GetReadLock(moduleLock);
2060 if (module->slotCount) {
2061 for (i = 0; i < module->slotCount; i++) {
2062 if (module->slots[i]->defaultFlags != 0) {
2063 slotCount++;
2064 }
2065 }
2066 } else {
2067 slotCount = module->slotInfoCount;
2068 }
2069
2070 slotStrings = (char **)PORT_ZAllocPORT_ZAlloc_Util(slotCount * sizeof(char *));
2071 if (slotStrings == NULL((void*)0)) {
2072 SECMOD_ReleaseReadLock(moduleLock);
2073 goto loser;
2074 }
2075
2076 /* build the slot info strings */
2077 if (module->slotCount) {
2078 for (i = 0, si = 0; i < module->slotCount; i++) {
2079 if (module->slots[i]->defaultFlags) {
2080 PORT_Assert(si < slotCount)((si < slotCount) ? ((void)0) : PR_Assert("si < slotCount"
, "/root/firefox-clang/security/nss/lib/pk11wrap/pk11pars.c",
2080))
;
2081 if (si >= slotCount)
2082 break;
2083 slotStrings[si] = NSSUTIL_MkSlotString(module->slots[i]->slotID,
2084 module->slots[i]->defaultFlags,
2085 module->slots[i]->timeout,
2086 module->slots[i]->askpw,
2087 module->slots[i]->hasRootCerts,
2088 module->slots[i]->hasRootTrust);
2089 si++;
2090 }
2091 }
2092 } else {
2093 for (i = 0; i < slotCount; i++) {
2094 slotStrings[i] = NSSUTIL_MkSlotString(
2095 module->slotInfo[i].slotID,
2096 module->slotInfo[i].defaultFlags,
2097 module->slotInfo[i].timeout,
2098 module->slotInfo[i].askpw,
2099 module->slotInfo[i].hasRootCerts,
2100 module->slotInfo[i].hasRootTrust);
2101 }
2102 }
2103
2104 SECMOD_ReleaseReadLock(moduleLock);
2105 nss = NSSUTIL_MkNSSString(slotStrings, slotCount, module->internal,
2106 module->isFIPS, module->isModuleDB,
2107 module->moduleDBOnly, module->isCritical,
2108 module->trustOrder, module->cipherOrder,
2109 module->ssl[0], module->ssl[1]);
2110 modSpec = NSSUTIL_MkModuleSpec(module->dllName, module->commonName,
2111 module->libraryParams, nss);
2112 PORT_FreePORT_Free_Util(slotStrings);
2113 PR_smprintf_free(nss);
2114loser:
2115 return (modSpec);
2116}
2117
2118char **
2119SECMOD_GetModuleSpecList(SECMODModule *module)
2120{
2121 SECMODModuleDBFunc func = (SECMODModuleDBFunc)module->moduleDBFunc;
2122 if (func) {
2123 return (*func)(SECMOD_MODULE_DB_FUNCTION_FIND0,
2124 module->libraryParams, NULL((void*)0));
2125 }
2126 return NULL((void*)0);
2127}
2128
2129SECStatus
2130SECMOD_AddPermDB(SECMODModule *module)
2131{
2132 SECMODModuleDBFunc func;
2133 char *moduleSpec;
2134 char **retString;
2135
2136 if (module->parent == NULL((void*)0))
2137 return SECFailure;
2138
2139 func = (SECMODModuleDBFunc)module->parent->moduleDBFunc;
2140 if (func) {
2141 moduleSpec = secmod_mkModuleSpec(module);
2142 retString = (*func)(SECMOD_MODULE_DB_FUNCTION_ADD1,
2143 module->parent->libraryParams, moduleSpec);
2144 PORT_FreePORT_Free_Util(moduleSpec);
2145 if (retString != NULL((void*)0))
2146 return SECSuccess;
2147 }
2148 return SECFailure;
2149}
2150
2151SECStatus
2152SECMOD_DeletePermDB(SECMODModule *module)
2153{
2154 SECMODModuleDBFunc func;
2155 char *moduleSpec;
2156 char **retString;
2157
2158 if (module->parent == NULL((void*)0))
2159 return SECFailure;
2160
2161 func = (SECMODModuleDBFunc)module->parent->moduleDBFunc;
2162 if (func) {
2163 moduleSpec = secmod_mkModuleSpec(module);
2164 retString = (*func)(SECMOD_MODULE_DB_FUNCTION_DEL2,
2165 module->parent->libraryParams, moduleSpec);
2166 PORT_FreePORT_Free_Util(moduleSpec);
2167 if (retString != NULL((void*)0))
2168 return SECSuccess;
2169 }
2170 return SECFailure;
2171}
2172
2173SECStatus
2174SECMOD_FreeModuleSpecList(SECMODModule *module, char **moduleSpecList)
2175{
2176 SECMODModuleDBFunc func = (SECMODModuleDBFunc)module->moduleDBFunc;
2177 char **retString;
2178 if (func) {
2179 retString = (*func)(SECMOD_MODULE_DB_FUNCTION_RELEASE3,
2180 module->libraryParams, moduleSpecList);
2181 if (retString != NULL((void*)0))
2182 return SECSuccess;
2183 }
2184 return SECFailure;
2185}
2186
2187/*
2188 * load a PKCS#11 module but do not add it to the default NSS trust domain
2189 */
2190SECMODModule *
2191SECMOD_LoadModule(char *modulespec, SECMODModule *parent, PRBool recurse)
2192{
2193 char *library = NULL((void*)0), *moduleName = NULL((void*)0), *parameters = NULL((void*)0), *nss = NULL((void*)0);
2194 char *config = NULL((void*)0);
2195 SECStatus status;
2196 SECMODModule *module = NULL((void*)0);
2197 SECMODModule *oldModule = NULL((void*)0);
2198 SECStatus rv;
2199 PRBool forwardPolicyFeedback = PR_FALSE0;
2200 PRUint32 forwardPolicyCheckFlags;
2201
2202 /* initialize the underlying module structures */
2203 SECMOD_Init();
2204
2205 status = NSSUTIL_ArgParseModuleSpecEx(modulespec, &library, &moduleName,
2206 &parameters, &nss,
2207 &config);
2208 if (status != SECSuccess) {
2209 goto loser;
2210 }
2211
2212 module = SECMOD_CreateModuleEx(library, moduleName, parameters, nss, config);
2213 forwardPolicyFeedback = NSSUTIL_ArgHasFlag("flags", "printPolicyFeedback", nss);
2214 forwardPolicyCheckFlags = secmod_parsePolicyCheckFlags(nss);
2215
2216 if (library)
2217 PORT_FreePORT_Free_Util(library);
2218 if (moduleName)
2219 PORT_FreePORT_Free_Util(moduleName);
2220 if (parameters)
2221 PORT_FreePORT_Free_Util(parameters);
2222 if (nss)
2223 PORT_FreePORT_Free_Util(nss);
2224 if (config)
2225 PORT_FreePORT_Free_Util(config);
2226 if (!module) {
2227 goto loser;
2228 }
2229
2230 /* a policy only stanza doesn't actually get 'loaded'. policy has already
2231 * been parsed as a side effect of the CreateModuleEx call */
2232 if (secmod_PolicyOnly(module)) {
2233 return module;
2234 }
2235 if (parent) {
2236 module->parent = SECMOD_ReferenceModule(parent);
2237 if (module->internal && secmod_IsInternalKeySlot(parent)) {
2238 module->internal = parent->internal;
2239 }
2240 }
2241
2242 /* load it */
2243 rv = secmod_LoadPKCS11Module(module, &oldModule);
2244 if (rv != SECSuccess) {
2245 goto loser;
2246 }
2247
2248 /* if we just reload an old module, no need to add it to any lists.
2249 * we simple release all our references */
2250 if (oldModule) {
2251 /* This module already exists, don't link it anywhere. This
2252 * will probably destroy this module */
2253 SECMOD_DestroyModule(module);
2254 return oldModule;
2255 }
2256
2257 if (recurse && module->isModuleDB) {
2258 char **moduleSpecList;
2259 PORT_SetErrorPORT_SetError_Util(0);
2260
2261 moduleSpecList = SECMOD_GetModuleSpecList(module);
2262 if (moduleSpecList) {
2263 char **index;
2264
2265 index = moduleSpecList;
2266 if (*index && SECMOD_GetSkipFirstFlag(module)) {
2267 index++;
2268 }
2269
2270 for (; *index; index++) {
2271 SECMODModule *child;
2272 if (0 == PORT_Strcmpstrcmp(*index, modulespec)) {
2273 /* avoid trivial infinite recursion */
2274 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_NO_MODULE);
2275 rv = SECFailure;
2276 break;
2277 }
2278 if (!forwardPolicyFeedback) {
2279 child = SECMOD_LoadModule(*index, module, PR_TRUE1);
2280 } else {
2281 /* Add printPolicyFeedback to the nss flags */
2282 char *specWithForwards =
2283 NSSUTIL_AddNSSFlagToModuleSpec(*index, "printPolicyFeedback");
2284 char *tmp;
2285 if (forwardPolicyCheckFlags & SECMOD_FLAG_POLICY_CHECK_IDENTIFIER0x01) {
2286 tmp = NSSUTIL_AddNSSFlagToModuleSpec(specWithForwards, "policyCheckIdentifier");
2287 PORT_FreePORT_Free_Util(specWithForwards);
2288 specWithForwards = tmp;
2289 }
2290 if (forwardPolicyCheckFlags & SECMOD_FLAG_POLICY_CHECK_VALUE0x02) {
2291 tmp = NSSUTIL_AddNSSFlagToModuleSpec(specWithForwards, "policyCheckValue");
2292 PORT_FreePORT_Free_Util(specWithForwards);
2293 specWithForwards = tmp;
2294 }
2295 child = SECMOD_LoadModule(specWithForwards, module, PR_TRUE1);
2296 PORT_FreePORT_Free_Util(specWithForwards);
2297 }
2298 if (!child)
2299 break;
2300 if (child->isCritical && !child->loaded) {
2301 int err = PORT_GetErrorPORT_GetError_Util();
2302 if (!err)
2303 err = SEC_ERROR_NO_MODULE;
2304 SECMOD_DestroyModule(child);
2305 PORT_SetErrorPORT_SetError_Util(err);
2306 rv = SECFailure;
2307 break;
2308 }
2309 SECMOD_DestroyModule(child);
2310 }
2311 SECMOD_FreeModuleSpecList(module, moduleSpecList);
2312 } else {
2313 if (!PORT_GetErrorPORT_GetError_Util())
2314 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_NO_MODULE);
2315 rv = SECFailure;
2316 }
2317 }
2318
2319 if (rv != SECSuccess) {
2320 goto loser;
2321 }
2322
2323 /* inherit the reference */
2324 if (!module->moduleDBOnly) {
2325 SECMOD_AddModuleToList(module);
2326 } else {
2327 SECMOD_AddModuleToDBOnlyList(module);
2328 }
2329
2330 /* handle any additional work here */
2331 return module;
2332
2333loser:
2334 if (module) {
2335 if (module->loaded) {
2336 SECMOD_UnloadModule(module);
2337 }
2338 SECMOD_AddModuleToUnloadList(module);
2339 }
2340 return module;
2341}
2342
2343SECMODModule *
2344SECMOD_LoadModuleWithFunction(const char *moduleName, CK_C_GetFunctionList fentry)
2345{
2346 SECMODModule *module = NULL((void*)0);
2347 SECMODModule *oldModule = NULL((void*)0);
2348 SECStatus rv;
2349
2350 /* initialize the underlying module structures */
2351 SECMOD_Init();
2352
2353 module = secmod_NewModule();
2354 if (module == NULL((void*)0)) {
2355 goto loser;
2356 }
2357
2358 module->commonName = PORT_ArenaStrdupPORT_ArenaStrdup_Util(module->arena, moduleName ? moduleName : "");
2359 module->internal = PR_FALSE0;
2360 module->isFIPS = PR_FALSE0;
2361 /* if the system FIPS mode is enabled, force FIPS to be on */
2362 if (SECMOD_GetSystemFIPSEnabled()) {
2363 module->isFIPS = PR_TRUE1;
2364 }
2365
2366 module->isCritical = PR_FALSE0;
2367 /* new field */
2368 module->trustOrder = NSSUTIL_DEFAULT_TRUST_ORDER50;
2369 /* new field */
2370 module->cipherOrder = NSSUTIL_DEFAULT_CIPHER_ORDER0;
2371 /* new field */
2372 module->isModuleDB = PR_FALSE0;
2373 module->moduleDBOnly = PR_FALSE0;
2374
2375 module->ssl[0] = 0;
2376 module->ssl[1] = 0;
2377
2378 secmod_PrivateModuleCount++;
2379
2380 /* load it */
2381 rv = secmod_LoadPKCS11ModuleFromFunction(module, &oldModule, fentry);
2382 if (rv != SECSuccess) {
2383 goto loser;
2384 }
2385
2386 /* if we just reload an old module, no need to add it to any lists.
2387 * we simple release all our references */
2388 if (oldModule) {
2389 /* This module already exists, don't link it anywhere. This
2390 * will probably destroy this module */
2391 SECMOD_DestroyModule(module);
2392 return oldModule;
2393 }
2394
2395 SECMOD_AddModuleToList(module);
2396 /* handle any additional work here */
2397 return module;
2398
2399loser:
2400 if (module) {
2401 if (module->loaded) {
2402 SECMOD_UnloadModule(module);
2403 }
2404 SECMOD_AddModuleToUnloadList(module);
2405 }
2406 return module;
2407}
2408
2409/*
2410 * load a PKCS#11 module and add it to the default NSS trust domain
2411 */
2412SECMODModule *
2413SECMOD_LoadUserModule(char *modulespec, SECMODModule *parent, PRBool recurse)
2414{
2415 SECStatus rv = SECSuccess;
2416 SECMODModule *newmod = SECMOD_LoadModule(modulespec, parent, recurse);
2417 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
2418
2419 if (newmod) {
2420 SECMOD_GetReadLock(moduleLock);
2421 rv = STAN_AddModuleToDefaultTrustDomain(newmod);
2422 SECMOD_ReleaseReadLock(moduleLock);
2423 if (SECSuccess != rv) {
2424 SECMOD_DestroyModule(newmod);
2425 return NULL((void*)0);
2426 }
2427 }
2428 return newmod;
2429}
2430
2431SECMODModule *
2432SECMOD_LoadUserModuleWithFunction(const char *moduleName, CK_C_GetFunctionList fentry)
2433{
2434 SECStatus rv = SECSuccess;
2435 SECMODModule *newmod = SECMOD_LoadModuleWithFunction(moduleName, fentry);
2436 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
2437
2438 if (newmod) {
2439 SECMOD_GetReadLock(moduleLock);
2440 rv = STAN_AddModuleToDefaultTrustDomain(newmod);
2441 SECMOD_ReleaseReadLock(moduleLock);
2442 if (SECSuccess != rv) {
2443 SECMOD_DestroyModule(newmod);
2444 return NULL((void*)0);
2445 }
2446 }
2447 return newmod;
2448}
2449
2450/*
2451 * remove the PKCS#11 module from the default NSS trust domain, call
2452 * C_Finalize, and destroy the module structure
2453 */
2454SECStatus
2455SECMOD_UnloadUserModule(SECMODModule *mod)
2456{
2457 SECStatus rv = SECSuccess;
2458 int atype = 0;
2459 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
2460 if (!mod) {
2461 return SECFailure;
2462 }
2463
2464 SECMOD_GetReadLock(moduleLock);
2465 rv = STAN_RemoveModuleFromDefaultTrustDomain(mod);
2466 SECMOD_ReleaseReadLock(moduleLock);
2467 if (SECSuccess != rv) {
2468 return SECFailure;
2469 }
2470 return SECMOD_DeleteModuleEx(NULL((void*)0), mod, &atype, PR_FALSE0);
2471}