1 /* ****************************************************************************
2
3 * eID Middleware Project.
4 * Copyright (C) 2014 FedICT.
5 *
6 * This is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License version
8 * 3.0 as published by the Free Software Foundation.
9 *
10 * This software is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this software; if not, see
17 * http://www.gnu.org/licenses/.
18
19 **************************************************************************** */
20 #ifdef WIN32
21 #include <win32.h>
22 #pragma pack(push, cryptoki, 1)
23 #include "pkcs11.h"
24 #pragma pack(pop, cryptoki)
25 #else
26 #include <unix.h>
27 #include <pkcs11.h>
28 #endif
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include "testlib.h"
33
34 #define HAS_CKM(ckm, crit_rsa, crit_ecdsa) case ckm: { printf("Found " #ckm "\n"); known_mechs++; if(crit_rsa) rsa_mechs++; if(crit_ecdsa) ecdsa_mechs++; } break;
35
TEST_FUNC(mechlist)36 TEST_FUNC(mechlist) {
37 CK_SLOT_ID slot;
38 CK_ULONG count=0;
39 CK_MECHANISM_TYPE_PTR mechlist;
40 CK_ULONG known_mechs = 0;
41 int rsa_mechs = 0;
42 int ecdsa_mechs = 0;
43 unsigned int i;
44 int ret;
45 int retval = TEST_RV_OK;
46 ckrv_mod m_small[] = {
47 { CKR_BUFFER_TOO_SMALL, TEST_RV_OK },
48 { CKR_OK, TEST_RV_FAIL },
49 };
50 ckrv_mod m_p11_ntoken[] = {
51 { CKR_TOKEN_NOT_PRESENT, TEST_RV_OK },
52 { CKR_FUNCTION_FAILED, TEST_RV_OK },
53 { CKR_OK, TEST_RV_FAIL },
54 };
55
56 check_rv_long(C_GetMechanismList(0, NULL_PTR, &count), m_p11_noinit);
57
58 check_rv(C_Initialize(NULL_PTR));
59
60 if((ret = find_slot(CK_TRUE, &slot)) != TEST_RV_OK) {
61 check_rv(C_Finalize(NULL_PTR));
62 return ret;
63 }
64
65 check_rv(C_GetMechanismList(slot, NULL_PTR, &count));
66 mechlist = malloc(sizeof(CK_MECHANISM_TYPE) * count);
67 printf("number of mechanisms supported: %lu\n", count);
68
69 for(i=0; i<count; i++) {
70 mechlist[i] = 0xdeadbeef;
71 }
72
73 check_rv(C_GetMechanismList(slot, mechlist, &count));
74 if(count == 0) {
75 printf("Token supports no mechanisms!\n");
76 retval = TEST_RV_FAIL;
77 goto done;
78 }
79
80 for(i=0; i<count; i++) {
81 unsigned long temp = i+1;
82
83 switch(mechlist[i]) {
84 HAS_CKM(CKM_RSA_PKCS, 1, 0);
85 HAS_CKM(CKM_RIPEMD160, 0, 0);
86 HAS_CKM(CKM_MD5, 0, 0);
87 HAS_CKM(CKM_SHA_1, 0, 0);
88 HAS_CKM(CKM_SHA256, 0, 0);
89 HAS_CKM(CKM_SHA384, 0, 0);
90 HAS_CKM(CKM_SHA512, 0, 0);
91 HAS_CKM(CKM_RIPEMD160_RSA_PKCS, 1, 0);
92 HAS_CKM(CKM_MD5_RSA_PKCS, 1, 0);
93 HAS_CKM(CKM_SHA1_RSA_PKCS, 1, 0);
94 HAS_CKM(CKM_SHA1_RSA_PKCS_PSS, 0, 0);
95 HAS_CKM(CKM_SHA256_RSA_PKCS, 1, 0);
96 HAS_CKM(CKM_SHA256_RSA_PKCS_PSS, 1, 0);
97 HAS_CKM(CKM_SHA384_RSA_PKCS, 1, 0);
98 HAS_CKM(CKM_SHA512_RSA_PKCS, 1, 0);
99 HAS_CKM(CKM_ECDSA, 0, 1);
100 HAS_CKM(CKM_ECDSA_SHA1, 0, 0);
101 HAS_CKM(CKM_ECDSA_SHA256, 0, 1);
102 HAS_CKM(CKM_ECDSA_SHA384, 0, 1);
103 HAS_CKM(CKM_ECDSA_SHA512, 0, 1);
104 case 0xdeadbeef:
105 printf("E: found uninitialized data\n");
106 retval = TEST_RV_FAIL;
107 goto done;
108 default:
109 printf("Found unknown mechanism %#08lx\n", mechlist[i]);
110 break;
111 }
112 if(i<(count-1)) {
113 check_rv_long(C_GetMechanismList(slot, mechlist, &temp), m_small);
114 } else {
115 check_rv(C_GetMechanismList(slot, mechlist, &temp));
116 }
117 }
118
119 if(count == known_mechs) {
120 printf("INFO: no unknown mechanisms found\n");
121 } else {
122 if(count > known_mechs) {
123 printf("INFO: %lu unknown mechanisms found\n", count - known_mechs);
124 } else {
125 fprintf(stderr, "E: something weird happened");
126 retval = TEST_RV_FAIL;
127 goto done;
128 }
129 }
130
131 verbose_assert(count == known_mechs);
132 verbose_assert(rsa_mechs == 7 || rsa_mechs == 8 || ecdsa_mechs == 4);
133
134 check_rv_long(C_GetMechanismList(slot+30, mechlist, &count), m_p11_badslot);
135
136 if(have_robot()) {
137 robot_remove_card();
138 check_rv_long(C_GetMechanismList(slot, mechlist, &count), m_p11_ntoken);
139 }
140
141 check_rv(C_Finalize(NULL_PTR));
142
143 done:
144 free(mechlist);
145
146 return retval;
147 }
148