1 /*
2  * Copyright (c) 2012 SURFnet
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 /*****************************************************************************
28  ObjectTests.cpp
29 
30  Contains test cases for:
31 	 C_CreateObject
32 	 C_CopyObject
33 	 C_DestroyObject
34 	 C_GetAttributeValue
35 	 C_SetAttributeValue
36 	 C_FindObjectsInit
37 	 C_FindObjects
38 	 C_FindObjectsFinal
39 	 C_GenererateKeyPair
40 
41  Below is a list of tests we need to add in order to verify that the PKCS#11 library
42  is working as expected.
43 
44  We want to be sure that order of attributes does not impact the tests, therefore
45  every function involving attributes should have the order of the attributes
46  in the template randomized.
47 
48  We want to be sure that only attributes that are specified as being part of an
49  object class can be used when creating an object.
50  Using other attributes should return an error on creation of the object.
51 
52  We want to be sure that attributes that are required but missing will result
53  in a template incomplete return value.
54 
55  We want to be sure that we get an error when trying to modify an attribute that
56  may not be modified
57 
58  We want to be sure that attributes that may be changed to one value but not
59  back to the previous value are handled correctly.
60 
61  We want to verify that an error is returned when we are trying to modify
62  read-only attributes.
63 
64  We want to verify that sensitive attributes cannot be read.
65 
66  Because the teardown also removes token objects it is not really
67  required to destroy objects created during the test in the CreateObject tests.
68 
69  *****************************************************************************/
70 
71 #include <config.h>
72 #include <stdlib.h>
73 #include <string.h>
74 #include "ObjectTests.h"
75 
76 // Common object attributes
77 const CK_BBOOL CKA_TOKEN_DEFAULT = CK_FALSE;
78 //const CK_BBOOL CKA_PRIVATE_DEFAULT = <token/object attribute dependent>
79 const CK_BBOOL CKA_MODIFIABLE_DEFAULT = CK_TRUE;
80 const CK_UTF8CHAR_PTR CKA_LABEL_DEFAULT = NULL;
81 const CK_BBOOL CKA_COPYABLE_DEFAULT = CK_TRUE;
82 const CK_BBOOL CKA_DESTROYABLE_DEFAULT = CK_TRUE;
83 
84 // Data Object Attributes
85 const CK_UTF8CHAR_PTR CKA_APPLICATION_DEFAULT = NULL;
86 const CK_BYTE_PTR CKA_OBJECT_ID_DEFAULT = NULL;
87 const CK_BYTE_PTR CKA_VALUE_DEFAULT = NULL;
88 
89 // CKA_TOKEN
90 const CK_BBOOL ON_TOKEN = CK_TRUE;
91 const CK_BBOOL IN_SESSION = CK_FALSE;
92 
93 // CKA_PRIVATE
94 const CK_BBOOL IS_PRIVATE = CK_TRUE;
95 const CK_BBOOL IS_PUBLIC = CK_FALSE;
96 
97 
98 CPPUNIT_TEST_SUITE_REGISTRATION(ObjectTests);
99 
checkCommonObjectAttributes(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_OBJECT_CLASS objClass)100 void ObjectTests::checkCommonObjectAttributes(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_OBJECT_CLASS objClass)
101 {
102 	CK_RV rv;
103 
104 	CK_OBJECT_CLASS obj_class = CKO_VENDOR_DEFINED;
105 	CK_ATTRIBUTE attribs[] = {
106 		{ CKA_CLASS, &obj_class, sizeof(obj_class) }
107 	};
108 
109 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 1) );
110 	CPPUNIT_ASSERT(rv == CKR_OK);
111 	CPPUNIT_ASSERT(obj_class == objClass);
112 }
113 
checkCommonStorageObjectAttributes(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_BBOOL bToken,CK_BBOOL,CK_BBOOL bModifiable,CK_UTF8CHAR_PTR pLabel,CK_ULONG ulLabelLen,CK_BBOOL bCopyable,CK_BBOOL bDestroyable)114 void ObjectTests::checkCommonStorageObjectAttributes(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_BBOOL bToken, CK_BBOOL /*bPrivate*/, CK_BBOOL bModifiable, CK_UTF8CHAR_PTR pLabel, CK_ULONG ulLabelLen, CK_BBOOL bCopyable, CK_BBOOL bDestroyable)
115 {
116 	CK_RV rv;
117 
118 	CK_BBOOL obj_token = CK_FALSE;
119 	CK_BBOOL obj_private = CK_FALSE;
120 	CK_BBOOL obj_modifiable = CK_FALSE;
121 	CK_BBOOL obj_copyable = CK_FALSE;
122 	CK_BBOOL obj_destroyable = CK_FALSE;
123 	CK_ATTRIBUTE attribs[] = {
124 		{ CKA_LABEL, NULL_PTR, 0 },
125 		{ CKA_TOKEN, &obj_token, sizeof(obj_token) },
126 		{ CKA_PRIVATE, &obj_private, sizeof(obj_private) },
127 		{ CKA_MODIFIABLE, &obj_modifiable, sizeof(obj_modifiable) },
128 		{ CKA_COPYABLE, &obj_copyable, sizeof(obj_copyable) },
129 		{ CKA_DESTROYABLE, &obj_destroyable, sizeof(obj_destroyable) }
130 	};
131 
132 	// Get length
133 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 1) );
134 	CPPUNIT_ASSERT(rv == CKR_OK);
135 	attribs[0].pValue = (CK_VOID_PTR)malloc(attribs[0].ulValueLen);
136 
137 	// Check values
138 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 6) );
139 	CPPUNIT_ASSERT(rv == CKR_OK);
140 	CPPUNIT_ASSERT(attribs[0].ulValueLen == ulLabelLen);
141 	CPPUNIT_ASSERT(obj_token == bToken);
142 	/* Default is token-specifict
143 	CPPUNIT_ASSERT(obj_private == bPrivate); */
144 	CPPUNIT_ASSERT(obj_modifiable == bModifiable);
145 	CPPUNIT_ASSERT(obj_copyable == bCopyable);
146 	CPPUNIT_ASSERT(obj_destroyable == bDestroyable);
147 	if (ulLabelLen > 0)
148 		CPPUNIT_ASSERT(memcmp(attribs[0].pValue, pLabel, ulLabelLen) == 0);
149 
150 	free(attribs[0].pValue);
151 }
152 
checkDataObjectAttributes(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_UTF8CHAR_PTR pApplication,CK_ULONG ulApplicationLen,CK_BYTE_PTR pObjectID,CK_ULONG ulObjectIdLen,CK_BYTE_PTR pValue,CK_ULONG ulValueLen)153 void ObjectTests::checkDataObjectAttributes(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_UTF8CHAR_PTR pApplication, CK_ULONG ulApplicationLen, CK_BYTE_PTR pObjectID, CK_ULONG ulObjectIdLen, CK_BYTE_PTR pValue, CK_ULONG ulValueLen)
154 {
155 	CK_RV rv;
156 
157 	CK_ATTRIBUTE attribs[] = {
158 		{ CKA_APPLICATION, NULL_PTR, 0 },
159 		{ CKA_OBJECT_ID, NULL_PTR, 0 },
160 		{ CKA_VALUE, NULL_PTR, 0 }
161 	};
162 
163 	// Get length
164 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 3) );
165 	CPPUNIT_ASSERT(rv == CKR_OK);
166 	attribs[0].pValue = (CK_VOID_PTR)malloc(attribs[0].ulValueLen);
167 	attribs[1].pValue = (CK_VOID_PTR)malloc(attribs[1].ulValueLen);
168 	attribs[2].pValue = (CK_VOID_PTR)malloc(attribs[2].ulValueLen);
169 
170 	// Check values
171 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 3) );
172 	CPPUNIT_ASSERT(rv == CKR_OK);
173 	CPPUNIT_ASSERT(attribs[0].ulValueLen == ulApplicationLen);
174 	CPPUNIT_ASSERT(attribs[1].ulValueLen == ulObjectIdLen);
175 	CPPUNIT_ASSERT(attribs[2].ulValueLen == ulValueLen);
176 	if (ulApplicationLen > 0)
177 		CPPUNIT_ASSERT(memcmp(attribs[0].pValue, pApplication, ulApplicationLen) == 0);
178 	if (ulObjectIdLen > 0)
179 		CPPUNIT_ASSERT(memcmp(attribs[1].pValue, pObjectID, ulObjectIdLen) == 0);
180 	if (ulValueLen > 0)
181 		CPPUNIT_ASSERT(memcmp(attribs[2].pValue, pValue, ulValueLen) == 0);
182 
183 	free(attribs[0].pValue);
184 	free(attribs[1].pValue);
185 	free(attribs[2].pValue);
186 }
187 
checkCommonCertificateObjectAttributes(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_CERTIFICATE_TYPE certType,CK_BBOOL bTrusted,CK_ULONG ulCertificateCategory,CK_BYTE_PTR pCheckValue,CK_ULONG ulCheckValueLen,CK_DATE startDate,CK_ULONG ulStartDateLen,CK_DATE endDate,CK_ULONG ulEndDateLen)188 void ObjectTests::checkCommonCertificateObjectAttributes(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_CERTIFICATE_TYPE certType, CK_BBOOL bTrusted, CK_ULONG ulCertificateCategory, CK_BYTE_PTR pCheckValue, CK_ULONG ulCheckValueLen, CK_DATE startDate, CK_ULONG ulStartDateLen, CK_DATE endDate, CK_ULONG ulEndDateLen)
189 {
190 	CK_RV rv;
191 
192 	CK_CERTIFICATE_TYPE obj_type = CKC_X_509;
193 	CK_BBOOL obj_trusted = CK_FALSE;
194 	CK_ULONG obj_category = 0;
195 	CK_DATE obj_start;
196 	CK_DATE obj_end;
197 	CK_ATTRIBUTE attribs[] = {
198 		{ CKA_CHECK_VALUE, NULL_PTR, 0 },
199 		{ CKA_CERTIFICATE_TYPE, &obj_type, sizeof(obj_type) },
200 		{ CKA_TRUSTED, &obj_trusted, sizeof(obj_trusted) },
201 		{ CKA_CERTIFICATE_CATEGORY, &obj_category, sizeof(obj_category) },
202 		{ CKA_START_DATE, &obj_start, sizeof(obj_start) },
203 		{ CKA_END_DATE, &obj_end, sizeof(obj_end) }
204 	};
205 
206 	// Get length
207 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 1) );
208 	CPPUNIT_ASSERT(rv == CKR_OK);
209 	attribs[0].pValue = (CK_VOID_PTR)malloc(attribs[0].ulValueLen);
210 
211 	// Check values
212 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 6) );
213 	CPPUNIT_ASSERT(rv == CKR_OK);
214 	CPPUNIT_ASSERT(attribs[0].ulValueLen == ulCheckValueLen);
215 	CPPUNIT_ASSERT(obj_type == certType);
216 	CPPUNIT_ASSERT(obj_trusted == bTrusted);
217 	CPPUNIT_ASSERT(obj_category == ulCertificateCategory);
218 	CPPUNIT_ASSERT(attribs[4].ulValueLen == ulStartDateLen);
219 	CPPUNIT_ASSERT(attribs[5].ulValueLen == ulEndDateLen);
220 	if (ulCheckValueLen > 0)
221 		CPPUNIT_ASSERT(memcmp(attribs[0].pValue, pCheckValue, ulCheckValueLen) == 0);
222 	if (ulStartDateLen > 0)
223 		CPPUNIT_ASSERT(memcmp(attribs[4].pValue, &startDate, ulStartDateLen) == 0);
224 	if (ulEndDateLen > 0)
225 		CPPUNIT_ASSERT(memcmp(attribs[5].pValue, &endDate, ulEndDateLen) == 0);
226 
227 	free(attribs[0].pValue);
228 }
229 
checkX509CertificateObjectAttributes(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_BYTE_PTR pSubject,CK_ULONG ulSubjectLen,CK_BYTE_PTR pId,CK_ULONG ulIdLen,CK_BYTE_PTR pIssuer,CK_ULONG ulIssuerLen,CK_BYTE_PTR pSerialNumber,CK_ULONG ulSerialNumberLen,CK_BYTE_PTR pValue,CK_ULONG ulValueLen,CK_BYTE_PTR pUrl,CK_ULONG ulUrlLen,CK_BYTE_PTR pHashOfSubjectPublicKey,CK_ULONG ulHashOfSubjectPublicKeyLen,CK_BYTE_PTR pHashOfIssuerPublicKey,CK_ULONG ulHashOfIssuerPublicKeyLen,CK_ULONG ulJavaMidpSecurityDomain,CK_MECHANISM_TYPE nameHashAlgorithm)230 void ObjectTests::checkX509CertificateObjectAttributes(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_BYTE_PTR pSubject, CK_ULONG ulSubjectLen, CK_BYTE_PTR pId, CK_ULONG ulIdLen, CK_BYTE_PTR pIssuer, CK_ULONG ulIssuerLen, CK_BYTE_PTR pSerialNumber, CK_ULONG ulSerialNumberLen, CK_BYTE_PTR pValue, CK_ULONG ulValueLen, CK_BYTE_PTR pUrl, CK_ULONG ulUrlLen, CK_BYTE_PTR pHashOfSubjectPublicKey, CK_ULONG ulHashOfSubjectPublicKeyLen, CK_BYTE_PTR pHashOfIssuerPublicKey, CK_ULONG ulHashOfIssuerPublicKeyLen, CK_ULONG ulJavaMidpSecurityDomain, CK_MECHANISM_TYPE nameHashAlgorithm)
231 {
232 	CK_RV rv;
233 
234 	CK_ULONG obj_java = 0;
235 	CK_MECHANISM_TYPE obj_mech = CKM_VENDOR_DEFINED;
236 	CK_ATTRIBUTE attribs[] = {
237 		{ CKA_SUBJECT, NULL_PTR, 0 },
238 		{ CKA_ID, NULL_PTR, 0 },
239 		{ CKA_ISSUER, NULL_PTR, 0 },
240 		{ CKA_SERIAL_NUMBER, NULL_PTR, 0 },
241 		{ CKA_VALUE, NULL_PTR, 0 },
242 		{ CKA_URL, NULL_PTR, 0 },
243 		{ CKA_HASH_OF_SUBJECT_PUBLIC_KEY, NULL_PTR, 0 },
244 		{ CKA_HASH_OF_ISSUER_PUBLIC_KEY, NULL_PTR, 0 },
245 		{ CKA_JAVA_MIDP_SECURITY_DOMAIN, &obj_java, sizeof(obj_java) },
246 		{ CKA_NAME_HASH_ALGORITHM, &obj_mech, sizeof(obj_mech) }
247 	};
248 
249 	// Get length
250 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 8) );
251 	CPPUNIT_ASSERT(rv == CKR_OK);
252 	attribs[0].pValue = (CK_VOID_PTR)malloc(attribs[0].ulValueLen);
253 	attribs[1].pValue = (CK_VOID_PTR)malloc(attribs[1].ulValueLen);
254 	attribs[2].pValue = (CK_VOID_PTR)malloc(attribs[2].ulValueLen);
255 	attribs[3].pValue = (CK_VOID_PTR)malloc(attribs[3].ulValueLen);
256 	attribs[4].pValue = (CK_VOID_PTR)malloc(attribs[4].ulValueLen);
257 	attribs[5].pValue = (CK_VOID_PTR)malloc(attribs[5].ulValueLen);
258 	attribs[6].pValue = (CK_VOID_PTR)malloc(attribs[6].ulValueLen);
259 	attribs[7].pValue = (CK_VOID_PTR)malloc(attribs[7].ulValueLen);
260 
261 	// Check values
262 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 10) );
263 	CPPUNIT_ASSERT(rv == CKR_OK);
264 	CPPUNIT_ASSERT(attribs[0].ulValueLen == ulSubjectLen);
265 	CPPUNIT_ASSERT(attribs[1].ulValueLen == ulIdLen);
266 	CPPUNIT_ASSERT(attribs[2].ulValueLen == ulIssuerLen);
267 	CPPUNIT_ASSERT(attribs[3].ulValueLen == ulSerialNumberLen);
268 	CPPUNIT_ASSERT(attribs[4].ulValueLen == ulValueLen);
269 	CPPUNIT_ASSERT(attribs[5].ulValueLen == ulUrlLen);
270 	CPPUNIT_ASSERT(attribs[6].ulValueLen == ulHashOfSubjectPublicKeyLen);
271 	CPPUNIT_ASSERT(attribs[7].ulValueLen == ulHashOfIssuerPublicKeyLen);
272 	CPPUNIT_ASSERT(obj_java == ulJavaMidpSecurityDomain);
273 	CPPUNIT_ASSERT(obj_mech == nameHashAlgorithm);
274 	if (ulSubjectLen > 0)
275 		CPPUNIT_ASSERT(memcmp(attribs[0].pValue, pSubject, ulSubjectLen) == 0);
276 	if (ulIdLen > 0)
277 		CPPUNIT_ASSERT(memcmp(attribs[1].pValue, pId, ulIdLen) == 0);
278 	if (ulIssuerLen > 0)
279 		CPPUNIT_ASSERT(memcmp(attribs[2].pValue, pIssuer, ulIssuerLen) == 0);
280 	if (ulSerialNumberLen > 0)
281 		CPPUNIT_ASSERT(memcmp(attribs[3].pValue, pSerialNumber, ulSerialNumberLen) == 0);
282 	if (ulValueLen > 0)
283 		CPPUNIT_ASSERT(memcmp(attribs[4].pValue, pValue, ulValueLen) == 0);
284 	if (ulUrlLen > 0)
285 		CPPUNIT_ASSERT(memcmp(attribs[5].pValue, pUrl, ulUrlLen) == 0);
286 	if (ulHashOfSubjectPublicKeyLen > 0)
287 		CPPUNIT_ASSERT(memcmp(attribs[6].pValue, pHashOfSubjectPublicKey, ulHashOfSubjectPublicKeyLen) == 0);
288 	if (ulHashOfIssuerPublicKeyLen > 0)
289 		CPPUNIT_ASSERT(memcmp(attribs[7].pValue, pHashOfIssuerPublicKey, ulHashOfIssuerPublicKeyLen) == 0);
290 
291 	free(attribs[0].pValue);
292 	free(attribs[1].pValue);
293 	free(attribs[2].pValue);
294 	free(attribs[3].pValue);
295 	free(attribs[4].pValue);
296 	free(attribs[5].pValue);
297 	free(attribs[6].pValue);
298 	free(attribs[7].pValue);
299 }
300 
checkCommonKeyAttributes(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_KEY_TYPE keyType,CK_BYTE_PTR pId,CK_ULONG ulIdLen,CK_DATE startDate,CK_ULONG ulStartDateLen,CK_DATE endDate,CK_ULONG ulEndDateLen,CK_BBOOL bDerive,CK_BBOOL bLocal,CK_MECHANISM_TYPE keyMechanismType,CK_MECHANISM_TYPE_PTR pAllowedMechanisms,CK_ULONG ulAllowedMechanismsLen)301 void ObjectTests::checkCommonKeyAttributes(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_KEY_TYPE keyType, CK_BYTE_PTR pId, CK_ULONG ulIdLen, CK_DATE startDate, CK_ULONG ulStartDateLen, CK_DATE endDate, CK_ULONG ulEndDateLen, CK_BBOOL bDerive, CK_BBOOL bLocal, CK_MECHANISM_TYPE keyMechanismType, CK_MECHANISM_TYPE_PTR pAllowedMechanisms, CK_ULONG ulAllowedMechanismsLen)
302 {
303 	CK_RV rv;
304 
305 	CK_KEY_TYPE obj_type = CKK_VENDOR_DEFINED;
306 	CK_DATE obj_start;
307 	CK_DATE obj_end;
308 	CK_BBOOL obj_derive = CK_FALSE;
309 	CK_BBOOL obj_local = CK_FALSE;
310 	CK_MECHANISM_TYPE obj_mech = CKM_VENDOR_DEFINED;
311 	CK_ATTRIBUTE attribs[] = {
312 		{ CKA_ID, NULL_PTR, 0 },
313 		{ CKA_KEY_TYPE, &obj_type, sizeof(obj_type) },
314 		{ CKA_START_DATE, &obj_start, sizeof(obj_start) },
315 		{ CKA_END_DATE, &obj_end, sizeof(obj_end) },
316 		{ CKA_DERIVE, &obj_derive, sizeof(obj_derive) },
317 		{ CKA_LOCAL, &obj_local, sizeof(obj_local) },
318 		{ CKA_KEY_GEN_MECHANISM, &obj_mech, sizeof(obj_mech) },
319 		{ CKA_ALLOWED_MECHANISMS, NULL_PTR, 0 }
320 	};
321 
322 	// Get length
323 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 1) );
324 	CPPUNIT_ASSERT(rv == CKR_OK);
325 	attribs[0].pValue = (CK_VOID_PTR)malloc(attribs[0].ulValueLen);
326 
327 	// Check values
328 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 8) );
329 	CPPUNIT_ASSERT(rv == CKR_OK);
330 	CPPUNIT_ASSERT(attribs[0].ulValueLen == ulIdLen);
331 	CPPUNIT_ASSERT(obj_type == keyType);
332 	CPPUNIT_ASSERT(attribs[2].ulValueLen == ulStartDateLen);
333 	CPPUNIT_ASSERT(attribs[3].ulValueLen == ulEndDateLen);
334 	CPPUNIT_ASSERT(obj_derive == bDerive);
335 	CPPUNIT_ASSERT(obj_local == bLocal);
336 	CPPUNIT_ASSERT(obj_mech == keyMechanismType);
337 	CPPUNIT_ASSERT(attribs[7].ulValueLen == ulAllowedMechanismsLen);
338 
339 	if (ulIdLen > 0)
340 		CPPUNIT_ASSERT(memcmp(attribs[0].pValue, pId, ulIdLen) == 0);
341 	if (ulStartDateLen > 0)
342 		CPPUNIT_ASSERT(memcmp(attribs[2].pValue, &startDate, ulStartDateLen) == 0);
343 	if (ulEndDateLen > 0)
344 		CPPUNIT_ASSERT(memcmp(attribs[3].pValue, &endDate, ulEndDateLen) == 0);
345 	if (ulAllowedMechanismsLen > 0)
346 		CPPUNIT_ASSERT(memcmp(attribs[7].pValue, pAllowedMechanisms, ulAllowedMechanismsLen) == 0);
347 
348 	free(attribs[0].pValue);
349 }
350 
checkCommonPublicKeyAttributes(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_BYTE_PTR pSubject,CK_ULONG ulSubjectLen,CK_BBOOL,CK_BBOOL,CK_BBOOL,CK_BBOOL,CK_BBOOL bTrusted,CK_ATTRIBUTE_PTR pWrapTemplate,CK_ULONG ulWrapTemplateLen)351 void ObjectTests::checkCommonPublicKeyAttributes(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_BYTE_PTR pSubject, CK_ULONG ulSubjectLen, CK_BBOOL /*bEncrypt*/, CK_BBOOL /*bVerify*/, CK_BBOOL /*bVerifyRecover*/, CK_BBOOL /*bWrap*/, CK_BBOOL bTrusted, CK_ATTRIBUTE_PTR pWrapTemplate, CK_ULONG ulWrapTemplateLen)
352 {
353 	CK_RV rv;
354 
355 	CK_BBOOL obj_encrypt = CK_FALSE;
356 	CK_BBOOL obj_verify = CK_FALSE;
357 	CK_BBOOL obj_verify_recover = CK_FALSE;
358 	CK_BBOOL obj_wrap = CK_FALSE;
359 	CK_BBOOL obj_trusted = CK_FALSE;
360 	CK_LONG len_wrap_template = ulWrapTemplateLen;
361 	CK_ATTRIBUTE attribs[] = {
362 		{ CKA_SUBJECT, NULL_PTR, 0 },
363 		{ CKA_ENCRYPT, &obj_encrypt, sizeof(obj_encrypt) },
364 		{ CKA_VERIFY, &obj_verify, sizeof(obj_verify) },
365 		{ CKA_VERIFY_RECOVER, &obj_verify_recover, sizeof(obj_verify_recover) },
366 		{ CKA_WRAP, &obj_wrap, sizeof(obj_wrap) },
367 		{ CKA_TRUSTED, &obj_trusted, sizeof(obj_trusted) },
368 		{ CKA_WRAP_TEMPLATE, pWrapTemplate, ulWrapTemplateLen }
369 	};
370 
371 	// Get length
372 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 1) );
373 	CPPUNIT_ASSERT(rv == CKR_OK);
374 	attribs[0].pValue = (CK_VOID_PTR)malloc(attribs[0].ulValueLen);
375 
376 	// Check values
377 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 7) );
378 	CPPUNIT_ASSERT(rv == CKR_OK);
379 	CPPUNIT_ASSERT(attribs[0].ulValueLen == ulSubjectLen);
380 	/* Default is token-specifict
381 	CPPUNIT_ASSERT(obj_encrypt == bEncrypt);
382 	CPPUNIT_ASSERT(obj_verify == bVerify);
383 	CPPUNIT_ASSERT(obj_verify_recover == bVerifyRecover);
384 	CPPUNIT_ASSERT(obj_wrap == bWrap); */
385 	CPPUNIT_ASSERT(obj_trusted == bTrusted);
386 	len_wrap_template = attribs[6].ulValueLen;
387 	CPPUNIT_ASSERT(len_wrap_template == 0);
388 	if (ulSubjectLen > 0)
389 		CPPUNIT_ASSERT(memcmp(attribs[0].pValue, pSubject, ulSubjectLen) == 0);
390 
391 	free(attribs[0].pValue);
392 }
393 
checkCommonPrivateKeyAttributes(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_BYTE_PTR pSubject,CK_ULONG ulSubjectLen,CK_BBOOL bSensitive,CK_BBOOL bDecrypt,CK_BBOOL bSign,CK_BBOOL bSignRecover,CK_BBOOL bUnwrap,CK_BBOOL bExtractable,CK_BBOOL bAlwaysSensitive,CK_BBOOL bNeverExtractable,CK_BBOOL bWrapWithTrusted,CK_ATTRIBUTE_PTR pUnwrapTemplate,CK_ULONG ulUnwrapTemplateLen,CK_BBOOL bAlwaysAuthenticate)394 void ObjectTests::checkCommonPrivateKeyAttributes(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_BYTE_PTR pSubject, CK_ULONG ulSubjectLen, CK_BBOOL bSensitive, CK_BBOOL bDecrypt, CK_BBOOL bSign, CK_BBOOL bSignRecover, CK_BBOOL bUnwrap, CK_BBOOL bExtractable, CK_BBOOL bAlwaysSensitive, CK_BBOOL bNeverExtractable, CK_BBOOL bWrapWithTrusted, CK_ATTRIBUTE_PTR pUnwrapTemplate, CK_ULONG ulUnwrapTemplateLen, CK_BBOOL bAlwaysAuthenticate)
395 {
396 	CK_RV rv;
397 
398 	CK_BBOOL obj_sensitive = CK_FALSE;
399 	CK_BBOOL obj_decrypt = CK_FALSE;
400 	CK_BBOOL obj_sign = CK_FALSE;
401 	CK_BBOOL obj_sign_recover = CK_FALSE;
402 	CK_BBOOL obj_unwrap = CK_FALSE;
403 	CK_BBOOL obj_extractable = CK_FALSE;
404 	CK_BBOOL obj_always_sensitive = CK_FALSE;
405 	CK_BBOOL obj_never_extractable = CK_FALSE;
406 	CK_BBOOL obj_wrap_with_trusted = CK_FALSE;
407 	CK_BBOOL obj_always_authenticate = CK_FALSE;
408 	CK_LONG len_unwrap_template = ulUnwrapTemplateLen;
409 	CK_ATTRIBUTE attribs[] = {
410 		{ CKA_SUBJECT, NULL_PTR, 0 },
411 		{ CKA_SENSITIVE, &obj_sensitive, sizeof(obj_sensitive) },
412 		{ CKA_DECRYPT, &obj_decrypt, sizeof(obj_decrypt) },
413 		{ CKA_SIGN, &obj_sign, sizeof(obj_sign) },
414 		{ CKA_SIGN_RECOVER, &obj_sign_recover, sizeof(obj_sign_recover) },
415 		{ CKA_UNWRAP, &obj_unwrap, sizeof(obj_unwrap) },
416 		{ CKA_EXTRACTABLE, &obj_extractable, sizeof(obj_extractable) },
417 		{ CKA_ALWAYS_SENSITIVE, &obj_always_sensitive, sizeof(obj_always_sensitive) },
418 		{ CKA_NEVER_EXTRACTABLE, &obj_never_extractable, sizeof(obj_never_extractable) },
419 		{ CKA_WRAP_WITH_TRUSTED, &obj_wrap_with_trusted, sizeof(obj_wrap_with_trusted) },
420 		{ CKA_UNWRAP_TEMPLATE, pUnwrapTemplate, ulUnwrapTemplateLen },
421 		{ CKA_ALWAYS_AUTHENTICATE, &obj_always_authenticate, sizeof(obj_always_authenticate) }
422 	};
423 
424 	// Get length
425 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 1) );
426 	CPPUNIT_ASSERT(rv == CKR_OK);
427 	attribs[0].pValue = (CK_VOID_PTR)malloc(attribs[0].ulValueLen);
428 
429 	// Check values
430 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 12) );
431 	CPPUNIT_ASSERT(rv == CKR_OK);
432 	CPPUNIT_ASSERT(attribs[0].ulValueLen == ulSubjectLen);
433 	CPPUNIT_ASSERT(obj_sensitive == bSensitive);
434 	CPPUNIT_ASSERT(obj_decrypt == bDecrypt);
435 	CPPUNIT_ASSERT(obj_sign == bSign);
436 	CPPUNIT_ASSERT(obj_sign_recover == bSignRecover);
437 	CPPUNIT_ASSERT(obj_unwrap == bUnwrap);
438 	CPPUNIT_ASSERT(obj_extractable == bExtractable);
439 	CPPUNIT_ASSERT(obj_always_sensitive == bAlwaysSensitive);
440 	CPPUNIT_ASSERT(obj_never_extractable == bNeverExtractable);
441 	CPPUNIT_ASSERT(obj_wrap_with_trusted == bWrapWithTrusted);
442 	CPPUNIT_ASSERT(obj_always_authenticate == bAlwaysAuthenticate);
443 	len_unwrap_template = attribs[10].ulValueLen;
444 	CPPUNIT_ASSERT(len_unwrap_template == 0);
445 	if (ulSubjectLen > 0)
446 		CPPUNIT_ASSERT(memcmp(attribs[0].pValue, pSubject, ulSubjectLen) == 0);
447 
448 	free(attribs[0].pValue);
449 }
450 
checkCommonRSAPublicKeyAttributes(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_BYTE_PTR pModulus,CK_ULONG ulModulusLen,CK_ULONG ulModulusBits,CK_BYTE_PTR pPublicExponent,CK_ULONG ulPublicExponentLen)451 void ObjectTests::checkCommonRSAPublicKeyAttributes(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_BYTE_PTR pModulus, CK_ULONG ulModulusLen, CK_ULONG ulModulusBits, CK_BYTE_PTR pPublicExponent, CK_ULONG ulPublicExponentLen)
452 {
453 	CK_RV rv;
454 
455 	CK_ULONG obj_bits = 0;
456 	CK_ATTRIBUTE attribs[] = {
457 		{ CKA_MODULUS, NULL_PTR, 0 },
458 		{ CKA_PUBLIC_EXPONENT, NULL_PTR, 0 },
459 		{ CKA_MODULUS_BITS, &obj_bits, sizeof(obj_bits) }
460 	};
461 
462 	// Get length
463 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 2) );
464 	CPPUNIT_ASSERT(rv == CKR_OK);
465 	attribs[0].pValue = (CK_VOID_PTR)malloc(attribs[0].ulValueLen);
466 	attribs[1].pValue = (CK_VOID_PTR)malloc(attribs[1].ulValueLen);
467 
468 	// Check values
469 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 3) );
470 	CPPUNIT_ASSERT(rv == CKR_OK);
471 	CPPUNIT_ASSERT(attribs[0].ulValueLen == ulModulusLen);
472 	CPPUNIT_ASSERT(attribs[1].ulValueLen == ulPublicExponentLen);
473 	CPPUNIT_ASSERT(obj_bits == ulModulusBits);
474 	if (ulModulusLen > 0)
475 		CPPUNIT_ASSERT(memcmp(attribs[0].pValue, pModulus, ulModulusLen) == 0);
476 	if (ulPublicExponentLen > 0)
477 		CPPUNIT_ASSERT(memcmp(attribs[1].pValue, pPublicExponent, ulPublicExponentLen) == 0);
478 
479 	free(attribs[0].pValue);
480 	free(attribs[1].pValue);
481 }
482 
checkCommonRSAPrivateKeyAttributes(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_BYTE_PTR pModulus,CK_ULONG ulModulusLen,CK_BYTE_PTR,CK_ULONG,CK_BYTE_PTR pPrivateExponent,CK_ULONG ulPrivateExponentLen,CK_BYTE_PTR,CK_ULONG,CK_BYTE_PTR,CK_ULONG,CK_BYTE_PTR,CK_ULONG,CK_BYTE_PTR,CK_ULONG,CK_BYTE_PTR,CK_ULONG)483 void ObjectTests::checkCommonRSAPrivateKeyAttributes(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_BYTE_PTR pModulus, CK_ULONG ulModulusLen, CK_BYTE_PTR /*pPublicExponent*/, CK_ULONG /*ulPublicExponentLen*/, CK_BYTE_PTR pPrivateExponent, CK_ULONG ulPrivateExponentLen, CK_BYTE_PTR /*pPrime1*/, CK_ULONG /*ulPrime1Len*/, CK_BYTE_PTR /*pPrime2*/, CK_ULONG /*ulPrime2Len*/, CK_BYTE_PTR /*pExponent1*/, CK_ULONG /*ulExponent1Len*/, CK_BYTE_PTR /*pExponent2*/, CK_ULONG /*ulExponent2Len*/, CK_BYTE_PTR /*pCoefficient*/, CK_ULONG /*ulCoefficientLen*/)
484 {
485 	CK_RV rv;
486 
487 	CK_ATTRIBUTE attribs[] = {
488 		{ CKA_MODULUS, NULL_PTR, 0 },
489 		{ CKA_PRIVATE_EXPONENT, NULL_PTR, 0 }
490 		/* Some tokens may only store modulus and private exponent
491 		{ CKA_PUBLIC_EXPONENT, NULL_PTR, 0 },
492 		{ CKA_PRIME_1, NULL_PTR, 0 },
493 		{ CKA_PRIME_2, NULL_PTR, 0 },
494 		{ CKA_EXPONENT_1, NULL_PTR, 0 },
495 		{ CKA_EXPONENT_2, NULL_PTR, 0 },
496 		{ CKA_COEFFICIENT, NULL_PTR, 0 }, */
497 	};
498 
499 	// Get length
500 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 2) );
501 	CPPUNIT_ASSERT(rv == CKR_OK);
502 	attribs[0].pValue = (CK_VOID_PTR)malloc(attribs[0].ulValueLen);
503 	attribs[1].pValue = (CK_VOID_PTR)malloc(attribs[1].ulValueLen);
504 
505 	// Check values
506 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &attribs[0], 2) );
507 	CPPUNIT_ASSERT(rv == CKR_OK);
508 	CPPUNIT_ASSERT(attribs[0].ulValueLen == ulModulusLen);
509 	CPPUNIT_ASSERT(attribs[1].ulValueLen == ulPrivateExponentLen);
510 	if (ulModulusLen > 0)
511 		CPPUNIT_ASSERT(memcmp(attribs[0].pValue, pModulus, ulModulusLen) == 0);
512 	if (ulPrivateExponentLen > 0)
513 		CPPUNIT_ASSERT(memcmp(attribs[1].pValue, pPrivateExponent, ulPrivateExponentLen) == 0);
514 
515 	free(attribs[0].pValue);
516 	free(attribs[1].pValue);
517 }
518 
createDataObjectMinimal(CK_SESSION_HANDLE hSession,CK_BBOOL bToken,CK_BBOOL bPrivate,CK_OBJECT_HANDLE & hObject)519 CK_RV ObjectTests::createDataObjectMinimal(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hObject)
520 {
521 	CK_OBJECT_CLASS cClass = CKO_DATA;
522 	CK_UTF8CHAR label[] = "A data object";
523 	CK_ATTRIBUTE objTemplate[] = {
524 		// Common
525 		{ CKA_CLASS, &cClass, sizeof(cClass) },
526 
527 		// Storage
528 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
529 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
530 		//CKA_MODIFIABLE
531 		{ CKA_LABEL, label, sizeof(label)-1 },
532 		//CKA_COPYABLE
533 		//CKA_DESTROYABLE
534 
535 		// Data
536 	 };
537 
538 	hObject = CK_INVALID_HANDLE;
539 	return CRYPTOKI_F_PTR( C_CreateObject(hSession, objTemplate, sizeof(objTemplate)/sizeof(CK_ATTRIBUTE),&hObject) );
540 }
541 
createDataObjectMCD(CK_SESSION_HANDLE hSession,CK_BBOOL bToken,CK_BBOOL bPrivate,CK_BBOOL bModifiable,CK_BBOOL bCopyable,CK_BBOOL bDestroyable,CK_OBJECT_HANDLE & hObject)542 CK_RV ObjectTests::createDataObjectMCD(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_BBOOL bModifiable, CK_BBOOL bCopyable, CK_BBOOL bDestroyable, CK_OBJECT_HANDLE &hObject)
543 {
544 	CK_OBJECT_CLASS cClass = CKO_DATA;
545 	CK_UTF8CHAR label[] = "A data object";
546 	CK_ATTRIBUTE objTemplate[] = {
547 		// Common
548 		{ CKA_CLASS, &cClass, sizeof(cClass) },
549 
550 		// Storage
551 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
552 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
553 		{ CKA_MODIFIABLE, &bModifiable, sizeof(bModifiable) },
554 		{ CKA_LABEL, label, sizeof(label)-1 },
555 		{ CKA_COPYABLE, &bCopyable, sizeof(bCopyable) },
556 		{ CKA_DESTROYABLE, &bDestroyable, sizeof(bDestroyable) }
557 
558 		// Data
559 	 };
560 
561 	hObject = CK_INVALID_HANDLE;
562 	return CRYPTOKI_F_PTR( C_CreateObject(hSession, objTemplate, sizeof(objTemplate)/sizeof(CK_ATTRIBUTE),&hObject) );
563 }
564 
createDataObjectNormal(CK_SESSION_HANDLE hSession,CK_BBOOL bToken,CK_BBOOL bPrivate,CK_OBJECT_HANDLE & hObject)565 CK_RV ObjectTests::createDataObjectNormal(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hObject)
566 {
567 	CK_OBJECT_CLASS cClass = CKO_DATA;
568 	CK_UTF8CHAR label[] = "A data object";
569 
570 	CK_UTF8CHAR application[] = "An application";
571 	CK_BYTE objectID[] = "invalid object id";
572 	CK_BYTE data[] = "Sample data";
573 
574 	CK_ATTRIBUTE objTemplate[] = {
575 		// Common
576 		{ CKA_CLASS, &cClass, sizeof(cClass) },
577 
578 		// Storage
579 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
580 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
581 		//CKA_MODIFIABLE
582 		{ CKA_LABEL, label, sizeof(label)-1 },
583 		//CKA_COPYABLE
584 		//CKA_DESTROYABLE
585 
586 		// Data
587 		{ CKA_APPLICATION, application, sizeof(application)-1 },
588 		{ CKA_OBJECT_ID, objectID, sizeof(objectID) },
589 		{ CKA_VALUE, data, sizeof(data) }
590 	};
591 
592 	hObject = CK_INVALID_HANDLE;
593 	return CRYPTOKI_F_PTR( C_CreateObject(hSession, objTemplate, sizeof(objTemplate)/sizeof(CK_ATTRIBUTE),&hObject) );
594 }
595 
createCertificateObjectIncomplete(CK_SESSION_HANDLE hSession,CK_BBOOL bToken,CK_BBOOL bPrivate,CK_OBJECT_HANDLE & hObject)596 CK_RV ObjectTests::createCertificateObjectIncomplete(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hObject)
597 {
598 	CK_OBJECT_CLASS cClass = CKO_CERTIFICATE;
599 	CK_ATTRIBUTE objTemplate[] = {
600 		// Common
601 		{ CKA_CLASS, &cClass, sizeof(cClass) },
602 		// Storage
603 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
604 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) }
605 	};
606 
607 	hObject = CK_INVALID_HANDLE;
608 	return CRYPTOKI_F_PTR( C_CreateObject(hSession, objTemplate, sizeof(objTemplate)/sizeof(CK_ATTRIBUTE),&hObject) );
609 }
610 
createCertificateObjectX509(CK_SESSION_HANDLE hSession,CK_BBOOL bToken,CK_BBOOL bPrivate,CK_OBJECT_HANDLE & hObject)611 CK_RV ObjectTests::createCertificateObjectX509(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hObject)
612 {
613 	CK_OBJECT_CLASS cClass = CKO_CERTIFICATE;
614 	CK_CERTIFICATE_TYPE cType = CKC_X_509;
615 	const char *pSubject = "invalid subject der";
616 	const char *pValue = "invalid certificate der";
617 
618 	CK_ATTRIBUTE objTemplate[] = {
619 		// Common
620 		{ CKA_CLASS, &cClass, sizeof(cClass) },
621 		// Storage
622 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
623 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
624 		// Common Certificate Object Attributes
625 		{ CKA_CERTIFICATE_TYPE, &cType, sizeof(cType) },
626 		// X.509 Certificate Object Attributes
627 		{ CKA_SUBJECT, (CK_VOID_PTR)pSubject, strlen(pSubject) },
628 		{ CKA_VALUE, (CK_VOID_PTR)pValue, strlen(pValue) }
629 	};
630 
631 	hObject = CK_INVALID_HANDLE;
632 	return CRYPTOKI_F_PTR( C_CreateObject(hSession, objTemplate, sizeof(objTemplate)/sizeof(CK_ATTRIBUTE),&hObject) );
633 }
634 
generateRsaKeyPair(CK_SESSION_HANDLE hSession,CK_BBOOL bTokenPuk,CK_BBOOL bPrivatePuk,CK_BBOOL bTokenPrk,CK_BBOOL bPrivatePrk,CK_OBJECT_HANDLE & hPuk,CK_OBJECT_HANDLE & hPrk)635 CK_RV ObjectTests::generateRsaKeyPair(CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk)
636 {
637 	CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
638 	CK_ULONG bits = 1536;
639 	CK_BYTE pubExp[] = {0x01, 0x00, 0x01};
640 	CK_BYTE subject[] = { 0x12, 0x34 }; // dummy
641 	CK_BYTE id[] = { 123 } ; // dummy
642 	CK_BBOOL bFalse = CK_FALSE;
643 	CK_BBOOL bTrue = CK_TRUE;
644 	CK_ATTRIBUTE pukAttribs[] = {
645 		{ CKA_TOKEN, &bTokenPuk, sizeof(bTokenPuk) },
646 		{ CKA_PRIVATE, &bPrivatePuk, sizeof(bPrivatePuk) },
647 		{ CKA_ENCRYPT, &bFalse, sizeof(bFalse) },
648 		{ CKA_VERIFY, &bTrue, sizeof(bTrue) },
649 		{ CKA_WRAP, &bFalse, sizeof(bFalse) },
650 		{ CKA_MODULUS_BITS, &bits, sizeof(bits) },
651 		{ CKA_PUBLIC_EXPONENT, &pubExp[0], sizeof(pubExp) }
652 	};
653 	CK_ATTRIBUTE prkAttribs[] = {
654 		{ CKA_TOKEN, &bTokenPrk, sizeof(bTokenPrk) },
655 		{ CKA_PRIVATE, &bPrivatePrk, sizeof(bPrivatePrk) },
656 		{ CKA_SUBJECT, &subject[0], sizeof(subject) },
657 		{ CKA_ID, &id[0], sizeof(id) },
658 		{ CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
659 		{ CKA_DECRYPT, &bFalse, sizeof(bFalse) },
660 		{ CKA_SIGN, &bTrue, sizeof(bTrue) },
661 		{ CKA_UNWRAP, &bFalse, sizeof(bFalse) }
662 	};
663 
664 	hPuk = CK_INVALID_HANDLE;
665 	hPrk = CK_INVALID_HANDLE;
666 	return CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism,
667 							 pukAttribs, sizeof(pukAttribs)/sizeof(CK_ATTRIBUTE),
668 							 prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE),
669 							 &hPuk, &hPrk) );
670 }
671 
testCreateObject()672 void ObjectTests::testCreateObject()
673 {
674 //    printf("\ntestCreateObject\n");
675 
676 	// [PKCS#11 v2.40, C_CreateObject]
677 	// a. Only session objects can be created during read-only session.
678 	// b. Only public objects can be created unless the normal user is logged in.
679 	// c. Key object will have CKA_LOCAL == CK_FALSE.
680 	// d. If key object is secret or a private key then both CKA_ALWAYS_SENSITIVE == CK_FALSE and CKA_NEVER_EXTRACTABLE == CKA_FALSE.
681 
682 	CK_RV rv;
683 	CK_SESSION_HANDLE hSession;
684 	CK_OBJECT_HANDLE hObject;
685 
686 	CK_BBOOL bFalse = CK_FALSE;
687 	CK_BBOOL bTrue = CK_TRUE;
688 	CK_OBJECT_CLASS secretClass = CKO_SECRET_KEY;
689 	CK_KEY_TYPE genKeyType = CKK_GENERIC_SECRET;
690 	CK_BYTE keyPtr[128];
691 	CK_ULONG keyLen = 128;
692 	CK_MECHANISM_TYPE allowedMechs[] = {
693 		CKM_RSA_PKCS_PSS,
694 		CKM_SHA256_RSA_PKCS_PSS
695 	};
696 	CK_ATTRIBUTE attribs[] = {
697 		{ CKA_EXTRACTABLE, &bFalse, sizeof(bFalse) },
698 		{ CKA_CLASS, &secretClass, sizeof(secretClass) },
699 		{ CKA_KEY_TYPE, &genKeyType, sizeof(genKeyType) },
700 		{ CKA_TOKEN, &bFalse, sizeof(bFalse) },
701 		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
702 		{ CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
703 		{ CKA_VALUE, keyPtr, keyLen },
704 		{ CKA_ALLOWED_MECHANISMS, &allowedMechs, sizeof(allowedMechs) }
705 	};
706 
707 	CK_BBOOL local;
708 	CK_BBOOL always;
709 	CK_BBOOL never;
710 	CK_MECHANISM_TYPE mechs[2] = {};
711 	CK_ATTRIBUTE getTemplate[] = {
712 		{ CKA_LOCAL, &local, sizeof(local) },
713 		{ CKA_ALWAYS_SENSITIVE, &always, sizeof(always) },
714 		{ CKA_NEVER_EXTRACTABLE, &never, sizeof(never) },
715 		{ CKA_ALLOWED_MECHANISMS, &mechs, sizeof(mechs) }
716 	};
717 
718 	// Just make sure that we finalize any previous tests
719 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
720 
721 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
722 	CPPUNIT_ASSERT(rv == CKR_OK);
723 
724 	/////////////////////////////////
725 	// READ-ONLY & PUBLIC
726 	/////////////////////////////////
727 
728 	// Open read-only session and don't login
729 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSession) );
730 	CPPUNIT_ASSERT(rv == CKR_OK);
731 
732 	// We should be allowed to create public session objects
733 	rv = createDataObjectMinimal(hSession, IN_SESSION, IS_PUBLIC, hObject);
734 	CPPUNIT_ASSERT(rv == CKR_OK);
735 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
736 	CPPUNIT_ASSERT(rv == CKR_OK);
737 
738 	// Only public objects can be created unless the normal user is logged in
739 	rv = createDataObjectMinimal(hSession, IN_SESSION, IS_PRIVATE, hObject);
740 	CPPUNIT_ASSERT(rv == CKR_USER_NOT_LOGGED_IN);
741 
742 	// We should not be allowed to create token objects because the session is read-only
743 	rv = createDataObjectMinimal(hSession, ON_TOKEN, IS_PUBLIC, hObject);
744 	CPPUNIT_ASSERT(rv == CKR_SESSION_READ_ONLY);
745 	rv = createDataObjectMinimal(hSession, ON_TOKEN, IS_PRIVATE, hObject);
746 	CPPUNIT_ASSERT(rv == CKR_SESSION_READ_ONLY);
747 
748 	/////////////////////////////////
749 	// READ-ONLY & USER
750 	/////////////////////////////////
751 
752 	// Login USER into the read-only session
753 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) );
754 	CPPUNIT_ASSERT(rv==CKR_OK);
755 
756 	// We should be allowed to create public session objects
757 	rv = createDataObjectMinimal(hSession, IN_SESSION, IS_PUBLIC, hObject);
758 	CPPUNIT_ASSERT(rv == CKR_OK);
759 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
760 	CPPUNIT_ASSERT(rv == CKR_OK);
761 
762 	// We should be allowed to create private session objects
763 	rv  = createDataObjectMinimal(hSession, IN_SESSION, IS_PRIVATE, hObject);
764 	CPPUNIT_ASSERT(rv == CKR_OK);
765 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
766 	CPPUNIT_ASSERT(rv == CKR_OK);
767 
768 	// We should not be allowed to create token objects.
769 	rv = createDataObjectMinimal(hSession, ON_TOKEN, IS_PUBLIC, hObject);
770 	CPPUNIT_ASSERT(rv == CKR_SESSION_READ_ONLY);
771 	rv = createDataObjectMinimal(hSession, ON_TOKEN, IS_PRIVATE, hObject);
772 	CPPUNIT_ASSERT(rv == CKR_SESSION_READ_ONLY);
773 
774 	// Close session
775 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSession) );
776 	CPPUNIT_ASSERT(rv==CKR_OK);
777 
778 	/////////////////////////////////
779 	// READ-WRITE & PUBLIC
780 	/////////////////////////////////
781 
782 	// Open as read-write session but don't login.
783 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
784 	CPPUNIT_ASSERT(rv == CKR_OK);
785 
786 	// We should be allowed to create public session objects
787 	rv = createDataObjectMinimal(hSession, IN_SESSION, IS_PUBLIC, hObject);
788 	CPPUNIT_ASSERT(rv == CKR_OK);
789 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
790 	CPPUNIT_ASSERT(rv == CKR_OK);
791 
792 	rv = createDataObjectMinimal(hSession, IN_SESSION, IS_PRIVATE, hObject);
793 	CPPUNIT_ASSERT(rv ==  CKR_USER_NOT_LOGGED_IN);
794 
795 	// We should be allowed to create public token objects even when not logged in.
796 	rv = createDataObjectMinimal(hSession, ON_TOKEN, IS_PUBLIC, hObject);
797 	CPPUNIT_ASSERT(rv ==  CKR_OK);
798 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
799 	CPPUNIT_ASSERT(rv == CKR_OK);
800 
801 	// We should not be able to create private token objects because we are not logged in now
802 	rv = createDataObjectMinimal(hSession, ON_TOKEN, IS_PRIVATE, hObject);
803 	CPPUNIT_ASSERT(rv == CKR_USER_NOT_LOGGED_IN);
804 
805 	// Close session
806 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSession) );
807 	CPPUNIT_ASSERT(rv == CKR_OK);
808 
809 	/////////////////////////////////
810 	// READ-WRITE & USER
811 	/////////////////////////////////
812 
813 	// Open as read-write session
814 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
815 	CPPUNIT_ASSERT(rv == CKR_OK);
816 
817 	// Login to the read-write session
818 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) );
819 	CPPUNIT_ASSERT(rv==CKR_OK);
820 
821 	// We should always be allowed to create public session objects
822 	rv = createDataObjectMinimal(hSession, IN_SESSION, IS_PUBLIC, hObject);
823 	CPPUNIT_ASSERT(rv == CKR_OK);
824 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
825 	CPPUNIT_ASSERT(rv == CKR_OK);
826 
827 	// We should be able allowed to create private session objects because we are logged in.
828 	rv = createDataObjectMinimal(hSession, IN_SESSION, IS_PRIVATE, hObject);
829 	CPPUNIT_ASSERT(rv == CKR_OK);
830 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
831 	CPPUNIT_ASSERT(rv == CKR_OK);
832 
833 	// We should be allowed to create public token objects even when not logged in.
834 	rv = createDataObjectMinimal(hSession, ON_TOKEN, IS_PUBLIC, hObject);
835 	CPPUNIT_ASSERT(rv == CKR_OK);
836 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
837 	CPPUNIT_ASSERT(rv == CKR_OK);
838 
839 	// We should be able to create private token objects because we are logged in now
840 	rv = createDataObjectMinimal(hSession, ON_TOKEN, IS_PRIVATE, hObject);
841 	CPPUNIT_ASSERT(rv == CKR_OK);
842 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
843 	CPPUNIT_ASSERT(rv == CKR_OK);
844 
845 	// Close session
846 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSession) );
847 	CPPUNIT_ASSERT(rv == CKR_OK);
848 
849 	/////////////////////////////////
850 	// READ-WRITE & SO
851 	/////////////////////////////////
852 
853 	// Open as read-write session
854 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
855 	CPPUNIT_ASSERT(rv == CKR_OK);
856 
857 	// Login to the read-write session
858 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_SO,m_soPin1,m_soPin1Length) );
859 	CPPUNIT_ASSERT(rv==CKR_OK);
860 
861 	// We should always be allowed to create public session objects
862 	rv = createDataObjectMinimal(hSession, IN_SESSION, IS_PUBLIC, hObject);
863 	CPPUNIT_ASSERT(rv == CKR_OK);
864 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
865 	CPPUNIT_ASSERT(rv == CKR_OK);
866 
867 	// Only public objects can be created unless the normal user is logged in.
868 	rv = createDataObjectMinimal(hSession, IN_SESSION, IS_PRIVATE, hObject);
869 	CPPUNIT_ASSERT(rv == CKR_USER_NOT_LOGGED_IN);
870 
871 	// We should be allowed to create public token objects even when not logged in.
872 	rv = createDataObjectMinimal(hSession, ON_TOKEN, IS_PUBLIC, hObject);
873 	CPPUNIT_ASSERT(rv == CKR_OK);
874 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
875 	CPPUNIT_ASSERT(rv == CKR_OK);
876 
877 	// Only public objects can be created unless the normal user is logged in.
878 	rv = createDataObjectMinimal(hSession, ON_TOKEN, IS_PRIVATE, hObject);
879 	CPPUNIT_ASSERT(rv == CKR_USER_NOT_LOGGED_IN);
880 
881 	// Close session
882 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSession) );
883 	CPPUNIT_ASSERT(rv == CKR_OK);
884 
885 	/////////////////////////////////
886 	// READ-WRITE & USER
887 	/////////////////////////////////
888 
889 	// Open as read-write session
890 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
891 	CPPUNIT_ASSERT(rv == CKR_OK);
892 
893 	// Login to the read-write session
894 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) );
895 	CPPUNIT_ASSERT(rv==CKR_OK);
896 
897 	// Create a secret object
898 	rv = CRYPTOKI_F_PTR( C_GenerateRandom(hSession, keyPtr, keyLen) );
899 	CPPUNIT_ASSERT(rv == CKR_OK);
900 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hObject) );
901 	CPPUNIT_ASSERT(rv == CKR_OK);
902 
903 	// Check value
904 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, getTemplate, 4) );
905 	CPPUNIT_ASSERT(rv == CKR_OK);
906 	CPPUNIT_ASSERT(local == CK_FALSE);
907 	CPPUNIT_ASSERT(always == CK_FALSE);
908 	CPPUNIT_ASSERT(never == CK_FALSE);
909 	CPPUNIT_ASSERT(sizeof(allowedMechs) == getTemplate[3].ulValueLen);
910 	CPPUNIT_ASSERT(memcmp(&allowedMechs, &mechs, sizeof(allowedMechs)) == 0);
911 
912 	// Destroy the secret object
913 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
914 	CPPUNIT_ASSERT(rv == CKR_OK);
915 
916 	// Close session
917 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSession) );
918 	CPPUNIT_ASSERT(rv == CKR_OK);
919 }
920 
testCopyObject()921 void ObjectTests::testCopyObject()
922 {
923 //    printf("\ntestCopyObject\n");
924 
925 	CK_RV rv;
926 	CK_SESSION_HANDLE hSession;
927 	CK_OBJECT_HANDLE hObject;
928 	CK_OBJECT_HANDLE hObjectCopy;
929 	CK_OBJECT_HANDLE hObject1;
930 
931 	// Just make sure that we finalize any previous tests
932 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
933 
934 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
935 	CPPUNIT_ASSERT(rv == CKR_OK);
936 
937 	// Open read-only session and don't login
938 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSession) );
939 	CPPUNIT_ASSERT(rv == CKR_OK);
940 
941 	// Get a public session object
942 	rv = createDataObjectMinimal(hSession, IN_SESSION, IS_PUBLIC, hObject);
943 	CPPUNIT_ASSERT(rv == CKR_OK);
944 	rv = createDataObjectMCD(hSession, IN_SESSION, IS_PUBLIC, CK_TRUE, CK_FALSE, CK_TRUE, hObjectCopy);
945 	CPPUNIT_ASSERT(rv == CKR_OK);
946 
947 	// Allowed to copy it
948 	const char *pLabel = "Label modified via C_CopyObject";
949 	CK_BBOOL bToken = CK_FALSE;
950 	CK_BBOOL bPrivate = CK_FALSE;
951 	CK_OBJECT_CLASS cClass = CKO_DATA;
952 	CK_ATTRIBUTE attribs[] = {
953 		{ CKA_LABEL, (CK_UTF8CHAR_PTR)pLabel, strlen(pLabel) },
954 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
955 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
956 		{ CKA_CLASS, &cClass, sizeof(cClass) }
957 	};
958 	rv = CRYPTOKI_F_PTR( C_CopyObject(hSession, hObject, &attribs[0], 1, &hObject1) );
959 	CPPUNIT_ASSERT(rv == CKR_OK);
960 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hObject1) );
961 	CPPUNIT_ASSERT(rv == CKR_OK);
962 
963 	// Not allowed to copy.
964 	rv = CRYPTOKI_F_PTR( C_CopyObject(hSession, hObjectCopy, &attribs[0], 1, &hObject1) );
965 	CPPUNIT_ASSERT(rv == CKR_ACTION_PROHIBITED);
966 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hObjectCopy) );
967 	CPPUNIT_ASSERT(rv == CKR_OK);
968 
969 	// Still allowed when still session and public
970 	rv = CRYPTOKI_F_PTR( C_CopyObject(hSession, hObject, &attribs[0], 3, &hObject1) );
971 	CPPUNIT_ASSERT(rv == CKR_OK);
972 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hObject1) );
973 	CPPUNIT_ASSERT(rv == CKR_OK);
974 
975 	// Not allowed to overwrite an !ck8 attribute
976 	rv = CRYPTOKI_F_PTR( C_CopyObject(hSession, hObject, &attribs[0], 4, &hObject1) );
977 	CPPUNIT_ASSERT(rv == CKR_ATTRIBUTE_READ_ONLY);
978 
979 	// Not allowed to go on token
980 	bToken = CK_TRUE;
981 	rv = CRYPTOKI_F_PTR( C_CopyObject(hSession, hObject, &attribs[0], 3, &hObject1) );
982 	bToken = CK_FALSE;
983 	CPPUNIT_ASSERT(rv == CKR_SESSION_READ_ONLY);
984 
985 	// Not allowed to go to private
986 	bPrivate = CK_TRUE;
987 	rv = CRYPTOKI_F_PTR( C_CopyObject(hSession, hObject, &attribs[0], 3, &hObject1) );
988 	bPrivate = CK_FALSE;
989 	CPPUNIT_ASSERT(rv == CKR_USER_NOT_LOGGED_IN);
990 
991 	// Close session
992 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSession) );
993 	CPPUNIT_ASSERT(rv == CKR_OK);
994 
995 	// Create a read-write session
996 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
997 	CPPUNIT_ASSERT(rv == CKR_OK);
998 
999 	// Login USER into the sessions so we can create a private object
1000 	rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
1001 	CPPUNIT_ASSERT(rv == CKR_OK);
1002 
1003 	// Get a public session object
1004 	rv = createDataObjectNormal(hSession, IN_SESSION, IS_PUBLIC, hObject);
1005 	CPPUNIT_ASSERT(rv == CKR_OK);
1006 
1007 	// Allowed to go on token
1008 	bToken = CK_TRUE;
1009 	rv = CRYPTOKI_F_PTR( C_CopyObject(hSession, hObject, &attribs[0], 3, &hObject1) );
1010 	CPPUNIT_ASSERT(rv == CKR_OK);
1011 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hObject1) );
1012 	CPPUNIT_ASSERT(rv == CKR_OK);
1013 
1014 	// Allowed to go to private
1015 	bPrivate = CK_TRUE;
1016 	rv = CRYPTOKI_F_PTR( C_CopyObject(hSession, hObject, &attribs[0], 3, &hObject1) );
1017 	CPPUNIT_ASSERT(rv == CKR_OK);
1018 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hObject1) );
1019 	CPPUNIT_ASSERT(rv == CKR_OK);
1020 
1021 	// Not allowed to change a !ck8 parameter
1022 	CK_BYTE id[] = "Another object ID";
1023 	attribs[3].type = CKA_OBJECT_ID;
1024 	attribs[3].pValue = id;
1025 	attribs[3].ulValueLen = sizeof(id);
1026 	rv = CRYPTOKI_F_PTR( C_CopyObject(hSession, hObject, &attribs[0], 4, &hObject1) );
1027 	CPPUNIT_ASSERT(rv == CKR_ATTRIBUTE_READ_ONLY);
1028 
1029 	// Not allowed to downgrade privacy
1030 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hObject) );
1031 	CPPUNIT_ASSERT(rv == CKR_OK);
1032 	rv = createDataObjectNormal(hSession, IN_SESSION, IS_PRIVATE, hObject);
1033 	CPPUNIT_ASSERT(rv == CKR_OK);
1034 	bToken = CK_FALSE;
1035 	bPrivate = CK_FALSE;
1036 	rv = CRYPTOKI_F_PTR( C_CopyObject(hSession, hObject, &attribs[0], 3, &hObject1) );
1037 	CPPUNIT_ASSERT(rv == CKR_TEMPLATE_INCONSISTENT);
1038 
1039 	// Close session
1040 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSession) );
1041 	CPPUNIT_ASSERT(rv == CKR_OK);
1042 }
1043 
testDestroyObject()1044 void ObjectTests::testDestroyObject()
1045 {
1046 //    printf("\ntestDestroyObject\n");
1047 
1048 	// [PKCS#11 v2.40, C_Logout] When logout is successful...
1049 	// a. Any of the application's handles to private objects become invalid.
1050 	// b. Even if a user is later logged back into the token those handles remain invalid.
1051 	// c. All private session objects from sessions belonging to the application area destroyed.
1052 
1053 	// [PKCS#11 v2.40, C_CreateObject]
1054 	// Only session objects can be created during read-only session.
1055 	// Only public objects can be created unless the normal user is logged in.
1056 
1057 	CK_RV rv;
1058 	CK_SESSION_HANDLE hSessionRO;
1059 	CK_SESSION_HANDLE hSessionRW;
1060 	CK_OBJECT_HANDLE hObjectSessionPublic;
1061 	CK_OBJECT_HANDLE hObjectSessionPrivate;
1062 	CK_OBJECT_HANDLE hObjectTokenPublic;
1063 	CK_OBJECT_HANDLE hObjectTokenPrivate;
1064 	CK_OBJECT_HANDLE hObjectDestroy;
1065 
1066 	// Just make sure that we finalize any previous tests
1067 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1068 
1069 	// Open read-only session on when the token is not initialized should fail
1070 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
1071 	CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);
1072 
1073 	// Initialize the library and start the test.
1074 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1075 	CPPUNIT_ASSERT(rv == CKR_OK);
1076 
1077 	// Try to destroy an invalid object using an invalid session
1078 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSessionRO,CK_INVALID_HANDLE) );
1079 	CPPUNIT_ASSERT(rv == CKR_SESSION_HANDLE_INVALID);
1080 
1081 	// Create a read-only session.
1082 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
1083 	CPPUNIT_ASSERT(rv == CKR_OK);
1084 
1085 	// Trying to destroy an invalid object in a read-only session
1086 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSessionRO,CK_INVALID_HANDLE) );
1087 	CPPUNIT_ASSERT(rv == CKR_OBJECT_HANDLE_INVALID);
1088 
1089 	// Create a read-write session
1090 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) );
1091 	CPPUNIT_ASSERT(rv == CKR_OK);
1092 
1093 	// Trying to destroy an invalid object in a read-write session
1094 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSessionRO,CK_INVALID_HANDLE) );
1095 	CPPUNIT_ASSERT(rv == CKR_OBJECT_HANDLE_INVALID);
1096 
1097 	// Login USER into the sessions so we can create a private objects
1098 	rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) );
1099 	CPPUNIT_ASSERT(rv==CKR_OK);
1100 
1101 	// Create all permutations of session/token, public/private objects
1102 	rv = createDataObjectMinimal(hSessionRW, IN_SESSION, IS_PUBLIC, hObjectSessionPublic);
1103 	CPPUNIT_ASSERT(rv == CKR_OK);
1104 	rv = createDataObjectMinimal(hSessionRW, IN_SESSION, IS_PRIVATE, hObjectSessionPrivate);
1105 	CPPUNIT_ASSERT(rv == CKR_OK);
1106 	rv = createDataObjectMinimal(hSessionRW, ON_TOKEN, IS_PUBLIC, hObjectTokenPublic);
1107 	CPPUNIT_ASSERT(rv == CKR_OK);
1108 	rv = createDataObjectMinimal(hSessionRW, ON_TOKEN, IS_PRIVATE, hObjectTokenPrivate);
1109 	CPPUNIT_ASSERT(rv == CKR_OK);
1110 	rv = createDataObjectMCD(hSessionRW, IN_SESSION, IS_PUBLIC, CK_TRUE, CK_TRUE, CK_FALSE, hObjectDestroy);
1111 	CPPUNIT_ASSERT(rv == CKR_OK);
1112 
1113 	// We should not be able to destroy a non-destroyable object.
1114 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSessionRO,hObjectDestroy) );
1115 	CPPUNIT_ASSERT(rv == CKR_ACTION_PROHIBITED);
1116 
1117 	// On a read-only session we should not be able to destroy the public token object
1118 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSessionRO,hObjectTokenPublic) );
1119 	CPPUNIT_ASSERT(rv == CKR_SESSION_READ_ONLY);
1120 
1121 	// On a read-only session we should not be able to destroy the private token object
1122 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSessionRO,hObjectTokenPrivate) );
1123 	CPPUNIT_ASSERT(rv == CKR_SESSION_READ_ONLY);
1124 
1125 	// Logout with a different session than the one used for login should be fine.
1126 	rv = CRYPTOKI_F_PTR( C_Logout(hSessionRW) );
1127 	CPPUNIT_ASSERT(rv==CKR_OK);
1128 
1129 	// Login USER into the sessions so we can destroy private objects
1130 	rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) );
1131 	CPPUNIT_ASSERT(rv==CKR_OK);
1132 
1133 	// We should be able to destroy the public session object from a read-only session.
1134 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSessionRO,hObjectSessionPublic) );
1135 	CPPUNIT_ASSERT(rv == CKR_OK);
1136 
1137 	// All private session objects should have been destroyed when logging out.
1138 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSessionRW,hObjectSessionPrivate) );
1139 	CPPUNIT_ASSERT(rv == CKR_OBJECT_HANDLE_INVALID);
1140 
1141 	// We should be able to destroy the public token object now.
1142 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSessionRW,hObjectTokenPublic) );
1143 	CPPUNIT_ASSERT(rv == CKR_OK);
1144 
1145 	// All handles to private token objects should have been invalidated when logging out.
1146 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSessionRW,hObjectTokenPrivate) );
1147 	CPPUNIT_ASSERT(rv == CKR_OBJECT_HANDLE_INVALID);
1148 
1149 	// Close session
1150 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSessionRO) );
1151 	CPPUNIT_ASSERT(rv == CKR_OK);
1152 
1153 	// Close session
1154 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSessionRW) );
1155 	CPPUNIT_ASSERT(rv == CKR_OK);
1156 }
1157 
testGetObjectSize()1158 void ObjectTests::testGetObjectSize()
1159 {
1160 	CK_RV rv;
1161 	CK_SESSION_HANDLE hSession;
1162 	CK_OBJECT_HANDLE hObject;
1163 
1164 	// Just make sure that we finalize any previous tests
1165 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1166 
1167 	// Open read-only session on when the token is not initialized should fail
1168 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1169 	CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);
1170 
1171 	// Initialize the library and start the test.
1172 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1173 	CPPUNIT_ASSERT(rv == CKR_OK);
1174 
1175 	// Open a session
1176 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1177 	CPPUNIT_ASSERT(rv == CKR_OK);
1178 
1179 	// Get an object
1180 	rv = createDataObjectMinimal(hSession, IN_SESSION, IS_PUBLIC, hObject);
1181 	CPPUNIT_ASSERT(rv == CKR_OK);
1182 
1183 	// Get the object size
1184 	CK_ULONG objectSize;
1185 	rv = CRYPTOKI_F_PTR( C_GetObjectSize(hSession, hObject, &objectSize) );
1186 	CPPUNIT_ASSERT(rv == CKR_OK);
1187 	CPPUNIT_ASSERT(objectSize == CK_UNAVAILABLE_INFORMATION);
1188 
1189 	// Close session
1190 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSession) );
1191 	CPPUNIT_ASSERT(rv == CKR_OK);
1192 }
1193 
testGetAttributeValue()1194 void ObjectTests::testGetAttributeValue()
1195 {
1196 	CK_RV rv;
1197 	CK_SESSION_HANDLE hSessionRO;
1198 	CK_SESSION_HANDLE hSessionRW;
1199 	CK_OBJECT_HANDLE hObjectSessionPublic;
1200 
1201 	// Just make sure that we finalize any previous tests
1202 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1203 
1204 	// Open read-only session on when the token is not initialized should fail
1205 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
1206 	CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);
1207 
1208 	// Initialize the library and start the test.
1209 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1210 	CPPUNIT_ASSERT(rv == CKR_OK);
1211 
1212 	// Open read-only session
1213 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
1214 	CPPUNIT_ASSERT(rv == CKR_OK);
1215 
1216 	// Open read-write
1217 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) );
1218 	CPPUNIT_ASSERT(rv == CKR_OK);
1219 
1220 	// Try to destroy an invalid object using an invalid session
1221 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSessionRO,CK_INVALID_HANDLE,NULL,1) );
1222 	CPPUNIT_ASSERT(rv == CKR_ARGUMENTS_BAD);
1223 
1224 	// Create all permutations of session/token, public/private objects
1225 	rv = createDataObjectMinimal(hSessionRO, IN_SESSION, IS_PUBLIC, hObjectSessionPublic);
1226 	CPPUNIT_ASSERT(rv == CKR_OK);
1227 
1228 	CK_OBJECT_CLASS cClass = CKO_VENDOR_DEFINED;
1229 	CK_ATTRIBUTE attribs[] = {
1230 		{ CKA_CLASS, &cClass, sizeof(cClass) }
1231 	};
1232 
1233 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue (hSessionRO,hObjectSessionPublic,&attribs[0],1) );//sizeof(attribs)/sizeof(CK_ATTRIBUTE));
1234 	CPPUNIT_ASSERT(rv == CKR_OK);
1235 
1236 	// Close session
1237 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSessionRO) );
1238 	CPPUNIT_ASSERT(rv == CKR_OK);
1239 
1240 	// Close session
1241 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSessionRW) );
1242 	CPPUNIT_ASSERT(rv == CKR_OK);
1243 }
1244 
testSetAttributeValue()1245 void ObjectTests::testSetAttributeValue()
1246 {
1247 	// [PKCS#11 v2.40, 4.1.1 Creating objects]
1248 	//    1. If the supplied template specifies a value for an invalid attribute, then the attempt
1249 	//    should fail with the error code CKR_ATTRIBUTE_TYPE_INVALID. An attribute
1250 	//    is valid if it is either one of the attributes described in the Cryptoki specification or an
1251 	//    additional vendor-specific attribute supported by the library and token.
1252 	//
1253 	//    2. If the supplied template specifies an invalid value for a valid attribute, then the
1254 	//    attempt should fail with the error code CKR_ATTRIBUTE_VALUE_INVALID.
1255 	//    The valid values for Cryptoki attributes are described in the Cryptoki specification.
1256 	//
1257 	//    3. If the supplied template specifies a value for a read-only attribute, then the attempt
1258 	//    should fail with the error code CKR_ATTRIBUTE_READ_ONLY. Whether or not a
1259 	//    given Cryptoki attribute is read-only is explicitly stated in the Cryptoki specification;
1260 	//    however, a particular library and token may be even more restrictive than Cryptoki
1261 	//    specifies. In other words, an attribute which Cryptoki says is not read-only may
1262 	//    nonetheless be read-only under certain circumstances (i.e., in conjunction with some
1263 	//    combinations of other attributes) for a particular library and token. Whether or not a
1264 	//    given non-Cryptoki attribute is read-only is obviously outside the scope of Cryptoki.
1265 	//
1266 	//    4. N/A (Does not apply to C_SetAttributeValue)
1267 	//
1268 	//    5. If the attribute values in the supplied template, together with any default attribute
1269 	//    values and any attribute values contributed to the object by the object-creation
1270 	//    function itself, are inconsistent, then the attempt should fail with the error code
1271 	//    CKR_TEMPLATE_INCONSISTENT. A set of attribute values is inconsistent if not
1272 	//    all of its members can be satisfied simultaneously by the token, although each value
1273 	//    individually is valid in Cryptoki. One example of an inconsistent template would be
1274 	//    using a template which specifies two different values for the same attribute. Another
1275 	//    example would be trying to create a secret key object with an attribute which is
1276 	//    appropriate for various types of public keys or private keys, but not for secret keys.
1277 	//    A final example would be a template with an attribute that violates some token
1278 	//    specific requirement. Note that this final example of an inconsistent template is
1279 	//    token-dependent—on a different token, such a template might not be inconsistent.
1280 	//
1281 	//    6. If the supplied template specifies the same value for a particular attribute more than
1282 	//    once (or the template specifies the same value for a particular attribute that the object-
1283 	//    creation function itself contributes to the object), then the behavior of Cryptoki is not
1284 	//    completely specified. The attempt to create an object can either succeed—thereby
1285 	//    creating the same object that would have been created if the multiply-specified
1286 	//    attribute had only appeared once—or it can fail with error code
1287 	//    CKR_TEMPLATE_INCONSISTENT. Library developers are encouraged to make
1288 	//    their libraries behave as though the attribute had only appeared once in the template;
1289 	//    application developers are strongly encouraged never to put a particular attribute into
1290 	//    a particular template more than once.
1291 
1292 	CK_RV rv;
1293 	CK_SESSION_HANDLE hSessionRO;
1294 	CK_SESSION_HANDLE hSessionRW;
1295 	CK_OBJECT_HANDLE hObjectSessionPublic;
1296 	CK_OBJECT_HANDLE hObjectSessionPrivate;
1297 	CK_OBJECT_HANDLE hObjectTokenPublic;
1298 	CK_OBJECT_HANDLE hObjectTokenPrivate;
1299 	CK_OBJECT_HANDLE hObjectSet;
1300 
1301 	// Just make sure that we finalize any previous tests
1302 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1303 
1304 	// Open read-only session on when the token is not initialized should fail
1305 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
1306 	CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);
1307 
1308 	// Initialize the library and start the test.
1309 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1310 	CPPUNIT_ASSERT(rv == CKR_OK);
1311 
1312 	// Open read-only session
1313 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
1314 	CPPUNIT_ASSERT(rv == CKR_OK);
1315 
1316 	// Open read-write session
1317 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) );
1318 	CPPUNIT_ASSERT(rv == CKR_OK);
1319 
1320 	// Login USER into the sessions so we can create a private objects
1321 	rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) );
1322 	CPPUNIT_ASSERT(rv==CKR_OK);
1323 
1324 	// Create all permutations of session/token, public/private objects
1325 	rv = createDataObjectMinimal(hSessionRO, IN_SESSION, IS_PUBLIC, hObjectSessionPublic);
1326 	CPPUNIT_ASSERT(rv == CKR_OK);
1327 	rv = createDataObjectMinimal(hSessionRW, IN_SESSION, IS_PRIVATE, hObjectSessionPrivate);
1328 	CPPUNIT_ASSERT(rv == CKR_OK);
1329 	rv = createDataObjectMinimal(hSessionRW, ON_TOKEN, IS_PUBLIC, hObjectTokenPublic);
1330 	CPPUNIT_ASSERT(rv == CKR_OK);
1331 	rv = createDataObjectMinimal(hSessionRW, ON_TOKEN, IS_PRIVATE, hObjectTokenPrivate);
1332 	CPPUNIT_ASSERT(rv == CKR_OK);
1333 	rv = createDataObjectMCD(hSessionRO, IN_SESSION, IS_PUBLIC, CK_FALSE, CK_TRUE, CK_TRUE, hObjectSet);
1334 	CPPUNIT_ASSERT(rv == CKR_OK);
1335 
1336 	// Check that label can be modified on all combintations of session/token and public/private objects
1337 	const char  *pLabel = "Label modified via C_SetAttributeValue";
1338 	CK_ATTRIBUTE attribs[] = {
1339 		{ CKA_LABEL, (CK_UTF8CHAR_PTR)pLabel, strlen(pLabel) }
1340 	};
1341 
1342 	rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRO,hObjectSessionPublic,&attribs[0],1) );
1343 	CPPUNIT_ASSERT(rv == CKR_OK);
1344 	rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRO,hObjectSessionPrivate,&attribs[0],1) );
1345 	CPPUNIT_ASSERT(rv == CKR_OK);
1346 	rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRO,hObjectTokenPublic,&attribs[0],1) );
1347 	CPPUNIT_ASSERT(rv == CKR_SESSION_READ_ONLY);
1348 	rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRW,hObjectTokenPublic,&attribs[0],1) );
1349 	CPPUNIT_ASSERT(rv == CKR_OK);
1350 	rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRO,hObjectTokenPrivate,&attribs[0],1) );
1351 	CPPUNIT_ASSERT(rv == CKR_SESSION_READ_ONLY);
1352 	rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRW,hObjectTokenPrivate,&attribs[0],1) );
1353 	CPPUNIT_ASSERT(rv == CKR_OK);
1354 	rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRO,hObjectSet,&attribs[0],1) );
1355 	CPPUNIT_ASSERT(rv == CKR_ACTION_PROHIBITED);
1356 
1357 	attribs[0].pValue = NULL_PTR;
1358 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSessionRO,hObjectSessionPublic,&attribs[0],1) );
1359 	CPPUNIT_ASSERT(rv == CKR_OK);
1360 	CPPUNIT_ASSERT(attribs[0].ulValueLen == strlen(pLabel));
1361 
1362 	char pStoredLabel[64];
1363 	attribs[0].pValue = &pStoredLabel[0];
1364 	attribs[0].ulValueLen = 64;
1365 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSessionRO,hObjectSessionPublic,&attribs[0],1) );
1366 	CPPUNIT_ASSERT(rv == CKR_OK);
1367 	CPPUNIT_ASSERT(attribs[0].ulValueLen == strlen(pLabel));
1368 	CPPUNIT_ASSERT(memcmp(pLabel,pStoredLabel,strlen(pLabel)) == 0);
1369 
1370 	// Close session
1371 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSessionRO) );
1372 	CPPUNIT_ASSERT(rv == CKR_OK);
1373 
1374 	// Close session
1375 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSessionRW) );
1376 	CPPUNIT_ASSERT(rv == CKR_OK);
1377 }
1378 
testFindObjects()1379 void ObjectTests::testFindObjects()
1380 {
1381 	CK_RV rv;
1382 	CK_SESSION_HANDLE hSessionRO;
1383 	CK_SESSION_HANDLE hSessionRW;
1384 	CK_OBJECT_HANDLE hObjectSessionPublic;
1385 	CK_OBJECT_HANDLE hObjectSessionPrivate;
1386 	CK_OBJECT_HANDLE hObjectTokenPublic;
1387 	CK_OBJECT_HANDLE hObjectTokenPrivate;
1388 
1389 	// Just make sure that we finalize any previous tests
1390 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1391 
1392 	// Open read-only session on when the token is not initialized should fail
1393 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
1394 	CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);
1395 
1396 	// Initialize the library and start the test.
1397 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1398 	CPPUNIT_ASSERT(rv == CKR_OK);
1399 
1400 	// Open read-only session
1401 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
1402 	CPPUNIT_ASSERT(rv == CKR_OK);
1403 
1404 	// Open read-write session
1405 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) );
1406 	CPPUNIT_ASSERT(rv == CKR_OK);
1407 
1408 	// Login USER into the sessions so we can create a private objects
1409 	rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) );
1410 	CPPUNIT_ASSERT(rv==CKR_OK);
1411 
1412 	// Create all permutations of session/token, public/private objects
1413 	rv = createDataObjectMinimal(hSessionRO, IN_SESSION, IS_PUBLIC, hObjectSessionPublic);
1414 	CPPUNIT_ASSERT(rv == CKR_OK);
1415 	rv = createDataObjectMinimal(hSessionRW, IN_SESSION, IS_PRIVATE, hObjectSessionPrivate);
1416 	CPPUNIT_ASSERT(rv == CKR_OK);
1417 	rv = createDataObjectMinimal(hSessionRW, ON_TOKEN, IS_PUBLIC, hObjectTokenPublic);
1418 	CPPUNIT_ASSERT(rv == CKR_OK);
1419 	rv = createDataObjectMinimal(hSessionRW, ON_TOKEN, IS_PRIVATE, hObjectTokenPrivate);
1420 	CPPUNIT_ASSERT(rv == CKR_OK);
1421 
1422 	// Set labels for the objects
1423 	const char  *pLabel = "Label modified via C_SetAttributeValue";
1424 	CK_ATTRIBUTE attribs[] = {
1425 		{ CKA_LABEL, (CK_UTF8CHAR_PTR)pLabel, strlen(pLabel) }
1426 	};
1427 	rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRO,hObjectSessionPublic,&attribs[0],1) );
1428 	CPPUNIT_ASSERT(rv == CKR_OK);
1429 	rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRO,hObjectSessionPrivate,&attribs[0],1) );
1430 	CPPUNIT_ASSERT(rv == CKR_OK);
1431 	rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRW,hObjectTokenPublic,&attribs[0],1) );
1432 	CPPUNIT_ASSERT(rv == CKR_OK);
1433 	rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRW,hObjectTokenPrivate,&attribs[0],1) );
1434 	CPPUNIT_ASSERT(rv == CKR_OK);
1435 
1436 	// Now find the objects while logged in should find them all.
1437 	rv = CRYPTOKI_F_PTR( C_FindObjectsInit(hSessionRO,&attribs[0],1) );
1438 	CPPUNIT_ASSERT(rv == CKR_OK);
1439 	CK_OBJECT_HANDLE hObjects[16];
1440 	CK_ULONG ulObjectCount = 0;
1441 	rv = CRYPTOKI_F_PTR( C_FindObjects(hSessionRO,&hObjects[0],16,&ulObjectCount) );
1442 	CPPUNIT_ASSERT(rv == CKR_OK);
1443 	CPPUNIT_ASSERT(4 == ulObjectCount);
1444 	rv = CRYPTOKI_F_PTR( C_FindObjectsFinal(hSessionRO) );
1445 
1446 
1447 	rv = CRYPTOKI_F_PTR( C_Logout(hSessionRO) );
1448 	CPPUNIT_ASSERT(rv == CKR_OK);
1449 
1450 	// Now find the objects while no longer logged in should find only 2
1451 	rv = CRYPTOKI_F_PTR( C_FindObjectsInit(hSessionRO,&attribs[0],1) );
1452 	CPPUNIT_ASSERT(rv == CKR_OK);
1453 	rv = CRYPTOKI_F_PTR( C_FindObjects(hSessionRO,&hObjects[0],16,&ulObjectCount) );
1454 	CPPUNIT_ASSERT(rv == CKR_OK);
1455 	CPPUNIT_ASSERT(2 == ulObjectCount);
1456 	rv = CRYPTOKI_F_PTR( C_FindObjectsFinal(hSessionRO) );
1457 
1458 	// Close the session used to create the session objects, should also destroy the session objects.
1459 	rv = CRYPTOKI_F_PTR( C_CloseSession(hSessionRO) );
1460 	CPPUNIT_ASSERT(rv == CKR_OK);
1461 
1462 	// Now find just the public token object as public session object should be gone now.
1463 	rv = CRYPTOKI_F_PTR( C_FindObjectsInit(hSessionRW,&attribs[0],1) );
1464 	CPPUNIT_ASSERT(rv == CKR_OK);
1465 	rv = CRYPTOKI_F_PTR( C_FindObjects(hSessionRW,&hObjects[0],16,&ulObjectCount) );
1466 	CPPUNIT_ASSERT(rv == CKR_OK);
1467 	CPPUNIT_ASSERT(1 == ulObjectCount);
1468 	rv = CRYPTOKI_F_PTR( C_FindObjectsFinal(hSessionRW) );
1469 
1470 	// Login USER into the sessions so we can gain access to private objects
1471 	rv = CRYPTOKI_F_PTR( C_Login(hSessionRW,CKU_USER,m_userPin1,m_userPin1Length) );
1472 	CPPUNIT_ASSERT(rv==CKR_OK);
1473 
1474 	// Now find just the public token object as public session object should be gone now.
1475 	rv = CRYPTOKI_F_PTR( C_FindObjectsInit(hSessionRW,&attribs[0],1) );
1476 	CPPUNIT_ASSERT(rv == CKR_OK);
1477 	rv = CRYPTOKI_F_PTR( C_FindObjects(hSessionRW,&hObjects[0],16,&ulObjectCount) );
1478 	CPPUNIT_ASSERT(rv == CKR_OK);
1479 	CPPUNIT_ASSERT(2 == ulObjectCount);
1480 	rv = CRYPTOKI_F_PTR( C_FindObjectsFinal(hSessionRW) );
1481 }
1482 
1483 
testGenerateKeys()1484 void ObjectTests::testGenerateKeys()
1485 {
1486 	CK_RV rv;
1487 	CK_SESSION_HANDLE hSessionRO;
1488 	CK_SESSION_HANDLE hSessionRW;
1489 
1490 	// Just make sure that we finalize any previous tests
1491 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1492 
1493 	// Open read-only session on when the token is not initialized should fail
1494 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
1495 	CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);
1496 
1497 	// Initialize the library and start the test.
1498 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1499 	CPPUNIT_ASSERT(rv == CKR_OK);
1500 
1501 	// Open read-only session
1502 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
1503 	CPPUNIT_ASSERT(rv == CKR_OK);
1504 
1505 	// Open read-write session
1506 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) );
1507 	CPPUNIT_ASSERT(rv == CKR_OK);
1508 
1509 	// Login USER into the sessions so we can create a private objects
1510 	rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) );
1511 	CPPUNIT_ASSERT(rv==CKR_OK);
1512 
1513 	CK_OBJECT_HANDLE hPuk = CK_INVALID_HANDLE;
1514 	CK_OBJECT_HANDLE hPrk = CK_INVALID_HANDLE;
1515 
1516 	// Generate all combinations of session/token public/private key pairs.
1517 	rv = generateRsaKeyPair(hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk,hPrk);
1518 	CPPUNIT_ASSERT(rv == CKR_OK);
1519 	rv = generateRsaKeyPair(hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PRIVATE,hPuk,hPrk);
1520 	CPPUNIT_ASSERT(rv == CKR_OK);
1521 	rv = generateRsaKeyPair(hSessionRW,IN_SESSION,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk,hPrk);
1522 	CPPUNIT_ASSERT(rv == CKR_OK);
1523 	rv = generateRsaKeyPair(hSessionRW,IN_SESSION,IS_PUBLIC,ON_TOKEN,IS_PRIVATE,hPuk,hPrk);
1524 	CPPUNIT_ASSERT(rv == CKR_OK);
1525 
1526 	rv = generateRsaKeyPair(hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PUBLIC,hPuk,hPrk);
1527 	CPPUNIT_ASSERT(rv == CKR_OK);
1528 	rv = generateRsaKeyPair(hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk,hPrk);
1529 	CPPUNIT_ASSERT(rv == CKR_OK);
1530 	rv = generateRsaKeyPair(hSessionRW,IN_SESSION,IS_PRIVATE,ON_TOKEN,IS_PUBLIC,hPuk,hPrk);
1531 	CPPUNIT_ASSERT(rv == CKR_OK);
1532 	rv = generateRsaKeyPair(hSessionRW,IN_SESSION,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk,hPrk);
1533 	CPPUNIT_ASSERT(rv == CKR_OK);
1534 
1535 	rv = generateRsaKeyPair(hSessionRW,ON_TOKEN,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk,hPrk);
1536 	CPPUNIT_ASSERT(rv == CKR_OK);
1537 	rv = generateRsaKeyPair(hSessionRW,ON_TOKEN,IS_PUBLIC,IN_SESSION,IS_PRIVATE,hPuk,hPrk);
1538 	CPPUNIT_ASSERT(rv == CKR_OK);
1539 	rv = generateRsaKeyPair(hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk,hPrk);
1540 	CPPUNIT_ASSERT(rv == CKR_OK);
1541 	rv = generateRsaKeyPair(hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PRIVATE,hPuk,hPrk);
1542 	CPPUNIT_ASSERT(rv == CKR_OK);
1543 
1544 	rv = generateRsaKeyPair(hSessionRW,ON_TOKEN,IS_PRIVATE,IN_SESSION,IS_PUBLIC,hPuk,hPrk);
1545 	CPPUNIT_ASSERT(rv == CKR_OK);
1546 	rv = generateRsaKeyPair(hSessionRW,ON_TOKEN,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk,hPrk);
1547 	CPPUNIT_ASSERT(rv == CKR_OK);
1548 	rv = generateRsaKeyPair(hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PUBLIC,hPuk,hPrk);
1549 	CPPUNIT_ASSERT(rv == CKR_OK);
1550 	rv = generateRsaKeyPair(hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk,hPrk);
1551 	CPPUNIT_ASSERT(rv == CKR_OK);
1552 }
1553 
testCreateCertificates()1554 void ObjectTests::testCreateCertificates()
1555 {
1556 	CK_RV rv;
1557 	CK_SESSION_HANDLE hSession;
1558 
1559 	// Just make sure that we finalize any previous tests
1560 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1561 
1562 	// Initialize the library and start the test.
1563 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1564 	CPPUNIT_ASSERT(rv == CKR_OK);
1565 
1566 	// Open read-write session
1567 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1568 	CPPUNIT_ASSERT(rv == CKR_OK);
1569 
1570 	// Login USER into the sessions so we can create a private objects
1571 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) );
1572 	CPPUNIT_ASSERT(rv==CKR_OK);
1573 
1574 	CK_OBJECT_HANDLE hObject = CK_INVALID_HANDLE;
1575 
1576 	rv = createCertificateObjectIncomplete(hSession,IN_SESSION,IS_PUBLIC,hObject);
1577 	CPPUNIT_ASSERT(rv == CKR_TEMPLATE_INCOMPLETE);
1578 	rv = createCertificateObjectX509(hSession,IN_SESSION,IS_PUBLIC,hObject);
1579 	CPPUNIT_ASSERT(rv == CKR_OK);
1580 
1581 	CK_BYTE pCheckValue[] = { 0x2b, 0x84, 0xf6 };
1582 	CK_ATTRIBUTE attribs[] = {
1583 		{ CKA_CHECK_VALUE, pCheckValue, sizeof(pCheckValue) }
1584 	};
1585 
1586 	rv = CRYPTOKI_F_PTR( C_SetAttributeValue(hSession, hObject, attribs, 1) );
1587 	CPPUNIT_ASSERT(rv == CKR_ATTRIBUTE_READ_ONLY);
1588 }
1589 
testDefaultDataAttributes()1590 void ObjectTests::testDefaultDataAttributes()
1591 {
1592 	CK_RV rv;
1593 	CK_SESSION_HANDLE hSession;
1594 	CK_OBJECT_HANDLE hObject = CK_INVALID_HANDLE;
1595 
1596 	// Minimal data object
1597 	CK_OBJECT_CLASS objClass = CKO_DATA;
1598 	CK_ATTRIBUTE objTemplate[] = {
1599 		{ CKA_CLASS, &objClass, sizeof(objClass) }
1600 	};
1601 
1602 	// Just make sure that we finalize any previous tests
1603 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1604 
1605 	// Initialize the library and start the test.
1606 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1607 	CPPUNIT_ASSERT(rv == CKR_OK);
1608 
1609 	// Open read-write session
1610 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1611 	CPPUNIT_ASSERT(rv == CKR_OK);
1612 
1613 	// Login USER into the sessions so we can create a private objects
1614 	rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
1615 	CPPUNIT_ASSERT(rv == CKR_OK);
1616 
1617 	// Create minimal data object
1618 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, objTemplate, sizeof(objTemplate)/sizeof(CK_ATTRIBUTE), &hObject) );
1619 	CPPUNIT_ASSERT(rv == CKR_OK);
1620 
1621 	// Check attributes in data object
1622 	checkCommonObjectAttributes(hSession, hObject, objClass);
1623 	checkCommonStorageObjectAttributes(hSession, hObject, CK_FALSE, CK_TRUE, CK_TRUE, NULL_PTR, 0, CK_TRUE, CK_TRUE);
1624 	checkDataObjectAttributes(hSession, hObject, NULL_PTR, 0, NULL_PTR, 0, NULL_PTR, 0);
1625 }
1626 
testDefaultX509CertAttributes()1627 void ObjectTests::testDefaultX509CertAttributes()
1628 {
1629 	CK_RV rv;
1630 	CK_SESSION_HANDLE hSession;
1631 	CK_OBJECT_HANDLE hObject = CK_INVALID_HANDLE;
1632 
1633 	// Minimal X509 certificate object
1634 	CK_OBJECT_CLASS objClass = CKO_CERTIFICATE;
1635 	CK_CERTIFICATE_TYPE certificateType = CKC_X_509;
1636 	CK_BYTE pSubject[] = "Test1";
1637 	CK_BYTE pValue[] = "Test2";
1638 	CK_BYTE pCheckValue[] = { 0x2b, 0x84, 0xf6 };
1639 	CK_DATE emptyDate;
1640 	CK_ATTRIBUTE objTemplate[] = {
1641 		{ CKA_CLASS, &objClass, sizeof(objClass) },
1642 		{ CKA_CERTIFICATE_TYPE, &certificateType, sizeof(certificateType) },
1643 		{ CKA_SUBJECT, pSubject, sizeof(pSubject)-1 },
1644 		{ CKA_VALUE, pValue, sizeof(pValue)-1 }
1645 	};
1646 
1647 	// Just make sure that we finalize any previous tests
1648 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1649 
1650 	// Initialize the library and start the test.
1651 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1652 	CPPUNIT_ASSERT(rv == CKR_OK);
1653 
1654 	// Open read-write session
1655 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1656 	CPPUNIT_ASSERT(rv == CKR_OK);
1657 
1658 	// Login USER into the sessions so we can create a private objects
1659 	rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
1660 	CPPUNIT_ASSERT(rv == CKR_OK);
1661 
1662 	// Create minimal X509 certificate
1663 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, objTemplate, sizeof(objTemplate)/sizeof(CK_ATTRIBUTE), &hObject) );
1664 	CPPUNIT_ASSERT(rv == CKR_OK);
1665 
1666 	// Check attributes in X509 certificate object
1667 	checkCommonObjectAttributes(hSession, hObject, objClass);
1668 	checkCommonStorageObjectAttributes(hSession, hObject, CK_FALSE, CK_FALSE, CK_TRUE, NULL_PTR, 0, CK_TRUE, CK_TRUE);
1669 	memset(&emptyDate, 0, sizeof(emptyDate));
1670 	checkCommonCertificateObjectAttributes(hSession, hObject, CKC_X_509, CK_FALSE, 0, pCheckValue, sizeof(pCheckValue), emptyDate, 0, emptyDate, 0);
1671 	checkX509CertificateObjectAttributes(hSession, hObject, pSubject, sizeof(pSubject)-1, NULL_PTR, 0, NULL_PTR, 0, NULL_PTR, 0, pValue, sizeof(pValue)-1, NULL_PTR, 0, NULL_PTR, 0, NULL_PTR, 0, 0, CKM_SHA_1);
1672 }
1673 
testDefaultRSAPubAttributes()1674 void ObjectTests::testDefaultRSAPubAttributes()
1675 {
1676 	CK_RV rv;
1677 	CK_SESSION_HANDLE hSession;
1678 	CK_OBJECT_HANDLE hObject = CK_INVALID_HANDLE;
1679 
1680 	// Minimal RSA public key object
1681 	CK_OBJECT_CLASS objClass = CKO_PUBLIC_KEY;
1682 	CK_KEY_TYPE objType = CKK_RSA;
1683 	CK_BYTE pN[] = { 0xC6, 0x47, 0xDD, 0x74, 0x3B, 0xCB, 0xDC, 0x6F, 0xCE, 0xA7,
1684 			 0xF0, 0x5F, 0x29, 0x4B, 0x27, 0x00, 0xCC, 0x92, 0xE9, 0x20,
1685 			 0x8A, 0x2C, 0x87, 0x36, 0x47, 0x24, 0xB0, 0xD5, 0x7D, 0xB0,
1686 			 0x92, 0x01, 0xA0, 0xA3, 0x55, 0x2E, 0x3F, 0xFE, 0xA7, 0x4C,
1687 			 0x4B, 0x3F, 0x9D, 0x4E, 0xCB, 0x78, 0x12, 0xA9, 0x42, 0xAD,
1688 			 0x51, 0x1F, 0x3B, 0xBD, 0x3D, 0x6A, 0xE5, 0x38, 0xB7, 0x45,
1689 			 0x65, 0x50, 0x30, 0x35 };
1690         CK_BYTE pE[] = { 0x01, 0x00, 0x01 };
1691 	CK_DATE emptyDate;
1692 	CK_ATTRIBUTE objTemplate[] = {
1693 		{ CKA_CLASS, &objClass, sizeof(objClass) },
1694 		{ CKA_KEY_TYPE, &objType, sizeof(objType) },
1695 		{ CKA_MODULUS, pN, sizeof(pN) },
1696 		{ CKA_PUBLIC_EXPONENT, pE, sizeof(pE) }
1697 	};
1698 
1699 	// Just make sure that we finalize any previous tests
1700 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1701 
1702 	// Initialize the library and start the test.
1703 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1704 	CPPUNIT_ASSERT(rv == CKR_OK);
1705 
1706 	// Open read-write session
1707 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1708 	CPPUNIT_ASSERT(rv == CKR_OK);
1709 
1710 	// Login USER into the sessions so we can create a private objects
1711 	rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
1712 	CPPUNIT_ASSERT(rv == CKR_OK);
1713 
1714 	// Create minimal RSA public key object
1715 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, objTemplate, sizeof(objTemplate)/sizeof(CK_ATTRIBUTE), &hObject) );
1716 	CPPUNIT_ASSERT(rv == CKR_OK);
1717 
1718 	// Check attributes in RSA public key object
1719 	checkCommonObjectAttributes(hSession, hObject, objClass);
1720 	checkCommonStorageObjectAttributes(hSession, hObject, CK_FALSE, CK_FALSE, CK_TRUE, NULL_PTR, 0, CK_TRUE, CK_TRUE);
1721 	memset(&emptyDate, 0, sizeof(emptyDate));
1722 	checkCommonKeyAttributes(hSession, hObject, objType, NULL_PTR, 0, emptyDate, 0, emptyDate, 0, CK_FALSE, CK_FALSE, CK_UNAVAILABLE_INFORMATION, NULL_PTR, 0);
1723 	checkCommonPublicKeyAttributes(hSession, hObject, NULL_PTR, 0, CK_TRUE, CK_TRUE, CK_TRUE, CK_TRUE, CK_FALSE, NULL_PTR, 0);
1724 	checkCommonRSAPublicKeyAttributes(hSession, hObject, pN, sizeof(pN), 512, pE, sizeof(pE));
1725 }
1726 
testDefaultRSAPrivAttributes()1727 void ObjectTests::testDefaultRSAPrivAttributes()
1728 {
1729 	CK_RV rv;
1730 	CK_SESSION_HANDLE hSession;
1731 	CK_OBJECT_HANDLE hObject = CK_INVALID_HANDLE;
1732 
1733 	// Minimal RSA private key object
1734 	CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
1735 	CK_KEY_TYPE objType = CKK_RSA;
1736 	CK_BBOOL bTrue = CK_TRUE;
1737 	CK_BBOOL bFalse = CK_FALSE;
1738 	CK_BYTE pN[] = { 0xC6, 0x47, 0xDD, 0x74, 0x3B, 0xCB, 0xDC, 0x6F, 0xCE, 0xA7,
1739 			 0xF0, 0x5F, 0x29, 0x4B, 0x27, 0x00, 0xCC, 0x92, 0xE9, 0x20,
1740 			 0x8A, 0x2C, 0x87, 0x36, 0x47, 0x24, 0xB0, 0xD5, 0x7D, 0xB0,
1741 			 0x92, 0x01, 0xA0, 0xA3, 0x55, 0x2E, 0x3F, 0xFE, 0xA7, 0x4C,
1742 			 0x4B, 0x3F, 0x9D, 0x4E, 0xCB, 0x78, 0x12, 0xA9, 0x42, 0xAD,
1743 			 0x51, 0x1F, 0x3B, 0xBD, 0x3D, 0x6A, 0xE5, 0x38, 0xB7, 0x45,
1744 			 0x65, 0x50, 0x30, 0x35 };
1745         CK_BYTE pD[] = { 0x6D, 0x94, 0x6B, 0xEB, 0xFF, 0xDC, 0x03, 0x80, 0x7B, 0x0A,
1746 			 0x4F, 0x0A, 0x98, 0x6C, 0xA3, 0x2A, 0x8A, 0xE4, 0xAA, 0x18,
1747 			 0x44, 0xA4, 0xA5, 0x39, 0x37, 0x0A, 0x2C, 0xFC, 0x5F, 0xD1,
1748 			 0x44, 0x6E, 0xCE, 0x25, 0x9B, 0xE5, 0xD1, 0x51, 0xAF, 0xA8,
1749 			 0x30, 0xD1, 0x4D, 0x3C, 0x60, 0x33, 0xB5, 0xED, 0x4C, 0x39,
1750 			 0xDA, 0x68, 0x78, 0xF9, 0x6B, 0x4F, 0x47, 0x55, 0xB2, 0x02,
1751 			 0x00, 0x7E, 0x9C, 0x05 };
1752 	CK_DATE emptyDate;
1753 	// Make the key non-sensitive and extractable so that we can test it.
1754 	CK_ATTRIBUTE objTemplate[] = {
1755 		{ CKA_CLASS, &objClass, sizeof(objClass) },
1756 		{ CKA_KEY_TYPE, &objType, sizeof(objType) },
1757 		{ CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
1758 		{ CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) },
1759 		{ CKA_MODULUS, pN, sizeof(pN) },
1760 		{ CKA_PRIVATE_EXPONENT, pD, sizeof(pD) }
1761 	};
1762 
1763 	// Just make sure that we finalize any previous tests
1764 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1765 
1766 	// Initialize the library and start the test.
1767 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1768 	CPPUNIT_ASSERT(rv == CKR_OK);
1769 
1770 	// Open read-write session
1771 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1772 	CPPUNIT_ASSERT(rv == CKR_OK);
1773 
1774 	// Login USER into the sessions so we can create a private objects
1775 	rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
1776 	CPPUNIT_ASSERT(rv == CKR_OK);
1777 
1778 	// Create minimal RSA public key object
1779 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, objTemplate, sizeof(objTemplate)/sizeof(CK_ATTRIBUTE), &hObject) );
1780 	CPPUNIT_ASSERT(rv == CKR_OK);
1781 
1782 	// Check attributes in RSA public key object
1783 	checkCommonObjectAttributes(hSession, hObject, objClass);
1784 	checkCommonStorageObjectAttributes(hSession, hObject, CK_FALSE, CK_TRUE, CK_TRUE, NULL_PTR, 0, CK_TRUE, CK_TRUE);
1785 	memset(&emptyDate, 0, sizeof(emptyDate));
1786 	checkCommonKeyAttributes(hSession, hObject, objType, NULL_PTR, 0, emptyDate, 0, emptyDate, 0, CK_FALSE, CK_FALSE, CK_UNAVAILABLE_INFORMATION, NULL_PTR, 0);
1787 	checkCommonPrivateKeyAttributes(hSession, hObject, NULL_PTR, 0, CK_FALSE, CK_TRUE, CK_TRUE, CK_TRUE, CK_TRUE, CK_TRUE, CK_FALSE, CK_FALSE, CK_FALSE, NULL_PTR, 0, CK_FALSE);
1788 	checkCommonRSAPrivateKeyAttributes(hSession, hObject, pN, sizeof(pN), NULL_PTR, 0, pD, sizeof(pD), NULL_PTR, 0, NULL_PTR, 0, NULL_PTR, 0, NULL_PTR, 0, NULL_PTR, 0);
1789 }
1790 
testAlwaysNeverAttribute()1791 void ObjectTests::testAlwaysNeverAttribute()
1792 {
1793 	CK_RV rv;
1794 	CK_SESSION_HANDLE hSession;
1795 	CK_OBJECT_HANDLE hPuk = CK_INVALID_HANDLE;
1796 	CK_OBJECT_HANDLE hPrk = CK_INVALID_HANDLE;
1797 
1798 	CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
1799 	CK_ULONG bits = 1536;
1800 	CK_BBOOL bFalse = CK_FALSE;
1801 	CK_BBOOL bTrue = CK_TRUE;
1802 	CK_BBOOL always;
1803 	CK_BBOOL never;
1804 	CK_ATTRIBUTE pukAttribs[] = {
1805 		{ CKA_MODULUS_BITS, &bits, sizeof(bits) }
1806 	};
1807 	CK_ATTRIBUTE prkAttribs[] = {
1808 		{ CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
1809 		{ CKA_EXTRACTABLE, &bFalse, sizeof(bFalse) }
1810 	};
1811 	CK_ATTRIBUTE getTemplate[] = {
1812 		{ CKA_ALWAYS_SENSITIVE, &always, sizeof(always) },
1813 		{ CKA_NEVER_EXTRACTABLE, &never, sizeof(never) }
1814 	};
1815 
1816 	// Just make sure that we finalize any previous tests
1817 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1818 
1819 	// Initialize the library and start the test.
1820 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1821 	CPPUNIT_ASSERT(rv == CKR_OK);
1822 
1823 	// Open read-write session
1824 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1825 	CPPUNIT_ASSERT(rv == CKR_OK);
1826 
1827 	// Login USER into the sessions so we can create a private objects
1828 	rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
1829 	CPPUNIT_ASSERT(rv == CKR_OK);
1830 
1831 	// Create object
1832 	rv = CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism, pukAttribs, 1, prkAttribs, 2, &hPuk, &hPrk) );
1833 	CPPUNIT_ASSERT(rv == CKR_OK);
1834 
1835 	// Check value
1836 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, getTemplate, 2) );
1837 	CPPUNIT_ASSERT(rv == CKR_OK);
1838 	CPPUNIT_ASSERT(always == CK_TRUE);
1839 	CPPUNIT_ASSERT(never == CK_TRUE);
1840 
1841 	// Set value
1842 	rv = CRYPTOKI_F_PTR( C_SetAttributeValue(hSession, hPrk, prkAttribs, 2) );
1843 	CPPUNIT_ASSERT(rv == CKR_ATTRIBUTE_READ_ONLY);
1844 
1845 	// Create object
1846 	prkAttribs[0].pValue = &bFalse;
1847 	prkAttribs[1].pValue = &bTrue;
1848 	rv = CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism, pukAttribs, 1, prkAttribs, 2, &hPuk, &hPrk) );
1849 	CPPUNIT_ASSERT(rv == CKR_OK);
1850 
1851 	// Check value
1852 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, getTemplate, 2) );
1853 	CPPUNIT_ASSERT(rv == CKR_OK);
1854 	CPPUNIT_ASSERT(always == CK_FALSE);
1855 	CPPUNIT_ASSERT(never == CK_FALSE);
1856 }
1857 
testSensitiveAttributes()1858 void ObjectTests::testSensitiveAttributes()
1859 {
1860 	CK_RV rv;
1861 	CK_SESSION_HANDLE hSession;
1862 	CK_OBJECT_HANDLE hPuk = CK_INVALID_HANDLE;
1863 	CK_OBJECT_HANDLE hPrk = CK_INVALID_HANDLE;
1864 
1865 	CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
1866 	CK_ULONG bits = 1536;
1867 	CK_BBOOL bSensitive = CK_TRUE;
1868 	CK_BBOOL bTrue = CK_TRUE;
1869 	CK_ATTRIBUTE pukAttribs[] = {
1870 		{ CKA_MODULUS_BITS, &bits, sizeof(bits) }
1871 	};
1872 	// Sensitive attributes cannot be revealed in plaintext even if wrapping is allowed
1873 	CK_ATTRIBUTE prkAttribs[] = {
1874 		{ CKA_SENSITIVE, &bSensitive, sizeof(bSensitive) },
1875 		{ CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) }
1876 	};
1877 	CK_ATTRIBUTE getTemplate[] = {
1878 		{ CKA_PRIVATE_EXPONENT, NULL_PTR, 0 },
1879 		{ CKA_PRIME_1, NULL_PTR, 0 },
1880 		{ CKA_PRIME_2, NULL_PTR, 0 },
1881 		{ CKA_EXPONENT_1, NULL_PTR, 0 },
1882 		{ CKA_EXPONENT_2, NULL_PTR, 0 },
1883 		{ CKA_COEFFICIENT, NULL_PTR, 0 }
1884 	};
1885 
1886 	// Just make sure that we finalize any previous tests
1887 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1888 
1889 	// Initialize the library and start the test.
1890 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1891 	CPPUNIT_ASSERT(rv == CKR_OK);
1892 
1893 	// Open read-write session
1894 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1895 	CPPUNIT_ASSERT(rv == CKR_OK);
1896 
1897 	// Login USER into the sessions so we can create a private objects
1898 	rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
1899 	CPPUNIT_ASSERT(rv == CKR_OK);
1900 
1901 	// Create object
1902 	rv = CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism, pukAttribs, 1, prkAttribs, 2, &hPuk, &hPrk) );
1903 	CPPUNIT_ASSERT(rv == CKR_OK);
1904 
1905 	// Check value
1906 	for (int i = 0; i < 6; i++)
1907 	{
1908 		rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, &getTemplate[i], 1) );
1909 		CPPUNIT_ASSERT(rv == CKR_ATTRIBUTE_SENSITIVE);
1910 	}
1911 
1912 	// Retry with non-sensitive object
1913 	bSensitive = CK_FALSE;
1914 	rv = CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism, pukAttribs, 1, prkAttribs, 2, &hPuk, &hPrk) );
1915 	CPPUNIT_ASSERT(rv == CKR_OK);
1916 
1917 	// Check value
1918 	for (int i = 0; i < 6; i++)
1919 	{
1920 		rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, &getTemplate[i], 1) );
1921 		CPPUNIT_ASSERT(rv == CKR_OK);
1922 	}
1923 }
1924 
testGetInvalidAttribute()1925 void ObjectTests::testGetInvalidAttribute()
1926 {
1927 	CK_RV rv;
1928 	CK_SESSION_HANDLE hSession;
1929 	CK_OBJECT_HANDLE hObject = CK_INVALID_HANDLE;
1930 
1931 	// Minimal data object
1932 	CK_OBJECT_CLASS objClass = CKO_DATA;
1933 	CK_BBOOL bSign;
1934 	CK_ATTRIBUTE objTemplate[] = {
1935 		{ CKA_CLASS, &objClass, sizeof(objClass) }
1936 	};
1937 	CK_ATTRIBUTE getTemplate[] = {
1938 		{ CKA_SIGN, &bSign, sizeof(bSign) }
1939 	};
1940 
1941 	// Just make sure that we finalize any previous tests
1942 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1943 
1944 	// Initialize the library and start the test.
1945 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1946 	CPPUNIT_ASSERT(rv == CKR_OK);
1947 
1948 	// Open read-write session
1949 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1950 	CPPUNIT_ASSERT(rv == CKR_OK);
1951 
1952 	// Login USER into the sessions so we can create a private objects
1953 	rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
1954 	CPPUNIT_ASSERT(rv == CKR_OK);
1955 
1956 	// Create minimal data object
1957 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, objTemplate, 1, &hObject) );
1958 	CPPUNIT_ASSERT(rv == CKR_OK);
1959 
1960 	// Check value
1961 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, getTemplate, 1) );
1962 	CPPUNIT_ASSERT(rv == CKR_ATTRIBUTE_TYPE_INVALID);
1963 }
1964 
testReAuthentication()1965 void ObjectTests::testReAuthentication()
1966 {
1967 	CK_RV rv;
1968 	CK_SESSION_HANDLE hSession;
1969 	CK_OBJECT_HANDLE hPuk = CK_INVALID_HANDLE;
1970 	CK_OBJECT_HANDLE hPrk = CK_INVALID_HANDLE;
1971 
1972 	CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
1973 	CK_ULONG bits = 1024;
1974 	CK_BBOOL bTrue = CK_TRUE;
1975 	CK_ATTRIBUTE pukAttribs[] = {
1976 		{ CKA_MODULUS_BITS, &bits, sizeof(bits) }
1977 	};
1978 	CK_ATTRIBUTE prkAttribs[] = {
1979 		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
1980 		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
1981 		{ CKA_SIGN, &bTrue, sizeof(bTrue) },
1982 		{ CKA_ALWAYS_AUTHENTICATE, &bTrue, sizeof(bTrue) }
1983 	};
1984 
1985 	CK_MECHANISM signMech = { CKM_SHA256_RSA_PKCS, NULL_PTR, 0 };
1986 	CK_BYTE data[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
1987 	CK_BYTE signature256[256];
1988 	CK_ULONG signature256Len = sizeof(signature256);
1989 
1990 	CK_MECHANISM encMech = { CKM_RSA_PKCS, NULL_PTR, 0 };
1991 	CK_BYTE cipherText[256];
1992 	CK_ULONG ulCipherTextLen = sizeof(cipherText);
1993 	CK_BYTE recoveredText[256];
1994 	CK_ULONG ulRecoveredTextLen = sizeof(recoveredText);
1995 
1996 	// Just make sure that we finalize any previous tests
1997 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1998 
1999 	// Initialize the library and start the test.
2000 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
2001 	CPPUNIT_ASSERT(rv == CKR_OK);
2002 
2003 	// Open read-write session
2004 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
2005 	CPPUNIT_ASSERT(rv == CKR_OK);
2006 
2007 	// Login USER into the sessions so we can create private objects
2008 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) );
2009 	CPPUNIT_ASSERT(rv == CKR_OK);
2010 
2011 	// Create object
2012 	rv = CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism, pukAttribs, 1, prkAttribs, 4, &hPuk, &hPrk) );
2013 	CPPUNIT_ASSERT(rv == CKR_OK);
2014 
2015 	// Test C_Sign with re-authentication with invalid and valid PIN
2016 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_CONTEXT_SPECIFIC,m_userPin1,m_userPin1Length) );
2017 	CPPUNIT_ASSERT(rv == CKR_OPERATION_NOT_INITIALIZED);
2018 	rv = CRYPTOKI_F_PTR( C_SignInit(hSession, &signMech, hPrk) );
2019 	CPPUNIT_ASSERT(rv == CKR_OK);
2020 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_CONTEXT_SPECIFIC,m_userPin1,m_userPin1Length-1) );
2021 	CPPUNIT_ASSERT(rv == CKR_PIN_INCORRECT);
2022 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_CONTEXT_SPECIFIC,m_userPin1,m_userPin1Length) );
2023 	CPPUNIT_ASSERT(rv == CKR_OK);
2024 	rv = CRYPTOKI_F_PTR( C_Sign(hSession, data, sizeof(data), signature256, &signature256Len) );
2025 	CPPUNIT_ASSERT(rv == CKR_OK);
2026 
2027 	// Test C_Sign without re-authentication
2028 	rv = CRYPTOKI_F_PTR( C_SignInit(hSession, &signMech, hPrk) );
2029 	CPPUNIT_ASSERT(rv == CKR_OK);
2030 	rv = CRYPTOKI_F_PTR( C_Sign(hSession, data, sizeof(data), signature256, &signature256Len) );
2031 	CPPUNIT_ASSERT(rv == CKR_USER_NOT_LOGGED_IN);
2032 	rv = CRYPTOKI_F_PTR( C_Sign(hSession, data, sizeof(data), signature256, &signature256Len) );
2033 	CPPUNIT_ASSERT(rv == CKR_OPERATION_NOT_INITIALIZED);
2034 
2035 	// Test C_SignUpdate with re-authentication
2036 	rv = CRYPTOKI_F_PTR( C_SignInit(hSession, &signMech, hPrk) );
2037 	CPPUNIT_ASSERT(rv == CKR_OK);
2038 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_CONTEXT_SPECIFIC,m_userPin1,m_userPin1Length) );
2039 	CPPUNIT_ASSERT(rv == CKR_OK);
2040 	rv = CRYPTOKI_F_PTR( C_SignUpdate(hSession, data, sizeof(data)) );
2041 	CPPUNIT_ASSERT(rv == CKR_OK);
2042 	rv = CRYPTOKI_F_PTR( C_SignFinal(hSession, signature256, &signature256Len) );
2043 	CPPUNIT_ASSERT(rv == CKR_OK);
2044 
2045 	// Test C_SignUpdate without re-authentication
2046 	rv = CRYPTOKI_F_PTR( C_SignInit(hSession, &signMech, hPrk) );
2047 	CPPUNIT_ASSERT(rv == CKR_OK);
2048 	rv = CRYPTOKI_F_PTR( C_SignUpdate(hSession, data, sizeof(data)) );
2049 	CPPUNIT_ASSERT(rv == CKR_USER_NOT_LOGGED_IN);
2050 	rv = CRYPTOKI_F_PTR( C_SignUpdate(hSession, data, sizeof(data)) );
2051 	CPPUNIT_ASSERT(rv == CKR_OPERATION_NOT_INITIALIZED);
2052 
2053 	// Test C_SignFinal with re-authentication
2054 	rv = CRYPTOKI_F_PTR( C_SignInit(hSession, &signMech, hPrk) );
2055 	CPPUNIT_ASSERT(rv == CKR_OK);
2056 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_CONTEXT_SPECIFIC,m_userPin1,m_userPin1Length) );
2057 	CPPUNIT_ASSERT(rv == CKR_OK);
2058 	rv = CRYPTOKI_F_PTR( C_SignFinal(hSession, signature256, &signature256Len) );
2059 	CPPUNIT_ASSERT(rv == CKR_OK);
2060 
2061 	// Test C_SignFinal without re-authentication
2062 	rv = CRYPTOKI_F_PTR( C_SignInit(hSession, &signMech, hPrk) );
2063 	CPPUNIT_ASSERT(rv == CKR_OK);
2064 	rv = CRYPTOKI_F_PTR( C_SignFinal(hSession, signature256, &signature256Len) );
2065 	CPPUNIT_ASSERT(rv == CKR_USER_NOT_LOGGED_IN);
2066 	rv = CRYPTOKI_F_PTR( C_SignFinal(hSession, signature256, &signature256Len) );
2067 	CPPUNIT_ASSERT(rv == CKR_OPERATION_NOT_INITIALIZED);
2068 
2069 	// Encrypt some data
2070 	rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&encMech,hPuk) );
2071 	CPPUNIT_ASSERT(rv==CKR_OK);
2072 	rv = CRYPTOKI_F_PTR( C_Encrypt(hSession,data,sizeof(data),cipherText,&ulCipherTextLen) );
2073 	CPPUNIT_ASSERT(rv==CKR_OK);
2074 
2075 	// Test C_Decrypt with re-authentication
2076 	rv = CRYPTOKI_F_PTR( C_DecryptInit(hSession,&encMech,hPrk) );
2077 	CPPUNIT_ASSERT(rv==CKR_OK);
2078 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_CONTEXT_SPECIFIC,m_userPin1,m_userPin1Length) );
2079 	CPPUNIT_ASSERT(rv == CKR_OK);
2080 	rv = CRYPTOKI_F_PTR( C_Decrypt(hSession,cipherText,ulCipherTextLen,recoveredText,&ulRecoveredTextLen) );
2081 	CPPUNIT_ASSERT(rv==CKR_OK);
2082 	CPPUNIT_ASSERT(memcmp(data, &recoveredText[ulRecoveredTextLen-sizeof(data)], sizeof(data)) == 0);
2083 
2084 	// Test C_Decrypt without re-authentication
2085 	rv = CRYPTOKI_F_PTR( C_DecryptInit(hSession,&encMech,hPrk) );
2086 	CPPUNIT_ASSERT(rv==CKR_OK);
2087 	rv = CRYPTOKI_F_PTR( C_Decrypt(hSession,cipherText,ulCipherTextLen,recoveredText,&ulRecoveredTextLen) );
2088 	CPPUNIT_ASSERT(rv == CKR_USER_NOT_LOGGED_IN);
2089 	rv = CRYPTOKI_F_PTR( C_Decrypt(hSession,cipherText,ulCipherTextLen,recoveredText,&ulRecoveredTextLen) );
2090 	CPPUNIT_ASSERT(rv == CKR_OPERATION_NOT_INITIALIZED);
2091 }
2092 
testAllowedMechanisms()2093 void ObjectTests::testAllowedMechanisms()
2094 {
2095 	CK_RV rv;
2096 	CK_SESSION_HANDLE hSession;
2097 
2098 	// Just make sure that we finalize any previous tests
2099 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
2100 
2101 	// Initialize the library and start the test.
2102 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
2103 	CPPUNIT_ASSERT(rv == CKR_OK);
2104 
2105 	// Open read-write session
2106 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
2107 	CPPUNIT_ASSERT(rv == CKR_OK);
2108 
2109 	// Login USER into the sessions so we can create a private objects
2110 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) );
2111 	CPPUNIT_ASSERT(rv==CKR_OK);
2112 
2113 	CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
2114 	CK_OBJECT_CLASS secretClass = CKO_SECRET_KEY;
2115 	CK_BYTE key[65] = { "0000000000000000000000000000000000000000000000000000000000000000" };
2116 	CK_MECHANISM_TYPE allowedMechs[] = { CKM_SHA256_HMAC, CKM_SHA512_HMAC };
2117 	CK_ATTRIBUTE attribs[] = {
2118 			{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2119 			{ CKA_CLASS, &secretClass, sizeof(secretClass) },
2120 			{ CKA_VALUE, &key, sizeof(key)-1 },
2121 			{ CKA_ALLOWED_MECHANISMS, &allowedMechs, sizeof(allowedMechs) }
2122 	};
2123 
2124 	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
2125 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hKey) );
2126 	CPPUNIT_ASSERT(rv == CKR_OK);
2127 
2128 	CK_BYTE data[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
2129 
2130 	// SHA_1_HMAC is not an allowed mechanism
2131 	CK_MECHANISM mechanism = { CKM_SHA_1_HMAC, NULL_PTR, 0 };
2132 	rv = CRYPTOKI_F_PTR( C_SignInit(hSession, &mechanism, hKey) );
2133 	CPPUNIT_ASSERT(rv == CKR_MECHANISM_INVALID);
2134 
2135 	// SHA256_HMAC is an allowed mechanism
2136 	mechanism.mechanism = CKM_SHA256_HMAC;
2137 	rv = CRYPTOKI_F_PTR( C_SignInit(hSession, &mechanism, hKey) );
2138 	CPPUNIT_ASSERT(rv == CKR_OK);
2139 	CK_BYTE signature256[256];
2140 	CK_ULONG signature256Len = sizeof(signature256);
2141 	rv = CRYPTOKI_F_PTR( C_Sign(hSession, data, sizeof(data), signature256, &signature256Len) );
2142 	CPPUNIT_ASSERT(rv == CKR_OK);
2143 
2144 	// SHA384_HMAC is not an allowed mechanism
2145 	mechanism.mechanism = CKM_SHA384_HMAC;
2146 	rv = CRYPTOKI_F_PTR( C_SignInit(hSession, &mechanism, hKey) );
2147 	CPPUNIT_ASSERT(rv == CKR_MECHANISM_INVALID);
2148 
2149 	// SHA512_HMAC is an allowed mechanism
2150 	mechanism.mechanism = CKM_SHA512_HMAC;
2151 	rv = CRYPTOKI_F_PTR( C_SignInit(hSession, &mechanism, hKey) );
2152 	CPPUNIT_ASSERT(rv == CKR_OK);
2153 	CK_BYTE signature512[512];
2154 	CK_ULONG signature512Len = sizeof(signature512);
2155 	rv = CRYPTOKI_F_PTR( C_Sign(hSession, data, sizeof(data), signature512, &signature512Len) );
2156 	CPPUNIT_ASSERT(rv == CKR_OK);
2157 
2158 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hKey) );
2159 	CPPUNIT_ASSERT(rv == CKR_OK);
2160 }
2161 
testTemplateAttribute()2162 void ObjectTests::testTemplateAttribute()
2163 {
2164 	CK_RV rv;
2165 	CK_SESSION_HANDLE hSession;
2166 	CK_OBJECT_HANDLE hObject = CK_INVALID_HANDLE;
2167 	CK_BYTE pE[] = { 0x01, 0x00, 0x01 };
2168 	CK_MECHANISM_TYPE allowedMechs[] = { CKM_SHA256_HMAC, CKM_SHA512_HMAC };
2169 
2170 	// Wrap template
2171 	CK_KEY_TYPE wrapType = CKK_SHA256_HMAC;;
2172 	CK_ATTRIBUTE wrapTemplate[] = {
2173 		{ CKA_KEY_TYPE, &wrapType, sizeof(wrapType) },
2174 		{ CKA_PUBLIC_EXPONENT, pE, sizeof(pE) },
2175 		{ CKA_ALLOWED_MECHANISMS, &allowedMechs, sizeof(allowedMechs) }
2176 	};
2177 
2178 	// Minimal public key object
2179 	CK_OBJECT_CLASS objClass = CKO_PUBLIC_KEY;
2180 	CK_KEY_TYPE objType = CKK_RSA;
2181 	CK_BYTE pN[] = { 0xC6, 0x47, 0xDD, 0x74, 0x3B, 0xCB, 0xDC, 0x6F, 0xCE, 0xA7,
2182 			 0xF0, 0x5F, 0x29, 0x4B, 0x27, 0x00, 0xCC, 0x92, 0xE9, 0x20,
2183 			 0x8A, 0x2C, 0x87, 0x36, 0x47, 0x24, 0xB0, 0xD5, 0x7D, 0xB0,
2184 			 0x92, 0x01, 0xA0, 0xA3, 0x55, 0x2E, 0x3F, 0xFE, 0xA7, 0x4C,
2185 			 0x4B, 0x3F, 0x9D, 0x4E, 0xCB, 0x78, 0x12, 0xA9, 0x42, 0xAD,
2186 			 0x51, 0x1F, 0x3B, 0xBD, 0x3D, 0x6A, 0xE5, 0x38, 0xB7, 0x45,
2187 			 0x65, 0x50, 0x30, 0x35 };
2188 	CK_ATTRIBUTE objTemplate[] = {
2189 		{ CKA_CLASS, &objClass, sizeof(objClass) },
2190 		{ CKA_KEY_TYPE, &objType, sizeof(objType) },
2191 		{ CKA_MODULUS, pN, sizeof(pN) },
2192 		{ CKA_PUBLIC_EXPONENT, pE, sizeof(pE) },
2193 		{ CKA_WRAP_TEMPLATE, wrapTemplate, sizeof(wrapTemplate) }
2194 	};
2195 
2196 	// Just make sure that we finalize any previous tests
2197 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
2198 
2199 	// Initialize the library and start the test.
2200 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
2201 	CPPUNIT_ASSERT(rv == CKR_OK);
2202 
2203 	// Open read-write session
2204 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
2205 	CPPUNIT_ASSERT(rv == CKR_OK);
2206 
2207 	// Login USER into the sessions so we can create a private objects
2208 	rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
2209 	CPPUNIT_ASSERT(rv == CKR_OK);
2210 
2211 	// Create minimal RSA public key object
2212 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, objTemplate, sizeof(objTemplate)/sizeof(CK_ATTRIBUTE), &hObject) );
2213 	CPPUNIT_ASSERT(rv == CKR_OK);
2214 
2215 	CK_ATTRIBUTE wrapAttribs[] = {
2216 		{ 0, NULL_PTR, 0 },
2217 		{ 0, NULL_PTR, 0 },
2218 		{ 0, NULL_PTR, 0 }
2219 	};
2220 	CK_ATTRIBUTE wrapAttrib = { CKA_WRAP_TEMPLATE, NULL_PTR, 0 };
2221 
2222 	// Get number of elements
2223 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &wrapAttrib, 1) );
2224 	CPPUNIT_ASSERT(rv == CKR_OK);
2225 	CPPUNIT_ASSERT(wrapAttrib.ulValueLen == 3 * sizeof(CK_ATTRIBUTE));
2226 
2227 	// Get element types and sizes
2228 	wrapAttrib.pValue = wrapAttribs;
2229 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &wrapAttrib, 1) );
2230 	CPPUNIT_ASSERT(rv == CKR_OK);
2231 	CPPUNIT_ASSERT(wrapAttrib.ulValueLen == 3 * sizeof(CK_ATTRIBUTE));
2232 	for (size_t i = 0; i < 3; i++)
2233 	{
2234 		switch (wrapAttribs[i].type)
2235 		{
2236 			case CKA_KEY_TYPE:
2237 				CPPUNIT_ASSERT(wrapAttribs[i].ulValueLen == sizeof(CK_KEY_TYPE));
2238 				break;
2239 			case CKA_PUBLIC_EXPONENT:
2240 				CPPUNIT_ASSERT(wrapAttribs[i].ulValueLen == sizeof(pE));
2241 				break;
2242 			case CKA_ALLOWED_MECHANISMS:
2243 				CPPUNIT_ASSERT(wrapAttribs[i].ulValueLen == sizeof(allowedMechs));
2244 				break;
2245 			default:
2246 				CPPUNIT_ASSERT(false);
2247 		}
2248 	}
2249 
2250 	// Get values
2251 	wrapAttribs[0].pValue = (CK_VOID_PTR)malloc(wrapAttribs[0].ulValueLen);
2252 	wrapAttribs[1].pValue = (CK_VOID_PTR)malloc(wrapAttribs[1].ulValueLen);
2253 	wrapAttribs[2].pValue = (CK_VOID_PTR)malloc(wrapAttribs[2].ulValueLen);
2254 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, &wrapAttrib, 1) );
2255 	CPPUNIT_ASSERT(rv == CKR_OK);
2256 	for (size_t i = 0; i < 3; i++)
2257 	{
2258 		switch (wrapAttribs[i].type)
2259 		{
2260 			case CKA_KEY_TYPE:
2261 				CPPUNIT_ASSERT(*(CK_KEY_TYPE*) wrapAttribs[i].pValue == CKK_SHA256_HMAC);
2262 				break;
2263 			case CKA_PUBLIC_EXPONENT:
2264 				CPPUNIT_ASSERT(memcmp(wrapAttribs[i].pValue, pE, sizeof(pE)) == 0);
2265 				break;
2266 			case CKA_ALLOWED_MECHANISMS:
2267 				CPPUNIT_ASSERT(memcmp(wrapAttribs[i].pValue, allowedMechs, sizeof(allowedMechs)) == 0);
2268 				break;
2269 			default:
2270 				CPPUNIT_ASSERT(false);
2271 		}
2272 	}
2273 
2274 	free(wrapAttribs[0].pValue);
2275 	free(wrapAttribs[1].pValue);
2276 	free(wrapAttribs[2].pValue);
2277 }
2278 
testCreateSecretKey()2279 void ObjectTests::testCreateSecretKey()
2280 {
2281 	CK_RV rv;
2282 	CK_SESSION_HANDLE hSession;
2283 
2284 	// Just make sure that we finalize any previous tests
2285 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
2286 
2287 	// Initialize the library and start the test.
2288 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
2289 	CPPUNIT_ASSERT(rv == CKR_OK);
2290 
2291 	// Open read-write session
2292 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
2293 	CPPUNIT_ASSERT(rv == CKR_OK);
2294 
2295 	// Login USER into the sessions so we can create a private objects
2296 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) );
2297 	CPPUNIT_ASSERT(rv==CKR_OK);
2298 
2299 	CK_BYTE genericKey[] = {
2300 		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
2301 		0x01, 0x02, 0x03, 0x04, 0x05, 0x06
2302 	};
2303 	CK_BYTE aesKey[] = {
2304 		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
2305 		0x01, 0x02, 0x03, 0x04, 0x05, 0x06
2306 	};
2307 	CK_BYTE desKey[] = {
2308 		0x81, 0xdc, 0x9b, 0xdb, 0x52, 0xd0, 0x4d, 0xc2
2309 	};
2310 	CK_BYTE des2Key[] = {
2311 		0x81, 0xdc, 0x9b, 0xdb, 0x52, 0xd0, 0x4d, 0xc2, 0x00, 0x36,
2312 		0xdb, 0xd8, 0x31, 0x3e, 0xd0, 0x55
2313 	};
2314 	CK_BYTE des3Key[] = {
2315 		0x81, 0xdc, 0x9b, 0xdb, 0x52, 0xd0, 0x4d, 0xc2, 0x00, 0x36,
2316 		0xdb, 0xd8, 0x31, 0x3e, 0xd0, 0x55, 0xcc, 0x57, 0x76, 0xd1,
2317 		0x6a, 0x1f, 0xb6, 0xe4
2318 	};
2319 	CK_BYTE genericKCV[] = { 0x5c, 0x3b, 0x7c };
2320 	CK_BYTE aesKCV[] =     { 0x08, 0xbd, 0x28 };
2321 	CK_BYTE desKCV[] =     { 0x08, 0xa1, 0x50 };
2322 	CK_BYTE des2KCV[] =    { 0xa9, 0x67, 0xae };
2323 	CK_BYTE des3KCV[] =    { 0x5c, 0x5e, 0xec };
2324 
2325 	CK_OBJECT_HANDLE hObject = CK_INVALID_HANDLE;
2326 	CK_BBOOL bFalse = CK_FALSE;
2327 	CK_BBOOL bTrue = CK_TRUE;
2328 	CK_OBJECT_CLASS secretClass = CKO_SECRET_KEY;
2329 	CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
2330 	CK_ATTRIBUTE attribs[] = {
2331 		{ CKA_VALUE, genericKey, sizeof(genericKey) },
2332 		{ CKA_EXTRACTABLE, &bFalse, sizeof(bFalse) },
2333 		{ CKA_CLASS, &secretClass, sizeof(secretClass) },
2334 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2335 		{ CKA_TOKEN, &bFalse, sizeof(bFalse) },
2336 		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
2337 		{ CKA_SENSITIVE, &bTrue, sizeof(bTrue) }
2338 	};
2339 
2340 	CK_BYTE pCheckValue[3];
2341 	CK_ATTRIBUTE attribKCV[] = {
2342 		{ CKA_CHECK_VALUE, pCheckValue, sizeof(pCheckValue) }
2343 	};
2344 
2345 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hObject) );
2346 	CPPUNIT_ASSERT(rv == CKR_OK);
2347 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, attribKCV, 1) );
2348 	CPPUNIT_ASSERT(rv == CKR_OK);
2349 	CPPUNIT_ASSERT(attribKCV[0].ulValueLen == 3);
2350 	CPPUNIT_ASSERT(memcmp(pCheckValue, genericKCV, 3) == 0);
2351 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
2352 	CPPUNIT_ASSERT(rv == CKR_OK);
2353 
2354 	keyType = CKK_AES;
2355 	attribs[0].pValue = aesKey;
2356 	attribs[0].ulValueLen = sizeof(aesKey);
2357 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hObject) );
2358 	CPPUNIT_ASSERT(rv == CKR_OK);
2359 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, attribKCV, 1) );
2360 	CPPUNIT_ASSERT(rv == CKR_OK);
2361 	CPPUNIT_ASSERT(attribKCV[0].ulValueLen == 3);
2362 	CPPUNIT_ASSERT(memcmp(pCheckValue, aesKCV, 3) == 0);
2363 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
2364 	CPPUNIT_ASSERT(rv == CKR_OK);
2365 
2366 	keyType = CKK_DES;
2367 	attribs[0].pValue = desKey;
2368 	attribs[0].ulValueLen = sizeof(desKey);
2369 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hObject) );
2370 	CPPUNIT_ASSERT(rv == CKR_OK);
2371 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, attribKCV, 1) );
2372 	CPPUNIT_ASSERT(rv == CKR_OK);
2373 	CPPUNIT_ASSERT(attribKCV[0].ulValueLen == 3);
2374 	CPPUNIT_ASSERT(memcmp(pCheckValue, desKCV, 3) == 0);
2375 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
2376 	CPPUNIT_ASSERT(rv == CKR_OK);
2377 
2378 	keyType = CKK_DES2;
2379 	attribs[0].pValue = des2Key;
2380 	attribs[0].ulValueLen = sizeof(des2Key);
2381 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hObject) );
2382 	CPPUNIT_ASSERT(rv == CKR_OK);
2383 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, attribKCV, 1) );
2384 	CPPUNIT_ASSERT(rv == CKR_OK);
2385 	CPPUNIT_ASSERT(attribKCV[0].ulValueLen == 3);
2386 	CPPUNIT_ASSERT(memcmp(pCheckValue, des2KCV, 3) == 0);
2387 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
2388 	CPPUNIT_ASSERT(rv == CKR_OK);
2389 
2390 	keyType = CKK_DES3;
2391 	attribs[0].pValue = des3Key;
2392 	attribs[0].ulValueLen = sizeof(des3Key);
2393 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hObject) );
2394 	CPPUNIT_ASSERT(rv == CKR_OK);
2395 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, attribKCV, 1) );
2396 	CPPUNIT_ASSERT(rv == CKR_OK);
2397 	CPPUNIT_ASSERT(attribKCV[0].ulValueLen == 3);
2398 	CPPUNIT_ASSERT(memcmp(pCheckValue, des3KCV, 3) == 0);
2399 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) );
2400 	CPPUNIT_ASSERT(rv == CKR_OK);
2401 }
2402 
2403