blob: 6c0a5fc066bd01331735c392dfed2105a127b25b [file] [log] [blame]
Etienne Carriere9b7b70d2020-05-16 10:27:23 +02001// SPDX-License-Identifier: GPL-2.0
Etienne Carriere109c1d72019-01-09 11:02:02 +01002/*
3 * Copyright (c) 2018, Linaro Limited
Etienne Carriere109c1d72019-01-09 11:02:02 +01004 */
5
Etienne Carrierefa7e34f2020-02-04 15:34:16 +01006#include <ck_debug.h>
Etienne Carriere109c1d72019-01-09 11:02:02 +01007#include <inttypes.h>
Etienne Carriere109c1d72019-01-09 11:02:02 +01008#include <pkcs11.h>
Etienne Carrierefa7e34f2020-02-04 15:34:16 +01009#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
Etienne Carriere109c1d72019-01-09 11:02:02 +010012
13#include "xtest_test.h"
14#include "xtest_helpers.h"
15
Etienne Carriere3b5558a2020-03-12 09:55:26 +010016/*
17 * Util to find a slot on which to open a session
18 */
19static CK_RV close_lib(void)
20{
21 return C_Finalize(0);
22}
23
24static CK_RV init_lib_and_find_token_slot(CK_SLOT_ID *slot)
25{
26 CK_RV rv = CKR_GENERAL_ERROR;
27 CK_SLOT_ID_PTR slots = NULL;
28 CK_ULONG count = 0;
29
30 rv = C_Initialize(0);
31 if (rv)
32 return rv;
33
34 rv = C_GetSlotList(CK_TRUE, NULL, &count);
35 if (rv != CKR_OK)
36 goto bail;
37
38 if (count < 1) {
39 rv = CKR_GENERAL_ERROR;
40 goto bail;
41 }
42
43 slots = malloc(count * sizeof(CK_SLOT_ID));
44 if (!slots) {
45 rv = CKR_HOST_MEMORY;
46 goto bail;
47 }
48
49 rv = C_GetSlotList(CK_TRUE, slots, &count);
50 if (rv)
51 goto bail;
52
53 /* Use the last slot */
54 *slot = slots[count - 1];
55
56bail:
57 free(slots);
58 if (rv)
59 close_lib();
60
61 return rv;
62}
63
Etienne Carriere61f89d82020-03-11 11:24:29 +010064static void xtest_pkcs11_test_1000(ADBG_Case_t *c)
Etienne Carriere109c1d72019-01-09 11:02:02 +010065{
66 CK_RV rv;
67
68 rv = C_Initialize(NULL);
69 if (!ADBG_EXPECT_CK_OK(c, rv))
70 return;
71
72 rv = C_Finalize(NULL);
73 if (!ADBG_EXPECT_CK_OK(c, rv))
74 return;
75
76 rv = C_Initialize(NULL);
77 if (!ADBG_EXPECT_CK_OK(c, rv))
78 return;
79
80 rv = C_Initialize(NULL);
81 ADBG_EXPECT_CK_RESULT(c, CKR_CRYPTOKI_ALREADY_INITIALIZED, rv);
82
83 rv = C_Finalize(NULL);
84 ADBG_EXPECT_CK_OK(c, rv);
Etienne Carriere21f4e3c2020-02-05 15:40:24 +010085
86 rv = C_Finalize(NULL);
87 ADBG_EXPECT_CK_RESULT(c, CKR_CRYPTOKI_NOT_INITIALIZED, rv);
Etienne Carriere109c1d72019-01-09 11:02:02 +010088}
89
Etienne Carriere61f89d82020-03-11 11:24:29 +010090ADBG_CASE_DEFINE(pkcs11, 1000, xtest_pkcs11_test_1000,
91 "Initialize and close Cryptoki library");
Etienne Carrierefa7e34f2020-02-04 15:34:16 +010092
Etienne Carriere61f89d82020-03-11 11:24:29 +010093static void xtest_pkcs11_test_1001(ADBG_Case_t *c)
Etienne Carrierefa7e34f2020-02-04 15:34:16 +010094{
95 CK_RV rv = CKR_GENERAL_ERROR;
96 CK_SLOT_ID_PTR slot_ids = NULL;
97 CK_ULONG slot_count = 0;
98 CK_ULONG present_slot_count = 0;
99 CK_INFO lib_info = { };
100 CK_SLOT_INFO slot_info = { };
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100101 CK_TOKEN_INFO token_info = { };
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100102 CK_FUNCTION_LIST_PTR ckfunc_list = NULL;
103 size_t i = 0;
104 CK_SLOT_ID max_slot_id = 0;
Etienne Carriered3121292020-03-04 17:38:24 +0100105 CK_MECHANISM_TYPE_PTR mecha_types = NULL;
106 CK_ULONG mecha_count = 0;
107 CK_MECHANISM_INFO mecha_info = { };
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100108
109 rv = C_Initialize(NULL);
110 if (!ADBG_EXPECT_CK_OK(c, rv))
111 return;
112
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100113 Do_ADBG_BeginSubCase(c, "Test C_GetFunctionList()");
114
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100115 rv = C_GetFunctionList(&ckfunc_list);
116 if (!ADBG_EXPECT_CK_OK(c, rv))
117 goto out;
118
119 if (!ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetInfo) ||
120 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetSlotList) ||
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100121 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetSlotInfo) ||
Etienne Carriered3121292020-03-04 17:38:24 +0100122 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetTokenInfo) ||
123 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetMechanismList) ||
124 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetMechanismInfo))
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100125 goto out;
126
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100127 Do_ADBG_EndSubCase(c, "Test C_GetFunctionList()");
128 Do_ADBG_BeginSubCase(c, "Test C_GetInfo()");
129
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100130 rv = C_GetInfo(&lib_info);
131 if (!ADBG_EXPECT_CK_OK(c, rv))
132 goto out;
133
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100134 Do_ADBG_EndSubCase(c, "Test C_GetInfo()");
135 Do_ADBG_BeginSubCase(c, "Test C_GetSlotList()");
136
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100137 rv = C_GetSlotList(0, NULL, &slot_count);
138 if (!ADBG_EXPECT_CK_OK(c, rv))
139 goto out;
140
141 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, slot_count, !=, 0))
142 goto out;
143
Etienne Carrierede746332020-03-04 19:43:53 +0100144 if (slot_count > 1) {
145 /* Ensure case non-NULL-buffer and zero-count is tested */
146 CK_SLOT_ID id = 0;
147
148 slot_count = 0;
149 rv = C_GetSlotList(0, &id, &slot_count);
150 if (!ADBG_EXPECT_CK_RESULT(c, CKR_BUFFER_TOO_SMALL, rv))
151 goto out;
152 }
153
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100154 rv = C_GetSlotList(1, NULL, &present_slot_count);
155 if (!ADBG_EXPECT_CK_OK(c, rv))
156 goto out;
157
158 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, slot_count, ==,
159 present_slot_count))
160 goto out;
161
162 slot_ids = calloc(slot_count, sizeof(CK_SLOT_ID));
163 if (!ADBG_EXPECT_NOT_NULL(c, slot_ids))
164 goto out;
165
166 slot_count--;
167 rv = C_GetSlotList(1, slot_ids, &slot_count);
168 if (!ADBG_EXPECT_CK_RESULT(c, CKR_BUFFER_TOO_SMALL, rv))
169 goto out;
170
171 rv = C_GetSlotList(1, slot_ids, &slot_count);
172 if (!ADBG_EXPECT_CK_OK(c, rv))
173 goto out;
174
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100175 Do_ADBG_EndSubCase(c, "Test C_GetSlotList()");
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100176 Do_ADBG_BeginSubCase(c, "Test C_Get{Slot|Token}Info()");
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100177
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100178 for (i = 0; i < slot_count; i++) {
179 CK_SLOT_ID slot = slot_ids[i];
180
181 rv = C_GetSlotInfo(slot, &slot_info);
182 if (!ADBG_EXPECT_CK_OK(c, rv))
183 goto out;
184
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100185 rv = C_GetTokenInfo(slot, &token_info);
186 if (!ADBG_EXPECT_CK_OK(c, rv))
187 goto out;
188
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100189 if (max_slot_id < slot)
190 max_slot_id = slot;
191 }
192
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100193 Do_ADBG_EndSubCase(c, "Test C_Get{Slot|Token}Info()");
Etienne Carriered3121292020-03-04 17:38:24 +0100194 Do_ADBG_BeginSubCase(c, "Test C_GetMechanism{List|Info}()");
195
196 for (i = 0; i < slot_count; i++) {
197 CK_SLOT_ID slot = slot_ids[i];
198 size_t j = 0;
199
200 mecha_count = 0;
201 rv = C_GetMechanismList(slot, NULL, &mecha_count);
202 if (!ADBG_EXPECT_CK_OK(c, rv))
203 goto out;
204
205 if (mecha_count == 0)
206 continue;
207
208 free(mecha_types);
209 mecha_types = calloc(mecha_count, sizeof(*mecha_types));
210 if (!ADBG_EXPECT_NOT_NULL(c, mecha_types))
211 goto out;
212
213 /* Test specific case: valid buffer reference with 0 count */
214 mecha_count = 0;
215 rv = C_GetMechanismList(slot, mecha_types, &mecha_count);
216 if (!ADBG_EXPECT_CK_RESULT(c, CKR_BUFFER_TOO_SMALL, rv))
217 goto out;
218
219 rv = C_GetMechanismList(slot, mecha_types, &mecha_count);
220 if (!ADBG_EXPECT_CK_OK(c, rv))
221 goto out;
222
223 for (j = 0; j < mecha_count; j++) {
224 rv = C_GetMechanismInfo(slot, mecha_types[j],
225 &mecha_info);
226 if (!ADBG_EXPECT_CK_OK(c, rv))
227 goto out;
228 }
229 }
230
231 Do_ADBG_EndSubCase(c, "Test C_GetMechanism{List|Info}()");
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100232 Do_ADBG_BeginSubCase(c, "Test C_Get*Info() with invalid reference");
233
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100234 rv = C_GetSlotInfo(max_slot_id + 1, &slot_info);
235 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
236 goto out;
237
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100238 rv = C_GetTokenInfo(max_slot_id + 1, &token_info);
239 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
240 goto out;
241
Etienne Carriered3121292020-03-04 17:38:24 +0100242 mecha_count = 1;
243 if (!mecha_types)
244 mecha_types = malloc(sizeof(*mecha_types));
245 if (!ADBG_EXPECT_NOT_NULL(c, mecha_types))
246 goto out;
247
248 rv = C_GetMechanismList(max_slot_id + 1, mecha_types, &mecha_count);
249 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
250 goto out;
251
252 rv = C_GetMechanismInfo(max_slot_id + 1, CKM_AES_KEY_GEN, &mecha_info);
253 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
254 goto out;
255
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100256 rv = C_GetSlotInfo(ULONG_MAX, &slot_info);
257 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
258 goto out;
259
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100260 rv = C_GetTokenInfo(ULONG_MAX, &token_info);
261 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
262 goto out;
263
Etienne Carriered3121292020-03-04 17:38:24 +0100264 mecha_count = 1;
265 rv = C_GetMechanismList(ULONG_MAX, mecha_types, &mecha_count);
266 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
267 goto out;
268
269 rv = C_GetMechanismInfo(ULONG_MAX, CKM_AES_KEY_GEN, &mecha_info);
270 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
271 goto out;
272
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100273out:
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100274 Do_ADBG_EndSubCase(c, NULL);
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100275 free(slot_ids);
Etienne Carriered3121292020-03-04 17:38:24 +0100276 free(mecha_types);
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100277
278 rv = C_Finalize(NULL);
279 ADBG_EXPECT_CK_OK(c, rv);
280}
281
Etienne Carriere61f89d82020-03-11 11:24:29 +0100282ADBG_CASE_DEFINE(pkcs11, 1001, xtest_pkcs11_test_1001,
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100283 "PKCS11: List PKCS#11 slots and get information from");
Etienne Carriere3b5558a2020-03-12 09:55:26 +0100284
285static void xtest_pkcs11_test_1002(ADBG_Case_t *c)
286{
287 CK_RV rv = CKR_GENERAL_ERROR;
288 CK_SLOT_ID slot = 0;
289 CK_SESSION_HANDLE session[3] = { 0 };
290 CK_FLAGS session_flags = 0;
291 CK_SESSION_INFO session_info = { };
292 CK_FUNCTION_LIST_PTR ckfunc_list = NULL;
293
294 rv = init_lib_and_find_token_slot(&slot);
295 if (!ADBG_EXPECT_CK_OK(c, rv))
296 return;
297
298 rv = C_GetFunctionList(&ckfunc_list);
299 if (!ADBG_EXPECT_CK_OK(c, rv) ||
300 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_OpenSession) ||
301 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_CloseSession) ||
302 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_CloseAllSessions) ||
303 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetSessionInfo))
304 goto bail;
305
306 Do_ADBG_BeginSubCase(c, "Test C_OpenSession()/C_GetSessionInfo()");
307
308 session_flags = CKF_RW_SESSION;
309
310 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[0]);
311 if (!ADBG_EXPECT_CK_RESULT(c, CKR_ARGUMENTS_BAD, rv))
312 goto bail;
313
314 session_flags = CKF_SERIAL_SESSION;
315
316 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[0]);
317 if (!ADBG_EXPECT_CK_OK(c, rv))
318 goto bail;
319
320 rv = C_GetSessionInfo(session[0], &session_info);
321 if (!ADBG_EXPECT_CK_OK(c, rv) ||
322 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.slotID, ==, slot) ||
323 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.flags, ==,
324 session_flags) ||
325 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.state, ==,
326 CKS_RO_PUBLIC_SESSION) ||
327 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.ulDeviceError, ==, 0))
328 goto bail;
329
330 session_flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
331
332 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[1]);
333 if (!ADBG_EXPECT_CK_OK(c, rv))
334 goto bail;
335
336 rv = C_GetSessionInfo(session[1], &session_info);
337 if (!ADBG_EXPECT_CK_OK(c, rv) ||
338 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.slotID, ==, slot) ||
339 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.flags, ==,
340 session_flags) ||
341 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.state, ==,
342 CKS_RW_PUBLIC_SESSION) ||
343 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.ulDeviceError, ==, 0))
344 goto bail;
345
346 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[2]);
347 if (!ADBG_EXPECT_CK_OK(c, rv))
348 goto bail;
349
350 rv = C_GetSessionInfo(session[2], &session_info);
351 if (!ADBG_EXPECT_CK_OK(c, rv) ||
352 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.slotID, ==, slot) ||
353 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.flags, ==,
354 session_flags) ||
355 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.state, ==,
356 CKS_RW_PUBLIC_SESSION) ||
357 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.ulDeviceError, ==, 0))
358 goto bail;
359
360 Do_ADBG_EndSubCase(c, "Test C_OpenSession()/C_GetSessionInfo()");
361 Do_ADBG_BeginSubCase(c, "Test C_CloseSession()");
362
363 /* Close 2 of them */
364 rv = C_CloseSession(session[0]);
365 if (!ADBG_EXPECT_CK_OK(c, rv))
366 goto bail;
367
368 rv = C_GetSessionInfo(session[0], &session_info);
369 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
370 goto bail;
371
372 rv = C_GetSessionInfo(session[1], &session_info);
373 if (!ADBG_EXPECT_CK_OK(c, rv))
374 goto bail;
375
376 rv = C_GetSessionInfo(session[2], &session_info);
377 if (!ADBG_EXPECT_CK_OK(c, rv))
378 goto bail;
379
380 /* Close all remaining sessions, later calls should failed on session */
381 rv = C_CloseAllSessions(slot);
382 if (!ADBG_EXPECT_CK_OK(c, rv))
383 goto bail;
384
385 rv = C_CloseSession(session[1]);
386 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
387 goto bail;
388
389 rv = C_CloseSession(session[2]);
390 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
391 goto bail;
392
393 rv = C_GetSessionInfo(session[1], &session_info);
394 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
395 goto bail;
396
397 rv = C_GetSessionInfo(session[2], &session_info);
398 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
399 goto bail;
400
401 /* Open a session, should be closed from library closure */
402 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[0]);
403 if (!ADBG_EXPECT_CK_OK(c, rv))
404 goto bail;
405
406bail:
407 Do_ADBG_EndSubCase(c, NULL);
408 rv = close_lib();
409 ADBG_EXPECT_CK_OK(c, rv);
410}
411
412ADBG_CASE_DEFINE(pkcs11, 1002, xtest_pkcs11_test_1002,
413 "PKCS11: Open and close PKCS#11 sessions");
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200414
415/*
416 * Helpers for tests where we must log into the token.
417 * These define the genuine PINs and label to be used with the test token.
418 */
419static CK_UTF8CHAR test_token_so_pin[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 , 9, 10, };
Jens Wiklander282a8a52020-04-14 17:01:36 +0200420static CK_UTF8CHAR test_token_user_pin[] = {
421 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
422};
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200423static CK_UTF8CHAR test_token_label[] = "PKCS11 TA test token";
424
425static CK_RV init_test_token(CK_SLOT_ID slot)
426{
427 return C_InitToken(slot, test_token_so_pin, sizeof(test_token_so_pin),
428 test_token_label);
429}
430
Jens Wiklander282a8a52020-04-14 17:01:36 +0200431/* Login as user, eventually reset user PIN if needed */
432static CK_RV init_user_test_token(CK_SLOT_ID slot)
433{
434 CK_FLAGS session_flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
435 CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
436 CK_RV rv = CKR_GENERAL_ERROR;
437
438 rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
439 if (rv)
440 return rv;
441
442 rv = C_Login(session, CKU_USER, test_token_user_pin,
443 sizeof(test_token_user_pin));
444 if (rv == CKR_OK) {
445 C_Logout(session);
446 C_CloseSession(session);
447 return rv;
448 }
449
450 rv = C_Login(session, CKU_SO, test_token_so_pin,
451 sizeof(test_token_so_pin));
452 if (rv) {
453 C_CloseSession(session);
454
455 rv = init_test_token(slot);
456 if (rv)
457 return rv;
458
459 rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
460 if (rv)
461 return rv;
462
463 rv = C_Login(session, CKU_SO, test_token_so_pin,
464 sizeof(test_token_so_pin));
465 if (rv) {
466 C_CloseSession(session);
467 return rv;
468 }
469 }
470
471 rv = C_InitPIN(session, test_token_user_pin,
472 sizeof(test_token_user_pin));
473
474 C_Logout(session);
475 C_CloseSession(session);
476
477 return rv;
478}
479
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200480static CK_RV test_already_initialized_token(ADBG_Case_t *c, CK_SLOT_ID slot)
481{
482 CK_RV rv = CKR_GENERAL_ERROR;
483 CK_TOKEN_INFO token_info = { };
484 /* Same content as test_token_so_pin[] but 1 more byte */
485 CK_UTF8CHAR pin1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, };
486 /* Same content as test_token_so_pin[] but 1 different byte */
487 CK_UTF8CHAR pin2[] = { 0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 10, };
488 CK_FLAGS flags = 0;
489
490 Do_ADBG_BeginSubCase(c, "C_InitToken() on initialized token");
491
492 rv = C_GetTokenInfo(slot, &token_info);
493 if (!ADBG_EXPECT_CK_OK(c, rv))
494 goto out;
495
496 rv = C_InitToken(slot, test_token_so_pin,
497 sizeof(test_token_so_pin) - 1, test_token_label);
498 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, rv, !=, CKR_OK))
499 goto out;
500
501 rv = C_InitToken(slot, pin1, sizeof(pin1), test_token_label);
502 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, rv, !=, CKR_OK))
503 goto out;
504
505 rv = C_InitToken(slot, pin2, sizeof(pin2), test_token_label);
506 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, rv, !=, CKR_OK))
507 goto out;
508
509 rv = C_GetTokenInfo(slot, &token_info);
510 if (!ADBG_EXPECT_CK_OK(c, rv))
511 goto out;
512
513 flags = token_info.flags;
514
515 /* Token should have set CKF_SO_PIN_COUNT_LOW to 1 */
516 if (!ADBG_EXPECT_TRUE(c, !!(flags & CKF_SO_PIN_COUNT_LOW))) {
517 rv = CKR_GENERAL_ERROR;
518 goto out;
519 }
520
521 rv = init_test_token(slot);
522 if (!ADBG_EXPECT_CK_OK(c, rv))
523 goto out;
524
525 rv = C_GetTokenInfo(slot, &token_info);
526 if (!ADBG_EXPECT_CK_OK(c, rv))
527 goto out;
528
529 flags = token_info.flags;
530
531 /*
532 * Token should have reset CKF_SO_PIN_COUNT_LOW to 0.
533 * Other flags should show a sane initialized state.
534 */
535 if (!ADBG_EXPECT_TRUE(c, !(flags & CKF_SO_PIN_COUNT_LOW)) ||
536 !ADBG_EXPECT_TRUE(c, !!(flags & CKF_TOKEN_INITIALIZED)) ||
537 !ADBG_EXPECT_TRUE(c, !(flags & CKF_ERROR_STATE)) ||
538 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_INITIALIZED))) {
539 rv = CKR_GENERAL_ERROR;
Jens Wiklander282a8a52020-04-14 17:01:36 +0200540 goto out;
541 }
542
543 rv = init_user_test_token(slot);
544 if (!ADBG_EXPECT_CK_OK(c, rv))
545 goto out;
546
547 rv = C_GetTokenInfo(slot, &token_info);
548 if (!ADBG_EXPECT_CK_OK(c, rv))
549 goto out;
550
551 flags = token_info.flags;
552
553 if (!ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_COUNT_LOW)) ||
554 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_FINAL_TRY)) ||
555 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_LOCKED)) ||
556 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_TO_BE_CHANGED)) ||
557 !ADBG_EXPECT_TRUE(c, !!(flags & CKF_USER_PIN_INITIALIZED)) ||
558 !ADBG_EXPECT_TRUE(c, !(flags & CKF_ERROR_STATE))) {
559 rv = CKR_GENERAL_ERROR;
560 goto out;
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200561 }
562
563out:
564 Do_ADBG_EndSubCase(c, "C_InitToken() on initialized token");
565
566 return rv;
567}
568
569static CK_RV test_uninitialized_token(ADBG_Case_t *c, CK_SLOT_ID slot)
570{
571 CK_RV rv = CKR_GENERAL_ERROR;
572 CK_TOKEN_INFO token_info = { };
573 CK_FLAGS flags = 0;
574
575 Do_ADBG_BeginSubCase(c, "C_InitToken() on uninitialized token");
576
577 rv = init_test_token(slot);
578 if (!ADBG_EXPECT_CK_OK(c, rv))
579 goto out;
580
581 rv = C_GetTokenInfo(slot, &token_info);
582 if (!ADBG_EXPECT_CK_OK(c, rv))
583 goto out;
584
585 flags = token_info.flags;
586
587 if (!ADBG_EXPECT_TRUE(c, !!(flags & CKF_TOKEN_INITIALIZED)) ||
588 !ADBG_EXPECT_TRUE(c, !(flags & CKF_ERROR_STATE)) ||
589 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_INITIALIZED))) {
590 rv = CKR_GENERAL_ERROR;
Jens Wiklander282a8a52020-04-14 17:01:36 +0200591 goto out;
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200592 }
593
Jens Wiklander282a8a52020-04-14 17:01:36 +0200594 rv = init_user_test_token(slot);
595 if (!ADBG_EXPECT_CK_OK(c, rv))
596 goto out;
597
598 rv = C_GetTokenInfo(slot, &token_info);
599 if (!ADBG_EXPECT_CK_OK(c, rv))
600 goto out;
601
602 flags = token_info.flags;
603
604 if (!ADBG_EXPECT_TRUE(c, !!(flags & CKF_TOKEN_INITIALIZED)) ||
605 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_COUNT_LOW)) ||
606 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_FINAL_TRY)) ||
607 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_LOCKED)) ||
608 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_TO_BE_CHANGED)) ||
609 !ADBG_EXPECT_TRUE(c, !!(flags & CKF_USER_PIN_INITIALIZED)) ||
610 !ADBG_EXPECT_TRUE(c, !(flags & CKF_ERROR_STATE)))
611 rv = CKR_GENERAL_ERROR;
612
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200613out:
614 Do_ADBG_EndSubCase(c, "C_InitToken() on uninitialized token");
615
616 return rv;
617}
618
Jens Wiklanderaa741512020-04-14 17:01:46 +0200619static CK_RV test_login_logout(ADBG_Case_t *c, CK_SLOT_ID slot)
620{
621 CK_FLAGS session_flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
622 CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
623 CK_RV rv = CKR_GENERAL_ERROR;
624
625 Do_ADBG_BeginSubCase(c, "Test C_Login()/C_Logout()");
626
627 rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
628 if (!ADBG_EXPECT_CK_OK(c, rv))
629 goto out;
630
631 /* Logout: should fail as we did not log in yet */
632 rv = C_Logout(session);
633 ADBG_EXPECT_CK_RESULT(c, CKR_USER_NOT_LOGGED_IN, rv);
634
635 /* Login/re-log/logout user */
636 rv = C_Login(session, CKU_USER, test_token_user_pin,
637 sizeof(test_token_user_pin));
638 if (!ADBG_EXPECT_CK_OK(c, rv))
639 goto out;
640
641 rv = C_Login(session, CKU_USER, test_token_user_pin,
642 sizeof(test_token_user_pin));
643 ADBG_EXPECT_CK_RESULT(c, CKR_USER_ALREADY_LOGGED_IN, rv);
644
645 rv = C_Logout(session);
646 if (!ADBG_EXPECT_CK_OK(c, rv))
647 goto out;
648
649 /* Login/re-log/logout security officer */
650 rv = C_Login(session, CKU_SO, test_token_so_pin,
651 sizeof(test_token_so_pin));
652 if (!ADBG_EXPECT_CK_OK(c, rv))
653 goto out;
654
655 rv = C_Login(session, CKU_SO, test_token_so_pin,
656 sizeof(test_token_so_pin));
657 ADBG_EXPECT_CK_RESULT(c, CKR_USER_ALREADY_LOGGED_IN, rv);
658
659 rv = C_Logout(session);
660 if (!ADBG_EXPECT_CK_OK(c, rv))
661 goto out;
662
663 /* Login user then SO and reverse */
664 rv = C_Login(session, CKU_SO, test_token_so_pin,
665 sizeof(test_token_so_pin));
666 ADBG_EXPECT_CK_OK(c, rv);
667
668 rv = C_Login(session, CKU_USER, test_token_user_pin,
669 sizeof(test_token_user_pin));
670 ADBG_EXPECT_CK_RESULT(c, CKR_USER_ANOTHER_ALREADY_LOGGED_IN, rv);
671
672 rv = C_Logout(session);
673 if (!ADBG_EXPECT_CK_OK(c, rv))
674 goto out;
675
676 rv = C_Login(session, CKU_USER, test_token_user_pin,
677 sizeof(test_token_user_pin));
678 ADBG_EXPECT_CK_OK(c, rv);
679
680 rv = C_Login(session, CKU_SO, test_token_so_pin,
681 sizeof(test_token_so_pin));
682 ADBG_EXPECT_CK_RESULT(c, CKR_USER_ANOTHER_ALREADY_LOGGED_IN, rv);
683
684 rv = C_Logout(session);
685 ADBG_EXPECT_CK_OK(c, rv);
686
687 /* Login context specifc, in an invalid case (need an operation) */
688 rv = C_Login(session, CKU_CONTEXT_SPECIFIC, test_token_user_pin,
689 sizeof(test_token_user_pin));
690 ADBG_EXPECT_CK_RESULT(c, CKR_OPERATION_NOT_INITIALIZED, rv);
691
692 rv = C_CloseSession(session);
693 ADBG_EXPECT_CK_OK(c, rv);
694
695out:
696 Do_ADBG_EndSubCase(c, "Test C_Login()/C_Logout()");
697 return rv;
698}
699
Jens Wiklander6ce1e692020-04-14 17:02:09 +0200700static CK_RV test_set_pin(ADBG_Case_t *c, CK_SLOT_ID slot,
701 CK_USER_TYPE user_type)
702{
703 CK_FLAGS session_flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
704 CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
705 CK_UTF8CHAR some_pin[] = { 7, 6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6, 7 };
706 CK_UTF8CHAR_PTR old_pin = NULL;
707 CK_USER_TYPE ut = user_type;
708 size_t old_pin_sz = 0;
709 CK_RV rv2 = CKR_OK;
710 CK_RV rv = CKR_OK;
711
712 Do_ADBG_BeginSubCase(c, "Test C_SetPIN() user_type %lu", user_type);
713
714 rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
715 if (!ADBG_EXPECT_CK_OK(c, rv))
716 goto out;
717
718 if (user_type == CKU_SO) {
719 old_pin = (CK_UTF8CHAR_PTR)test_token_so_pin;
720 old_pin_sz = sizeof(test_token_so_pin);
721 } else {
722 old_pin = (CK_UTF8CHAR_PTR)test_token_user_pin;
723 old_pin_sz = sizeof(test_token_user_pin);
724 ut = CKU_USER;
725 }
726
727 if (ut == user_type) {
728 rv = C_Login(session, ut, old_pin, old_pin_sz);
729 if (!ADBG_EXPECT_CK_OK(c, rv))
730 goto out_session;
731 }
732
733 rv = C_SetPIN(session, old_pin, old_pin_sz, some_pin, sizeof(some_pin));
734 if (!ADBG_EXPECT_CK_OK(c, rv)) {
735 if (ut == user_type)
736 goto out_logout;
737 else
738 goto out_session;
739 }
740
741 if (ut == user_type) {
742 rv = C_Logout(session);
743 if (!ADBG_EXPECT_CK_OK(c, rv))
744 goto out_session;
745 }
746
747 rv = C_Login(session, ut, some_pin, sizeof(some_pin));
748 if (!ADBG_EXPECT_CK_OK(c, rv))
749 goto out_session;
750
751 rv = C_SetPIN(session, some_pin, sizeof(some_pin), old_pin, old_pin_sz);
752 ADBG_EXPECT_CK_OK(c, rv);
753
754out_logout:
755 rv2 = C_Logout(session);
756 if (!ADBG_EXPECT_CK_OK(c, rv2) && !rv)
757 rv = rv2;
758out_session:
759 rv2 = C_CloseSession(session);
760 if (!ADBG_EXPECT_CK_OK(c, rv2) && !rv)
761 rv = rv2;
762out:
763 Do_ADBG_EndSubCase(c, "Test C_SetPIN() user_type %lu", user_type);
764
765 return rv;
766}
767
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200768static void xtest_pkcs11_test_1003(ADBG_Case_t *c)
769{
770 CK_RV rv = CKR_GENERAL_ERROR;
771 CK_FUNCTION_LIST_PTR ckfunc_list = NULL;
772 CK_SLOT_ID slot = 0;
773 CK_TOKEN_INFO token_info = { };
774
775 rv = C_GetFunctionList(&ckfunc_list);
776 if (!ADBG_EXPECT_CK_OK(c, rv) ||
Jens Wiklander282a8a52020-04-14 17:01:36 +0200777 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_InitToken) ||
778 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_InitPIN) ||
Jens Wiklanderaa741512020-04-14 17:01:46 +0200779 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_SetPIN) ||
780 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_Login) ||
781 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_Logout))
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200782 goto out;
783
784 rv = init_lib_and_find_token_slot(&slot);
785 if (!ADBG_EXPECT_CK_OK(c, rv))
786 return;
787
788 rv = C_GetTokenInfo(slot, &token_info);
789 if (!ADBG_EXPECT_CK_OK(c, rv))
790 goto out;
791
792 /* Abort test if token is about to lock */
793 if (!ADBG_EXPECT_TRUE(c, !(token_info.flags & CKF_SO_PIN_FINAL_TRY)))
794 goto out;
795
796 if (!(token_info.flags & CKF_TOKEN_INITIALIZED)) {
797 rv = test_uninitialized_token(c, slot);
798 if (rv != CKR_OK)
799 goto out;
800 }
801
802 rv = test_already_initialized_token(c, slot);
803 if (rv != CKR_OK)
804 goto out;
805
Jens Wiklanderaa741512020-04-14 17:01:46 +0200806 rv = test_login_logout(c, slot);
807 if (rv != CKR_OK)
808 goto out;
809
Jens Wiklander6ce1e692020-04-14 17:02:09 +0200810 rv = test_set_pin(c, slot, CKU_USER);
811 if (rv != CKR_OK)
812 goto out;
Jens Wiklanderaa741512020-04-14 17:01:46 +0200813
Jens Wiklander6ce1e692020-04-14 17:02:09 +0200814 rv = test_set_pin(c, slot, CKU_SO);
815 if (rv != CKR_OK)
816 goto out;
Jens Wiklanderaa741512020-04-14 17:01:46 +0200817
Jens Wiklander6ce1e692020-04-14 17:02:09 +0200818 /*
819 * CKU_CONTEXT_SPECIFIC is anything not CKU_USER or CKU_SO in order
820 * to skip the initial login.
821 */
822 test_set_pin(c, slot, CKU_CONTEXT_SPECIFIC);
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200823out:
824 rv = close_lib();
825 ADBG_EXPECT_CK_OK(c, rv);
826}
827
828ADBG_CASE_DEFINE(pkcs11, 1003, xtest_pkcs11_test_1003,
829 "PKCS11: Login to PKCS#11 token");