summaryrefslogtreecommitdiff
path: root/src/session.c
blob: a11fb5020b8819e6afa081996db29a9ae0d9ddad (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

#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 */

	/** - 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 */

	/** - 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 */

	/** - 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);

		/** - 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 */

	/** - 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);

	/** - 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;
}