Bug Summary

File:s/lib/softoken/pkcs11.c
Warning:line 4327, column 13
Value stored to 'rv' is never read

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 pkcs11.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 -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/softoken -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/softoken -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D SHLIB_SUFFIX="so" -D SHLIB_PREFIX="lib" -D SOFTOKEN_LIB_NAME="libsoftokn3.so" -D SHLIB_VERSION="3" -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/nss -I ../../../dist/private/nss -internal-isystem /usr/lib/llvm-18/lib/clang/18/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 -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c pkcs11.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 * This file implements PKCS 11 on top of our existing security modules
6 *
7 * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
8 * This implementation has two slots:
9 * slot 1 is our generic crypto support. It does not require login.
10 * It supports Public Key ops, and all they bulk ciphers and hashes.
11 * It can also support Private Key ops for imported Private keys. It does
12 * not have any token storage.
13 * slot 2 is our private key support. It requires a login before use. It
14 * can store Private Keys and Certs as token objects. Currently only private
15 * keys and their associated Certificates are saved on the token.
16 *
17 * In this implementation, session objects are only visible to the session
18 * that created or generated them.
19 */
20#include "seccomon.h"
21#include "secitem.h"
22#include "pkcs11.h"
23#include "pkcs11i.h"
24#include "softoken.h"
25#include "lowkeyi.h"
26#include "blapi.h"
27#include "secder.h"
28#include "secport.h"
29#include "secrng.h"
30#include "prtypes.h"
31#include "nspr.h"
32#include "softkver.h"
33#include "secoid.h"
34#include "sftkdb.h"
35#include "utilpars.h"
36#include "ec.h"
37#include "secasn1.h"
38#include "secerr.h"
39#include "lgglue.h"
40#include "kem.h"
41
42PRBool parentForkedAfterC_Initialize;
43
44#ifndef NO_FORK_CHECK
45
46PRBool sftkForkCheckDisabled;
47
48#if defined(CHECK_FORK_PTHREAD) || defined(CHECK_FORK_MIXED)
49PRBool forked = PR_FALSE0;
50#endif
51
52#if defined(CHECK_FORK_GETPID) || defined(CHECK_FORK_MIXED)
53#include <unistd.h>
54pid_t myPid;
55#endif
56
57#ifdef CHECK_FORK_MIXED
58#include <sys/systeminfo.h>
59PRBool usePthread_atfork;
60#endif
61
62#endif
63
64#ifdef XP_UNIX1
65#define LIB_PARAM_DEFAULT_FILE_LOCATION"/etc/nss/params.config" "/etc/nss/params.config"
66#endif
67
68#define LIB_PARAM_DEFAULT" configdir='' certPrefix='' keyPrefix='' secmod='' flags=noCertDB,noModDB " " configdir='' certPrefix='' keyPrefix='' secmod='' flags=noCertDB,noModDB "
69/*
70 * ******************** Static data *******************************
71 */
72
73/* The next three strings must be exactly 32 characters long */
74static char *manufacturerID = "Mozilla Foundation ";
75static char manufacturerID_space[33];
76static char *libraryDescription = "NSS Internal Crypto Services ";
77static char libraryDescription_space[33];
78
79/*
80 * In FIPS mode, we disallow login attempts for 1 second after a login
81 * failure so that there are at most 60 login attempts per minute.
82 */
83static PRIntervalTime loginWaitTime;
84
85#define __PASTE(x, y) x##y
86
87/*
88 * we renamed all our internal functions, get the correct
89 * definitions for them...
90 */
91#undef CK_PKCS11_FUNCTION_INFO
92#undef CK_NEED_ARG_LIST
93
94#define CK_PKCS11_3_0 1
95#define CK_EXTERNextern extern
96#define CK_PKCS11_FUNCTION_INFO(func) \
97 CK_RV __PASTE(NS, func)
98#define CK_NEED_ARG_LIST 1
99
100#include "pkcs11f.h"
101
102#ifndef NSS_FIPS_DISABLE
103/* ------------- forward declare all the FIPS functions ------------- */
104#undef CK_NEED_ARG_LIST
105#undef CK_PKCS11_FUNCTION_INFO
106
107#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F, name)
108#define CK_NEED_ARG_LIST 1
109
110#include "pkcs11f.h"
111#endif
112
113/* build the crypto module table */
114static CK_FUNCTION_LIST_3_0 sftk_funcList = {
115 { CRYPTOKI_VERSION_MAJOR3, CRYPTOKI_VERSION_MINOR0 },
116
117#undef CK_PKCS11_FUNCTION_INFO
118#undef CK_NEED_ARG_LIST
119
120#define CK_PKCS11_FUNCTION_INFO(func) \
121 __PASTE(NS, func) \
122 ,
123#include "pkcs11f.h"
124
125};
126
127/* need a special version of get info for version 2 which returns the version
128 * 2.4 version number */
129CK_RV NSC_GetInfoV2(CK_INFO_PTR pInfo);
130CK_RV NSC_GetMechanismInfoV2(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
131 CK_MECHANISM_INFO_PTR pInfo);
132
133/* build the crypto module table */
134static CK_FUNCTION_LIST sftk_funcList_v2 = {
135 { 2, 40 },
136
137#undef CK_PKCS11_3_0
138#define CK_PKCS_11_2_0_ONLY 1
139#undef CK_PKCS11_FUNCTION_INFO
140#undef CK_NEED_ARG_LIST
141#define C_GetInfo C_GetInfoV2
142#define C_GetMechanismInfo C_GetMechanismInfoV2
143
144#define CK_PKCS11_FUNCTION_INFO(func) \
145 __PASTE(NS, func) \
146 ,
147#include "pkcs11f.h"
148
149};
150
151#undef C_GetInfo
152#undef C_GetMechanismInfo
153#undef CK_PKCS_11_2_0_ONLY
154#undef CK_PKCS11_FUNCTION_INFO
155#undef CK_NEED_ARG_LIST
156
157#undef __PASTE
158
159CK_NSS_MODULE_FUNCTIONS sftk_module_funcList = {
160 { 1, 0 },
161 NSC_ModuleDBFunc
162};
163
164static CK_RV
165nsc_NSSGetFIPSStatus(CK_SESSION_HANDLE hSession,
166 CK_OBJECT_HANDLE hObject,
167 CK_ULONG ulOperationType,
168 CK_ULONG *pulFIPSStatus);
169CK_NSS_FIPS_FUNCTIONS sftk_fips_funcList = {
170 { 1, 0 },
171 nsc_NSSGetFIPSStatus
172};
173
174CK_NSS_KEM_FUNCTIONS sftk_kem_funcList = {
175 { 1, 0 },
176 NSC_Encapsulate,
177 NSC_Decapsulate
178};
179
180/*
181 * Array is orderd by default first
182 */
183static CK_INTERFACE nss_interfaces[] = {
184 { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_funcList, NSS_INTERFACE_FLAGS0x00000001UL },
185 { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_funcList_v2, NSS_INTERFACE_FLAGS0x00000001UL },
186 { (CK_UTF8CHAR_PTR) "Vendor NSS Module Interface", &sftk_module_funcList, NSS_INTERFACE_FLAGS0x00000001UL },
187 { (CK_UTF8CHAR_PTR) "Vendor NSS FIPS Interface", &sftk_fips_funcList, NSS_INTERFACE_FLAGS0x00000001UL },
188 { (CK_UTF8CHAR_PTR) "Vendor NSS KEM Interface", &sftk_kem_funcList, NSS_INTERFACE_FLAGS0x00000001UL }
189};
190/* must match the count of interfaces in nss_interfaces above */
191#define NSS_INTERFACE_COUNT5 5
192
193/* List of DES Weak Keys */
194typedef unsigned char desKey[8];
195static const desKey sftk_desWeakTable[] = {
196#ifdef noParity
197 /* weak */
198 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
199 { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e },
200 { 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 },
201 { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
202 /* semi-weak */
203 { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe },
204 { 0xfe, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0xfe },
205
206 { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 },
207 { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e },
208
209 { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x0f, 0x00, 0x0f },
210 { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 },
211
212 { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe },
213 { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e },
214
215 { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e },
216 { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 },
217
218 { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe },
219 { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 },
220#else
221 /* weak */
222 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
223 { 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e },
224 { 0xe0, 0xe0, 0xe0, 0xe0, 0xf1, 0xf1, 0xf1, 0xf1 },
225 { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
226
227 /* semi-weak */
228 { 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe },
229 { 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01 },
230
231 { 0x1f, 0xe0, 0x1f, 0xe0, 0x0e, 0xf1, 0x0e, 0xf1 },
232 { 0xe0, 0x1f, 0xe0, 0x1f, 0xf1, 0x0e, 0xf1, 0x0e },
233
234 { 0x01, 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1 },
235 { 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1, 0x01 },
236
237 { 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe },
238 { 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e },
239
240 { 0x01, 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e },
241 { 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e, 0x01 },
242
243 { 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe },
244 { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1 }
245#endif
246};
247
248static const int sftk_desWeakTableSize = sizeof(sftk_desWeakTable) /
249 sizeof(sftk_desWeakTable[0]);
250
251/* DES KEY Parity conversion table. Takes each byte/2 as an index, returns
252 * that byte with the proper parity bit set */
253static const unsigned char parityTable[256] = {
254 /* Even...0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e */
255 /* E */ 0x01, 0x02, 0x04, 0x07, 0x08, 0x0b, 0x0d, 0x0e,
256 /* Odd....0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e */
257 /* O */ 0x10, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, 0x1f,
258 /* Odd....0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e */
259 /* O */ 0x20, 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x2f,
260 /* Even...0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e */
261 /* E */ 0x31, 0x32, 0x34, 0x37, 0x38, 0x3b, 0x3d, 0x3e,
262 /* Odd....0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e */
263 /* O */ 0x40, 0x43, 0x45, 0x46, 0x49, 0x4a, 0x4c, 0x4f,
264 /* Even...0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e */
265 /* E */ 0x51, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d, 0x5e,
266 /* Even...0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e */
267 /* E */ 0x61, 0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x6e,
268 /* Odd....0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e */
269 /* O */ 0x70, 0x73, 0x75, 0x76, 0x79, 0x7a, 0x7c, 0x7f,
270 /* Odd....0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e */
271 /* O */ 0x80, 0x83, 0x85, 0x86, 0x89, 0x8a, 0x8c, 0x8f,
272 /* Even...0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e */
273 /* E */ 0x91, 0x92, 0x94, 0x97, 0x98, 0x9b, 0x9d, 0x9e,
274 /* Even...0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae */
275 /* E */ 0xa1, 0xa2, 0xa4, 0xa7, 0xa8, 0xab, 0xad, 0xae,
276 /* Odd....0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe */
277 /* O */ 0xb0, 0xb3, 0xb5, 0xb6, 0xb9, 0xba, 0xbc, 0xbf,
278 /* Even...0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce */
279 /* E */ 0xc1, 0xc2, 0xc4, 0xc7, 0xc8, 0xcb, 0xcd, 0xce,
280 /* Odd....0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde */
281 /* O */ 0xd0, 0xd3, 0xd5, 0xd6, 0xd9, 0xda, 0xdc, 0xdf,
282 /* Odd....0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee */
283 /* O */ 0xe0, 0xe3, 0xe5, 0xe6, 0xe9, 0xea, 0xec, 0xef,
284 /* Even...0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe */
285 /* E */ 0xf1, 0xf2, 0xf4, 0xf7, 0xf8, 0xfb, 0xfd, 0xfe
286};
287
288/* Mechanisms */
289struct mechanismList {
290 CK_MECHANISM_TYPE type;
291 CK_MECHANISM_INFO info;
292 PRBool privkey;
293};
294
295/*
296 * the following table includes a complete list of mechanism defined by
297 * PKCS #11 version 2.01. Those Mechanisms not supported by this PKCS #11
298 * module are ifdef'ed out.
299 */
300#define CKF_EN_DE0x00000100UL | 0x00000200UL CKF_ENCRYPT0x00000100UL | CKF_DECRYPT0x00000200UL
301#define CKF_WR_UN0x00020000UL | 0x00040000UL CKF_WRAP0x00020000UL | CKF_UNWRAP0x00040000UL
302#define CKF_SN_VR0x00000800UL | 0x00002000 CKF_SIGN0x00000800UL | CKF_VERIFY0x00002000
303#define CKF_SN_RE0x00001000UL | 0x00004000UL CKF_SIGN_RECOVER0x00001000UL | CKF_VERIFY_RECOVER0x00004000UL
304#define CKF_EN_DE_MSG0x00000100UL | 0x00000200UL | 0x00000002UL | 0x00000004UL CKF_ENCRYPT0x00000100UL | CKF_DECRYPT0x00000200UL | CKF_MESSAGE_ENCRYPT0x00000002UL | CKF_MESSAGE_DECRYPT0x00000004UL
305
306#define CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL CKF_EN_DE0x00000100UL | 0x00000200UL | CKF_WR_UN0x00020000UL | 0x00040000UL
307#define CKF_SN_VR_RE0x00000800UL | 0x00002000 | 0x00001000UL | 0x00004000UL CKF_SN_VR0x00000800UL | 0x00002000 | CKF_SN_RE0x00001000UL | 0x00004000UL
308#define CKF_DUZ_IT_ALL0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL | 0x00000800UL
| 0x00002000 | 0x00001000UL | 0x00004000UL
CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL | CKF_SN_VR_RE0x00000800UL | 0x00002000 | 0x00001000UL | 0x00004000UL
309
310#define CKF_EC_PNU0x00100000UL | 0x00800000UL | 0x01000000UL CKF_EC_F_P0x00100000UL | CKF_EC_NAMEDCURVE0x00800000UL | CKF_EC_UNCOMPRESS0x01000000UL
311
312#define CKF_EC_BPNU0x00200000UL | 0x00100000UL | 0x00800000UL | 0x01000000UL CKF_EC_F_2M0x00200000UL | CKF_EC_PNU0x00100000UL | 0x00800000UL | 0x01000000UL
313#define CKF_EC_POC0x00100000UL | 0x00800000UL | 0x02000000UL CKF_EC_F_P0x00100000UL | CKF_EC_OID0x00800000UL | CKF_EC_COMPRESS0x02000000UL
314
315#define CK_MAX0xffffffff 0xffffffff
316
317static const struct mechanismList mechanisms[] = {
318
319 /*
320 * PKCS #11 Mechanism List.
321 *
322 * The first argument is the PKCS #11 Mechanism we support.
323 * The second argument is Mechanism info structure. It includes:
324 * The minimum key size,
325 * in bits for RSA, DSA, DH, EC*, KEA, RC2 and RC4 * algs.
326 * in bytes for RC5, AES, Camellia, and CAST*
327 * ignored for DES*, IDEA and FORTEZZA based
328 * The maximum key size,
329 * in bits for RSA, DSA, DH, EC*, KEA, RC2 and RC4 * algs.
330 * in bytes for RC5, AES, Camellia, and CAST*
331 * ignored for DES*, IDEA and FORTEZZA based
332 * Flags
333 * What operations are supported by this mechanism.
334 * The third argument is a bool which tells if this mechanism is
335 * supported in the database token.
336 *
337 */
338
339 /* ------------------------- RSA Operations ---------------------------*/
340 { CKM_RSA_PKCS_KEY_PAIR_GEN0x00000000UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_GENERATE_KEY_PAIR0x00010000UL }, PR_TRUE1 },
341 { CKM_RSA_PKCS0x00000001UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_DUZ_IT_ALL0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL | 0x00000800UL
| 0x00002000 | 0x00001000UL | 0x00004000UL
}, PR_TRUE1 },
342 { CKM_RSA_PKCS_PSS0x0000000DUL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
343 { CKM_RSA_PKCS_OAEP0x00000009UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
344#ifdef SFTK_RSA9796_SUPPORTED
345 { CKM_RSA_97960x00000002UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_DUZ_IT_ALL0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL | 0x00000800UL
| 0x00002000 | 0x00001000UL | 0x00004000UL
}, PR_TRUE1 },
346#endif
347 { CKM_RSA_X_5090x00000003UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_DUZ_IT_ALL0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL | 0x00000800UL
| 0x00002000 | 0x00001000UL | 0x00004000UL
}, PR_TRUE1 },
348 /* -------------- RSA Multipart Signing Operations -------------------- */
349 { CKM_MD2_RSA_PKCS0x00000004UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
350 { CKM_MD5_RSA_PKCS0x00000005UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
351 { CKM_SHA1_RSA_PKCS0x00000006UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
352 { CKM_SHA224_RSA_PKCS0x00000046UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
353 { CKM_SHA256_RSA_PKCS0x00000040UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
354 { CKM_SHA384_RSA_PKCS0x00000041UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
355 { CKM_SHA512_RSA_PKCS0x00000042UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
356 { CKM_SHA1_RSA_PKCS_PSS0x0000000EUL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
357 { CKM_SHA224_RSA_PKCS_PSS0x00000047UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
358 { CKM_SHA256_RSA_PKCS_PSS0x00000043UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
359 { CKM_SHA384_RSA_PKCS_PSS0x00000044UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
360 { CKM_SHA512_RSA_PKCS_PSS0x00000045UL, { RSA_MIN_MODULUS_BITS128, CK_MAX0xffffffff, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
361 /* ------------------------- DSA Operations --------------------------- */
362 { CKM_DSA_KEY_PAIR_GEN0x00000010UL, { DSA_MIN_P_BITS512, DSA_MAX_P_BITS3072, CKF_GENERATE_KEY_PAIR0x00010000UL }, PR_TRUE1 },
363 { CKM_DSA0x00000011UL, { DSA_MIN_P_BITS512, DSA_MAX_P_BITS3072, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
364 { CKM_DSA_PARAMETER_GEN0x00002000UL, { DSA_MIN_P_BITS512, DSA_MAX_P_BITS3072, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
365 { CKM_DSA_SHA10x00000012UL, { DSA_MIN_P_BITS512, DSA_MAX_P_BITS3072, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
366 { CKM_DSA_SHA2240x00000013UL, { DSA_MIN_P_BITS512, DSA_MAX_P_BITS3072, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
367 { CKM_DSA_SHA2560x00000014UL, { DSA_MIN_P_BITS512, DSA_MAX_P_BITS3072, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
368 { CKM_DSA_SHA3840x00000015UL, { DSA_MIN_P_BITS512, DSA_MAX_P_BITS3072, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
369 { CKM_DSA_SHA5120x00000016UL, { DSA_MIN_P_BITS512, DSA_MAX_P_BITS3072, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
370 /* -------------------- Diffie Hellman Operations --------------------- */
371 /* no diffie hellman yet */
372 { CKM_DH_PKCS_KEY_PAIR_GEN0x00000020UL, { DH_MIN_P_BITS128, DH_MAX_P_BITS16384, CKF_GENERATE_KEY_PAIR0x00010000UL }, PR_TRUE1 },
373 { CKM_DH_PKCS_DERIVE0x00000021UL, { DH_MIN_P_BITS128, DH_MAX_P_BITS16384, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
374 /* -------------------- Elliptic Curve Operations --------------------- */
375 { CKM_EC_KEY_PAIR_GEN0x00001040UL, { EC_MIN_KEY_BITS256, EC_MAX_KEY_BITS521, CKF_GENERATE_KEY_PAIR0x00010000UL | CKF_EC_BPNU0x00200000UL | 0x00100000UL | 0x00800000UL | 0x01000000UL }, PR_TRUE1 },
376 { CKM_ECDH1_DERIVE0x00001050UL, { EC_MIN_KEY_BITS256, EC_MAX_KEY_BITS521, CKF_DERIVE0x00080000UL | CKF_EC_BPNU0x00200000UL | 0x00100000UL | 0x00800000UL | 0x01000000UL }, PR_TRUE1 },
377 { CKM_ECDSA0x00001041UL, { EC_MIN_KEY_BITS256, EC_MAX_KEY_BITS521, CKF_SN_VR0x00000800UL | 0x00002000 | CKF_EC_BPNU0x00200000UL | 0x00100000UL | 0x00800000UL | 0x01000000UL }, PR_TRUE1 },
378 { CKM_ECDSA_SHA10x00001042UL, { EC_MIN_KEY_BITS256, EC_MAX_KEY_BITS521, CKF_SN_VR0x00000800UL | 0x00002000 | CKF_EC_BPNU0x00200000UL | 0x00100000UL | 0x00800000UL | 0x01000000UL }, PR_TRUE1 },
379 { CKM_ECDSA_SHA2240x00001043UL, { EC_MIN_KEY_BITS256, EC_MAX_KEY_BITS521, CKF_SN_VR0x00000800UL | 0x00002000 | CKF_EC_BPNU0x00200000UL | 0x00100000UL | 0x00800000UL | 0x01000000UL }, PR_TRUE1 },
380 { CKM_ECDSA_SHA2560x00001044UL, { EC_MIN_KEY_BITS256, EC_MAX_KEY_BITS521, CKF_SN_VR0x00000800UL | 0x00002000 | CKF_EC_BPNU0x00200000UL | 0x00100000UL | 0x00800000UL | 0x01000000UL }, PR_TRUE1 },
381 { CKM_ECDSA_SHA3840x00001045UL, { EC_MIN_KEY_BITS256, EC_MAX_KEY_BITS521, CKF_SN_VR0x00000800UL | 0x00002000 | CKF_EC_BPNU0x00200000UL | 0x00100000UL | 0x00800000UL | 0x01000000UL }, PR_TRUE1 },
382 { CKM_ECDSA_SHA5120x00001046UL, { EC_MIN_KEY_BITS256, EC_MAX_KEY_BITS521, CKF_SN_VR0x00000800UL | 0x00002000 | CKF_EC_BPNU0x00200000UL | 0x00100000UL | 0x00800000UL | 0x01000000UL }, PR_TRUE1 },
383 { CKM_EC_EDWARDS_KEY_PAIR_GEN0x00001055UL, { ECD_MIN_KEY_BITS255, ECD_MAX_KEY_BITS255, CKF_GENERATE_KEY_PAIR0x00010000UL }, PR_TRUE1 },
384 { CKM_EDDSA0x00001057UL, { ECD_MIN_KEY_BITS255, ECD_MAX_KEY_BITS255, CKF_SN_VR0x00000800UL | 0x00002000 | CKF_EC_POC0x00100000UL | 0x00800000UL | 0x02000000UL }, PR_TRUE1 },
385 /* ------------------------- RC2 Operations --------------------------- */
386 { CKM_RC2_KEY_GEN0x00000100UL, { 1, 128, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
387 { CKM_RC2_ECB0x00000101UL, { 1, 128, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
388 { CKM_RC2_CBC0x00000102UL, { 1, 128, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
389 { CKM_RC2_MAC0x00000103UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
390 { CKM_RC2_MAC_GENERAL0x00000104UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
391 { CKM_RC2_CBC_PAD0x00000105UL, { 1, 128, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
392 /* ------------------------- RC4 Operations --------------------------- */
393 { CKM_RC4_KEY_GEN0x00000110UL, { 1, 256, CKF_GENERATE0x00008000UL }, PR_FALSE0 },
394 { CKM_RC40x00000111UL, { 1, 256, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_FALSE0 },
395 /* ------------------------- DES Operations --------------------------- */
396 { CKM_DES_KEY_GEN0x00000120UL, { 8, 8, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
397 { CKM_DES_ECB0x00000121UL, { 8, 8, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
398 { CKM_DES_CBC0x00000122UL, { 8, 8, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
399 { CKM_DES_MAC0x00000123UL, { 8, 8, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
400 { CKM_DES_MAC_GENERAL0x00000124UL, { 8, 8, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
401 { CKM_DES_CBC_PAD0x00000125UL, { 8, 8, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
402 { CKM_DES2_KEY_GEN0x00000130UL, { 24, 24, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
403 { CKM_DES3_KEY_GEN0x00000131UL, { 24, 24, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
404 { CKM_DES3_ECB0x00000132UL, { 24, 24, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
405 { CKM_DES3_CBC0x00000133UL, { 24, 24, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
406 { CKM_DES3_MAC0x00000134UL, { 24, 24, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
407 { CKM_DES3_MAC_GENERAL0x00000135UL, { 24, 24, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
408 { CKM_DES3_CBC_PAD0x00000136UL, { 24, 24, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
409 /* ------------------------- CDMF Operations --------------------------- */
410 { CKM_CDMF_KEY_GEN0x00000140UL, { 8, 8, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
411 { CKM_CDMF_ECB0x00000141UL, { 8, 8, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
412 { CKM_CDMF_CBC0x00000142UL, { 8, 8, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
413 { CKM_CDMF_MAC0x00000143UL, { 8, 8, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
414 { CKM_CDMF_MAC_GENERAL0x00000144UL, { 8, 8, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
415 { CKM_CDMF_CBC_PAD0x00000145UL, { 8, 8, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
416 /* ------------------------- AES Operations --------------------------- */
417 { CKM_AES_KEY_GEN0x00001080UL, { 16, 32, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
418 { CKM_AES_ECB0x00001081UL, { 16, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
419 { CKM_AES_CBC0x00001082UL, { 16, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
420 { CKM_AES_MAC0x00001083UL, { 16, 32, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
421 { CKM_AES_MAC_GENERAL0x00001084UL, { 16, 32, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
422 { CKM_AES_CMAC0x0000108AUL, { 16, 32, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
423 { CKM_AES_CMAC_GENERAL0x0000108BUL, { 16, 32, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
424 { CKM_AES_CBC_PAD0x00001085UL, { 16, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
425 { CKM_AES_CTS0x00001089UL, { 16, 32, CKF_EN_DE0x00000100UL | 0x00000200UL }, PR_TRUE1 },
426 { CKM_AES_CTR0x00001086UL, { 16, 32, CKF_EN_DE0x00000100UL | 0x00000200UL }, PR_TRUE1 },
427 { CKM_AES_GCM0x00001087UL, { 16, 32, CKF_EN_DE_MSG0x00000100UL | 0x00000200UL | 0x00000002UL | 0x00000004UL }, PR_TRUE1 },
428 { CKM_AES_XCBC_MAC_960x0000108DUL, { 12, 12, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
429 { CKM_AES_XCBC_MAC0x0000108CUL, { 16, 16, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
430 /* ------------------------- Camellia Operations --------------------- */
431 { CKM_CAMELLIA_KEY_GEN0x00000550UL, { 16, 32, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
432 { CKM_CAMELLIA_ECB0x00000551UL, { 16, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
433 { CKM_CAMELLIA_CBC0x00000552UL, { 16, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
434 { CKM_CAMELLIA_MAC0x00000553UL, { 16, 32, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
435 { CKM_CAMELLIA_MAC_GENERAL0x00000554UL, { 16, 32, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
436 { CKM_CAMELLIA_CBC_PAD0x00000555UL, { 16, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
437/* ------------------------- SEED Operations --------------------------- */
438#ifndef NSS_DISABLE_DEPRECATED_SEED
439 { CKM_SEED_KEY_GEN0x00000650UL, { 16, 16, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
440 { CKM_SEED_ECB0x00000651UL, { 16, 16, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
441 { CKM_SEED_CBC0x00000652UL, { 16, 16, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
442 { CKM_SEED_MAC0x00000653UL, { 16, 16, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
443 { CKM_SEED_MAC_GENERAL0x00000654UL, { 16, 16, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
444 { CKM_SEED_CBC_PAD0x00000655UL, { 16, 16, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
445#endif
446/* ------------------------- ChaCha20 Operations ---------------------- */
447#ifndef NSS_DISABLE_CHACHAPOLY
448 { CKM_NSS_CHACHA20_KEY_GEN((0x80000000UL | 0x4E534350) + 27), { 32, 32, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
449 { CKM_NSS_CHACHA20_POLY1305((0x80000000UL | 0x4E534350) + 28), { 32, 32, CKF_EN_DE0x00000100UL | 0x00000200UL }, PR_TRUE1 },
450 { CKM_NSS_CHACHA20_CTR((0x80000000UL | 0x4E534350) + 33), { 32, 32, CKF_EN_DE0x00000100UL | 0x00000200UL }, PR_TRUE1 },
451 { CKM_CHACHA20_KEY_GEN0x00001225UL, { 32, 32, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
452 { CKM_CHACHA200x00001226UL, { 32, 32, CKF_EN_DE0x00000100UL | 0x00000200UL }, PR_TRUE1 },
453 { CKM_CHACHA20_POLY13050x00004021UL, { 32, 32, CKF_EN_DE_MSG0x00000100UL | 0x00000200UL | 0x00000002UL | 0x00000004UL }, PR_TRUE1 },
454#endif /* NSS_DISABLE_CHACHAPOLY */
455 /* ------------------------- Hashing Operations ----------------------- */
456 { CKM_MD20x00000200UL, { 0, 0, CKF_DIGEST0x00000400UL }, PR_FALSE0 },
457 { CKM_MD2_HMAC0x00000201UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
458 { CKM_MD2_HMAC_GENERAL0x00000202UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
459 { CKM_MD50x00000210UL, { 0, 0, CKF_DIGEST0x00000400UL }, PR_FALSE0 },
460 { CKM_MD5_HMAC0x00000211UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
461 { CKM_MD5_HMAC_GENERAL0x00000212UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
462 { CKM_SHA_10x00000220UL, { 0, 0, CKF_DIGEST0x00000400UL }, PR_FALSE0 },
463 { CKM_SHA_1_HMAC0x00000221UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
464 { CKM_SHA_1_HMAC_GENERAL0x00000222UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
465 { CKM_SHA2240x00000255UL, { 0, 0, CKF_DIGEST0x00000400UL }, PR_FALSE0 },
466 { CKM_SHA224_HMAC0x00000256UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
467 { CKM_SHA224_HMAC_GENERAL0x00000257UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
468 { CKM_SHA2560x00000250UL, { 0, 0, CKF_DIGEST0x00000400UL }, PR_FALSE0 },
469 { CKM_SHA256_HMAC0x00000251UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
470 { CKM_SHA256_HMAC_GENERAL0x00000252UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
471 { CKM_SHA3840x00000260UL, { 0, 0, CKF_DIGEST0x00000400UL }, PR_FALSE0 },
472 { CKM_SHA384_HMAC0x00000261UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
473 { CKM_SHA384_HMAC_GENERAL0x00000262UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
474 { CKM_SHA5120x00000270UL, { 0, 0, CKF_DIGEST0x00000400UL }, PR_FALSE0 },
475 { CKM_SHA512_HMAC0x00000271UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
476 { CKM_SHA512_HMAC_GENERAL0x00000272UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
477 { CKM_SHA3_2240x000002B5UL, { 0, 0, CKF_DIGEST0x00000400UL }, PR_FALSE0 },
478 { CKM_SHA3_224_HMAC0x000002B6UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
479 { CKM_SHA3_224_HMAC_GENERAL0x000002B7UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
480 { CKM_SHA3_2560x000002B0UL, { 0, 0, CKF_DIGEST0x00000400UL }, PR_FALSE0 },
481 { CKM_SHA3_256_HMAC0x000002B1UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
482 { CKM_SHA3_256_HMAC_GENERAL0x000002B2UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
483 { CKM_SHA3_3840x000002C0UL, { 0, 0, CKF_DIGEST0x00000400UL }, PR_FALSE0 },
484 { CKM_SHA3_384_HMAC0x000002C1UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
485 { CKM_SHA3_384_HMAC_GENERAL0x000002C2UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
486 { CKM_SHA3_5120x000002D0UL, { 0, 0, CKF_DIGEST0x00000400UL }, PR_FALSE0 },
487 { CKM_SHA3_512_HMAC0x000002D1UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
488 { CKM_SHA3_512_HMAC_GENERAL0x000002D2UL, { 1, 128, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
489 { CKM_TLS_PRF_GENERAL0x80000373UL, { 0, 512, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_FALSE0 },
490 { CKM_TLS_MAC0x000003E4UL, { 0, 512, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_FALSE0 },
491 { CKM_NSS_TLS_PRF_GENERAL_SHA256((0x80000000UL | 0x4E534350) + 21),
492 { 0, 512, CKF_SN_VR0x00000800UL | 0x00002000 },
493 PR_FALSE0 },
494 /* ------------------------- HKDF Operations -------------------------- */
495 { CKM_HKDF_DERIVE0x0000402aUL, { 1, 255 * 64, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
496 { CKM_HKDF_DATA0x0000402bUL, { 1, 255 * 64, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
497 { CKM_HKDF_KEY_GEN0x0000402cUL, { 20, 64, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
498 { CKM_NSS_HKDF_SHA1((0x80000000UL | 0x4E534350) + 3), { 1, 128, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
499 { CKM_NSS_HKDF_SHA256((0x80000000UL | 0x4E534350) + 4), { 1, 128, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
500 { CKM_NSS_HKDF_SHA384((0x80000000UL | 0x4E534350) + 5), { 1, 128, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
501 { CKM_NSS_HKDF_SHA512((0x80000000UL | 0x4E534350) + 6), { 1, 128, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
502/* ------------------------- CAST Operations --------------------------- */
503#ifdef NSS_SOFTOKEN_DOES_CAST
504 /* Cast operations are not supported ( yet? ) */
505 { CKM_CAST_KEY_GEN0x00000300UL, { 1, 8, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
506 { CKM_CAST_ECB0x00000301UL, { 1, 8, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
507 { CKM_CAST_CBC0x00000302UL, { 1, 8, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
508 { CKM_CAST_MAC0x00000303UL, { 1, 8, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
509 { CKM_CAST_MAC_GENERAL0x00000304UL, { 1, 8, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
510 { CKM_CAST_CBC_PAD0x00000305UL, { 1, 8, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
511 { CKM_CAST3_KEY_GEN0x00000310UL, { 1, 16, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
512 { CKM_CAST3_ECB0x00000311UL, { 1, 16, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
513 { CKM_CAST3_CBC0x00000312UL, { 1, 16, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
514 { CKM_CAST3_MAC0x00000313UL, { 1, 16, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
515 { CKM_CAST3_MAC_GENERAL0x00000314UL, { 1, 16, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
516 { CKM_CAST3_CBC_PAD0x00000315UL, { 1, 16, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
517 { CKM_CAST5_KEY_GEN0x00000320UL, { 1, 16, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
518 { CKM_CAST5_ECB0x00000321UL, { 1, 16, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
519 { CKM_CAST5_CBC0x00000322UL, { 1, 16, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
520 { CKM_CAST5_MAC0x00000323UL, { 1, 16, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
521 { CKM_CAST5_MAC_GENERAL0x00000324UL, { 1, 16, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
522 { CKM_CAST5_CBC_PAD0x00000325UL, { 1, 16, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
523#endif
524#if NSS_SOFTOKEN_DOES_RC5
525 /* ------------------------- RC5 Operations --------------------------- */
526 { CKM_RC5_KEY_GEN0x00000330UL, { 1, 32, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
527 { CKM_RC5_ECB0x00000331UL, { 1, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
528 { CKM_RC5_CBC0x00000332UL, { 1, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
529 { CKM_RC5_MAC0x00000333UL, { 1, 32, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
530 { CKM_RC5_MAC_GENERAL0x00000334UL, { 1, 32, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
531 { CKM_RC5_CBC_PAD0x00000335UL, { 1, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
532#endif
533#ifdef NSS_SOFTOKEN_DOES_IDEA
534 /* ------------------------- IDEA Operations -------------------------- */
535 { CKM_IDEA_KEY_GEN0x00000340UL, { 16, 16, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
536 { CKM_IDEA_ECB0x00000341UL, { 16, 16, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
537 { CKM_IDEA_CBC0x00000342UL, { 16, 16, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
538 { CKM_IDEA_MAC0x00000343UL, { 16, 16, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
539 { CKM_IDEA_MAC_GENERAL0x00000344UL, { 16, 16, CKF_SN_VR0x00000800UL | 0x00002000 }, PR_TRUE1 },
540 { CKM_IDEA_CBC_PAD0x00000345UL, { 16, 16, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
541#endif
542 /* --------------------- Secret Key Operations ------------------------ */
543 { CKM_GENERIC_SECRET_KEY_GEN0x00000350UL, { 1, 32, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
544 { CKM_CONCATENATE_BASE_AND_KEY0x00000360UL, { 1, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
545 { CKM_CONCATENATE_BASE_AND_DATA0x00000362UL, { 1, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
546 { CKM_CONCATENATE_DATA_AND_BASE0x00000363UL, { 1, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
547 { CKM_XOR_BASE_AND_DATA0x00000364UL, { 1, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
548 { CKM_EXTRACT_KEY_FROM_KEY0x00000365UL, { 1, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
549 { CKM_DES3_ECB_ENCRYPT_DATA0x00001102UL, { 1, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
550 { CKM_DES3_CBC_ENCRYPT_DATA0x00001103UL, { 1, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
551 { CKM_AES_ECB_ENCRYPT_DATA0x00001104UL, { 1, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
552 { CKM_AES_CBC_ENCRYPT_DATA0x00001105UL, { 1, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
553 { CKM_CAMELLIA_ECB_ENCRYPT_DATA0x00000556UL, { 1, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
554 { CKM_CAMELLIA_CBC_ENCRYPT_DATA0x00000557UL, { 1, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
555#ifndef NSS_DISABLE_DEPRECATED_SEED
556 { CKM_SEED_ECB_ENCRYPT_DATA0x00000656UL, { 1, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
557 { CKM_SEED_CBC_ENCRYPT_DATA0x00000657UL, { 1, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
558#endif
559 /* ---------------------- SSL Key Derivations ------------------------- */
560 { CKM_SSL3_PRE_MASTER_KEY_GEN0x00000370UL, { 48, 48, CKF_GENERATE0x00008000UL }, PR_FALSE0 },
561 { CKM_SSL3_MASTER_KEY_DERIVE0x00000371UL, { 48, 48, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
562 { CKM_SSL3_MASTER_KEY_DERIVE_DH0x00000373UL, { 8, 128, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
563 { CKM_SSL3_KEY_AND_MAC_DERIVE0x00000372UL, { 48, 48, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
564 { CKM_SSL3_MD5_MAC0x00000380UL, { 0, 16, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
565 { CKM_SSL3_SHA1_MAC0x00000381UL, { 0, 20, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
566 { CKM_MD5_KEY_DERIVATION0x00000390UL, { 0, 16, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
567 { CKM_MD2_KEY_DERIVATION0x00000391UL, { 0, 16, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
568 { CKM_SHA1_KEY_DERIVATION0x00000392UL, { 0, 20, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
569 { CKM_SHA224_KEY_DERIVATION0x00000396UL, { 0, 28, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
570 { CKM_SHA256_KEY_DERIVATION0x00000393UL, { 0, 32, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
571 { CKM_SHA384_KEY_DERIVATION0x00000394UL, { 0, 48, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
572 { CKM_SHA512_KEY_DERIVATION0x00000395UL, { 0, 64, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
573 { CKM_TLS_MASTER_KEY_DERIVE0x00000375UL, { 48, 48, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
574 { CKM_TLS12_MASTER_KEY_DERIVE0x000003E0UL, { 48, 48, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
575 { CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 22),
576 { 48, 48, CKF_DERIVE0x00080000UL },
577 PR_FALSE0 },
578 { CKM_TLS_MASTER_KEY_DERIVE_DH0x00000377UL, { 8, 128, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
579 { CKM_TLS12_MASTER_KEY_DERIVE_DH0x000003E2UL, { 8, 128, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
580 { CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256((0x80000000UL | 0x4E534350) + 24),
581 { 8, 128, CKF_DERIVE0x00080000UL },
582 PR_FALSE0 },
583 { CKM_TLS_KEY_AND_MAC_DERIVE0x00000376UL, { 48, 48, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
584 { CKM_TLS12_KEY_AND_MAC_DERIVE0x000003E1UL, { 48, 48, CKF_DERIVE0x00080000UL }, PR_FALSE0 },
585 { CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 23),
586 { 48, 48, CKF_DERIVE0x00080000UL },
587 PR_FALSE0 },
588 { CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE((0x80000000UL | 0x4E534350) + 25),
589 { 48, 128, CKF_DERIVE0x00080000UL },
590 PR_FALSE0 },
591 { CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH((0x80000000UL | 0x4E534350) + 26),
592 { 48, 128, CKF_DERIVE0x00080000UL },
593 PR_FALSE0 },
594 /* ---------------------- PBE Key Derivations ------------------------ */
595 { CKM_PBE_MD2_DES_CBC0x000003A0UL, { 8, 8, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
596 { CKM_PBE_MD5_DES_CBC0x000003A1UL, { 8, 8, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
597 /* ------------------ NSS PBE Key Derivations ------------------- */
598 { CKM_NSS_PBE_SHA1_DES_CBC0x80000002UL, { 8, 8, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
599 { CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC0x80000008UL, { 24, 24, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
600 { CKM_PBE_SHA1_DES3_EDE_CBC0x000003A8UL, { 24, 24, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
601 { CKM_PBE_SHA1_DES2_EDE_CBC0x000003A9UL, { 24, 24, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
602 { CKM_PBE_SHA1_RC2_40_CBC0x000003ABUL, { 40, 40, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
603 { CKM_PBE_SHA1_RC2_128_CBC0x000003AAUL, { 128, 128, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
604 { CKM_PBE_SHA1_RC4_400x000003A7UL, { 40, 40, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
605 { CKM_PBE_SHA1_RC4_1280x000003A6UL, { 128, 128, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
606 { CKM_PBA_SHA1_WITH_SHA1_HMAC0x000003C0UL, { 20, 20, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
607 { CKM_PKCS5_PBKD20x000003B0UL, { 1, 256, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
608 { CKM_NSS_PBE_SHA1_HMAC_KEY_GEN0x80000009UL, { 20, 20, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
609 { CKM_NSS_PBE_MD5_HMAC_KEY_GEN0x8000000aUL, { 16, 16, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
610 { CKM_NSS_PBE_MD2_HMAC_KEY_GEN0x8000000bUL, { 16, 16, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
611 { CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 29), { 28, 28, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
612 { CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 30), { 32, 32, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
613 { CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 31), { 48, 48, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
614 { CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 32), { 64, 64, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
615 /* ------------------ NIST 800-108 Key Derivations ------------------- */
616 { CKM_SP800_108_COUNTER_KDF0x000003acUL, { 0, CK_MAX0xffffffff, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
617 { CKM_SP800_108_FEEDBACK_KDF0x000003adUL, { 0, CK_MAX0xffffffff, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
618 { CKM_SP800_108_DOUBLE_PIPELINE_KDF0x000003aeUL, { 0, CK_MAX0xffffffff, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
619 { CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 42), { 0, CK_MAX0xffffffff, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
620 { CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 43), { 0, CK_MAX0xffffffff, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
621 { CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 44), { 0, CK_MAX0xffffffff, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
622 /* ------------------ AES Key Wrap (also encrypt) ------------------- */
623 { CKM_NSS_AES_KEY_WRAP((0x80000000UL | 0x4E534350) + 1), { 16, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
624 { CKM_NSS_AES_KEY_WRAP_PAD((0x80000000UL | 0x4E534350) + 2), { 16, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
625 { CKM_AES_KEY_WRAP0x00002109UL, { 16, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
626 { CKM_AES_KEY_WRAP_PAD0x0000210AUL, { 16, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
627 { CKM_AES_KEY_WRAP_KWP0x0000210BUL, { 1, 32, CKF_EN_DE_WR_UN0x00000100UL | 0x00000200UL | 0x00020000UL | 0x00040000UL }, PR_TRUE1 },
628 /* --------------------------- J-PAKE -------------------------------- */
629 { CKM_NSS_JPAKE_ROUND1_SHA1((0x80000000UL | 0x4E534350) + 7), { 0, 0, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
630 { CKM_NSS_JPAKE_ROUND1_SHA256((0x80000000UL | 0x4E534350) + 8), { 0, 0, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
631 { CKM_NSS_JPAKE_ROUND1_SHA384((0x80000000UL | 0x4E534350) + 9), { 0, 0, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
632 { CKM_NSS_JPAKE_ROUND1_SHA512((0x80000000UL | 0x4E534350) + 10), { 0, 0, CKF_GENERATE0x00008000UL }, PR_TRUE1 },
633 { CKM_NSS_JPAKE_ROUND2_SHA1((0x80000000UL | 0x4E534350) + 11), { 0, 0, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
634 { CKM_NSS_JPAKE_ROUND2_SHA256((0x80000000UL | 0x4E534350) + 12), { 0, 0, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
635 { CKM_NSS_JPAKE_ROUND2_SHA384((0x80000000UL | 0x4E534350) + 13), { 0, 0, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
636 { CKM_NSS_JPAKE_ROUND2_SHA512((0x80000000UL | 0x4E534350) + 14), { 0, 0, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
637 { CKM_NSS_JPAKE_FINAL_SHA1((0x80000000UL | 0x4E534350) + 15), { 0, 0, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
638 { CKM_NSS_JPAKE_FINAL_SHA256((0x80000000UL | 0x4E534350) + 16), { 0, 0, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
639 { CKM_NSS_JPAKE_FINAL_SHA384((0x80000000UL | 0x4E534350) + 17), { 0, 0, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
640 { CKM_NSS_JPAKE_FINAL_SHA512((0x80000000UL | 0x4E534350) + 18), { 0, 0, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
641 /* -------------------- Constant Time TLS MACs ----------------------- */
642 { CKM_NSS_HMAC_CONSTANT_TIME((0x80000000UL | 0x4E534350) + 19), { 0, 0, CKF_DIGEST0x00000400UL }, PR_TRUE1 },
643 { CKM_NSS_SSL3_MAC_CONSTANT_TIME((0x80000000UL | 0x4E534350) + 20), { 0, 0, CKF_DIGEST0x00000400UL }, PR_TRUE1 },
644 /* -------------------- IPSEC ----------------------- */
645 { CKM_NSS_IKE_PRF_PLUS_DERIVE((0x80000000UL | 0x4E534350) + 34), { 8, 255 * 64, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
646 { CKM_NSS_IKE_PRF_DERIVE((0x80000000UL | 0x4E534350) + 35), { 8, 64, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
647 { CKM_NSS_IKE1_PRF_DERIVE((0x80000000UL | 0x4E534350) + 36), { 8, 64, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
648 { CKM_NSS_IKE1_APP_B_PRF_DERIVE((0x80000000UL | 0x4E534350) + 37), { 8, 255 * 64, CKF_DERIVE0x00080000UL }, PR_TRUE1 },
649 /* -------------------- Kyber Operations ----------------------- */
650 { CKM_NSS_KYBER_KEY_PAIR_GEN((0x80000000UL | 0x4E534350) + 45), { 0, 0, CKF_GENERATE_KEY_PAIR0x00010000UL }, PR_TRUE1 },
651 { CKM_NSS_KYBER((0x80000000UL | 0x4E534350) + 46), { 0, 0, 0 }, PR_TRUE1 },
652};
653static const CK_ULONG mechanismCount = sizeof(mechanisms) / sizeof(mechanisms[0]);
654
655/* sigh global so fipstokn can read it */
656PRBool nsc_init = PR_FALSE0;
657
658#if defined(CHECK_FORK_PTHREAD) || defined(CHECK_FORK_MIXED)
659
660#include <pthread.h>
661
662static void
663ForkedChild(void)
664{
665 if (nsc_init || nsf_init) {
666 forked = PR_TRUE1;
667 }
668}
669
670#endif
671
672static char *
673sftk_setStringName(const char *inString, char *buffer, int buffer_length, PRBool nullTerminate)
674{
675 int full_length, string_length;
676
677 full_length = nullTerminate ? buffer_length - 1 : buffer_length;
678 string_length = PORT_Strlen(inString)strlen(inString);
679 /*
680 * shorten the string, respecting utf8 encoding
681 * to do so, we work backward from the end
682 * bytes looking from the end are either:
683 * - ascii [0x00,0x7f]
684 * - the [2-n]th byte of a multibyte sequence
685 * [0x3F,0xBF], i.e, most significant 2 bits are '10'
686 * - the first byte of a multibyte sequence [0xC0,0xFD],
687 * i.e, most significant 2 bits are '11'
688 *
689 * When the string is too long, we lop off any trailing '10' bytes,
690 * if any. When these are all eliminated we lop off
691 * one additional byte. Thus if we lopped any '10'
692 * we'll be lopping a '11' byte (the first byte of the multibyte sequence),
693 * otherwise we're lopping off an ascii character.
694 *
695 * To test for '10' bytes, we first AND it with
696 * 11000000 (0xc0) so that we get 10000000 (0x80) if and only if
697 * the byte starts with 10. We test for equality.
698 */
699 while (string_length > full_length) {
700 /* need to shorten */
701 while (string_length > 0 &&
702 ((inString[string_length - 1] & (char)0xc0) == (char)0x80)) {
703 /* lop off '10' byte */
704 string_length--;
705 }
706 /*
707 * test string_length in case bad data is received
708 * and string consisted of all '10' bytes,
709 * avoiding any infinite loop
710 */
711 if (string_length) {
712 /* remove either '11' byte or an asci byte */
713 string_length--;
714 }
715 }
716 PORT_Memsetmemset(buffer, ' ', full_length);
717 if (nullTerminate) {
718 buffer[full_length] = 0;
719 }
720 PORT_Memcpymemcpy(buffer, inString, string_length);
721 return buffer;
722}
723/*
724 * Configuration utils
725 */
726static CK_RV
727sftk_configure(const char *man, const char *libdes)
728{
729
730 /* make sure the internationalization was done correctly... */
731 if (man) {
732 manufacturerID = sftk_setStringName(man, manufacturerID_space,
733 sizeof(manufacturerID_space), PR_TRUE1);
734 }
735 if (libdes) {
736 libraryDescription = sftk_setStringName(libdes,
737 libraryDescription_space, sizeof(libraryDescription_space),
738 PR_TRUE1);
739 }
740
741 return CKR_OK0x00000000UL;
742}
743
744/*
745 * ******************** Password Utilities *******************************
746 */
747
748/*
749 * see if the key DB password is enabled
750 */
751static PRBool
752sftk_hasNullPassword(SFTKSlot *slot, SFTKDBHandle *keydb)
753{
754 PRBool pwenabled;
755
756 pwenabled = PR_FALSE0;
757 if (sftkdb_HasPasswordSet(keydb) == SECSuccess) {
758 PRBool tokenRemoved = PR_FALSE0;
759 SECStatus rv = sftkdb_CheckPasswordNull(keydb, &tokenRemoved);
760 if (tokenRemoved) {
761 sftk_CloseAllSessions(slot, PR_FALSE0);
762 }
763 return (rv == SECSuccess);
764 }
765
766 return pwenabled;
767}
768
769/*
770 * ******************** Object Creation Utilities ***************************
771 */
772
773/* Make sure a given attribute exists. If it doesn't, initialize it to
774 * value and len
775 */
776CK_RV
777sftk_defaultAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
778 const void *value, unsigned int len)
779{
780 if (!sftk_hasAttribute(object, type)) {
781 return sftk_AddAttributeType(object, type, value, len);
782 }
783 return CKR_OK0x00000000UL;
784}
785
786/*
787 * check the consistancy and initialize a Data Object
788 */
789static CK_RV
790sftk_handleDataObject(SFTKSession *session, SFTKObject *object)
791{
792 CK_RV crv;
793
794 /* first reject private and token data objects */
795 if (sftk_isTrue(object, CKA_PRIVATE0x00000002UL) || sftk_isTrue(object, CKA_TOKEN0x00000001UL)) {
796 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
797 }
798
799 /* now just verify the required date fields */
800 crv = sftk_defaultAttribute(object, CKA_APPLICATION0x00000010UL, NULL((void*)0), 0);
801 if (crv != CKR_OK0x00000000UL)
802 return crv;
803 crv = sftk_defaultAttribute(object, CKA_VALUE0x00000011UL, NULL((void*)0), 0);
804 if (crv != CKR_OK0x00000000UL)
805 return crv;
806
807 return CKR_OK0x00000000UL;
808}
809
810/*
811 * check the consistancy and initialize a Certificate Object
812 */
813static CK_RV
814sftk_handleCertObject(SFTKSession *session, SFTKObject *object)
815{
816 CK_CERTIFICATE_TYPE type;
817 SFTKAttribute *attribute;
818 CK_RV crv;
819
820 /* certificates must have a type */
821 if (!sftk_hasAttribute(object, CKA_CERTIFICATE_TYPE0x00000080UL)) {
822 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
823 }
824
825 /* we can't store any certs private */
826 if (sftk_isTrue(object, CKA_PRIVATE0x00000002UL)) {
827 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
828 }
829
830 /* We only support X.509 Certs for now */
831 attribute = sftk_FindAttribute(object, CKA_CERTIFICATE_TYPE0x00000080UL);
832 if (attribute == NULL((void*)0))
833 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
834 type = *(CK_CERTIFICATE_TYPE *)attribute->attrib.pValue;
835 sftk_FreeAttribute(attribute);
836
837 if (type != CKC_X_5090x00000000UL) {
838 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
839 }
840
841 /* X.509 Certificate */
842
843 /* make sure we have a cert */
844 if (!sftk_hasAttribute(object, CKA_VALUE0x00000011UL)) {
845 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
846 }
847
848 /* in PKCS #11, Subject is a required field */
849 if (!sftk_hasAttribute(object, CKA_SUBJECT0x00000101UL)) {
850 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
851 }
852
853 /* in PKCS #11, Issuer is a required field */
854 if (!sftk_hasAttribute(object, CKA_ISSUER0x00000081UL)) {
855 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
856 }
857
858 /* in PKCS #11, Serial is a required field */
859 if (!sftk_hasAttribute(object, CKA_SERIAL_NUMBER0x00000082UL)) {
860 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
861 }
862
863 /* add it to the object */
864 object->objectInfo = NULL((void*)0);
865 object->infoFree = (SFTKFree)NULL((void*)0);
866
867 /* now just verify the required date fields */
868 crv = sftk_defaultAttribute(object, CKA_ID0x00000102UL, NULL((void*)0), 0);
869 if (crv != CKR_OK0x00000000UL) {
870 return crv;
871 }
872
873 if (sftk_isTrue(object, CKA_TOKEN0x00000001UL)) {
874 SFTKSlot *slot = session->slot;
875 SFTKDBHandle *certHandle = sftk_getCertDB(slot);
876
877 if (certHandle == NULL((void*)0)) {
878 return CKR_TOKEN_WRITE_PROTECTED0x000000E2UL;
879 }
880
881 crv = sftkdb_write(certHandle, object, &object->handle);
882 sftk_freeDB(certHandle);
883 return crv;
884 }
885
886 return CKR_OK0x00000000UL;
887}
888
889/*
890 * check the consistancy and initialize a Trust Object
891 */
892static CK_RV
893sftk_handleTrustObject(SFTKSession *session, SFTKObject *object)
894{
895 /* we can't store any certs private */
896 if (sftk_isTrue(object, CKA_PRIVATE0x00000002UL)) {
897 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
898 }
899
900 /* certificates must have a type */
901 if (!sftk_hasAttribute(object, CKA_ISSUER0x00000081UL)) {
902 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
903 }
904 if (!sftk_hasAttribute(object, CKA_SERIAL_NUMBER0x00000082UL)) {
905 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
906 }
907 if (!sftk_hasAttribute(object, CKA_CERT_SHA1_HASH(((0x80000000UL | 0x4E534350) + 0x2000) + 100))) {
908 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
909 }
910 if (!sftk_hasAttribute(object, CKA_CERT_MD5_HASH(((0x80000000UL | 0x4E534350) + 0x2000) + 101))) {
911 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
912 }
913
914 if (sftk_isTrue(object, CKA_TOKEN0x00000001UL)) {
915 SFTKSlot *slot = session->slot;
916 SFTKDBHandle *certHandle = sftk_getCertDB(slot);
917 CK_RV crv;
918
919 if (certHandle == NULL((void*)0)) {
920 return CKR_TOKEN_WRITE_PROTECTED0x000000E2UL;
921 }
922
923 crv = sftkdb_write(certHandle, object, &object->handle);
924 sftk_freeDB(certHandle);
925 return crv;
926 }
927
928 return CKR_OK0x00000000UL;
929}
930
931/*
932 * check the consistancy and initialize a Trust Object
933 */
934static CK_RV
935sftk_handleSMimeObject(SFTKSession *session, SFTKObject *object)
936{
937
938 /* we can't store any certs private */
939 if (sftk_isTrue(object, CKA_PRIVATE0x00000002UL)) {
940 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
941 }
942
943 /* certificates must have a type */
944 if (!sftk_hasAttribute(object, CKA_SUBJECT0x00000101UL)) {
945 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
946 }
947 if (!sftk_hasAttribute(object, CKA_NSS_EMAIL((0x80000000UL | 0x4E534350) + 2))) {
948 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
949 }
950
951 if (sftk_isTrue(object, CKA_TOKEN0x00000001UL)) {
952 SFTKSlot *slot = session->slot;
953 SFTKDBHandle *certHandle;
954 CK_RV crv;
955
956 PORT_Assert(slot)((slot)?((void)0):PR_Assert("slot","pkcs11.c",956));
957 if (slot == NULL((void*)0)) {
958 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
959 }
960
961 certHandle = sftk_getCertDB(slot);
962 if (certHandle == NULL((void*)0)) {
963 return CKR_TOKEN_WRITE_PROTECTED0x000000E2UL;
964 }
965
966 crv = sftkdb_write(certHandle, object, &object->handle);
967 sftk_freeDB(certHandle);
968 return crv;
969 }
970
971 return CKR_OK0x00000000UL;
972}
973
974/*
975 * check the consistancy and initialize a Trust Object
976 */
977static CK_RV
978sftk_handleCrlObject(SFTKSession *session, SFTKObject *object)
979{
980
981 /* we can't store any certs private */
982 if (sftk_isTrue(object, CKA_PRIVATE0x00000002UL)) {
983 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
984 }
985
986 /* certificates must have a type */
987 if (!sftk_hasAttribute(object, CKA_SUBJECT0x00000101UL)) {
988 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
989 }
990 if (!sftk_hasAttribute(object, CKA_VALUE0x00000011UL)) {
991 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
992 }
993
994 if (sftk_isTrue(object, CKA_TOKEN0x00000001UL)) {
995 SFTKSlot *slot = session->slot;
996 SFTKDBHandle *certHandle = sftk_getCertDB(slot);
997 CK_RV crv;
998
999 if (certHandle == NULL((void*)0)) {
1000 return CKR_TOKEN_WRITE_PROTECTED0x000000E2UL;
1001 }
1002
1003 crv = sftkdb_write(certHandle, object, &object->handle);
1004 sftk_freeDB(certHandle);
1005 return crv;
1006 }
1007
1008 return CKR_OK0x00000000UL;
1009}
1010
1011/*
1012 * check the consistancy and initialize a Public Key Object
1013 */
1014static CK_RV
1015sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
1016 CK_KEY_TYPE key_type)
1017{
1018 CK_BBOOL encrypt = CK_TRUE1;
1019 CK_BBOOL recover = CK_TRUE1;
1020 CK_BBOOL wrap = CK_TRUE1;
1021 CK_BBOOL derive = CK_FALSE0;
1022 CK_BBOOL verify = CK_TRUE1;
1023 CK_RV crv;
1024
1025 switch (key_type) {
1026 case CKK_RSA0x00000000UL:
1027 crv = sftk_ConstrainAttribute(object, CKA_MODULUS0x00000120UL,
1028 RSA_MIN_MODULUS_BITS128, 0, 0);
1029 if (crv != CKR_OK0x00000000UL) {
1030 return crv;
1031 }
1032 crv = sftk_ConstrainAttribute(object, CKA_PUBLIC_EXPONENT0x00000122UL, 2, 0, 0);
1033 if (crv != CKR_OK0x00000000UL) {
1034 return crv;
1035 }
1036 break;
1037 case CKK_DSA0x00000001UL:
1038 crv = sftk_ConstrainAttribute(object, CKA_SUBPRIME0x00000131UL,
1039 DSA_MIN_Q_BITS160, DSA_MAX_Q_BITS256, 0);
1040 if (crv != CKR_OK0x00000000UL) {
1041 return crv;
1042 }
1043 crv = sftk_ConstrainAttribute(object, CKA_PRIME0x00000130UL,
1044 DSA_MIN_P_BITS512, DSA_MAX_P_BITS3072, 64);
1045 if (crv != CKR_OK0x00000000UL) {
1046 return crv;
1047 }
1048 crv = sftk_ConstrainAttribute(object, CKA_BASE0x00000132UL, 2, DSA_MAX_P_BITS3072, 0);
1049 if (crv != CKR_OK0x00000000UL) {
1050 return crv;
1051 }
1052 crv = sftk_ConstrainAttribute(object, CKA_VALUE0x00000011UL, 2, DSA_MAX_P_BITS3072, 0);
1053 if (crv != CKR_OK0x00000000UL) {
1054 return crv;
1055 }
1056 encrypt = CK_FALSE0;
1057 recover = CK_FALSE0;
1058 wrap = CK_FALSE0;
1059 break;
1060 case CKK_DH0x00000002UL:
1061 crv = sftk_ConstrainAttribute(object, CKA_PRIME0x00000130UL,
1062 DH_MIN_P_BITS128, DH_MAX_P_BITS16384, 0);
1063 if (crv != CKR_OK0x00000000UL) {
1064 return crv;
1065 }
1066 crv = sftk_ConstrainAttribute(object, CKA_BASE0x00000132UL, 2, DH_MAX_P_BITS16384, 0);
1067 if (crv != CKR_OK0x00000000UL) {
1068 return crv;
1069 }
1070 crv = sftk_ConstrainAttribute(object, CKA_VALUE0x00000011UL, 2, DH_MAX_P_BITS16384, 0);
1071 if (crv != CKR_OK0x00000000UL) {
1072 return crv;
1073 }
1074 verify = CK_FALSE0;
1075 derive = CK_TRUE1;
1076 encrypt = CK_FALSE0;
1077 recover = CK_FALSE0;
1078 wrap = CK_FALSE0;
1079 break;
1080 case CKK_EC_MONTGOMERY0x00000041UL:
1081 case CKK_EC_EDWARDS0x00000040UL:
1082 case CKK_EC0x00000003UL:
1083 if (!sftk_hasAttribute(object, CKA_EC_PARAMS0x00000180UL)) {
1084 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1085 }
1086 if (!sftk_hasAttribute(object, CKA_EC_POINT0x00000181UL)) {
1087 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1088 }
1089 /* for ECDSA and EDDSA. Change if the structure of any of them is modified. */
1090 derive = (key_type == CKK_EC_EDWARDS0x00000040UL) ? CK_FALSE0 : CK_TRUE1; /* CK_TRUE for ECDH */
1091 verify = CK_TRUE1; /* for ECDSA and EDDSA */
1092 encrypt = CK_FALSE0;
1093 recover = CK_FALSE0;
1094 wrap = CK_FALSE0;
1095 break;
1096 case CKK_NSS_KYBER((0x80000000UL | 0x4E534350) + 5):
1097 if (!sftk_hasAttribute(object, CKA_NSS_PARAMETER_SET((0x80000000UL | 0x4E534350) + 40))) {
1098 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1099 }
1100 derive = CK_FALSE0;
1101 verify = CK_FALSE0;
1102 encrypt = CK_FALSE0;
1103 recover = CK_FALSE0;
1104 wrap = CK_FALSE0;
1105 break;
1106 default:
1107 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
1108 }
1109
1110 /* make sure the required fields exist */
1111 crv = sftk_defaultAttribute(object, CKA_SUBJECT0x00000101UL, NULL((void*)0), 0);
1112 if (crv != CKR_OK0x00000000UL)
1113 return crv;
1114 crv = sftk_defaultAttribute(object, CKA_ENCRYPT0x00000104UL, &encrypt, sizeof(CK_BBOOL));
1115 if (crv != CKR_OK0x00000000UL)
1116 return crv;
1117 crv = sftk_defaultAttribute(object, CKA_VERIFY0x0000010AUL, &verify, sizeof(CK_BBOOL));
1118 if (crv != CKR_OK0x00000000UL)
1119 return crv;
1120 crv = sftk_defaultAttribute(object, CKA_VERIFY_RECOVER0x0000010BUL,
1121 &recover, sizeof(CK_BBOOL));
1122 if (crv != CKR_OK0x00000000UL)
1123 return crv;
1124 crv = sftk_defaultAttribute(object, CKA_WRAP0x00000106UL, &wrap, sizeof(CK_BBOOL));
1125 if (crv != CKR_OK0x00000000UL)
1126 return crv;
1127 crv = sftk_defaultAttribute(object, CKA_DERIVE0x0000010CUL, &derive, sizeof(CK_BBOOL));
1128 if (crv != CKR_OK0x00000000UL)
1129 return crv;
1130
1131 object->objectInfo = sftk_GetPubKey(object, key_type, &crv);
1132 if (object->objectInfo == NULL((void*)0)) {
1133 return crv;
1134 }
1135 object->infoFree = (SFTKFree)nsslowkey_DestroyPublicKey;
1136
1137 /* Check that an imported EC key is valid */
1138 if (key_type == CKK_EC0x00000003UL || key_type == CKK_EC_EDWARDS0x00000040UL || key_type == CKK_EC_MONTGOMERY0x00000041UL) {
1139 NSSLOWKEYPublicKey *pubKey = (NSSLOWKEYPublicKey *)object->objectInfo;
1140 SECStatus rv = EC_ValidatePublicKey(&pubKey->u.ec.ecParams,
1141 &pubKey->u.ec.publicValue);
1142
1143 if (rv != SECSuccess) {
1144 return CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
1145 }
1146 }
1147
1148 if (sftk_isTrue(object, CKA_TOKEN0x00000001UL)) {
1149 SFTKSlot *slot = session->slot;
1150 SFTKDBHandle *certHandle = sftk_getCertDB(slot);
1151
1152 if (certHandle == NULL((void*)0)) {
1153 return CKR_TOKEN_WRITE_PROTECTED0x000000E2UL;
1154 }
1155
1156 crv = sftkdb_write(certHandle, object, &object->handle);
1157 sftk_freeDB(certHandle);
1158 return crv;
1159 }
1160
1161 return CKR_OK0x00000000UL;
1162}
1163
1164static NSSLOWKEYPrivateKey *
1165sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key, CK_RV *rvp);
1166
1167static SECStatus
1168sftk_verifyRSAPrivateKey(SFTKObject *object, PRBool fillIfNeeded);
1169
1170/*
1171 * check the consistancy and initialize a Private Key Object
1172 */
1173static CK_RV
1174sftk_handlePrivateKeyObject(SFTKSession *session, SFTKObject *object, CK_KEY_TYPE key_type)
1175{
1176 CK_BBOOL cktrue = CK_TRUE1;
1177 CK_BBOOL encrypt = CK_TRUE1;
1178 CK_BBOOL sign = CK_FALSE0;
1179 CK_BBOOL recover = CK_TRUE1;
1180 CK_BBOOL wrap = CK_TRUE1;
1181 CK_BBOOL derive = CK_TRUE1;
1182 CK_BBOOL ckfalse = CK_FALSE0;
1183 PRBool createObjectInfo = PR_TRUE1;
1184 PRBool fillPrivateKey = PR_FALSE0;
1185 int missing_rsa_mod_component = 0;
1186 int missing_rsa_exp_component = 0;
1187 int missing_rsa_crt_component = 0;
1188
1189 SECItem mod;
1190 CK_RV crv;
1191 SECStatus rv;
1192
1193 switch (key_type) {
1194 case CKK_RSA0x00000000UL:
1195 if (!sftk_hasAttribute(object, CKA_MODULUS0x00000120UL)) {
1196 missing_rsa_mod_component++;
1197 }
1198 if (!sftk_hasAttribute(object, CKA_PUBLIC_EXPONENT0x00000122UL)) {
1199 missing_rsa_exp_component++;
1200 }
1201 if (!sftk_hasAttribute(object, CKA_PRIVATE_EXPONENT0x00000123UL)) {
1202 missing_rsa_exp_component++;
1203 }
1204 if (!sftk_hasAttribute(object, CKA_PRIME_10x00000124UL)) {
1205 missing_rsa_mod_component++;
1206 }
1207 if (!sftk_hasAttribute(object, CKA_PRIME_20x00000125UL)) {
1208 missing_rsa_mod_component++;
1209 }
1210 if (!sftk_hasAttribute(object, CKA_EXPONENT_10x00000126UL)) {
1211 missing_rsa_crt_component++;
1212 }
1213 if (!sftk_hasAttribute(object, CKA_EXPONENT_20x00000127UL)) {
1214 missing_rsa_crt_component++;
1215 }
1216 if (!sftk_hasAttribute(object, CKA_COEFFICIENT0x00000128UL)) {
1217 missing_rsa_crt_component++;
1218 }
1219 if (missing_rsa_mod_component || missing_rsa_exp_component ||
1220 missing_rsa_crt_component) {
1221 /* we are missing a component, see if we have enough to rebuild
1222 * the rest */
1223 int have_exp = 2 - missing_rsa_exp_component;
1224 int have_component = 5 -
1225 (missing_rsa_exp_component + missing_rsa_mod_component);
1226
1227 if ((have_exp == 0) || (have_component < 3)) {
1228 /* nope, not enough to reconstruct the private key */
1229 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1230 }
1231 fillPrivateKey = PR_TRUE1;
1232 }
1233 /*verify the parameters for consistency*/
1234 rv = sftk_verifyRSAPrivateKey(object, fillPrivateKey);
1235 if (rv != SECSuccess) {
1236 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1237 }
1238
1239 /* make sure Netscape DB attribute is set correctly */
1240 crv = sftk_Attribute2SSecItem(NULL((void*)0), &mod, object, CKA_MODULUS0x00000120UL);
1241 if (crv != CKR_OK0x00000000UL)
1242 return crv;
1243 crv = sftk_forceAttribute(object, CKA_NSS_DB0xD5A0DB00L,
1244 sftk_item_expand(&mod)(&mod)->data, (&mod)->len);
1245 if (mod.data)
1246 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&mod, PR_FALSE0);
1247 if (crv != CKR_OK0x00000000UL)
1248 return crv;
1249
1250 sign = CK_TRUE1;
1251 derive = CK_FALSE0;
1252 break;
1253 case CKK_DSA0x00000001UL:
1254 if (!sftk_hasAttribute(object, CKA_SUBPRIME0x00000131UL)) {
1255 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1256 }
1257 sign = CK_TRUE1;
1258 derive = CK_FALSE0;
1259 /* fall through */
1260 case CKK_DH0x00000002UL:
1261 if (!sftk_hasAttribute(object, CKA_PRIME0x00000130UL)) {
1262 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1263 }
1264 if (!sftk_hasAttribute(object, CKA_BASE0x00000132UL)) {
1265 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1266 }
1267 if (!sftk_hasAttribute(object, CKA_VALUE0x00000011UL)) {
1268 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1269 }
1270 /* allow subprime to be set after the fact */
1271 crv = sftk_defaultAttribute(object, CKA_SUBPRIME0x00000131UL, NULL((void*)0), 0);
1272 if (crv != CKR_OK0x00000000UL) {
1273 return crv;
1274 }
1275 encrypt = CK_FALSE0;
1276 recover = CK_FALSE0;
1277 wrap = CK_FALSE0;
1278 break;
1279 case CKK_EC0x00000003UL:
1280 case CKK_EC_EDWARDS0x00000040UL:
1281 case CKK_EC_MONTGOMERY0x00000041UL:
1282 if (!sftk_hasAttribute(object, CKA_EC_PARAMS0x00000180UL)) {
1283 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1284 }
1285 if (!sftk_hasAttribute(object, CKA_VALUE0x00000011UL)) {
1286 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1287 }
1288 /* for ECDSA and EDDSA. Change if the structure of any of them is modified. */
1289 derive = (key_type == CKK_EC_EDWARDS0x00000040UL) ? CK_FALSE0 : CK_TRUE1; /* CK_TRUE for ECDH */
1290 sign = CK_TRUE1; /* for ECDSA and EDDSA */
1291 encrypt = CK_FALSE0;
1292 recover = CK_FALSE0;
1293 wrap = CK_FALSE0;
1294 break;
1295 case CKK_NSS_JPAKE_ROUND1((0x80000000UL | 0x4E534350) + 2):
1296 if (!sftk_hasAttribute(object, CKA_PRIME0x00000130UL) ||
1297 !sftk_hasAttribute(object, CKA_SUBPRIME0x00000131UL) ||
1298 !sftk_hasAttribute(object, CKA_BASE0x00000132UL)) {
1299 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1300 }
1301 /* fall through */
1302 case CKK_NSS_JPAKE_ROUND2((0x80000000UL | 0x4E534350) + 3):
1303 /* CKA_NSS_JPAKE_SIGNERID and CKA_NSS_JPAKE_PEERID are checked in
1304 the J-PAKE code. */
1305 encrypt = sign = recover = wrap = CK_FALSE0;
1306 derive = CK_TRUE1;
1307 createObjectInfo = PR_FALSE0;
1308 break;
1309 case CKK_NSS_KYBER((0x80000000UL | 0x4E534350) + 5):
1310 if (!sftk_hasAttribute(object, CKA_KEY_TYPE0x00000100UL)) {
1311 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1312 }
1313 if (!sftk_hasAttribute(object, CKA_VALUE0x00000011UL)) {
1314 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1315 }
1316 encrypt = sign = recover = wrap = CK_FALSE0;
1317 break;
1318 default:
1319 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
1320 }
1321 crv = sftk_defaultAttribute(object, CKA_SUBJECT0x00000101UL, NULL((void*)0), 0);
1322 if (crv != CKR_OK0x00000000UL)
1323 return crv;
1324 crv = sftk_defaultAttribute(object, CKA_SENSITIVE0x00000103UL, &cktrue, sizeof(CK_BBOOL));
1325 if (crv != CKR_OK0x00000000UL)
1326 return crv;
1327 crv = sftk_defaultAttribute(object, CKA_EXTRACTABLE0x00000162UL, &cktrue, sizeof(CK_BBOOL));
1328 if (crv != CKR_OK0x00000000UL)
1329 return crv;
1330 crv = sftk_defaultAttribute(object, CKA_DECRYPT0x00000105UL, &encrypt, sizeof(CK_BBOOL));
1331 if (crv != CKR_OK0x00000000UL)
1332 return crv;
1333 crv = sftk_defaultAttribute(object, CKA_SIGN0x00000108UL, &sign, sizeof(CK_BBOOL));
1334 if (crv != CKR_OK0x00000000UL)
1335 return crv;
1336 crv = sftk_defaultAttribute(object, CKA_SIGN_RECOVER0x00000109UL, &recover,
1337 sizeof(CK_BBOOL));
1338 if (crv != CKR_OK0x00000000UL)
1339 return crv;
1340 crv = sftk_defaultAttribute(object, CKA_UNWRAP0x00000107UL, &wrap, sizeof(CK_BBOOL));
1341 if (crv != CKR_OK0x00000000UL)
1342 return crv;
1343 crv = sftk_defaultAttribute(object, CKA_DERIVE0x0000010CUL, &derive, sizeof(CK_BBOOL));
1344 if (crv != CKR_OK0x00000000UL)
1345 return crv;
1346 /* the next two bits get modified only in the key gen and token cases */
1347 crv = sftk_forceAttribute(object, CKA_ALWAYS_SENSITIVE0x00000165UL,
1348 &ckfalse, sizeof(CK_BBOOL));
1349 if (crv != CKR_OK0x00000000UL)
1350 return crv;
1351 crv = sftk_forceAttribute(object, CKA_NEVER_EXTRACTABLE0x00000164UL,
1352 &ckfalse, sizeof(CK_BBOOL));
1353 if (crv != CKR_OK0x00000000UL)
1354 return crv;
1355
1356 /* should we check the non-token RSA private keys? */
1357
1358 if (sftk_isTrue(object, CKA_TOKEN0x00000001UL)) {
1359 SFTKSlot *slot = session->slot;
1360 SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
1361
1362 if (keyHandle == NULL((void*)0)) {
1363 return CKR_TOKEN_WRITE_PROTECTED0x000000E2UL;
1364 }
1365
1366 crv = sftkdb_write(keyHandle, object, &object->handle);
1367 sftk_freeDB(keyHandle);
1368 return crv;
1369 } else if (createObjectInfo) {
1370 object->objectInfo = sftk_mkPrivKey(object, key_type, &crv);
1371 if (object->objectInfo == NULL((void*)0))
1372 return crv;
1373 object->infoFree = (SFTKFree)nsslowkey_DestroyPrivateKey;
1374 }
1375 return CKR_OK0x00000000UL;
1376}
1377
1378/* forward declare the DES formating function for handleSecretKey */
1379void sftk_FormatDESKey(unsigned char *key, int length);
1380
1381/* Validate secret key data, and set defaults */
1382static CK_RV
1383validateSecretKey(SFTKSession *session, SFTKObject *object,
1384 CK_KEY_TYPE key_type, PRBool isFIPS)
1385{
1386 CK_RV crv;
1387 CK_BBOOL cktrue = CK_TRUE1;
1388 CK_BBOOL ckfalse = CK_FALSE0;
1389 SFTKAttribute *attribute = NULL((void*)0);
1390 unsigned long requiredLen;
1391
1392 crv = sftk_defaultAttribute(object, CKA_SENSITIVE0x00000103UL,
1393 isFIPS ? &cktrue : &ckfalse, sizeof(CK_BBOOL));
1394 if (crv != CKR_OK0x00000000UL)
1395 return crv;
1396 crv = sftk_defaultAttribute(object, CKA_EXTRACTABLE0x00000162UL,
1397 &cktrue, sizeof(CK_BBOOL));
1398 if (crv != CKR_OK0x00000000UL)
1399 return crv;
1400 crv = sftk_defaultAttribute(object, CKA_ENCRYPT0x00000104UL, &cktrue, sizeof(CK_BBOOL));
1401 if (crv != CKR_OK0x00000000UL)
1402 return crv;
1403 crv = sftk_defaultAttribute(object, CKA_DECRYPT0x00000105UL, &cktrue, sizeof(CK_BBOOL));
1404 if (crv != CKR_OK0x00000000UL)
1405 return crv;
1406 crv = sftk_defaultAttribute(object, CKA_SIGN0x00000108UL, &ckfalse, sizeof(CK_BBOOL));
1407 if (crv != CKR_OK0x00000000UL)
1408 return crv;
1409 crv = sftk_defaultAttribute(object, CKA_VERIFY0x0000010AUL, &ckfalse, sizeof(CK_BBOOL));
1410 if (crv != CKR_OK0x00000000UL)
1411 return crv;
1412 crv = sftk_defaultAttribute(object, CKA_WRAP0x00000106UL, &cktrue, sizeof(CK_BBOOL));
1413 if (crv != CKR_OK0x00000000UL)
1414 return crv;
1415 crv = sftk_defaultAttribute(object, CKA_UNWRAP0x00000107UL, &cktrue, sizeof(CK_BBOOL));
1416 if (crv != CKR_OK0x00000000UL)
1417 return crv;
1418
1419 if (!sftk_hasAttribute(object, CKA_VALUE0x00000011UL)) {
1420 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1421 }
1422 /* the next two bits get modified only in the key gen and token cases */
1423 crv = sftk_forceAttribute(object, CKA_ALWAYS_SENSITIVE0x00000165UL,
1424 &ckfalse, sizeof(CK_BBOOL));
1425 if (crv != CKR_OK0x00000000UL)
1426 return crv;
1427 crv = sftk_forceAttribute(object, CKA_NEVER_EXTRACTABLE0x00000164UL,
1428 &ckfalse, sizeof(CK_BBOOL));
1429 if (crv != CKR_OK0x00000000UL)
1430 return crv;
1431
1432 /* some types of keys have a value length */
1433 crv = CKR_OK0x00000000UL;
1434 switch (key_type) {
1435 /* force CKA_VALUE_LEN to be set */
1436 case CKK_GENERIC_SECRET0x00000010UL:
1437 case CKK_RC20x00000011UL:
1438 case CKK_RC40x00000012UL:
1439#if NSS_SOFTOKEN_DOES_RC5
1440 case CKK_RC50x00000019UL:
1441#endif
1442#ifdef NSS_SOFTOKEN_DOES_CAST
1443 case CKK_CAST0x00000016UL:
1444 case CKK_CAST30x00000017UL:
1445 case CKK_CAST50x00000018UL:
1446#endif
1447#if NSS_SOFTOKEN_DOES_IDEA
1448 case CKK_IDEA0x0000001AUL:
1449#endif
1450 attribute = sftk_FindAttribute(object, CKA_VALUE0x00000011UL);
1451 /* shouldn't happen */
1452 if (attribute == NULL((void*)0))
1453 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1454 crv = sftk_forceAttribute(object, CKA_VALUE_LEN0x00000161UL,
1455 &attribute->attrib.ulValueLen, sizeof(CK_ULONG));
1456 sftk_FreeAttribute(attribute);
1457 break;
1458 /* force the value to have the correct parity */
1459 case CKK_DES0x00000013UL:
1460 case CKK_DES20x00000014UL:
1461 case CKK_DES30x00000015UL:
1462 case CKK_CDMF0x0000001EUL:
1463 attribute = sftk_FindAttribute(object, CKA_VALUE0x00000011UL);
1464 /* shouldn't happen */
1465 if (attribute == NULL((void*)0))
1466 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1467 requiredLen = sftk_MapKeySize(key_type);
1468 if (attribute->attrib.ulValueLen != requiredLen) {
1469 sftk_FreeAttribute(attribute);
1470 return CKR_KEY_SIZE_RANGE0x00000062UL;
1471 }
1472 sftk_FormatDESKey((unsigned char *)attribute->attrib.pValue,
1473 attribute->attrib.ulValueLen);
1474 sftk_FreeAttribute(attribute);
1475 break;
1476 case CKK_AES0x0000001FUL:
1477 attribute = sftk_FindAttribute(object, CKA_VALUE0x00000011UL);
1478 /* shouldn't happen */
1479 if (attribute == NULL((void*)0))
1480 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1481 if (attribute->attrib.ulValueLen != 16 &&
1482 attribute->attrib.ulValueLen != 24 &&
1483 attribute->attrib.ulValueLen != 32) {
1484 sftk_FreeAttribute(attribute);
1485 return CKR_KEY_SIZE_RANGE0x00000062UL;
1486 }
1487 crv = sftk_forceAttribute(object, CKA_VALUE_LEN0x00000161UL,
1488 &attribute->attrib.ulValueLen, sizeof(CK_ULONG));
1489 sftk_FreeAttribute(attribute);
1490 break;
1491 default:
1492 break;
1493 }
1494
1495 return crv;
1496}
1497
1498/*
1499 * check the consistancy and initialize a Secret Key Object
1500 */
1501static CK_RV
1502sftk_handleSecretKeyObject(SFTKSession *session, SFTKObject *object,
1503 CK_KEY_TYPE key_type, PRBool isFIPS)
1504{
1505 CK_RV crv;
1506
1507 /* First validate and set defaults */
1508 crv = validateSecretKey(session, object, key_type, isFIPS);
1509 if (crv != CKR_OK0x00000000UL)
1510 goto loser;
1511
1512 /* If the object is a TOKEN object, store in the database */
1513 if (sftk_isTrue(object, CKA_TOKEN0x00000001UL)) {
1514 SFTKSlot *slot = session->slot;
1515 SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
1516
1517 if (keyHandle == NULL((void*)0)) {
1518 return CKR_TOKEN_WRITE_PROTECTED0x000000E2UL;
1519 }
1520
1521 crv = sftkdb_write(keyHandle, object, &object->handle);
1522 sftk_freeDB(keyHandle);
1523 return crv;
1524 }
1525
1526loser:
1527
1528 return crv;
1529}
1530
1531/*
1532 * check the consistancy and initialize a Key Object
1533 */
1534static CK_RV
1535sftk_handleKeyObject(SFTKSession *session, SFTKObject *object)
1536{
1537 SFTKAttribute *attribute;
1538 CK_KEY_TYPE key_type;
1539 CK_BBOOL ckfalse = CK_FALSE0;
1540 CK_RV crv;
1541
1542 /* verify the required fields */
1543 if (!sftk_hasAttribute(object, CKA_KEY_TYPE0x00000100UL)) {
1544 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1545 }
1546
1547 /* now verify the common fields */
1548 crv = sftk_defaultAttribute(object, CKA_ID0x00000102UL, NULL((void*)0), 0);
1549 if (crv != CKR_OK0x00000000UL)
1550 return crv;
1551 crv = sftk_defaultAttribute(object, CKA_START_DATE0x00000110UL, NULL((void*)0), 0);
1552 if (crv != CKR_OK0x00000000UL)
1553 return crv;
1554 crv = sftk_defaultAttribute(object, CKA_END_DATE0x00000111UL, NULL((void*)0), 0);
1555 if (crv != CKR_OK0x00000000UL)
1556 return crv;
1557 /* CKA_DERIVE is common to all keys, but it's default value is
1558 * key dependent */
1559 crv = sftk_defaultAttribute(object, CKA_LOCAL0x00000163UL, &ckfalse, sizeof(CK_BBOOL));
1560 if (crv != CKR_OK0x00000000UL)
1561 return crv;
1562
1563 /* get the key type */
1564 attribute = sftk_FindAttribute(object, CKA_KEY_TYPE0x00000100UL);
1565 if (!attribute) {
1566 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
1567 }
1568 key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
1569 sftk_FreeAttribute(attribute);
1570
1571 switch (object->objclass) {
1572 case CKO_PUBLIC_KEY0x00000002UL:
1573 return sftk_handlePublicKeyObject(session, object, key_type);
1574 case CKO_PRIVATE_KEY0x00000003UL:
1575 return sftk_handlePrivateKeyObject(session, object, key_type);
1576 case CKO_SECRET_KEY0x00000004UL:
1577 /* make sure the required fields exist */
1578 return sftk_handleSecretKeyObject(session, object, key_type,
1579 (PRBool)(sftk_isFIPS(session->slot->slotID)(((session->slot->slotID) == 3) || ((session->slot->
slotID) >= 101))
));
1580 default:
1581 break;
1582 }
1583 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
1584}
1585
1586/*
1587 * check the consistancy and Verify a DSA Parameter Object
1588 */
1589static CK_RV
1590sftk_handleDSAParameterObject(SFTKSession *session, SFTKObject *object)
1591{
1592 SFTKAttribute *primeAttr = NULL((void*)0);
1593 SFTKAttribute *subPrimeAttr = NULL((void*)0);
1594 SFTKAttribute *baseAttr = NULL((void*)0);
1595 SFTKAttribute *seedAttr = NULL((void*)0);
1596 SFTKAttribute *hAttr = NULL((void*)0);
1597 SFTKAttribute *attribute;
1598 CK_RV crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1599 PQGParams params;
1600 PQGVerify vfy, *verify = NULL((void*)0);
1601 SECStatus result, rv;
1602 /* This bool keeps track of whether or not we need verify parameters.
1603 * If a P, Q and G or supplied, we dont' need verify parameters, as we
1604 * have PQ and G.
1605 * - If G is not supplied, the presumption is that we want to
1606 * verify P and Q only.
1607 * - If counter is supplied, it is presumed we want to verify PQ because
1608 * the counter is only used in verification.
1609 * - If H is supplied, is is presumed we want to verify G because H is
1610 * only used to verify G.
1611 * - Any verification step must have the SEED (counter or H could be
1612 * missing depending on exactly what we want to verify). If SEED is supplied,
1613 * the code just goes ahead and runs verify (other errors are parameter
1614 * errors are detected by the PQG_VerifyParams function). If SEED is not
1615 * supplied, but we determined that we are trying to verify (because needVfy
1616 * is set, go ahead and return CKR_TEMPLATE_INCOMPLETE.
1617 */
1618 PRBool needVfy = PR_FALSE0;
1619
1620 primeAttr = sftk_FindAttribute(object, CKA_PRIME0x00000130UL);
1621 if (primeAttr == NULL((void*)0))
1622 goto loser;
1623 params.prime.data = primeAttr->attrib.pValue;
1624 params.prime.len = primeAttr->attrib.ulValueLen;
1625
1626 subPrimeAttr = sftk_FindAttribute(object, CKA_SUBPRIME0x00000131UL);
1627 if (subPrimeAttr == NULL((void*)0))
1628 goto loser;
1629 params.subPrime.data = subPrimeAttr->attrib.pValue;
1630 params.subPrime.len = subPrimeAttr->attrib.ulValueLen;
1631
1632 baseAttr = sftk_FindAttribute(object, CKA_BASE0x00000132UL);
1633 if (baseAttr != NULL((void*)0)) {
1634 params.base.data = baseAttr->attrib.pValue;
1635 params.base.len = baseAttr->attrib.ulValueLen;
1636 } else {
1637 params.base.data = NULL((void*)0);
1638 params.base.len = 0;
1639 needVfy = PR_TRUE1; /* presumably only including PQ so we can verify
1640 * them. */
1641 }
1642
1643 attribute = sftk_FindAttribute(object, CKA_NSS_PQG_COUNTER((0x80000000UL | 0x4E534350) + 20));
1644 if (attribute != NULL((void*)0)) {
1645 vfy.counter = *(CK_ULONG *)attribute->attrib.pValue;
1646 sftk_FreeAttribute(attribute);
1647 needVfy = PR_TRUE1; /* included a count so we can verify PQ */
1648 } else {
1649 vfy.counter = -1;
1650 }
1651
1652 hAttr = sftk_FindAttribute(object, CKA_NSS_PQG_H((0x80000000UL | 0x4E534350) + 22));
1653 if (hAttr != NULL((void*)0)) {
1654 vfy.h.data = hAttr->attrib.pValue;
1655 vfy.h.len = hAttr->attrib.ulValueLen;
1656 needVfy = PR_TRUE1; /* included H so we can verify G */
1657 } else {
1658 vfy.h.data = NULL((void*)0);
1659 vfy.h.len = 0;
1660 }
1661 seedAttr = sftk_FindAttribute(object, CKA_NSS_PQG_SEED((0x80000000UL | 0x4E534350) + 21));
1662 if (seedAttr != NULL((void*)0)) {
1663 vfy.seed.data = seedAttr->attrib.pValue;
1664 vfy.seed.len = seedAttr->attrib.ulValueLen;
1665
1666 verify = &vfy;
1667 } else if (needVfy) {
1668 goto loser; /* Verify always needs seed, if we need verify and not seed
1669 * then fail */
1670 }
1671
1672 crv = CKR_FUNCTION_FAILED0x00000006UL;
1673 rv = PQG_VerifyParams(&params, verify, &result);
1674 if (rv == SECSuccess) {
1675 crv = (result == SECSuccess) ? CKR_OK0x00000000UL : CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
1676 }
1677
1678loser:
1679 if (hAttr)
1680 sftk_FreeAttribute(hAttr);
1681 if (seedAttr)
1682 sftk_FreeAttribute(seedAttr);
1683 if (baseAttr)
1684 sftk_FreeAttribute(baseAttr);
1685 if (subPrimeAttr)
1686 sftk_FreeAttribute(subPrimeAttr);
1687 if (primeAttr)
1688 sftk_FreeAttribute(primeAttr);
1689
1690 return crv;
1691}
1692
1693/*
1694 * check the consistancy and initialize a Key Parameter Object
1695 */
1696static CK_RV
1697sftk_handleKeyParameterObject(SFTKSession *session, SFTKObject *object)
1698{
1699 SFTKAttribute *attribute;
1700 CK_KEY_TYPE key_type;
1701 CK_BBOOL ckfalse = CK_FALSE0;
1702 CK_RV crv;
1703
1704 /* verify the required fields */
1705 if (!sftk_hasAttribute(object, CKA_KEY_TYPE0x00000100UL)) {
1706 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1707 }
1708
1709 /* now verify the common fields */
1710 crv = sftk_defaultAttribute(object, CKA_LOCAL0x00000163UL, &ckfalse, sizeof(CK_BBOOL));
1711 if (crv != CKR_OK0x00000000UL)
1712 return crv;
1713
1714 /* get the key type */
1715 attribute = sftk_FindAttribute(object, CKA_KEY_TYPE0x00000100UL);
1716 if (!attribute) {
1717 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
1718 }
1719 key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
1720 sftk_FreeAttribute(attribute);
1721
1722 switch (key_type) {
1723 case CKK_DSA0x00000001UL:
1724 return sftk_handleDSAParameterObject(session, object);
1725
1726 default:
1727 break;
1728 }
1729 return CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1730}
1731
1732/*
1733 * Handle Object does all the object consistancy checks, automatic attribute
1734 * generation, attribute defaulting, etc. If handleObject succeeds, the object
1735 * will be assigned an object handle, and the object installed in the session
1736 * or stored in the DB.
1737 */
1738CK_RV
1739sftk_handleObject(SFTKObject *object, SFTKSession *session)
1740{
1741 SFTKSlot *slot = session->slot;
1742 SFTKAttribute *attribute;
1743 CK_BBOOL ckfalse = CK_FALSE0;
1744 CK_BBOOL cktrue = CK_TRUE1;
1745 PRBool isLoggedIn, needLogin;
1746 CK_RV crv;
1747
1748 /* make sure all the base object types are defined. If not set the
1749 * defaults */
1750 crv = sftk_defaultAttribute(object, CKA_TOKEN0x00000001UL, &ckfalse, sizeof(CK_BBOOL));
1751 if (crv != CKR_OK0x00000000UL)
1752 return crv;
1753 crv = sftk_defaultAttribute(object, CKA_PRIVATE0x00000002UL, &ckfalse, sizeof(CK_BBOOL));
1754 if (crv != CKR_OK0x00000000UL)
1755 return crv;
1756 crv = sftk_defaultAttribute(object, CKA_LABEL0x00000003UL, NULL((void*)0), 0);
1757 if (crv != CKR_OK0x00000000UL)
1758 return crv;
1759 crv = sftk_defaultAttribute(object, CKA_MODIFIABLE0x00000170UL, &cktrue, sizeof(CK_BBOOL));
1760 if (crv != CKR_OK0x00000000UL)
1761 return crv;
1762
1763 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
1764 isLoggedIn = slot->isLoggedIn;
1765 needLogin = slot->needLogin;
1766 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
1767
1768 /* don't create a private object if we aren't logged in */
1769 if (!isLoggedIn && needLogin && sftk_isTrue(object, CKA_PRIVATE0x00000002UL)) {
1770 return CKR_USER_NOT_LOGGED_IN0x00000101UL;
1771 }
1772
1773 if (((session->info.flags & CKF_RW_SESSION0x00000002UL) == 0) &&
1774 (sftk_isTrue(object, CKA_TOKEN0x00000001UL))) {
1775 return CKR_SESSION_READ_ONLY0x000000B5UL;
1776 }
1777
1778 /* Assign a unique SESSION object handle to every new object,
1779 * whether it is a session object or a token object.
1780 * At this point, all new objects are structured as session objects.
1781 * Objects with the CKA_TOKEN attribute true will be turned into
1782 * token objects and will have a token object handle assigned to
1783 * them by a call to sftk_mkHandle in the handler for each object
1784 * class, invoked below.
1785 *
1786 * It may be helpful to note/remember that
1787 * sftk_narrowToXxxObject uses sftk_isToken,
1788 * sftk_isToken examines the sign bit of the object's handle, but
1789 * sftk_isTrue(...,CKA_TOKEN) examines the CKA_TOKEN attribute.
1790 */
1791 object->handle = sftk_getNextHandle(slot);
1792
1793 /* get the object class */
1794 attribute = sftk_FindAttribute(object, CKA_CLASS0x00000000UL);
1795 if (attribute == NULL((void*)0)) {
1796 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
1797 }
1798 object->objclass = *(CK_OBJECT_CLASS *)attribute->attrib.pValue;
1799 sftk_FreeAttribute(attribute);
1800
1801 /* Now handle the specific object class.
1802 * At this point, all objects are session objects, and the session
1803 * number must be passed to the object class handlers.
1804 */
1805 switch (object->objclass) {
1806 case CKO_DATA0x00000000UL:
1807 crv = sftk_handleDataObject(session, object);
1808 break;
1809 case CKO_CERTIFICATE0x00000001UL:
1810 crv = sftk_handleCertObject(session, object);
1811 break;
1812 case CKO_NSS_TRUST((0x80000000UL | 0x4E534350) + 3):
1813 crv = sftk_handleTrustObject(session, object);
1814 break;
1815 case CKO_NSS_CRL((0x80000000UL | 0x4E534350) + 1):
1816 crv = sftk_handleCrlObject(session, object);
1817 break;
1818 case CKO_NSS_SMIME((0x80000000UL | 0x4E534350) + 2):
1819 crv = sftk_handleSMimeObject(session, object);
1820 break;
1821 case CKO_PRIVATE_KEY0x00000003UL:
1822 case CKO_PUBLIC_KEY0x00000002UL:
1823 case CKO_SECRET_KEY0x00000004UL:
1824 crv = sftk_handleKeyObject(session, object);
1825 break;
1826 case CKO_DOMAIN_PARAMETERS0x00000006UL:
1827 crv = sftk_handleKeyParameterObject(session, object);
1828 break;
1829 default:
1830 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
1831 break;
1832 }
1833
1834 /* can't fail from here on out unless the pk_handlXXX functions have
1835 * failed the request */
1836 if (crv != CKR_OK0x00000000UL) {
1837 return crv;
1838 }
1839
1840 /* Now link the object into the slot and session structures.
1841 * If the object has a true CKA_TOKEN attribute, the above object
1842 * class handlers will have set the sign bit in the object handle,
1843 * causing the following test to be true.
1844 */
1845 if (sftk_isToken(object->handle)(((object->handle)&0x80000000L) == 0x80000000L)) {
1846 sftk_convertSessionToToken(object);
1847 } else {
1848 object->slot = slot;
1849 sftk_AddObject(session, object);
1850 }
1851
1852 return CKR_OK0x00000000UL;
1853}
1854
1855/*
1856 * ******************** Public Key Utilities ***************************
1857 */
1858/* Generate a low public key structure from an object */
1859NSSLOWKEYPublicKey *
1860sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type,
1861 CK_RV *crvp)
1862{
1863 NSSLOWKEYPublicKey *pubKey;
1864 PLArenaPool *arena;
1865 CK_RV crv;
1866
1867 if (object->objclass != CKO_PUBLIC_KEY0x00000002UL) {
1868 *crvp = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1869 return NULL((void*)0);
1870 }
1871
1872 if (sftk_isToken(object->handle)(((object->handle)&0x80000000L) == 0x80000000L)) {
1873 /* ferret out the token object handle */
1874 }
1875
1876 /* If we already have a key, use it */
1877 if (object->objectInfo) {
1878 *crvp = CKR_OK0x00000000UL;
1879 return (NSSLOWKEYPublicKey *)object->objectInfo;
1880 }
1881
1882 /* allocate the structure */
1883 arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
1884 if (arena == NULL((void*)0)) {
1885 *crvp = CKR_HOST_MEMORY0x00000002UL;
1886 return NULL((void*)0);
1887 }
1888
1889 pubKey = (NSSLOWKEYPublicKey *)
1890 PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, sizeof(NSSLOWKEYPublicKey));
1891 if (pubKey == NULL((void*)0)) {
1892 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
1893 *crvp = CKR_HOST_MEMORY0x00000002UL;
1894 return NULL((void*)0);
1895 }
1896
1897 /* fill in the structure */
1898 pubKey->arena = arena;
1899 switch (key_type) {
1900 case CKK_RSA0x00000000UL:
1901 pubKey->keyType = NSSLOWKEYRSAKey;
1902 crv = sftk_Attribute2SSecItem(arena, &pubKey->u.rsa.modulus,
1903 object, CKA_MODULUS0x00000120UL);
1904 if (crv != CKR_OK0x00000000UL)
1905 break;
1906 crv = sftk_Attribute2SSecItem(arena, &pubKey->u.rsa.publicExponent,
1907 object, CKA_PUBLIC_EXPONENT0x00000122UL);
1908 break;
1909 case CKK_DSA0x00000001UL:
1910 pubKey->keyType = NSSLOWKEYDSAKey;
1911 crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dsa.params.prime,
1912 object, CKA_PRIME0x00000130UL);
1913 if (crv != CKR_OK0x00000000UL)
1914 break;
1915 crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dsa.params.subPrime,
1916 object, CKA_SUBPRIME0x00000131UL);
1917 if (crv != CKR_OK0x00000000UL)
1918 break;
1919 crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dsa.params.base,
1920 object, CKA_BASE0x00000132UL);
1921 if (crv != CKR_OK0x00000000UL)
1922 break;
1923 crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dsa.publicValue,
1924 object, CKA_VALUE0x00000011UL);
1925 break;
1926 case CKK_DH0x00000002UL:
1927 pubKey->keyType = NSSLOWKEYDHKey;
1928 crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dh.prime,
1929 object, CKA_PRIME0x00000130UL);
1930 if (crv != CKR_OK0x00000000UL)
1931 break;
1932 crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dh.base,
1933 object, CKA_BASE0x00000132UL);
1934 if (crv != CKR_OK0x00000000UL)
1935 break;
1936 crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dh.publicValue,
1937 object, CKA_VALUE0x00000011UL);
1938 break;
1939 case CKK_EC_EDWARDS0x00000040UL:
1940 case CKK_EC_MONTGOMERY0x00000041UL:
1941 case CKK_EC0x00000003UL:
1942 pubKey->keyType = NSSLOWKEYECKey;
1943 crv = sftk_Attribute2SSecItem(arena,
1944 &pubKey->u.ec.ecParams.DEREncoding,
1945 object, CKA_EC_PARAMS0x00000180UL);
1946 if (crv != CKR_OK0x00000000UL)
1947 break;
1948
1949 /* Fill out the rest of the ecParams structure
1950 * based on the encoded params
1951 */
1952 if (EC_FillParams(arena, &pubKey->u.ec.ecParams.DEREncoding,
1953 &pubKey->u.ec.ecParams) != SECSuccess) {
1954 crv = CKR_DOMAIN_PARAMS_INVALID0x00000130UL;
1955 break;
1956 }
1957
1958 crv = sftk_Attribute2SSecItem(arena, &pubKey->u.ec.publicValue,
1959 object, CKA_EC_POINT0x00000181UL);
1960 if (crv == CKR_OK0x00000000UL) {
1961 unsigned int keyLen = EC_GetPointSize(&pubKey->u.ec.ecParams);
1962
1963 /* special note: We can't just use the first byte to distinguish
1964 * between EC_POINT_FORM_UNCOMPRESSED and SEC_ASN1_OCTET_STRING.
1965 * Both are 0x04. */
1966
1967 /* Handle the non-DER encoded case.
1968 * Some curves are always pressumed to be non-DER.
1969 */
1970 if (pubKey->u.ec.ecParams.type != ec_params_named ||
1971 (pubKey->u.ec.publicValue.len == keyLen &&
1972 pubKey->u.ec.publicValue.data[0] == EC_POINT_FORM_UNCOMPRESSED0x04)) {
1973 break; /* key was not DER encoded, no need to unwrap */
1974 }
1975
1976 /* handle the encoded case */
1977 if ((pubKey->u.ec.publicValue.data[0] == SEC_ASN1_OCTET_STRING0x04) &&
1978 pubKey->u.ec.publicValue.len > keyLen) {
1979 SECItem publicValue;
1980 SECStatus rv;
1981
1982 rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, &publicValue,
1983 SEC_ASN1_GET(SEC_OctetStringTemplate)SEC_OctetStringTemplate_Util,
1984 &pubKey->u.ec.publicValue);
1985 /* nope, didn't decode correctly */
1986 if ((rv != SECSuccess) || (publicValue.len != keyLen)) {
1987 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
1988 break;
1989 }
1990 /* we don't handle compressed points except in the case of ECCurve25519 */
1991 if (publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED0x04) {
1992 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
1993 break;
1994 }
1995 /* replace our previous with the decoded key */
1996 pubKey->u.ec.publicValue = publicValue;
1997 break;
1998 }
1999 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
2000 }
2001 break;
2002 case CKK_NSS_KYBER((0x80000000UL | 0x4E534350) + 5):
2003 crv = CKR_OK0x00000000UL;
2004 break;
2005 default:
2006 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
2007 break;
2008 }
2009 *crvp = crv;
2010 if (crv != CKR_OK0x00000000UL) {
2011 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
2012 return NULL((void*)0);
2013 }
2014
2015 object->objectInfo = pubKey;
2016 object->infoFree = (SFTKFree)nsslowkey_DestroyPublicKey;
2017 return pubKey;
2018}
2019
2020/* make a private key from a verified object */
2021static NSSLOWKEYPrivateKey *
2022sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
2023{
2024 NSSLOWKEYPrivateKey *privKey;
2025 SFTKItemTemplate itemTemplate[SFTK_MAX_ITEM_TEMPLATE10];
2026 int itemTemplateCount = 0;
2027 PLArenaPool *arena;
2028 CK_RV crv = CKR_OK0x00000000UL;
2029 SECStatus rv;
2030
2031 arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
2032 if (arena == NULL((void*)0)) {
2033 *crvp = CKR_HOST_MEMORY0x00000002UL;
2034 return NULL((void*)0);
2035 }
2036
2037 privKey = (NSSLOWKEYPrivateKey *)
2038 PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena, sizeof(NSSLOWKEYPrivateKey));
2039 if (privKey == NULL((void*)0)) {
2040 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
2041 *crvp = CKR_HOST_MEMORY0x00000002UL;
2042 return NULL((void*)0);
2043 }
2044
2045 /* in future this would be a switch on key_type */
2046 privKey->arena = arena;
2047 switch (key_type) {
2048 case CKK_RSA0x00000000UL:
2049 privKey->keyType = NSSLOWKEYRSAKey;
2050
2051 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000120UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.modulus
2052 &privKey->u.rsa.modulus, CKA_MODULUS)itemTemplate[itemTemplateCount].type = 0x00000120UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.modulus
;
2053 itemTemplateCount++;
2054 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000122UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.publicExponent
2055 &privKey->u.rsa.publicExponent, CKA_PUBLIC_EXPONENT)itemTemplate[itemTemplateCount].type = 0x00000122UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.publicExponent
;
2056 itemTemplateCount++;
2057 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000123UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.privateExponent
2058 &privKey->u.rsa.privateExponent, CKA_PRIVATE_EXPONENT)itemTemplate[itemTemplateCount].type = 0x00000123UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.privateExponent
;
2059 itemTemplateCount++;
2060 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000124UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.prime1
2061 &privKey->u.rsa.prime1, CKA_PRIME_1)itemTemplate[itemTemplateCount].type = 0x00000124UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.prime1
;
2062 itemTemplateCount++;
2063 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000125UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.prime2
2064 &privKey->u.rsa.prime2, CKA_PRIME_2)itemTemplate[itemTemplateCount].type = 0x00000125UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.prime2
;
2065 itemTemplateCount++;
2066 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000126UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.exponent1
2067 &privKey->u.rsa.exponent1, CKA_EXPONENT_1)itemTemplate[itemTemplateCount].type = 0x00000126UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.exponent1
;
2068 itemTemplateCount++;
2069 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000127UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.exponent2
2070 &privKey->u.rsa.exponent2, CKA_EXPONENT_2)itemTemplate[itemTemplateCount].type = 0x00000127UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.exponent2
;
2071 itemTemplateCount++;
2072 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000128UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.coefficient
2073 &privKey->u.rsa.coefficient, CKA_COEFFICIENT)itemTemplate[itemTemplateCount].type = 0x00000128UL; itemTemplate
[itemTemplateCount].item = &privKey->u.rsa.coefficient
;
2074 itemTemplateCount++;
2075 rv = DER_SetUInteger(privKey->arena, &privKey->u.rsa.version,
2076 NSSLOWKEY_PRIVATE_KEY_INFO_VERSION0);
2077 if (rv != SECSuccess)
2078 crv = CKR_HOST_MEMORY0x00000002UL;
2079 break;
2080
2081 case CKK_DSA0x00000001UL:
2082 privKey->keyType = NSSLOWKEYDSAKey;
2083 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000130UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dsa.params.prime
2084 &privKey->u.dsa.params.prime, CKA_PRIME)itemTemplate[itemTemplateCount].type = 0x00000130UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dsa.params.prime
;
2085 itemTemplateCount++;
2086 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000131UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dsa.params.subPrime
2087 &privKey->u.dsa.params.subPrime, CKA_SUBPRIME)itemTemplate[itemTemplateCount].type = 0x00000131UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dsa.params.subPrime
;
2088 itemTemplateCount++;
2089 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000132UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dsa.params.base
2090 &privKey->u.dsa.params.base, CKA_BASE)itemTemplate[itemTemplateCount].type = 0x00000132UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dsa.params.base
;
2091 itemTemplateCount++;
2092 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000011UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dsa.privateValue
2093 &privKey->u.dsa.privateValue, CKA_VALUE)itemTemplate[itemTemplateCount].type = 0x00000011UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dsa.privateValue
;
2094 itemTemplateCount++;
2095 /* privKey was zero'd so public value is already set to NULL, 0
2096 * if we don't set it explicitly */
2097 break;
2098
2099 case CKK_DH0x00000002UL:
2100 privKey->keyType = NSSLOWKEYDHKey;
2101 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000130UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dh.prime
2102 &privKey->u.dh.prime, CKA_PRIME)itemTemplate[itemTemplateCount].type = 0x00000130UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dh.prime
;
2103 itemTemplateCount++;
2104 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000132UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dh.base
2105 &privKey->u.dh.base, CKA_BASE)itemTemplate[itemTemplateCount].type = 0x00000132UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dh.base
;
2106 itemTemplateCount++;
2107 SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,itemTemplate[itemTemplateCount].type = 0x00000011UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dh.privateValue
2108 &privKey->u.dh.privateValue, CKA_VALUE)itemTemplate[itemTemplateCount].type = 0x00000011UL; itemTemplate
[itemTemplateCount].item = &privKey->u.dh.privateValue
;
2109 itemTemplateCount++;
2110 /* privKey was zero'd so public value is already set to NULL, 0
2111 * if we don't set it explicitly */
2112 break;
2113 case CKK_EC_EDWARDS0x00000040UL:
2114 case CKK_EC_MONTGOMERY0x00000041UL:
2115 case CKK_EC0x00000003UL:
2116 privKey->keyType = NSSLOWKEYECKey;
2117 crv = sftk_Attribute2SSecItem(arena,
2118 &privKey->u.ec.ecParams.DEREncoding,
2119 object, CKA_EC_PARAMS0x00000180UL);
2120 if (crv != CKR_OK0x00000000UL)
2121 break;
2122
2123 /* Fill out the rest of the ecParams structure
2124 * based on the encoded params
2125 */
2126 if (EC_FillParams(arena, &privKey->u.ec.ecParams.DEREncoding,
2127 &privKey->u.ec.ecParams) != SECSuccess) {
2128 crv = CKR_DOMAIN_PARAMS_INVALID0x00000130UL;
2129 break;
2130 }
2131 crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.privateValue,
2132 object, CKA_VALUE0x00000011UL);
2133 if (crv != CKR_OK0x00000000UL)
2134 break;
2135
2136 if (sftk_hasAttribute(object, CKA_NSS_DB0xD5A0DB00L)) {
2137 crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.publicValue,
2138 object, CKA_NSS_DB0xD5A0DB00L);
2139 if (crv != CKR_OK0x00000000UL)
2140 break;
2141 /* privKey was zero'd so public value is already set to NULL, 0
2142 * if we don't set it explicitly */
2143 }
2144 rv = DER_SetUInteger(privKey->arena, &privKey->u.ec.version,
2145 NSSLOWKEY_EC_PRIVATE_KEY_VERSION1);
2146 if (rv != SECSuccess) {
2147 crv = CKR_HOST_MEMORY0x00000002UL;
2148/* The following ifdef is needed for Linux arm distros and
2149 * Android as gcc 4.6 has a bug when targeting arm (but not
2150 * thumb). The bug has been fixed in gcc 4.7.
2151 * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56561
2152 */
2153#if defined(__arm__) && !defined(__thumb__) && defined(__GNUC__4)
2154 *crvp = CKR_HOST_MEMORY0x00000002UL;
2155 break;
2156#endif
2157 }
2158 break;
2159
2160 case CKK_NSS_KYBER((0x80000000UL | 0x4E534350) + 5):
2161 break;
2162
2163 default:
2164 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
2165 break;
2166 }
2167 if (crv == CKR_OK0x00000000UL && itemTemplateCount != 0) {
2168 PORT_Assert(itemTemplateCount > 0)((itemTemplateCount > 0)?((void)0):PR_Assert("itemTemplateCount > 0"
,"pkcs11.c",2168))
;
2169 PORT_Assert(itemTemplateCount <= SFTK_MAX_ITEM_TEMPLATE)((itemTemplateCount <= 10)?((void)0):PR_Assert("itemTemplateCount <= SFTK_MAX_ITEM_TEMPLATE"
,"pkcs11.c",2169))
;
2170 crv = sftk_MultipleAttribute2SecItem(arena, object, itemTemplate,
2171 itemTemplateCount);
2172 }
2173 *crvp = crv;
2174 if (crv != CKR_OK0x00000000UL) {
2175 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
2176 return NULL((void*)0);
2177 }
2178 return privKey;
2179}
2180
2181/*
2182 * If a partial RSA private key is present, fill in the rest if necessary,
2183 * and then verify the parameters are well-formed
2184 */
2185static SECStatus
2186sftk_verifyRSAPrivateKey(SFTKObject *object, PRBool fillIfNeeded)
2187{
2188 RSAPrivateKey tmpKey = { 0 };
2189 SFTKAttribute *modulus = NULL((void*)0);
2190 SFTKAttribute *prime1 = NULL((void*)0);
2191 SFTKAttribute *prime2 = NULL((void*)0);
2192 SFTKAttribute *privateExponent = NULL((void*)0);
2193 SFTKAttribute *publicExponent = NULL((void*)0);
2194 SFTKAttribute *exponent1 = NULL((void*)0);
2195 SFTKAttribute *exponent2 = NULL((void*)0);
2196 SFTKAttribute *coefficient = NULL((void*)0);
2197 SECStatus rv;
2198 CK_RV crv;
2199
2200 /* first fill in the components that we have. Populate only uses
2201 * the non-crt components, so only fill those in */
2202 tmpKey.arena = NULL((void*)0);
2203 modulus = sftk_FindAttribute(object, CKA_MODULUS0x00000120UL);
2204 if (modulus) {
2205 tmpKey.modulus.data = modulus->attrib.pValue;
2206 tmpKey.modulus.len = modulus->attrib.ulValueLen;
2207 }
2208 prime1 = sftk_FindAttribute(object, CKA_PRIME_10x00000124UL);
2209 if (prime1) {
2210 tmpKey.prime1.data = prime1->attrib.pValue;
2211 tmpKey.prime1.len = prime1->attrib.ulValueLen;
2212 }
2213 prime2 = sftk_FindAttribute(object, CKA_PRIME_20x00000125UL);
2214 if (prime2) {
2215 tmpKey.prime2.data = prime2->attrib.pValue;
2216 tmpKey.prime2.len = prime2->attrib.ulValueLen;
2217 }
2218 privateExponent = sftk_FindAttribute(object, CKA_PRIVATE_EXPONENT0x00000123UL);
2219 if (privateExponent) {
2220 tmpKey.privateExponent.data = privateExponent->attrib.pValue;
2221 tmpKey.privateExponent.len = privateExponent->attrib.ulValueLen;
2222 }
2223 publicExponent = sftk_FindAttribute(object, CKA_PUBLIC_EXPONENT0x00000122UL);
2224 if (publicExponent) {
2225 tmpKey.publicExponent.data = publicExponent->attrib.pValue;
2226 tmpKey.publicExponent.len = publicExponent->attrib.ulValueLen;
2227 }
2228 exponent1 = sftk_FindAttribute(object, CKA_EXPONENT_10x00000126UL);
2229 if (exponent1) {
2230 tmpKey.exponent1.data = exponent1->attrib.pValue;
2231 tmpKey.exponent1.len = exponent1->attrib.ulValueLen;
2232 }
2233 exponent2 = sftk_FindAttribute(object, CKA_EXPONENT_20x00000127UL);
2234 if (exponent2) {
2235 tmpKey.exponent2.data = exponent2->attrib.pValue;
2236 tmpKey.exponent2.len = exponent2->attrib.ulValueLen;
2237 }
2238 coefficient = sftk_FindAttribute(object, CKA_COEFFICIENT0x00000128UL);
2239 if (coefficient) {
2240 tmpKey.coefficient.data = coefficient->attrib.pValue;
2241 tmpKey.coefficient.len = coefficient->attrib.ulValueLen;
2242 }
2243
2244 if (fillIfNeeded) {
2245 /*
2246 * populate requires one exponent plus 2 other components to work.
2247 * we expected our caller to check that first. If that didn't happen,
2248 * populate will simply return an error here.
2249 */
2250 rv = RSA_PopulatePrivateKey(&tmpKey);
2251 if (rv != SECSuccess) {
2252 goto loser;
2253 }
2254 }
2255 rv = RSA_PrivateKeyCheck(&tmpKey);
2256 if (rv != SECSuccess) {
2257 goto loser;
2258 }
2259 /* now that we have a fully populated key, set all our attribute values */
2260 rv = SECFailure;
2261 if (!modulus || modulus->attrib.pValue != tmpKey.modulus.data) {
2262 crv = sftk_forceAttribute(object, CKA_MODULUS0x00000120UL,
2263 sftk_item_expand(&tmpKey.modulus)(&tmpKey.modulus)->data, (&tmpKey.modulus)->len);
2264 if (crv != CKR_OK0x00000000UL)
2265 goto loser;
2266 }
2267 if (!publicExponent ||
2268 publicExponent->attrib.pValue != tmpKey.publicExponent.data) {
2269 crv = sftk_forceAttribute(object, CKA_PUBLIC_EXPONENT0x00000122UL,
2270 sftk_item_expand(&tmpKey.publicExponent)(&tmpKey.publicExponent)->data, (&tmpKey.publicExponent
)->len
);
2271 if (crv != CKR_OK0x00000000UL)
2272 goto loser;
2273 }
2274 if (!privateExponent ||
2275 privateExponent->attrib.pValue != tmpKey.privateExponent.data) {
2276 crv = sftk_forceAttribute(object, CKA_PRIVATE_EXPONENT0x00000123UL,
2277 sftk_item_expand(&tmpKey.privateExponent)(&tmpKey.privateExponent)->data, (&tmpKey.privateExponent
)->len
);
2278 if (crv != CKR_OK0x00000000UL)
2279 goto loser;
2280 }
2281 if (!prime1 || prime1->attrib.pValue != tmpKey.prime1.data) {
2282 crv = sftk_forceAttribute(object, CKA_PRIME_10x00000124UL,
2283 sftk_item_expand(&tmpKey.prime1)(&tmpKey.prime1)->data, (&tmpKey.prime1)->len);
2284 if (crv != CKR_OK0x00000000UL)
2285 goto loser;
2286 }
2287 if (!prime2 || prime2->attrib.pValue != tmpKey.prime2.data) {
2288 crv = sftk_forceAttribute(object, CKA_PRIME_20x00000125UL,
2289 sftk_item_expand(&tmpKey.prime2)(&tmpKey.prime2)->data, (&tmpKey.prime2)->len);
2290 if (crv != CKR_OK0x00000000UL)
2291 goto loser;
2292 }
2293 if (!exponent1 || exponent1->attrib.pValue != tmpKey.exponent1.data) {
2294 crv = sftk_forceAttribute(object, CKA_EXPONENT_10x00000126UL,
2295 sftk_item_expand(&tmpKey.exponent1)(&tmpKey.exponent1)->data, (&tmpKey.exponent1)->
len
);
2296 if (crv != CKR_OK0x00000000UL)
2297 goto loser;
2298 }
2299 if (!exponent2 || exponent2->attrib.pValue != tmpKey.exponent2.data) {
2300 crv = sftk_forceAttribute(object, CKA_EXPONENT_20x00000127UL,
2301 sftk_item_expand(&tmpKey.exponent2)(&tmpKey.exponent2)->data, (&tmpKey.exponent2)->
len
);
2302 if (crv != CKR_OK0x00000000UL)
2303 goto loser;
2304 }
2305 if (!coefficient || coefficient->attrib.pValue != tmpKey.coefficient.data) {
2306 crv = sftk_forceAttribute(object, CKA_COEFFICIENT0x00000128UL,
2307 sftk_item_expand(&tmpKey.coefficient)(&tmpKey.coefficient)->data, (&tmpKey.coefficient)
->len
);
2308 if (crv != CKR_OK0x00000000UL)
2309 goto loser;
2310 }
2311 rv = SECSuccess;
2312
2313/* we're done (one way or the other), clean up all our stuff */
2314loser:
2315 if (tmpKey.arena) {
2316 PORT_FreeArenaPORT_FreeArena_Util(tmpKey.arena, PR_TRUE1);
2317 }
2318 if (modulus) {
2319 sftk_FreeAttribute(modulus);
2320 }
2321 if (prime1) {
2322 sftk_FreeAttribute(prime1);
2323 }
2324 if (prime2) {
2325 sftk_FreeAttribute(prime2);
2326 }
2327 if (privateExponent) {
2328 sftk_FreeAttribute(privateExponent);
2329 }
2330 if (publicExponent) {
2331 sftk_FreeAttribute(publicExponent);
2332 }
2333 if (exponent1) {
2334 sftk_FreeAttribute(exponent1);
2335 }
2336 if (exponent2) {
2337 sftk_FreeAttribute(exponent2);
2338 }
2339 if (coefficient) {
2340 sftk_FreeAttribute(coefficient);
2341 }
2342 return rv;
2343}
2344
2345/* Generate a low private key structure from an object */
2346NSSLOWKEYPrivateKey *
2347sftk_GetPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
2348{
2349 NSSLOWKEYPrivateKey *priv = NULL((void*)0);
2350
2351 if (object->objclass != CKO_PRIVATE_KEY0x00000003UL) {
2352 *crvp = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
2353 return NULL((void*)0);
2354 }
2355 if (object->objectInfo) {
2356 *crvp = CKR_OK0x00000000UL;
2357 return (NSSLOWKEYPrivateKey *)object->objectInfo;
2358 }
2359
2360 priv = sftk_mkPrivKey(object, key_type, crvp);
2361 object->objectInfo = priv;
2362 object->infoFree = (SFTKFree)nsslowkey_DestroyPrivateKey;
2363 return priv;
2364}
2365
2366/* populate a public key object from a lowpublic keys structure */
2367CK_RV
2368sftk_PutPubKey(SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType, NSSLOWKEYPublicKey *pubKey)
2369{
2370 CK_OBJECT_CLASS classType = CKO_PUBLIC_KEY0x00000002UL;
2371 CK_BBOOL cktrue = CK_TRUE1;
2372 CK_RV crv = CKR_OK0x00000000UL;
2373 sftk_DeleteAttributeType(publicKey, CKA_CLASS0x00000000UL);
2374 sftk_DeleteAttributeType(publicKey, CKA_KEY_TYPE0x00000100UL);
2375 sftk_DeleteAttributeType(publicKey, CKA_VALUE0x00000011UL);
2376
2377 switch (keyType) {
2378 case CKK_RSA0x00000000UL:
2379 sftk_DeleteAttributeType(publicKey, CKA_MODULUS0x00000120UL);
2380 sftk_DeleteAttributeType(publicKey, CKA_PUBLIC_EXPONENT0x00000122UL);
2381 /* format the keys */
2382 /* fill in the RSA dependent paramenters in the public key */
2383 crv = sftk_AddAttributeType(publicKey, CKA_MODULUS0x00000120UL,
2384 sftk_item_expand(&pubKey->u.rsa.modulus)(&pubKey->u.rsa.modulus)->data, (&pubKey->u.
rsa.modulus)->len
);
2385 if (crv != CKR_OK0x00000000UL) {
2386 break;
2387 }
2388 crv = sftk_AddAttributeType(publicKey, CKA_PUBLIC_EXPONENT0x00000122UL,
2389 sftk_item_expand(&pubKey->u.rsa.publicExponent)(&pubKey->u.rsa.publicExponent)->data, (&pubKey
->u.rsa.publicExponent)->len
);
2390 break;
2391 case CKK_DSA0x00000001UL:
2392 sftk_DeleteAttributeType(publicKey, CKA_PRIME0x00000130UL);
2393 sftk_DeleteAttributeType(publicKey, CKA_SUBPRIME0x00000131UL);
2394 sftk_DeleteAttributeType(publicKey, CKA_BASE0x00000132UL);
2395 crv = sftk_AddAttributeType(publicKey, CKA_PRIME0x00000130UL,
2396 sftk_item_expand(&pubKey->u.dsa.params.prime)(&pubKey->u.dsa.params.prime)->data, (&pubKey->
u.dsa.params.prime)->len
);
2397 if (crv != CKR_OK0x00000000UL) {
2398 break;
2399 }
2400 crv = sftk_AddAttributeType(publicKey, CKA_SUBPRIME0x00000131UL,
2401 sftk_item_expand(&pubKey->u.dsa.params.subPrime)(&pubKey->u.dsa.params.subPrime)->data, (&pubKey
->u.dsa.params.subPrime)->len
);
2402 if (crv != CKR_OK0x00000000UL) {
2403 break;
2404 }
2405 crv = sftk_AddAttributeType(publicKey, CKA_BASE0x00000132UL,
2406 sftk_item_expand(&pubKey->u.dsa.params.base)(&pubKey->u.dsa.params.base)->data, (&pubKey->
u.dsa.params.base)->len
);
2407 if (crv != CKR_OK0x00000000UL) {
2408 break;
2409 }
2410 crv = sftk_AddAttributeType(publicKey, CKA_VALUE0x00000011UL,
2411 sftk_item_expand(&pubKey->u.dsa.publicValue)(&pubKey->u.dsa.publicValue)->data, (&pubKey->
u.dsa.publicValue)->len
);
2412 break;
2413 case CKK_DH0x00000002UL:
2414 sftk_DeleteAttributeType(publicKey, CKA_PRIME0x00000130UL);
2415 sftk_DeleteAttributeType(publicKey, CKA_BASE0x00000132UL);
2416 crv = sftk_AddAttributeType(publicKey, CKA_PRIME0x00000130UL,
2417 sftk_item_expand(&pubKey->u.dh.prime)(&pubKey->u.dh.prime)->data, (&pubKey->u.dh.
prime)->len
);
2418 if (crv != CKR_OK0x00000000UL) {
2419 break;
2420 }
2421 crv = sftk_AddAttributeType(publicKey, CKA_BASE0x00000132UL,
2422 sftk_item_expand(&pubKey->u.dh.base)(&pubKey->u.dh.base)->data, (&pubKey->u.dh.base
)->len
);
2423 if (crv != CKR_OK0x00000000UL) {
2424 break;
2425 }
2426 crv = sftk_AddAttributeType(publicKey, CKA_VALUE0x00000011UL,
2427 sftk_item_expand(&pubKey->u.dh.publicValue)(&pubKey->u.dh.publicValue)->data, (&pubKey->
u.dh.publicValue)->len
);
2428 break;
2429 case CKK_EC0x00000003UL:
2430 case CKK_EC_MONTGOMERY0x00000041UL:
2431 case CKK_EC_EDWARDS0x00000040UL:
2432 sftk_DeleteAttributeType(publicKey, CKA_EC_PARAMS0x00000180UL);
2433 sftk_DeleteAttributeType(publicKey, CKA_EC_POINT0x00000181UL);
2434 crv = sftk_AddAttributeType(publicKey, CKA_EC_PARAMS0x00000180UL,
2435 sftk_item_expand(&pubKey->u.ec.ecParams.DEREncoding)(&pubKey->u.ec.ecParams.DEREncoding)->data, (&pubKey
->u.ec.ecParams.DEREncoding)->len
);
2436 if (crv != CKR_OK0x00000000UL) {
2437 break;
2438 }
2439 crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT0x00000181UL,
2440 sftk_item_expand(&pubKey->u.ec.publicValue)(&pubKey->u.ec.publicValue)->data, (&pubKey->
u.ec.publicValue)->len
);
2441 break;
2442 default:
2443 return CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
2444 }
2445 if (crv != CKR_OK0x00000000UL) {
2446 return crv;
2447 }
2448 crv = sftk_AddAttributeType(publicKey, CKA_CLASS0x00000000UL, &classType,
2449 sizeof(CK_OBJECT_CLASS));
2450 if (crv != CKR_OK0x00000000UL) {
2451 return crv;
2452 }
2453 crv = sftk_AddAttributeType(publicKey, CKA_KEY_TYPE0x00000100UL, &keyType,
2454 sizeof(CK_KEY_TYPE));
2455 if (crv != CKR_OK0x00000000UL) {
2456 return crv;
2457 }
2458 /* now handle the operator attributes */
2459 if (sftk_isTrue(privateKey, CKA_DECRYPT0x00000105UL)) {
2460 crv = sftk_forceAttribute(publicKey, CKA_ENCRYPT0x00000104UL, &cktrue, sizeof(CK_BBOOL));
2461 if (crv != CKR_OK0x00000000UL) {
2462 return crv;
2463 }
2464 }
2465 if (sftk_isTrue(privateKey, CKA_SIGN0x00000108UL)) {
2466 crv = sftk_forceAttribute(publicKey, CKA_VERIFY0x0000010AUL, &cktrue, sizeof(CK_BBOOL));
2467 if (crv != CKR_OK0x00000000UL) {
2468 return crv;
2469 }
2470 }
2471 if (sftk_isTrue(privateKey, CKA_SIGN_RECOVER0x00000109UL)) {
2472 crv = sftk_forceAttribute(publicKey, CKA_VERIFY_RECOVER0x0000010BUL, &cktrue, sizeof(CK_BBOOL));
2473 if (crv != CKR_OK0x00000000UL) {
2474 return crv;
2475 }
2476 }
2477 if (sftk_isTrue(privateKey, CKA_DERIVE0x0000010CUL)) {
2478 crv = sftk_forceAttribute(publicKey, CKA_DERIVE0x0000010CUL, &cktrue, sizeof(CK_BBOOL));
2479 if (crv != CKR_OK0x00000000UL) {
2480 return crv;
2481 }
2482 }
2483 return crv;
2484}
2485
2486/*
2487 **************************** Symetric Key utils ************************
2488 */
2489/*
2490 * set the DES key with parity bits correctly
2491 */
2492void
2493sftk_FormatDESKey(unsigned char *key, int length)
2494{
2495 int i;
2496
2497 /* format the des key */
2498 for (i = 0; i < length; i++) {
2499 key[i] = parityTable[key[i] >> 1];
2500 }
2501}
2502
2503/*
2504 * check a des key (des2 or des3 subkey) for weak keys.
2505 */
2506PRBool
2507sftk_CheckDESKey(unsigned char *key)
2508{
2509 int i;
2510
2511 /* format the des key with parity */
2512 sftk_FormatDESKey(key, 8);
2513
2514 for (i = 0; i < sftk_desWeakTableSize; i++) {
2515 if (PORT_Memcmpmemcmp(key, sftk_desWeakTable[i], 8) == 0) {
2516 return PR_TRUE1;
2517 }
2518 }
2519 return PR_FALSE0;
2520}
2521
2522/*
2523 * check if a des or triple des key is weak.
2524 */
2525PRBool
2526sftk_IsWeakKey(unsigned char *key, CK_KEY_TYPE key_type)
2527{
2528
2529 switch (key_type) {
2530 case CKK_DES0x00000013UL:
2531 return sftk_CheckDESKey(key);
2532 case CKM_DES2_KEY_GEN0x00000130UL:
2533 if (sftk_CheckDESKey(key))
2534 return PR_TRUE1;
2535 return sftk_CheckDESKey(&key[8]);
2536 case CKM_DES3_KEY_GEN0x00000131UL:
2537 if (sftk_CheckDESKey(key))
2538 return PR_TRUE1;
2539 if (sftk_CheckDESKey(&key[8]))
2540 return PR_TRUE1;
2541 return sftk_CheckDESKey(&key[16]);
2542 default:
2543 break;
2544 }
2545 return PR_FALSE0;
2546}
2547
2548/**********************************************************************
2549 *
2550 * Start of PKCS 11 functions
2551 *
2552 **********************************************************************/
2553
2554/* return the function list */
2555CK_RV
2556NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
2557{
2558 *pFunctionList = (CK_FUNCTION_LIST_PTR)&sftk_funcList_v2;
2559 return CKR_OK0x00000000UL;
2560}
2561
2562/* return the function list */
2563CK_RV
2564C_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
2565{
2566#ifdef NSS_FIPS_DISABLED
2567 return NSC_GetFunctionList(pFunctionList);
2568#else
2569 if (NSS_GetSystemFIPSEnabled()) {
2570 return FC_GetFunctionList(pFunctionList);
2571 } else {
2572 return NSC_GetFunctionList(pFunctionList);
2573 }
2574#endif
2575}
2576
2577CK_RV
2578NSC_GetInterfaceList(CK_INTERFACE_PTR interfaces, CK_ULONG_PTR pulCount)
2579{
2580 CK_ULONG count = *pulCount;
2581 *pulCount = NSS_INTERFACE_COUNT5;
2582 if (interfaces == NULL((void*)0)) {
2583 return CKR_OK0x00000000UL;
2584 }
2585 if (count < NSS_INTERFACE_COUNT5) {
2586 return CKR_BUFFER_TOO_SMALL0x00000150UL;
2587 }
2588 PORT_Memcpymemcpy(interfaces, nss_interfaces, sizeof(nss_interfaces));
2589 return CKR_OK0x00000000UL;
2590}
2591
2592CK_RV
2593C_GetInterfaceList(CK_INTERFACE_PTR interfaces, CK_ULONG_PTR pulCount)
2594{
2595#ifdef NSS_FIPS_DISABLED
2596 return NSC_GetInterfaceList(interfaces, pulCount);
2597#else
2598 if (NSS_GetSystemFIPSEnabled()) {
2599 return FC_GetInterfaceList(interfaces, pulCount);
2600 } else {
2601 return NSC_GetInterfaceList(interfaces, pulCount);
2602 }
2603#endif
2604}
2605
2606/*
2607 * Get the requested interface, use the nss_interfaces array so we can
2608 * easily add new interfaces as they occur.
2609 */
2610CK_RV
2611NSC_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion,
2612 CK_INTERFACE_PTR_PTR ppInterface, CK_FLAGS flags)
2613{
2614 int i;
2615 for (i = 0; i < NSS_INTERFACE_COUNT5; i++) {
2616 CK_INTERFACE_PTR interface = &nss_interfaces[i];
2617 if (pInterfaceName && PORT_Strcmpstrcmp((char *)pInterfaceName, (char *)interface->pInterfaceName) != 0) {
2618 continue;
2619 }
2620 if (pVersion && PORT_Memcmpmemcmp(pVersion, (CK_VERSION *)interface->pFunctionList, sizeof(CK_VERSION)) != 0) {
2621 continue;
2622 }
2623 if (flags & ((interface->flags & flags) != flags)) {
2624 continue;
2625 }
2626 *ppInterface = interface;
2627 return CKR_OK0x00000000UL;
2628 }
2629 return CKR_ARGUMENTS_BAD0x00000007UL;
2630}
2631
2632CK_RV
2633C_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion,
2634 CK_INTERFACE_PTR_PTR ppInterface, CK_FLAGS flags)
2635{
2636#ifdef NSS_FIPS_DISABLED
2637 return NSC_GetInterface(pInterfaceName, pVersion, ppInterface, flags);
2638#else
2639 if (NSS_GetSystemFIPSEnabled()) {
2640 return FC_GetInterface(pInterfaceName, pVersion, ppInterface, flags);
2641 } else {
2642 return NSC_GetInterface(pInterfaceName, pVersion, ppInterface, flags);
2643 }
2644#endif
2645}
2646
2647static PLHashNumber
2648sftk_HashNumber(const void *key)
2649{
2650 return (PLHashNumber)((char *)key - (char *)NULL((void*)0));
2651}
2652
2653/*
2654 * eventually I'd like to expunge all occurances of XXX_SLOT_ID and
2655 * just go with the info in the slot. This is one place, however,
2656 * where it might be a little difficult.
2657 */
2658const char *
2659sftk_getDefTokName(CK_SLOT_ID slotID)
2660{
2661 static char buf[33];
2662
2663 switch (slotID) {
2664 case NETSCAPE_SLOT_ID1:
2665 return "NSS Generic Crypto Services ";
2666 case PRIVATE_KEY_SLOT_ID2:
2667 return "NSS Certificate DB ";
2668 case FIPS_SLOT_ID3:
2669 return "NSS FIPS 140-2 Certificate DB ";
2670 default:
2671 break;
2672 }
2673 snprintf(buf, sizeof(buf), "NSS Application Token %08x ", (unsigned int)slotID);
2674 return buf;
2675}
2676
2677const char *
2678sftk_getDefSlotName(CK_SLOT_ID slotID)
2679{
2680 static char buf[65];
2681
2682 switch (slotID) {
2683 case NETSCAPE_SLOT_ID1:
2684 return "NSS Internal Cryptographic Services ";
2685 case PRIVATE_KEY_SLOT_ID2:
2686 return "NSS User Private Key and Certificate Services ";
2687 case FIPS_SLOT_ID3:
2688 return "NSS FIPS 140-2 User Private Key Services ";
2689 default:
2690 break;
2691 }
2692 snprintf(buf, sizeof(buf),
2693 "NSS Application Slot %08x ",
2694 (unsigned int)slotID);
2695 return buf;
2696}
2697
2698static CK_ULONG nscSlotCount[2] = { 0, 0 };
2699static CK_SLOT_ID_PTR nscSlotList[2] = { NULL((void*)0), NULL((void*)0) };
2700static CK_ULONG nscSlotListSize[2] = { 0, 0 };
2701static PLHashTable *nscSlotHashTable[2] = { NULL((void*)0), NULL((void*)0) };
2702
2703static unsigned int
2704sftk_GetModuleIndex(CK_SLOT_ID slotID)
2705{
2706 if (sftk_isFIPS(slotID)(((slotID) == 3) || ((slotID) >= 101))) {
2707 return NSC_FIPS_MODULE1;
2708 }
2709 return NSC_NON_FIPS_MODULE0;
2710}
2711
2712/* look up a slot structure from the ID (used to be a macro when we only
2713 * had two slots) */
2714/* if all is true, return the slot even if it has been 'unloaded' */
2715/* if all is false, only return the slots which are present */
2716SFTKSlot *
2717sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all)
2718{
2719 SFTKSlot *slot;
2720 unsigned int index = sftk_GetModuleIndex(slotID);
2721
2722 if (nscSlotHashTable[index] == NULL((void*)0))
2723 return NULL((void*)0);
2724 slot = (SFTKSlot *)PL_HashTableLookupConst(nscSlotHashTable[index],
2725 (void *)(uintptr_t)slotID);
2726 /* cleared slots shouldn't 'show up' */
2727 if (slot && !all && !slot->present)
2728 slot = NULL((void*)0);
2729 return slot;
2730}
2731
2732CK_SLOT_ID
2733sftk_SlotIDFromSessionHandle(CK_SESSION_HANDLE handle)
2734{
2735 CK_ULONG slotIDIndex = (handle >> 24) & 0x7f;
2736 CK_ULONG moduleIndex = (handle >> 31) & 1;
2737
2738 if (slotIDIndex >= nscSlotCount[moduleIndex]) {
2739 return (CK_SLOT_ID)-1;
2740 }
2741 return nscSlotList[moduleIndex][slotIDIndex];
2742}
2743
2744SFTKSlot *
2745sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle)
2746{
2747 return sftk_SlotFromID(sftk_SlotIDFromSessionHandle(handle), PR_FALSE0);
2748}
2749
2750static CK_RV
2751sftk_RegisterSlot(SFTKSlot *slot, unsigned int moduleIndex)
2752{
2753 PLHashEntry *entry;
2754 unsigned int index;
2755
2756 index = sftk_GetModuleIndex(slot->slotID);
2757
2758 /* make sure the slotID for this module is valid */
2759 if (moduleIndex != index) {
2760 return CKR_SLOT_ID_INVALID0x00000003UL;
2761 }
2762
2763 if (nscSlotList[index] == NULL((void*)0)) {
2764 nscSlotListSize[index] = NSC_SLOT_LIST_BLOCK_SIZE10;
2765 nscSlotList[index] = (CK_SLOT_ID *)
2766 PORT_ZAllocPORT_ZAlloc_Util(nscSlotListSize[index] * sizeof(CK_SLOT_ID));
2767 if (nscSlotList[index] == NULL((void*)0)) {
2768 return CKR_HOST_MEMORY0x00000002UL;
2769 }
2770 }
2771 if (nscSlotCount[index] >= nscSlotListSize[index]) {
2772 CK_SLOT_ID *oldNscSlotList = nscSlotList[index];
2773 CK_ULONG oldNscSlotListSize = nscSlotListSize[index];
2774 nscSlotListSize[index] += NSC_SLOT_LIST_BLOCK_SIZE10;
2775 nscSlotList[index] = (CK_SLOT_ID *)PORT_ReallocPORT_Realloc_Util(oldNscSlotList,
2776 nscSlotListSize[index] * sizeof(CK_SLOT_ID));
2777 if (nscSlotList[index] == NULL((void*)0)) {
2778 /* evidently coverity doesn't know realloc does not
2779 * free var if it fails ! */
2780 /* coverity [use_after_free : FALSE] */
2781 nscSlotList[index] = oldNscSlotList;
2782 nscSlotListSize[index] = oldNscSlotListSize;
2783 return CKR_HOST_MEMORY0x00000002UL;
2784 }
2785 }
2786
2787 if (nscSlotHashTable[index] == NULL((void*)0)) {
2788 nscSlotHashTable[index] = PL_NewHashTable(64, sftk_HashNumber,
2789 PL_CompareValues, PL_CompareValues, NULL((void*)0), 0);
2790 if (nscSlotHashTable[index] == NULL((void*)0)) {
2791 return CKR_HOST_MEMORY0x00000002UL;
2792 }
2793 }
2794
2795 entry = PL_HashTableAdd(nscSlotHashTable[index], (void *)(uintptr_t)slot->slotID, slot);
2796 if (entry == NULL((void*)0)) {
2797 return CKR_HOST_MEMORY0x00000002UL;
2798 }
2799 slot->index = (nscSlotCount[index] & 0x7f) | ((index << 7) & 0x80);
2800 nscSlotList[index][nscSlotCount[index]++] = slot->slotID;
2801
2802 return CKR_OK0x00000000UL;
2803}
2804
2805/*
2806 * ths function has all the common initialization that happens whenever we
2807 * create a new slot or repurpose an old slot (only valid for slotID's 4
2808 * and greater).
2809 *
2810 * things that are not reinitialized are:
2811 * slotID (can't change)
2812 * slotDescription (can't change once defined)
2813 * the locks and hash tables (difficult to change in running code, and
2814 * unnecessary. hash tables and list are cleared on shutdown, but they
2815 * are cleared in a 'friendly' way).
2816 * session and object ID counters -- so any old sessions and objects in the
2817 * application will get properly notified that the world has changed.
2818 *
2819 * things that are reinitialized:
2820 * database (otherwise what would the point be;).
2821 * state variables related to databases.
2822 * session count stat info.
2823 * tokenDescription.
2824 *
2825 * NOTE: slotID's 4 and greater show up as removable devices.
2826 *
2827 */
2828CK_RV
2829SFTK_SlotReInit(SFTKSlot *slot, char *configdir, char *updatedir,
2830 char *updateID, sftk_token_parameters *params,
2831 unsigned int moduleIndex)
2832{
2833 PRBool needLogin = !params->noKeyDB;
2834 CK_RV crv;
2835
2836 slot->hasTokens = PR_FALSE0;
2837 slot->sessionIDConflict = 0;
2838 slot->sessionCount = 0;
2839 slot->rwSessionCount = 0;
2840 slot->needLogin = PR_FALSE0;
2841 slot->isLoggedIn = PR_FALSE0;
2842 slot->ssoLoggedIn = PR_FALSE0;
2843 slot->DB_loaded = PR_FALSE0;
2844 slot->certDB = NULL((void*)0);
2845 slot->keyDB = NULL((void*)0);
2846 slot->minimumPinLen = 0;
2847 slot->readOnly = params->readOnly;
2848 sftk_setStringName(params->tokdes ? params->tokdes : sftk_getDefTokName(slot->slotID), slot->tokDescription,
2849 sizeof(slot->tokDescription), PR_TRUE1);
2850 sftk_setStringName(params->updtokdes ? params->updtokdes : " ",
2851 slot->updateTokDescription,
2852 sizeof(slot->updateTokDescription), PR_TRUE1);
2853
2854 if ((!params->noCertDB) || (!params->noKeyDB)) {
2855 SFTKDBHandle *certHandle = NULL((void*)0);
2856 SFTKDBHandle *keyHandle = NULL((void*)0);
2857 crv = sftk_DBInit(params->configdir ? params->configdir : configdir,
2858 params->certPrefix, params->keyPrefix,
2859 params->updatedir ? params->updatedir : updatedir,
2860 params->updCertPrefix, params->updKeyPrefix,
2861 params->updateID ? params->updateID : updateID,
2862 params->readOnly, params->noCertDB, params->noKeyDB,
2863 params->forceOpen,
2864 moduleIndex == NSC_FIPS_MODULE1,
2865 &certHandle, &keyHandle);
2866 if (crv != CKR_OK0x00000000UL) {
2867 goto loser;
2868 }
2869
2870 slot->certDB = certHandle;
2871 slot->keyDB = keyHandle;
2872 }
2873 if (needLogin) {
2874 /* if the data base is initialized with a null password,remember that */
2875 slot->needLogin =
2876 (PRBool)!sftk_hasNullPassword(slot, slot->keyDB);
2877 if ((params->minPW >= 0) && (params->minPW <= SFTK_MAX_PIN500)) {
2878 slot->minimumPinLen = params->minPW;
2879 }
2880 if ((slot->minimumPinLen == 0) && (params->pwRequired)) {
2881 slot->minimumPinLen = 1;
2882 }
2883 /* Make sure the pin len is set to the Minimum allowed value for fips
2884 * when in FIPS mode. NOTE: we don't set it if the database has not
2885 * been initialized yet so that we can init into level1 mode if needed
2886 */
2887 if ((sftkdb_HasPasswordSet(slot->keyDB) == SECSuccess) &&
2888 (moduleIndex == NSC_FIPS_MODULE1) &&
2889 (slot->minimumPinLen < FIPS_MIN_PIN7)) {
2890 slot->minimumPinLen = FIPS_MIN_PIN7;
2891 }
2892 }
2893
2894 slot->present = PR_TRUE1;
2895 return CKR_OK0x00000000UL;
2896
2897loser:
2898 SFTK_ShutdownSlot(slot);
2899 return crv;
2900}
2901
2902/*
2903 * initialize one of the slot structures. figure out which by the ID
2904 */
2905CK_RV
2906SFTK_SlotInit(char *configdir, char *updatedir, char *updateID,
2907 sftk_token_parameters *params, unsigned int moduleIndex)
2908{
2909 unsigned int i;
2910 CK_SLOT_ID slotID = params->slotID;
2911 SFTKSlot *slot;
2912 CK_RV crv = CKR_HOST_MEMORY0x00000002UL;
2913
2914 /*
2915 * first we initialize everything that is 'permanent' with this slot.
2916 * that is everything we aren't going to shutdown if we close this slot
2917 * and open it up again with different databases */
2918
2919 slot = PORT_ZNew(SFTKSlot)(SFTKSlot *)PORT_ZAlloc_Util(sizeof(SFTKSlot));
2920
2921 if (slot == NULL((void*)0)) {
2922 return CKR_HOST_MEMORY0x00000002UL;
2923 }
2924
2925 slot->optimizeSpace = params->optimizeSpace;
2926 if (slot->optimizeSpace) {
2927 slot->sessObjHashSize = SPACE_SESSION_OBJECT_HASH_SIZE32;
2928 slot->sessHashSize = SPACE_SESSION_HASH_SIZE32;
2929 slot->numSessionLocks = 1;
2930 } else {
2931 slot->sessObjHashSize = TIME_SESSION_OBJECT_HASH_SIZE1024;
2932 slot->sessHashSize = TIME_SESSION_HASH_SIZE1024;
2933 slot->numSessionLocks = slot->sessHashSize / BUCKETS_PER_SESSION_LOCK(1 << (1));
2934 }
2935 slot->sessionLockMask = slot->numSessionLocks - 1;
2936
2937 slot->slotLock = PZ_NewLock(nssILockSession)PR_NewLock();
2938 if (slot->slotLock == NULL((void*)0))
2939 goto mem_loser;
2940 slot->sessionLock = PORT_ZNewArray(PZLock *, slot->numSessionLocks)(PRLock * *)PORT_ZAlloc_Util(sizeof(PRLock *) * (slot->numSessionLocks
))
;
2941 if (slot->sessionLock == NULL((void*)0))
2942 goto mem_loser;
2943 for (i = 0; i < slot->numSessionLocks; i++) {
2944 slot->sessionLock[i] = PZ_NewLock(nssILockSession)PR_NewLock();
2945 if (slot->sessionLock[i] == NULL((void*)0))
2946 goto mem_loser;
2947 }
2948 slot->objectLock = PZ_NewLock(nssILockObject)PR_NewLock();
2949 if (slot->objectLock == NULL((void*)0))
2950 goto mem_loser;
2951 slot->pwCheckLock = PR_NewLock();
2952 if (slot->pwCheckLock == NULL((void*)0))
2953 goto mem_loser;
2954 slot->head = PORT_ZNewArray(SFTKSession *, slot->sessHashSize)(SFTKSession * *)PORT_ZAlloc_Util(sizeof(SFTKSession *) * (slot
->sessHashSize))
;
2955 if (slot->head == NULL((void*)0))
2956 goto mem_loser;
2957 slot->sessObjHashTable = PORT_ZNewArray(SFTKObject *, slot->sessObjHashSize)(SFTKObject * *)PORT_ZAlloc_Util(sizeof(SFTKObject *) * (slot
->sessObjHashSize))
;
2958 if (slot->sessObjHashTable == NULL((void*)0))
2959 goto mem_loser;
2960 slot->tokObjHashTable = PL_NewHashTable(64, sftk_HashNumber, PL_CompareValues,
2961 SECITEM_HashCompare, NULL((void*)0), 0);
2962 if (slot->tokObjHashTable == NULL((void*)0))
2963 goto mem_loser;
2964
2965 slot->sessionIDCount = 0;
2966 slot->sessionObjectHandleCount = NSC_MIN_SESSION_OBJECT_HANDLE1U;
2967 slot->slotID = slotID;
2968 sftk_setStringName(params->slotdes ? params->slotdes : sftk_getDefSlotName(slotID), slot->slotDescription,
2969 sizeof(slot->slotDescription), PR_TRUE1);
2970 crv = sftk_InitSession(&slot->moduleObjects, slot, slotID, NULL((void*)0), NULL((void*)0),
2971 CKF_SERIAL_SESSION0x00000004UL);
2972 if (crv != CKR_OK0x00000000UL) {
2973 goto loser;
2974 }
2975
2976 /* call the reinit code to set everything that changes between token
2977 * init calls */
2978 crv = SFTK_SlotReInit(slot, configdir, updatedir, updateID,
2979 params, moduleIndex);
2980 if (crv != CKR_OK0x00000000UL) {
2981 goto loser;
2982 }
2983 if (sftk_isFIPS(slotID)(((slotID) == 3) || ((slotID) >= 101))) {
2984 crv = sftk_CreateValidationObjects(slot);
2985 if (crv != CKR_OK0x00000000UL) {
2986 goto loser;
2987 }
2988 }
2989 crv = sftk_RegisterSlot(slot, moduleIndex);
2990 if (crv != CKR_OK0x00000000UL) {
2991 goto loser;
2992 }
2993 return CKR_OK0x00000000UL;
2994
2995mem_loser:
2996 crv = CKR_HOST_MEMORY0x00000002UL;
2997loser:
2998 SFTK_DestroySlotData(slot);
2999 return crv;
3000}
3001
3002CK_RV
3003sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout)
3004{
3005 SFTKSession *session;
3006 unsigned int i;
3007 SFTKDBHandle *handle;
3008
3009 /* first log out the card */
3010 /* special case - if we are in a middle of upgrade, we want to close the
3011 * sessions to fake a token removal to tell the upper level code we have
3012 * switched from one database to another, but we don't want to
3013 * explicity logout in case we can continue the upgrade with the
3014 * existing password if possible.
3015 */
3016 if (logout) {
3017 handle = sftk_getKeyDB(slot);
3018 SKIP_AFTER_FORK(PZ_Lock(slot->slotLock))PR_Lock((slot->slotLock));
3019 slot->isLoggedIn = PR_FALSE0;
3020 if (slot->needLogin && handle) {
3021 sftkdb_ClearPassword(handle);
3022 }
3023 SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock))PR_Unlock((slot->slotLock));
3024 if (handle) {
3025 sftk_freeDB(handle);
3026 }
3027 }
3028
3029 /* now close all the current sessions */
3030 /* NOTE: If you try to open new sessions before NSC_CloseAllSessions
3031 * completes, some of those new sessions may or may not be closed by
3032 * NSC_CloseAllSessions... but any session running when this code starts
3033 * will guarrenteed be close, and no session will be partially closed */
3034 for (i = 0; i < slot->sessHashSize; i++) {
3035 PZLockPRLock *lock = SFTK_SESSION_LOCK(slot, i)((slot)->sessionLock[(i) & (slot)->sessionLockMask]
)
;
3036 do {
3037 SKIP_AFTER_FORK(PZ_Lock(lock))PR_Lock((lock));
3038 session = slot->head[i];
3039 /* hand deque */
3040 /* this duplicates function of NSC_close session functions, but
3041 * because we know that we are freeing all the sessions, we can
3042 * do more efficient processing */
3043 if (session) {
3044 slot->head[i] = session->next;
3045 if (session->next)
3046 session->next->prev = NULL((void*)0);
3047 session->next = session->prev = NULL((void*)0);
3048 SKIP_AFTER_FORK(PZ_Unlock(lock))PR_Unlock((lock));
3049 SKIP_AFTER_FORK(PZ_Lock(slot->slotLock))PR_Lock((slot->slotLock));
3050 --slot->sessionCount;
3051 SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock))PR_Unlock((slot->slotLock));
3052 if (session->info.flags & CKF_RW_SESSION0x00000002UL) {
3053 (void)PR_ATOMIC_DECREMENT(&slot->rwSessionCount)__sync_sub_and_fetch(&slot->rwSessionCount, 1);
3054 }
3055 } else {
3056 SKIP_AFTER_FORK(PZ_Unlock(lock))PR_Unlock((lock));
3057 }
3058 if (session) {
3059 sftk_DestroySession(session);
3060 }
3061 } while (session != NULL((void*)0));
3062 }
3063 return CKR_OK0x00000000UL;
3064}
3065
3066/*
3067 * shut down the databases.
3068 * we get the slot lock (which also protects slot->certDB and slot->keyDB)
3069 * and clear the values so the new users will not find the databases.
3070 * once things are clear, we can release our references to the databases.
3071 * The databases will close when the last reference is released.
3072 *
3073 * We use reference counts so that we don't crash if someone shuts down
3074 * a token that another thread is actively using.
3075 */
3076static void
3077sftk_DBShutdown(SFTKSlot *slot)
3078{
3079 SFTKDBHandle *certHandle;
3080 SFTKDBHandle *keyHandle;
3081 SKIP_AFTER_FORK(PZ_Lock(slot->slotLock))PR_Lock((slot->slotLock));
3082 certHandle = slot->certDB;
3083 slot->certDB = NULL((void*)0);
3084 keyHandle = slot->keyDB;
3085 slot->keyDB = NULL((void*)0);
3086 SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock))PR_Unlock((slot->slotLock));
3087 if (certHandle) {
3088 sftk_freeDB(certHandle);
3089 }
3090 if (keyHandle) {
3091 sftk_freeDB(keyHandle);
3092 }
3093}
3094
3095CK_RV
3096SFTK_ShutdownSlot(SFTKSlot *slot)
3097{
3098 /* make sure no new PK11 calls work except C_GetSlotInfo */
3099 slot->present = PR_FALSE0;
3100
3101 /* close all outstanding sessions
3102 * the sessHashSize variable guarentees we have all the session
3103 * mechanism set up */
3104 if (slot->head) {
3105 sftk_CloseAllSessions(slot, PR_TRUE1);
3106 }
3107
3108 /* clear all objects.. session objects are cleared as a result of
3109 * closing all the sessions. We just need to clear the token object
3110 * cache. slot->tokObjHashTable guarentees we have the token
3111 * infrastructure set up. */
3112 if (slot->tokObjHashTable) {
3113 SFTK_ClearTokenKeyHashTable(slot);
3114 }
3115
3116 /* clear the slot description for the next guy */
3117 PORT_Memsetmemset(slot->tokDescription, 0, sizeof(slot->tokDescription));
3118
3119 /* now shut down the databases. */
3120 sftk_DBShutdown(slot);
3121 return CKR_OK0x00000000UL;
3122}
3123
3124/*
3125 * initialize one of the slot structures. figure out which by the ID
3126 */
3127CK_RV
3128SFTK_DestroySlotData(SFTKSlot *slot)
3129{
3130 unsigned int i;
3131
3132 SFTK_ShutdownSlot(slot);
3133
3134 sftk_ClearSession(&slot->moduleObjects);
3135
3136 if (slot->tokObjHashTable) {
3137 PL_HashTableDestroy(slot->tokObjHashTable);
3138 slot->tokObjHashTable = NULL((void*)0);
3139 }
3140
3141 if (slot->sessObjHashTable) {
3142 PORT_FreePORT_Free_Util(slot->sessObjHashTable);
3143 slot->sessObjHashTable = NULL((void*)0);
3144 }
3145 slot->sessObjHashSize = 0;
3146
3147 if (slot->head) {
3148 PORT_FreePORT_Free_Util(slot->head);
3149 slot->head = NULL((void*)0);
3150 }
3151 slot->sessHashSize = 0;
3152
3153 /* OK everything has been disassembled, now we can finally get rid
3154 * of the locks */
3155 SKIP_AFTER_FORK(PZ_DestroyLock(slot->slotLock))PR_DestroyLock((slot->slotLock));
3156 slot->slotLock = NULL((void*)0);
3157 if (slot->sessionLock) {
3158 for (i = 0; i < slot->numSessionLocks; i++) {
3159 if (slot->sessionLock[i]) {
3160 SKIP_AFTER_FORK(PZ_DestroyLock(slot->sessionLock[i]))PR_DestroyLock((slot->sessionLock[i]));
3161 slot->sessionLock[i] = NULL((void*)0);
3162 }
3163 }
3164 PORT_FreePORT_Free_Util(slot->sessionLock);
3165 slot->sessionLock = NULL((void*)0);
3166 }
3167 if (slot->objectLock) {
3168 SKIP_AFTER_FORK(PZ_DestroyLock(slot->objectLock))PR_DestroyLock((slot->objectLock));
3169 slot->objectLock = NULL((void*)0);
3170 }
3171 if (slot->pwCheckLock) {
3172 SKIP_AFTER_FORK(PR_DestroyLock(slot->pwCheckLock))PR_DestroyLock(slot->pwCheckLock);
3173 slot->pwCheckLock = NULL((void*)0);
3174 }
3175 PORT_FreePORT_Free_Util(slot);
3176 return CKR_OK0x00000000UL;
3177}
3178
3179/*
3180 * handle the SECMOD.db
3181 */
3182char **
3183NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args)
3184{
3185#ifndef NSS_DISABLE_DBM
3186 char *secmod = NULL((void*)0);
3187 char *appName = NULL((void*)0);
3188 char *filename = NULL((void*)0);
3189 NSSDBType dbType = NSS_DB_TYPE_NONE;
3190 PRBool rw;
3191 static char *success = "Success";
3192#endif /* NSS_DISABLE_DBM */
3193 char **rvstr = NULL((void*)0);
3194
3195 rvstr = NSSUTIL_DoModuleDBFunction(function, parameters, args);
3196 if (rvstr != NULL((void*)0)) {
3197 return rvstr;
3198 }
3199
3200 if (PORT_GetErrorPORT_GetError_Util() != SEC_ERROR_LEGACY_DATABASE) {
3201 return NULL((void*)0);
3202 }
3203
3204#ifndef NSS_DISABLE_DBM
3205 /* The legacy database uses the old dbm, which is only linked with the
3206 * legacy DB handler, which is only callable from softoken */
3207
3208 secmod = _NSSUTIL_GetSecmodName(parameters, &dbType, &appName,
3209 &filename, &rw);
3210
3211 switch (function) {
3212 case SECMOD_MODULE_DB_FUNCTION_FIND0:
3213 if (secmod == NULL((void*)0)) {
3214 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
3215 goto loser;
3216 }
3217 if (rw && (dbType != NSS_DB_TYPE_LEGACY) &&
3218 (dbType != NSS_DB_TYPE_MULTIACCESS)) {
3219 /* if we get here, we are trying to update the local database */
3220 /* force data from the legacy DB */
3221 char *oldSecmod = NULL((void*)0);
3222 char *oldAppName = NULL((void*)0);
3223 char *oldFilename = NULL((void*)0);
3224 PRBool oldrw;
3225 char **strings = NULL((void*)0);
3226 int i;
3227
3228 dbType = NSS_DB_TYPE_LEGACY;
3229 oldSecmod = _NSSUTIL_GetSecmodName(parameters, &dbType, &oldAppName,
3230 &oldFilename, &oldrw);
3231 strings = sftkdbCall_ReadSecmodDB(appName, oldFilename, oldSecmod,
3232 (char *)parameters, oldrw);
3233 if (strings) {
3234 /* write out the strings */
3235 for (i = 0; strings[i]; i++) {
3236 NSSUTIL_DoModuleDBFunction(SECMOD_MODULE_DB_FUNCTION_ADD1,
3237 parameters, strings[i]);
3238 }
3239 sftkdbCall_ReleaseSecmodDBData(oldAppName, oldFilename, oldSecmod,
3240 (char **)strings, oldrw);
3241 } else {
3242 /* write out a dummy record */
3243 NSSUTIL_DoModuleDBFunction(SECMOD_MODULE_DB_FUNCTION_ADD1,
3244 parameters, " ");
3245 }
3246 if (oldSecmod) {
3247 PR_smprintf_free(oldSecmod);
3248 }
3249 if (oldAppName) {
3250 PORT_FreePORT_Free_Util(oldAppName);
3251 }
3252 if (oldFilename) {
3253 PORT_FreePORT_Free_Util(oldFilename);
3254 }
3255 rvstr = NSSUTIL_DoModuleDBFunction(function, parameters, args);
3256 break;
3257 }
3258 rvstr = sftkdbCall_ReadSecmodDB(appName, filename, secmod,
3259 (char *)parameters, rw);
3260 break;
3261 case SECMOD_MODULE_DB_FUNCTION_ADD1:
3262 if (secmod == NULL((void*)0)) {
3263 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
3264 goto loser;
3265 }
3266 rvstr = (sftkdbCall_AddSecmodDB(appName, filename, secmod,
3267 (char *)args, rw) == SECSuccess)
3268 ? &success
3269 : NULL((void*)0);
3270 break;
3271 case SECMOD_MODULE_DB_FUNCTION_DEL2:
3272 if (secmod == NULL((void*)0)) {
3273 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
3274 goto loser;
3275 }
3276 rvstr = (sftkdbCall_DeleteSecmodDB(appName, filename, secmod,
3277 (char *)args, rw) == SECSuccess)
3278 ? &success
3279 : NULL((void*)0);
3280 break;
3281 case SECMOD_MODULE_DB_FUNCTION_RELEASE3:
3282 rvstr = (sftkdbCall_ReleaseSecmodDBData(appName, filename, secmod,
3283 (char **)args, rw) == SECSuccess)
3284 ? &success
3285 : NULL((void*)0);
3286 break;
3287 }
3288
3289loser:
3290 if (secmod)
3291 PR_smprintf_free(secmod);
3292 if (appName)
3293 PORT_FreePORT_Free_Util(appName);
3294 if (filename)
3295 PORT_FreePORT_Free_Util(filename);
3296#endif /* NSS_DISABLE_DBM */
3297 return rvstr;
3298}
3299
3300static void
3301nscFreeAllSlots(unsigned int moduleIndex)
3302{
3303 /* free all the slots */
3304 SFTKSlot *slot = NULL((void*)0);
3305 CK_SLOT_ID slotID;
3306 int i;
3307
3308 if (nscSlotList[moduleIndex]) {
3309 CK_ULONG tmpSlotCount = nscSlotCount[moduleIndex];
3310 CK_SLOT_ID_PTR tmpSlotList = nscSlotList[moduleIndex];
3311 PLHashTable *tmpSlotHashTable = nscSlotHashTable[moduleIndex];
3312
3313 /* first close all the session */
3314 for (i = 0; i < (int)tmpSlotCount; i++) {
3315 slotID = tmpSlotList[i];
3316 (void)NSC_CloseAllSessions(slotID);
3317 }
3318
3319 /* now clear out the statics */
3320 nscSlotList[moduleIndex] = NULL((void*)0);
3321 nscSlotCount[moduleIndex] = 0;
3322 nscSlotHashTable[moduleIndex] = NULL((void*)0);
3323 nscSlotListSize[moduleIndex] = 0;
3324
3325 for (i = 0; i < (int)tmpSlotCount; i++) {
3326 slotID = tmpSlotList[i];
3327 slot = (SFTKSlot *)
3328 PL_HashTableLookup(tmpSlotHashTable, (void *)(uintptr_t)slotID);
3329 PORT_Assert(slot)((slot)?((void)0):PR_Assert("slot","pkcs11.c",3329));
3330 if (!slot)
3331 continue;
3332 SFTK_DestroySlotData(slot);
3333 PL_HashTableRemove(tmpSlotHashTable, (void *)(uintptr_t)slotID);
3334 }
3335 PORT_FreePORT_Free_Util(tmpSlotList);
3336 PL_HashTableDestroy(tmpSlotHashTable);
3337 }
3338}
3339
3340static void
3341sftk_closePeer(PRBool isFIPS)
3342{
3343 CK_SLOT_ID slotID = isFIPS ? PRIVATE_KEY_SLOT_ID2 : FIPS_SLOT_ID3;
3344 SFTKSlot *slot;
3345 unsigned int moduleIndex = isFIPS ? NSC_NON_FIPS_MODULE0 : NSC_FIPS_MODULE1;
3346 PLHashTable *tmpSlotHashTable = nscSlotHashTable[moduleIndex];
3347
3348 slot = (SFTKSlot *)PL_HashTableLookup(tmpSlotHashTable, (void *)(uintptr_t)slotID);
3349 if (slot == NULL((void*)0)) {
3350 return;
3351 }
3352 sftk_DBShutdown(slot);
3353 return;
3354}
3355
3356extern void sftk_PBELockInit(void);
3357extern void sftk_PBELockShutdown(void);
3358
3359/* Parse the library parameters from the first occurance in the following src.:
3360 * 1. C_INITIALIZED_ARGS - lib params are included in LibraryParameters field
3361 * 2. NSS_LIB_PARAMS - env. var. containing the lib. params.
3362 * 3. NSS_LIB_PARAMS_FILE - env. var. pointion to a file with lib. params.
3363 * 4. /etc/nss/params.config - default lib. param. file location [Linux only]
3364 * 5. LIB_PARAM_DEFAULT - string ensureing the pressence at all times
3365 * "configdir='' certPrefix='' keyPrefix='' secmod='' flags=noCertDB,noModDB"
3366 */
3367static CK_RV
3368sftk_getParameters(CK_C_INITIALIZE_ARGS *init_args, PRBool isFIPS,
3369 sftk_parameters *paramStrings)
3370{
3371 CK_RV crv;
3372 char *libParams;
3373 const char *filename;
3374 PRFileDesc *file_dc;
3375 PRBool free_mem = PR_FALSE0;
3376
3377 if (!init_args || !init_args->LibraryParameters) {
3378 /* Library parameters were not provided via C_Initialize_args*/
3379
3380 /* Enviromental value has precedence to configuration filename */
3381 libParams = PR_GetEnvSecure("NSS_LIB_PARAMS");
3382
3383 if (!libParams) {
3384 /* Load from config filename or use default */
3385 filename = PR_GetEnvSecure("NSS_LIB_PARAMS_FILE");
3386#ifdef XP_UNIX1
3387 /* Use default configuration file for Linux only */
3388 if (!filename)
3389 filename = LIB_PARAM_DEFAULT_FILE_LOCATION"/etc/nss/params.config";
3390#endif
3391 if (filename) {
3392 file_dc = PR_OpenFile(filename, PR_RDONLY0x01, 444);
3393 if (file_dc) {
3394 /* file opened */
3395 PRInt32 len = PR_Available(file_dc);
3396 libParams = PORT_NewArray(char, len + 1)(char *)PORT_Alloc_Util(sizeof(char) * (len + 1));
3397 if (libParams) {
3398 /* memory allocated */
3399 if (PR_Read(file_dc, libParams, len) == -1) {
3400 PORT_FreePORT_Free_Util(libParams);
3401 libParams = NULL((void*)0);
3402 } else {
3403 free_mem = PR_TRUE1;
3404 libParams[len] = '\0';
3405 }
3406 }
3407
3408 PR_Close(file_dc);
3409 }
3410 }
3411 }
3412
3413 if (libParams == NULL((void*)0))
3414 libParams = LIB_PARAM_DEFAULT" configdir='' certPrefix='' keyPrefix='' secmod='' flags=noCertDB,noModDB ";
3415
3416 } else {
3417 /* Use parameters provided with C_Initialize_args */
3418 libParams = (char *)init_args->LibraryParameters;
3419 }
3420
3421 crv = sftk_parseParameters(libParams, paramStrings, isFIPS);
3422 if (crv != CKR_OK0x00000000UL) {
3423 crv = CKR_ARGUMENTS_BAD0x00000007UL;
3424 goto loser;
3425 }
3426
3427 crv = CKR_OK0x00000000UL;
3428loser:
3429 if (free_mem)
3430 PORT_FreePORT_Free_Util(libParams);
3431
3432 return crv;
3433}
3434
3435/* NSC_Initialize initializes the Cryptoki library. */
3436CK_RV
3437nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
3438{
3439 CK_RV crv = CKR_OK0x00000000UL;
3440 SECStatus rv;
3441 CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *)pReserved;
3442 PRBool destroy_freelist_on_error = PR_TRUE1;
3443 int i;
3444 unsigned int moduleIndex = isFIPS ? NSC_FIPS_MODULE1 : NSC_NON_FIPS_MODULE0;
3445
3446 if (isFIPS) {
3447 loginWaitTime = PR_SecondsToInterval(1);
3448 }
3449
3450 ENABLE_FORK_CHECK();
3451
3452 sftk_PBELockInit();
3453
3454 rv = SECOID_Init();
3455 if (rv != SECSuccess) {
3456 crv = CKR_DEVICE_ERROR0x00000030UL;
3457 return crv;
3458 }
3459
3460 rv = RNG_RNGInit(); /* initialize random number generator */
3461 if (rv != SECSuccess) {
3462 crv = CKR_DEVICE_ERROR0x00000030UL;
3463 return crv;
3464 }
3465 rv = BL_Init(); /* initialize freebl engine */
3466 if (rv != SECSuccess) {
3467 crv = CKR_DEVICE_ERROR0x00000030UL;
3468 return crv;
3469 }
3470
3471 /* NOTE:
3472 * we should be getting out mutexes from this list, not statically binding
3473 * them from NSPR. This should happen before we allow the internal to split
3474 * off from the rest on NSS.
3475 */
3476
3477 /* initialize the key and cert db's */
3478 if (init_args && (!(init_args->flags & CKF_OS_LOCKING_OK0x00000002UL))) {
3479 if (init_args->CreateMutex && init_args->DestroyMutex &&
3480 init_args->LockMutex && init_args->UnlockMutex) {
3481 /* softoken always uses NSPR (ie. OS locking), and doesn't know how
3482 * to use the lock functions provided by the application.
3483 */
3484 crv = CKR_CANT_LOCK0x0000000AUL;
3485 return crv;
3486 }
3487 if (init_args->CreateMutex || init_args->DestroyMutex ||
3488 init_args->LockMutex || init_args->UnlockMutex) {
3489 /* only some of the lock functions were provided by the
3490 * application. This is invalid per PKCS#11 spec.
3491 */
3492 crv = CKR_ARGUMENTS_BAD0x00000007UL;
3493 return crv;
3494 }
3495 }
3496
3497 sftk_parameters paramStrings;
3498
3499 /* load and parse the library parameters */
3500 crv = sftk_getParameters(init_args, isFIPS, &paramStrings);
3501 if (crv != CKR_OK0x00000000UL) {
3502 goto loser;
3503 }
3504
3505 crv = sftk_configure(paramStrings.man, paramStrings.libdes);
3506 if (crv != CKR_OK0x00000000UL) {
3507 goto loser;
3508 }
3509
3510 /* if we have a peer already open, have him close his DB's so we
3511 * don't clobber each other. */
3512 if ((isFIPS && nsc_init) || (!isFIPS && nsf_init)) {
3513 sftk_closePeer(isFIPS);
3514 if (sftk_audit_enabled) {
3515 if (isFIPS && nsc_init) {
3516 sftk_LogAuditMessage(NSS_AUDIT_INFO, NSS_AUDIT_FIPS_STATE,
3517 "enabled FIPS mode");
3518 } else {
3519 sftk_LogAuditMessage(NSS_AUDIT_INFO, NSS_AUDIT_FIPS_STATE,
3520 "disabled FIPS mode");
3521 }
3522 }
3523 /* if we have a peer open, we don't want to destroy the freelist
3524 * from under the peer if we fail, the free list will be
3525 * destroyed in that case when the C_Finalize is called for
3526 * the peer */
3527 destroy_freelist_on_error = PR_FALSE0;
3528 }
3529 /* allow us to create objects in SFTK_SlotInit */
3530 sftk_InitFreeLists();
3531
3532 for (i = 0; i < paramStrings.token_count; i++) {
3533 crv = SFTK_SlotInit(paramStrings.configdir,
3534 paramStrings.updatedir, paramStrings.updateID,
3535 &paramStrings.tokens[i], moduleIndex);
3536 if (crv != CKR_OK0x00000000UL) {
3537 nscFreeAllSlots(moduleIndex);
3538 break;
3539 }
3540 }
3541
3542loser:
3543
3544 sftk_freeParams(&paramStrings);
3545
3546 if (destroy_freelist_on_error && (CKR_OK0x00000000UL != crv)) {
3547 /* idempotent. If the list are already freed, this is a noop */
3548 sftk_CleanupFreeLists();
3549 }
3550
3551#ifndef NO_FORK_CHECK
3552 if (CKR_OK0x00000000UL == crv) {
3553#if defined(CHECK_FORK_MIXED)
3554 /* Before Solaris 10, fork handlers are not unregistered at dlclose()
3555 * time. So, we only use pthread_atfork on Solaris 10 and later. For
3556 * earlier versions, we use PID checks.
3557 */
3558 char buf[200];
3559 int major = 0, minor = 0;
3560
3561 long rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
3562 if (rv > 0 && rv < sizeof(buf)) {
3563 if (2 == sscanf(buf, "%d.%d", &major, &minor)) {
3564 /* Are we on Solaris 10 or greater ? */
3565 if (major > 5 || (5 == major && minor >= 10)) {
3566 /* we are safe to use pthread_atfork */
3567 usePthread_atfork = PR_TRUE1;
3568 }
3569 }
3570 }
3571 if (usePthread_atfork) {
3572 pthread_atfork(NULL((void*)0), NULL((void*)0), ForkedChild);
3573 } else {
3574 myPid = getpid();
3575 }
3576
3577#elif defined(CHECK_FORK_PTHREAD)
3578 pthread_atfork(NULL((void*)0), NULL((void*)0), ForkedChild);
3579#elif defined(CHECK_FORK_GETPID)
3580 myPid = getpid();
3581#else
3582#error Incorrect fork check method.
3583#endif
3584 }
3585#endif
3586 return crv;
3587}
3588
3589CK_RV
3590NSC_Initialize(CK_VOID_PTR pReserved)
3591{
3592 CK_RV crv;
3593
3594 sftk_ForkReset(pReserved, &crv);
3595
3596 if (nsc_init) {
3597 return CKR_CRYPTOKI_ALREADY_INITIALIZED0x00000191UL;
3598 }
3599 crv = nsc_CommonInitialize(pReserved, PR_FALSE0);
3600 nsc_init = (PRBool)(crv == CKR_OK0x00000000UL);
3601 return crv;
3602}
3603
3604/* NSC_Finalize indicates that an application is done with the
3605 * Cryptoki library.*/
3606CK_RV
3607nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS)
3608{
3609 /* propagate the fork status to freebl and util */
3610 BL_SetForkState(parentForkedAfterC_Initialize);
3611 UTIL_SetForkState(parentForkedAfterC_Initialize);
3612
3613 nscFreeAllSlots(isFIPS ? NSC_FIPS_MODULE1 : NSC_NON_FIPS_MODULE0);
3614
3615 /* don't muck with the globals if our peer is still initialized */
3616 if (isFIPS && nsc_init) {
3617 return CKR_OK0x00000000UL;
3618 }
3619 if (!isFIPS && nsf_init) {
3620 return CKR_OK0x00000000UL;
3621 }
3622
3623 sftk_CleanupFreeLists();
3624 sftkdb_Shutdown();
3625
3626 /* This function does not discard all our previously aquired entropy. */
3627 RNG_RNGShutdown();
3628
3629 /* tell freeBL to clean up after itself */
3630 BL_Cleanup();
3631
3632 /* reset fork status in freebl. We must do this before BL_Unload so that
3633 * this call doesn't force freebl to be reloaded. */
3634 BL_SetForkState(PR_FALSE0);
3635
3636#ifndef NSS_STATIC_SOFTOKEN
3637 /* unload freeBL shared library from memory. This may only decrement the
3638 * OS refcount if it's been loaded multiple times, eg. by libssl */
3639 BL_Unload();
3640#endif
3641
3642 /* clean up the default OID table */
3643 SECOID_Shutdown();
3644
3645 sftk_PBELockShutdown();
3646
3647 /* reset fork status in util */
3648 UTIL_SetForkState(PR_FALSE0);
3649
3650 nsc_init = PR_FALSE0;
3651
3652#ifndef NO_FORK_CHECK
3653#ifdef CHECK_FORK_MIXED
3654 if (!usePthread_atfork) {
3655 myPid = 0; /* allow CHECK_FORK in the next softoken initialization to
3656 * succeed */
3657 } else {
3658 forked = PR_FALSE0; /* allow reinitialization */
3659 }
3660#elif defined(CHECK_FORK_GETPID)
3661 myPid = 0; /* allow reinitialization */
3662#elif defined(CHECK_FORK_PTHREAD)
3663 forked = PR_FALSE0; /* allow reinitialization */
3664#endif
3665#endif
3666 return CKR_OK0x00000000UL;
3667}
3668
3669/* Hard-reset the entire softoken PKCS#11 module if the parent process forked
3670 * while it was initialized. */
3671PRBool
3672sftk_ForkReset(CK_VOID_PTR pReserved, CK_RV *crv)
3673{
3674#ifndef NO_FORK_CHECK
3675 if (PARENT_FORKED()) {
3676 parentForkedAfterC_Initialize = PR_TRUE1;
3677 if (nsc_init) {
3678 /* finalize non-FIPS token */
3679 *crv = nsc_CommonFinalize(pReserved, PR_FALSE0);
3680 PORT_Assert(CKR_OK == *crv)((0x00000000UL == *crv)?((void)0):PR_Assert("CKR_OK == *crv",
"pkcs11.c",3680))
;
3681 nsc_init = (PRBool) !(*crv == CKR_OK0x00000000UL);
3682 }
3683 if (nsf_init) {
3684 /* finalize FIPS token */
3685 *crv = nsc_CommonFinalize(pReserved, PR_TRUE1);
3686 PORT_Assert(CKR_OK == *crv)((0x00000000UL == *crv)?((void)0):PR_Assert("CKR_OK == *crv",
"pkcs11.c",3686))
;
3687 nsf_init = (PRBool) !(*crv == CKR_OK0x00000000UL);
3688 }
3689 parentForkedAfterC_Initialize = PR_FALSE0;
3690 return PR_TRUE1;
3691 }
3692#endif
3693 return PR_FALSE0;
3694}
3695
3696/* NSC_Finalize indicates that an application is done with the
3697 * Cryptoki library.*/
3698CK_RV
3699NSC_Finalize(CK_VOID_PTR pReserved)
3700{
3701 CK_RV crv;
3702
3703 /* reset entire PKCS#11 module upon fork */
3704 if (sftk_ForkReset(pReserved, &crv)) {
3705 return crv;
3706 }
3707
3708 if (!nsc_init) {
3709 return CKR_OK0x00000000UL;
3710 }
3711
3712 crv = nsc_CommonFinalize(pReserved, PR_FALSE0);
3713
3714 nsc_init = (PRBool) !(crv == CKR_OK0x00000000UL);
3715
3716 return crv;
3717}
3718
3719extern const char __nss_softokn_version[];
3720
3721/* NSC_GetInfo returns general information about Cryptoki. */
3722CK_RV
3723NSC_GetInfo(CK_INFO_PTR pInfo)
3724{
3725#define NSS_VERSION_VARIABLE __nss_softokn_version
3726#include "verref.h"
3727
3728 CHECK_FORK();
3729
3730 pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR3;
3731 pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR0;
3732 PORT_Memcpymemcpy(pInfo->manufacturerID, manufacturerID, 32);
3733 pInfo->libraryVersion.major = SOFTOKEN_VMAJOR3;
3734 pInfo->libraryVersion.minor = SOFTOKEN_VMINOR101;
3735 PORT_Memcpymemcpy(pInfo->libraryDescription, libraryDescription, 32);
3736 pInfo->flags = 0;
3737 return CKR_OK0x00000000UL;
3738}
3739
3740/* NSC_GetInfo returns general information about Cryptoki. */
3741CK_RV
3742NSC_GetInfoV2(CK_INFO_PTR pInfo)
3743{
3744 CHECK_FORK();
3745
3746 pInfo->cryptokiVersion.major = 2;
3747 pInfo->cryptokiVersion.minor = 40;
3748 PORT_Memcpymemcpy(pInfo->manufacturerID, manufacturerID, 32);
3749 pInfo->libraryVersion.major = SOFTOKEN_VMAJOR3;
3750 pInfo->libraryVersion.minor = SOFTOKEN_VMINOR101;
3751 PORT_Memcpymemcpy(pInfo->libraryDescription, libraryDescription, 32);
3752 pInfo->flags = 0;
3753 return CKR_OK0x00000000UL;
3754}
3755
3756/* NSC_GetSlotList obtains a list of slots in the system. */
3757CK_RV
3758nsc_CommonGetSlotList(CK_BBOOL tokenPresent,
3759 CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount,
3760 unsigned int moduleIndex)
3761{
3762 *pulCount = nscSlotCount[moduleIndex];
3763 if (pSlotList != NULL((void*)0)) {
3764 PORT_Memcpymemcpy(pSlotList, nscSlotList[moduleIndex],
3765 nscSlotCount[moduleIndex] * sizeof(CK_SLOT_ID));
3766 }
3767 return CKR_OK0x00000000UL;
3768}
3769
3770/* NSC_GetSlotList obtains a list of slots in the system. */
3771CK_RV
3772NSC_GetSlotList(CK_BBOOL tokenPresent,
3773 CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
3774{
3775 CHECK_FORK();
3776 return nsc_CommonGetSlotList(tokenPresent, pSlotList, pulCount,
3777 NSC_NON_FIPS_MODULE0);
3778}
3779
3780/* NSC_GetSlotInfo obtains information about a particular slot in the system. */
3781CK_RV
3782NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
3783{
3784 SFTKSlot *slot = sftk_SlotFromID(slotID, PR_TRUE1);
3785
3786 CHECK_FORK();
3787
3788 if (slot == NULL((void*)0))
3789 return CKR_SLOT_ID_INVALID0x00000003UL;
3790
3791 PORT_Memcpymemcpy(pInfo->manufacturerID, manufacturerID,
3792 sizeof(pInfo->manufacturerID));
3793 PORT_Memcpymemcpy(pInfo->slotDescription, slot->slotDescription,
3794 sizeof(pInfo->slotDescription));
3795 pInfo->flags = (slot->present) ? CKF_TOKEN_PRESENT0x00000001UL : 0;
3796
3797 /* all user defined slots are defined as removable */
3798 if (slotID >= SFTK_MIN_USER_SLOT_ID4) {
3799 pInfo->flags |= CKF_REMOVABLE_DEVICE0x00000002UL;
3800 } else {
3801 /* In the case where we are doing a merge update, we need
3802 * the DB slot to be removable so the token name can change
3803 * appropriately. */
3804 SFTKDBHandle *handle = sftk_getKeyDB(slot);
3805 if (handle) {
3806 if (sftkdb_InUpdateMerge(handle)) {
3807 pInfo->flags |= CKF_REMOVABLE_DEVICE0x00000002UL;
3808 }
3809 sftk_freeDB(handle);
3810 }
3811 }
3812
3813 /* If there is no key database, this is for example the case when NSS was
3814 * initialized with NSS_NoDbInit(), then there won't be any point in
3815 * requesting a PIN. Set the CKF_USER_PIN_INITIALIZED bit so that
3816 * PK11_NeedUserInit() doesn't indicate that a PIN is needed.
3817 */
3818 if (slot->keyDB == NULL((void*)0)) {
3819 pInfo->flags |= CKF_USER_PIN_INITIALIZED0x00000008UL;
3820 }
3821
3822 /* ok we really should read it out of the keydb file. */
3823 /* pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION; */
3824 pInfo->hardwareVersion.major = SOFTOKEN_VMAJOR3;
3825 pInfo->hardwareVersion.minor = SOFTOKEN_VMINOR101;
3826 pInfo->firmwareVersion.major = SOFTOKEN_VPATCH0;
3827 pInfo->firmwareVersion.minor = SOFTOKEN_VBUILD0;
3828 return CKR_OK0x00000000UL;
3829}
3830
3831/*
3832 * check the current state of the 'needLogin' flag in case the database has
3833 * been changed underneath us.
3834 */
3835static PRBool
3836sftk_checkNeedLogin(SFTKSlot *slot, SFTKDBHandle *keyHandle)
3837{
3838 PRBool needLogin;
3839 if (sftkdb_PWCached(keyHandle) == SECSuccess) {
3840 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
3841 needLogin = slot->needLogin;
3842 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
3843 } else {
3844 needLogin = (PRBool)!sftk_hasNullPassword(slot, keyHandle);
3845 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
3846 slot->needLogin = needLogin;
3847 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
3848 }
3849 return needLogin;
3850}
3851
3852static PRBool
3853sftk_isBlank(const char *s, int len)
3854{
3855 int i;
3856 for (i = 0; i < len; i++) {
3857 if (s[i] != ' ') {
3858 return PR_FALSE0;
3859 }
3860 }
3861 return PR_TRUE1;
3862}
3863
3864/* NSC_GetTokenInfo obtains information about a particular token in
3865 * the system. */
3866CK_RV
3867NSC_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
3868{
3869 SFTKSlot *slot;
3870 SFTKDBHandle *handle;
3871
3872 CHECK_FORK();
3873
3874 if (!nsc_init && !nsf_init)
3875 return CKR_CRYPTOKI_NOT_INITIALIZED0x00000190UL;
3876 slot = sftk_SlotFromID(slotID, PR_FALSE0);
3877 if (slot == NULL((void*)0))
3878 return CKR_SLOT_ID_INVALID0x00000003UL;
3879
3880 PORT_Memcpymemcpy(pInfo->manufacturerID, manufacturerID, 32);
3881 PORT_Memcpymemcpy(pInfo->model, "NSS 3 ", 16);
3882 PORT_Memcpymemcpy(pInfo->serialNumber, "0000000000000000", 16);
3883 PORT_Memcpymemcpy(pInfo->utcTime, "0000000000000000", 16);
3884 pInfo->ulMaxSessionCount = 0; /* arbitrarily large */
3885 pInfo->ulMaxRwSessionCount = 0; /* arbitarily large */
3886 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock)); /* Protect sessionCount / rwSessioncount */
3887 pInfo->ulSessionCount = slot->sessionCount;
3888 pInfo->ulRwSessionCount = slot->rwSessionCount;
3889 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock)); /* Unlock before sftk_getKeyDB */
3890 pInfo->firmwareVersion.major = 0;
3891 pInfo->firmwareVersion.minor = 0;
3892 PORT_Memcpymemcpy(pInfo->label, slot->tokDescription, sizeof(pInfo->label));
3893 handle = sftk_getKeyDB(slot);
3894 pInfo->flags = CKF_RNG0x00000001UL | CKF_DUAL_CRYPTO_OPERATIONS0x00000200UL;
3895 if (handle == NULL((void*)0)) {
3896 pInfo->flags |= CKF_WRITE_PROTECTED0x00000002UL;
3897 pInfo->ulMaxPinLen = 0;
3898 pInfo->ulMinPinLen = 0;
3899 pInfo->ulTotalPublicMemory = 0;
3900 pInfo->ulFreePublicMemory = 0;
3901 pInfo->ulTotalPrivateMemory = 0;
3902 pInfo->ulFreePrivateMemory = 0;
3903 pInfo->hardwareVersion.major = 4;
3904 pInfo->hardwareVersion.minor = 0;
3905 } else {
3906 /*
3907 * we have three possible states which we may be in:
3908 * (1) No DB password has been initialized. This also means we
3909 * have no keys in the key db.
3910 * (2) Password initialized to NULL. This means we have keys, but
3911 * the user has chosen not use a password.
3912 * (3) Finally we have an initialized password whicn is not NULL, and
3913 * we will need to prompt for it.
3914 */
3915 if (sftkdb_HasPasswordSet(handle) == SECFailure) {
3916 pInfo->flags |= CKF_LOGIN_REQUIRED0x00000004UL;
3917 } else if (!sftk_checkNeedLogin(slot, handle)) {
3918 pInfo->flags |= CKF_USER_PIN_INITIALIZED0x00000008UL;
3919 } else {
3920 pInfo->flags |= CKF_LOGIN_REQUIRED0x00000004UL | CKF_USER_PIN_INITIALIZED0x00000008UL;
3921 /*
3922 * if we are doing a merge style update, and we need to get the password
3923 * of our source database (the database we are updating from), make sure we
3924 * return a token name that will match the database we are prompting for.
3925 */
3926 if (sftkdb_NeedUpdateDBPassword(handle)) {
3927 /* if we have an update tok description, use it. otherwise
3928 * use the updateID for this database */
3929 if (!sftk_isBlank(slot->updateTokDescription,
3930 sizeof(pInfo->label))) {
3931 PORT_Memcpymemcpy(pInfo->label, slot->updateTokDescription,
3932 sizeof(pInfo->label));
3933 } else {
3934 /* build from updateID */
3935 const char *updateID = sftkdb_GetUpdateID(handle);
3936 if (updateID) {
3937 sftk_setStringName(updateID, (char *)pInfo->label,
3938 sizeof(pInfo->label), PR_FALSE0);
3939 }
3940 }
3941 }
3942 }
3943 pInfo->ulMaxPinLen = SFTK_MAX_PIN500;
3944 pInfo->ulMinPinLen = (CK_ULONG)slot->minimumPinLen;
3945 pInfo->ulTotalPublicMemory = 1;
3946 pInfo->ulFreePublicMemory = 1;
3947 pInfo->ulTotalPrivateMemory = 1;
3948 pInfo->ulFreePrivateMemory = 1;
3949#ifdef SHDB_FIXME
3950 pInfo->hardwareVersion.major = CERT_DB_FILE_VERSION;
3951 pInfo->hardwareVersion.minor = handle->version;
3952#else
3953 pInfo->hardwareVersion.major = 0;
3954 pInfo->hardwareVersion.minor = 0;
3955#endif
3956 sftk_freeDB(handle);
3957 }
3958 /*
3959 * CKF_LOGIN_REQUIRED CKF_USER_PIN_INITIALIZED how CKF_TOKEN_INITIALIZED
3960 * should be set
3961 * 0 0 1
3962 * 1 0 0
3963 * 0 1 1
3964 * 1 1 1
3965 */
3966 if (!(pInfo->flags & CKF_LOGIN_REQUIRED0x00000004UL) ||
3967 (pInfo->flags & CKF_USER_PIN_INITIALIZED0x00000008UL)) {
3968 pInfo->flags |= CKF_TOKEN_INITIALIZED0x00000400UL;
3969 }
3970 return CKR_OK0x00000000UL;
3971}
3972
3973/* NSC_GetMechanismList obtains a list of mechanism types
3974 * supported by a token. */
3975CK_RV
3976NSC_GetMechanismList(CK_SLOT_ID slotID,
3977 CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount)
3978{
3979 CK_ULONG i;
3980
3981 CHECK_FORK();
3982
3983 switch (slotID) {
3984 /* default: */
3985 case NETSCAPE_SLOT_ID1:
3986 *pulCount = mechanismCount;
3987 if (pMechanismList != NULL((void*)0)) {
3988 for (i = 0; i < mechanismCount; i++) {
3989 pMechanismList[i] = mechanisms[i].type;
3990 }
3991 }
3992 break;
3993 default:
3994 *pulCount = 0;
3995 for (i = 0; i < mechanismCount; i++) {
3996 if (mechanisms[i].privkey) {
3997 (*pulCount)++;
3998 if (pMechanismList != NULL((void*)0)) {
3999 *pMechanismList++ = mechanisms[i].type;
4000 }
4001 }
4002 }
4003 break;
4004 }
4005 return CKR_OK0x00000000UL;
4006}
4007
4008/* NSC_GetMechanismInfo obtains information about a particular mechanism
4009 * possibly supported by a token. */
4010CK_RV
4011NSC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
4012 CK_MECHANISM_INFO_PTR pInfo)
4013{
4014 PRBool isPrivateKey;
4015 CK_ULONG i;
4016
4017 CHECK_FORK();
4018
4019 switch (slotID) {
4020 case NETSCAPE_SLOT_ID1:
4021 isPrivateKey = PR_FALSE0;
4022 break;
4023 default:
4024 isPrivateKey = PR_TRUE1;
4025 break;
4026 }
4027 for (i = 0; i < mechanismCount; i++) {
4028 if (type == mechanisms[i].type) {
4029 if (isPrivateKey && !mechanisms[i].privkey) {
4030 return CKR_MECHANISM_INVALID0x00000070UL;
4031 }
4032 PORT_Memcpymemcpy(pInfo, &mechanisms[i].info, sizeof(CK_MECHANISM_INFO));
4033 return CKR_OK0x00000000UL;
4034 }
4035 }
4036 return CKR_MECHANISM_INVALID0x00000070UL;
4037}
4038
4039/*
4040 * If we are using the V2 interface, strip out the message flags
4041 */
4042#define SFTK_MESSAGE_FLAGS(0x00000002UL | 0x00000004UL | 0x00000008UL | 0x00000010UL) (CKF_MESSAGE_ENCRYPT0x00000002UL | CKF_MESSAGE_DECRYPT0x00000004UL | CKF_MESSAGE_SIGN0x00000008UL | CKF_MESSAGE_VERIFY0x00000010UL)
4043CK_RV
4044NSC_GetMechanismInfoV2(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
4045 CK_MECHANISM_INFO_PTR pInfo)
4046{
4047 CK_RV crv;
4048 crv = NSC_GetMechanismInfo(slotID, type, pInfo);
4049 if (crv == CKR_OK0x00000000UL) {
4050 pInfo->flags = pInfo->flags & ~SFTK_MESSAGE_FLAGS(0x00000002UL | 0x00000004UL | 0x00000008UL | 0x00000010UL);
4051 }
4052 return crv;
4053}
4054
4055CK_RV
4056sftk_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op)
4057{
4058 CK_ULONG i;
4059 CK_FLAGS flags = sftk_AttributeToFlags(op);
4060
4061 if (flags == 0) {
4062 return CKR_ARGUMENTS_BAD0x00000007UL;
4063 }
4064 for (i = 0; i < mechanismCount; i++) {
4065 if (type == mechanisms[i].type) {
4066 return (flags & mechanisms[i].info.flags) ? CKR_OK0x00000000UL
4067 : CKR_MECHANISM_INVALID0x00000070UL;
4068 }
4069 }
4070 return CKR_MECHANISM_INVALID0x00000070UL;
4071}
4072
4073/* NSC_InitToken initializes a token. */
4074CK_RV
4075NSC_InitToken(CK_SLOT_ID slotID, CK_CHAR_PTR pPin,
4076 CK_ULONG ulPinLen, CK_CHAR_PTR pLabel)
4077{
4078 SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE0);
4079 SFTKDBHandle *handle;
4080 SECStatus rv;
4081 unsigned int i;
4082 SFTKObject *object;
4083
4084 CHECK_FORK();
4085
4086 if (slot == NULL((void*)0))
4087 return CKR_SLOT_ID_INVALID0x00000003UL;
4088
4089 /* don't initialize the database if we aren't talking to a token
4090 * that uses the key database.
4091 */
4092 if (slotID == NETSCAPE_SLOT_ID1) {
4093 return CKR_TOKEN_WRITE_PROTECTED0x000000E2UL;
4094 }
4095
4096 /* first, delete all our loaded key and cert objects from our
4097 * internal list. */
4098 PZ_Lock(slot->objectLock)PR_Lock((slot->objectLock));
4099 for (i = 0; i < slot->sessObjHashSize; i++) {
4100 do {
4101 object = slot->sessObjHashTable[i];
4102 /* hand deque */
4103 /* this duplicates function of NSC_close session functions, but
4104 * because we know that we are freeing all the sessions, we can
4105 * do more efficient processing */
4106 if (object) {
4107 slot->sessObjHashTable[i] = object->next;
4108
4109 if (object->next)
4110 object->next->prev = NULL((void*)0);
4111 object->next = object->prev = NULL((void*)0);
4112 }
4113 if (object)
4114 sftk_FreeObject(object);
4115 } while (object != NULL((void*)0));
4116 }
4117 slot->DB_loaded = PR_FALSE0;
4118 PZ_Unlock(slot->objectLock)PR_Unlock((slot->objectLock));
4119
4120 /* then clear out the key database */
4121 handle = sftk_getKeyDB(slot);
4122 if (handle == NULL((void*)0)) {
4123 return CKR_TOKEN_WRITE_PROTECTED0x000000E2UL;
4124 }
4125
4126 rv = sftkdb_ResetKeyDB(handle);
4127 /* clear the password */
4128 sftkdb_ClearPassword(handle);
4129 /* update slot->needLogin (should be true now since no password is set) */
4130 sftk_checkNeedLogin(slot, handle);
4131 sftk_freeDB(handle);
4132 if (rv != SECSuccess) {
4133 return CKR_DEVICE_ERROR0x00000030UL;
4134 }
4135
4136 return CKR_OK0x00000000UL;
4137}
4138
4139/* NSC_InitPIN initializes the normal user's PIN. */
4140CK_RV
4141NSC_InitPIN(CK_SESSION_HANDLE hSession,
4142 CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
4143{
4144 SFTKSession *sp = NULL((void*)0);
4145 SFTKSlot *slot;
4146 SFTKDBHandle *handle = NULL((void*)0);
4147 char newPinStr[SFTK_MAX_PIN500 + 1];
4148 SECStatus rv;
4149 CK_RV crv = CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4150 PRBool tokenRemoved = PR_FALSE0;
4151
4152 CHECK_FORK();
4153
4154 sp = sftk_SessionFromHandle(hSession);
4155 if (sp == NULL((void*)0)) {
4156 goto loser;
4157 }
4158
4159 slot = sftk_SlotFromSession(sp)((sp)->slot);
4160 if (slot == NULL((void*)0)) {
4161 goto loser;
4162 }
4163
4164 handle = sftk_getKeyDB(slot);
4165 if (handle == NULL((void*)0)) {
4166 crv = CKR_PIN_LEN_RANGE0x000000A2UL;
4167 goto loser;
4168 }
4169
4170 if (sp->info.state != CKS_RW_SO_FUNCTIONS4) {
4171 crv = CKR_USER_NOT_LOGGED_IN0x00000101UL;
4172 goto loser;
4173 }
4174
4175 sftk_FreeSession(sp);
4176 sp = NULL((void*)0);
4177
4178 /* make sure the pins aren't too long */
4179 if (ulPinLen > SFTK_MAX_PIN500) {
4180 crv = CKR_PIN_LEN_RANGE0x000000A2UL;
4181 goto loser;
4182 }
4183 if (ulPinLen < (CK_ULONG)slot->minimumPinLen) {
4184 crv = CKR_PIN_LEN_RANGE0x000000A2UL;
4185 goto loser;
4186 }
4187
4188 if (sftkdb_HasPasswordSet(handle) != SECFailure) {
4189 crv = CKR_DEVICE_ERROR0x00000030UL;
4190 goto loser;
4191 }
4192
4193 /* convert to null terminated string */
4194 PORT_Memcpymemcpy(newPinStr, pPin, ulPinLen);
4195 newPinStr[ulPinLen] = 0;
4196
4197 /* build the hashed pins which we pass around */
4198
4199 /* change the data base */
4200 rv = sftkdb_ChangePassword(handle, NULL((void*)0), newPinStr, &tokenRemoved);
4201 if (tokenRemoved) {
4202 sftk_CloseAllSessions(slot, PR_FALSE0);
4203 }
4204 PORT_Memsetmemset(newPinStr, 0, ulPinLen);
4205 sftk_freeDB(handle);
4206 handle = NULL((void*)0);
4207
4208 /* Now update our local copy of the pin */
4209 if (rv == SECSuccess) {
4210 if (ulPinLen == 0) {
4211 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
4212 slot->needLogin = PR_FALSE0;
4213 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
4214 }
4215 /* database has been initialized, now force min password in FIPS
4216 * mode. NOTE: if we are in level1, we may not have a password, but
4217 * forcing it now will prevent an insufficient password from being set.
4218 */
4219 if ((sftk_GetModuleIndex(slot->slotID) == NSC_FIPS_MODULE1) &&
4220 (slot->minimumPinLen < FIPS_MIN_PIN7)) {
4221 slot->minimumPinLen = FIPS_MIN_PIN7;
4222 }
4223 return CKR_OK0x00000000UL;
4224 }
4225 crv = CKR_PIN_INCORRECT0x000000A0UL;
4226
4227loser:
4228 if (sp) {
4229 sftk_FreeSession(sp);
4230 }
4231 if (handle) {
4232 sftk_freeDB(handle);
4233 }
4234 return crv;
4235}
4236
4237/* NSC_SetPIN modifies the PIN of user that is currently logged in. */
4238/* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
4239CK_RV
4240NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
4241 CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen)
4242{
4243 SFTKSession *sp = NULL((void*)0);
4244 SFTKSlot *slot;
4245 SFTKDBHandle *handle = NULL((void*)0);
4246 char newPinStr[SFTK_MAX_PIN500 + 1], oldPinStr[SFTK_MAX_PIN500 + 1];
4247 SECStatus rv;
4248 CK_RV crv = CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4249 PRBool needLogin;
4250 PRBool tokenRemoved = PR_FALSE0;
4251
4252 CHECK_FORK();
4253
4254 sp = sftk_SessionFromHandle(hSession);
4255 if (sp == NULL((void*)0)) {
4256 goto loser;
4257 }
4258
4259 slot = sftk_SlotFromSession(sp)((sp)->slot);
4260 if (!slot) {
4261 goto loser;
4262 }
4263
4264 handle = sftk_getKeyDB(slot);
4265 if (handle == NULL((void*)0)) {
4266 sftk_FreeSession(sp);
4267 return CKR_PIN_LEN_RANGE0x000000A2UL; /* XXX FIXME wrong return value */
4268 }
4269
4270 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
4271 needLogin = slot->needLogin;
4272 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
4273 if (needLogin && sp->info.state != CKS_RW_USER_FUNCTIONS3) {
4274 crv = CKR_USER_NOT_LOGGED_IN0x00000101UL;
4275 goto loser;
4276 }
4277
4278 sftk_FreeSession(sp);
4279 sp = NULL((void*)0);
4280
4281 /* make sure the pins aren't too long */
4282 if ((ulNewLen > SFTK_MAX_PIN500) || (ulOldLen > SFTK_MAX_PIN500)) {
4283 crv = CKR_PIN_LEN_RANGE0x000000A2UL;
4284 goto loser;
4285 }
4286 /* check the length of new pin, unless both old and new passwords
4287 * are empty */
4288 if ((ulNewLen != 0 || ulOldLen != 0) &&
4289 ulNewLen < (CK_ULONG)slot->minimumPinLen) {
4290 crv = CKR_PIN_LEN_RANGE0x000000A2UL;
4291 goto loser;
4292 }
4293
4294 /* convert to null terminated string */
4295 PORT_Memcpymemcpy(newPinStr, pNewPin, ulNewLen);
4296 newPinStr[ulNewLen] = 0;
4297 PORT_Memcpymemcpy(oldPinStr, pOldPin, ulOldLen);
4298 oldPinStr[ulOldLen] = 0;
4299
4300 /* change the data base password */
4301 PR_Lock(slot->pwCheckLock);
4302 rv = sftkdb_ChangePassword(handle, oldPinStr, newPinStr, &tokenRemoved);
4303 PORT_Memsetmemset(newPinStr, 0, ulNewLen);
4304 PORT_Memsetmemset(oldPinStr, 0, ulOldLen);
4305 if (tokenRemoved) {
4306 sftk_CloseAllSessions(slot, PR_FALSE0);
4307 }
4308 if ((rv != SECSuccess) && (sftk_isFIPS(slot->slotID)(((slot->slotID) == 3) || ((slot->slotID) >= 101)))) {
4309 PR_Sleep(loginWaitTime);
4310 }
4311 PR_Unlock(slot->pwCheckLock);
4312
4313 /* Now update our local copy of the pin */
4314 if (rv == SECSuccess) {
4315 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
4316 slot->needLogin = (PRBool)(ulNewLen != 0);
4317 slot->isLoggedIn = (PRBool)(sftkdb_PWCached(handle) == SECSuccess);
4318 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
4319 /* Reset login flags. */
4320 if (ulNewLen == 0) {
4321 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
4322 slot->isLoggedIn = PR_FALSE0;
4323 slot->ssoLoggedIn = PR_FALSE0;
4324 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
4325
4326 tokenRemoved = PR_FALSE0;
4327 rv = sftkdb_CheckPasswordNull(handle, &tokenRemoved);
Value stored to 'rv' is never read
4328 if (tokenRemoved) {
4329 sftk_CloseAllSessions(slot, PR_FALSE0);
4330 }
4331 }
4332 sftk_update_all_states(slot);
4333 sftk_freeDB(handle);
4334 return CKR_OK0x00000000UL;
4335 }
4336 crv = CKR_PIN_INCORRECT0x000000A0UL;
4337loser:
4338 if (sp) {
4339 sftk_FreeSession(sp);
4340 }
4341 if (handle) {
4342 sftk_freeDB(handle);
4343 }
4344 return crv;
4345}
4346
4347/* NSC_OpenSession opens a session between an application and a token. */
4348CK_RV
4349NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
4350 CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession)
4351{
4352 SFTKSlot *slot;
4353 CK_SESSION_HANDLE sessionID;
4354 SFTKSession *session;
4355 SFTKSession *sameID;
4356
4357 CHECK_FORK();
4358
4359 slot = sftk_SlotFromID(slotID, PR_FALSE0);
4360 if (slot == NULL((void*)0))
4361 return CKR_SLOT_ID_INVALID0x00000003UL;
4362
4363 /* new session (we only have serial sessions) */
4364 session = sftk_NewSession(slotID, Notify, pApplication,
4365 flags | CKF_SERIAL_SESSION0x00000004UL);
4366 if (session == NULL((void*)0))
4367 return CKR_HOST_MEMORY0x00000002UL;
4368
4369 if (slot->readOnly && (flags & CKF_RW_SESSION0x00000002UL)) {
4370 /* NETSCAPE_SLOT_ID is Read ONLY */
4371 session->info.flags &= ~CKF_RW_SESSION0x00000002UL;
4372 }
4373 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
4374 ++slot->sessionCount;
4375 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
4376 if (session->info.flags & CKF_RW_SESSION0x00000002UL) {
4377 (void)PR_ATOMIC_INCREMENT(&slot->rwSessionCount)__sync_add_and_fetch(&slot->rwSessionCount, 1);
4378 }
4379
4380 do {
4381 PZLockPRLock *lock;
4382 do {
4383 sessionID = (PR_ATOMIC_INCREMENT(&slot->sessionIDCount)__sync_add_and_fetch(&slot->sessionIDCount, 1) & 0xffffff) | (slot->index << 24);
4384 } while (sessionID == CK_INVALID_HANDLE0);
4385 lock = SFTK_SESSION_LOCK(slot, sessionID)((slot)->sessionLock[(sessionID) & (slot)->sessionLockMask
])
;
4386 PZ_Lock(lock)PR_Lock((lock));
4387 sftkqueue_find(sameID, sessionID, slot->head, slot->sessHashSize)for ((sameID) = (slot->head)[((PRUint32)((sessionID)*1791398085
) & (slot->sessHashSize - 1))]; (sameID) != ((void*)0)
; (sameID) = (sameID)->next) { if ((sameID)->handle == (
sessionID)) { break; } }
;
4388 if (sameID == NULL((void*)0)) {
4389 session->handle = sessionID;
4390 sftk_update_state(slot, session);
4391 sftkqueue_add(session, sessionID, slot->head, slot->sessHashSize){ int tmp = ((PRUint32)((sessionID)*1791398085) & (slot->
sessHashSize - 1)); (session)->next = (slot->head)[tmp]
; (session)->prev = ((void*)0); if ((slot->head)[tmp]) (
slot->head)[tmp]->prev = (session); (slot->head)[tmp
] = (session); }
;
4392 } else {
4393 slot->sessionIDConflict++; /* for debugging */
4394 }
4395 PZ_Unlock(lock)PR_Unlock((lock));
4396 } while (sameID != NULL((void*)0));
4397
4398 *phSession = sessionID;
4399 return CKR_OK0x00000000UL;
4400}
4401
4402/* NSC_CloseSession closes a session between an application and a token. */
4403CK_RV
4404NSC_CloseSession(CK_SESSION_HANDLE hSession)
4405{
4406 SFTKSlot *slot;
4407 SFTKSession *session;
4408 PRBool sessionFound;
4409 PZLockPRLock *lock;
4410
4411 CHECK_FORK();
4412
4413 session = sftk_SessionFromHandle(hSession);
4414 if (session == NULL((void*)0))
4415 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4416 slot = sftk_SlotFromSession(session)((session)->slot);
4417 sessionFound = PR_FALSE0;
4418
4419 /* lock */
4420 lock = SFTK_SESSION_LOCK(slot, hSession)((slot)->sessionLock[(hSession) & (slot)->sessionLockMask
])
;
4421 PZ_Lock(lock)PR_Lock((lock));
4422 if (sftkqueue_is_queued(session, hSession, slot->head, slot->sessHashSize)(((session)->next) || ((session)->prev) || ((slot->head
)[((PRUint32)((hSession)*1791398085) & (slot->sessHashSize
- 1))] == (session)))
) {
4423 sessionFound = PR_TRUE1;
4424 sftkqueue_delete(session, hSession, slot->head, slot->sessHashSize)if ((session)->next) (session)->next->prev = (session
)->prev; if ((session)->prev) (session)->prev->next
= (session)->next; else (slot->head)[((PRUint32)((hSession
)*1791398085) & (slot->sessHashSize - 1))] = ((session
)->next); (session)->next = ((void*)0); (session)->prev
= ((void*)0);
;
4425 }
4426 PZ_Unlock(lock)PR_Unlock((lock));
4427
4428 if (sessionFound) {
4429 SFTKDBHandle *handle;
4430 handle = sftk_getKeyDB(slot);
4431 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
4432 if (--slot->sessionCount == 0) {
4433 slot->isLoggedIn = PR_FALSE0;
4434 if (slot->needLogin && handle) {
4435 sftkdb_ClearPassword(handle);
4436 }
4437 }
4438 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
4439 if (handle) {
4440 sftk_freeDB(handle);
4441 }
4442 if (session->info.flags & CKF_RW_SESSION0x00000002UL) {
4443 (void)PR_ATOMIC_DECREMENT(&slot->rwSessionCount)__sync_sub_and_fetch(&slot->rwSessionCount, 1);
4444 }
4445 sftk_DestroySession(session);
4446 session = NULL((void*)0);
4447 }
4448
4449 return CKR_OK0x00000000UL;
4450}
4451
4452/* NSC_CloseAllSessions closes all sessions with a token. */
4453CK_RV
4454NSC_CloseAllSessions(CK_SLOT_ID slotID)
4455{
4456 SFTKSlot *slot;
4457
4458#ifndef NO_FORK_CHECK
4459 /* skip fork check if we are being called from C_Initialize or C_Finalize */
4460 if (!parentForkedAfterC_Initialize) {
4461 CHECK_FORK();
4462 }
4463#endif
4464
4465 slot = sftk_SlotFromID(slotID, PR_FALSE0);
4466 if (slot == NULL((void*)0))
4467 return CKR_SLOT_ID_INVALID0x00000003UL;
4468
4469 return sftk_CloseAllSessions(slot, PR_TRUE1);
4470}
4471
4472/* NSC_GetSessionInfo obtains information about the session. */
4473CK_RV
4474NSC_GetSessionInfo(CK_SESSION_HANDLE hSession,
4475 CK_SESSION_INFO_PTR pInfo)
4476{
4477 SFTKSession *session;
4478
4479 CHECK_FORK();
4480
4481 session = sftk_SessionFromHandle(hSession);
4482 if (session == NULL((void*)0))
4483 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4484
4485 PORT_Memcpymemcpy(pInfo, &session->info, sizeof(CK_SESSION_INFO));
4486 sftk_FreeSession(session);
4487 return CKR_OK0x00000000UL;
4488}
4489
4490/* NSC_Login logs a user into a token. */
4491CK_RV
4492NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
4493 CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
4494{
4495 SFTKSlot *slot;
4496 SFTKSession *session;
4497 SFTKDBHandle *handle;
4498 CK_FLAGS sessionFlags;
4499 SECStatus rv;
4500 CK_RV crv;
4501 char pinStr[SFTK_MAX_PIN500 + 1];
4502 PRBool tokenRemoved = PR_FALSE0;
4503 PRBool isLoggedIn;
4504 PRBool needLogin;
4505
4506 CHECK_FORK();
4507
4508 /* get the slot */
4509 slot = sftk_SlotFromSessionHandle(hSession);
4510 if (slot == NULL((void*)0)) {
4511 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4512 }
4513
4514 /* make sure the session is valid */
4515 session = sftk_SessionFromHandle(hSession);
4516 if (session == NULL((void*)0)) {
4517 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4518 }
4519 sessionFlags = session->info.flags;
4520 sftk_FreeSession(session);
4521 session = NULL((void*)0);
4522
4523 /* can't log into the Netscape Slot */
4524 if (slot->slotID == NETSCAPE_SLOT_ID1) {
4525 return CKR_USER_TYPE_INVALID0x00000103UL;
4526 }
4527
4528 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
4529 isLoggedIn = slot->isLoggedIn;
4530 needLogin = slot->needLogin;
4531 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
4532
4533 if (isLoggedIn)
4534 return CKR_USER_ALREADY_LOGGED_IN0x00000100UL;
4535 if (!needLogin) {
4536 return ulPinLen ? CKR_PIN_INCORRECT0x000000A0UL : CKR_OK0x00000000UL;
4537 }
4538 slot->ssoLoggedIn = PR_FALSE0;
4539
4540 if (ulPinLen > SFTK_MAX_PIN500)
4541 return CKR_PIN_LEN_RANGE0x000000A2UL;
4542
4543 /* convert to null terminated string */
4544 if (ulPinLen) {
4545 PORT_Memcpymemcpy(pinStr, pPin, ulPinLen);
4546 }
4547 pinStr[ulPinLen] = 0;
4548
4549 handle = sftk_getKeyDB(slot);
4550 if (handle == NULL((void*)0)) {
4551 PORT_Memsetmemset(pinStr, 0, ulPinLen);
4552 return CKR_USER_TYPE_INVALID0x00000103UL;
4553 }
4554
4555 /*
4556 * Deal with bootstrap. We allow the SSO to login in with a NULL
4557 * password if and only if we haven't initialized the KEY DB yet.
4558 * We only allow this on a RW session.
4559 */
4560 rv = sftkdb_HasPasswordSet(handle);
4561 if (rv == SECFailure) {
4562 /* allow SSO's to log in only if there is not password on the
4563 * key database */
4564 if (((userType == CKU_SO0) && (sessionFlags & CKF_RW_SESSION0x00000002UL))
4565 /* fips always needs to authenticate, even if there isn't a db */
4566 || (sftk_isFIPS(slot->slotID)(((slot->slotID) == 3) || ((slot->slotID) >= 101)))) {
4567 /* should this be a fixed password? */
4568 if (ulPinLen == 0) {
4569 sftkdb_ClearPassword(handle);
4570 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
4571 slot->isLoggedIn = PR_TRUE1;
4572 slot->ssoLoggedIn = (PRBool)(userType == CKU_SO0);
4573 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
4574 sftk_update_all_states(slot);
4575 crv = CKR_OK0x00000000UL;
4576 goto done;
4577 }
4578 crv = CKR_PIN_INCORRECT0x000000A0UL;
4579 goto done;
4580 }
4581 crv = CKR_USER_TYPE_INVALID0x00000103UL;
4582 goto done;
4583 }
4584
4585 /* don't allow the SSO to log in if the user is already initialized */
4586 if (userType != CKU_USER1) {
4587 crv = CKR_USER_TYPE_INVALID0x00000103UL;
4588 goto done;
4589 }
4590
4591 /* build the hashed pins which we pass around */
4592 PR_Lock(slot->pwCheckLock);
4593 rv = sftkdb_CheckPassword(handle, pinStr, &tokenRemoved);
4594 if (tokenRemoved) {
4595 sftk_CloseAllSessions(slot, PR_FALSE0);
4596 }
4597 if ((rv != SECSuccess) && (sftk_isFIPS(slot->slotID)(((slot->slotID) == 3) || ((slot->slotID) >= 101)))) {
4598 PR_Sleep(loginWaitTime);
4599 }
4600 PR_Unlock(slot->pwCheckLock);
4601 if (rv == SECSuccess) {
4602 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
4603 /* make sure the login state matches the underlying
4604 * database state */
4605 slot->isLoggedIn = sftkdb_PWCached(handle) == SECSuccess ? PR_TRUE1 : PR_FALSE0;
4606 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
4607
4608 sftk_freeDB(handle);
4609 handle = NULL((void*)0);
4610
4611 /* update all sessions */
4612 sftk_update_all_states(slot);
4613 return CKR_OK0x00000000UL;
4614 }
4615
4616 crv = CKR_PIN_INCORRECT0x000000A0UL;
4617done:
4618 PORT_Memsetmemset(pinStr, 0, ulPinLen);
4619 if (handle) {
4620 sftk_freeDB(handle);
4621 }
4622 return crv;
4623}
4624
4625CK_RV
4626NSC_LoginUser(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
4627 CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pUsername,
4628 CK_ULONG ulUsernameLen)
4629{
4630 /* softoken currently does not support additional users */
4631 return CKR_OPERATION_NOT_INITIALIZED0x00000091UL;
4632}
4633
4634/* NSC_Logout logs a user out from a token. */
4635CK_RV
4636NSC_Logout(CK_SESSION_HANDLE hSession)
4637{
4638 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
4639 SFTKSession *session;
4640 SFTKDBHandle *handle;
4641
4642 CHECK_FORK();
4643
4644 if (slot == NULL((void*)0)) {
4645 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4646 }
4647 session = sftk_SessionFromHandle(hSession);
4648 if (session == NULL((void*)0))
4649 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4650 sftk_FreeSession(session);
4651 session = NULL((void*)0);
4652
4653 if (!slot->isLoggedIn)
4654 return CKR_USER_NOT_LOGGED_IN0x00000101UL;
4655
4656 handle = sftk_getKeyDB(slot);
4657 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
4658 slot->isLoggedIn = PR_FALSE0;
4659 slot->ssoLoggedIn = PR_FALSE0;
4660 if (slot->needLogin && handle) {
4661 sftkdb_ClearPassword(handle);
4662 }
4663 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
4664 if (handle) {
4665 sftk_freeDB(handle);
4666 }
4667
4668 sftk_update_all_states(slot);
4669 return CKR_OK0x00000000UL;
4670}
4671
4672/*
4673 * Create or remove a new slot on the fly.
4674 * When creating a slot, "slot" is the slot that the request came from. The
4675 * resulting slot will live in the same module as "slot".
4676 * When removing a slot, "slot" is the slot to be removed.
4677 * "object" is the creation object that specifies the module spec for the slot
4678 * to add or remove.
4679 */
4680static CK_RV
4681sftk_CreateNewSlot(SFTKSlot *slot, CK_OBJECT_CLASS class,
4682 SFTKObject *object)
4683{
4684 PRBool isValidUserSlot = PR_FALSE0;
4685 PRBool isValidFIPSUserSlot = PR_FALSE0;
4686 PRBool isValidSlot = PR_FALSE0;
4687 PRBool isFIPS = PR_FALSE0;
4688 unsigned int moduleIndex = NSC_NON_FIPS_MODULE0;
4689 SFTKAttribute *attribute;
4690 sftk_parameters paramStrings;
4691 char *paramString;
4692 CK_SLOT_ID slotID = 0;
4693 SFTKSlot *newSlot = NULL((void*)0);
4694 CK_RV crv = CKR_OK0x00000000UL;
4695
4696 if (class != CKO_NSS_DELSLOT((0x80000000UL | 0x4E534350) + 6) && class != CKO_NSS_NEWSLOT((0x80000000UL | 0x4E534350) + 5)) {
4697 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
4698 }
4699 if (class == CKO_NSS_NEWSLOT((0x80000000UL | 0x4E534350) + 5) && slot->slotID == FIPS_SLOT_ID3) {
4700 isFIPS = PR_TRUE1;
4701 }
4702 attribute = sftk_FindAttribute(object, CKA_NSS_MODULE_SPEC((0x80000000UL | 0x4E534350) + 24));
4703 if (attribute == NULL((void*)0)) {
4704 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
4705 }
4706 paramString = (char *)attribute->attrib.pValue;
4707 crv = sftk_parseParameters(paramString, &paramStrings, isFIPS);
4708 if (crv != CKR_OK0x00000000UL) {
4709 goto loser;
4710 }
4711
4712 /* enforce only one at a time */
4713 if (paramStrings.token_count != 1) {
4714 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
4715 goto loser;
4716 }
4717
4718 slotID = paramStrings.tokens[0].slotID;
4719
4720 /* stay within the valid ID space */
4721 isValidUserSlot = (slotID >= SFTK_MIN_USER_SLOT_ID4 &&
4722 slotID <= SFTK_MAX_USER_SLOT_ID100);
4723 isValidFIPSUserSlot = (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID101 &&
4724 slotID <= SFTK_MAX_FIPS_USER_SLOT_ID127);
4725
4726 if (class == CKO_NSS_DELSLOT((0x80000000UL | 0x4E534350) + 6)) {
4727 if (slot->slotID == slotID) {
4728 isValidSlot = isValidUserSlot || isValidFIPSUserSlot;
4729 }
4730 } else {
4731 /* only the crypto or FIPS slots can create new slot objects */
4732 if (slot->slotID == NETSCAPE_SLOT_ID1) {
4733 isValidSlot = isValidUserSlot;
4734 moduleIndex = NSC_NON_FIPS_MODULE0;
4735 } else if (slot->slotID == FIPS_SLOT_ID3) {
4736 isValidSlot = isValidFIPSUserSlot;
4737 moduleIndex = NSC_FIPS_MODULE1;
4738 }
4739 }
4740
4741 if (!isValidSlot) {
4742 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
4743 goto loser;
4744 }
4745
4746 /* unload any existing slot at this id */
4747 newSlot = sftk_SlotFromID(slotID, PR_TRUE1);
4748 if (newSlot && newSlot->present) {
4749 crv = SFTK_ShutdownSlot(newSlot);
4750 if (crv != CKR_OK0x00000000UL) {
4751 goto loser;
4752 }
4753 }
4754
4755 /* if we were just planning on deleting the slot, then do so now */
4756 if (class == CKO_NSS_DELSLOT((0x80000000UL | 0x4E534350) + 6)) {
4757 /* sort of a unconventional use of this error code, be we are
4758 * overusing CKR_ATTRIBUTE_VALUE_INVALID, and it does apply */
4759 crv = newSlot ? CKR_OK0x00000000UL : CKR_SLOT_ID_INVALID0x00000003UL;
4760 goto loser; /* really exit */
4761 }
4762
4763 if (newSlot) {
4764 crv = SFTK_SlotReInit(newSlot, paramStrings.configdir,
4765 paramStrings.updatedir, paramStrings.updateID,
4766 &paramStrings.tokens[0], moduleIndex);
4767 } else {
4768 crv = SFTK_SlotInit(paramStrings.configdir,
4769 paramStrings.updatedir, paramStrings.updateID,
4770 &paramStrings.tokens[0], moduleIndex);
4771 }
4772
4773loser:
4774 sftk_freeParams(&paramStrings);
4775 sftk_FreeAttribute(attribute);
4776
4777 return crv;
4778}
4779
4780/* NSC_CreateObject creates a new object. */
4781CK_RV
4782NSC_CreateObject(CK_SESSION_HANDLE hSession,
4783 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
4784 CK_OBJECT_HANDLE_PTR phObject)
4785{
4786 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
4787 SFTKSession *session;
4788 SFTKObject *object;
4789 /* make sure class isn't randomly CKO_NSS_NEWSLOT or
4790 * CKO_NETSCPE_DELSLOT. */
4791 CK_OBJECT_CLASS class = CKO_VENDOR_DEFINED0x80000000UL;
4792 CK_RV crv;
4793 int i;
4794
4795 CHECK_FORK();
4796
4797 *phObject = CK_INVALID_HANDLE0;
4798
4799 if (slot == NULL((void*)0)) {
4800 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4801 }
4802 /*
4803 * now lets create an object to hang the attributes off of
4804 */
4805 object = sftk_NewObject(slot); /* fill in the handle later */
4806 if (object == NULL((void*)0)) {
4807 return CKR_HOST_MEMORY0x00000002UL;
4808 }
4809
4810 /*
4811 * sftk_NewObject will set object->isFIPS to PR_TRUE if the slot is FIPS.
4812 * We don't need to worry about that here, as FC_CreateObject will always
4813 * disallow the import of secret and private keys, regardless of isFIPS
4814 * approval status. Therefore, at this point we know that the key is a
4815 * public key, which is acceptable to be imported in plaintext.
4816 */
4817
4818 /*
4819 * load the template values into the object
4820 */
4821 for (i = 0; i < (int)ulCount; i++) {
4822 crv = sftk_AddAttributeType(object, sftk_attr_expand(&pTemplate[i])(&pTemplate[i])->type, (&pTemplate[i])->pValue,
(&pTemplate[i])->ulValueLen
);
4823 if (crv != CKR_OK0x00000000UL) {
4824 sftk_FreeObject(object);
4825 return crv;
4826 }
4827 if ((pTemplate[i].type == CKA_CLASS0x00000000UL) && pTemplate[i].pValue) {
4828 class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
4829 }
4830 }
4831
4832 /* get the session */
4833 session = sftk_SessionFromHandle(hSession);
4834 if (session == NULL((void*)0)) {
4835 sftk_FreeObject(object);
4836 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4837 }
4838
4839 /*
4840 * handle pseudo objects (CKO_NEWSLOT)
4841 */
4842 if ((class == CKO_NSS_NEWSLOT((0x80000000UL | 0x4E534350) + 5)) || (class == CKO_NSS_DELSLOT((0x80000000UL | 0x4E534350) + 6))) {
4843 crv = sftk_CreateNewSlot(slot, class, object);
4844 goto done;
4845 }
4846
4847 /*
4848 * handle the base object stuff
4849 */
4850 crv = sftk_handleObject(object, session);
4851 *phObject = object->handle;
4852done:
4853 sftk_FreeSession(session);
4854 sftk_FreeObject(object);
4855
4856 return crv;
4857}
4858
4859/* NSC_CopyObject copies an object, creating a new object for the copy. */
4860CK_RV
4861NSC_CopyObject(CK_SESSION_HANDLE hSession,
4862 CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
4863 CK_OBJECT_HANDLE_PTR phNewObject)
4864{
4865 SFTKObject *destObject, *srcObject;
4866 SFTKSession *session;
4867 CK_RV crv = CKR_OK0x00000000UL;
4868 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
4869 int i;
4870
4871 CHECK_FORK();
4872
4873 if (slot == NULL((void*)0)) {
4874 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4875 }
4876 /* Get srcObject so we can find the class */
4877 session = sftk_SessionFromHandle(hSession);
4878 if (session == NULL((void*)0)) {
4879 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4880 }
4881 srcObject = sftk_ObjectFromHandle(hObject, session);
4882 if (srcObject == NULL((void*)0)) {
4883 sftk_FreeSession(session);
4884 return CKR_OBJECT_HANDLE_INVALID0x00000082UL;
4885 }
4886 /*
4887 * create an object to hang the attributes off of
4888 */
4889 destObject = sftk_NewObject(slot); /* fill in the handle later */
4890 if (destObject == NULL((void*)0)) {
4891 sftk_FreeSession(session);
4892 sftk_FreeObject(srcObject);
4893 return CKR_HOST_MEMORY0x00000002UL;
4894 }
4895
4896 /*
4897 * load the template values into the object
4898 */
4899 for (i = 0; i < (int)ulCount; i++) {
4900 if (sftk_modifyType(pTemplate[i].type, srcObject->objclass) == SFTK_NEVER) {
4901 crv = CKR_ATTRIBUTE_READ_ONLY0x00000010UL;
4902 break;
4903 }
4904 crv = sftk_AddAttributeType(destObject, sftk_attr_expand(&pTemplate[i])(&pTemplate[i])->type, (&pTemplate[i])->pValue,
(&pTemplate[i])->ulValueLen
);
4905 if (crv != CKR_OK0x00000000UL) {
4906 break;
4907 }
4908 }
4909 if (crv != CKR_OK0x00000000UL) {
4910 sftk_FreeSession(session);
4911 sftk_FreeObject(srcObject);
4912 sftk_FreeObject(destObject);
4913 return crv;
4914 }
4915
4916 /* sensitive can only be changed to CK_TRUE */
4917 if (sftk_hasAttribute(destObject, CKA_SENSITIVE0x00000103UL)) {
4918 if (!sftk_isTrue(destObject, CKA_SENSITIVE0x00000103UL)) {
4919 sftk_FreeSession(session);
4920 sftk_FreeObject(srcObject);
4921 sftk_FreeObject(destObject);
4922 return CKR_ATTRIBUTE_READ_ONLY0x00000010UL;
4923 }
4924 }
4925
4926 /*
4927 * now copy the old attributes from the new attributes
4928 */
4929 /* don't create a token object if we aren't in a rw session */
4930 /* we need to hold the lock to copy a consistant version of
4931 * the object. */
4932 crv = sftk_CopyObject(destObject, srcObject);
4933
4934 destObject->objclass = srcObject->objclass;
4935 sftk_FreeObject(srcObject);
4936 if (crv != CKR_OK0x00000000UL) {
4937 sftk_FreeObject(destObject);
4938 sftk_FreeSession(session);
4939 return crv;
4940 }
4941
4942 crv = sftk_handleObject(destObject, session);
4943 *phNewObject = destObject->handle;
4944 sftk_FreeSession(session);
4945 sftk_FreeObject(destObject);
4946
4947 return crv;
4948}
4949
4950/* NSC_GetObjectSize gets the size of an object in bytes. */
4951CK_RV
4952NSC_GetObjectSize(CK_SESSION_HANDLE hSession,
4953 CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize)
4954{
4955 CHECK_FORK();
4956
4957 *pulSize = 0;
4958 return CKR_OK0x00000000UL;
4959}
4960
4961static CK_RV
4962nsc_GetTokenAttributeValue(SFTKSession *session, CK_OBJECT_HANDLE hObject,
4963 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
4964{
4965 SFTKSlot *slot = sftk_SlotFromSession(session)((session)->slot);
4966 SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, hObject);
4967 SFTKDBHandle *keydb = NULL((void*)0);
4968 CK_RV crv;
4969
4970 if (dbHandle == NULL((void*)0)) {
4971 return CKR_OBJECT_HANDLE_INVALID0x00000082UL;
4972 }
4973
4974 crv = sftkdb_GetAttributeValue(dbHandle, hObject, pTemplate, ulCount);
4975
4976 /* make sure we don't export any sensitive information */
4977 keydb = sftk_getKeyDB(slot);
4978 if (dbHandle == keydb) {
4979 CK_ULONG i;
4980 for (i = 0; i < ulCount; i++) {
4981 if (sftk_isSensitive(pTemplate[i].type, CKO_PRIVATE_KEY0x00000003UL)) {
4982 crv = CKR_ATTRIBUTE_SENSITIVE0x00000011UL;
4983 if (pTemplate[i].pValue && (pTemplate[i].ulValueLen != -1)) {
4984 PORT_Memsetmemset(pTemplate[i].pValue, 0,
4985 pTemplate[i].ulValueLen);
4986 }
4987 pTemplate[i].ulValueLen = -1;
4988 }
4989 }
4990 }
4991
4992 sftk_freeDB(dbHandle);
4993 if (keydb) {
4994 sftk_freeDB(keydb);
4995 }
4996 return crv;
4997}
4998
4999/* NSC_GetAttributeValue obtains the value of one or more object attributes. */
5000CK_RV
5001NSC_GetAttributeValue(CK_SESSION_HANDLE hSession,
5002 CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
5003{
5004 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
5005 SFTKSession *session;
5006 SFTKObject *object;
5007 SFTKAttribute *attribute;
5008 PRBool sensitive, isLoggedIn, needLogin;
5009 CK_RV crv;
5010 int i;
5011
5012 CHECK_FORK();
5013
5014 if (slot == NULL((void*)0)) {
5015 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
5016 }
5017 /*
5018 * make sure we're allowed
5019 */
5020 session = sftk_SessionFromHandle(hSession);
5021 if (session == NULL((void*)0)) {
5022 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
5023 }
5024
5025 /* short circuit everything for token objects */
5026 if (sftk_isToken(hObject)(((hObject)&0x80000000L) == 0x80000000L)) {
5027 crv = nsc_GetTokenAttributeValue(session, hObject, pTemplate, ulCount);
5028 sftk_FreeSession(session);
5029 return crv;
5030 }
5031
5032 /* handle the session object */
5033 object = sftk_ObjectFromHandle(hObject, session);
5034 sftk_FreeSession(session);
5035 if (object == NULL((void*)0)) {
5036 return CKR_OBJECT_HANDLE_INVALID0x00000082UL;
5037 }
5038
5039 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
5040 isLoggedIn = slot->isLoggedIn;
5041 needLogin = slot->needLogin;
5042 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
5043
5044 /* don't read a private object if we aren't logged in */
5045 if (!isLoggedIn && needLogin && sftk_isTrue(object, CKA_PRIVATE0x00000002UL)) {
5046 sftk_FreeObject(object);
5047 return CKR_USER_NOT_LOGGED_IN0x00000101UL;
5048 }
5049
5050 crv = CKR_OK0x00000000UL;
5051 sensitive = sftk_isTrue(object, CKA_SENSITIVE0x00000103UL);
5052 for (i = 0; i < (int)ulCount; i++) {
5053 /* Make sure that this attribute is retrievable */
5054 if (sensitive && sftk_isSensitive(pTemplate[i].type, object->objclass)) {
5055 crv = CKR_ATTRIBUTE_SENSITIVE0x00000011UL;
5056 pTemplate[i].ulValueLen = -1;
5057 continue;
5058 }
5059 attribute = sftk_FindAttribute(object, pTemplate[i].type);
5060 if (attribute == NULL((void*)0)) {
5061 crv = CKR_ATTRIBUTE_TYPE_INVALID0x00000012UL;
5062 pTemplate[i].ulValueLen = -1;
5063 continue;
5064 }
5065 if (pTemplate[i].pValue != NULL((void*)0)) {
5066 PORT_Memcpymemcpy(pTemplate[i].pValue, attribute->attrib.pValue,
5067 attribute->attrib.ulValueLen);
5068 }
5069 pTemplate[i].ulValueLen = attribute->attrib.ulValueLen;
5070 sftk_FreeAttribute(attribute);
5071 }
5072
5073 sftk_FreeObject(object);
5074 return crv;
5075}
5076
5077/* NSC_SetAttributeValue modifies the value of one or more object attributes */
5078CK_RV
5079NSC_SetAttributeValue(CK_SESSION_HANDLE hSession,
5080 CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
5081{
5082 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
5083 SFTKSession *session;
5084 SFTKAttribute *attribute;
5085 SFTKObject *object;
5086 PRBool isToken, isLoggedIn, needLogin;
5087 CK_RV crv = CKR_OK0x00000000UL;
5088 CK_BBOOL legal;
5089 int i;
5090
5091 CHECK_FORK();
5092
5093 if (slot == NULL((void*)0)) {
5094 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
5095 }
5096 /*
5097 * make sure we're allowed
5098 */
5099 session = sftk_SessionFromHandle(hSession);
5100 if (session == NULL((void*)0)) {
5101 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
5102 }
5103
5104 object = sftk_ObjectFromHandle(hObject, session);
5105 if (object == NULL((void*)0)) {
5106 sftk_FreeSession(session);
5107 return CKR_OBJECT_HANDLE_INVALID0x00000082UL;
5108 }
5109
5110 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
5111 isLoggedIn = slot->isLoggedIn;
5112 needLogin = slot->needLogin;
5113 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
5114
5115 /* don't modify a private object if we aren't logged in */
5116 if (!isLoggedIn && needLogin && sftk_isTrue(object, CKA_PRIVATE0x00000002UL)) {
5117 sftk_FreeSession(session);
5118 sftk_FreeObject(object);
5119 return CKR_USER_NOT_LOGGED_IN0x00000101UL;
5120 }
5121
5122 /* don't modify a token object if we aren't in a rw session */
5123 isToken = sftk_isTrue(object, CKA_TOKEN0x00000001UL);
5124 if (((session->info.flags & CKF_RW_SESSION0x00000002UL) == 0) && isToken) {
5125 sftk_FreeSession(session);
5126 sftk_FreeObject(object);
5127 return CKR_SESSION_READ_ONLY0x000000B5UL;
5128 }
5129 sftk_FreeSession(session);
5130
5131 /* only change modifiable objects */
5132 if (!sftk_isTrue(object, CKA_MODIFIABLE0x00000170UL)) {
5133 sftk_FreeObject(object);
5134 return CKR_ATTRIBUTE_READ_ONLY0x00000010UL;
5135 }
5136
5137 for (i = 0; i < (int)ulCount; i++) {
5138 /* Make sure that this attribute is changeable */
5139 switch (sftk_modifyType(pTemplate[i].type, object->objclass)) {
5140 case SFTK_NEVER:
5141 case SFTK_ONCOPY:
5142 default:
5143 crv = CKR_ATTRIBUTE_READ_ONLY0x00000010UL;
5144 break;
5145
5146 case SFTK_SENSITIVE:
5147 legal = (pTemplate[i].type == CKA_EXTRACTABLE0x00000162UL) ? CK_FALSE0 : CK_TRUE1;
5148 if ((*(CK_BBOOL *)pTemplate[i].pValue) != legal) {
5149 crv = CKR_ATTRIBUTE_READ_ONLY0x00000010UL;
5150 }
5151 break;
5152 case SFTK_ALWAYS:
5153 break;
5154 }
5155 if (crv != CKR_OK0x00000000UL)
5156 break;
5157
5158 /* find the old attribute */
5159 attribute = sftk_FindAttribute(object, pTemplate[i].type);
5160 if (attribute == NULL((void*)0)) {
5161 crv = CKR_ATTRIBUTE_TYPE_INVALID0x00000012UL;
5162 break;
5163 }
5164 sftk_FreeAttribute(attribute);
5165 crv = sftk_forceAttribute(object, sftk_attr_expand(&pTemplate[i])(&pTemplate[i])->type, (&pTemplate[i])->pValue,
(&pTemplate[i])->ulValueLen
);
5166 if (crv != CKR_OK0x00000000UL)
5167 break;
5168 }
5169
5170 sftk_FreeObject(object);
5171 return crv;
5172}
5173
5174static CK_RV
5175sftk_expandSearchList(SFTKSearchResults *search, int count)
5176{
5177 search->array_size += count;
5178 search->handles = (CK_OBJECT_HANDLE *)PORT_ReallocPORT_Realloc_Util(search->handles,
5179 sizeof(CK_OBJECT_HANDLE) * search->array_size);
5180 return search->handles ? CKR_OK0x00000000UL : CKR_HOST_MEMORY0x00000002UL;
5181}
5182
5183static CK_RV
5184sftk_searchDatabase(SFTKDBHandle *handle, SFTKSearchResults *search,
5185 const CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
5186{
5187 CK_RV crv;
5188 int objectListSize = search->array_size - search->size;
5189 CK_OBJECT_HANDLE *array = &search->handles[search->size];
5190 SDBFind *find;
5191 CK_ULONG count;
5192
5193 crv = sftkdb_FindObjectsInit(handle, pTemplate, ulCount, &find);
5194 if (crv != CKR_OK0x00000000UL)
5195 return crv;
5196 do {
5197 crv = sftkdb_FindObjects(handle, find, array, objectListSize, &count);
5198 if ((crv != CKR_OK0x00000000UL) || (count == 0))
5199 break;
5200 search->size += count;
5201 objectListSize -= count;
5202 if (objectListSize > 0)
5203 break;
5204 crv = sftk_expandSearchList(search, NSC_SEARCH_BLOCK_SIZE5);
5205 objectListSize = NSC_SEARCH_BLOCK_SIZE5;
5206 array = &search->handles[search->size];
5207 } while (crv == CKR_OK0x00000000UL);
5208 sftkdb_FindObjectsFinal(handle, find);
5209
5210 return crv;
5211}
5212
5213/* softoken used to search the SMimeEntries automatically instead of
5214 * doing this in pk11wrap. This code should really be up in
5215 * pk11wrap so that it will work with other tokens other than softoken.
5216 */
5217CK_RV
5218sftk_emailhack(SFTKSlot *slot, SFTKDBHandle *handle,
5219 SFTKSearchResults *search, CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
5220{
5221 PRBool isCert = PR_FALSE0;
5222 int emailIndex = -1;
5223 unsigned int i;
5224 SFTKSearchResults smime_search;
5225 CK_ATTRIBUTE smime_template[2];
5226 CK_OBJECT_CLASS smime_class = CKO_NSS_SMIME((0x80000000UL | 0x4E534350) + 2);
5227 SFTKAttribute *attribute = NULL((void*)0);
5228 SFTKObject *object = NULL((void*)0);
5229 CK_RV crv = CKR_OK0x00000000UL;
5230
5231 smime_search.handles = NULL((void*)0); /* paranoia, some one is bound to add a goto
5232 * loser before this gets initialized */
5233
5234 /* see if we are looking for email certs */
5235 for (i = 0; i < ulCount; i++) {
5236 if (pTemplate[i].type == CKA_CLASS0x00000000UL) {
5237 if ((pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS) ||
5238 (*(CK_OBJECT_CLASS *)pTemplate[i].pValue) != CKO_CERTIFICATE0x00000001UL)) {
5239 /* not a cert, skip out */
5240 break;
5241 }
5242 isCert = PR_TRUE1;
5243 } else if (pTemplate[i].type == CKA_NSS_EMAIL((0x80000000UL | 0x4E534350) + 2)) {
5244 emailIndex = i;
5245 }
5246 if (isCert && (emailIndex != -1))
5247 break;
5248 }
5249
5250 if (!isCert || (emailIndex == -1)) {
5251 return CKR_OK0x00000000UL;
5252 }
5253
5254 /* we are doing a cert and email search, find the SMimeEntry */
5255 smime_template[0].type = CKA_CLASS0x00000000UL;
5256 smime_template[0].pValue = &smime_class;
5257 smime_template[0].ulValueLen = sizeof(smime_class);
5258 smime_template[1] = pTemplate[emailIndex];
5259
5260 smime_search.handles = (CK_OBJECT_HANDLE *)
5261 PORT_AllocPORT_Alloc_Util(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE5);
5262 if (smime_search.handles == NULL((void*)0)) {
5263 crv = CKR_HOST_MEMORY0x00000002UL;
5264 goto loser;
5265 }
5266 smime_search.index = 0;
5267 smime_search.size = 0;
5268 smime_search.array_size = NSC_SEARCH_BLOCK_SIZE5;
5269
5270 crv = sftk_searchDatabase(handle, &smime_search, smime_template, 2);
5271 if (crv != CKR_OK0x00000000UL || smime_search.size == 0) {
5272 goto loser;
5273 }
5274
5275 /* get the SMime subject */
5276 object = sftk_NewTokenObject(slot, NULL((void*)0), smime_search.handles[0]);
5277 if (object == NULL((void*)0)) {
5278 crv = CKR_HOST_MEMORY0x00000002UL; /* is there any other reason for this failure? */
5279 goto loser;
5280 }
5281 attribute = sftk_FindAttribute(object, CKA_SUBJECT0x00000101UL);
5282 if (attribute == NULL((void*)0)) {
5283 crv = CKR_ATTRIBUTE_TYPE_INVALID0x00000012UL;
5284 goto loser;
5285 }
5286
5287 /* now find the certs with that subject */
5288 pTemplate[emailIndex] = attribute->attrib;
5289 /* now add the appropriate certs to the search list */
5290 crv = sftk_searchDatabase(handle, search, pTemplate, ulCount);
5291 pTemplate[emailIndex] = smime_template[1]; /* restore the user's template*/
5292
5293loser:
5294 if (attribute) {
5295 sftk_FreeAttribute(attribute);
5296 }
5297 if (object) {
5298 sftk_FreeObject(object);
5299 }
5300 if (smime_search.handles) {
5301 PORT_FreePORT_Free_Util(smime_search.handles);
5302 }
5303
5304 return crv;
5305}
5306
5307static void
5308sftk_pruneSearch(CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount,
5309 PRBool *searchCertDB, PRBool *searchKeyDB)
5310{
5311 CK_ULONG i;
5312
5313 *searchCertDB = PR_TRUE1;
5314 *searchKeyDB = PR_TRUE1;
5315 for (i = 0; i < ulCount; i++) {
5316 if (pTemplate[i].type == CKA_CLASS0x00000000UL && pTemplate[i].pValue != NULL((void*)0)) {
5317 CK_OBJECT_CLASS class = *((CK_OBJECT_CLASS *)pTemplate[i].pValue);
5318 if (class == CKO_PRIVATE_KEY0x00000003UL || class == CKO_SECRET_KEY0x00000004UL) {
5319 *searchCertDB = PR_FALSE0;
5320 } else {
5321 *searchKeyDB = PR_FALSE0;
5322 }
5323 break;
5324 }
5325 }
5326}
5327
5328static CK_RV
5329sftk_searchTokenList(SFTKSlot *slot, SFTKSearchResults *search,
5330 CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount,
5331 PRBool isLoggedIn)
5332{
5333 CK_RV crv = CKR_OK0x00000000UL;
5334 CK_RV crv2;
5335 PRBool searchCertDB;
5336 PRBool searchKeyDB;
5337
5338 sftk_pruneSearch(pTemplate, ulCount, &searchCertDB, &searchKeyDB);
5339
5340 if (searchCertDB) {
5341 SFTKDBHandle *certHandle = sftk_getCertDB(slot);
5342 crv = sftk_searchDatabase(certHandle, search, pTemplate, ulCount);
5343 crv2 = sftk_emailhack(slot, certHandle, search, pTemplate, ulCount);
5344 if (crv == CKR_OK0x00000000UL)
5345 crv = crv2;
5346 sftk_freeDB(certHandle);
5347 }
5348
5349 if (crv == CKR_OK0x00000000UL && isLoggedIn && searchKeyDB) {
5350 SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
5351 crv = sftk_searchDatabase(keyHandle, search, pTemplate, ulCount);
5352 sftk_freeDB(keyHandle);
5353 }
5354 return crv;
5355}
5356
5357/* NSC_FindObjectsInit initializes a search for token and session objects
5358 * that match a template. */
5359CK_RV
5360NSC_FindObjectsInit(CK_SESSION_HANDLE hSession,
5361 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
5362{
5363 SFTKSearchResults *search = NULL((void*)0), *freeSearch = NULL((void*)0);
5364 SFTKSession *session = NULL((void*)0);
5365 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
5366 CK_RV crv = CKR_OK0x00000000UL;
5367 PRBool isLoggedIn;
5368
5369 CHECK_FORK();
5370
5371 if (slot == NULL((void*)0)) {
5372 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
5373 }
5374 session = sftk_SessionFromHandle(hSession);
5375 if (session == NULL((void*)0)) {
5376 crv = CKR_SESSION_HANDLE_INVALID0x000000B3UL;
5377 goto loser;
5378 }
5379
5380 search = (SFTKSearchResults *)PORT_AllocPORT_Alloc_Util(sizeof(SFTKSearchResults));
5381 if (search == NULL((void*)0)) {
5382 crv = CKR_HOST_MEMORY0x00000002UL;
5383 goto loser;
5384 }
5385 search->handles = (CK_OBJECT_HANDLE *)
5386 PORT_AllocPORT_Alloc_Util(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE5);
5387 if (search->handles == NULL((void*)0)) {
5388 crv = CKR_HOST_MEMORY0x00000002UL;
5389 goto loser;
5390 }
5391 search->index = 0;
5392 search->size = 0;
5393 search->array_size = NSC_SEARCH_BLOCK_SIZE5;
5394
5395 PZ_Lock(slot->slotLock)PR_Lock((slot->slotLock));
5396 isLoggedIn = (PRBool)((!slot->needLogin) || slot->isLoggedIn);
5397 PZ_Unlock(slot->slotLock)PR_Unlock((slot->slotLock));
5398
5399 crv = sftk_searchTokenList(slot, search, pTemplate, ulCount, isLoggedIn);
5400 if (crv != CKR_OK0x00000000UL) {
5401 goto loser;
5402 }
5403
5404 /* build list of found objects in the session */
5405 crv = sftk_searchObjectList(search, slot->sessObjHashTable,
5406 slot->sessObjHashSize, slot->objectLock,
5407 pTemplate, ulCount, isLoggedIn);
5408 if (crv != CKR_OK0x00000000UL) {
5409 goto loser;
5410 }
5411
5412 if ((freeSearch = session->search) != NULL((void*)0)) {
5413 session->search = NULL((void*)0);
5414 sftk_FreeSearch(freeSearch);
5415 }
5416 session->search = search;
5417 sftk_FreeSession(session);
5418 return CKR_OK0x00000000UL;
5419
5420loser:
5421 if (search) {
5422 sftk_FreeSearch(search);
5423 }
5424 if (session) {
5425 sftk_FreeSession(session);
5426 }
5427 return crv;
5428}
5429
5430/* NSC_FindObjects continues a search for token and session objects
5431 * that match a template, obtaining additional object handles. */
5432CK_RV
5433NSC_FindObjects(CK_SESSION_HANDLE hSession,
5434 CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount,
5435 CK_ULONG_PTR pulObjectCount)
5436{
5437 SFTKSession *session;
5438 SFTKSearchResults *search;
5439 int transfer;
5440 int left;
5441
5442 CHECK_FORK();
5443
5444 *pulObjectCount = 0;
5445 session = sftk_SessionFromHandle(hSession);
5446 if (session == NULL((void*)0))
5447 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
5448 if (session->search == NULL((void*)0)) {
5449 sftk_FreeSession(session);
5450 return CKR_OK0x00000000UL;
5451 }
5452 search = session->search;
5453 left = session->search->size - session->search->index;
5454 transfer = ((int)ulMaxObjectCount > left) ? left : ulMaxObjectCount;
5455 if (transfer > 0) {
5456 PORT_Memcpymemcpy(phObject, &search->handles[search->index],
5457 transfer * sizeof(CK_OBJECT_HANDLE));
5458 } else {
5459 *phObject = CK_INVALID_HANDLE0;
5460 }
5461
5462 search->index += transfer;
5463 if (search->index == search->size) {
5464 session->search = NULL((void*)0);
5465 sftk_FreeSearch(search);
5466 }
5467 *pulObjectCount = transfer;
5468 sftk_FreeSession(session);
5469 return CKR_OK0x00000000UL;
5470}
5471
5472/* NSC_FindObjectsFinal finishes a search for token and session objects. */
5473CK_RV
5474NSC_FindObjectsFinal(CK_SESSION_HANDLE hSession)
5475{
5476 SFTKSession *session;
5477 SFTKSearchResults *search;
5478
5479 CHECK_FORK();
5480
5481 session = sftk_SessionFromHandle(hSession);
5482 if (session == NULL((void*)0))
5483 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
5484 search = session->search;
5485 session->search = NULL((void*)0);
5486 sftk_FreeSession(session);
5487 if (search != NULL((void*)0)) {
5488 sftk_FreeSearch(search);
5489 }
5490 return CKR_OK0x00000000UL;
5491}
5492
5493CK_RV
5494NSC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
5495 CK_VOID_PTR pReserved)
5496{
5497 CHECK_FORK();
5498
5499 return CKR_FUNCTION_NOT_SUPPORTED0x00000054UL;
5500}
5501
5502static CK_RV
5503nsc_NSSGetFIPSStatus(CK_SESSION_HANDLE hSession,
5504 CK_OBJECT_HANDLE hObject,
5505 CK_ULONG ulOperationType,
5506 CK_ULONG *pulFIPSStatus)
5507{
5508 CK_ULONG sessionState = CKS_NSS_UNINITIALIZED0xffffffffUL;
5509 CK_ULONG objectState = CKS_NSS_UNINITIALIZED0xffffffffUL;
5510 PRBool needSession = PR_FALSE0;
5511 PRBool needObject = PR_FALSE0;
5512 SFTKSession *session;
5513 SFTKObject *object;
5514
5515 *pulFIPSStatus = CKS_NSS_FIPS_NOT_OK0UL;
5516
5517 /* first determine what we need to look up */
5518 switch (ulOperationType) {
5519 case CKT_NSS_SESSION_CHECK1UL:
5520 case CKT_NSS_SESSION_LAST_CHECK4UL:
5521 needSession = PR_TRUE1;
5522 needObject = PR_FALSE0;
5523 break;
5524 case CKT_NSS_OBJECT_CHECK2UL:
5525 needSession = PR_FALSE0;
5526 needObject = PR_TRUE1;
5527 break;
5528 case CKT_NSS_BOTH_CHECK3UL:
5529 needSession = PR_TRUE1;
5530 needObject = PR_TRUE1;
5531 break;
5532 default:
5533 return CKR_ARGUMENTS_BAD0x00000007UL;
5534 }
5535
5536 /* we always need the session handle, the object handle is only
5537 * meaningful if there is a session */
5538 session = sftk_SessionFromHandle(hSession);
5539 if (!session) {
5540 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
5541 }
5542 if (needSession) {
5543 if (CKT_NSS_SESSION_LAST_CHECK4UL == ulOperationType) {
5544 sessionState = session->lastOpWasFIPS ? CKS_NSS_FIPS_OK1UL : CKS_NSS_FIPS_NOT_OK0UL;
5545 } else {
5546 if (session->enc_context) {
5547 sessionState = session->enc_context->isFIPS ? CKS_NSS_FIPS_OK1UL : CKS_NSS_FIPS_NOT_OK0UL;
5548 }
5549 if (sessionState != CKS_NSS_FIPS_NOT_OK0UL && session->hash_context) {
5550 sessionState = session->hash_context->isFIPS ? CKS_NSS_FIPS_OK1UL : CKS_NSS_FIPS_NOT_OK0UL;
5551 }
5552 /* sessionState is set to CKS_NSS_UNINITIALIZED if neither
5553 * context exists */
5554 }
5555 }
5556
5557 if (needObject) {
5558 object = sftk_ObjectFromHandle(hObject, session);
5559 if (!object) {
5560 sftk_FreeSession(session);
5561 return CKR_OBJECT_HANDLE_INVALID0x00000082UL;
5562 }
5563 objectState = object->isFIPS ? CKS_NSS_FIPS_OK1UL : CKS_NSS_FIPS_NOT_OK0UL;
5564 sftk_FreeObject(object);
5565 }
5566
5567 sftk_FreeSession(session);
5568
5569 /* If we didn't fetch the state, then it is uninitialized.
5570 * The session state can also be uninitialized if there are no active
5571 * crypto operations on the session. Turns out the rules for combining
5572 * the states are the same whether or not the state was uninitialzed
5573 * because we didn't fetch it or because there wasn't a state to fetch.
5574 */
5575
5576 /* if the object State is uninitialized, return the state of the session. */
5577 if (objectState == CKS_NSS_UNINITIALIZED0xffffffffUL) {
5578 /* if they are both uninitalized, return CKS_FIPS_NOT_OK */
5579 if (sessionState == CKS_NSS_UNINITIALIZED0xffffffffUL) {
5580 /* *pulFIPSStatus already set to CKS_FIPS_NOT_OK */
5581 return CKR_OK0x00000000UL;
5582 }
5583 *pulFIPSStatus = sessionState;
5584 return CKR_OK0x00000000UL;
5585 }
5586 /* objectState is initialized, if sessionState is uninitialized, we can
5587 * just return objectState */
5588 if (sessionState == CKS_NSS_UNINITIALIZED0xffffffffUL) {
5589 *pulFIPSStatus = objectState;
5590 return CKR_OK0x00000000UL;
5591 }
5592
5593 /* they are are not equal, one must be CKS_FIPS_NOT_OK, so we return that
5594 * value CKS_FIPS_NOT_OK */
5595 if (objectState != sessionState) {
5596 /* *pulFIPSStatus already set to CKS_FIPS_NOT_OK */
5597 return CKR_OK0x00000000UL;
5598 }
5599
5600 /* objectState and sessionState or the same, so we can return either */
5601 *pulFIPSStatus = sessionState;
5602 return CKR_OK0x00000000UL;
5603}