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