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