4
* Copyright (C) 2010 Stefan Walter
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU Lesser General License as
8
* published by the Free Software Foundation; either version 2.1 of
9
* the License, or (at your option) any later version.
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 License for more details.
16
* You should have received a copy of the GNU Lesser General
17
* License along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27
#include "pkcs11/pkcs11.h"
28
#include "pkcs11/pkcs11i.h"
35
* This is *NOT* how you'd want to implement a PKCS#11 module. This
36
* fake module simply provides enough for gck library to test against.
37
* It doesn't pass any tests, or behave as expected from a PKCS#11 module.
41
static gboolean initialized = FALSE;
42
static gchar *the_pin = NULL;
43
static gulong n_the_pin = 0;
45
static gboolean logged_in = FALSE;
46
static CK_USER_TYPE user_type = 0;
47
static CK_FUNCTION_LIST functionList;
49
typedef enum _Operation {
54
typedef struct _Session {
55
CK_SESSION_HANDLE handle;
61
/* For find operations */
64
/* For crypto operations */
65
CK_OBJECT_HANDLE crypto_key;
66
CK_ATTRIBUTE_TYPE crypto_method;
67
CK_MECHANISM_TYPE crypto_mechanism;
68
CK_BBOOL want_context_login;
70
/* For 'signing' with CKM_MOCK_PREFIX */
71
CK_BYTE sign_prefix[128];
72
CK_ULONG n_sign_prefix;
75
static guint unique_identifier = 100;
76
static GHashTable *the_sessions = NULL;
77
static GHashTable *the_objects = NULL;
80
PRIVATE_KEY_CAPITALIZE = 3,
81
PUBLIC_KEY_CAPITALIZE = 4,
82
PRIVATE_KEY_PREFIX = 5,
86
#define SIGNED_PREFIX "signed-prefix:"
89
free_session (gpointer data)
91
Session *sess = (Session*)data;
93
g_hash_table_destroy (sess->objects);
98
lookup_object (Session *session, CK_OBJECT_HANDLE hObject)
100
GckAttributes *attrs;
101
attrs = g_hash_table_lookup (the_objects, GUINT_TO_POINTER (hObject));
103
attrs = g_hash_table_lookup (session->objects, GUINT_TO_POINTER (hObject));
108
gck_mock_module_take_object (GckAttributes *attrs)
113
g_return_val_if_fail (the_objects, 0);
115
handle = ++unique_identifier;
116
if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token))
117
g_return_val_if_fail (token == TRUE, 0);
119
gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);
120
g_hash_table_insert (the_objects, GUINT_TO_POINTER (handle), attrs);
125
gck_mock_module_enumerate_objects (CK_SESSION_HANDLE handle, GckMockEnumerator func,
133
g_assert (the_objects);
137
g_hash_table_iter_init (&iter, the_objects);
138
while (g_hash_table_iter_next (&iter, &key, &value)) {
139
if (!(func) (GPOINTER_TO_UINT (key), value, user_data))
143
/* session objects */
145
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (handle));
147
g_hash_table_iter_init (&iter, session->objects);
148
while (g_hash_table_iter_next (&iter, &key, &value)) {
149
if (!(func) (GPOINTER_TO_UINT (key), value, user_data))
156
typedef struct _FindObject {
157
CK_ATTRIBUTE_PTR attrs;
159
CK_OBJECT_HANDLE object;
163
enumerate_and_find_object (CK_OBJECT_HANDLE object, GckAttributes *attrs, gpointer user_data)
165
FindObject *ctx = user_data;
166
CK_ATTRIBUTE_PTR match;
170
for (i = 0; i < ctx->n_attrs; ++i) {
171
match = ctx->attrs + i;
172
attr = gck_attributes_find (attrs, match->type);
174
return TRUE; /* Continue */
176
if (attr->length != match->ulValueLen ||
177
memcmp (attr->value, match->pValue, attr->length) != 0)
178
return TRUE; /* Continue */
181
ctx->object = object;
182
return FALSE; /* Stop iteration */
186
gck_mock_module_find_object (CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
191
ctx.n_attrs = n_attrs;
194
gck_mock_module_enumerate_objects (session, enumerate_and_find_object, &ctx);
200
enumerate_and_count_objects (CK_OBJECT_HANDLE object, GckAttributes *attrs, gpointer user_data)
202
guint *n_objects = user_data;
204
return TRUE; /* Continue */
208
gck_mock_module_count_objects (CK_SESSION_HANDLE session)
211
gck_mock_module_enumerate_objects (session, enumerate_and_count_objects, &n_objects);
216
gck_mock_module_set_object (CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR attrs,
222
CK_ATTRIBUTE_PTR set;
224
g_return_if_fail (object != 0);
225
g_return_if_fail (the_objects);
227
atts = g_hash_table_lookup (the_objects, GUINT_TO_POINTER (object));
228
g_return_if_fail (atts);
230
for (i = 0; i < n_attrs; ++i) {
232
attr = gck_attributes_find (atts, set->type);
234
gck_attributes_add_data (atts, set->type, set->pValue, set->ulValueLen);
236
gck_attribute_clear (attr);
237
gck_attribute_init (attr, set->type, set->pValue, set->ulValueLen);
243
gck_mock_module_set_pin (const gchar *password)
246
the_pin = g_strdup (password);
247
n_the_pin = strlen (password);
251
gck_mock_C_Initialize (CK_VOID_PTR pInitArgs)
253
GckAttributes *attrs;
255
CK_C_INITIALIZE_ARGS_PTR args;
257
g_return_val_if_fail (initialized == FALSE, CKR_CRYPTOKI_ALREADY_INITIALIZED);
259
args = (CK_C_INITIALIZE_ARGS_PTR)pInitArgs;
261
g_return_val_if_fail(
262
(args->CreateMutex == NULL && args->DestroyMutex == NULL &&
263
args->LockMutex == NULL && args->UnlockMutex == NULL) ||
264
(args->CreateMutex != NULL && args->DestroyMutex != NULL &&
265
args->LockMutex != NULL && args->UnlockMutex != NULL),
268
/* Flags should allow OS locking and os threads */
269
g_return_val_if_fail ((args->flags & CKF_OS_LOCKING_OK), CKR_CANT_LOCK);
270
g_return_val_if_fail ((args->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) == 0, CKR_NEED_TO_CREATE_THREADS);
273
the_pin = g_strdup ("booo");
274
n_the_pin = strlen (the_pin);
275
the_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_session);
276
the_objects = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)gck_attributes_unref);
278
/* Our token object */
279
attrs = gck_attributes_new ();
280
gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_DATA);
281
gck_attributes_add_string (attrs, CKA_LABEL, "TEST LABEL");
282
g_hash_table_insert (the_objects, GUINT_TO_POINTER (2), attrs);
284
/* Private capitalize key */
285
value = CKM_MOCK_CAPITALIZE;
286
attrs = gck_attributes_new ();
287
gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_PRIVATE_KEY);
288
gck_attributes_add_string (attrs, CKA_LABEL, "Private Capitalize Key");
289
gck_attributes_add_data (attrs, CKA_ALLOWED_MECHANISMS, &value, sizeof (value));
290
gck_attributes_add_boolean (attrs, CKA_DECRYPT, CK_TRUE);
291
gck_attributes_add_boolean (attrs, CKA_PRIVATE, CK_TRUE);
292
gck_attributes_add_boolean (attrs, CKA_WRAP, CK_TRUE);
293
gck_attributes_add_boolean (attrs, CKA_UNWRAP, CK_TRUE);
294
gck_attributes_add_boolean (attrs, CKA_DERIVE, CK_TRUE);
295
gck_attributes_add_string (attrs, CKA_VALUE, "value");
296
gck_attributes_add_string (attrs, CKA_GNOME_UNIQUE, "unique1");
297
g_hash_table_insert (the_objects, GUINT_TO_POINTER (PRIVATE_KEY_CAPITALIZE), attrs);
299
/* Public capitalize key */
300
value = CKM_MOCK_CAPITALIZE;
301
attrs = gck_attributes_new ();
302
gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_PUBLIC_KEY);
303
gck_attributes_add_string (attrs, CKA_LABEL, "Public Capitalize Key");
304
gck_attributes_add_data (attrs, CKA_ALLOWED_MECHANISMS, &value, sizeof (value));
305
gck_attributes_add_boolean (attrs, CKA_ENCRYPT, CK_TRUE);
306
gck_attributes_add_boolean (attrs, CKA_PRIVATE, CK_FALSE);
307
gck_attributes_add_string (attrs, CKA_VALUE, "value");
308
gck_attributes_add_string (attrs, CKA_GNOME_UNIQUE, "unique2");
309
g_hash_table_insert (the_objects, GUINT_TO_POINTER (PUBLIC_KEY_CAPITALIZE), attrs);
311
/* Private prefix key */
312
value = CKM_MOCK_PREFIX;
313
attrs = gck_attributes_new ();
314
gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_PRIVATE_KEY);
315
gck_attributes_add_string (attrs, CKA_LABEL, "Private prefix key");
316
gck_attributes_add_data (attrs, CKA_ALLOWED_MECHANISMS, &value, sizeof (value));
317
gck_attributes_add_boolean (attrs, CKA_SIGN, CK_TRUE);
318
gck_attributes_add_boolean (attrs, CKA_PRIVATE, CK_TRUE);
319
gck_attributes_add_boolean (attrs, CKA_ALWAYS_AUTHENTICATE, CK_TRUE);
320
gck_attributes_add_string (attrs, CKA_VALUE, "value");
321
gck_attributes_add_string (attrs, CKA_GNOME_UNIQUE, "unique3");
322
g_hash_table_insert (the_objects, GUINT_TO_POINTER (PRIVATE_KEY_PREFIX), attrs);
324
/* Private prefix key */
325
value = CKM_MOCK_PREFIX;
326
attrs = gck_attributes_new ();
327
gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_PUBLIC_KEY);
328
gck_attributes_add_string (attrs, CKA_LABEL, "Public prefix key");
329
gck_attributes_add_data (attrs, CKA_ALLOWED_MECHANISMS, &value, sizeof (value));
330
gck_attributes_add_boolean (attrs, CKA_VERIFY, CK_TRUE);
331
gck_attributes_add_boolean (attrs, CKA_PRIVATE, CK_FALSE);
332
gck_attributes_add_string (attrs, CKA_VALUE, "value");
333
gck_attributes_add_string (attrs, CKA_GNOME_UNIQUE, "unique4");
334
g_hash_table_insert (the_objects, GUINT_TO_POINTER (PUBLIC_KEY_PREFIX), attrs);
341
gck_mock_validate_and_C_Initialize (CK_VOID_PTR pInitArgs)
343
CK_C_INITIALIZE_ARGS_PTR args;
347
args = (CK_C_INITIALIZE_ARGS_PTR)pInitArgs;
349
g_assert ((args->CreateMutex) (NULL) == CKR_ARGUMENTS_BAD && "CreateMutex succeeded wrong");
350
g_assert ((args->DestroyMutex) (NULL) == CKR_MUTEX_BAD && "DestroyMutex succeeded wrong");
351
g_assert ((args->LockMutex) (NULL) == CKR_MUTEX_BAD && "LockMutex succeeded wrong");
352
g_assert ((args->UnlockMutex) (NULL) == CKR_MUTEX_BAD && "UnlockMutex succeeded wrong");
354
/* Try to create an actual mutex */
355
rv = (args->CreateMutex) (&mutex);
356
g_assert (rv == CKR_OK && "CreateMutex g_assert_not_reacheded");
357
g_assert (mutex != NULL && "CreateMutex created null mutex");
359
/* Try and lock the mutex */
360
rv = (args->LockMutex) (mutex);
361
g_assert (rv == CKR_OK && "LockMutex g_assert_not_reacheded");
363
/* Try and unlock the mutex */
364
rv = (args->UnlockMutex) (mutex);
365
g_assert (rv == CKR_OK && "UnlockMutex g_assert_not_reacheded");
367
/* Try and destroy the mutex */
368
rv = (args->DestroyMutex) (mutex);
369
g_assert (rv == CKR_OK && "DestroyMutex g_assert_not_reacheded");
372
return gck_mock_C_Initialize (pInitArgs);
376
gck_mock_C_Finalize (CK_VOID_PTR pReserved)
378
g_return_val_if_fail (pReserved == NULL, CKR_ARGUMENTS_BAD);
379
g_return_val_if_fail (initialized == TRUE, CKR_CRYPTOKI_NOT_INITIALIZED);
383
g_hash_table_destroy (the_objects);
386
g_hash_table_destroy (the_sessions);
393
static const CK_INFO TEST_INFO = {
394
{ CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
395
"TEST MANUFACTURER ",
402
gck_mock_C_GetInfo (CK_INFO_PTR pInfo)
404
g_return_val_if_fail (pInfo, CKR_ARGUMENTS_BAD);
405
memcpy (pInfo, &TEST_INFO, sizeof (*pInfo));
410
gck_mock_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
412
g_return_val_if_fail (list, CKR_ARGUMENTS_BAD);
413
*list = &functionList;
420
* TWO: token not present
424
gck_mock_C_GetSlotList (CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
428
g_return_val_if_fail (pulCount, CKR_ARGUMENTS_BAD);
430
count = tokenPresent ? 1 : 2;
432
/* Application only wants to know the number of slots. */
433
if (pSlotList == NULL) {
438
if (*pulCount < count)
439
g_return_val_if_reached (CKR_BUFFER_TOO_SMALL);
442
pSlotList[0] = GCK_MOCK_SLOT_ONE_ID;
444
pSlotList[1] = GCK_MOCK_SLOT_TWO_ID;
449
/* Update gck-mock.h URIs when updating this */
451
static const CK_SLOT_INFO TEST_INFO_ONE = {
453
"TEST MANUFACTURER ",
454
CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE,
459
/* Update gck-mock.h URIs when updating this */
461
static const CK_SLOT_INFO TEST_INFO_TWO = {
463
"TEST MANUFACTURER ",
464
CKF_REMOVABLE_DEVICE,
470
gck_mock_C_GetSlotInfo (CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
472
g_return_val_if_fail (pInfo, CKR_ARGUMENTS_BAD);
474
if (slotID == GCK_MOCK_SLOT_ONE_ID) {
475
memcpy (pInfo, &TEST_INFO_ONE, sizeof (*pInfo));
477
} else if (slotID == GCK_MOCK_SLOT_TWO_ID) {
478
memcpy (pInfo, &TEST_INFO_TWO, sizeof (*pInfo));
481
g_return_val_if_reached (CKR_SLOT_ID_INVALID);
485
/* Update gck-mock.h URIs when updating this */
487
static const CK_TOKEN_INFO TEST_TOKEN_ONE = {
489
"TEST MANUFACTURER ",
492
CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_CLOCK_ON_TOKEN | CKF_TOKEN_INITIALIZED,
505
{ '1', '9', '9', '9', '0', '5', '2', '5', '0', '9', '1', '9', '5', '9', '0', '0' }
509
gck_mock_C_GetTokenInfo (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
511
g_return_val_if_fail (pInfo != NULL, CKR_ARGUMENTS_BAD);
513
if (slotID == GCK_MOCK_SLOT_ONE_ID) {
514
memcpy (pInfo, &TEST_TOKEN_ONE, sizeof (*pInfo));
516
} else if (slotID == GCK_MOCK_SLOT_TWO_ID) {
517
return CKR_TOKEN_NOT_PRESENT;
519
g_return_val_if_reached (CKR_SLOT_ID_INVALID);
524
gck_mock_fail_C_GetTokenInfo (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
526
return CKR_GENERAL_ERROR;
531
* CKM_MOCK_CAPITALIZE
536
gck_mock_C_GetMechanismList (CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
537
CK_ULONG_PTR pulCount)
539
g_return_val_if_fail (slotID == GCK_MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
540
g_return_val_if_fail (pulCount, CKR_ARGUMENTS_BAD);
542
/* Application only wants to know the number of slots. */
543
if (pMechanismList == NULL) {
549
g_return_val_if_reached (CKR_BUFFER_TOO_SMALL);
551
pMechanismList[0] = CKM_MOCK_CAPITALIZE;
552
pMechanismList[1] = CKM_MOCK_PREFIX;
556
static const CK_MECHANISM_INFO TEST_MECH_CAPITALIZE = {
560
static const CK_MECHANISM_INFO TEST_MECH_PREFIX = {
565
gck_mock_C_GetMechanismInfo (CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
566
CK_MECHANISM_INFO_PTR pInfo)
568
g_return_val_if_fail (slotID == GCK_MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
569
g_return_val_if_fail (pInfo, CKR_ARGUMENTS_BAD);
571
if (type == CKM_MOCK_CAPITALIZE) {
572
memcpy (pInfo, &TEST_MECH_CAPITALIZE, sizeof (*pInfo));
574
} else if (type == CKM_MOCK_PREFIX) {
575
memcpy (pInfo, &TEST_MECH_PREFIX, sizeof (*pInfo));
578
g_return_val_if_reached (CKR_MECHANISM_INVALID);
583
gck_mock_specific_args_C_InitToken (CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen,
584
CK_UTF8CHAR_PTR pLabel)
586
g_return_val_if_fail (slotID == GCK_MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
588
g_return_val_if_fail (pPin, CKR_PIN_INVALID);
589
g_return_val_if_fail (strlen ("TEST PIN") == ulPinLen, CKR_PIN_INVALID);
590
g_return_val_if_fail (strncmp ((gchar*)pPin, "TEST PIN", ulPinLen) == 0, CKR_PIN_INVALID);
591
g_return_val_if_fail (pLabel != NULL, CKR_PIN_INVALID);
592
g_return_val_if_fail (strcmp ((gchar*)pPin, "TEST LABEL") == 0, CKR_PIN_INVALID);
595
the_pin = g_strndup ((gchar*)pPin, ulPinLen);
596
n_the_pin = ulPinLen;
601
gck_mock_unsupported_C_WaitForSlotEvent (CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
603
return CKR_FUNCTION_NOT_SUPPORTED;
607
gck_mock_C_OpenSession (CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication,
608
CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession)
612
g_return_val_if_fail (slotID == GCK_MOCK_SLOT_ONE_ID || slotID == GCK_MOCK_SLOT_TWO_ID, CKR_SLOT_ID_INVALID);
613
g_return_val_if_fail (phSession != NULL, CKR_ARGUMENTS_BAD);
614
g_return_val_if_fail ((flags & CKF_SERIAL_SESSION) == CKF_SERIAL_SESSION, CKR_SESSION_PARALLEL_NOT_SUPPORTED);
616
sess = g_new0 (Session, 1);
617
sess->handle = ++unique_identifier;
618
sess->info.flags = flags;
619
sess->info.slotID = slotID;
620
sess->info.state = 0;
621
sess->info.ulDeviceError = 1414;
622
sess->objects = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)gck_attributes_unref);
623
*phSession = sess->handle;
625
g_hash_table_replace (the_sessions, GUINT_TO_POINTER (sess->handle), sess);
630
gck_mock_fail_C_OpenSession (CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication,
631
CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession)
633
return CKR_GENERAL_ERROR;
637
gck_mock_C_CloseSession (CK_SESSION_HANDLE hSession)
641
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
642
g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
644
g_hash_table_remove (the_sessions, GUINT_TO_POINTER (hSession));
649
gck_mock_C_CloseAllSessions (CK_SLOT_ID slotID)
651
g_return_val_if_fail (slotID == GCK_MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
653
g_hash_table_remove_all (the_sessions);
658
gck_mock_C_GetFunctionStatus (CK_SESSION_HANDLE hSession)
660
return CKR_FUNCTION_NOT_PARALLEL;
664
gck_mock_C_CancelFunction (CK_SESSION_HANDLE hSession)
666
return CKR_FUNCTION_NOT_PARALLEL;
670
gck_mock_C_GetSessionInfo (CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
674
g_return_val_if_fail (pInfo != NULL, CKR_ARGUMENTS_BAD);
676
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
677
g_assert (session != NULL && "No such session found");
679
return CKR_SESSION_HANDLE_INVALID;
682
if (session->info.flags & CKF_RW_SESSION)
683
session->info.state = CKS_RW_USER_FUNCTIONS;
685
session->info.state = CKS_RO_USER_FUNCTIONS;
687
if (session->info.flags & CKF_RW_SESSION)
688
session->info.state = CKS_RW_PUBLIC_SESSION;
690
session->info.state = CKS_RO_PUBLIC_SESSION;
693
memcpy (pInfo, &session->info, sizeof (*pInfo));
698
gck_mock_fail_C_GetSessionInfo (CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
700
return CKR_GENERAL_ERROR;
704
gck_mock_C_InitPIN (CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin,
709
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
710
g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
713
the_pin = g_strndup ((gchar*)pPin, ulPinLen);
714
n_the_pin = ulPinLen;
719
gck_mock_C_SetPIN (CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
720
CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen)
725
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
726
g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
728
old = g_strndup ((gchar*)pOldPin, ulOldLen);
729
if (!old || !g_str_equal (old, the_pin))
730
return CKR_PIN_INCORRECT;
733
the_pin = g_strndup ((gchar*)pNewPin, ulNewLen);
734
n_the_pin = ulNewLen;
739
gck_mock_unsupported_C_GetOperationState (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState,
740
CK_ULONG_PTR pulOperationStateLen)
742
return CKR_FUNCTION_NOT_SUPPORTED;
746
gck_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)
750
return CKR_FUNCTION_NOT_SUPPORTED;
754
gck_mock_C_Login (CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
755
CK_UTF8CHAR_PTR pPin, CK_ULONG pPinLen)
759
g_return_val_if_fail (userType == CKU_SO ||
760
userType == CKU_USER ||
761
userType == CKU_CONTEXT_SPECIFIC,
762
CKR_USER_TYPE_INVALID);
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);
769
return CKR_PIN_INCORRECT;
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;
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;
781
user_type = userType;
788
gck_mock_C_Logout (CK_SESSION_HANDLE hSession)
792
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
793
g_assert (session != NULL && "No such session found");
795
return CKR_SESSION_HANDLE_INVALID;
797
g_assert (logged_in && "Not logged in");
804
gck_mock_C_CreateObject (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
805
CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject)
807
GckAttributes *attrs;
809
gboolean token, priv;
810
CK_OBJECT_CLASS klass;
811
CK_OBJECT_HANDLE object;
815
g_return_val_if_fail (phObject, CKR_ARGUMENTS_BAD);
817
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
818
g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
820
attrs = gck_attributes_new ();
821
for (i = 0; i < ulCount; ++i)
822
gck_attributes_add_data (attrs, pTemplate[i].type, pTemplate[i].pValue, pTemplate[i].ulValueLen);
824
if (gck_attributes_find_boolean (attrs, CKA_PRIVATE, &priv) && priv) {
826
gck_attributes_unref (attrs);
827
return CKR_USER_NOT_LOGGED_IN;
831
/* In order to create a credential we must check CK_VALUE */
832
if (gck_attributes_find_ulong (attrs, CKA_CLASS, &klass) && klass == CKO_G_CREDENTIAL) {
833
if (gck_attributes_find_ulong (attrs, CKA_G_OBJECT, &object)) {
834
attr = gck_attributes_find (attrs, CKA_VALUE);
835
if (!attr || attr->length != n_the_pin ||
836
memcmp (attr->value, the_pin, attr->length) != 0) {
837
gck_attributes_unref (attrs);
838
return CKR_PIN_INCORRECT;
843
*phObject = ++unique_identifier;
844
if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
845
g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phObject), attrs);
847
g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phObject), attrs);
853
gck_mock_fail_C_CreateObject (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
854
CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject)
857
return CKR_FUNCTION_FAILED;
861
gck_mock_unsupported_C_CopyObject (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
862
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
863
CK_OBJECT_HANDLE_PTR phNewObject)
865
return CKR_FUNCTION_NOT_SUPPORTED;
869
gck_mock_C_DestroyObject (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
871
GckAttributes *attrs;
875
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
876
g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
878
attrs = lookup_object (session, hObject);
879
g_return_val_if_fail (attrs, CKR_OBJECT_HANDLE_INVALID);
881
if (gck_attributes_find_boolean (attrs, CKA_PRIVATE, &priv) && priv) {
883
return CKR_USER_NOT_LOGGED_IN;
886
g_hash_table_remove (the_objects, GUINT_TO_POINTER (hObject));
887
g_hash_table_remove (session->objects, GUINT_TO_POINTER (hObject));
893
gck_mock_unsupported_C_GetObjectSize (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
894
CK_ULONG_PTR pulSize)
896
return CKR_FUNCTION_NOT_SUPPORTED;
900
gck_mock_C_GetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
901
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
903
CK_ATTRIBUTE_PTR result;
905
GckAttributes *attrs;
910
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
911
g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
913
attrs = lookup_object (session, hObject);
915
g_assert_not_reached (); /* "invalid object handle passed" */
916
return CKR_OBJECT_HANDLE_INVALID;
919
for (i = 0; i < ulCount; ++i) {
920
result = pTemplate + i;
921
attr = gck_attributes_find (attrs, result->type);
923
result->ulValueLen = (CK_ULONG)-1;
924
ret = CKR_ATTRIBUTE_TYPE_INVALID;
928
if (!result->pValue) {
929
result->ulValueLen = attr->length;
933
if (result->ulValueLen >= attr->length) {
934
memcpy (result->pValue, attr->value, attr->length);
938
result->ulValueLen = (CK_ULONG)-1;
939
ret = CKR_BUFFER_TOO_SMALL;
946
gck_mock_fail_C_GetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
947
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
949
return CKR_FUNCTION_FAILED;
953
gck_mock_C_SetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
954
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
957
GckAttributes *attrs;
958
CK_ATTRIBUTE_PTR set;
962
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
963
g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
965
attrs = lookup_object (session, hObject);
966
g_return_val_if_fail (attrs, CKR_OBJECT_HANDLE_INVALID);
968
for (i = 0; i < ulCount; ++i) {
970
attr = gck_attributes_find (attrs, set->type);
972
gck_attributes_add_data (attrs, set->type, set->pValue, set->ulValueLen);
974
gck_attribute_clear (attr);
975
gck_attribute_init (attr, set->type, set->pValue, set->ulValueLen);
982
typedef struct _FindObjects {
983
CK_ATTRIBUTE_PTR template;
989
enumerate_and_find_objects (CK_OBJECT_HANDLE object, GckAttributes *attrs, gpointer user_data)
991
FindObjects *ctx = user_data;
992
CK_ATTRIBUTE_PTR match;
996
for (i = 0; i < ctx->count; ++i) {
997
match = ctx->template + i;
998
attr = gck_attributes_find (attrs, match->type);
1000
return TRUE; /* Continue */
1002
if (attr->length != match->ulValueLen ||
1003
memcmp (attr->value, match->pValue, attr->length) != 0)
1004
return TRUE; /* Continue */
1007
ctx->session->matches = g_list_prepend (ctx->session->matches, GUINT_TO_POINTER (object));
1008
return TRUE; /* Continue */
1012
gck_mock_C_FindObjectsInit (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
1018
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1019
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1021
/* Starting an operation, cancels any previous one */
1022
if (session->operation != 0)
1023
session->operation = 0;
1025
session->operation = OP_FIND;
1027
ctx.template = pTemplate;
1028
ctx.count = ulCount;
1029
ctx.session = session;
1031
gck_mock_module_enumerate_objects (hSession, enumerate_and_find_objects, &ctx);
1036
gck_mock_fail_C_FindObjects (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject,
1037
CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
1040
return CKR_FUNCTION_FAILED;
1044
gck_mock_C_FindObjects (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject,
1045
CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
1049
g_return_val_if_fail (phObject, CKR_ARGUMENTS_BAD);
1050
g_return_val_if_fail (pulObjectCount, CKR_ARGUMENTS_BAD);
1051
g_return_val_if_fail (ulMaxObjectCount != 0, CKR_ARGUMENTS_BAD);
1053
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1054
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1055
g_return_val_if_fail (session->operation == OP_FIND, CKR_OPERATION_NOT_INITIALIZED);
1057
*pulObjectCount = 0;
1058
while (ulMaxObjectCount > 0 && session->matches) {
1059
*phObject = GPOINTER_TO_UINT (session->matches->data);
1062
++(*pulObjectCount);
1063
session->matches = g_list_remove (session->matches, session->matches->data);
1070
gck_mock_C_FindObjectsFinal (CK_SESSION_HANDLE hSession)
1075
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1076
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1077
g_return_val_if_fail (session->operation == OP_FIND, CKR_OPERATION_NOT_INITIALIZED);
1079
session->operation = 0;
1080
g_list_free (session->matches);
1081
session->matches = NULL;
1087
gck_mock_C_EncryptInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1088
CK_OBJECT_HANDLE hKey)
1092
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1093
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1095
/* Starting an operation, cancels any previous one */
1096
if (session->operation != 0)
1097
session->operation = 0;
1099
g_assert (pMechanism);
1100
g_assert (pMechanism->mechanism == CKM_MOCK_CAPITALIZE);
1101
g_assert (hKey == PUBLIC_KEY_CAPITALIZE);
1103
session->operation = OP_CRYPTO;
1104
session->crypto_method = CKA_ENCRYPT;
1105
session->crypto_mechanism = CKM_MOCK_CAPITALIZE;
1106
session->crypto_key = hKey;
1111
gck_mock_C_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
1112
CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
1117
g_return_val_if_fail (pData, CKR_DATA_INVALID);
1118
g_return_val_if_fail (pulEncryptedDataLen, CKR_ARGUMENTS_BAD);
1120
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1121
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1122
g_return_val_if_fail (session->operation == OP_CRYPTO, CKR_OPERATION_NOT_INITIALIZED);
1123
g_return_val_if_fail (session->crypto_method == CKA_ENCRYPT, CKR_OPERATION_NOT_INITIALIZED);
1125
g_assert (session->crypto_mechanism == CKM_MOCK_CAPITALIZE);
1126
g_assert (session->crypto_key == PUBLIC_KEY_CAPITALIZE);
1128
if (!pEncryptedData) {
1129
*pulEncryptedDataLen = ulDataLen;
1133
if (*pulEncryptedDataLen < ulDataLen) {
1134
*pulEncryptedDataLen = ulDataLen;
1135
return CKR_BUFFER_TOO_SMALL;
1138
for (i = 0; i < ulDataLen; ++i)
1139
pEncryptedData[i] = g_ascii_toupper (pData[i]);
1140
*pulEncryptedDataLen = ulDataLen;
1142
session->operation = 0;
1143
session->crypto_method = 0;
1144
session->crypto_mechanism = 0;
1145
session->crypto_key = 0;
1151
gck_mock_unsupported_C_EncryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
1152
CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
1153
CK_ULONG_PTR pulEncryptedPartLen)
1155
return CKR_FUNCTION_NOT_SUPPORTED;
1159
gck_mock_unsupported_C_EncryptFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart,
1160
CK_ULONG_PTR pulLastEncryptedPartLen)
1162
return CKR_FUNCTION_NOT_SUPPORTED;
1166
gck_mock_C_DecryptInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1167
CK_OBJECT_HANDLE hKey)
1171
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1172
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1174
/* Starting an operation, cancels any previous one */
1175
if (session->operation != 0)
1176
session->operation = 0;
1178
g_assert (pMechanism);
1179
g_assert (pMechanism->mechanism == CKM_MOCK_CAPITALIZE);
1180
g_assert (hKey == PRIVATE_KEY_CAPITALIZE);
1182
session->operation = OP_CRYPTO;
1183
session->crypto_method = CKA_DECRYPT;
1184
session->crypto_mechanism = CKM_MOCK_CAPITALIZE;
1185
session->crypto_key = hKey;
1190
gck_mock_C_Decrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData,
1191
CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
1196
g_return_val_if_fail (pEncryptedData, CKR_ENCRYPTED_DATA_INVALID);
1197
g_return_val_if_fail (pulDataLen, CKR_ARGUMENTS_BAD);
1199
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1200
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1201
g_return_val_if_fail (session->operation == OP_CRYPTO, CKR_OPERATION_NOT_INITIALIZED);
1202
g_return_val_if_fail (session->crypto_method == CKA_DECRYPT, CKR_OPERATION_NOT_INITIALIZED);
1204
g_assert (session->crypto_method == CKA_DECRYPT);
1205
g_assert (session->crypto_mechanism == CKM_MOCK_CAPITALIZE);
1206
g_assert (session->crypto_key == PRIVATE_KEY_CAPITALIZE);
1209
*pulDataLen = ulEncryptedDataLen;
1213
if (*pulDataLen < ulEncryptedDataLen) {
1214
*pulDataLen = ulEncryptedDataLen;
1215
return CKR_BUFFER_TOO_SMALL;
1218
for (i = 0; i < ulEncryptedDataLen; ++i)
1219
pData[i] = g_ascii_tolower (pEncryptedData[i]);
1220
*pulDataLen = ulEncryptedDataLen;
1222
session->operation = 0;
1223
session->crypto_method = 0;
1224
session->crypto_mechanism = 0;
1225
session->crypto_key = 0;
1231
gck_mock_unsupported_C_DecryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart,
1232
CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
1234
return CKR_FUNCTION_NOT_SUPPORTED;
1238
gck_mock_unsupported_C_DecryptFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart,
1239
CK_ULONG_PTR pulLastPartLen)
1241
return CKR_FUNCTION_NOT_SUPPORTED;
1245
gck_mock_unsupported_C_DigestInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism)
1247
return CKR_FUNCTION_NOT_SUPPORTED;
1251
gck_mock_unsupported_C_Digest (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
1252
CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
1254
return CKR_FUNCTION_NOT_SUPPORTED;
1258
gck_mock_unsupported_C_DigestUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
1260
return CKR_FUNCTION_NOT_SUPPORTED;
1264
gck_mock_unsupported_C_DigestKey (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
1266
return CKR_FUNCTION_NOT_SUPPORTED;
1270
gck_mock_unsupported_C_DigestFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest,
1271
CK_ULONG_PTR pulDigestLen)
1273
return CKR_FUNCTION_NOT_SUPPORTED;
1277
gck_mock_C_SignInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1278
CK_OBJECT_HANDLE hKey)
1282
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1283
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1285
/* Starting an operation, cancels any previous one */
1286
if (session->operation != 0)
1287
session->operation = 0;
1289
g_assert (pMechanism);
1290
g_assert (pMechanism->mechanism == CKM_MOCK_PREFIX);
1291
g_assert (hKey == PRIVATE_KEY_PREFIX);
1293
session->operation = OP_CRYPTO;
1294
session->crypto_method = CKA_SIGN;
1295
session->crypto_mechanism = CKM_MOCK_PREFIX;
1296
session->crypto_key = hKey;
1298
if (pMechanism->pParameter) {
1299
g_assert (pMechanism->ulParameterLen < sizeof (session->sign_prefix));
1300
memcpy (session->sign_prefix, pMechanism->pParameter, pMechanism->ulParameterLen);
1301
session->n_sign_prefix = pMechanism->ulParameterLen;
1303
g_assert (strlen (SIGNED_PREFIX) + 1 < sizeof (session->sign_prefix));
1304
strcpy ((gchar*)session->sign_prefix, SIGNED_PREFIX);
1305
session->n_sign_prefix = strlen (SIGNED_PREFIX);
1308
/* The private key has CKA_ALWAYS_AUTHENTICATE above */
1309
session->want_context_login = CK_TRUE;
1315
gck_mock_C_Sign (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
1316
CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
1321
g_return_val_if_fail (pData, CKR_DATA_INVALID);
1322
g_return_val_if_fail (pulSignatureLen, CKR_ARGUMENTS_BAD);
1324
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1325
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1326
g_return_val_if_fail (session->operation == OP_CRYPTO, CKR_OPERATION_NOT_INITIALIZED);
1327
g_return_val_if_fail (session->crypto_method == CKA_SIGN, CKR_OPERATION_NOT_INITIALIZED);
1329
if (session->want_context_login)
1330
return CKR_USER_NOT_LOGGED_IN;
1332
g_assert (session->crypto_method == CKA_SIGN);
1333
g_assert (session->crypto_mechanism == CKM_MOCK_PREFIX);
1334
g_assert (session->crypto_key == PRIVATE_KEY_PREFIX);
1336
length = session->n_sign_prefix + ulDataLen;
1339
*pulSignatureLen = length;
1343
if (*pulSignatureLen < length) {
1344
*pulSignatureLen = length;
1345
return CKR_BUFFER_TOO_SMALL;
1348
memcpy (pSignature, session->sign_prefix, session->n_sign_prefix);
1349
memcpy (pSignature + session->n_sign_prefix, pData, ulDataLen);
1350
*pulSignatureLen = length;
1352
session->operation = 0;
1353
session->crypto_method = 0;
1354
session->crypto_mechanism = 0;
1355
session->crypto_key = 0;
1361
gck_mock_unsupported_C_SignUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
1363
return CKR_FUNCTION_NOT_SUPPORTED;
1367
gck_mock_unsupported_C_SignFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
1368
CK_ULONG_PTR pulSignatureLen)
1370
return CKR_FUNCTION_NOT_SUPPORTED;
1374
gck_mock_unsupported_C_SignRecoverInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1375
CK_OBJECT_HANDLE hKey)
1377
return CKR_FUNCTION_NOT_SUPPORTED;
1381
gck_mock_unsupported_C_SignRecover (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
1382
CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
1384
return CKR_FUNCTION_NOT_SUPPORTED;
1388
gck_mock_C_VerifyInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1389
CK_OBJECT_HANDLE hKey)
1393
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1394
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1396
/* Starting an operation, cancels any previous one */
1397
if (session->operation != 0)
1398
session->operation = 0;
1400
g_assert (pMechanism);
1401
g_assert (pMechanism->mechanism == CKM_MOCK_PREFIX);
1402
g_assert (hKey == PUBLIC_KEY_PREFIX);
1404
session->operation = OP_CRYPTO;
1405
session->crypto_method = CKA_VERIFY;
1406
session->crypto_mechanism = CKM_MOCK_PREFIX;
1407
session->crypto_key = hKey;
1409
if (pMechanism->pParameter) {
1410
g_assert (pMechanism->ulParameterLen < sizeof (session->sign_prefix));
1411
memcpy (session->sign_prefix, pMechanism->pParameter, pMechanism->ulParameterLen);
1412
session->n_sign_prefix = pMechanism->ulParameterLen;
1414
g_assert (strlen (SIGNED_PREFIX) + 1 < sizeof (session->sign_prefix));
1415
strcpy ((gchar*)session->sign_prefix, SIGNED_PREFIX);
1416
session->n_sign_prefix = strlen (SIGNED_PREFIX);
1423
gck_mock_C_Verify (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
1424
CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
1429
g_return_val_if_fail (pData, CKR_DATA_INVALID);
1430
g_return_val_if_fail (pSignature, CKR_ARGUMENTS_BAD);
1432
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1433
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1434
g_return_val_if_fail (session->operation == OP_CRYPTO, CKR_OPERATION_NOT_INITIALIZED);
1435
g_return_val_if_fail (session->crypto_method == CKA_VERIFY, CKR_OPERATION_NOT_INITIALIZED);
1437
g_assert (session->crypto_method == CKA_VERIFY);
1438
g_assert (session->crypto_mechanism == CKM_MOCK_PREFIX);
1439
g_assert (session->crypto_key == PUBLIC_KEY_PREFIX);
1441
length = session->n_sign_prefix + ulDataLen;
1443
if (ulSignatureLen < length) {
1445
return CKR_SIGNATURE_LEN_RANGE;
1448
if (memcmp (pSignature, session->sign_prefix, session->n_sign_prefix) == 0 &&
1449
memcmp (pSignature + session->n_sign_prefix, pData, ulDataLen) == 0)
1452
return CKR_SIGNATURE_INVALID;
1456
gck_mock_unsupported_C_VerifyUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
1458
return CKR_FUNCTION_NOT_SUPPORTED;
1462
gck_mock_unsupported_C_VerifyFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
1463
CK_ULONG pulSignatureLen)
1465
return CKR_FUNCTION_NOT_SUPPORTED;
1469
gck_mock_unsupported_C_VerifyRecoverInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1470
CK_OBJECT_HANDLE hKey)
1472
return CKR_FUNCTION_NOT_SUPPORTED;
1476
gck_mock_unsupported_C_VerifyRecover (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
1477
CK_ULONG pulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
1479
return CKR_FUNCTION_NOT_SUPPORTED;
1483
gck_mock_unsupported_C_DigestEncryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
1484
CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
1485
CK_ULONG_PTR ulEncryptedPartLen)
1487
return CKR_FUNCTION_NOT_SUPPORTED;
1491
gck_mock_unsupported_C_DecryptDigestUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart,
1492
CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
1493
CK_ULONG_PTR pulPartLen)
1495
return CKR_FUNCTION_NOT_SUPPORTED;
1499
gck_mock_unsupported_C_SignEncryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
1500
CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
1501
CK_ULONG_PTR ulEncryptedPartLen)
1503
return CKR_FUNCTION_NOT_SUPPORTED;
1507
gck_mock_unsupported_C_DecryptVerifyUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart,
1508
CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
1509
CK_ULONG_PTR pulPartLen)
1511
return CKR_FUNCTION_NOT_SUPPORTED;
1515
gck_mock_unsupported_C_GenerateKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1516
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
1517
CK_OBJECT_HANDLE_PTR phKey)
1519
return CKR_FUNCTION_NOT_SUPPORTED;
1523
gck_mock_unsupported_C_GenerateKeyPair (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1524
CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount,
1525
CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount,
1526
CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)
1528
GckAttributes *attrs;
1533
g_return_val_if_fail (pMechanism, CKR_MECHANISM_INVALID);
1534
g_return_val_if_fail (pPublicKeyTemplate, CKR_TEMPLATE_INCOMPLETE);
1535
g_return_val_if_fail (ulPublicKeyAttributeCount, CKR_TEMPLATE_INCOMPLETE);
1536
g_return_val_if_fail (pPrivateKeyTemplate, CKR_TEMPLATE_INCOMPLETE);
1537
g_return_val_if_fail (ulPrivateKeyAttributeCount, CKR_TEMPLATE_INCOMPLETE);
1538
g_return_val_if_fail (phPublicKey, CKR_ARGUMENTS_BAD);
1539
g_return_val_if_fail (phPrivateKey, CKR_ARGUMENTS_BAD);
1541
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1542
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1544
if (pMechanism->mechanism != CKM_MOCK_GENERATE)
1545
return CKR_MECHANISM_INVALID;
1547
if (!pMechanism->pParameter || pMechanism->ulParameterLen != 9 ||
1548
memcmp (pMechanism->pParameter, "generate", 9) != 0)
1549
g_return_val_if_reached (CKR_MECHANISM_PARAM_INVALID);
1551
attrs = gck_attributes_new ();
1552
gck_attributes_add_string (attrs, CKA_VALUE, "generated");
1553
for (i = 0; i < ulPublicKeyAttributeCount; ++i)
1554
gck_attributes_add_data (attrs, pPublicKeyTemplate[i].type,
1555
pPublicKeyTemplate[i].pValue,
1556
pPublicKeyTemplate[i].ulValueLen);
1557
*phPublicKey = ++unique_identifier;
1558
if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
1559
g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phPublicKey), attrs);
1561
g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phPublicKey), attrs);
1563
attrs = gck_attributes_new ();
1564
gck_attributes_add_string (attrs, CKA_VALUE, "generated");
1565
for (i = 0; i < ulPrivateKeyAttributeCount; ++i)
1566
gck_attributes_add_data (attrs, pPrivateKeyTemplate[i].type,
1567
pPrivateKeyTemplate[i].pValue,
1568
pPrivateKeyTemplate[i].ulValueLen);
1569
*phPrivateKey = ++unique_identifier;
1570
if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
1571
g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phPrivateKey), attrs);
1573
g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phPrivateKey), attrs);
1578
gck_mock_unsupported_C_WrapKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1579
CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey,
1580
CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
1582
GckAttributes *attrs;
1586
g_return_val_if_fail (pMechanism, CKR_MECHANISM_INVALID);
1587
g_return_val_if_fail (hWrappingKey, CKR_OBJECT_HANDLE_INVALID);
1588
g_return_val_if_fail (hKey, CKR_OBJECT_HANDLE_INVALID);
1589
g_return_val_if_fail (pulWrappedKeyLen, CKR_WRAPPED_KEY_LEN_RANGE);
1591
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1592
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1594
attrs = lookup_object (session, hWrappingKey);
1595
g_return_val_if_fail (attrs, CKR_WRAPPING_KEY_HANDLE_INVALID);
1597
attrs = lookup_object (session, hKey);
1598
g_return_val_if_fail (attrs, CKR_WRAPPED_KEY_INVALID);
1600
if (pMechanism->mechanism != CKM_MOCK_WRAP)
1601
return CKR_MECHANISM_INVALID;
1603
if (pMechanism->pParameter) {
1604
if (pMechanism->ulParameterLen != 4 ||
1605
memcmp (pMechanism->pParameter, "wrap", 4) != 0)
1606
g_return_val_if_reached (CKR_MECHANISM_PARAM_INVALID);
1609
attr = gck_attributes_find (attrs, CKA_VALUE);
1611
return CKR_WRAPPED_KEY_INVALID;
1614
*pulWrappedKeyLen = attr->length;
1618
if (*pulWrappedKeyLen < attr->length) {
1619
*pulWrappedKeyLen = attr->length;
1620
return CKR_BUFFER_TOO_SMALL;
1623
memcpy (pWrappedKey, attr->value, attr->length);
1624
*pulWrappedKeyLen = attr->length;
1630
gck_mock_unsupported_C_UnwrapKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1631
CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey,
1632
CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate,
1633
CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
1635
GckAttributes *attrs;
1640
g_return_val_if_fail (pMechanism, CKR_MECHANISM_INVALID);
1641
g_return_val_if_fail (hUnwrappingKey, CKR_WRAPPING_KEY_HANDLE_INVALID);
1642
g_return_val_if_fail (pWrappedKey, CKR_WRAPPED_KEY_INVALID);
1643
g_return_val_if_fail (ulWrappedKeyLen, CKR_WRAPPED_KEY_LEN_RANGE);
1644
g_return_val_if_fail (phKey, CKR_ARGUMENTS_BAD);
1645
g_return_val_if_fail (pTemplate, CKR_TEMPLATE_INCOMPLETE);
1646
g_return_val_if_fail (ulCount, CKR_TEMPLATE_INCONSISTENT);
1648
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1649
g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1651
attrs = lookup_object (session, hUnwrappingKey);
1652
g_return_val_if_fail (attrs, CKR_WRAPPING_KEY_HANDLE_INVALID);
1654
if (pMechanism->mechanism != CKM_MOCK_WRAP)
1655
return CKR_MECHANISM_INVALID;
1657
if (pMechanism->pParameter) {
1658
if (pMechanism->ulParameterLen != 4 ||
1659
memcmp (pMechanism->pParameter, "wrap", 4) != 0)
1660
g_return_val_if_reached (CKR_MECHANISM_PARAM_INVALID);
1663
attrs = gck_attributes_new ();
1664
gck_attributes_add_data (attrs, CKA_VALUE, pWrappedKey, ulWrappedKeyLen);
1665
for (i = 0; i < ulCount; ++i)
1666
gck_attributes_add_data (attrs, pTemplate[i].type,
1667
pTemplate[i].pValue,
1668
pTemplate[i].ulValueLen);
1669
*phKey = ++unique_identifier;
1670
if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
1671
g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phKey), attrs);
1673
g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phKey), attrs);
1679
gck_mock_unsupported_C_DeriveKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1680
CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
1681
CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
1683
GckAttributes *attrs, *copy;
1688
g_return_val_if_fail (pMechanism, CKR_MECHANISM_INVALID);
1689
g_return_val_if_fail (ulCount, CKR_TEMPLATE_INCOMPLETE);
1690
g_return_val_if_fail (pTemplate, CKR_TEMPLATE_INCOMPLETE);
1691
g_return_val_if_fail (phKey, CKR_ARGUMENTS_BAD);
1693
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1694
g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
1696
attrs = lookup_object (session, hBaseKey);
1697
g_return_val_if_fail (attrs, CKR_KEY_HANDLE_INVALID);
1699
if (pMechanism->mechanism != CKM_MOCK_DERIVE)
1700
return CKR_MECHANISM_INVALID;
1702
if (pMechanism->pParameter) {
1703
if (pMechanism->ulParameterLen != 6 ||
1704
memcmp (pMechanism->pParameter, "derive", 6) != 0)
1705
g_return_val_if_reached (CKR_MECHANISM_PARAM_INVALID);
1708
copy = gck_attributes_new ();
1709
gck_attributes_add_string (copy, CKA_VALUE, "derived");
1710
for (i = 0; i < ulCount; ++i)
1711
gck_attributes_add_data (copy, pTemplate[i].type,
1712
pTemplate[i].pValue,
1713
pTemplate[i].ulValueLen);
1714
for (i = 0; i < gck_attributes_count (attrs); ++i)
1715
gck_attributes_add (copy, gck_attributes_at (attrs, i));
1716
*phKey = ++unique_identifier;
1717
if (gck_attributes_find_boolean (copy, CKA_TOKEN, &token) && token)
1718
g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phKey), copy);
1720
g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phKey), copy);
1726
gck_mock_unsupported_C_SeedRandom (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
1728
return CKR_FUNCTION_NOT_SUPPORTED;
1732
gck_mock_unsupported_C_GenerateRandom (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData,
1733
CK_ULONG ulRandomLen)
1735
return CKR_FUNCTION_NOT_SUPPORTED;
1738
static CK_FUNCTION_LIST functionList = {
1739
{ 2, 11 }, /* version */
1740
gck_mock_validate_and_C_Initialize,
1741
gck_mock_C_Finalize,
1743
gck_mock_C_GetFunctionList,
1744
gck_mock_C_GetSlotList,
1745
gck_mock_C_GetSlotInfo,
1746
gck_mock_C_GetTokenInfo,
1747
gck_mock_C_GetMechanismList,
1748
gck_mock_C_GetMechanismInfo,
1749
gck_mock_specific_args_C_InitToken,
1752
gck_mock_C_OpenSession,
1753
gck_mock_C_CloseSession,
1754
gck_mock_C_CloseAllSessions,
1755
gck_mock_C_GetSessionInfo,
1756
gck_mock_unsupported_C_GetOperationState,
1757
gck_mock_unsupported_C_SetOperationState,
1760
gck_mock_C_CreateObject,
1761
gck_mock_unsupported_C_CopyObject,
1762
gck_mock_C_DestroyObject,
1763
gck_mock_unsupported_C_GetObjectSize,
1764
gck_mock_C_GetAttributeValue,
1765
gck_mock_C_SetAttributeValue,
1766
gck_mock_C_FindObjectsInit,
1767
gck_mock_C_FindObjects,
1768
gck_mock_C_FindObjectsFinal,
1769
gck_mock_C_EncryptInit,
1771
gck_mock_unsupported_C_EncryptUpdate,
1772
gck_mock_unsupported_C_EncryptFinal,
1773
gck_mock_C_DecryptInit,
1775
gck_mock_unsupported_C_DecryptUpdate,
1776
gck_mock_unsupported_C_DecryptFinal,
1777
gck_mock_unsupported_C_DigestInit,
1778
gck_mock_unsupported_C_Digest,
1779
gck_mock_unsupported_C_DigestUpdate,
1780
gck_mock_unsupported_C_DigestKey,
1781
gck_mock_unsupported_C_DigestFinal,
1782
gck_mock_C_SignInit,
1784
gck_mock_unsupported_C_SignUpdate,
1785
gck_mock_unsupported_C_SignFinal,
1786
gck_mock_unsupported_C_SignRecoverInit,
1787
gck_mock_unsupported_C_SignRecover,
1788
gck_mock_C_VerifyInit,
1790
gck_mock_unsupported_C_VerifyUpdate,
1791
gck_mock_unsupported_C_VerifyFinal,
1792
gck_mock_unsupported_C_VerifyRecoverInit,
1793
gck_mock_unsupported_C_VerifyRecover,
1794
gck_mock_unsupported_C_DigestEncryptUpdate,
1795
gck_mock_unsupported_C_DecryptDigestUpdate,
1796
gck_mock_unsupported_C_SignEncryptUpdate,
1797
gck_mock_unsupported_C_DecryptVerifyUpdate,
1798
gck_mock_unsupported_C_GenerateKey,
1799
gck_mock_unsupported_C_GenerateKeyPair,
1800
gck_mock_unsupported_C_WrapKey,
1801
gck_mock_unsupported_C_UnwrapKey,
1802
gck_mock_unsupported_C_DeriveKey,
1803
gck_mock_unsupported_C_SeedRandom,
1804
gck_mock_unsupported_C_GenerateRandom,
1805
gck_mock_C_GetFunctionStatus,
1806
gck_mock_C_CancelFunction,
1807
gck_mock_unsupported_C_WaitForSlotEvent