1 /*
2  * COPYRIGHT (c) International Business Machines Corp. 2015-2017
3  *
4  * This program is provided under the terms of the Common Public License,
5  * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
6  * software constitutes recipient's acceptance of CPL-1.0 terms which can be
7  * found in the file LICENSE file or at
8  * https://opensource.org/licenses/cpl1.0.php
9  */
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <memory.h>
15 
16 #include "pkcs11types.h"
17 #include "regress.h"
18 #include "common.c"
19 
do_GetInfo(void)20 CK_RV do_GetInfo(void)
21 {
22     CK_FLAGS flags;
23     CK_SESSION_HANDLE session;
24     CK_RV rc = 0;
25     CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
26     CK_ULONG user_pin_len;
27     CK_INFO info;
28 
29     // Do some setup and login to the token
30     testcase_begin("C_GetInfo function check");
31     testcase_rw_session();
32     testcase_user_login();
33 
34     testcase_new_assertion();
35 
36     rc = funcs->C_GetInfo(&info);
37     if (rc != CKR_OK) {
38         testcase_fail("C_GetInfo() rc=%s", p11_get_ckr(rc));
39         goto testcase_cleanup;
40     }
41 
42     testcase_pass("Library info successfully sourced");
43 
44 testcase_cleanup:
45     testcase_user_logout();
46     rc = funcs->C_CloseSession(session);
47     if (rc != CKR_OK)
48         testcase_error("C_CloseSession() failed.");
49 
50     return rc;
51 }
52 
do_GetSlotList(void)53 CK_RV do_GetSlotList(void)
54 {
55     CK_FLAGS flags;
56     CK_SESSION_HANDLE session;
57     CK_RV rc = 0;
58     CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
59     CK_ULONG user_pin_len;
60 
61     CK_BBOOL tokenPresent;
62     CK_SLOT_ID_PTR pSlotList = NULL;
63     CK_ULONG ulCount = 0;
64 
65     tokenPresent = TRUE;
66 
67     testcase_begin("testing C_GetSlotList");
68     testcase_rw_session();
69     testcase_user_login();
70 
71     testcase_new_assertion();
72 
73     /* pkcs#11v2.20, Section 11.5
74      * If pSlotList is NULL_PTR, then all that C_GetSlotList does is
75      * return (in *pulCount) the number of slots, without actually
76      * returning a list of slots.
77      */
78     rc = funcs->C_GetSlotList(tokenPresent, NULL, &ulCount);
79     if (rc != CKR_OK) {
80         testcase_fail("C_GetSlotList rc=%s", p11_get_ckr(rc));
81         goto testcase_cleanup;
82     }
83 
84     if (ulCount)
85         testcase_pass("C_GetSlotList received slot count.");
86     else
87         testcase_fail("C_GetSlotList did not receive slot count.");
88 
89     pSlotList = (CK_SLOT_ID *) malloc(ulCount * sizeof(CK_SLOT_ID));
90     if (!pSlotList) {
91         testcase_error("malloc failed to allocate memory for list\n");
92         rc = CKR_HOST_MEMORY;
93         goto testcase_cleanup;
94     }
95 
96     testcase_new_assertion();
97 
98     /* Get the slots */
99     rc = funcs->C_GetSlotList(tokenPresent, pSlotList, &ulCount);
100     if (rc != CKR_OK) {
101         testcase_fail("C_GetSlotList rc=%s", p11_get_ckr(rc));
102         goto testcase_cleanup;
103     }
104 
105     testcase_pass("Slot list returned successfully");
106 
107 testcase_cleanup:
108     if (pSlotList)
109         free(pSlotList);
110 
111     testcase_user_logout();
112     rc = funcs->C_CloseSession(session);
113     if (rc != CKR_OK)
114         testcase_error("C_CloseSession failed.");
115 
116     return rc;
117 }
118 
do_GetSlotInfo(void)119 CK_RV do_GetSlotInfo(void)
120 {
121     CK_FLAGS flags;
122     CK_SESSION_HANDLE session;
123     CK_RV rc = 0;
124     CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
125     CK_ULONG user_pin_len;
126 
127     CK_SLOT_ID slot_id = SLOT_ID;
128     CK_SLOT_INFO info;
129 
130     testcase_begin("testing C_GetSlotInfo");
131     testcase_rw_session();
132     testcase_user_login();
133 
134     /* Test expected values */
135     testcase_new_assertion();
136 
137     rc = funcs->C_GetSlotInfo(slot_id, &info);
138     if (rc != CKR_OK) {
139         testcase_fail("C_GetSlotInfo() rc = %s", p11_get_ckr(rc));
140         goto testcase_cleanup;
141     }
142 
143     testcase_pass("Slot info of in-use slot received successfully");
144 
145     /* Test for invalid slot */
146     testcase_new_assertion();
147 
148     rc = funcs->C_GetSlotInfo(9999, &info);
149     if (rc != CKR_SLOT_ID_INVALID) {
150         testcase_fail("C_GetSlotInfo returned %s instead of"
151                       " CKR_SLOT_ID_INVALID.", p11_get_ckr(rc));
152         rc = CKR_FUNCTION_FAILED;       // dont confuse loop in main
153         goto testcase_cleanup;
154     }
155 
156     testcase_pass("C_GetSlotInfo correctly returned " "CKR_SLOT_ID_INVALID.");
157     rc = 0;                     // don't confuse loop in main
158 
159 testcase_cleanup:
160     testcase_user_logout();
161     rc = funcs->C_CloseSession(session);
162     if (rc != CKR_OK)
163         testcase_error("C_CloseSessions failed.");
164 
165     return rc;
166 }
167 
do_GetTokenInfo(void)168 CK_RV do_GetTokenInfo(void)
169 {
170     CK_FLAGS flags;
171     CK_SESSION_HANDLE session;
172     CK_RV rc = 0;
173     CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
174     CK_ULONG user_pin_len;
175     CK_SLOT_ID slot_id = SLOT_ID;
176     CK_TOKEN_INFO info;
177 
178     testcase_begin("testing C_GetTokenInfo()");
179     testcase_rw_session();
180     testcase_user_login();
181 
182     testcase_new_assertion();
183 
184     rc = funcs->C_GetTokenInfo(slot_id, &info);
185     if (rc != CKR_OK) {
186         testcase_fail("C_GetTokenInfo rc=%s", p11_get_ckr(rc));
187         return rc;
188     }
189 
190     testcase_pass("C_GetTokenInfo returned successfully");
191 
192     /* Test with an invalid slot id */
193     testcase_new_assertion();
194 
195     rc = funcs->C_GetTokenInfo(9999, &info);
196     if (rc != CKR_SLOT_ID_INVALID) {
197         testcase_fail("C_GetTokenInfo() rc = %s", p11_get_ckr(rc));
198         goto testcase_cleanup;
199     }
200 
201     testcase_pass("C_GetTokenInfo returned error when given invalid slot.");
202 
203 testcase_cleanup:
204     testcase_user_logout();
205     rc = funcs->C_CloseSession(session);
206     if (rc != CKR_OK)
207         testcase_error("C_CloseSessions failed.");
208 
209     return rc;
210 }
211 
do_GetMechanismList(void)212 CK_RV do_GetMechanismList(void)
213 {
214     CK_FLAGS flags = 0;
215     CK_SESSION_HANDLE session = 0;
216     CK_RV rc = 0;
217     CK_BYTE user_pin[PKCS11_MAX_PIN_LEN] = {0};
218     CK_ULONG user_pin_len = 0;
219     CK_SLOT_ID slot_id = SLOT_ID;
220     CK_ULONG count = 0;
221     CK_MECHANISM_TYPE *mech_list = NULL;
222 
223     testcase_begin("testing C_GetMechanismList");
224     testcase_rw_session();
225     testcase_user_login();
226 
227     /* pkcs11v2.20, page 111
228      * If pMechanismList is NULL_PTR, then all that C_GetMechanismList
229      * does is return (in *pulCount) the number of mechanisms, without
230      * actually returning a list of mechanisms. The contents of
231      * *pulCount on entry to C_GetMechanismList has no meaning in this
232      * case, and the call returns the value CKR_OK.
233      */
234     testcase_new_assertion();
235 
236     rc = funcs->C_GetMechanismList(slot_id, NULL, &count);
237     if (rc != CKR_OK) {
238         testcase_fail("C_GetMechanismList 1 rc=%s", p11_get_ckr(rc));
239         return rc;
240     }
241 
242     if (count)
243         testcase_pass("C_GetMechanismList returned mechanism count.");
244     else
245         testcase_fail("C_GetMechanismList did not not return "
246                       "mechanism count.");
247 
248     mech_list = (CK_MECHANISM_TYPE *) calloc(1, count * sizeof(CK_MECHANISM_TYPE));
249     if (!mech_list) {
250         testcase_fail();
251         rc = CKR_HOST_MEMORY;
252         goto testcase_cleanup;
253     }
254 
255     testcase_new_assertion();
256     rc = funcs->C_GetMechanismList(slot_id, mech_list, &count);
257     if (rc != CKR_OK) {
258         testcase_fail("C_GetMechanismList 2 rc=%s", p11_get_ckr(rc));
259         goto testcase_cleanup;
260     }
261 
262     testcase_pass("Mechanism listing from current slot");
263 
264     /* Test for invalid slot */
265     testcase_new_assertion();
266 
267     rc = funcs->C_GetMechanismList(9999, NULL, &count);
268     if (rc != CKR_SLOT_ID_INVALID) {
269         testcase_fail("C_GetMechanismList() returned %s instead of"
270                       " CKR_SLOT_ID_INVALID.", p11_get_ckr(rc));
271         rc = CKR_FUNCTION_FAILED;
272         goto testcase_cleanup;
273     }
274 
275     testcase_pass("C_GetMechanismList correctly returned "
276                   "CKR_SLOT_ID_INVALID.");
277     rc = CKR_OK;
278 
279 testcase_cleanup:
280     if (mech_list)
281         free(mech_list);
282 
283     testcase_user_logout();
284     rc = funcs->C_CloseSession(session);
285     if (rc != CKR_OK)
286         testcase_error("C_CloseSessions failed.");
287 
288     return rc;
289 }
290 
do_GetMechanismInfo(void)291 CK_RV do_GetMechanismInfo(void)
292 {
293     CK_FLAGS flags = 0;
294     CK_SESSION_HANDLE session = 0;
295     CK_RV rc = 0;
296     CK_BYTE user_pin[PKCS11_MAX_PIN_LEN] = {0};
297     CK_ULONG user_pin_len = 0;
298     CK_SLOT_ID slot_id = SLOT_ID;
299     CK_MECHANISM_INFO info;
300     CK_ULONG i = 0, count = 0;
301     CK_MECHANISM_TYPE *mech_list = NULL;
302 
303     memset(&info, 0, sizeof(info));
304 
305     testcase_begin("testing C_GetMechanismInfo");
306     testcase_rw_session();
307     testcase_user_login();
308 
309     testcase_new_assertion();
310 
311     rc = funcs->C_GetMechanismList(slot_id, NULL, &count);
312     if (rc != CKR_OK) {
313         testcase_error("C_GetMechanismList #1 rc=%s", p11_get_ckr(rc));
314         return rc;
315     }
316 
317     mech_list = (CK_MECHANISM_TYPE *) calloc(1, count * sizeof(CK_MECHANISM_TYPE));
318     if (!mech_list) {
319         rc = CKR_HOST_MEMORY;
320         goto testcase_cleanup;
321     }
322 
323     rc = funcs->C_GetMechanismList(slot_id, mech_list, &count);
324     if (rc != CKR_OK) {
325         testcase_error("C_GetMechanismList #2 rc=%s", p11_get_ckr(rc));
326         goto testcase_cleanup;
327     }
328 
329     for (i = 0; i < count; i++) {
330         rc = funcs->C_GetMechanismInfo(slot_id, mech_list[i], &info);
331         if (rc != CKR_OK)
332             break;
333     }
334 
335     if (rc != CKR_OK)
336         testcase_fail("C_GetMechanismInfo rc=%s", p11_get_ckr(rc));
337     else
338         testcase_pass("C_GetMechanismInfo was successful.");
339 
340     testcase_new_assertion();
341 
342     rc = funcs->C_GetMechanismInfo(slot_id, 0x12345678, &info);
343 
344     if (rc != CKR_MECHANISM_INVALID)
345         testcase_fail("C_GetMechanismInfo returned rc=%s instead "
346                           "of CKR_MECHANISM_INVALID", p11_get_ckr(rc));
347     else
348         testcase_pass("C_GetMechanismInfo correctly returned CKR_MECHANISM_INVALID.");
349 
350 testcase_cleanup:
351     if (mech_list)
352         free(mech_list);
353 
354     testcase_user_logout();
355     rc = funcs->C_CloseSession(session);
356     if (rc != CKR_OK)
357         testcase_error("C_CloseSessions rc=%s", p11_get_ckr(rc));
358 
359     return rc;
360 }
361 
do_InitToken(void)362 CK_RV do_InitToken(void)
363 {
364     CK_BYTE label[32] = {0};
365     int len = 0;
366     CK_CHAR so_pin[PKCS11_MAX_PIN_LEN] = {0};
367     CK_RV rc = 0;
368 
369     testcase_begin("testing C_InitToken");
370 
371     memcpy(label, "L13                                   ", 32);
372     for (len = 0; len < 31; len++) {
373         if (label[len] == '\0') {
374             label[len] = ' ';
375             break;
376         }
377     }
378 
379     testcase_new_assertion();
380     /* test with invalid SO PIN */
381     rc = funcs->C_InitToken(SLOT_ID, NULL, strlen((char *) so_pin), label);
382     if (rc != CKR_ARGUMENTS_BAD) {
383         testcase_fail("C_InitToken returned %s instead of "
384                       "CKR_ARGUMENTS_BAD", p11_get_ckr(rc));
385         goto testcase_cleanup;
386     }
387 
388     testcase_pass("C_InitToken correctly return CKR_ARGUMENS_BAD.");
389 
390     /* test with invalid slot id */
391     testcase_new_assertion();
392     rc = funcs->C_InitToken(9999, so_pin, strlen((char *) so_pin), label);
393     if (rc != CKR_SLOT_ID_INVALID) {
394         testcase_fail("C_InitToken returned %s instead of "
395                       "CKR_SLOT_ID_INVALID.", p11_get_ckr(rc));
396         rc = CKR_FUNCTION_FAILED;
397     } else {
398         testcase_pass("C_InitToken correctly returned CKR_SLOT_ID_INVALID.");
399         rc = CKR_OK;
400     }
401 
402 testcase_cleanup:
403     return rc;
404 }
405 
do_InitPIN(void)406 CK_RV do_InitPIN(void)
407 {
408     CK_SLOT_ID slot_id;
409     CK_FLAGS flags;
410     CK_SESSION_HANDLE session;
411     CK_CHAR so_pin[PKCS11_MAX_PIN_LEN];
412     CK_CHAR user_pin[PKCS11_MAX_PIN_LEN];
413     CK_ULONG so_pin_len;
414     CK_ULONG user_pin_len;
415     CK_RV rc;
416 
417     testcase_begin("Testing C_InitPIN");
418 
419     if (get_user_pin(user_pin))
420         return CKR_FUNCTION_FAILED;
421 
422     user_pin_len = (CK_ULONG) strlen((char *) user_pin);
423 
424     if (get_so_pin(so_pin))
425         return CKR_FUNCTION_FAILED;
426 
427     so_pin_len = (CK_ULONG) strlen((char *) so_pin);
428 
429     slot_id = SLOT_ID;
430     flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
431 
432     // try to call C_InitPIN from a public session
433     testcase_new_assertion();
434     rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &session);
435     if (rc != CKR_OK) {
436         testcase_error("C_OpenSession rc=%s", p11_get_ckr(rc));
437         return rc;
438     }
439 
440     rc = funcs->C_InitPIN(session, user_pin, user_pin_len);
441     if (rc != CKR_USER_NOT_LOGGED_IN) {
442         testcase_fail("C_InitPIN returned %s instead of "
443                       "CKR_USER_NOT_LOGGED_IN", p11_get_ckr(rc));
444         goto testcase_cleanup;
445     }
446 
447     testcase_pass("C_InitPin correctly returned CKR_USER_NOT_LOGGED_IN.");
448 
449     // try to call C_InitPIN from an SO session
450     testcase_new_assertion();
451     rc = funcs->C_Login(session, CKU_SO, so_pin, so_pin_len);
452     if (rc != CKR_OK) {
453         testcase_error("C_Login #1 failed: rc=%s", p11_get_ckr(rc));
454         goto testcase_cleanup;
455     }
456 
457     rc = funcs->C_InitPIN(session, user_pin, user_pin_len);
458     if (rc != CKR_OK)
459         testcase_fail("C_InitPIN failed: rc=%s", p11_get_ckr(rc));
460     else
461         testcase_pass("C_InitPIN #1 was successful.");
462 
463     rc = funcs->C_Logout(session);
464     if (rc != CKR_OK) {
465         testcase_error("C_Logout #1 failed.");
466         goto testcase_cleanup;
467     }
468     // try to call C_InitPIN from a normal user session
469     testcase_new_assertion();
470     rc = funcs->C_Login(session, CKU_USER, user_pin, user_pin_len);
471     if (rc != CKR_OK) {
472         testcase_error("C_Login failed: rc=%s", p11_get_ckr(rc));
473         goto testcase_cleanup;
474     }
475 
476     rc = funcs->C_InitPIN(session, user_pin, user_pin_len);
477     if (rc != CKR_USER_NOT_LOGGED_IN) {
478         testcase_fail("C_InitPIN returned %s instead of "
479                       "CKR_USER_NOT_LOGGED_IN.", p11_get_ckr(rc));
480         rc = CKR_FUNCTION_FAILED;
481     } else {
482         testcase_pass("C_InitPIN #2 was successful.");
483         rc = CKR_OK;
484     }
485 
486     rc = funcs->C_Logout(session);
487     if (rc != CKR_OK)
488         testcase_error("C_Logout #2 rc=%s", p11_get_ckr(rc));
489 
490 testcase_cleanup:
491     rc = funcs->C_CloseAllSessions(slot_id);
492     if (rc != CKR_OK)
493         testcase_error("C_CloseAllSessions #1 rc=%s", p11_get_ckr(rc));
494 
495     return rc;
496 }
497 
do_SetPIN(void)498 CK_RV do_SetPIN(void)
499 {
500     CK_SLOT_ID slot_id;
501     CK_FLAGS flags;
502     CK_SESSION_HANDLE session;
503     CK_CHAR old_pin[PKCS11_MAX_PIN_LEN];
504     CK_CHAR new_pin[PKCS11_MAX_PIN_LEN];
505     CK_ULONG old_len;
506     CK_ULONG new_len;
507     CK_RV rc;
508 
509     testcase_begin("Testing C_SetPIN");
510 
511     // first, try to get the user PIN
512     if (get_user_pin(old_pin))
513         return CKR_FUNCTION_FAILED;
514 
515     old_len = (CK_ULONG) strlen((char *) old_pin);
516 
517     memcpy(new_pin, "ABCDEF", 6);
518     new_len = 6;
519 
520     slot_id = SLOT_ID;
521 
522     /* try to call C_SetPIN from a R/O public session, it should fail.
523      */
524     flags = CKF_SERIAL_SESSION;
525     testcase_new_assertion();
526     rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &session);
527     if (rc != CKR_OK) {
528         testcase_error("C_OpenSession #1 rc=%s", p11_get_ckr(rc));
529         return rc;
530     }
531 
532     rc = funcs->C_SetPIN(session, old_pin, old_len, new_pin, new_len);
533     if (rc != CKR_SESSION_READ_ONLY) {
534         testcase_fail("C_SetPIN #1 returned %s instead of "
535                       "CKR_SESSION_READ_ONLY.", p11_get_ckr(rc));
536         rc = CKR_FUNCTION_FAILED;
537         goto testcase_cleanup;
538     }
539 
540     testcase_pass("C_SetPIN successful in pubic session.");
541 
542     rc = funcs->C_CloseSession(session);
543     if (rc != CKR_OK) {
544         testcase_error("C_CloseSession #1 failed.");
545         goto testcase_cleanup;
546     }
547 
548     /* try to call C_SetPIN from a R/W public session, it should work.
549      */
550     testcase_new_assertion();
551 
552     flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
553     rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &session);
554     if (rc != CKR_OK) {
555         testcase_error("C_OpenSession #1 rc=%s", p11_get_ckr(rc));
556         return rc;
557     }
558 
559     rc = funcs->C_SetPIN(session, old_pin, old_len, new_pin, new_len);
560     if (rc != CKR_OK) {
561         testcase_fail("C_SetPIN failed: rc = %s", p11_get_ckr(rc));
562         goto testcase_cleanup;
563     }
564 
565     testcase_pass("C_SetPIN successful in r/w pubic session.");
566 
567     rc = funcs->C_CloseSession(session);
568     if (rc != CKR_OK) {
569         testcase_error("C_CloseSession #1 failed.");
570         goto testcase_cleanup;
571     }
572 
573     /* open a new session and try logging in with new pin */
574     flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
575     rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &session);
576     if (rc != CKR_OK) {
577         testcase_error("C_OpenSession #1 rc=%s", p11_get_ckr(rc));
578         return rc;
579     }
580 
581     testcase_new_assertion();
582 
583     rc = funcs->C_Login(session, CKU_USER, new_pin, new_len);
584     if (rc != CKR_OK) {
585         testcase_fail("C_Login #1 failed: rc=%s", p11_get_ckr(rc));
586         goto testcase_cleanup;
587     }
588 
589     testcase_pass("Successfully logged in with new pin.");
590 
591     /* try to call C_SetPIN from a normal user session, r/w user.
592      * set back to original user pin. this should work.
593      */
594     testcase_new_assertion();
595 
596     rc = funcs->C_SetPIN(session, new_pin, new_len, old_pin, old_len);
597     if (rc != CKR_OK) {
598         testcase_fail("C_SetPIN #2 rc=%s", p11_get_ckr(rc));
599         goto testcase_cleanup;
600     }
601 
602     testcase_pass("C_SetPIN successful.");
603 
604     rc = funcs->C_Logout(session);
605     if (rc != CKR_OK) {
606         testcase_error("C_Logout #1 falied: rc=%s", p11_get_ckr(rc));
607         goto testcase_cleanup;
608     }
609 
610     /*
611      *  done with user tests...now try with the SO
612      */
613 
614     if (get_so_pin(old_pin))
615         return CKR_FUNCTION_FAILED;
616 
617     /* try to call C_SetPIN from a normal user session */
618     testcase_new_assertion();
619 
620     rc = funcs->C_Login(session, CKU_SO, old_pin, old_len);
621     if (rc != CKR_OK) {
622         testcase_error("C_Login #3failed: rc=%s", p11_get_ckr(rc));
623         goto testcase_cleanup;
624     }
625 
626     rc = funcs->C_SetPIN(session, old_pin, old_len, new_pin, new_len);
627     if (rc != CKR_OK) {
628         testcase_fail("C_SetPIN #4 failed: rc=%s", p11_get_ckr(rc));
629         goto testcase_cleanup;
630     }
631 
632     testcase_pass("C_SetPIN successfully set SO PIN.");
633 
634     rc = funcs->C_Logout(session);
635     if (rc != CKR_OK) {
636         testcase_error("C_Logout #3 failed.");
637         goto testcase_cleanup;
638     }
639 
640     /* now login with new pin. should work. */
641     testcase_new_assertion();
642 
643     rc = funcs->C_Login(session, CKU_SO, new_pin, new_len);
644     if (rc != CKR_OK)
645         testcase_fail("C_Login #5 failed: rc=%s", p11_get_ckr(rc));
646     else
647         testcase_pass("C_Login #5 was successful.");
648 
649     /* change the PIN back to the original so the rest of this program
650      * doesn't break
651      */
652     rc = funcs->C_SetPIN(session, new_pin, new_len, old_pin, old_len);
653     if (rc != CKR_OK)
654         testcase_error("C_SetPIN #5 failed to set back to the original "
655                        "SO PIN, rc=%s", p11_get_ckr(rc));
656 
657     rc = funcs->C_Logout(session);
658     if (rc != CKR_OK)
659         testcase_error("C_Logout #4 failed.");
660 
661 testcase_cleanup:
662     rc = funcs->C_CloseSession(session);
663     if (rc != CKR_OK)
664         testcase_error("C_CloseSession #1 failed.");
665 
666     return rc;
667 }
668 
669 
api_driver(void)670 CK_RV api_driver(void)
671 {
672     CK_RV rc;
673 
674     rc = do_GetInfo();
675     if (rc && !no_stop)
676         return rc;
677 
678     rc = do_GetSlotList();
679     if (rc && !no_stop)
680         return rc;
681 
682     rc = do_GetSlotInfo();
683     if (rc && !no_stop)
684         return rc;
685 
686     rc = do_GetTokenInfo();
687     if (rc && !no_stop)
688         return rc;
689 
690     rc = do_GetMechanismList();
691     if (rc && !no_stop)
692         return rc;
693 
694     rc = do_GetMechanismInfo();
695     if (rc && !no_stop)
696         return rc;
697 
698     /* do not run on icsf token */
699     if (!is_icsf_token(SLOT_ID)) {
700         rc = do_InitToken();
701         if (rc && !no_stop)
702             return rc;
703     }
704 
705     rc = do_InitPIN();
706     if (rc && !no_stop)
707         return rc;
708 
709     rc = do_SetPIN();
710     if (rc && !no_stop)
711         return rc;
712 
713     return rc;
714 }
715 
main(int argc,char ** argv)716 int main(int argc, char **argv)
717 {
718     int rc;
719     CK_C_INITIALIZE_ARGS cinit_args;
720     CK_RV rv = 0;
721 
722     rc = do_ParseArgs(argc, argv);
723     if (rc != 1)
724         return rc;
725 
726     printf("Using slot #%lu...\n\n", SLOT_ID);
727     printf("With option: nostop: %d\n", no_stop);
728 
729     rc = do_GetFunctionList();
730     if (!rc) {
731         testcase_error("do_getFunctionList(), rc=%s", p11_get_ckr(rc));
732         return rc;
733     }
734 
735     memset(&cinit_args, 0x0, sizeof(cinit_args));
736     cinit_args.flags = CKF_OS_LOCKING_OK;
737 
738     funcs->C_Initialize(&cinit_args);
739 
740     {
741         CK_SESSION_HANDLE hsess = 0;
742 
743         rc = funcs->C_GetFunctionStatus(hsess);
744         if (rc != CKR_FUNCTION_NOT_PARALLEL)
745             return rc;
746 
747         rc = funcs->C_CancelFunction(hsess);
748         if (rc != CKR_FUNCTION_NOT_PARALLEL)
749             return rc;
750     }
751 
752     testcase_setup(0);
753     rv = api_driver();
754     testcase_print_result();
755 
756     funcs->C_Finalize(NULL_PTR);
757 
758     /* make sure we return non-zero if rv is non-zero */
759     return ((rv == 0) || (rv % 256) ? (int)rv : -1);
760 }
761