summaryrefslogtreecommitdiff
path: root/src/session.c
blob: ae20c0cf8efeca6907c8ae9e6249697e6197b0a4 (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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

#include "config.h"

#include "p11-tests.h"

#include <string.h>

static const char *login_pin = NULL;

void
session_info(CK_SESSION_HANDLE session, CK_SLOT_ID slot, CK_FLAGS flags, CK_STATE state)
{
	CK_SESSION_INFO info;
	CK_RV rv;

	if(session == CK_INVALID)
		return;

	/** C_GetSessionInfo */

	if(p11t_test_unexpected)
	{
		/** - Invalid session */
		rv = (p11t_module_funcs->C_GetSessionInfo)((CK_SESSION_HANDLE)-33, &info);
		p11t_check_returns("C_GetSessionInfo: with invalid session", rv, CKR_SESSION_HANDLE_INVALID);

		/** - NULL arguments */
		rv = (p11t_module_funcs->C_GetSessionInfo)(session, NULL);
		p11t_check_returns("C_GetSessionInfo: with null", rv, CKR_ARGUMENTS_BAD);
	}

	/** - Valid call */
	rv = (p11t_module_funcs->C_GetSessionInfo)(session, &info);
	if(!p11t_check_returns("C_GetSessionInfo", rv, CKR_OK))
		return;

	/** - Valid slot id */
	p11t_check_ulong("CK_SESSION_INFO.slotID", info.slotID, slot);

	/** - Valid state for session */
	p11t_check_ulong("CK_SESSION_INFO.state", info.state, state);

	/** - Valid flags for session */
	p11t_check_flag("CK_SESSION_INFO.flags", info.flags, flags);
}

void
session_main(CK_SLOT_ID slot)
{
	CK_SESSION_HANDLE session_ro = CK_INVALID;
	CK_SESSION_HANDLE session_rw = CK_INVALID;
	CK_SESSION_HANDLE session_ro2 = CK_INVALID;
	CK_SESSION_INFO info;
	CK_RV rv;

	assert(p11t_module_funcs);

	/** C_OpenSession */

	if(p11t_test_unexpected)
	{
		/** - Invalid slot */
		rv = (p11t_module_funcs->C_OpenSession)((CK_SLOT_ID)-5, CKF_SERIAL_SESSION, NULL, NULL, &session_ro);
		p11t_check_returns("C_OpenSession: with invalid slot", rv, CKR_SLOT_ID_INVALID);

		/** - Null arguments */
		rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION, NULL, NULL, NULL);
		p11t_check_returns("C_OpenSession: with invalid slot", rv, CKR_ARGUMENTS_BAD);

		/** - No flags */
		rv = (p11t_module_funcs->C_OpenSession)(slot, 0, NULL, NULL, &session_ro);
		p11t_check_returns("C_OpenSession: with 0 flags", rv, CKR_SESSION_PARALLEL_NOT_SUPPORTED);

		/** - Without serial flag */
		rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_RW_SESSION, NULL, NULL, &session_ro);
		p11t_check_returns("C_OpenSession: with RW flags", rv, CKR_SESSION_PARALLEL_NOT_SUPPORTED);
	}

	/** - Valid flags */
	rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION, NULL, NULL, &session_ro);
	p11t_check_returns("C_OpenSession: with serial flags", rv, CKR_OK);
	rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION, NULL, NULL, &session_ro2);
	p11t_check_returns("C_OpenSession: with serial flags", rv, CKR_OK);

	/** - Read write session */
	rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session_rw);
	if(rv == CKR_TOKEN_WRITE_PROTECTED)
		session_rw = CK_INVALID;
	else
		p11t_check_returns("C_OpenSession: with read write flags", rv, CKR_OK);

	/* Test all the sessions and validate their state */
	session_info(session_ro, slot, CKF_SERIAL_SESSION, CKS_RO_PUBLIC_SESSION);
	session_info(session_ro2, slot, CKF_SERIAL_SESSION, CKS_RO_PUBLIC_SESSION);
	if(session_rw)
		session_info(session_rw, slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, CKS_RW_PUBLIC_SESSION);

	/** C_CloseSession */

	if(p11t_test_unexpected)
	{
		/** - Invalid session */
		rv = (p11t_module_funcs->C_CloseSession)((CK_SESSION_HANDLE)-10);
		p11t_check_returns("C_CloseSession: invalid handle", rv, CKR_SESSION_HANDLE_INVALID);
	}

	if(session_ro != CK_INVALID)
	{
		/** - Normal call */
		rv = (p11t_module_funcs->C_CloseSession)(session_ro);
		p11t_check_returns("C_CloseSession: valid", rv, CKR_OK);

		if(p11t_test_unexpected)
		{
			/** - Check open session was closed */
			rv = (p11t_module_funcs->C_GetSessionInfo)(session_ro, &info);
			p11t_check_returns("C_GetSessionInfo: after close", rv, CKR_SESSION_HANDLE_INVALID);

			/** - Close twice */

			/*
			 * Note that CKR_SESSION_CLOSED is a valid return in this case.
			 * That should only be returned in the rare case when a session
			 * was closed during the execution of a function. A corner case.
			 */

			rv = (p11t_module_funcs->C_CloseSession)(session_ro);
			p11t_check_returns("C_CloseSession: valid", rv, CKR_SESSION_HANDLE_INVALID);
		}
	}

	if(session_rw != CK_INVALID)
	{
		rv = (p11t_module_funcs->C_CloseSession)(session_rw);
		p11t_check_returns("C_CloseSession: read write", rv, CKR_OK);
	}

	/** C_CloseAllSessions */

	if(p11t_test_unexpected)
	{
		/** - Invalid slot id */
		rv = (p11t_module_funcs->C_CloseAllSessions)((CK_SLOT_ID)-34);
		p11t_check_returns("C_CloseAllSessions: invalid slot", rv, CKR_SLOT_ID_INVALID);
	}

	/** - Normal call */
	rv = (p11t_module_funcs->C_CloseAllSessions)(slot);
	p11t_check_returns("C_CloseAllSessions", rv, CKR_OK);

	if(p11t_test_unexpected)
	{
		/** - Check open session was closed */
		rv = (p11t_module_funcs->C_GetSessionInfo)(session_ro2, &info);
		p11t_check_returns("C_GetSessionInfo: after close all", rv, CKR_SESSION_HANDLE_INVALID);

		/** - Call when no sessions open */
		rv = (p11t_module_funcs->C_CloseAllSessions)(slot);
		p11t_check_returns("C_CloseAllSessions", rv, CKR_OK);
	}
}

void
session_pin(CK_SLOT_ID slot)
{
	/** C_InitPIN */

	/** - Not Implemented */

	/** C_SetPIN */

	/** - Not Implemented */
}

void
p11t_session_tests()
{
	CK_ULONG i;

	for(i = 0; i < p11t_slot_count; ++i)
	{
		CK_SLOT_ID slot = p11t_slot_ids[i];
		session_pin(slot);
		session_main(slot);
	}
}

void
p11t_session_config(const char *name, const char *value)
{
	if(strcmp(name, "login-pin") == 0)
		login_pin = value;
}