/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include #include #include "pkcs11Global.h" #include "pkcs11Session.h" #include "pkcs11Slot.h" #include "metaGlobal.h" /* * C_OpenSession will need to create a pseudo session associated * with the session created by the plugged in provider. Only * minimal argument checking is done here, as we rely on the * underlying provider to catch most errors. */ CK_RV C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession) { CK_RV rv; CK_SLOT_ID true_id; CK_SLOT_ID fw_st_id; /* id for accessing framework's slottable */ CK_SESSION_HANDLE prov_sess; if (!pkcs11_initialized) { return (CKR_CRYPTOKI_NOT_INITIALIZED); } /* Check for a fastpath */ if (purefastpath || policyfastpath) { if (metaslot_enabled) { /* * if metaslot is enabled and we are in fastpath * mode, only one other slot is in the framework * so, need to go to that slot's entry * to look up the true slot ID for the slot */ return (fast_funcs->C_OpenSession(TRUEID(slotID+1), flags, pApplication, Notify, phSession)); } else { return (fast_funcs->C_OpenSession(slotID, flags, pApplication, Notify, phSession)); } } if (slotID == METASLOT_FRAMEWORK_ID) { rv = meta_OpenSession(METASLOT_SLOTID, flags, pApplication, Notify, &prov_sess); } else { /* Check that slotID is valid */ if (pkcs11_validate_and_convert_slotid(slotID, &fw_st_id) != CKR_OK) { return (CKR_SLOT_ID_INVALID); } true_id = TRUEID(fw_st_id); rv = FUNCLIST(fw_st_id)->C_OpenSession(true_id, flags, pApplication, Notify, &prov_sess); } /* Present consistent interface for framework */ if (rv == CKR_FUNCTION_NOT_SUPPORTED) { return (CKR_FUNCTION_FAILED); } else if (rv != CKR_OK) { /* could not create session with provider, return now */ return (rv); } /* Provider was successful, now create session in framework */ if (slotID == METASLOT_FRAMEWORK_ID) { rv = pkcs11_session_add( slottable->st_slots[METASLOT_FRAMEWORK_ID], METASLOT_FRAMEWORK_ID, phSession, prov_sess); } else { rv = pkcs11_session_add(slottable->st_slots[fw_st_id], fw_st_id, phSession, prov_sess); } if (rv != CKR_OK) { /* Trouble in the framework, clean up provider session */ FUNCLIST(slotID)->C_CloseSession(prov_sess); } return (rv); } /* * C_CloseSession will close a session with the underlying provider, * and if that's successful will close it in the framework. */ CK_RV C_CloseSession(CK_SESSION_HANDLE hSession) { CK_RV rv; pkcs11_session_t *sessp; /* Check for a fastpath */ if (purefastpath || policyfastpath) { return (fast_funcs->C_CloseSession(hSession)); } if (!pkcs11_initialized) { return (CKR_CRYPTOKI_NOT_INITIALIZED); } /* Obtain the session pointer */ HANDLE2SESSION(hSession, sessp, rv); if (rv != CKR_OK) { return (rv); } /* Delete the session with the provider */ rv = FUNCLIST(sessp->se_slotid)->C_CloseSession(sessp->se_handle); /* Present consistent interface for framework */ if (rv == CKR_FUNCTION_NOT_SUPPORTED) { return (CKR_FUNCTION_FAILED); } else if (rv != CKR_OK) { /* could not delete session with provider, return now */ return (rv); } /* Delete session from the framework */ pkcs11_session_delete(slottable->st_slots[sessp->se_slotid], sessp); return (rv); } /* * C_CloseAllSessions will close all sessions associated with this * slot with the underlying provider. If that is successful, will * close the associated sessions in the framework. If the provider * has not implemented C_CloseAllSessions, then we will loop through * the list of sessions and individually call C_CloseSession. */ CK_RV C_CloseAllSessions(CK_SLOT_ID slotID) { CK_RV rv, rv1; CK_SLOT_ID true_id; CK_SLOT_ID fw_st_id; /* id for accessing framework's slottable */ pkcs11_session_t *sessp, *sess_nextp; pkcs11_slot_t *slotp; if (!pkcs11_initialized) { return (CKR_CRYPTOKI_NOT_INITIALIZED); } /* Check for a fastpath */ if (purefastpath || policyfastpath) { if (metaslot_enabled) { /* * if metaslot is enabled and we are in fastpath * mode, only one other slot is in the framework * so, need to go to that slot's entry * to look up the true slot ID for the slot */ return (fast_funcs->C_CloseAllSessions( TRUEID(slotID+1))); } else { return (fast_funcs->C_CloseAllSessions(slotID)); } } /* Check that slotID is valid */ if (pkcs11_validate_and_convert_slotid(slotID, &fw_st_id) != CKR_OK) { return (CKR_SLOT_ID_INVALID); } slotp = slottable->st_slots[fw_st_id]; true_id = TRUEID(fw_st_id); rv = FUNCLIST(fw_st_id)->C_CloseAllSessions(true_id); /* Present consistent interface for framework */ if (rv == CKR_FUNCTION_NOT_SUPPORTED) { /* Need to attempt to individually delete sessions */ /* reset rv */ rv = CKR_OK; (void) pthread_mutex_lock(&slotp->sl_mutex); sessp = slotp->sl_sess_list; while (sessp) { sess_nextp = sessp->se_next; rv1 = FUNCLIST(fw_st_id)-> C_CloseSession(sessp->se_handle); /* Record the first error encountered */ if ((rv == CKR_OK) && (rv1 != CKR_OK)) { rv = rv1; } sessp = sess_nextp; } (void) pthread_mutex_unlock(&slotp->sl_mutex); } if (rv != CKR_OK) { /* could not delete sessionlist with provider, return now */ return (rv); } /* Delete sessions from the framework */ pkcs11_sessionlist_delete(slotp); return (rv); } /* * C_GetSessionInfo is a pure wrapper to the underlying provider. * The only argument checked is whether or not hSession is valid. */ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo) { CK_RV rv; CK_SLOT_ID slot_id; pkcs11_session_t *sessp; /* Check for a fastpath */ if (purefastpath || policyfastpath) { rv = fast_funcs->C_GetSessionInfo(hSession, pInfo); /* * If metaslot is enabled, and we are here, that * that means there's only 1 other slot in the * framework, and that slot should be hidden. * so, override value of slot id to be metaslot's * slot id. */ if (metaslot_enabled) { pInfo->slotID = METASLOT_FRAMEWORK_ID; } return (rv); } if (!pkcs11_initialized) { return (CKR_CRYPTOKI_NOT_INITIALIZED); } /* Obtain the session pointer */ HANDLE2SESSION(hSession, sessp, rv); if (rv != CKR_OK) { return (rv); } /* Find the slot id for the framework */ slot_id = sessp->se_slotid; /* Get session info from the provider */ rv = FUNCLIST(slot_id)-> C_GetSessionInfo(sessp->se_handle, pInfo); /* Present consistent interface to the application */ if (rv == CKR_FUNCTION_NOT_SUPPORTED) { return (CKR_FUNCTION_FAILED); } /* Override value of slot id to framework's */ pInfo->slotID = slot_id; return (rv); } /* * C_GetOperationState is a pure wrapper to the underlying provider. * The only argument checked is whether or not hSession is valid. */ CK_RV C_GetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) { CK_RV rv; pkcs11_session_t *sessp; /* Check for a fastpath */ if (purefastpath || policyfastpath) { return (fast_funcs->C_GetOperationState(hSession, pOperationState, pulOperationStateLen)); } if (!pkcs11_initialized) { return (CKR_CRYPTOKI_NOT_INITIALIZED); } /* Obtain the session pointer */ HANDLE2SESSION(hSession, sessp, rv); if (rv != CKR_OK) { return (rv); } /* Get the operation state with the provider */ rv = FUNCLIST(sessp->se_slotid)->C_GetOperationState(sessp->se_handle, pOperationState, pulOperationStateLen); /* Present consistent interface to the application */ if (rv == CKR_FUNCTION_NOT_SUPPORTED) { return (CKR_FUNCTION_FAILED); } return (rv); } /* * C_SetOperationState is a pure wrapper to the underlying provider. * The only argument checked is whether or not hSession is valid. */ CK_RV C_SetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) { CK_RV rv; pkcs11_session_t *sessp; /* Check for a fastpath */ if (purefastpath || policyfastpath) { return (fast_funcs->C_SetOperationState(hSession, pOperationState, ulOperationStateLen, hEncryptionKey, hAuthenticationKey)); } if (!pkcs11_initialized) { return (CKR_CRYPTOKI_NOT_INITIALIZED); } /* Obtain the session pointer */ HANDLE2SESSION(hSession, sessp, rv); if (rv != CKR_OK) { return (rv); } /* Set the operation state with the provider */ rv = FUNCLIST(sessp->se_slotid)->C_SetOperationState(sessp->se_handle, pOperationState, ulOperationStateLen, hEncryptionKey, hAuthenticationKey); /* Present consistent interface to the application */ if (rv == CKR_FUNCTION_NOT_SUPPORTED) { return (CKR_FUNCTION_FAILED); } return (rv); } /* * C_Login is a pure wrapper to the underlying provider. * The only argument checked is whether or not hSession is valid. */ CK_RV C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) { CK_RV rv; pkcs11_session_t *sessp; /* Check for a fastpath */ if (purefastpath || policyfastpath) { return (fast_funcs->C_Login(hSession, userType, pPin, ulPinLen)); } if (!pkcs11_initialized) { return (CKR_CRYPTOKI_NOT_INITIALIZED); } /* Obtain the session pointer */ HANDLE2SESSION(hSession, sessp, rv); if (rv != CKR_OK) { return (rv); } /* Login with the provider */ rv = FUNCLIST(sessp->se_slotid)->C_Login(sessp->se_handle, userType, pPin, ulPinLen); /* Present consistent interface to the application */ if (rv == CKR_FUNCTION_NOT_SUPPORTED) { return (CKR_FUNCTION_FAILED); } return (rv); } /* * C_Logout is a pure wrapper to the underlying provider. * The only argument checked is whether or not hSession is valid. */ CK_RV C_Logout(CK_SESSION_HANDLE hSession) { CK_RV rv; pkcs11_session_t *sessp; /* Check for a fastpath */ if (purefastpath || policyfastpath) { return (fast_funcs->C_Logout(hSession)); } if (!pkcs11_initialized) { return (CKR_CRYPTOKI_NOT_INITIALIZED); } /* Obtain the session pointer */ HANDLE2SESSION(hSession, sessp, rv); if (rv != CKR_OK) { return (rv); } rv = FUNCLIST(sessp->se_slotid)->C_Logout(sessp->se_handle); /* Present consistent interface to the application */ if (rv == CKR_FUNCTION_NOT_SUPPORTED) { return (CKR_FUNCTION_FAILED); } return (rv); }