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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SOFTSESSION_H 27 #define _SOFTSESSION_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #include <pthread.h> 36 #include <security/pkcs11t.h> 37 38 39 #define SOFTTOKEN_SESSION_MAGIC 0xECF00002 40 41 /* 42 * This is only used by the C_G(S)etOperationState. 43 */ 44 #define DIGEST_OP 1 45 46 /* 47 * This is only used by the C_G(S)etOperationState. 48 */ 49 typedef struct internal_op_state { 50 /* Holds the length of the saved state */ 51 CK_ULONG op_len; 52 53 /* crypto operation to be saved or restored */ 54 CK_ULONG op_active; 55 56 /* Holds the saved session state */ 57 CK_STATE op_session_state; 58 59 } internal_op_state_t; 60 61 typedef struct crypto_active_op { 62 CK_MECHANISM mech; 63 void *context; 64 uint32_t flags; 65 } crypto_active_op_t; 66 67 68 /* 69 * Definition for flags in crypto_active_op_t 70 */ 71 #define CRYPTO_OPERATION_ACTIVE 1 /* Cryptoki operation is active */ 72 #define CRYPTO_OPERATION_UPDATE 2 /* Cryptoki multi-part op active */ 73 #define CRYPTO_KEY_DIGESTED 3 /* A C_DigestKey() was called */ 74 75 typedef struct session { 76 ulong_t magic_marker; /* magic # be validated for integrity */ 77 pthread_mutex_t session_mutex; /* session's mutex lock */ 78 pthread_cond_t ses_free_cond; /* cond variable for signal and wait */ 79 uint32_t ses_refcnt; /* session reference count */ 80 uint32_t ses_close_sync; /* session closing flags */ 81 CK_STATE state; /* session state */ 82 83 /* Place holder for parameters passed in the C_OpenSession */ 84 CK_FLAGS flags; 85 CK_NOTIFY Notify; 86 CK_VOID_PTR pApplication; 87 88 /* Pointers to form the global session list */ 89 struct session *next; /* points to next session on the list */ 90 struct session *prev; /* points to prev session on the list */ 91 92 struct object *object_list; /* points to list of objects */ 93 94 crypto_active_op_t digest; /* context of active digest operation */ 95 crypto_active_op_t encrypt; /* context of active encrypt op */ 96 crypto_active_op_t decrypt; /* context of active decrypt op */ 97 crypto_active_op_t sign; /* context of active sign op */ 98 crypto_active_op_t verify; /* context of active verify op */ 99 /* context of active FindObjects op */ 100 crypto_active_op_t find_objects; 101 } soft_session_t; 102 103 /* 104 * slot_t is a global structure to be used only by the 105 * token objects to hold the token object related 106 * in-core information. 107 */ 108 typedef struct slot { 109 uint_t ks_version; /* in-core keystore version number */ 110 boolean_t authenticated; /* Has C_Login called */ 111 boolean_t userpin_change_needed; /* set if PIN expired */ 112 pthread_mutex_t slot_mutex; 113 pthread_mutex_t keystore_mutex; /* Protects keystore_load_status */ 114 uint_t keystore_load_status; /* Keystore load status */ 115 /* points to in-core token object list */ 116 struct object *token_object_list; 117 } slot_t; 118 119 /* 120 * The following structure is used to link the to-be-freed sessions 121 * into a linked list. The sessions on this linked list have 122 * not yet been freed via free() after C_CloseSession() call; instead 123 * they are added to this list. The actual free will take place when 124 * the number of sessions queued reaches MAX_SES_TO_BE_FREED, at which 125 * time the first session in the list will be freed. 126 */ 127 #define MAX_SES_TO_BE_FREED 300 128 129 typedef struct ses_to_be_freed_list { 130 struct session *first; /* points to the first session in the list */ 131 struct session *last; /* points to the last session in the list */ 132 uint32_t count; /* current total sessions in the list */ 133 pthread_mutex_t ses_to_be_free_mutex; 134 } ses_to_be_freed_list_t; 135 136 /* 137 * Flag definitions for ses_close_sync 138 */ 139 #define SESSION_IS_CLOSING 1 /* Session is in a closing state */ 140 #define SESSION_REFCNT_WAITING 2 /* Waiting for session reference */ 141 /* count to become zero */ 142 143 /* 144 * This macro is used to decrement the session reference count by one. 145 * 146 * The caller of this macro uses the argument lock_held to indicate that 147 * whether the caller holds the lock on the session or not. 148 * 149 * SES_REFRELE macro does the following: 150 * 1) Get the session lock if the caller does not hold it. 151 * 2) Decrement the session reference count by one. 152 * 3) If the session reference count becomes zero after being decremented, 153 * and there is a closing session thread in the wait state, then 154 * call pthread_cond_signal() to wake up that thread who is blocked 155 * in the session deletion routine due to non-zero reference ount. 156 * 4) Always release the session lock. 157 */ 158 #define SES_REFRELE(s, lock_held) { \ 159 if (!lock_held) \ 160 (void) pthread_mutex_lock(&s->session_mutex); \ 161 if ((--((s)->ses_refcnt) == 0) && \ 162 (s->ses_close_sync & SESSION_REFCNT_WAITING)) { \ 163 (void) pthread_mutex_unlock(&s->session_mutex); \ 164 (void) pthread_cond_signal(&s->ses_free_cond); \ 165 } else { \ 166 (void) pthread_mutex_unlock(&s->session_mutex); \ 167 } \ 168 } 169 170 171 extern pthread_mutex_t soft_sessionlist_mutex; 172 extern soft_session_t *soft_session_list; 173 extern int all_sessions_closing; 174 extern CK_ULONG soft_session_cnt; /* the number of opened sessions */ 175 extern CK_ULONG soft_session_rw_cnt; /* the number of opened R/W sessions */ 176 177 178 /* 179 * Function Prototypes. 180 */ 181 CK_RV handle2session(CK_SESSION_HANDLE hSession, soft_session_t **session_p); 182 183 CK_RV soft_delete_all_sessions(boolean_t force); 184 185 void soft_delete_all_objects_in_session(soft_session_t *sp); 186 187 CK_RV soft_add_session(CK_FLAGS flags, CK_VOID_PTR pApplication, 188 CK_NOTIFY notify, CK_ULONG *phSession); 189 190 CK_RV soft_delete_session(soft_session_t *sp, 191 boolean_t force, boolean_t lock_held); 192 193 CK_RV soft_get_operationstate(soft_session_t *, CK_BYTE_PTR, CK_ULONG_PTR); 194 CK_RV soft_set_operationstate(soft_session_t *, CK_BYTE_PTR, CK_ULONG, 195 CK_OBJECT_HANDLE, CK_OBJECT_HANDLE); 196 197 198 /* Token object related function prototypes. */ 199 200 CK_RV soft_login(CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen); 201 202 void soft_logout(void); 203 204 void soft_acquire_all_session_mutexes(); 205 void soft_release_all_session_mutexes(); 206 207 #ifdef __cplusplus 208 } 209 #endif 210 211 #endif /* _SOFTSESSION_H */ 212