blob: e3725b0fcc4d0594ee5ebbd2a9c9c6c4f0bc996a [file] [log] [blame]
Etienne Carriere109c1d72019-01-09 11:02:02 +01001/*
2 * Copyright (c) 2018, Linaro Limited
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Etienne Carrierefa7e34f2020-02-04 15:34:16 +010014#include <ck_debug.h>
Etienne Carriere109c1d72019-01-09 11:02:02 +010015#include <inttypes.h>
Etienne Carriere109c1d72019-01-09 11:02:02 +010016#include <pkcs11.h>
Etienne Carrierefa7e34f2020-02-04 15:34:16 +010017#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
Etienne Carriere109c1d72019-01-09 11:02:02 +010020
21#include "xtest_test.h"
22#include "xtest_helpers.h"
23
Etienne Carriere3b5558a2020-03-12 09:55:26 +010024/*
25 * Util to find a slot on which to open a session
26 */
27static CK_RV close_lib(void)
28{
29 return C_Finalize(0);
30}
31
32static CK_RV init_lib_and_find_token_slot(CK_SLOT_ID *slot)
33{
34 CK_RV rv = CKR_GENERAL_ERROR;
35 CK_SLOT_ID_PTR slots = NULL;
36 CK_ULONG count = 0;
37
38 rv = C_Initialize(0);
39 if (rv)
40 return rv;
41
42 rv = C_GetSlotList(CK_TRUE, NULL, &count);
43 if (rv != CKR_OK)
44 goto bail;
45
46 if (count < 1) {
47 rv = CKR_GENERAL_ERROR;
48 goto bail;
49 }
50
51 slots = malloc(count * sizeof(CK_SLOT_ID));
52 if (!slots) {
53 rv = CKR_HOST_MEMORY;
54 goto bail;
55 }
56
57 rv = C_GetSlotList(CK_TRUE, slots, &count);
58 if (rv)
59 goto bail;
60
61 /* Use the last slot */
62 *slot = slots[count - 1];
63
64bail:
65 free(slots);
66 if (rv)
67 close_lib();
68
69 return rv;
70}
71
Etienne Carriere61f89d82020-03-11 11:24:29 +010072static void xtest_pkcs11_test_1000(ADBG_Case_t *c)
Etienne Carriere109c1d72019-01-09 11:02:02 +010073{
74 CK_RV rv;
75
76 rv = C_Initialize(NULL);
77 if (!ADBG_EXPECT_CK_OK(c, rv))
78 return;
79
80 rv = C_Finalize(NULL);
81 if (!ADBG_EXPECT_CK_OK(c, rv))
82 return;
83
84 rv = C_Initialize(NULL);
85 if (!ADBG_EXPECT_CK_OK(c, rv))
86 return;
87
88 rv = C_Initialize(NULL);
89 ADBG_EXPECT_CK_RESULT(c, CKR_CRYPTOKI_ALREADY_INITIALIZED, rv);
90
91 rv = C_Finalize(NULL);
92 ADBG_EXPECT_CK_OK(c, rv);
Etienne Carriere21f4e3c2020-02-05 15:40:24 +010093
94 rv = C_Finalize(NULL);
95 ADBG_EXPECT_CK_RESULT(c, CKR_CRYPTOKI_NOT_INITIALIZED, rv);
Etienne Carriere109c1d72019-01-09 11:02:02 +010096}
97
Etienne Carriere61f89d82020-03-11 11:24:29 +010098ADBG_CASE_DEFINE(pkcs11, 1000, xtest_pkcs11_test_1000,
99 "Initialize and close Cryptoki library");
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100100
Etienne Carriere61f89d82020-03-11 11:24:29 +0100101static void xtest_pkcs11_test_1001(ADBG_Case_t *c)
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100102{
103 CK_RV rv = CKR_GENERAL_ERROR;
104 CK_SLOT_ID_PTR slot_ids = NULL;
105 CK_ULONG slot_count = 0;
106 CK_ULONG present_slot_count = 0;
107 CK_INFO lib_info = { };
108 CK_SLOT_INFO slot_info = { };
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100109 CK_TOKEN_INFO token_info = { };
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100110 CK_FUNCTION_LIST_PTR ckfunc_list = NULL;
111 size_t i = 0;
112 CK_SLOT_ID max_slot_id = 0;
Etienne Carriered3121292020-03-04 17:38:24 +0100113 CK_MECHANISM_TYPE_PTR mecha_types = NULL;
114 CK_ULONG mecha_count = 0;
115 CK_MECHANISM_INFO mecha_info = { };
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100116
117 rv = C_Initialize(NULL);
118 if (!ADBG_EXPECT_CK_OK(c, rv))
119 return;
120
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100121 Do_ADBG_BeginSubCase(c, "Test C_GetFunctionList()");
122
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100123 rv = C_GetFunctionList(&ckfunc_list);
124 if (!ADBG_EXPECT_CK_OK(c, rv))
125 goto out;
126
127 if (!ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetInfo) ||
128 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetSlotList) ||
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100129 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetSlotInfo) ||
Etienne Carriered3121292020-03-04 17:38:24 +0100130 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetTokenInfo) ||
131 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetMechanismList) ||
132 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetMechanismInfo))
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100133 goto out;
134
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100135 Do_ADBG_EndSubCase(c, "Test C_GetFunctionList()");
136 Do_ADBG_BeginSubCase(c, "Test C_GetInfo()");
137
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100138 rv = C_GetInfo(&lib_info);
139 if (!ADBG_EXPECT_CK_OK(c, rv))
140 goto out;
141
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100142 Do_ADBG_EndSubCase(c, "Test C_GetInfo()");
143 Do_ADBG_BeginSubCase(c, "Test C_GetSlotList()");
144
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100145 rv = C_GetSlotList(0, NULL, &slot_count);
146 if (!ADBG_EXPECT_CK_OK(c, rv))
147 goto out;
148
149 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, slot_count, !=, 0))
150 goto out;
151
Etienne Carrierede746332020-03-04 19:43:53 +0100152 if (slot_count > 1) {
153 /* Ensure case non-NULL-buffer and zero-count is tested */
154 CK_SLOT_ID id = 0;
155
156 slot_count = 0;
157 rv = C_GetSlotList(0, &id, &slot_count);
158 if (!ADBG_EXPECT_CK_RESULT(c, CKR_BUFFER_TOO_SMALL, rv))
159 goto out;
160 }
161
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100162 rv = C_GetSlotList(1, NULL, &present_slot_count);
163 if (!ADBG_EXPECT_CK_OK(c, rv))
164 goto out;
165
166 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, slot_count, ==,
167 present_slot_count))
168 goto out;
169
170 slot_ids = calloc(slot_count, sizeof(CK_SLOT_ID));
171 if (!ADBG_EXPECT_NOT_NULL(c, slot_ids))
172 goto out;
173
174 slot_count--;
175 rv = C_GetSlotList(1, slot_ids, &slot_count);
176 if (!ADBG_EXPECT_CK_RESULT(c, CKR_BUFFER_TOO_SMALL, rv))
177 goto out;
178
179 rv = C_GetSlotList(1, slot_ids, &slot_count);
180 if (!ADBG_EXPECT_CK_OK(c, rv))
181 goto out;
182
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100183 Do_ADBG_EndSubCase(c, "Test C_GetSlotList()");
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100184 Do_ADBG_BeginSubCase(c, "Test C_Get{Slot|Token}Info()");
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100185
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100186 for (i = 0; i < slot_count; i++) {
187 CK_SLOT_ID slot = slot_ids[i];
188
189 rv = C_GetSlotInfo(slot, &slot_info);
190 if (!ADBG_EXPECT_CK_OK(c, rv))
191 goto out;
192
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100193 rv = C_GetTokenInfo(slot, &token_info);
194 if (!ADBG_EXPECT_CK_OK(c, rv))
195 goto out;
196
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100197 if (max_slot_id < slot)
198 max_slot_id = slot;
199 }
200
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100201 Do_ADBG_EndSubCase(c, "Test C_Get{Slot|Token}Info()");
Etienne Carriered3121292020-03-04 17:38:24 +0100202 Do_ADBG_BeginSubCase(c, "Test C_GetMechanism{List|Info}()");
203
204 for (i = 0; i < slot_count; i++) {
205 CK_SLOT_ID slot = slot_ids[i];
206 size_t j = 0;
207
208 mecha_count = 0;
209 rv = C_GetMechanismList(slot, NULL, &mecha_count);
210 if (!ADBG_EXPECT_CK_OK(c, rv))
211 goto out;
212
213 if (mecha_count == 0)
214 continue;
215
216 free(mecha_types);
217 mecha_types = calloc(mecha_count, sizeof(*mecha_types));
218 if (!ADBG_EXPECT_NOT_NULL(c, mecha_types))
219 goto out;
220
221 /* Test specific case: valid buffer reference with 0 count */
222 mecha_count = 0;
223 rv = C_GetMechanismList(slot, mecha_types, &mecha_count);
224 if (!ADBG_EXPECT_CK_RESULT(c, CKR_BUFFER_TOO_SMALL, rv))
225 goto out;
226
227 rv = C_GetMechanismList(slot, mecha_types, &mecha_count);
228 if (!ADBG_EXPECT_CK_OK(c, rv))
229 goto out;
230
231 for (j = 0; j < mecha_count; j++) {
232 rv = C_GetMechanismInfo(slot, mecha_types[j],
233 &mecha_info);
234 if (!ADBG_EXPECT_CK_OK(c, rv))
235 goto out;
236 }
237 }
238
239 Do_ADBG_EndSubCase(c, "Test C_GetMechanism{List|Info}()");
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100240 Do_ADBG_BeginSubCase(c, "Test C_Get*Info() with invalid reference");
241
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100242 rv = C_GetSlotInfo(max_slot_id + 1, &slot_info);
243 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
244 goto out;
245
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100246 rv = C_GetTokenInfo(max_slot_id + 1, &token_info);
247 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
248 goto out;
249
Etienne Carriered3121292020-03-04 17:38:24 +0100250 mecha_count = 1;
251 if (!mecha_types)
252 mecha_types = malloc(sizeof(*mecha_types));
253 if (!ADBG_EXPECT_NOT_NULL(c, mecha_types))
254 goto out;
255
256 rv = C_GetMechanismList(max_slot_id + 1, mecha_types, &mecha_count);
257 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
258 goto out;
259
260 rv = C_GetMechanismInfo(max_slot_id + 1, CKM_AES_KEY_GEN, &mecha_info);
261 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
262 goto out;
263
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100264 rv = C_GetSlotInfo(ULONG_MAX, &slot_info);
265 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
266 goto out;
267
Etienne Carriere6818d5f2020-03-04 15:34:50 +0100268 rv = C_GetTokenInfo(ULONG_MAX, &token_info);
269 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
270 goto out;
271
Etienne Carriered3121292020-03-04 17:38:24 +0100272 mecha_count = 1;
273 rv = C_GetMechanismList(ULONG_MAX, mecha_types, &mecha_count);
274 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
275 goto out;
276
277 rv = C_GetMechanismInfo(ULONG_MAX, CKM_AES_KEY_GEN, &mecha_info);
278 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SLOT_ID_INVALID, rv))
279 goto out;
280
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100281out:
Etienne Carrieree90a4e42020-03-02 12:04:08 +0100282 Do_ADBG_EndSubCase(c, NULL);
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100283 free(slot_ids);
Etienne Carriered3121292020-03-04 17:38:24 +0100284 free(mecha_types);
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100285
286 rv = C_Finalize(NULL);
287 ADBG_EXPECT_CK_OK(c, rv);
288}
289
Etienne Carriere61f89d82020-03-11 11:24:29 +0100290ADBG_CASE_DEFINE(pkcs11, 1001, xtest_pkcs11_test_1001,
Etienne Carrierefa7e34f2020-02-04 15:34:16 +0100291 "PKCS11: List PKCS#11 slots and get information from");
Etienne Carriere3b5558a2020-03-12 09:55:26 +0100292
293static void xtest_pkcs11_test_1002(ADBG_Case_t *c)
294{
295 CK_RV rv = CKR_GENERAL_ERROR;
296 CK_SLOT_ID slot = 0;
297 CK_SESSION_HANDLE session[3] = { 0 };
298 CK_FLAGS session_flags = 0;
299 CK_SESSION_INFO session_info = { };
300 CK_FUNCTION_LIST_PTR ckfunc_list = NULL;
301
302 rv = init_lib_and_find_token_slot(&slot);
303 if (!ADBG_EXPECT_CK_OK(c, rv))
304 return;
305
306 rv = C_GetFunctionList(&ckfunc_list);
307 if (!ADBG_EXPECT_CK_OK(c, rv) ||
308 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_OpenSession) ||
309 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_CloseSession) ||
310 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_CloseAllSessions) ||
311 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_GetSessionInfo))
312 goto bail;
313
314 Do_ADBG_BeginSubCase(c, "Test C_OpenSession()/C_GetSessionInfo()");
315
316 session_flags = CKF_RW_SESSION;
317
318 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[0]);
319 if (!ADBG_EXPECT_CK_RESULT(c, CKR_ARGUMENTS_BAD, rv))
320 goto bail;
321
322 session_flags = CKF_SERIAL_SESSION;
323
324 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[0]);
325 if (!ADBG_EXPECT_CK_OK(c, rv))
326 goto bail;
327
328 rv = C_GetSessionInfo(session[0], &session_info);
329 if (!ADBG_EXPECT_CK_OK(c, rv) ||
330 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.slotID, ==, slot) ||
331 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.flags, ==,
332 session_flags) ||
333 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.state, ==,
334 CKS_RO_PUBLIC_SESSION) ||
335 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.ulDeviceError, ==, 0))
336 goto bail;
337
338 session_flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
339
340 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[1]);
341 if (!ADBG_EXPECT_CK_OK(c, rv))
342 goto bail;
343
344 rv = C_GetSessionInfo(session[1], &session_info);
345 if (!ADBG_EXPECT_CK_OK(c, rv) ||
346 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.slotID, ==, slot) ||
347 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.flags, ==,
348 session_flags) ||
349 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.state, ==,
350 CKS_RW_PUBLIC_SESSION) ||
351 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.ulDeviceError, ==, 0))
352 goto bail;
353
354 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[2]);
355 if (!ADBG_EXPECT_CK_OK(c, rv))
356 goto bail;
357
358 rv = C_GetSessionInfo(session[2], &session_info);
359 if (!ADBG_EXPECT_CK_OK(c, rv) ||
360 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.slotID, ==, slot) ||
361 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.flags, ==,
362 session_flags) ||
363 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.state, ==,
364 CKS_RW_PUBLIC_SESSION) ||
365 !ADBG_EXPECT_COMPARE_UNSIGNED(c, session_info.ulDeviceError, ==, 0))
366 goto bail;
367
368 Do_ADBG_EndSubCase(c, "Test C_OpenSession()/C_GetSessionInfo()");
369 Do_ADBG_BeginSubCase(c, "Test C_CloseSession()");
370
371 /* Close 2 of them */
372 rv = C_CloseSession(session[0]);
373 if (!ADBG_EXPECT_CK_OK(c, rv))
374 goto bail;
375
376 rv = C_GetSessionInfo(session[0], &session_info);
377 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
378 goto bail;
379
380 rv = C_GetSessionInfo(session[1], &session_info);
381 if (!ADBG_EXPECT_CK_OK(c, rv))
382 goto bail;
383
384 rv = C_GetSessionInfo(session[2], &session_info);
385 if (!ADBG_EXPECT_CK_OK(c, rv))
386 goto bail;
387
388 /* Close all remaining sessions, later calls should failed on session */
389 rv = C_CloseAllSessions(slot);
390 if (!ADBG_EXPECT_CK_OK(c, rv))
391 goto bail;
392
393 rv = C_CloseSession(session[1]);
394 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
395 goto bail;
396
397 rv = C_CloseSession(session[2]);
398 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
399 goto bail;
400
401 rv = C_GetSessionInfo(session[1], &session_info);
402 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
403 goto bail;
404
405 rv = C_GetSessionInfo(session[2], &session_info);
406 if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_HANDLE_INVALID, rv))
407 goto bail;
408
409 /* Open a session, should be closed from library closure */
410 rv = C_OpenSession(slot, session_flags, NULL, 0, &session[0]);
411 if (!ADBG_EXPECT_CK_OK(c, rv))
412 goto bail;
413
414bail:
415 Do_ADBG_EndSubCase(c, NULL);
416 rv = close_lib();
417 ADBG_EXPECT_CK_OK(c, rv);
418}
419
420ADBG_CASE_DEFINE(pkcs11, 1002, xtest_pkcs11_test_1002,
421 "PKCS11: Open and close PKCS#11 sessions");
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200422
423/*
424 * Helpers for tests where we must log into the token.
425 * These define the genuine PINs and label to be used with the test token.
426 */
427static CK_UTF8CHAR test_token_so_pin[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 , 9, 10, };
Jens Wiklander282a8a52020-04-14 17:01:36 +0200428static CK_UTF8CHAR test_token_user_pin[] = {
429 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
430};
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200431static CK_UTF8CHAR test_token_label[] = "PKCS11 TA test token";
432
433static CK_RV init_test_token(CK_SLOT_ID slot)
434{
435 return C_InitToken(slot, test_token_so_pin, sizeof(test_token_so_pin),
436 test_token_label);
437}
438
Jens Wiklander282a8a52020-04-14 17:01:36 +0200439/* Login as user, eventually reset user PIN if needed */
440static CK_RV init_user_test_token(CK_SLOT_ID slot)
441{
442 CK_FLAGS session_flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
443 CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
444 CK_RV rv = CKR_GENERAL_ERROR;
445
446 rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
447 if (rv)
448 return rv;
449
450 rv = C_Login(session, CKU_USER, test_token_user_pin,
451 sizeof(test_token_user_pin));
452 if (rv == CKR_OK) {
453 C_Logout(session);
454 C_CloseSession(session);
455 return rv;
456 }
457
458 rv = C_Login(session, CKU_SO, test_token_so_pin,
459 sizeof(test_token_so_pin));
460 if (rv) {
461 C_CloseSession(session);
462
463 rv = init_test_token(slot);
464 if (rv)
465 return rv;
466
467 rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
468 if (rv)
469 return rv;
470
471 rv = C_Login(session, CKU_SO, test_token_so_pin,
472 sizeof(test_token_so_pin));
473 if (rv) {
474 C_CloseSession(session);
475 return rv;
476 }
477 }
478
479 rv = C_InitPIN(session, test_token_user_pin,
480 sizeof(test_token_user_pin));
481
482 C_Logout(session);
483 C_CloseSession(session);
484
485 return rv;
486}
487
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200488static CK_RV test_already_initialized_token(ADBG_Case_t *c, CK_SLOT_ID slot)
489{
490 CK_RV rv = CKR_GENERAL_ERROR;
491 CK_TOKEN_INFO token_info = { };
492 /* Same content as test_token_so_pin[] but 1 more byte */
493 CK_UTF8CHAR pin1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, };
494 /* Same content as test_token_so_pin[] but 1 different byte */
495 CK_UTF8CHAR pin2[] = { 0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 10, };
496 CK_FLAGS flags = 0;
497
498 Do_ADBG_BeginSubCase(c, "C_InitToken() on initialized token");
499
500 rv = C_GetTokenInfo(slot, &token_info);
501 if (!ADBG_EXPECT_CK_OK(c, rv))
502 goto out;
503
504 rv = C_InitToken(slot, test_token_so_pin,
505 sizeof(test_token_so_pin) - 1, test_token_label);
506 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, rv, !=, CKR_OK))
507 goto out;
508
509 rv = C_InitToken(slot, pin1, sizeof(pin1), test_token_label);
510 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, rv, !=, CKR_OK))
511 goto out;
512
513 rv = C_InitToken(slot, pin2, sizeof(pin2), test_token_label);
514 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, rv, !=, CKR_OK))
515 goto out;
516
517 rv = C_GetTokenInfo(slot, &token_info);
518 if (!ADBG_EXPECT_CK_OK(c, rv))
519 goto out;
520
521 flags = token_info.flags;
522
523 /* Token should have set CKF_SO_PIN_COUNT_LOW to 1 */
524 if (!ADBG_EXPECT_TRUE(c, !!(flags & CKF_SO_PIN_COUNT_LOW))) {
525 rv = CKR_GENERAL_ERROR;
526 goto out;
527 }
528
529 rv = init_test_token(slot);
530 if (!ADBG_EXPECT_CK_OK(c, rv))
531 goto out;
532
533 rv = C_GetTokenInfo(slot, &token_info);
534 if (!ADBG_EXPECT_CK_OK(c, rv))
535 goto out;
536
537 flags = token_info.flags;
538
539 /*
540 * Token should have reset CKF_SO_PIN_COUNT_LOW to 0.
541 * Other flags should show a sane initialized state.
542 */
543 if (!ADBG_EXPECT_TRUE(c, !(flags & CKF_SO_PIN_COUNT_LOW)) ||
544 !ADBG_EXPECT_TRUE(c, !!(flags & CKF_TOKEN_INITIALIZED)) ||
545 !ADBG_EXPECT_TRUE(c, !(flags & CKF_ERROR_STATE)) ||
546 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_INITIALIZED))) {
547 rv = CKR_GENERAL_ERROR;
Jens Wiklander282a8a52020-04-14 17:01:36 +0200548 goto out;
549 }
550
551 rv = init_user_test_token(slot);
552 if (!ADBG_EXPECT_CK_OK(c, rv))
553 goto out;
554
555 rv = C_GetTokenInfo(slot, &token_info);
556 if (!ADBG_EXPECT_CK_OK(c, rv))
557 goto out;
558
559 flags = token_info.flags;
560
561 if (!ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_COUNT_LOW)) ||
562 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_FINAL_TRY)) ||
563 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_LOCKED)) ||
564 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_TO_BE_CHANGED)) ||
565 !ADBG_EXPECT_TRUE(c, !!(flags & CKF_USER_PIN_INITIALIZED)) ||
566 !ADBG_EXPECT_TRUE(c, !(flags & CKF_ERROR_STATE))) {
567 rv = CKR_GENERAL_ERROR;
568 goto out;
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200569 }
570
571out:
572 Do_ADBG_EndSubCase(c, "C_InitToken() on initialized token");
573
574 return rv;
575}
576
577static CK_RV test_uninitialized_token(ADBG_Case_t *c, CK_SLOT_ID slot)
578{
579 CK_RV rv = CKR_GENERAL_ERROR;
580 CK_TOKEN_INFO token_info = { };
581 CK_FLAGS flags = 0;
582
583 Do_ADBG_BeginSubCase(c, "C_InitToken() on uninitialized token");
584
585 rv = init_test_token(slot);
586 if (!ADBG_EXPECT_CK_OK(c, rv))
587 goto out;
588
589 rv = C_GetTokenInfo(slot, &token_info);
590 if (!ADBG_EXPECT_CK_OK(c, rv))
591 goto out;
592
593 flags = token_info.flags;
594
595 if (!ADBG_EXPECT_TRUE(c, !!(flags & CKF_TOKEN_INITIALIZED)) ||
596 !ADBG_EXPECT_TRUE(c, !(flags & CKF_ERROR_STATE)) ||
597 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_INITIALIZED))) {
598 rv = CKR_GENERAL_ERROR;
Jens Wiklander282a8a52020-04-14 17:01:36 +0200599 goto out;
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200600 }
601
Jens Wiklander282a8a52020-04-14 17:01:36 +0200602 rv = init_user_test_token(slot);
603 if (!ADBG_EXPECT_CK_OK(c, rv))
604 goto out;
605
606 rv = C_GetTokenInfo(slot, &token_info);
607 if (!ADBG_EXPECT_CK_OK(c, rv))
608 goto out;
609
610 flags = token_info.flags;
611
612 if (!ADBG_EXPECT_TRUE(c, !!(flags & CKF_TOKEN_INITIALIZED)) ||
613 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_COUNT_LOW)) ||
614 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_FINAL_TRY)) ||
615 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_LOCKED)) ||
616 !ADBG_EXPECT_TRUE(c, !(flags & CKF_USER_PIN_TO_BE_CHANGED)) ||
617 !ADBG_EXPECT_TRUE(c, !!(flags & CKF_USER_PIN_INITIALIZED)) ||
618 !ADBG_EXPECT_TRUE(c, !(flags & CKF_ERROR_STATE)))
619 rv = CKR_GENERAL_ERROR;
620
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200621out:
622 Do_ADBG_EndSubCase(c, "C_InitToken() on uninitialized token");
623
624 return rv;
625}
626
Jens Wiklanderaa741512020-04-14 17:01:46 +0200627static CK_RV test_login_logout(ADBG_Case_t *c, CK_SLOT_ID slot)
628{
629 CK_FLAGS session_flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
630 CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
631 CK_RV rv = CKR_GENERAL_ERROR;
632
633 Do_ADBG_BeginSubCase(c, "Test C_Login()/C_Logout()");
634
635 rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
636 if (!ADBG_EXPECT_CK_OK(c, rv))
637 goto out;
638
639 /* Logout: should fail as we did not log in yet */
640 rv = C_Logout(session);
641 ADBG_EXPECT_CK_RESULT(c, CKR_USER_NOT_LOGGED_IN, rv);
642
643 /* Login/re-log/logout user */
644 rv = C_Login(session, CKU_USER, test_token_user_pin,
645 sizeof(test_token_user_pin));
646 if (!ADBG_EXPECT_CK_OK(c, rv))
647 goto out;
648
649 rv = C_Login(session, CKU_USER, test_token_user_pin,
650 sizeof(test_token_user_pin));
651 ADBG_EXPECT_CK_RESULT(c, CKR_USER_ALREADY_LOGGED_IN, rv);
652
653 rv = C_Logout(session);
654 if (!ADBG_EXPECT_CK_OK(c, rv))
655 goto out;
656
657 /* Login/re-log/logout security officer */
658 rv = C_Login(session, CKU_SO, test_token_so_pin,
659 sizeof(test_token_so_pin));
660 if (!ADBG_EXPECT_CK_OK(c, rv))
661 goto out;
662
663 rv = C_Login(session, CKU_SO, test_token_so_pin,
664 sizeof(test_token_so_pin));
665 ADBG_EXPECT_CK_RESULT(c, CKR_USER_ALREADY_LOGGED_IN, rv);
666
667 rv = C_Logout(session);
668 if (!ADBG_EXPECT_CK_OK(c, rv))
669 goto out;
670
671 /* Login user then SO and reverse */
672 rv = C_Login(session, CKU_SO, test_token_so_pin,
673 sizeof(test_token_so_pin));
674 ADBG_EXPECT_CK_OK(c, rv);
675
676 rv = C_Login(session, CKU_USER, test_token_user_pin,
677 sizeof(test_token_user_pin));
678 ADBG_EXPECT_CK_RESULT(c, CKR_USER_ANOTHER_ALREADY_LOGGED_IN, rv);
679
680 rv = C_Logout(session);
681 if (!ADBG_EXPECT_CK_OK(c, rv))
682 goto out;
683
684 rv = C_Login(session, CKU_USER, test_token_user_pin,
685 sizeof(test_token_user_pin));
686 ADBG_EXPECT_CK_OK(c, rv);
687
688 rv = C_Login(session, CKU_SO, test_token_so_pin,
689 sizeof(test_token_so_pin));
690 ADBG_EXPECT_CK_RESULT(c, CKR_USER_ANOTHER_ALREADY_LOGGED_IN, rv);
691
692 rv = C_Logout(session);
693 ADBG_EXPECT_CK_OK(c, rv);
694
695 /* Login context specifc, in an invalid case (need an operation) */
696 rv = C_Login(session, CKU_CONTEXT_SPECIFIC, test_token_user_pin,
697 sizeof(test_token_user_pin));
698 ADBG_EXPECT_CK_RESULT(c, CKR_OPERATION_NOT_INITIALIZED, rv);
699
700 rv = C_CloseSession(session);
701 ADBG_EXPECT_CK_OK(c, rv);
702
703out:
704 Do_ADBG_EndSubCase(c, "Test C_Login()/C_Logout()");
705 return rv;
706}
707
Jens Wiklander6ce1e692020-04-14 17:02:09 +0200708static CK_RV test_set_pin(ADBG_Case_t *c, CK_SLOT_ID slot,
709 CK_USER_TYPE user_type)
710{
711 CK_FLAGS session_flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
712 CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
713 CK_UTF8CHAR some_pin[] = { 7, 6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6, 7 };
714 CK_UTF8CHAR_PTR old_pin = NULL;
715 CK_USER_TYPE ut = user_type;
716 size_t old_pin_sz = 0;
717 CK_RV rv2 = CKR_OK;
718 CK_RV rv = CKR_OK;
719
720 Do_ADBG_BeginSubCase(c, "Test C_SetPIN() user_type %lu", user_type);
721
722 rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
723 if (!ADBG_EXPECT_CK_OK(c, rv))
724 goto out;
725
726 if (user_type == CKU_SO) {
727 old_pin = (CK_UTF8CHAR_PTR)test_token_so_pin;
728 old_pin_sz = sizeof(test_token_so_pin);
729 } else {
730 old_pin = (CK_UTF8CHAR_PTR)test_token_user_pin;
731 old_pin_sz = sizeof(test_token_user_pin);
732 ut = CKU_USER;
733 }
734
735 if (ut == user_type) {
736 rv = C_Login(session, ut, old_pin, old_pin_sz);
737 if (!ADBG_EXPECT_CK_OK(c, rv))
738 goto out_session;
739 }
740
741 rv = C_SetPIN(session, old_pin, old_pin_sz, some_pin, sizeof(some_pin));
742 if (!ADBG_EXPECT_CK_OK(c, rv)) {
743 if (ut == user_type)
744 goto out_logout;
745 else
746 goto out_session;
747 }
748
749 if (ut == user_type) {
750 rv = C_Logout(session);
751 if (!ADBG_EXPECT_CK_OK(c, rv))
752 goto out_session;
753 }
754
755 rv = C_Login(session, ut, some_pin, sizeof(some_pin));
756 if (!ADBG_EXPECT_CK_OK(c, rv))
757 goto out_session;
758
759 rv = C_SetPIN(session, some_pin, sizeof(some_pin), old_pin, old_pin_sz);
760 ADBG_EXPECT_CK_OK(c, rv);
761
762out_logout:
763 rv2 = C_Logout(session);
764 if (!ADBG_EXPECT_CK_OK(c, rv2) && !rv)
765 rv = rv2;
766out_session:
767 rv2 = C_CloseSession(session);
768 if (!ADBG_EXPECT_CK_OK(c, rv2) && !rv)
769 rv = rv2;
770out:
771 Do_ADBG_EndSubCase(c, "Test C_SetPIN() user_type %lu", user_type);
772
773 return rv;
774}
775
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200776static void xtest_pkcs11_test_1003(ADBG_Case_t *c)
777{
778 CK_RV rv = CKR_GENERAL_ERROR;
779 CK_FUNCTION_LIST_PTR ckfunc_list = NULL;
780 CK_SLOT_ID slot = 0;
781 CK_TOKEN_INFO token_info = { };
782
783 rv = C_GetFunctionList(&ckfunc_list);
784 if (!ADBG_EXPECT_CK_OK(c, rv) ||
Jens Wiklander282a8a52020-04-14 17:01:36 +0200785 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_InitToken) ||
786 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_InitPIN) ||
Jens Wiklanderaa741512020-04-14 17:01:46 +0200787 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_SetPIN) ||
788 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_Login) ||
789 !ADBG_EXPECT_NOT_NULL(c, ckfunc_list->C_Logout))
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200790 goto out;
791
792 rv = init_lib_and_find_token_slot(&slot);
793 if (!ADBG_EXPECT_CK_OK(c, rv))
794 return;
795
796 rv = C_GetTokenInfo(slot, &token_info);
797 if (!ADBG_EXPECT_CK_OK(c, rv))
798 goto out;
799
800 /* Abort test if token is about to lock */
801 if (!ADBG_EXPECT_TRUE(c, !(token_info.flags & CKF_SO_PIN_FINAL_TRY)))
802 goto out;
803
804 if (!(token_info.flags & CKF_TOKEN_INITIALIZED)) {
805 rv = test_uninitialized_token(c, slot);
806 if (rv != CKR_OK)
807 goto out;
808 }
809
810 rv = test_already_initialized_token(c, slot);
811 if (rv != CKR_OK)
812 goto out;
813
Jens Wiklanderaa741512020-04-14 17:01:46 +0200814 rv = test_login_logout(c, slot);
815 if (rv != CKR_OK)
816 goto out;
817
Jens Wiklander6ce1e692020-04-14 17:02:09 +0200818 rv = test_set_pin(c, slot, CKU_USER);
819 if (rv != CKR_OK)
820 goto out;
Jens Wiklanderaa741512020-04-14 17:01:46 +0200821
Jens Wiklander6ce1e692020-04-14 17:02:09 +0200822 rv = test_set_pin(c, slot, CKU_SO);
823 if (rv != CKR_OK)
824 goto out;
Jens Wiklanderaa741512020-04-14 17:01:46 +0200825
Jens Wiklander6ce1e692020-04-14 17:02:09 +0200826 /*
827 * CKU_CONTEXT_SPECIFIC is anything not CKU_USER or CKU_SO in order
828 * to skip the initial login.
829 */
830 test_set_pin(c, slot, CKU_CONTEXT_SPECIFIC);
Jens Wiklander14f8e8d2020-04-14 17:01:24 +0200831out:
832 rv = close_lib();
833 ADBG_EXPECT_CK_OK(c, rv);
834}
835
836ADBG_CASE_DEFINE(pkcs11, 1003, xtest_pkcs11_test_1003,
837 "PKCS11: Login to PKCS#11 token");