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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <pthread.h> 28 #include <security/cryptoki.h> 29 #include "pkcs11Global.h" 30 #include "pkcs11Session.h" 31 #include "pkcs11Slot.h" 32 #include "metaGlobal.h" 33 34 /* 35 * C_OpenSession will need to create a pseudo session associated 36 * with the session created by the plugged in provider. Only 37 * minimal argument checking is done here, as we rely on the 38 * underlying provider to catch most errors. 39 */ 40 CK_RV 41 C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, 42 CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession) 43 { 44 45 CK_RV rv; 46 CK_SLOT_ID true_id; 47 CK_SLOT_ID fw_st_id; /* id for accessing framework's slottable */ 48 CK_SESSION_HANDLE prov_sess; 49 50 if (!pkcs11_initialized) { 51 return (CKR_CRYPTOKI_NOT_INITIALIZED); 52 } 53 54 /* Check for a fastpath */ 55 if (purefastpath || policyfastpath) { 56 if (metaslot_enabled) { 57 /* 58 * if metaslot is enabled and we are in fastpath 59 * mode, only one other slot is in the framework 60 * so, need to go to that slot's entry 61 * to look up the true slot ID for the slot 62 */ 63 return (fast_funcs->C_OpenSession(TRUEID(slotID+1), 64 flags, pApplication, Notify, phSession)); 65 } else { 66 return (fast_funcs->C_OpenSession(slotID, flags, 67 pApplication, Notify, phSession)); 68 } 69 } 70 71 72 if (slotID == METASLOT_FRAMEWORK_ID) { 73 rv = meta_OpenSession(METASLOT_SLOTID, flags, 74 pApplication, Notify, &prov_sess); 75 } else { 76 /* Check that slotID is valid */ 77 if (pkcs11_validate_and_convert_slotid(slotID, &fw_st_id) 78 != CKR_OK) { 79 return (CKR_SLOT_ID_INVALID); 80 } 81 true_id = TRUEID(fw_st_id); 82 rv = FUNCLIST(fw_st_id)->C_OpenSession(true_id, flags, 83 pApplication, Notify, &prov_sess); 84 } 85 86 /* Present consistent interface for framework */ 87 if (rv == CKR_FUNCTION_NOT_SUPPORTED) { 88 return (CKR_FUNCTION_FAILED); 89 } else if (rv != CKR_OK) { 90 /* could not create session with provider, return now */ 91 return (rv); 92 } 93 94 /* Provider was successful, now create session in framework */ 95 if (slotID == METASLOT_FRAMEWORK_ID) { 96 rv = pkcs11_session_add( 97 slottable->st_slots[METASLOT_FRAMEWORK_ID], 98 METASLOT_FRAMEWORK_ID, phSession, prov_sess); 99 } else { 100 rv = pkcs11_session_add(slottable->st_slots[fw_st_id], 101 fw_st_id, phSession, prov_sess); 102 } 103 104 if (rv != CKR_OK) { 105 /* Trouble in the framework, clean up provider session */ 106 FUNCLIST(slotID)->C_CloseSession(prov_sess); 107 } 108 return (rv); 109 } 110 111 /* 112 * C_CloseSession will close a session with the underlying provider, 113 * and if that's successful will close it in the framework. 114 */ 115 CK_RV 116 C_CloseSession(CK_SESSION_HANDLE hSession) 117 { 118 CK_RV rv; 119 pkcs11_session_t *sessp; 120 121 /* Check for a fastpath */ 122 if (purefastpath || policyfastpath) { 123 return (fast_funcs->C_CloseSession(hSession)); 124 } 125 126 if (!pkcs11_initialized) { 127 return (CKR_CRYPTOKI_NOT_INITIALIZED); 128 } 129 130 /* Obtain the session pointer */ 131 HANDLE2SESSION(hSession, sessp, rv); 132 133 if (rv != CKR_OK) { 134 return (rv); 135 } 136 137 /* Delete the session with the provider */ 138 rv = FUNCLIST(sessp->se_slotid)->C_CloseSession(sessp->se_handle); 139 140 /* Present consistent interface for framework */ 141 if (rv == CKR_FUNCTION_NOT_SUPPORTED) { 142 return (CKR_FUNCTION_FAILED); 143 } else if (rv != CKR_OK) { 144 /* could not delete session with provider, return now */ 145 return (rv); 146 } 147 148 /* Delete session from the framework */ 149 pkcs11_session_delete(slottable->st_slots[sessp->se_slotid], sessp); 150 151 return (rv); 152 } 153 154 /* 155 * C_CloseAllSessions will close all sessions associated with this 156 * slot with the underlying provider. If that is successful, will 157 * close the associated sessions in the framework. If the provider 158 * has not implemented C_CloseAllSessions, then we will loop through 159 * the list of sessions and individually call C_CloseSession. 160 */ 161 CK_RV 162 C_CloseAllSessions(CK_SLOT_ID slotID) 163 { 164 165 CK_RV rv, rv1; 166 167 CK_SLOT_ID true_id; 168 CK_SLOT_ID fw_st_id; /* id for accessing framework's slottable */ 169 pkcs11_session_t *sessp, *sess_nextp; 170 pkcs11_slot_t *slotp; 171 172 if (!pkcs11_initialized) { 173 return (CKR_CRYPTOKI_NOT_INITIALIZED); 174 } 175 176 /* Check for a fastpath */ 177 if (purefastpath || policyfastpath) { 178 if (metaslot_enabled) { 179 /* 180 * if metaslot is enabled and we are in fastpath 181 * mode, only one other slot is in the framework 182 * so, need to go to that slot's entry 183 * to look up the true slot ID for the slot 184 */ 185 return (fast_funcs->C_CloseAllSessions( 186 TRUEID(slotID+1))); 187 } else { 188 return (fast_funcs->C_CloseAllSessions(slotID)); 189 } 190 } 191 192 /* Check that slotID is valid */ 193 if (pkcs11_validate_and_convert_slotid(slotID, &fw_st_id) != CKR_OK) { 194 return (CKR_SLOT_ID_INVALID); 195 } 196 197 slotp = slottable->st_slots[fw_st_id]; 198 true_id = TRUEID(fw_st_id); 199 200 rv = FUNCLIST(fw_st_id)->C_CloseAllSessions(true_id); 201 202 /* Present consistent interface for framework */ 203 if (rv == CKR_FUNCTION_NOT_SUPPORTED) { 204 /* Need to attempt to individually delete sessions */ 205 206 /* reset rv */ 207 rv = CKR_OK; 208 209 (void) pthread_mutex_lock(&slotp->sl_mutex); 210 sessp = slotp->sl_sess_list; 211 212 while (sessp) { 213 sess_nextp = sessp->se_next; 214 215 rv1 = FUNCLIST(fw_st_id)-> 216 C_CloseSession(sessp->se_handle); 217 218 /* Record the first error encountered */ 219 if ((rv == CKR_OK) && (rv1 != CKR_OK)) { 220 rv = rv1; 221 } 222 223 sessp = sess_nextp; 224 } 225 226 (void) pthread_mutex_unlock(&slotp->sl_mutex); 227 } 228 229 if (rv != CKR_OK) { 230 /* could not delete sessionlist with provider, return now */ 231 return (rv); 232 } 233 234 /* Delete sessions from the framework */ 235 pkcs11_sessionlist_delete(slotp); 236 237 return (rv); 238 } 239 240 /* 241 * C_GetSessionInfo is a pure wrapper to the underlying provider. 242 * The only argument checked is whether or not hSession is valid. 243 */ 244 CK_RV 245 C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo) 246 { 247 248 CK_RV rv; 249 CK_SLOT_ID slot_id; 250 pkcs11_session_t *sessp; 251 252 /* Check for a fastpath */ 253 if (purefastpath || policyfastpath) { 254 rv = fast_funcs->C_GetSessionInfo(hSession, pInfo); 255 256 /* 257 * If metaslot is enabled, and we are here, that 258 * that means there's only 1 other slot in the 259 * framework, and that slot should be hidden. 260 * so, override value of slot id to be metaslot's 261 * slot id. 262 */ 263 if (metaslot_enabled) { 264 pInfo->slotID = METASLOT_FRAMEWORK_ID; 265 } 266 return (rv); 267 } 268 269 if (!pkcs11_initialized) { 270 return (CKR_CRYPTOKI_NOT_INITIALIZED); 271 } 272 273 /* Obtain the session pointer */ 274 HANDLE2SESSION(hSession, sessp, rv); 275 276 if (rv != CKR_OK) { 277 return (rv); 278 } 279 280 /* Find the slot id for the framework */ 281 slot_id = sessp->se_slotid; 282 283 /* Get session info from the provider */ 284 rv = FUNCLIST(slot_id)-> 285 C_GetSessionInfo(sessp->se_handle, pInfo); 286 287 /* Present consistent interface to the application */ 288 if (rv == CKR_FUNCTION_NOT_SUPPORTED) { 289 return (CKR_FUNCTION_FAILED); 290 } 291 292 /* Override value of slot id to framework's */ 293 pInfo->slotID = slot_id; 294 295 return (rv); 296 } 297 298 /* 299 * C_GetOperationState is a pure wrapper to the underlying provider. 300 * The only argument checked is whether or not hSession is valid. 301 */ 302 CK_RV 303 C_GetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, 304 CK_ULONG_PTR pulOperationStateLen) 305 { 306 307 CK_RV rv; 308 pkcs11_session_t *sessp; 309 310 /* Check for a fastpath */ 311 if (purefastpath || policyfastpath) { 312 return (fast_funcs->C_GetOperationState(hSession, 313 pOperationState, pulOperationStateLen)); 314 } 315 316 if (!pkcs11_initialized) { 317 return (CKR_CRYPTOKI_NOT_INITIALIZED); 318 } 319 320 /* Obtain the session pointer */ 321 HANDLE2SESSION(hSession, sessp, rv); 322 323 if (rv != CKR_OK) { 324 return (rv); 325 } 326 327 /* Get the operation state with the provider */ 328 rv = FUNCLIST(sessp->se_slotid)->C_GetOperationState(sessp->se_handle, 329 pOperationState, pulOperationStateLen); 330 331 /* Present consistent interface to the application */ 332 if (rv == CKR_FUNCTION_NOT_SUPPORTED) { 333 return (CKR_FUNCTION_FAILED); 334 } 335 336 return (rv); 337 } 338 339 340 /* 341 * C_SetOperationState is a pure wrapper to the underlying provider. 342 * The only argument checked is whether or not hSession is valid. 343 */ 344 CK_RV 345 C_SetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, 346 CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, 347 CK_OBJECT_HANDLE hAuthenticationKey) 348 { 349 CK_RV rv; 350 pkcs11_session_t *sessp; 351 352 /* Check for a fastpath */ 353 if (purefastpath || policyfastpath) { 354 return (fast_funcs->C_SetOperationState(hSession, 355 pOperationState, ulOperationStateLen, 356 hEncryptionKey, hAuthenticationKey)); 357 } 358 359 if (!pkcs11_initialized) { 360 return (CKR_CRYPTOKI_NOT_INITIALIZED); 361 } 362 363 /* Obtain the session pointer */ 364 HANDLE2SESSION(hSession, sessp, rv); 365 366 if (rv != CKR_OK) { 367 return (rv); 368 } 369 370 /* Set the operation state with the provider */ 371 rv = FUNCLIST(sessp->se_slotid)->C_SetOperationState(sessp->se_handle, 372 pOperationState, ulOperationStateLen, hEncryptionKey, 373 hAuthenticationKey); 374 375 /* Present consistent interface to the application */ 376 if (rv == CKR_FUNCTION_NOT_SUPPORTED) { 377 return (CKR_FUNCTION_FAILED); 378 } 379 380 return (rv); 381 } 382 383 384 /* 385 * C_Login is a pure wrapper to the underlying provider. 386 * The only argument checked is whether or not hSession is valid. 387 */ 388 CK_RV 389 C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, 390 CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) 391 { 392 CK_RV rv; 393 pkcs11_session_t *sessp; 394 395 /* Check for a fastpath */ 396 if (purefastpath || policyfastpath) { 397 return (fast_funcs->C_Login(hSession, userType, pPin, 398 ulPinLen)); 399 } 400 401 if (!pkcs11_initialized) { 402 return (CKR_CRYPTOKI_NOT_INITIALIZED); 403 } 404 405 /* Obtain the session pointer */ 406 HANDLE2SESSION(hSession, sessp, rv); 407 408 if (rv != CKR_OK) { 409 return (rv); 410 } 411 412 /* Login with the provider */ 413 rv = FUNCLIST(sessp->se_slotid)->C_Login(sessp->se_handle, 414 userType, pPin, ulPinLen); 415 416 /* Present consistent interface to the application */ 417 if (rv == CKR_FUNCTION_NOT_SUPPORTED) { 418 return (CKR_FUNCTION_FAILED); 419 } 420 421 return (rv); 422 } 423 424 /* 425 * C_Logout is a pure wrapper to the underlying provider. 426 * The only argument checked is whether or not hSession is valid. 427 */ 428 CK_RV 429 C_Logout(CK_SESSION_HANDLE hSession) 430 { 431 CK_RV rv; 432 pkcs11_session_t *sessp; 433 434 /* Check for a fastpath */ 435 if (purefastpath || policyfastpath) { 436 return (fast_funcs->C_Logout(hSession)); 437 } 438 439 if (!pkcs11_initialized) { 440 return (CKR_CRYPTOKI_NOT_INITIALIZED); 441 } 442 443 /* Obtain the session pointer */ 444 HANDLE2SESSION(hSession, sessp, rv); 445 446 if (rv != CKR_OK) { 447 return (rv); 448 } 449 450 rv = FUNCLIST(sessp->se_slotid)->C_Logout(sessp->se_handle); 451 452 /* Present consistent interface to the application */ 453 if (rv == CKR_FUNCTION_NOT_SUPPORTED) { 454 return (CKR_FUNCTION_FAILED); 455 } 456 457 return (rv); 458 } 459