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