1 /*
2  * gnome-keyring
3  *
4  * Copyright (C) 2010 Stefan Walter
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "config.h"
22 
23 #include "gkm-attributes.h"
24 #include "gkm-mock.h"
25 #include "gkm-util.h"
26 
27 #include "pkcs11/pkcs11.h"
28 #include "pkcs11/pkcs11i.h"
29 
30 #include <glib.h>
31 
32 #include <string.h>
33 
34 #define GKM_TEST_SLOT_ONE  52
35 #define GKM_TEST_SLOT_TWO  134
36 
37 
38 static gboolean initialized = FALSE;
39 static gchar *the_pin = NULL;
40 static gulong n_the_pin = 0;
41 
42 static gboolean logged_in = FALSE;
43 static CK_USER_TYPE user_type = 0;
44 static CK_FUNCTION_LIST functionList;
45 
46 typedef enum _Operation {
47 	OP_FIND = 1,
48 	OP_CRYPTO
49 } Operation;
50 
51 typedef struct _Session {
52 	CK_SESSION_HANDLE handle;
53 	CK_SESSION_INFO info;
54 	GHashTable *objects;
55 
56 	Operation operation;
57 
58 	/* For find operations */
59 	GList *matches;
60 
61 	/* For crypto operations */
62 	CK_OBJECT_HANDLE crypto_key;
63 	CK_ATTRIBUTE_TYPE crypto_method;
64 	CK_MECHANISM_TYPE crypto_mechanism;
65 	CK_BBOOL want_context_login;
66 
67 	/* For 'signing' with CKM_MOCK_PREFIX */
68 	CK_BYTE sign_prefix[128];
69 	CK_ULONG n_sign_prefix;
70 } Session;
71 
72 static guint unique_identifier = 100;
73 static GHashTable *the_sessions = NULL;
74 static GHashTable *the_objects = NULL;
75 static GSList *the_objects_list = NULL;
76 static GArray *the_credential_template = NULL;
77 
78 enum {
79 	PRIVATE_KEY_CAPITALIZE = 3,
80 	PUBLIC_KEY_CAPITALIZE = 4,
81 	PRIVATE_KEY_PREFIX = 5,
82 	PUBLIC_KEY_PREFIX = 6
83 };
84 
85 #define SIGNED_PREFIX "signed-prefix:"
86 
87 static void
free_session(gpointer data)88 free_session (gpointer data)
89 {
90 	Session *sess = (Session*)data;
91 	if (sess)
92 		g_hash_table_destroy (sess->objects);
93 	g_free (sess);
94 }
95 
96 static GArray*
lookup_object(Session * session,CK_OBJECT_HANDLE hObject)97 lookup_object (Session *session, CK_OBJECT_HANDLE hObject)
98 {
99 	GArray *attrs;
100 	attrs = g_hash_table_lookup (the_objects, GUINT_TO_POINTER (hObject));
101 	if (!attrs)
102 		attrs = g_hash_table_lookup (session->objects, GUINT_TO_POINTER (hObject));
103 	return attrs;
104 }
105 
106 typedef struct {
107 	guint handle;
108 	GArray *template; /* owned by the_objects */
109 } ObjectData;
110 
111 static gint
list_find_handle(gconstpointer l,gconstpointer r)112 list_find_handle (gconstpointer l, gconstpointer r)
113 {
114 	guint handle;
115 	ObjectData *item;
116 
117 	handle = GPOINTER_TO_UINT (r);
118 	item = (ObjectData *) l;
119 
120 	if (item->handle == handle)
121 		return 0;
122 
123 	return -1;
124 }
125 
126 static void
insert_template(guint handle,GArray * template)127 insert_template (guint handle, GArray *template)
128 {
129 	ObjectData *data;
130 
131 	data = g_new0 (ObjectData, 1);
132 	data->handle = handle;
133 	data->template = template;
134 
135 	g_hash_table_insert (the_objects, GUINT_TO_POINTER (handle), template);
136 	the_objects_list = g_slist_append (the_objects_list, data);
137 }
138 
139 CK_OBJECT_HANDLE
gkm_mock_module_take_object(GArray * template)140 gkm_mock_module_take_object (GArray *template)
141 {
142 	gboolean token;
143 	guint handle;
144 
145 	g_return_val_if_fail (the_objects, 0);
146 
147 	handle = ++unique_identifier;
148 	if (gkm_template_find_boolean (template, CKA_TOKEN, &token))
149 		g_return_val_if_fail (token == TRUE, 0);
150 	else
151 		gkm_template_set_boolean (template, CKA_TOKEN, CK_TRUE);
152 	insert_template (handle, template);
153 	return handle;
154 }
155 
156 void
gkm_mock_module_enumerate_objects(CK_SESSION_HANDLE handle,GkmMockEnumerator func,gpointer user_data)157 gkm_mock_module_enumerate_objects (CK_SESSION_HANDLE handle, GkmMockEnumerator func,
158                                    gpointer user_data)
159 {
160 	GHashTableIter iter;
161 	gpointer key;
162 	gpointer value;
163 	Session *session;
164 	ObjectData *data;
165 	GSList *l = NULL;
166 
167 	g_assert (the_objects);
168 	g_assert (func);
169 
170 	/* Token objects */
171 	for (l = the_objects_list; l != NULL; l = l->next) {
172 		data = (ObjectData *) l->data;
173 		if (!(func) (data->handle, data->template, user_data))
174 			return;
175 	}
176 
177 	/* session objects */
178 	if (handle) {
179 		session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (handle));
180 		if (session) {
181 			g_hash_table_iter_init (&iter, session->objects);
182 			while (g_hash_table_iter_next (&iter, &key, &value)) {
183 				if (!(func) (GPOINTER_TO_UINT (key), value, user_data))
184 					return;
185 			}
186 		}
187 	}
188 }
189 
190 typedef struct _FindObject {
191 	CK_ATTRIBUTE_PTR attrs;
192 	CK_ULONG n_attrs;
193 	CK_OBJECT_HANDLE object;
194 } FindObject;
195 
196 static gboolean
enumerate_and_find_object(CK_OBJECT_HANDLE object,GArray * template,gpointer user_data)197 enumerate_and_find_object (CK_OBJECT_HANDLE object, GArray *template, gpointer user_data)
198 {
199 	FindObject *ctx = user_data;
200 	CK_ATTRIBUTE_PTR match, attr;
201 	CK_ULONG i;
202 
203 	for (i = 0; i < ctx->n_attrs; ++i) {
204 		match = ctx->attrs + i;
205 		attr = gkm_template_find (template, match->type);
206 		if (!attr)
207 			return TRUE; /* Continue */
208 
209 		if (attr->ulValueLen != match->ulValueLen ||
210 		    memcmp (attr->pValue, match->pValue, attr->ulValueLen) != 0)
211 			return TRUE; /* Continue */
212 	}
213 
214 	ctx->object = object;
215 	return FALSE; /* Stop iteration */
216 }
217 
218 CK_OBJECT_HANDLE
gkm_mock_module_find_object(CK_SESSION_HANDLE session,CK_ATTRIBUTE_PTR attrs,CK_ULONG n_attrs)219 gkm_mock_module_find_object (CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
220 {
221 	FindObject ctx;
222 
223 	ctx.attrs = attrs;
224 	ctx.n_attrs = n_attrs;
225 	ctx.object = 0;
226 
227 	gkm_mock_module_enumerate_objects (session, enumerate_and_find_object, &ctx);
228 
229 	return ctx.object;
230 }
231 
232 static gboolean
enumerate_and_count_objects(CK_OBJECT_HANDLE object,GArray * template,gpointer user_data)233 enumerate_and_count_objects (CK_OBJECT_HANDLE object, GArray *template, gpointer user_data)
234 {
235 	guint *n_objects = user_data;
236 	++(*n_objects);
237 	return TRUE; /* Continue */
238 }
239 
240 guint
gkm_mock_module_count_objects(CK_SESSION_HANDLE session)241 gkm_mock_module_count_objects (CK_SESSION_HANDLE session)
242 {
243 	guint n_objects = 0;
244 	gkm_mock_module_enumerate_objects (session, enumerate_and_count_objects, &n_objects);
245 	return n_objects;
246 }
247 
248 void
gkm_mock_module_set_object(CK_OBJECT_HANDLE object,CK_ATTRIBUTE_PTR attrs,CK_ULONG n_attrs)249 gkm_mock_module_set_object (CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR attrs,
250                             CK_ULONG n_attrs)
251 {
252 	CK_ULONG i;
253 	GArray *template;
254 
255 	g_return_if_fail (object != 0);
256 	g_return_if_fail (the_objects);
257 
258 	template = g_hash_table_lookup (the_objects, GUINT_TO_POINTER (object));
259 	g_return_if_fail (template);
260 
261 	for (i = 0; i < n_attrs; ++i)
262 		gkm_template_set (template, attrs + i);
263 }
264 
265 void
gkm_mock_module_set_pin(const gchar * password)266 gkm_mock_module_set_pin (const gchar *password)
267 {
268 	g_free (the_pin);
269 	the_pin = g_strdup (password);
270 	n_the_pin = strlen (password);
271 }
272 
273 CK_RV
gkm_mock_C_Initialize(CK_VOID_PTR pInitArgs)274 gkm_mock_C_Initialize (CK_VOID_PTR pInitArgs)
275 {
276 	GArray *attrs;
277 	CK_ULONG value;
278 	CK_C_INITIALIZE_ARGS_PTR args;
279 
280 	g_return_val_if_fail (initialized == FALSE, CKR_CRYPTOKI_ALREADY_INITIALIZED);
281 
282 	args = (CK_C_INITIALIZE_ARGS_PTR)pInitArgs;
283 	if (args) {
284 		g_return_val_if_fail(
285 		              (args->CreateMutex == NULL && args->DestroyMutex == NULL &&
286 		               args->LockMutex == NULL && args->UnlockMutex == NULL) ||
287 		              (args->CreateMutex != NULL && args->DestroyMutex != NULL &&
288 		               args->LockMutex != NULL && args->UnlockMutex != NULL),
289 		               CKR_ARGUMENTS_BAD);
290 
291 		/* Flags should allow OS locking and os threads */
292 		g_return_val_if_fail (args->flags & CKF_OS_LOCKING_OK, CKR_CANT_LOCK);
293 		g_return_val_if_fail (args->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS, CKR_NEED_TO_CREATE_THREADS);
294 	}
295 
296 	the_pin = g_strdup ("booo");
297 	n_the_pin = strlen (the_pin);
298 	the_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_session);
299 	the_objects = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)gkm_template_free);
300 	the_credential_template = gkm_template_new (NULL, 0);
301 
302 	/* Our token object */
303 	attrs = gkm_template_new (NULL, 0);
304 	gkm_template_set_ulong (attrs, CKA_CLASS, CKO_DATA);
305 	gkm_template_set_string (attrs, CKA_LABEL, "TEST LABEL");
306 	insert_template (2, attrs);
307 
308 	/* Private capitalize key */
309 	value = CKM_MOCK_CAPITALIZE;
310 	attrs = gkm_template_new (NULL, 0);
311 	gkm_template_set_ulong (attrs, CKA_CLASS, CKO_PRIVATE_KEY);
312 	gkm_template_set_string (attrs, CKA_LABEL, "Private Capitalize Key");
313 	gkm_template_set_value (attrs, CKA_ALLOWED_MECHANISMS, &value, sizeof (value));
314 	gkm_template_set_boolean (attrs, CKA_DECRYPT, CK_TRUE);
315 	gkm_template_set_boolean (attrs, CKA_PRIVATE, CK_TRUE);
316 	gkm_template_set_boolean (attrs, CKA_WRAP, CK_TRUE);
317 	gkm_template_set_boolean (attrs, CKA_UNWRAP, CK_TRUE);
318 	gkm_template_set_boolean (attrs, CKA_DERIVE, CK_TRUE);
319 	gkm_template_set_string (attrs, CKA_VALUE, "value");
320 	gkm_template_set_string (attrs, CKA_GNOME_UNIQUE, "unique1");
321 	insert_template (PRIVATE_KEY_CAPITALIZE, attrs);
322 
323 	/* Public capitalize key */
324 	value = CKM_MOCK_CAPITALIZE;
325 	attrs = gkm_template_new (NULL, 0);
326 	gkm_template_set_ulong (attrs, CKA_CLASS, CKO_PUBLIC_KEY);
327 	gkm_template_set_string (attrs, CKA_LABEL, "Public Capitalize Key");
328 	gkm_template_set_value (attrs, CKA_ALLOWED_MECHANISMS, &value, sizeof (value));
329 	gkm_template_set_boolean (attrs, CKA_ENCRYPT, CK_TRUE);
330 	gkm_template_set_boolean (attrs, CKA_PRIVATE, CK_FALSE);
331 	gkm_template_set_string (attrs, CKA_VALUE, "value");
332 	gkm_template_set_string (attrs, CKA_GNOME_UNIQUE, "unique2");
333 	insert_template (PUBLIC_KEY_CAPITALIZE, attrs);
334 
335 	/* Private prefix key */
336 	value = CKM_MOCK_PREFIX;
337 	attrs = gkm_template_new (NULL, 0);
338 	gkm_template_set_ulong (attrs, CKA_CLASS, CKO_PRIVATE_KEY);
339 	gkm_template_set_string (attrs, CKA_LABEL, "Private prefix key");
340 	gkm_template_set_value (attrs, CKA_ALLOWED_MECHANISMS, &value, sizeof (value));
341 	gkm_template_set_boolean (attrs, CKA_SIGN, CK_TRUE);
342 	gkm_template_set_boolean (attrs, CKA_PRIVATE, CK_TRUE);
343 	gkm_template_set_boolean (attrs, CKA_ALWAYS_AUTHENTICATE, CK_TRUE);
344 	gkm_template_set_string (attrs, CKA_VALUE, "value");
345 	gkm_template_set_string (attrs, CKA_GNOME_UNIQUE, "unique3");
346 	insert_template (PRIVATE_KEY_PREFIX, attrs);
347 
348 	/* Private prefix key */
349 	value = CKM_MOCK_PREFIX;
350 	attrs = gkm_template_new (NULL, 0);
351 	gkm_template_set_ulong (attrs, CKA_CLASS, CKO_PUBLIC_KEY);
352 	gkm_template_set_string (attrs, CKA_LABEL, "Public prefix key");
353 	gkm_template_set_value (attrs, CKA_ALLOWED_MECHANISMS, &value, sizeof (value));
354 	gkm_template_set_boolean (attrs, CKA_VERIFY, CK_TRUE);
355 	gkm_template_set_boolean (attrs, CKA_PRIVATE, CK_FALSE);
356 	gkm_template_set_string (attrs, CKA_VALUE, "value");
357 	gkm_template_set_string (attrs, CKA_GNOME_UNIQUE, "unique4");
358 	insert_template (PUBLIC_KEY_PREFIX, attrs);
359 
360 	initialized = TRUE;
361 	return CKR_OK;
362 }
363 
364 CK_RV
gkm_mock_C_Finalize(CK_VOID_PTR pReserved)365 gkm_mock_C_Finalize (CK_VOID_PTR pReserved)
366 {
367 	g_return_val_if_fail (pReserved == NULL, CKR_ARGUMENTS_BAD);
368 	g_return_val_if_fail (initialized == TRUE, CKR_CRYPTOKI_NOT_INITIALIZED);
369 
370 	initialized = FALSE;
371 	logged_in = FALSE;
372 	g_hash_table_destroy (the_objects);
373 	the_objects = NULL;
374 
375 	g_slist_free_full (the_objects_list, g_free);
376 	the_objects_list = NULL;
377 
378 	g_hash_table_destroy (the_sessions);
379 	the_sessions = NULL;
380 
381 	gkm_template_free (the_credential_template);
382 	the_credential_template = NULL;
383 
384 	g_free (the_pin);
385 	return CKR_OK;
386 }
387 
388 static const CK_INFO TEST_INFO = {
389 	{ CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
390 	"TEST MANUFACTURER              ",
391 	0,
392 	"TEST LIBRARY                   ",
393 	{ 45, 145 }
394 };
395 
396 CK_RV
gkm_mock_C_GetInfo(CK_INFO_PTR pInfo)397 gkm_mock_C_GetInfo (CK_INFO_PTR pInfo)
398 {
399 	g_assert (pInfo != NULL && "Invalid pointer to GetInfo");
400 	memcpy (pInfo, &TEST_INFO, sizeof (*pInfo));
401 	return CKR_OK;
402 }
403 
404 CK_RV
gkm_mock_C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR list)405 gkm_mock_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
406 {
407 	if (!list)
408 		return CKR_ARGUMENTS_BAD;
409 	*list = &functionList;
410 	return CKR_OK;
411 }
412 
413 /*
414  * Two slots
415  *  ONE: token present
416  *  TWO: token not present
417  */
418 
419 CK_RV
gkm_mock_C_GetSlotList(CK_BBOOL tokenPresent,CK_SLOT_ID_PTR pSlotList,CK_ULONG_PTR pulCount)420 gkm_mock_C_GetSlotList (CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
421 {
422 	CK_ULONG count;
423 
424 	g_assert (pulCount != NULL && "Invalid pulCount");
425 
426 	count = tokenPresent ? 1 : 2;
427 
428 	/* Application only wants to know the number of slots. */
429 	if (pSlotList == NULL) {
430 		*pulCount = count;
431 		return CKR_OK;
432 	}
433 
434 	if (*pulCount < count) {
435 		g_assert (*pulCount && "Passed in a bad count");
436 		return CKR_BUFFER_TOO_SMALL;
437 	}
438 
439 	*pulCount = count;
440 	pSlotList[0] = GKM_TEST_SLOT_ONE;
441 	if (!tokenPresent)
442 		pSlotList[1] = GKM_TEST_SLOT_TWO;
443 
444 	return CKR_OK;
445 }
446 
447 static const CK_SLOT_INFO TEST_INFO_ONE = {
448 	"TEST SLOT                                                       ",
449 	"TEST MANUFACTURER              ",
450 	CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE,
451 	{ 55, 155 },
452 	{ 65, 165 },
453 };
454 
455 static const CK_SLOT_INFO TEST_INFO_TWO = {
456 	"TEST SLOT                                                       ",
457 	"TEST MANUFACTURER              ",
458 	CKF_REMOVABLE_DEVICE,
459 	{ 55, 155 },
460 	{ 65, 165 },
461 };
462 
463 CK_RV
gkm_mock_C_GetSlotInfo(CK_SLOT_ID slotID,CK_SLOT_INFO_PTR pInfo)464 gkm_mock_C_GetSlotInfo (CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
465 {
466 	g_assert (pInfo != NULL && "Invalid pInfo");
467 
468 	if (slotID == GKM_TEST_SLOT_ONE) {
469 		memcpy (pInfo, &TEST_INFO_ONE, sizeof (*pInfo));
470 		return CKR_OK;
471 	} else if (slotID == GKM_TEST_SLOT_TWO) {
472 		memcpy (pInfo, &TEST_INFO_TWO, sizeof (*pInfo));
473 		return CKR_OK;
474 	} else {
475 		g_assert_not_reached (); /* "Invalid slot id" */
476 		return CKR_SLOT_ID_INVALID;
477 	}
478 }
479 
480 static const CK_TOKEN_INFO TEST_TOKEN_ONE = {
481 	"TEST LABEL                      ",
482 	"TEST MANUFACTURER               ",
483 	"TEST MODEL      ",
484 	"TEST SERIAL     ",
485 	CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_CLOCK_ON_TOKEN | CKF_TOKEN_INITIALIZED,
486 	1,
487 	2,
488 	3,
489 	4,
490 	5,
491 	6,
492 	7,
493 	8,
494 	9,
495 	10,
496 	{ 75, 175 },
497 	{ 85, 185 },
498 	{ '1', '9', '9', '9', '0', '5', '2', '5', '0', '9', '1', '9', '5', '9', '0', '0' }
499 };
500 
501 CK_RV
gkm_mock_C_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)502 gkm_mock_C_GetTokenInfo (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
503 {
504 	g_return_val_if_fail (pInfo != NULL, CKR_ARGUMENTS_BAD);
505 
506 	if (slotID == GKM_TEST_SLOT_ONE) {
507 		memcpy (pInfo, &TEST_TOKEN_ONE, sizeof (*pInfo));
508 		return CKR_OK;
509 	} else if (slotID == GKM_TEST_SLOT_TWO) {
510 		return CKR_TOKEN_NOT_PRESENT;
511 	} else {
512 		g_return_val_if_reached (CKR_SLOT_ID_INVALID);
513 	}
514 }
515 
516 CK_RV
gkm_mock_fail_C_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)517 gkm_mock_fail_C_GetTokenInfo (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
518 {
519 	return CKR_GENERAL_ERROR;
520 }
521 
522 /*
523  * TWO mechanisms:
524  *  CKM_MOCK_CAPITALIZE
525  *  CKM_MOCK_PREFIX
526  */
527 
528 CK_RV
gkm_mock_C_GetMechanismList(CK_SLOT_ID slotID,CK_MECHANISM_TYPE_PTR pMechanismList,CK_ULONG_PTR pulCount)529 gkm_mock_C_GetMechanismList (CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
530                              CK_ULONG_PTR pulCount)
531 {
532 	g_assert (slotID == GKM_TEST_SLOT_ONE && "Invalid slotID");
533 	g_assert (pulCount != NULL && "Invalid pulCount");
534 
535 	/* Application only wants to know the number of slots. */
536 	if (pMechanismList == NULL) {
537 		*pulCount = 2;
538 		return CKR_OK;
539 	}
540 
541 	if (*pulCount != 2) {
542 		g_assert (*pulCount && "Passed in a bad count");
543 		return CKR_BUFFER_TOO_SMALL;
544 	}
545 
546 	pMechanismList[0] = CKM_MOCK_CAPITALIZE;
547 	pMechanismList[1] = CKM_MOCK_PREFIX;
548 	return CKR_OK;
549 }
550 
551 static const CK_MECHANISM_INFO TEST_MECH_CAPITALIZE = {
552 	512, 4096, 0
553 };
554 
555 static const CK_MECHANISM_INFO TEST_MECH_PREFIX = {
556 	2048, 2048, 0
557 };
558 
559 CK_RV
gkm_mock_C_GetMechanismInfo(CK_SLOT_ID slotID,CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo)560 gkm_mock_C_GetMechanismInfo (CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
561                              CK_MECHANISM_INFO_PTR pInfo)
562 {
563 	g_assert (slotID == GKM_TEST_SLOT_ONE && "Invalid slotID");
564 	g_assert (pInfo != NULL && "Invalid pInfo");
565 
566 	if (type == CKM_MOCK_CAPITALIZE) {
567 		memcpy (pInfo, &TEST_MECH_CAPITALIZE, sizeof (*pInfo));
568 		return CKR_OK;
569 	} else if (type == CKM_MOCK_PREFIX) {
570 		memcpy (pInfo, &TEST_MECH_PREFIX, sizeof (*pInfo));
571 		return CKR_OK;
572 	} else {
573 		g_assert_not_reached (); /* "Invalid type" */
574 		return CKR_MECHANISM_INVALID;
575 	}
576 }
577 
578 CK_RV
gkm_mock_C_InitToken(CK_SLOT_ID slotID,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen,CK_UTF8CHAR_PTR pLabel)579 gkm_mock_C_InitToken (CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen,
580                       CK_UTF8CHAR_PTR pLabel)
581 {
582 	g_assert (slotID == GKM_TEST_SLOT_ONE && "Invalid slotID");
583 	g_assert (pPin != NULL && "Invalid pPin");
584 	g_assert (strlen ("TEST PIN") && "Invalid ulPinLen");
585 	g_assert (strncmp ((gchar*)pPin, "TEST PIN", ulPinLen) == 0 && "Invalid pPin string");
586 	g_assert (pLabel != NULL && "Invalid pLabel");
587 	g_assert (strcmp ((gchar*)pPin, "TEST LABEL") == 0 && "Invalid pLabel string");
588 
589 	g_free (the_pin);
590 	the_pin = g_strndup ((gchar*)pPin, ulPinLen);
591 	n_the_pin = ulPinLen;
592 	return CKR_OK;
593 }
594 
595 CK_RV
gkm_mock_unsupported_C_WaitForSlotEvent(CK_FLAGS flags,CK_SLOT_ID_PTR pSlot,CK_VOID_PTR pReserved)596 gkm_mock_unsupported_C_WaitForSlotEvent (CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
597 {
598 	return CKR_FUNCTION_NOT_SUPPORTED;
599 }
600 
601 CK_RV
gkm_mock_C_OpenSession(CK_SLOT_ID slotID,CK_FLAGS flags,CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession)602 gkm_mock_C_OpenSession (CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication,
603                         CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession)
604 {
605 	Session *sess;
606 
607 	g_return_val_if_fail (slotID == GKM_TEST_SLOT_ONE, CKR_SLOT_ID_INVALID);
608 	g_return_val_if_fail (phSession != NULL, CKR_ARGUMENTS_BAD);
609 	g_return_val_if_fail ((flags & CKF_SERIAL_SESSION) == CKF_SERIAL_SESSION, CKR_SESSION_PARALLEL_NOT_SUPPORTED);
610 
611 	sess = g_new0 (Session, 1);
612 	sess->handle = ++unique_identifier;
613 	sess->info.flags = flags;
614 	sess->info.slotID = slotID;
615 	sess->info.state = 0;
616 	sess->info.ulDeviceError = 1414;
617 	sess->objects = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)gkm_template_free);
618 	*phSession = sess->handle;
619 
620 	g_hash_table_replace (the_sessions, GUINT_TO_POINTER (sess->handle), sess);
621 	return CKR_OK;
622 }
623 
624 CK_RV
gkm_mock_fail_C_OpenSession(CK_SLOT_ID slotID,CK_FLAGS flags,CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession)625 gkm_mock_fail_C_OpenSession (CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication,
626                              CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession)
627 {
628 	return CKR_GENERAL_ERROR;
629 }
630 
631 CK_RV
gkm_mock_C_CloseSession(CK_SESSION_HANDLE hSession)632 gkm_mock_C_CloseSession (CK_SESSION_HANDLE hSession)
633 {
634 	Session *session;
635 
636 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
637 	g_assert (session != NULL && "No such session found");
638 	if (!session)
639 		return CKR_SESSION_HANDLE_INVALID;
640 
641 	g_hash_table_remove (the_sessions, GUINT_TO_POINTER (hSession));
642 	return CKR_OK;
643 }
644 
645 CK_RV
gkm_mock_C_CloseAllSessions(CK_SLOT_ID slotID)646 gkm_mock_C_CloseAllSessions (CK_SLOT_ID slotID)
647 {
648 	g_assert (slotID == GKM_TEST_SLOT_ONE && "Invalid slotID");
649 
650 	g_hash_table_remove_all (the_sessions);
651 	return CKR_OK;
652 }
653 
654 CK_RV
gkm_mock_C_GetFunctionStatus(CK_SESSION_HANDLE hSession)655 gkm_mock_C_GetFunctionStatus (CK_SESSION_HANDLE hSession)
656 {
657 	return CKR_FUNCTION_NOT_PARALLEL;
658 }
659 
660 CK_RV
gkm_mock_C_CancelFunction(CK_SESSION_HANDLE hSession)661 gkm_mock_C_CancelFunction (CK_SESSION_HANDLE hSession)
662 {
663 	return CKR_FUNCTION_NOT_PARALLEL;
664 }
665 
666 CK_RV
gkm_mock_C_GetSessionInfo(CK_SESSION_HANDLE hSession,CK_SESSION_INFO_PTR pInfo)667 gkm_mock_C_GetSessionInfo (CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
668 {
669 	Session *session;
670 
671 	g_return_val_if_fail (pInfo != NULL, CKR_ARGUMENTS_BAD);
672 
673 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
674 	g_assert (session != NULL && "No such session found");
675 	if (!session)
676 		return CKR_SESSION_HANDLE_INVALID;
677 
678 	if (logged_in) {
679 		if (session->info.flags & CKF_RW_SESSION)
680 			session->info.state = CKS_RW_USER_FUNCTIONS;
681 		else
682 			session->info.state = CKS_RO_USER_FUNCTIONS;
683 	} else {
684 		if (session->info.flags & CKF_RW_SESSION)
685 			session->info.state = CKS_RW_PUBLIC_SESSION;
686 		else
687 			session->info.state = CKS_RO_PUBLIC_SESSION;
688 	}
689 
690 	memcpy (pInfo, &session->info, sizeof (*pInfo));
691 	return CKR_OK;
692 }
693 
694 CK_RV
gkm_mock_fail_C_GetSessionInfo(CK_SESSION_HANDLE hSession,CK_SESSION_INFO_PTR pInfo)695 gkm_mock_fail_C_GetSessionInfo (CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
696 {
697 	return CKR_GENERAL_ERROR;
698 }
699 
700 CK_RV
gkm_mock_C_InitPIN(CK_SESSION_HANDLE hSession,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen)701 gkm_mock_C_InitPIN (CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin,
702                     CK_ULONG ulPinLen)
703 {
704 	Session *session;
705 
706 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
707 	g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
708 
709 	g_free (the_pin);
710 	the_pin = g_strndup ((gchar*)pPin, ulPinLen);
711 	n_the_pin = ulPinLen;
712 	return CKR_OK;
713 }
714 
715 CK_RV
gkm_mock_C_SetPIN(CK_SESSION_HANDLE hSession,CK_UTF8CHAR_PTR pOldPin,CK_ULONG ulOldLen,CK_UTF8CHAR_PTR pNewPin,CK_ULONG ulNewLen)716 gkm_mock_C_SetPIN (CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
717                    CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen)
718 {
719 	Session *session;
720 	gchar *old;
721 
722 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
723 	g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
724 
725 	old = g_strndup ((gchar*)pOldPin, ulOldLen);
726 	if (!old || !g_str_equal (old, the_pin)) {
727 		g_free (old);
728 		return CKR_PIN_INCORRECT;
729 	}
730 
731 	g_free (old);
732 	g_free (the_pin);
733 	the_pin = g_strndup ((gchar*)pNewPin, ulNewLen);
734 	n_the_pin = ulNewLen;
735 	return CKR_OK;
736 }
737 
738 CK_RV
gkm_mock_unsupported_C_GetOperationState(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pOperationState,CK_ULONG_PTR pulOperationStateLen)739 gkm_mock_unsupported_C_GetOperationState (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState,
740                                           CK_ULONG_PTR pulOperationStateLen)
741 {
742 	return CKR_FUNCTION_NOT_SUPPORTED;
743 }
744 
745 CK_RV
gkm_mock_unsupported_C_SetOperationState(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pOperationState,CK_ULONG ulOperationStateLen,CK_OBJECT_HANDLE hEncryptionKey,CK_OBJECT_HANDLE hAuthenticationKey)746 gkm_mock_unsupported_C_SetOperationState (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState,
747                                           CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey,
748                                           CK_OBJECT_HANDLE hAuthenticationKey)
749 {
750 	return CKR_FUNCTION_NOT_SUPPORTED;
751 }
752 
753 CK_RV
gkm_mock_C_Login(CK_SESSION_HANDLE hSession,CK_USER_TYPE userType,CK_UTF8CHAR_PTR pPin,CK_ULONG pPinLen)754 gkm_mock_C_Login (CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
755                   CK_UTF8CHAR_PTR pPin, CK_ULONG pPinLen)
756 {
757 	Session *session;
758 
759 	g_return_val_if_fail (userType == CKU_SO ||
760 	                      userType == CKU_USER ||
761 	                      userType == CKU_CONTEXT_SPECIFIC,
762 	                      CKR_USER_TYPE_INVALID);
763 
764 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
765 	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
766 	g_return_val_if_fail (logged_in == FALSE, CKR_USER_ALREADY_LOGGED_IN);
767 
768 	if (!pPin)
769 		return CKR_PIN_INCORRECT;
770 
771 	if (pPinLen != strlen (the_pin))
772 		return CKR_PIN_INCORRECT;
773 	if (strncmp ((gchar*)pPin, the_pin, pPinLen) != 0)
774 		return CKR_PIN_INCORRECT;
775 
776 	if (userType == CKU_CONTEXT_SPECIFIC) {
777 		g_return_val_if_fail (session->want_context_login == TRUE, CKR_OPERATION_NOT_INITIALIZED);
778 		session->want_context_login = CK_FALSE;
779 	} else {
780 		logged_in = TRUE;
781 		user_type = userType;
782 	}
783 
784 	return CKR_OK;
785 }
786 
787 CK_RV
gkm_mock_C_Logout(CK_SESSION_HANDLE hSession)788 gkm_mock_C_Logout (CK_SESSION_HANDLE hSession)
789 {
790 	Session *session;
791 
792 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
793 	g_assert (session != NULL && "No such session found");
794 	if (!session)
795 		return CKR_SESSION_HANDLE_INVALID;
796 
797 	g_assert (logged_in && "Not logged in");
798 	logged_in = FALSE;
799 	user_type = 0;
800 	return CKR_OK;
801 }
802 
803 CK_RV
gkm_mock_C_CreateObject(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phObject)804 gkm_mock_C_CreateObject (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
805                          CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject)
806 {
807 	GArray *attrs;
808 	Session *session;
809 	gboolean token, priv;
810 	CK_OBJECT_CLASS klass;
811 	CK_OBJECT_HANDLE object;
812 	CK_ATTRIBUTE_PTR attr;
813 
814 	g_assert (phObject != NULL);
815 
816 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
817 	g_assert (session != NULL && "No such session found");
818 	if (!session)
819 		return CKR_SESSION_HANDLE_INVALID;
820 
821 	attrs = gkm_template_new (pTemplate, ulCount);
822 
823 	if (gkm_template_find_boolean (attrs, CKA_PRIVATE, &priv) && priv) {
824 		if (!logged_in) {
825 			gkm_template_free (attrs);
826 			return CKR_USER_NOT_LOGGED_IN;
827 		}
828 	}
829 
830 	/* In order to create a credential we must check CK_VALUE */
831 	if (gkm_template_find_ulong (attrs, CKA_CLASS, &klass) && klass == CKO_G_CREDENTIAL) {
832 		if (gkm_template_find_ulong (attrs, CKA_G_OBJECT, &object)) {
833 			attr = gkm_template_find (attrs, CKA_VALUE);
834 			if (!attr || attr->ulValueLen != n_the_pin ||
835 			    memcmp (attr->pValue, the_pin, attr->ulValueLen) != 0) {
836 				gkm_template_free (attrs);
837 				return CKR_PIN_INCORRECT;
838 			}
839 		}
840 	}
841 
842 	*phObject = ++unique_identifier;
843 	if (gkm_template_find_boolean (attrs, CKA_TOKEN, &token) && token)
844 		insert_template (*phObject, attrs);
845 	else
846 		g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phObject), attrs);
847 
848 	return CKR_OK;
849 }
850 
851 CK_RV
gkm_mock_unsupported_C_CopyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phNewObject)852 gkm_mock_unsupported_C_CopyObject (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
853                                    CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
854                                    CK_OBJECT_HANDLE_PTR phNewObject)
855 {
856 	return CKR_FUNCTION_NOT_SUPPORTED;
857 }
858 
859 CK_RV
gkm_mock_C_DestroyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject)860 gkm_mock_C_DestroyObject (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
861 {
862 	GArray *attrs;
863 	Session *session;
864 	GSList *list;
865 	gboolean priv;
866 
867 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
868 	g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
869 
870 	attrs = lookup_object (session, hObject);
871 	g_return_val_if_fail (attrs, CKR_OBJECT_HANDLE_INVALID);
872 
873 	if (gkm_template_find_boolean (attrs, CKA_PRIVATE, &priv) && priv) {
874 		if (!logged_in)
875 			return CKR_USER_NOT_LOGGED_IN;
876 	}
877 
878 	g_hash_table_remove (the_objects, GUINT_TO_POINTER (hObject));
879 	do {
880 		list = g_slist_find_custom (the_objects_list, GUINT_TO_POINTER (hObject), list_find_handle);
881 		if (list != NULL) {
882 			g_free (list->data);
883 			the_objects_list = g_slist_delete_link (the_objects_list, list);
884 		}
885 	} while (list != NULL);
886 	g_hash_table_remove (session->objects, GUINT_TO_POINTER (hObject));
887 
888 	return CKR_OK;
889 }
890 
891 CK_RV
gkm_mock_unsupported_C_GetObjectSize(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ULONG_PTR pulSize)892 gkm_mock_unsupported_C_GetObjectSize (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
893                                       CK_ULONG_PTR pulSize)
894 {
895 	return CKR_FUNCTION_NOT_SUPPORTED;
896 }
897 
898 CK_RV
gkm_mock_C_GetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)899 gkm_mock_C_GetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
900                               CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
901 {
902 	CK_ATTRIBUTE_PTR result;
903 	CK_RV ret = CKR_OK;
904 	GArray *attrs;
905 	CK_ATTRIBUTE_PTR attr;
906 	Session *session;
907 	CK_ULONG i;
908 
909 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
910 	g_assert (session != NULL && "No such session found");
911 	if (!session)
912 		return CKR_SESSION_HANDLE_INVALID;
913 
914 	attrs = lookup_object (session, hObject);
915 	if (!attrs) {
916 		g_assert_not_reached (); /* "invalid object handle passed" */
917 		return CKR_OBJECT_HANDLE_INVALID;
918 	}
919 
920 	for (i = 0; i < ulCount; ++i) {
921 		result = pTemplate + i;
922 		if (result->type == CKA_G_CREDENTIAL_TEMPLATE) {
923 			gkm_attribute_set_template (result, the_credential_template);
924 			continue;
925 		}
926 		attr = gkm_template_find (attrs, result->type);
927 		if (!attr) {
928 			result->ulValueLen = (CK_ULONG)-1;
929 			ret = CKR_ATTRIBUTE_TYPE_INVALID;
930 			continue;
931 		}
932 
933 		if (!result->pValue) {
934 			result->ulValueLen = attr->ulValueLen;
935 			continue;
936 		}
937 
938 		if (result->ulValueLen >= attr->ulValueLen) {
939 			memcpy (result->pValue, attr->pValue, attr->ulValueLen);
940 			continue;
941 		}
942 
943 		result->ulValueLen = (CK_ULONG)-1;
944 		ret = CKR_BUFFER_TOO_SMALL;
945 	}
946 
947 	return ret;
948 }
949 
950 CK_RV
gkm_mock_C_SetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)951 gkm_mock_C_SetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
952                               CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
953 {
954 	Session *session;
955 	GArray *attrs;
956 	CK_ULONG i;
957 
958 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
959 	g_assert (session != NULL && "No such session found");
960 	if (!session)
961 		return CKR_SESSION_HANDLE_INVALID;
962 
963 	attrs = lookup_object (session, hObject);
964 	if (!attrs) {
965 		g_assert_not_reached (); /* "invalid object handle passed" */
966 		return CKR_OBJECT_HANDLE_INVALID;
967 	}
968 
969 	for (i = 0; i < ulCount; ++i) {
970 		CK_ATTRIBUTE_PTR attr = pTemplate + i;
971 
972 		if (attr->type == CKA_G_CREDENTIAL_TEMPLATE) {
973 			CK_RV rv;
974 			GArray *template;
975 
976 			rv = gkm_attribute_get_template (attr, &template);
977 			if (rv != CKR_OK)
978 				return CKR_OBJECT_HANDLE_INVALID;
979 			gkm_template_free(the_credential_template);
980 			the_credential_template = template;
981 		} else {
982 			gkm_template_set (attrs, attr);
983 		}
984 	}
985 
986 	return CKR_OK;
987 }
988 
989 typedef struct _FindObjects {
990 	CK_ATTRIBUTE_PTR template;
991 	CK_ULONG count;
992 	Session *session;
993 } FindObjects;
994 
995 static gboolean
enumerate_and_find_objects(CK_OBJECT_HANDLE object,GArray * attrs,gpointer user_data)996 enumerate_and_find_objects (CK_OBJECT_HANDLE object, GArray *attrs, gpointer user_data)
997 {
998 	FindObjects *ctx = user_data;
999 	CK_ATTRIBUTE_PTR match, attr;
1000 	CK_ULONG i;
1001 
1002 	for (i = 0; i < ctx->count; ++i) {
1003 		match = ctx->template + i;
1004 		attr = gkm_template_find (attrs, match->type);
1005 		if (!attr)
1006 			return TRUE; /* Continue */
1007 
1008 		if (attr->ulValueLen != match->ulValueLen ||
1009 		    memcmp (attr->pValue, match->pValue, attr->ulValueLen) != 0)
1010 			return TRUE; /* Continue */
1011 	}
1012 
1013 	ctx->session->matches = g_list_prepend (ctx->session->matches, GUINT_TO_POINTER (object));
1014 	return TRUE; /* Continue */
1015 }
1016 
1017 CK_RV
gkm_mock_C_FindObjectsInit(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1018 gkm_mock_C_FindObjectsInit (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
1019                             CK_ULONG ulCount)
1020 {
1021 	Session *session;
1022 	FindObjects ctx;
1023 
1024 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1025 	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1026 
1027 	/* Starting an operation, cancels any previous one */
1028 	if (session->operation != 0)
1029 		session->operation = 0;
1030 
1031 	session->operation = OP_FIND;
1032 
1033 	ctx.template = pTemplate;
1034 	ctx.count = ulCount;
1035 	ctx.session = session;
1036 
1037 	gkm_mock_module_enumerate_objects (hSession, enumerate_and_find_objects, &ctx);
1038 	return CKR_OK;
1039 }
1040 
1041 CK_RV
gkm_mock_C_FindObjects(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,CK_ULONG_PTR pulObjectCount)1042 gkm_mock_C_FindObjects (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject,
1043                         CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
1044 {
1045 	Session *session;
1046 
1047 	g_assert (phObject != NULL);
1048 	g_assert (pulObjectCount != NULL);
1049 	g_assert (ulMaxObjectCount != 0);
1050 
1051 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1052 	g_assert (session != NULL && "No such session found");
1053 	if (!session)
1054 		return CKR_SESSION_HANDLE_INVALID;
1055 
1056 	if (session->operation != OP_FIND) {
1057 		g_assert_not_reached (); /* "invalid call to FindObjects" */
1058 		return CKR_OPERATION_NOT_INITIALIZED;
1059 	}
1060 
1061 	*pulObjectCount = 0;
1062 	while (ulMaxObjectCount > 0 && session->matches) {
1063 		*phObject = GPOINTER_TO_UINT (session->matches->data);
1064 		++phObject;
1065 		--ulMaxObjectCount;
1066 		++(*pulObjectCount);
1067 		session->matches = g_list_remove (session->matches, session->matches->data);
1068 	}
1069 
1070 	return CKR_OK;
1071 }
1072 
1073 CK_RV
gkm_mock_C_FindObjectsFinal(CK_SESSION_HANDLE hSession)1074 gkm_mock_C_FindObjectsFinal (CK_SESSION_HANDLE hSession)
1075 {
1076 
1077 	Session *session;
1078 
1079 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1080 	g_assert (session != NULL && "No such session found");
1081 	if (!session)
1082 		return CKR_SESSION_HANDLE_INVALID;
1083 
1084 	if (session->operation != OP_FIND) {
1085 		g_assert_not_reached (); /* "invalid call to FindObjectsFinal" */
1086 		return CKR_OPERATION_NOT_INITIALIZED;
1087 	}
1088 
1089 	session->operation = 0;
1090 	g_list_free (session->matches);
1091 	session->matches = NULL;
1092 
1093 	return CKR_OK;
1094 }
1095 
1096 CK_RV
gkm_mock_C_EncryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1097 gkm_mock_C_EncryptInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1098                         CK_OBJECT_HANDLE hKey)
1099 {
1100 	Session *session;
1101 
1102 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1103 	g_assert (session != NULL && "No such session found");
1104 	if (!session)
1105 		return CKR_SESSION_HANDLE_INVALID;
1106 
1107 	/* Starting an operation, cancels any previous one */
1108 	if (session->operation != 0)
1109 		session->operation = 0;
1110 
1111 	g_assert (pMechanism);
1112 	g_assert (pMechanism->mechanism == CKM_MOCK_CAPITALIZE);
1113 	g_assert (hKey == PUBLIC_KEY_CAPITALIZE);
1114 
1115 	session->operation = OP_CRYPTO;
1116 	session->crypto_method = CKA_ENCRYPT;
1117 	session->crypto_mechanism = CKM_MOCK_CAPITALIZE;
1118 	session->crypto_key = hKey;
1119 	return CKR_OK;
1120 }
1121 
1122 CK_RV
gkm_mock_C_Encrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)1123 gkm_mock_C_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
1124                     CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
1125 {
1126 	Session *session;
1127 	CK_ULONG i;
1128 
1129 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1130 	g_assert (session != NULL && "No such session found");
1131 	if (!session)
1132 		return CKR_SESSION_HANDLE_INVALID;
1133 
1134 	if (session->operation != OP_CRYPTO) {
1135 		g_assert_not_reached (); /* "invalid call to Encrypt" */
1136 		return CKR_OPERATION_NOT_INITIALIZED;
1137 	}
1138 
1139 	g_assert (pData);
1140 	g_assert (pulEncryptedDataLen);
1141 	g_assert (session->crypto_method == CKA_ENCRYPT);
1142 	g_assert (session->crypto_mechanism == CKM_MOCK_CAPITALIZE);
1143 	g_assert (session->crypto_key == PUBLIC_KEY_CAPITALIZE);
1144 
1145 	if (!pEncryptedData) {
1146 		*pulEncryptedDataLen = ulDataLen;
1147 		return CKR_OK;
1148 	}
1149 
1150 	if (*pulEncryptedDataLen < ulDataLen) {
1151 		*pulEncryptedDataLen = ulDataLen;
1152 		return CKR_BUFFER_TOO_SMALL;
1153 	}
1154 
1155 	for (i = 0; i < ulDataLen; ++i)
1156 		pEncryptedData[i] = g_ascii_toupper (pData[i]);
1157 	*pulEncryptedDataLen = ulDataLen;
1158 
1159 	session->operation = 0;
1160 	session->crypto_method = 0;
1161 	session->crypto_mechanism = 0;
1162 	session->crypto_key = 0;
1163 
1164 	return CKR_OK;
1165 }
1166 
1167 CK_RV
gkm_mock_unsupported_C_EncryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen,CK_BYTE_PTR pEncryptedPart,CK_ULONG_PTR pulEncryptedPartLen)1168 gkm_mock_unsupported_C_EncryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
1169                                       CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
1170                                       CK_ULONG_PTR pulEncryptedPartLen)
1171 {
1172 	return CKR_FUNCTION_NOT_SUPPORTED;
1173 }
1174 
1175 CK_RV
gkm_mock_unsupported_C_EncryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pLastEncryptedPart,CK_ULONG_PTR pulLastEncryptedPartLen)1176 gkm_mock_unsupported_C_EncryptFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart,
1177                                      CK_ULONG_PTR pulLastEncryptedPartLen)
1178 {
1179 	return CKR_FUNCTION_NOT_SUPPORTED;
1180 }
1181 
1182 CK_RV
gkm_mock_C_DecryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1183 gkm_mock_C_DecryptInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1184                         CK_OBJECT_HANDLE hKey)
1185 {
1186 	Session *session;
1187 
1188 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1189 	g_assert (session != NULL && "No such session found");
1190 	if (!session)
1191 		return CKR_SESSION_HANDLE_INVALID;
1192 
1193 	/* Starting an operation, cancels any previous one */
1194 	if (session->operation != 0)
1195 		session->operation = 0;
1196 
1197 	g_assert (pMechanism);
1198 	g_assert (pMechanism->mechanism == CKM_MOCK_CAPITALIZE);
1199 	g_assert (hKey == PRIVATE_KEY_CAPITALIZE);
1200 
1201 	session->operation = OP_CRYPTO;
1202 	session->crypto_method = CKA_DECRYPT;
1203 	session->crypto_mechanism = CKM_MOCK_CAPITALIZE;
1204 	session->crypto_key = hKey;
1205 	return CKR_OK;
1206 }
1207 
1208 CK_RV
gkm_mock_C_Decrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)1209 gkm_mock_C_Decrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData,
1210                     CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
1211 {
1212 	Session *session;
1213 	CK_ULONG i;
1214 
1215 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1216 	g_assert (session != NULL && "No such session found");
1217 	if (!session)
1218 		return CKR_SESSION_HANDLE_INVALID;
1219 
1220 	if (session->operation != OP_CRYPTO) {
1221 		g_assert_not_reached (); /* "invalid call to Encrypt" */
1222 		return CKR_OPERATION_NOT_INITIALIZED;
1223 	}
1224 
1225 	g_assert (pEncryptedData);
1226 	g_assert (pulDataLen);
1227 	g_assert (session->crypto_method == CKA_DECRYPT);
1228 	g_assert (session->crypto_mechanism == CKM_MOCK_CAPITALIZE);
1229 	g_assert (session->crypto_key == PRIVATE_KEY_CAPITALIZE);
1230 
1231 	if (!pData) {
1232 		*pulDataLen = ulEncryptedDataLen;
1233 		return CKR_OK;
1234 	}
1235 
1236 	if (*pulDataLen < ulEncryptedDataLen) {
1237 		*pulDataLen = ulEncryptedDataLen;
1238 		return CKR_BUFFER_TOO_SMALL;
1239 	}
1240 
1241 	for (i = 0; i < ulEncryptedDataLen; ++i)
1242 		pData[i] = g_ascii_tolower (pEncryptedData[i]);
1243 	*pulDataLen = ulEncryptedDataLen;
1244 
1245 	session->operation = 0;
1246 	session->crypto_method = 0;
1247 	session->crypto_mechanism = 0;
1248 	session->crypto_key = 0;
1249 
1250 	return CKR_OK;
1251 }
1252 
1253 CK_RV
gkm_mock_unsupported_C_DecryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedPart,CK_ULONG ulEncryptedPartLen,CK_BYTE_PTR pPart,CK_ULONG_PTR pulPartLen)1254 gkm_mock_unsupported_C_DecryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart,
1255                                       CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
1256 {
1257 	return CKR_FUNCTION_NOT_SUPPORTED;
1258 }
1259 
1260 CK_RV
gkm_mock_unsupported_C_DecryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pLastPart,CK_ULONG_PTR pulLastPartLen)1261 gkm_mock_unsupported_C_DecryptFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart,
1262                                      CK_ULONG_PTR pulLastPartLen)
1263 {
1264 	return CKR_FUNCTION_NOT_SUPPORTED;
1265 }
1266 
1267 CK_RV
gkm_mock_unsupported_C_DigestInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism)1268 gkm_mock_unsupported_C_DigestInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism)
1269 {
1270 	return CKR_FUNCTION_NOT_SUPPORTED;
1271 }
1272 
1273 CK_RV
gkm_mock_unsupported_C_Digest(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)1274 gkm_mock_unsupported_C_Digest (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
1275                                CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
1276 {
1277 	return CKR_FUNCTION_NOT_SUPPORTED;
1278 }
1279 
1280 CK_RV
gkm_mock_unsupported_C_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)1281 gkm_mock_unsupported_C_DigestUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
1282 {
1283 	return CKR_FUNCTION_NOT_SUPPORTED;
1284 }
1285 
1286 CK_RV
gkm_mock_unsupported_C_DigestKey(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hKey)1287 gkm_mock_unsupported_C_DigestKey (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
1288 {
1289 	return CKR_FUNCTION_NOT_SUPPORTED;
1290 }
1291 
1292 CK_RV
gkm_mock_unsupported_C_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)1293 gkm_mock_unsupported_C_DigestFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest,
1294                                     CK_ULONG_PTR pulDigestLen)
1295 {
1296 	return CKR_FUNCTION_NOT_SUPPORTED;
1297 }
1298 
1299 CK_RV
gkm_mock_C_SignInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1300 gkm_mock_C_SignInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1301                      CK_OBJECT_HANDLE hKey)
1302 {
1303 	Session *session;
1304 
1305 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1306 	g_assert (session != NULL && "No such session found");
1307 	if (!session)
1308 		return CKR_SESSION_HANDLE_INVALID;
1309 
1310 	/* Starting an operation, cancels any previous one */
1311 	if (session->operation != 0)
1312 		session->operation = 0;
1313 
1314 	g_assert (pMechanism);
1315 	g_assert (pMechanism->mechanism == CKM_MOCK_PREFIX);
1316 	g_assert (hKey == PRIVATE_KEY_PREFIX);
1317 
1318 	session->operation = OP_CRYPTO;
1319 	session->crypto_method = CKA_SIGN;
1320 	session->crypto_mechanism = CKM_MOCK_PREFIX;
1321 	session->crypto_key = hKey;
1322 
1323 	if (pMechanism->pParameter) {
1324 		g_assert (pMechanism->ulParameterLen < sizeof (session->sign_prefix));
1325 		memcpy (session->sign_prefix, pMechanism->pParameter, pMechanism->ulParameterLen);
1326 		session->n_sign_prefix = pMechanism->ulParameterLen;
1327 	} else {
1328 		g_assert (strlen (SIGNED_PREFIX) + 1 < sizeof (session->sign_prefix));
1329 		strcpy ((gchar*)session->sign_prefix, SIGNED_PREFIX);
1330 		session->n_sign_prefix = strlen (SIGNED_PREFIX);
1331 	}
1332 
1333 	/* The private key has CKA_ALWAYS_AUTHENTICATE above */
1334 	session->want_context_login = CK_TRUE;
1335 
1336 	return CKR_OK;
1337 }
1338 
1339 CK_RV
gkm_mock_C_Sign(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)1340 gkm_mock_C_Sign (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
1341                  CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
1342 {
1343 	Session *session;
1344 	CK_ULONG length;
1345 
1346 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1347 	g_assert (session != NULL && "No such session found");
1348 	if (!session)
1349 		return CKR_SESSION_HANDLE_INVALID;
1350 
1351 	if (session->operation != OP_CRYPTO) {
1352 		g_assert_not_reached (); /* "invalid call to Encrypt" */
1353 		return CKR_OPERATION_NOT_INITIALIZED;
1354 	}
1355 
1356 	if (session->want_context_login)
1357 		return CKR_USER_NOT_LOGGED_IN;
1358 
1359 	g_assert (pData);
1360 	g_assert (pulSignatureLen);
1361 	g_assert (session->crypto_method == CKA_SIGN);
1362 	g_assert (session->crypto_mechanism == CKM_MOCK_PREFIX);
1363 	g_assert (session->crypto_key == PRIVATE_KEY_PREFIX);
1364 
1365 	length = session->n_sign_prefix + ulDataLen;
1366 
1367 	if (!pSignature) {
1368 		*pulSignatureLen = length;
1369 		return CKR_OK;
1370 	}
1371 
1372 	if (*pulSignatureLen < length) {
1373 		*pulSignatureLen = length;
1374 		return CKR_BUFFER_TOO_SMALL;
1375 	}
1376 
1377 	memcpy (pSignature, session->sign_prefix, session->n_sign_prefix);
1378 	memcpy (pSignature + session->n_sign_prefix, pData, ulDataLen);
1379 	*pulSignatureLen = length;
1380 
1381 	session->operation = 0;
1382 	session->crypto_method = 0;
1383 	session->crypto_mechanism = 0;
1384 	session->crypto_key = 0;
1385 
1386 	return CKR_OK;
1387 }
1388 
1389 CK_RV
gkm_mock_unsupported_C_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)1390 gkm_mock_unsupported_C_SignUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
1391 {
1392 	return CKR_FUNCTION_NOT_SUPPORTED;
1393 }
1394 
1395 CK_RV
gkm_mock_unsupported_C_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)1396 gkm_mock_unsupported_C_SignFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
1397                                   CK_ULONG_PTR pulSignatureLen)
1398 {
1399 	return CKR_FUNCTION_NOT_SUPPORTED;
1400 }
1401 
1402 CK_RV
gkm_mock_unsupported_C_SignRecoverInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1403 gkm_mock_unsupported_C_SignRecoverInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1404                                         CK_OBJECT_HANDLE hKey)
1405 {
1406 	return CKR_FUNCTION_NOT_SUPPORTED;
1407 }
1408 
1409 CK_RV
gkm_mock_unsupported_C_SignRecover(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)1410 gkm_mock_unsupported_C_SignRecover (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
1411                                     CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
1412 {
1413 	return CKR_FUNCTION_NOT_SUPPORTED;
1414 }
1415 
1416 CK_RV
gkm_mock_C_VerifyInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1417 gkm_mock_C_VerifyInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1418                        CK_OBJECT_HANDLE hKey)
1419 {
1420 	Session *session;
1421 
1422 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1423 	g_assert (session != NULL && "No such session found");
1424 	if (!session)
1425 		return CKR_SESSION_HANDLE_INVALID;
1426 
1427 	/* Starting an operation, cancels any previous one */
1428 	if (session->operation != 0)
1429 		session->operation = 0;
1430 
1431 	g_assert (pMechanism);
1432 	g_assert (pMechanism->mechanism == CKM_MOCK_PREFIX);
1433 	g_assert (hKey == PUBLIC_KEY_PREFIX);
1434 
1435 	session->operation = OP_CRYPTO;
1436 	session->crypto_method = CKA_VERIFY;
1437 	session->crypto_mechanism = CKM_MOCK_PREFIX;
1438 	session->crypto_key = hKey;
1439 
1440 	if (pMechanism->pParameter) {
1441 		g_assert (pMechanism->ulParameterLen < sizeof (session->sign_prefix));
1442 		memcpy (session->sign_prefix, pMechanism->pParameter, pMechanism->ulParameterLen);
1443 		session->n_sign_prefix = pMechanism->ulParameterLen;
1444 	} else {
1445 		g_assert (strlen (SIGNED_PREFIX) + 1 < sizeof (session->sign_prefix));
1446 		strcpy ((gchar*)session->sign_prefix, SIGNED_PREFIX);
1447 		session->n_sign_prefix = strlen (SIGNED_PREFIX);
1448 	}
1449 
1450 	return CKR_OK;
1451 }
1452 
1453 CK_RV
gkm_mock_C_Verify(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)1454 gkm_mock_C_Verify (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
1455                    CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
1456 {
1457 	Session *session;
1458 	CK_ULONG length;
1459 
1460 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1461 	g_assert (session != NULL && "No such session found");
1462 	if (!session)
1463 		return CKR_SESSION_HANDLE_INVALID;
1464 
1465 	if (session->operation != OP_CRYPTO) {
1466 		g_assert_not_reached (); /* "invalid call to Encrypt" */
1467 		return CKR_OPERATION_NOT_INITIALIZED;
1468 	}
1469 
1470 	g_assert (pData);
1471 	g_assert (pSignature);
1472 	g_assert (session->crypto_method == CKA_VERIFY);
1473 	g_assert (session->crypto_mechanism == CKM_MOCK_PREFIX);
1474 	g_assert (session->crypto_key == PUBLIC_KEY_PREFIX);
1475 
1476 	length = session->n_sign_prefix + ulDataLen;
1477 
1478 	if (ulSignatureLen < length) {
1479 		g_assert (FALSE);
1480 		return CKR_SIGNATURE_LEN_RANGE;
1481 	}
1482 
1483 	if (memcmp (pSignature, session->sign_prefix, session->n_sign_prefix) == 0 &&
1484 	    memcmp (pSignature + session->n_sign_prefix, pData, ulDataLen) == 0)
1485 		return CKR_OK;
1486 
1487 	return CKR_SIGNATURE_INVALID;
1488 }
1489 
1490 CK_RV
gkm_mock_unsupported_C_VerifyUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)1491 gkm_mock_unsupported_C_VerifyUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
1492 {
1493 	return CKR_FUNCTION_NOT_SUPPORTED;
1494 }
1495 
1496 CK_RV
gkm_mock_unsupported_C_VerifyFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG pulSignatureLen)1497 gkm_mock_unsupported_C_VerifyFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
1498                                     CK_ULONG pulSignatureLen)
1499 {
1500 	return CKR_FUNCTION_NOT_SUPPORTED;
1501 }
1502 
1503 CK_RV
gkm_mock_unsupported_C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1504 gkm_mock_unsupported_C_VerifyRecoverInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1505                                           CK_OBJECT_HANDLE hKey)
1506 {
1507 	return CKR_FUNCTION_NOT_SUPPORTED;
1508 }
1509 
1510 CK_RV
gkm_mock_unsupported_C_VerifyRecover(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG pulSignatureLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)1511 gkm_mock_unsupported_C_VerifyRecover (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
1512                                       CK_ULONG pulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
1513 {
1514 	return CKR_FUNCTION_NOT_SUPPORTED;
1515 }
1516 
1517 CK_RV
gkm_mock_unsupported_C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen,CK_BYTE_PTR pEncryptedPart,CK_ULONG_PTR ulEncryptedPartLen)1518 gkm_mock_unsupported_C_DigestEncryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
1519                                             CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
1520                                             CK_ULONG_PTR ulEncryptedPartLen)
1521 {
1522 	return CKR_FUNCTION_NOT_SUPPORTED;
1523 }
1524 
1525 CK_RV
gkm_mock_unsupported_C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedPart,CK_ULONG ulEncryptedPartLen,CK_BYTE_PTR pPart,CK_ULONG_PTR pulPartLen)1526 gkm_mock_unsupported_C_DecryptDigestUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart,
1527                                             CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
1528                                             CK_ULONG_PTR pulPartLen)
1529 {
1530 	return CKR_FUNCTION_NOT_SUPPORTED;
1531 }
1532 
1533 CK_RV
gkm_mock_unsupported_C_SignEncryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen,CK_BYTE_PTR pEncryptedPart,CK_ULONG_PTR ulEncryptedPartLen)1534 gkm_mock_unsupported_C_SignEncryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
1535                                           CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
1536                                           CK_ULONG_PTR ulEncryptedPartLen)
1537 {
1538 	return CKR_FUNCTION_NOT_SUPPORTED;
1539 }
1540 
1541 CK_RV
gkm_mock_unsupported_C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedPart,CK_ULONG ulEncryptedPartLen,CK_BYTE_PTR pPart,CK_ULONG_PTR pulPartLen)1542 gkm_mock_unsupported_C_DecryptVerifyUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart,
1543                                             CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
1544                                             CK_ULONG_PTR pulPartLen)
1545 {
1546 	return CKR_FUNCTION_NOT_SUPPORTED;
1547 }
1548 
1549 CK_RV
gkm_mock_unsupported_C_GenerateKey(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey)1550 gkm_mock_unsupported_C_GenerateKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1551                                     CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
1552                                     CK_OBJECT_HANDLE_PTR phKey)
1553 {
1554 	return CKR_FUNCTION_NOT_SUPPORTED;
1555 }
1556 
1557 CK_RV
gkm_mock_unsupported_C_GenerateKeyPair(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pPublicKeyTemplate,CK_ULONG ulPublicKeyAttributeCount,CK_ATTRIBUTE_PTR pPrivateKeyTemplate,CK_ULONG ulPrivateKeyAttributeCount,CK_OBJECT_HANDLE_PTR phPublicKey,CK_OBJECT_HANDLE_PTR phPrivateKey)1558 gkm_mock_unsupported_C_GenerateKeyPair (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1559                                         CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount,
1560                                         CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount,
1561                                         CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)
1562 {
1563 	return CKR_FUNCTION_NOT_SUPPORTED;
1564 }
1565 
1566 CK_RV
gkm_mock_unsupported_C_WrapKey(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hWrappingKey,CK_OBJECT_HANDLE hKey,CK_BYTE_PTR pWrappedKey,CK_ULONG_PTR pulWrappedKeyLen)1567 gkm_mock_unsupported_C_WrapKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1568                                 CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey,
1569                                 CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
1570 {
1571 	return CKR_FUNCTION_NOT_SUPPORTED;
1572 }
1573 
1574 CK_RV
gkm_mock_unsupported_C_UnwrapKey(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE pUnwrappingKey,CK_BYTE_PTR pWrappedKey,CK_ULONG pulWrappedKeyLen,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey)1575 gkm_mock_unsupported_C_UnwrapKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1576                                   CK_OBJECT_HANDLE pUnwrappingKey, CK_BYTE_PTR pWrappedKey,
1577                                   CK_ULONG pulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate,
1578                                   CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
1579 {
1580 	return CKR_FUNCTION_NOT_SUPPORTED;
1581 }
1582 
1583 CK_RV
gkm_mock_unsupported_C_DeriveKey(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hBaseKey,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey)1584 gkm_mock_unsupported_C_DeriveKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1585                                   CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
1586                                   CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
1587 {
1588 	return CKR_FUNCTION_NOT_SUPPORTED;
1589 }
1590 
1591 CK_RV
gkm_mock_unsupported_C_SeedRandom(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSeed,CK_ULONG ulSeedLen)1592 gkm_mock_unsupported_C_SeedRandom (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
1593 {
1594 	return CKR_FUNCTION_NOT_SUPPORTED;
1595 }
1596 
1597 CK_RV
gkm_mock_unsupported_C_GenerateRandom(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pRandomData,CK_ULONG ulRandomLen)1598 gkm_mock_unsupported_C_GenerateRandom (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData,
1599                            CK_ULONG ulRandomLen)
1600 {
1601 	return CKR_FUNCTION_NOT_SUPPORTED;
1602 }
1603 
1604 static CK_FUNCTION_LIST functionList = {
1605 	{ 2, 11 },	/* version */
1606 	gkm_mock_C_Initialize,
1607 	gkm_mock_C_Finalize,
1608 	gkm_mock_C_GetInfo,
1609 	gkm_mock_C_GetFunctionList,
1610 	gkm_mock_C_GetSlotList,
1611 	gkm_mock_C_GetSlotInfo,
1612 	gkm_mock_C_GetTokenInfo,
1613 	gkm_mock_C_GetMechanismList,
1614 	gkm_mock_C_GetMechanismInfo,
1615 	gkm_mock_C_InitToken,
1616 	gkm_mock_C_InitPIN,
1617 	gkm_mock_C_SetPIN,
1618 	gkm_mock_C_OpenSession,
1619 	gkm_mock_C_CloseSession,
1620 	gkm_mock_C_CloseAllSessions,
1621 	gkm_mock_C_GetSessionInfo,
1622 	gkm_mock_unsupported_C_GetOperationState,
1623 	gkm_mock_unsupported_C_SetOperationState,
1624 	gkm_mock_C_Login,
1625 	gkm_mock_C_Logout,
1626 	gkm_mock_C_CreateObject,
1627 	gkm_mock_unsupported_C_CopyObject,
1628 	gkm_mock_C_DestroyObject,
1629 	gkm_mock_unsupported_C_GetObjectSize,
1630 	gkm_mock_C_GetAttributeValue,
1631 	gkm_mock_C_SetAttributeValue,
1632 	gkm_mock_C_FindObjectsInit,
1633 	gkm_mock_C_FindObjects,
1634 	gkm_mock_C_FindObjectsFinal,
1635 	gkm_mock_C_EncryptInit,
1636 	gkm_mock_C_Encrypt,
1637 	gkm_mock_unsupported_C_EncryptUpdate,
1638 	gkm_mock_unsupported_C_EncryptFinal,
1639 	gkm_mock_C_DecryptInit,
1640 	gkm_mock_C_Decrypt,
1641 	gkm_mock_unsupported_C_DecryptUpdate,
1642 	gkm_mock_unsupported_C_DecryptFinal,
1643 	gkm_mock_unsupported_C_DigestInit,
1644 	gkm_mock_unsupported_C_Digest,
1645 	gkm_mock_unsupported_C_DigestUpdate,
1646 	gkm_mock_unsupported_C_DigestKey,
1647 	gkm_mock_unsupported_C_DigestFinal,
1648 	gkm_mock_C_SignInit,
1649 	gkm_mock_C_Sign,
1650 	gkm_mock_unsupported_C_SignUpdate,
1651 	gkm_mock_unsupported_C_SignFinal,
1652 	gkm_mock_unsupported_C_SignRecoverInit,
1653 	gkm_mock_unsupported_C_SignRecover,
1654 	gkm_mock_C_VerifyInit,
1655 	gkm_mock_C_Verify,
1656 	gkm_mock_unsupported_C_VerifyUpdate,
1657 	gkm_mock_unsupported_C_VerifyFinal,
1658 	gkm_mock_unsupported_C_VerifyRecoverInit,
1659 	gkm_mock_unsupported_C_VerifyRecover,
1660 	gkm_mock_unsupported_C_DigestEncryptUpdate,
1661 	gkm_mock_unsupported_C_DecryptDigestUpdate,
1662 	gkm_mock_unsupported_C_SignEncryptUpdate,
1663 	gkm_mock_unsupported_C_DecryptVerifyUpdate,
1664 	gkm_mock_unsupported_C_GenerateKey,
1665 	gkm_mock_unsupported_C_GenerateKeyPair,
1666 	gkm_mock_unsupported_C_WrapKey,
1667 	gkm_mock_unsupported_C_UnwrapKey,
1668 	gkm_mock_unsupported_C_DeriveKey,
1669 	gkm_mock_unsupported_C_SeedRandom,
1670 	gkm_mock_unsupported_C_GenerateRandom,
1671 	gkm_mock_C_GetFunctionStatus,
1672 	gkm_mock_C_CancelFunction,
1673 	gkm_mock_unsupported_C_WaitForSlotEvent
1674 };
1675