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