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 
31 #include "testlib.h"
32 
33 #define ADD_CKO(cko) ckos[cko] = #cko
34 
TEST_FUNC(objects)35 TEST_FUNC(objects) {
36 	CK_SESSION_HANDLE session;
37 	CK_OBJECT_HANDLE object;
38 	CK_ULONG count;
39 	CK_SLOT_ID slot;
40 	CK_ATTRIBUTE attr[2];
41 	CK_ATTRIBUTE invalid[1];
42 	CK_OBJECT_CLASS klass;
43 
44 	char label[1024];
45 	char* ckos[8];
46 	int ret;
47 	ckrv_mod m[] = {
48 		{ CKR_OK, TEST_RV_FAIL },
49 		{ CKR_OPERATION_ACTIVE, TEST_RV_OK },
50 	};
51 	ckrv_mod m_inv[] = {
52 		{ CKR_ATTRIBUTE_TYPE_INVALID, TEST_RV_OK },
53 		{ CKR_OK, TEST_RV_FAIL },
54 	};
55 
56 	ADD_CKO(CKO_DATA);
57 	ADD_CKO(CKO_CERTIFICATE);
58 	ADD_CKO(CKO_PUBLIC_KEY);
59 	ADD_CKO(CKO_PRIVATE_KEY);
60 	ADD_CKO(CKO_SECRET_KEY);
61 	ADD_CKO(CKO_HW_FEATURE);
62 	ADD_CKO(CKO_DOMAIN_PARAMETERS);
63 	ADD_CKO(CKO_MECHANISM);
64 
65 	check_rv(C_Initialize(NULL_PTR));
66 
67 	if((ret = find_slot(CK_TRUE, &slot)) != TEST_RV_OK) {
68 		check_rv(C_Finalize(NULL_PTR));
69 		return ret;
70 	}
71 
72 	check_rv(C_OpenSession(slot, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session));
73 
74 	check_rv(C_FindObjectsInit(session, NULL_PTR, 0));
75 
76 	do {
77 		check_rv(C_FindObjects(session, &object, 1, &count));
78 
79 		if(!count) continue;
80 
81 		attr[0].type = CKA_CLASS;
82 		attr[0].pValue = &klass;
83 		attr[0].ulValueLen=sizeof(klass);
84 
85 		attr[1].type = CKA_LABEL;
86 		attr[1].pValue = &label;
87 		attr[1].ulValueLen=1024;
88 
89 		invalid[0].type = CKA_OBJECT_ID;
90 		invalid[0].pValue = NULL_PTR;
91 		invalid[0].ulValueLen = 0;
92 
93 		check_rv(C_GetAttributeValue(session, object, attr, 2));
94 
95 		check_rv_long(C_GetAttributeValue(session, object, invalid, 1), m_inv);
96 
97 		label[attr[1].ulValueLen] = '\0';
98 
99 		printf("Found object %lx (label: %s) of class %s (%#lx)\n", object, label, ckos[klass], klass);
100 		verbose_assert(klass == CKO_CERTIFICATE || klass == CKO_PUBLIC_KEY || klass == CKO_PRIVATE_KEY);
101 	} while(count);
102 
103 	check_rv_long(C_FindObjectsInit(session, NULL_PTR, 0), m);
104 
105 	check_rv(C_FindObjectsFinal(session));
106 
107 	check_rv(C_CloseSession(session));
108 
109 	check_rv(C_OpenSession(slot, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session));
110 
111 	check_rv(C_FindObjectsInit(session, NULL_PTR, 0));
112 
113 	check_rv(C_CloseSession(session));
114 
115 	check_rv(C_OpenSession(slot, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session));
116 
117 	check_rv(C_FindObjectsInit(session, NULL_PTR, 0));
118 
119 	check_rv(C_CloseSession(session));
120 
121 	check_rv(C_OpenSession(slot, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session));
122 
123 	if(have_robot()) {
124 		ckrv_mod m_maybe_rmvd[] = {
125 			{ CKR_TOKEN_NOT_PRESENT, TEST_RV_OK },
126 			{ CKR_DEVICE_REMOVED, TEST_RV_OK},
127 		};
128 		ckrv_mod m_is_rmvd[] = {
129 			{ CKR_OK, TEST_RV_FAIL },
130 			{ CKR_TOKEN_NOT_PRESENT, TEST_RV_OK },
131 			{ CKR_DEVICE_REMOVED, TEST_RV_OK },
132 		};
133 		ckrv_mod m_inv[] = {
134 			{ CKR_OK, TEST_RV_FAIL },
135 			{ CKR_DEVICE_REMOVED, TEST_RV_OK },	// really?!?
136 			{ CKR_SESSION_HANDLE_INVALID, TEST_RV_OK },
137 		};
138 
139 		check_rv(C_FindObjectsInit(session, NULL_PTR, 0));
140 
141 		robot_remove_card();
142 
143 		check_rv_long(C_FindObjects(session, &object, 1, &count), m_maybe_rmvd);
144 
145 		check_rv_long(C_GetAttributeValue(session, object, attr, 1), m_is_rmvd);
146 
147 		if((ret = find_slot(CK_TRUE, &slot)) != TEST_RV_OK) {
148 			check_rv(C_Finalize(NULL_PTR));
149 			return ret;
150 		}
151 
152 		check_rv_long(C_FindObjectsInit(session, NULL_PTR, 0), m_inv);
153 
154 		check_rv(C_CloseSession(session));
155 
156 		check_rv(C_OpenSession(slot, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session));
157 
158 		check_rv(C_FindObjectsInit(session, NULL_PTR, 0));
159 	} else {
160 		printf("Robot not present, skipping card removal/insertion part of test...\n");
161 	}
162 
163 	check_rv(C_Finalize(NULL_PTR));
164 
165 	return TEST_RV_OK;
166 }
167