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