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 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <pthread.h> 28 #include <stdlib.h> 29 #include <security/cryptoki.h> 30 #include "pkcs11Global.h" 31 #include "pkcs11Slot.h" 32 #include "pkcs11Session.h" 33 34 35 /* 36 * pkcs11_session_add: 37 * Create a session and add it to the list of sessions associated 38 * with the slot it is being opened on. The session handle, fwsessionp, 39 * will be the memory address of the session, typecast to a CK_SESSION_HANDLE. 40 * 41 * Assumptions: slotp is a valid slot, mutexes are not held, and 42 * the provider already successfully opened related session. 43 */ 44 CK_RV 45 pkcs11_session_add(pkcs11_slot_t *slotp, CK_SLOT_ID slot_id, 46 CK_SESSION_HANDLE_PTR fwsessionp, CK_SESSION_HANDLE prov_sess) 47 { 48 49 pkcs11_session_t *newhandle = malloc(sizeof (pkcs11_session_t)); 50 51 if (newhandle == NULL) { 52 return (CKR_HOST_MEMORY); 53 } 54 55 newhandle->se_magic = PKCS11_SESSION_MAGIC; 56 newhandle->se_handle = prov_sess; 57 newhandle->se_slotid = slot_id; 58 59 (void) pthread_mutex_lock(&slotp->sl_mutex); 60 61 /* Insert the new session in the front of the slot's session list */ 62 if (slotp->sl_sess_list == NULL) { 63 slotp->sl_sess_list = newhandle; 64 newhandle->se_prev = NULL; 65 newhandle->se_next = NULL; 66 } else { 67 slotp->sl_sess_list->se_prev = newhandle; 68 newhandle->se_next = slotp->sl_sess_list; 69 newhandle->se_prev = NULL; 70 slotp->sl_sess_list = newhandle; 71 } 72 73 /* Typecast the address of session structure to a session handle */ 74 *fwsessionp = (CK_SESSION_HANDLE)newhandle; 75 76 (void) pthread_mutex_unlock(&slotp->sl_mutex); 77 78 return (CKR_OK); 79 } 80 81 /* 82 * pkcs11_session_delete: 83 * Delete a session from a particular slot's session list. 84 * 85 * Assumptions: slotp is a valid slot, sessp is a valid session, 86 * provider has already successfully closed this session, and 87 * mutexes are not held. 88 */ 89 void 90 pkcs11_session_delete(pkcs11_slot_t *slotp, pkcs11_session_t *sessp) 91 { 92 93 /* Acquire the slot's lock */ 94 (void) pthread_mutex_lock(&slotp->sl_mutex); 95 96 if (slotp->sl_sess_list == sessp) { 97 /* This is the first session in the list */ 98 if (sessp->se_next != NULL) { 99 slotp->sl_sess_list = sessp->se_next; 100 sessp->se_next->se_prev = NULL; 101 } else { 102 /* Session is the only one in the list */ 103 slotp->sl_sess_list = NULL; 104 } 105 } else { 106 /* Session is not the first one in the list */ 107 if (sessp->se_next != NULL) { 108 /* Session is in the middle of the list */ 109 sessp->se_prev->se_next = sessp->se_next; 110 sessp->se_next->se_prev = sessp->se_prev; 111 } else { 112 /* Session is the last one in the list */ 113 sessp->se_prev->se_next = NULL; 114 } 115 } 116 117 /* Mark session as no longer valid */ 118 sessp->se_magic = 0; 119 120 free(sessp); 121 122 (void) pthread_mutex_unlock(&slotp->sl_mutex); 123 124 } 125 126 /* 127 * pkcs11_sessionlist_delete: 128 * Delete all sessions associated with a particular slot's session list. 129 * 130 * Assumptions: slotp is a valid slot, no mutexes are held, and the 131 * sessions were successfully closed with the provider already. 132 */ 133 void 134 pkcs11_sessionlist_delete(pkcs11_slot_t *slotp) 135 { 136 137 pkcs11_session_t *sessp, *sess_nextp; 138 139 sessp = slotp->sl_sess_list; 140 141 /* Delete all the sessions in this slot's session list */ 142 while (sessp) { 143 sess_nextp = sessp->se_next; 144 145 pkcs11_session_delete(slotp, sessp); 146 147 sessp = sess_nextp; 148 } 149 150 slotp->sl_sess_list = NULL; 151 152 } 153