Bug Summary

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