summaryrefslogtreecommitdiff
path: root/usr/src/lib/pkcs11/libpkcs11/common/pkcs11Sessionlist.c
blob: 55ba162e2f842a68215fd8eff9ddc702e56037d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <pthread.h>
#include <stdlib.h>
#include <security/cryptoki.h>
#include "pkcs11Global.h"
#include "pkcs11Slot.h"
#include "pkcs11Session.h"


/*
 * pkcs11_session_add:
 * Create a session and add it to the list of sessions associated
 * with the slot it is being opened on.  The session handle, fwsessionp,
 * will be the memory address of the session, typecast to a CK_SESSION_HANDLE.
 *
 * Assumptions: slotp is a valid slot, mutexes are not held, and
 * the provider already successfully opened related session.
 */
CK_RV
pkcs11_session_add(pkcs11_slot_t *slotp, CK_SLOT_ID slot_id,
    CK_SESSION_HANDLE_PTR fwsessionp, CK_SESSION_HANDLE prov_sess)
{

	pkcs11_session_t *newhandle = malloc(sizeof (pkcs11_session_t));

	if (newhandle == NULL) {
		return (CKR_HOST_MEMORY);
	}

	newhandle->se_magic = PKCS11_SESSION_MAGIC;
	newhandle->se_handle = prov_sess;
	newhandle->se_slotid = slot_id;

	(void) pthread_mutex_lock(&slotp->sl_mutex);

	/* Insert the new session in the front of the slot's session list */
	if (slotp->sl_sess_list == NULL) {
		slotp->sl_sess_list = newhandle;
		newhandle->se_prev = NULL;
		newhandle->se_next = NULL;
	} else {
		slotp->sl_sess_list->se_prev = newhandle;
		newhandle->se_next = slotp->sl_sess_list;
		newhandle->se_prev = NULL;
		slotp->sl_sess_list = newhandle;
	}

	/* Typecast the address of session structure to a session handle */
	*fwsessionp = (CK_SESSION_HANDLE)newhandle;

	(void) pthread_mutex_unlock(&slotp->sl_mutex);

	return (CKR_OK);
}

/*
 * pkcs11_session_delete:
 * Delete a session from a particular slot's session list.
 *
 * Assumptions: slotp is a valid slot, sessp is a valid session,
 * provider has already successfully closed this session, and
 * mutexes are not held.
 */
void
pkcs11_session_delete(pkcs11_slot_t *slotp, pkcs11_session_t *sessp)
{

	/* Acquire the slot's lock */
	(void) pthread_mutex_lock(&slotp->sl_mutex);

	if (slotp->sl_sess_list == sessp) {
		/* This is the first session in the list */
		if (sessp->se_next != NULL) {
			slotp->sl_sess_list = sessp->se_next;
			sessp->se_next->se_prev = NULL;
		} else {
			/* Session is the only one in the list */
			slotp->sl_sess_list = NULL;
		}
	} else {
		/* Session is not the first one in the list */
		if (sessp->se_next != NULL) {
			/* Session is in the middle of the list */
			sessp->se_prev->se_next = sessp->se_next;
			sessp->se_next->se_prev = sessp->se_prev;
		} else {
			/* Session is the last one in the list */
			sessp->se_prev->se_next = NULL;
		}
	}

	/* Mark session as no longer valid */
	sessp->se_magic = 0;

	free(sessp);

	(void) pthread_mutex_unlock(&slotp->sl_mutex);

}

/*
 * pkcs11_sessionlist_delete:
 * Delete all sessions associated with a particular slot's session list.
 *
 * Assumptions: slotp is a valid slot, no mutexes are held, and the
 * sessions were successfully closed with the provider already.
 */
void
pkcs11_sessionlist_delete(pkcs11_slot_t *slotp)
{

	pkcs11_session_t *sessp, *sess_nextp;

	sessp = slotp->sl_sess_list;

	/* Delete all the sessions in this slot's session list */
	while (sessp) {
		sess_nextp = sessp->se_next;

		pkcs11_session_delete(slotp, sessp);

		sessp = sess_nextp;
	}

	slotp->sl_sess_list = NULL;

}