📄 pkcs11-session.c
字号:
/* * pkcs11-session.c: PKCS#11 functions for session management * * Copyright (C) 2001 Timo Ter鋝 <timo.teras@iki.fi> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "sc-pkcs11.h"CK_RV C_OpenSession(CK_SLOT_ID slotID, /* the slot's ID */ CK_FLAGS flags, /* defined in CK_SESSION_INFO */ CK_VOID_PTR pApplication, /* pointer passed to callback */ CK_NOTIFY Notify, /* notification callback function */ CK_SESSION_HANDLE_PTR phSession) /* receives new session handle */{ struct sc_pkcs11_slot *slot; struct sc_pkcs11_session *session; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; sc_debug(context, "Opening new session for slot %d\n", slotID); if (!(flags & CKF_SERIAL_SESSION)) { rv = CKR_SESSION_PARALLEL_NOT_SUPPORTED; goto out; } if (flags & ~(CKF_SERIAL_SESSION | CKF_RW_SESSION)) { rv = CKR_ARGUMENTS_BAD; goto out; } rv = slot_get_token(slotID, &slot); if (rv != CKR_OK) goto out; /* Check that no conflictions sessions exist */ if (!(flags & CKF_RW_SESSION) && (slot->login_user == CKU_SO)) { rv = CKR_SESSION_READ_WRITE_SO_EXISTS; goto out; } session = (struct sc_pkcs11_session*) malloc(sizeof(struct sc_pkcs11_session)); memset(session, 0, sizeof(struct sc_pkcs11_session)); session->slot = slot; session->notify_callback = Notify; session->notify_data = pApplication; session->flags = flags; rv = pool_insert(&session_pool, session, phSession); if (rv != CKR_OK) free(session); else slot->nsessions++;out: sc_pkcs11_unlock(); return rv;}CK_RV C_CloseSession(CK_SESSION_HANDLE hSession) /* the session's handle */{ struct sc_pkcs11_slot *slot; struct sc_pkcs11_session *session; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find_and_delete(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; sc_debug(context, "C_CloseSession(slot %d)\n", session->slot->id); /* If we're the last session using this slot, make sure * we log out */ slot = session->slot; slot->nsessions--; if (slot->nsessions == 0 && slot->login_user >= 0) { slot->login_user = -1; slot->card->framework->logout(slot->card, slot->fw_data); } free(session);out: sc_pkcs11_unlock(); return rv;}/* Internal version of C_CloseAllSessions that gets called with * the global lock held */CK_RV sc_pkcs11_close_all_sessions(CK_SLOT_ID slotID){ struct sc_pkcs11_pool_item *item, *next; struct sc_pkcs11_session *session; sc_debug(context, "C_CloseAllSessions().\n"); for (item = session_pool.head; item != NULL; item = next) { session = (struct sc_pkcs11_session*) item->item; next = item->next; if (session->slot->id == slotID) { C_CloseSession(item->handle); } } return CKR_OK;}CK_RV C_CloseAllSessions(CK_SLOT_ID slotID) /* the token's slot */{ struct sc_pkcs11_slot *slot; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = slot_get_token(slotID, &slot); if (rv != CKR_OK) goto out; rv = sc_pkcs11_close_all_sessions(slotID);out: sc_pkcs11_unlock(); return rv;}CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_SESSION_INFO_PTR pInfo) /* receives session information */{ struct sc_pkcs11_session *session; struct sc_pkcs11_slot *slot; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; if (pInfo == NULL_PTR) { rv = CKR_ARGUMENTS_BAD; goto out; } rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; sc_debug(context, "C_GetSessionInfo(slot %d).\n", session->slot->id); pInfo->slotID = session->slot->id; pInfo->flags = session->flags; pInfo->ulDeviceError = 0; slot = session->slot; if (slot->login_user == CKU_SO) { pInfo->state = CKS_RW_SO_FUNCTIONS; } else if (slot->login_user == CKU_USER || (!(slot->token_info.flags & CKF_LOGIN_REQUIRED))) { pInfo->state = (session->flags & CKF_RW_SESSION) ? CKS_RW_USER_FUNCTIONS : CKS_RO_USER_FUNCTIONS; } else { pInfo->state = (session->flags & CKF_RW_SESSION) ? CKS_RW_PUBLIC_SESSION : CKS_RO_PUBLIC_SESSION; }out: sc_pkcs11_unlock(); return rv;}CK_RV C_GetOperationState(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pOperationState, /* location receiving state */ CK_ULONG_PTR pulOperationStateLen) /* location receiving state length */{ return CKR_FUNCTION_NOT_SUPPORTED;}CK_RV C_SetOperationState(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pOperationState, /* the location holding the state */ CK_ULONG ulOperationStateLen, /* location holding state length */ CK_OBJECT_HANDLE hEncryptionKey, /* handle of en/decryption key */ CK_OBJECT_HANDLE hAuthenticationKey) /* handle of sign/verify key */{ return CKR_FUNCTION_NOT_SUPPORTED;}CK_RV C_Login(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_USER_TYPE userType, /* the user type */ CK_CHAR_PTR pPin, /* the user's PIN */ CK_ULONG ulPinLen) /* the length of the PIN */{ int rv; struct sc_pkcs11_session *session; struct sc_pkcs11_slot *slot; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; if (userType != CKU_USER && userType != CKU_SO) { rv = CKR_USER_TYPE_INVALID; goto out; } rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; sc_debug(context, "Login for session %d\n", hSession); slot = session->slot; if (!(slot->token_info.flags & CKF_USER_PIN_INITIALIZED)) { rv = CKR_USER_PIN_NOT_INITIALIZED; goto out; } if (slot->login_user >= 0) { rv = CKR_USER_ALREADY_LOGGED_IN; goto out; } rv = slot->card->framework->login(slot->card, slot->fw_data, userType, pPin, ulPinLen); if (rv == CKR_OK) slot->login_user = userType;out: sc_pkcs11_unlock(); return rv;}CK_RV C_Logout(CK_SESSION_HANDLE hSession) /* the session's handle */{ int rv; struct sc_pkcs11_session *session; struct sc_pkcs11_slot *slot; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; sc_debug(context, "Logout for session %d\n", hSession); slot = session->slot; if (slot->login_user >= 0) { slot->login_user = -1; rv = slot->card->framework->logout(slot->card, slot->fw_data); } else rv = CKR_USER_NOT_LOGGED_IN;out: sc_pkcs11_unlock(); return rv;}CK_RV C_InitPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen){ struct sc_pkcs11_session *session; struct sc_pkcs11_slot *slot; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; slot = session->slot; if (slot->login_user != CKU_SO) { rv = CKR_USER_NOT_LOGGED_IN; } else if (slot->card->framework->init_pin == NULL) { rv = CKR_FUNCTION_NOT_SUPPORTED; } else { rv = slot->card->framework->init_pin(slot->card, slot, pPin, ulPinLen); }out: sc_pkcs11_unlock(); return rv;}CK_RV C_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen){ int rv; struct sc_pkcs11_session *session; struct sc_pkcs11_slot *slot; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; sc_debug(context, "Changing PIN (session %d)\n", hSession);#if 0 if (!(ses->flags & CKF_RW_SESSION)) { rv = CKR_SESSION_READ_ONLY; goto out; }#endif slot = session->slot; rv = slot->card->framework->change_pin(slot->card, slot->fw_data, pOldPin, ulOldLen, pNewPin, ulNewLen);out: sc_pkcs11_unlock(); return rv;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -