1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2018, Joyent, Inc.
25 */
26
27 #include <strings.h>
28 #include <cryptoutil.h>
29 #include <security/cryptoki.h>
30 #include <sys/crypto/common.h>
31 #include <arcfour.h>
32 #include "softGlobal.h"
33 #include "softSession.h"
34 #include <aes_impl.h>
35 #include <blowfish_impl.h>
36 #include <des_impl.h>
37 #include <ecc_impl.h>
38 #include "softDH.h"
39 #include "softObject.h"
40 #include "softKeystore.h"
41 #include "softKeystoreUtil.h"
42
43
44 static CK_MECHANISM_TYPE soft_mechanisms[] = {
45 CKM_DES_CBC,
46 CKM_DES_CBC_PAD,
47 CKM_DES_ECB,
48 CKM_DES_KEY_GEN,
49 CKM_DES_MAC_GENERAL,
50 CKM_DES_MAC,
51 CKM_DES3_CBC,
52 CKM_DES3_CBC_PAD,
53 CKM_DES3_ECB,
54 CKM_DES2_KEY_GEN,
55 CKM_DES3_KEY_GEN,
56 CKM_AES_CBC,
57 CKM_AES_CBC_PAD,
58 CKM_AES_CTR,
59 CKM_AES_CMAC_GENERAL,
60 CKM_AES_CMAC,
61 CKM_AES_ECB,
62 CKM_AES_KEY_GEN,
63 CKM_BLOWFISH_CBC,
64 CKM_BLOWFISH_KEY_GEN,
65 CKM_SHA_1,
66 CKM_SHA_1_HMAC,
67 CKM_SHA_1_HMAC_GENERAL,
68 CKM_SHA256,
69 CKM_SHA256_HMAC,
70 CKM_SHA256_HMAC_GENERAL,
71 CKM_SHA384,
72 CKM_SHA384_HMAC,
73 CKM_SHA384_HMAC_GENERAL,
74 CKM_SHA512,
75 CKM_SHA512_HMAC,
76 CKM_SHA512_HMAC_GENERAL,
77 CKM_SSL3_SHA1_MAC,
78 CKM_MD5,
79 CKM_MD5_HMAC,
80 CKM_MD5_HMAC_GENERAL,
81 CKM_SSL3_MD5_MAC,
82 CKM_RC4,
83 CKM_RC4_KEY_GEN,
84 CKM_DSA,
85 CKM_DSA_SHA1,
86 CKM_DSA_KEY_PAIR_GEN,
87 CKM_RSA_PKCS,
88 CKM_RSA_PKCS_KEY_PAIR_GEN,
89 CKM_RSA_X_509,
90 CKM_MD5_RSA_PKCS,
91 CKM_SHA1_RSA_PKCS,
92 CKM_SHA256_RSA_PKCS,
93 CKM_SHA384_RSA_PKCS,
94 CKM_SHA512_RSA_PKCS,
95 CKM_DH_PKCS_KEY_PAIR_GEN,
96 CKM_DH_PKCS_DERIVE,
97 CKM_MD5_KEY_DERIVATION,
98 CKM_SHA1_KEY_DERIVATION,
99 CKM_SHA256_KEY_DERIVATION,
100 CKM_SHA384_KEY_DERIVATION,
101 CKM_SHA512_KEY_DERIVATION,
102 CKM_PBE_SHA1_RC4_128,
103 CKM_PKCS5_PBKD2,
104 CKM_SSL3_PRE_MASTER_KEY_GEN,
105 CKM_TLS_PRE_MASTER_KEY_GEN,
106 CKM_SSL3_MASTER_KEY_DERIVE,
107 CKM_TLS_MASTER_KEY_DERIVE,
108 CKM_SSL3_MASTER_KEY_DERIVE_DH,
109 CKM_TLS_MASTER_KEY_DERIVE_DH,
110 CKM_SSL3_KEY_AND_MAC_DERIVE,
111 CKM_TLS_KEY_AND_MAC_DERIVE,
112 CKM_TLS_PRF,
113 CKM_EC_KEY_PAIR_GEN,
114 CKM_ECDSA,
115 CKM_ECDSA_SHA1,
116 CKM_ECDH1_DERIVE
117 };
118
119 /*
120 * This is the table of CK_MECHANISM_INFO structs for the supported mechanisms.
121 * The index for this table is the same as the one above for the same
122 * mechanism.
123 * The minimum and maximum sizes of the key for the mechanism can be measured
124 * in bits or in bytes (i.e. mechanism-dependent). This table specifies the
125 * supported range of key sizes in bytes; unless noted as in bits.
126 */
127 static CK_MECHANISM_INFO soft_mechanism_info[] = {
128 {DES_MINBYTES, DES_MAXBYTES,
129 CKF_ENCRYPT|CKF_DECRYPT|
130 CKF_WRAP|CKF_UNWRAP}, /* CKM_DES_CBC */
131 {DES_MINBYTES, DES_MAXBYTES,
132 CKF_ENCRYPT|CKF_DECRYPT|
133 CKF_WRAP|CKF_UNWRAP}, /* CKM_DES_CBC_PAD */
134 {DES_MINBYTES, DES_MAXBYTES,
135 CKF_ENCRYPT|CKF_DECRYPT|
136 CKF_WRAP|CKF_UNWRAP}, /* CKM_DES_ECB */
137 {DES_MINBYTES, DES_MAXBYTES,
138 CKF_GENERATE}, /* CKM_DES_KEY_GEN */
139 {DES_MINBYTES, DES_MAXBYTES,
140 CKF_SIGN|CKF_VERIFY}, /* CKM_DES_MAC_GENERAL */
141 {DES_MINBYTES, DES_MAXBYTES,
142 CKF_SIGN|CKF_VERIFY}, /* CKM_DES_MAC */
143 {DES3_MINBYTES, DES3_MAXBYTES,
144 CKF_ENCRYPT|CKF_DECRYPT|
145 CKF_WRAP|CKF_UNWRAP}, /* CKM_DES3_CBC */
146 {DES3_MINBYTES, DES3_MAXBYTES,
147 CKF_ENCRYPT|CKF_DECRYPT|
148 CKF_WRAP|CKF_UNWRAP}, /* CKM_DES3_CBC_PAD */
149 {DES3_MINBYTES, DES3_MAXBYTES,
150 CKF_ENCRYPT|CKF_DECRYPT|
151 CKF_WRAP|CKF_UNWRAP}, /* CKM_DES3_ECB */
152 {DES2_MAXBYTES, DES2_MAXBYTES,
153 CKF_GENERATE}, /* CKM_DES2_KEY_GEN */
154 {DES3_MAXBYTES, DES3_MAXBYTES, /* CKK_DES3 only */
155 CKF_GENERATE}, /* CKM_DES3_KEY_GEN */
156 {AES_MINBYTES, AES_MAXBYTES,
157 CKF_ENCRYPT|CKF_DECRYPT|
158 CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_CBC */
159 {AES_MINBYTES, AES_MAXBYTES,
160 CKF_ENCRYPT|CKF_DECRYPT|
161 CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_CBC_PAD */
162 {AES_MINBYTES, AES_MAXBYTES,
163 CKF_ENCRYPT|CKF_DECRYPT|
164 CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_CTR */
165 {AES_MINBYTES, AES_MAXBYTES,
166 CKF_SIGN|CKF_VERIFY}, /* CKM_AES_CMAC_GENERAL */
167 {AES_MINBYTES, AES_MAXBYTES,
168 CKF_SIGN|CKF_VERIFY}, /* CKM_AES_CMAC */
169 {AES_MINBYTES, AES_MAXBYTES,
170 CKF_ENCRYPT|CKF_DECRYPT|
171 CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_ECB */
172 {AES_MINBYTES, AES_MAXBYTES,
173 CKF_GENERATE}, /* CKM_AES_KEY_GEN */
174 {BLOWFISH_MINBYTES, BLOWFISH_MAXBYTES,
175 CKF_ENCRYPT|CKF_DECRYPT|
176 CKF_WRAP|CKF_UNWRAP}, /* CKM_BLOWFISH_ECB */
177 {BLOWFISH_MINBYTES, BLOWFISH_MAXBYTES,
178 CKF_GENERATE}, /* CKM_BLOWFISH_KEY_GEN */
179 {0, 0, CKF_DIGEST}, /* CKM_SHA_1 */
180 {1, 64, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA_1_HMAC */
181 {1, 64, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA_1_HMAC_GENERAL */
182 {0, 0, CKF_DIGEST}, /* CKM_SHA256 */
183 {1, 64, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA256_HMAC */
184 {1, 64, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA256_HMAC_GENERAL */
185 {0, 0, CKF_DIGEST}, /* CKM_SHA384 */
186 {1, 128, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA384_HMAC */
187 {1, 128, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA384_HMAC_GENERAL */
188 {0, 0, CKF_DIGEST}, /* CKM_SHA512 */
189 {1, 128, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA512_HMAC */
190 {1, 128, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA512_HMAC_GENERAL */
191 {1, 512, CKF_SIGN|CKF_VERIFY}, /* CKM_SSL3_SHA1_MAC */
192 {0, 0, CKF_DIGEST}, /* CKM_MD5 */
193 {1, 64, CKF_SIGN|CKF_VERIFY}, /* CKM_MD5_HMAC */
194 {1, 64, CKF_SIGN|CKF_VERIFY}, /* CKM_MD5_HMAC_GENERAL */
195 {1, 512, CKF_SIGN|CKF_VERIFY}, /* CKM_SSL3_MD5_MAC */
196 {8, ARCFOUR_MAX_KEY_BITS, CKF_ENCRYPT|CKF_DECRYPT}, /* CKM_RC4; */
197 /* in bits */
198 {8, ARCFOUR_MAX_KEY_BITS, CKF_GENERATE }, /* CKM_RC4_KEY_GEN; in bits */
199 {512, 1024, CKF_SIGN|CKF_VERIFY}, /* CKM_DSA; in bits */
200 {512, 1024, CKF_SIGN|CKF_VERIFY}, /* CKM_DSA_SHA1; in bits */
201 {512, 1024, CKF_GENERATE_KEY_PAIR}, /* CKM_DSA_KEY_PAIR_GEN; */
202 /* in bits */
203 {256, 4096, CKF_ENCRYPT|CKF_DECRYPT|
204 CKF_SIGN|CKF_SIGN_RECOVER|
205 CKF_WRAP|CKF_UNWRAP|
206 CKF_VERIFY|CKF_VERIFY_RECOVER}, /* CKM_RSA_PKCS; in bits */
207 {256, 4096, CKF_GENERATE_KEY_PAIR}, /* CKM_RSA_PKCS_KEY_PAIR_GEN; */
208 /* in bits */
209 {256, 4096, CKF_ENCRYPT|CKF_DECRYPT|
210 CKF_SIGN|CKF_SIGN_RECOVER|
211 CKF_WRAP|CKF_UNWRAP|
212 CKF_VERIFY|CKF_VERIFY_RECOVER}, /* CKM_RSA_X_509 in bits */
213 {256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_MD5_RSA_PKCS in bits */
214 {256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA1_RSA_PKCS in bits */
215 {256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA256_RSA_PKCS in bits */
216 {256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA384_RSA_PKCS in bits */
217 {256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA512_RSA_PKCS in bits */
218 {DH_MIN_KEY_LEN, DH_MAX_KEY_LEN, CKF_GENERATE_KEY_PAIR},
219 /* CKM_DH_PKCS_KEY_PAIR_GEN */
220 /* in bits */
221 {DH_MIN_KEY_LEN, DH_MAX_KEY_LEN, CKF_DERIVE},
222 /* CKM_DH_PKCS_DERIVE; */
223 /* in bits */
224 {1, 16, CKF_DERIVE}, /* CKM_MD5_KEY_DERIVATION */
225 {1, 20, CKF_DERIVE}, /* CKM_SHA1_KEY_DERIVATION */
226 {1, 32, CKF_DERIVE}, /* CKM_SHA256_KEY_DERIVATION */
227 {1, 48, CKF_DERIVE}, /* CKM_SHA384_KEY_DERIVATION */
228 {1, 64, CKF_DERIVE}, /* CKM_SHA512_KEY_DERIVATION */
229 {0, 0, CKF_GENERATE}, /* CKM_PBE_SHA1_RC4_128 */
230 {0, 0, CKF_GENERATE}, /* CKM_PKCS5_PBKD2 */
231 {48, 48, CKF_GENERATE}, /* CKM_SSL3_PRE_MASTER_KEY_GEN */
232 {48, 48, CKF_GENERATE}, /* CKM_TLS_PRE_MASTER_KEY_GEN */
233 {48, 48, CKF_DERIVE}, /* CKM_SSL3_MASTER_KEY_DERIVE */
234 {48, 48, CKF_DERIVE}, /* CKM_TLS_MASTER_KEY_DERIVE */
235 {48, 48, CKF_DERIVE}, /* CKM_SSL3_MASTER_KEY_DERIVE_DH */
236 {48, 48, CKF_DERIVE}, /* CKM_TLS_MASTER_KEY_DERIVE_DH */
237 {0, 0, CKF_DERIVE}, /* CKM_SSL3_KEY_AND_MAC_DERIVE */
238 {0, 0, CKF_DERIVE}, /* CKM_TLS_KEY_AND_MAC_DERIVE */
239 {0, 0, CKF_DERIVE}, /* CKM_TLS_PRF */
240 {EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_GENERATE_KEY_PAIR},
241 {EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_SIGN|CKF_VERIFY},
242 {EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_SIGN|CKF_VERIFY},
243 {EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_DERIVE}
244 };
245
246 /*
247 * Slot ID for softtoken is always 1. tokenPresent is ignored.
248 * Also, only one slot is used.
249 */
250 /*ARGSUSED*/
251 CK_RV
252 C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList,
253 CK_ULONG_PTR pulCount)
254 {
255
256 CK_RV rv;
257
258 if (!softtoken_initialized)
259 return (CKR_CRYPTOKI_NOT_INITIALIZED);
260
261 if (pulCount == NULL) {
262 return (CKR_ARGUMENTS_BAD);
263 }
264
265 if (pSlotList == NULL) {
266 /*
267 * Application only wants to know the number of slots.
268 */
269 *pulCount = 1;
270 return (CKR_OK);
271 }
272
273 if ((*pulCount < 1) && (pSlotList != NULL)) {
274 rv = CKR_BUFFER_TOO_SMALL;
275 } else {
276 pSlotList[0] = SOFTTOKEN_SLOTID;
277 rv = CKR_OK;
278 }
279
280 *pulCount = 1;
281 return (rv);
282 }
283
284
285 CK_RV
286 C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
287 {
288
289 if (!softtoken_initialized)
290 return (CKR_CRYPTOKI_NOT_INITIALIZED);
291
292 if (pInfo == NULL)
293 return (CKR_ARGUMENTS_BAD);
294
295 /* Make sure the slot ID is valid */
296 if (slotID != SOFTTOKEN_SLOTID)
297 return (CKR_SLOT_ID_INVALID);
298
299 /* Provide information about the slot in the provided buffer */
300 (void) strncpy((char *)pInfo->slotDescription, SOFT_SLOT_DESCRIPTION,
301 64);
302 (void) strncpy((char *)pInfo->manufacturerID, SOFT_MANUFACTURER_ID, 32);
303 pInfo->flags = CKF_TOKEN_PRESENT;
304 pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
305 pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
306 pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
307 pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
308
309 return (CKR_OK);
310 }
311
312 CK_RV
313 C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
314 {
315 boolean_t pin_initialized = B_FALSE;
316 char *ks_cryptpin = NULL;
317
318 if (!softtoken_initialized)
319 return (CKR_CRYPTOKI_NOT_INITIALIZED);
320
321 /* Make sure the slot ID is valid */
322 if (slotID != SOFTTOKEN_SLOTID)
323 return (CKR_SLOT_ID_INVALID);
324
325 if (pInfo == NULL)
326 return (CKR_ARGUMENTS_BAD);
327
328 /*
329 * It is intentional that we don't forward the error code
330 * returned from soft_keystore_pin_initialized() to the caller
331 */
332 pInfo->flags = SOFT_TOKEN_FLAGS;
333 if (soft_slot.keystore_load_status == KEYSTORE_UNAVAILABLE) {
334 pInfo->flags |= CKF_WRITE_PROTECTED;
335 } else {
336 if ((soft_keystore_pin_initialized(&pin_initialized,
337 &ks_cryptpin, B_FALSE) == CKR_OK) && !pin_initialized)
338 pInfo->flags |= CKF_USER_PIN_TO_BE_CHANGED;
339 }
340
341 if (ks_cryptpin != NULL) {
342 size_t cplen = strlen(ks_cryptpin) + 1;
343
344 freezero(ks_cryptpin, cplen);
345 }
346
347 /* Provide information about a token in the provided buffer */
348 (void) strncpy((char *)pInfo->label, SOFT_TOKEN_LABEL, 32);
349 (void) strncpy((char *)pInfo->manufacturerID, SOFT_MANUFACTURER_ID, 32);
350 (void) strncpy((char *)pInfo->model, TOKEN_MODEL, 16);
351 (void) strncpy((char *)pInfo->serialNumber, SOFT_TOKEN_SERIAL, 16);
352
353 pInfo->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
354 pInfo->ulSessionCount = soft_session_cnt;
355 pInfo->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
356 pInfo->ulRwSessionCount = soft_session_rw_cnt;
357 pInfo->ulMaxPinLen = MAX_PIN_LEN;
358 pInfo->ulMinPinLen = MIN_PIN_LEN;
359 pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
360 pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
361 pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
362 pInfo->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
363 pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
364 pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
365 pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
366 pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
367 (void) memset(pInfo->utcTime, ' ', 16);
368
369 return (CKR_OK);
370 }
371
372 /*ARGSUSED*/
373 CK_RV
374 C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
375 {
376 if (!softtoken_initialized)
377 return (CKR_CRYPTOKI_NOT_INITIALIZED);
378
379 /*
380 * This is currently not implemented, however we could cause this
381 * to wait for the token files to appear if soft_token_present is
382 * false.
383 * However there is currently no polite and portable way to do that
384 * because we might not even be able to get to an fd to the
385 * parent directory, so instead we don't support any slot events.
386 */
387 return (CKR_FUNCTION_NOT_SUPPORTED);
388 }
389
390
391 CK_RV
392 C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
393 CK_ULONG_PTR pulCount)
394 {
395
396 ulong_t i;
397 ulong_t mechnum;
398
399 if (!softtoken_initialized)
400 return (CKR_CRYPTOKI_NOT_INITIALIZED);
401
402 if (slotID != SOFTTOKEN_SLOTID)
403 return (CKR_SLOT_ID_INVALID);
404
405 mechnum = sizeof (soft_mechanisms) / sizeof (CK_MECHANISM_TYPE);
406
407 if (pMechanismList == NULL) {
408 /*
409 * Application only wants to know the number of
410 * supported mechanism types.
411 */
412 *pulCount = mechnum;
413 return (CKR_OK);
414 }
415
416 if (*pulCount < mechnum) {
417 *pulCount = mechnum;
418 return (CKR_BUFFER_TOO_SMALL);
419 }
420
421 for (i = 0; i < mechnum; i++) {
422 pMechanismList[i] = soft_mechanisms[i];
423 }
424
425 *pulCount = mechnum;
426
427 return (CKR_OK);
428 }
429
430
431 CK_RV
432 C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
433 CK_MECHANISM_INFO_PTR pInfo)
434 {
435
436 ulong_t i;
437 ulong_t mechnum;
438
439 if (!softtoken_initialized)
440 return (CKR_CRYPTOKI_NOT_INITIALIZED);
441
442 if (slotID != SOFTTOKEN_SLOTID)
443 return (CKR_SLOT_ID_INVALID);
444
445 if (pInfo == NULL) {
446 return (CKR_ARGUMENTS_BAD);
447 }
448
449 mechnum = sizeof (soft_mechanisms) / sizeof (CK_MECHANISM_TYPE);
450 for (i = 0; i < mechnum; i++) {
451 if (soft_mechanisms[i] == type)
452 break;
453 }
454
455 if (i == mechnum)
456 /* unsupported mechanism */
457 return (CKR_MECHANISM_INVALID);
458
459 pInfo->ulMinKeySize = soft_mechanism_info[i].ulMinKeySize;
460 pInfo->ulMaxKeySize = soft_mechanism_info[i].ulMaxKeySize;
461 pInfo->flags = soft_mechanism_info[i].flags;
462
463 return (CKR_OK);
464 }
465
466
467 /*ARGSUSED*/
468 CK_RV
469 C_InitToken(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen,
470 CK_UTF8CHAR_PTR pLabel)
471 {
472 if (!softtoken_initialized)
473 return (CKR_CRYPTOKI_NOT_INITIALIZED);
474
475 if (create_keystore() != 0)
476 return (CKR_FUNCTION_FAILED);
477
478 return (CKR_OK);
479 }
480
481 /*ARGSUSED*/
482 CK_RV
483 C_InitPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
484 {
485 if (!softtoken_initialized)
486 return (CKR_CRYPTOKI_NOT_INITIALIZED);
487
488 return (CKR_FUNCTION_NOT_SUPPORTED);
489 }
490
491
492 CK_RV
493 C_SetPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
494 CK_ULONG ulOldPinLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
495 {
496
497 soft_session_t *session_p;
498 CK_RV rv;
499 boolean_t lock_held = B_FALSE;
500
501 if (!softtoken_initialized)
502 return (CKR_CRYPTOKI_NOT_INITIALIZED);
503
504 /*
505 * Obtain the session pointer. Also, increment the session
506 * reference count.
507 */
508 rv = handle2session(hSession, &session_p);
509 if (rv != CKR_OK)
510 return (rv);
511
512 if (!soft_keystore_status(KEYSTORE_LOAD)) {
513 SES_REFRELE(session_p, lock_held);
514 return (CKR_DEVICE_REMOVED);
515 }
516
517 if ((ulOldPinLen < MIN_PIN_LEN) || (ulOldPinLen > MAX_PIN_LEN) ||
518 (ulNewPinLen < MIN_PIN_LEN) ||(ulNewPinLen > MAX_PIN_LEN)) {
519 SES_REFRELE(session_p, lock_held);
520 return (CKR_PIN_LEN_RANGE);
521 }
522
523 if ((pOldPin == NULL_PTR) || (pNewPin == NULL_PTR)) {
524 /*
525 * We don't support CKF_PROTECTED_AUTHENTICATION_PATH
526 */
527 SES_REFRELE(session_p, lock_held);
528 return (CKR_ARGUMENTS_BAD);
529 }
530
531 /* check the state of the session */
532 if ((session_p->state != CKS_RW_PUBLIC_SESSION) &&
533 (session_p->state != CKS_RW_USER_FUNCTIONS)) {
534 SES_REFRELE(session_p, lock_held);
535 return (CKR_SESSION_READ_ONLY);
536 }
537
538 rv = soft_setpin(pOldPin, ulOldPinLen, pNewPin, ulNewPinLen);
539
540 SES_REFRELE(session_p, lock_held);
541 return (rv);
542 }