~noskcaj/ubuntu/vivid/gnome-keyring/3.15.90

« back to all changes in this revision

Viewing changes to gck/gck-mock.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach
  • Date: 2012-05-14 22:13:02 UTC
  • mfrom: (1.3.1)
  • mto: (80.2.8 experimental) (1.1.77)
  • mto: This revision was merged to the branch mainline in revision 148.
  • Revision ID: package-import@ubuntu.com-20120514221302-0l3gjmqpe6xopond
ImportĀ upstreamĀ versionĀ 3.4.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
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  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  License for more details.
15
 
 *
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
19
 
 * 02111-1307, USA.
20
 
 */
21
 
 
22
 
#include "config.h"
23
 
 
24
 
#include "gck.h"
25
 
#include "gck-mock.h"
26
 
 
27
 
#include "pkcs11/pkcs11.h"
28
 
#include "pkcs11/pkcs11i.h"
29
 
 
30
 
#include <glib.h>
31
 
 
32
 
#include <string.h>
33
 
 
34
 
/*
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.
38
 
 */
39
 
 
40
 
 
41
 
static gboolean initialized = FALSE;
42
 
static gchar *the_pin = NULL;
43
 
static gulong n_the_pin = 0;
44
 
 
45
 
static gboolean logged_in = FALSE;
46
 
static CK_USER_TYPE user_type = 0;
47
 
static CK_FUNCTION_LIST functionList;
48
 
 
49
 
typedef enum _Operation {
50
 
        OP_FIND = 1,
51
 
        OP_CRYPTO
52
 
} Operation;
53
 
 
54
 
typedef struct _Session {
55
 
        CK_SESSION_HANDLE handle;
56
 
        CK_SESSION_INFO info;
57
 
        GHashTable *objects;
58
 
 
59
 
        Operation operation;
60
 
 
61
 
        /* For find operations */
62
 
        GList *matches;
63
 
 
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;
69
 
 
70
 
        /* For 'signing' with CKM_MOCK_PREFIX */
71
 
        CK_BYTE sign_prefix[128];
72
 
        CK_ULONG n_sign_prefix;
73
 
} Session;
74
 
 
75
 
static guint unique_identifier = 100;
76
 
static GHashTable *the_sessions = NULL;
77
 
static GHashTable *the_objects = NULL;
78
 
 
79
 
enum {
80
 
        PRIVATE_KEY_CAPITALIZE = 3,
81
 
        PUBLIC_KEY_CAPITALIZE = 4,
82
 
        PRIVATE_KEY_PREFIX = 5,
83
 
        PUBLIC_KEY_PREFIX = 6
84
 
};
85
 
 
86
 
#define SIGNED_PREFIX "signed-prefix:"
87
 
 
88
 
static void
89
 
free_session (gpointer data)
90
 
{
91
 
        Session *sess = (Session*)data;
92
 
        if (sess)
93
 
                g_hash_table_destroy (sess->objects);
94
 
        g_free (sess);
95
 
}
96
 
 
97
 
static GckAttributes*
98
 
lookup_object (Session *session, CK_OBJECT_HANDLE hObject)
99
 
{
100
 
        GckAttributes *attrs;
101
 
        attrs = g_hash_table_lookup (the_objects, GUINT_TO_POINTER (hObject));
102
 
        if (!attrs)
103
 
                attrs = g_hash_table_lookup (session->objects, GUINT_TO_POINTER (hObject));
104
 
        return attrs;
105
 
}
106
 
 
107
 
CK_OBJECT_HANDLE
108
 
gck_mock_module_take_object (GckAttributes *attrs)
109
 
{
110
 
        gboolean token;
111
 
        guint handle;
112
 
 
113
 
        g_return_val_if_fail (the_objects, 0);
114
 
 
115
 
        handle = ++unique_identifier;
116
 
        if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token))
117
 
                g_return_val_if_fail (token == TRUE, 0);
118
 
        else
119
 
                gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);
120
 
        g_hash_table_insert (the_objects, GUINT_TO_POINTER (handle), attrs);
121
 
        return handle;
122
 
}
123
 
 
124
 
void
125
 
gck_mock_module_enumerate_objects (CK_SESSION_HANDLE handle, GckMockEnumerator func,
126
 
                                   gpointer user_data)
127
 
{
128
 
        GHashTableIter iter;
129
 
        gpointer key;
130
 
        gpointer value;
131
 
        Session *session;
132
 
 
133
 
        g_assert (the_objects);
134
 
        g_assert (func);
135
 
 
136
 
        /* Token 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))
140
 
                        return;
141
 
        }
142
 
 
143
 
        /* session objects */
144
 
        if (handle) {
145
 
                session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (handle));
146
 
                if (session) {
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))
150
 
                                        return;
151
 
                        }
152
 
                }
153
 
        }
154
 
}
155
 
 
156
 
typedef struct _FindObject {
157
 
        CK_ATTRIBUTE_PTR attrs;
158
 
        CK_ULONG n_attrs;
159
 
        CK_OBJECT_HANDLE object;
160
 
} FindObject;
161
 
 
162
 
static gboolean
163
 
enumerate_and_find_object (CK_OBJECT_HANDLE object, GckAttributes *attrs, gpointer user_data)
164
 
{
165
 
        FindObject *ctx = user_data;
166
 
        CK_ATTRIBUTE_PTR match;
167
 
        GckAttribute *attr;
168
 
        CK_ULONG i;
169
 
 
170
 
        for (i = 0; i < ctx->n_attrs; ++i) {
171
 
                match = ctx->attrs + i;
172
 
                attr = gck_attributes_find (attrs, match->type);
173
 
                if (!attr)
174
 
                        return TRUE; /* Continue */
175
 
 
176
 
                if (attr->length != match->ulValueLen ||
177
 
                    memcmp (attr->value, match->pValue, attr->length) != 0)
178
 
                        return TRUE; /* Continue */
179
 
        }
180
 
 
181
 
        ctx->object = object;
182
 
        return FALSE; /* Stop iteration */
183
 
}
184
 
 
185
 
CK_OBJECT_HANDLE
186
 
gck_mock_module_find_object (CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
187
 
{
188
 
        FindObject ctx;
189
 
 
190
 
        ctx.attrs = attrs;
191
 
        ctx.n_attrs = n_attrs;
192
 
        ctx.object = 0;
193
 
 
194
 
        gck_mock_module_enumerate_objects (session, enumerate_and_find_object, &ctx);
195
 
 
196
 
        return ctx.object;
197
 
}
198
 
 
199
 
static gboolean
200
 
enumerate_and_count_objects (CK_OBJECT_HANDLE object, GckAttributes *attrs, gpointer user_data)
201
 
{
202
 
        guint *n_objects = user_data;
203
 
        ++(*n_objects);
204
 
        return TRUE; /* Continue */
205
 
}
206
 
 
207
 
guint
208
 
gck_mock_module_count_objects (CK_SESSION_HANDLE session)
209
 
{
210
 
        guint n_objects = 0;
211
 
        gck_mock_module_enumerate_objects (session, enumerate_and_count_objects, &n_objects);
212
 
        return n_objects;
213
 
}
214
 
 
215
 
void
216
 
gck_mock_module_set_object (CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR attrs,
217
 
                            CK_ULONG n_attrs)
218
 
{
219
 
        CK_ULONG i;
220
 
        GckAttributes *atts;
221
 
        GckAttribute *attr;
222
 
        CK_ATTRIBUTE_PTR set;
223
 
 
224
 
        g_return_if_fail (object != 0);
225
 
        g_return_if_fail (the_objects);
226
 
 
227
 
        atts = g_hash_table_lookup (the_objects, GUINT_TO_POINTER (object));
228
 
        g_return_if_fail (atts);
229
 
 
230
 
        for (i = 0; i < n_attrs; ++i) {
231
 
                set = attrs + i;
232
 
                attr = gck_attributes_find (atts, set->type);
233
 
                if (!attr) {
234
 
                        gck_attributes_add_data (atts, set->type, set->pValue, set->ulValueLen);
235
 
                } else {
236
 
                        gck_attribute_clear (attr);
237
 
                        gck_attribute_init (attr, set->type, set->pValue, set->ulValueLen);
238
 
                }
239
 
        }
240
 
}
241
 
 
242
 
void
243
 
gck_mock_module_set_pin (const gchar *password)
244
 
{
245
 
        g_free (the_pin);
246
 
        the_pin = g_strdup (password);
247
 
        n_the_pin = strlen (password);
248
 
}
249
 
 
250
 
CK_RV
251
 
gck_mock_C_Initialize (CK_VOID_PTR pInitArgs)
252
 
{
253
 
        GckAttributes *attrs;
254
 
        CK_ULONG value;
255
 
        CK_C_INITIALIZE_ARGS_PTR args;
256
 
 
257
 
        g_return_val_if_fail (initialized == FALSE, CKR_CRYPTOKI_ALREADY_INITIALIZED);
258
 
 
259
 
        args = (CK_C_INITIALIZE_ARGS_PTR)pInitArgs;
260
 
        if (args) {
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),
266
 
                               CKR_ARGUMENTS_BAD);
267
 
 
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);
271
 
        }
272
 
 
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);
277
 
 
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);
283
 
 
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);
298
 
 
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);
310
 
 
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);
323
 
 
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);
335
 
 
336
 
        initialized = TRUE;
337
 
        return CKR_OK;
338
 
}
339
 
 
340
 
CK_RV
341
 
gck_mock_validate_and_C_Initialize (CK_VOID_PTR pInitArgs)
342
 
{
343
 
        CK_C_INITIALIZE_ARGS_PTR args;
344
 
        void *mutex;
345
 
        CK_RV rv;
346
 
 
347
 
        args = (CK_C_INITIALIZE_ARGS_PTR)pInitArgs;
348
 
        if (args) {
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");
353
 
 
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");
358
 
 
359
 
                /* Try and lock the mutex */
360
 
                rv = (args->LockMutex) (mutex);
361
 
                g_assert (rv == CKR_OK && "LockMutex g_assert_not_reacheded");
362
 
 
363
 
                /* Try and unlock the mutex */
364
 
                rv = (args->UnlockMutex) (mutex);
365
 
                g_assert (rv == CKR_OK && "UnlockMutex g_assert_not_reacheded");
366
 
 
367
 
                /* Try and destroy the mutex */
368
 
                rv = (args->DestroyMutex) (mutex);
369
 
                g_assert (rv == CKR_OK && "DestroyMutex g_assert_not_reacheded");
370
 
        }
371
 
 
372
 
        return gck_mock_C_Initialize (pInitArgs);
373
 
}
374
 
 
375
 
CK_RV
376
 
gck_mock_C_Finalize (CK_VOID_PTR pReserved)
377
 
{
378
 
        g_return_val_if_fail (pReserved == NULL, CKR_ARGUMENTS_BAD);
379
 
        g_return_val_if_fail (initialized == TRUE, CKR_CRYPTOKI_NOT_INITIALIZED);
380
 
 
381
 
        initialized = FALSE;
382
 
        logged_in = FALSE;
383
 
        g_hash_table_destroy (the_objects);
384
 
        the_objects = NULL;
385
 
 
386
 
        g_hash_table_destroy (the_sessions);
387
 
        the_sessions = NULL;
388
 
 
389
 
        g_free (the_pin);
390
 
        return CKR_OK;
391
 
}
392
 
 
393
 
static const CK_INFO TEST_INFO = {
394
 
        { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
395
 
        "TEST MANUFACTURER              ",
396
 
        0,
397
 
        "TEST LIBRARY                   ",
398
 
        { 45, 145 }
399
 
};
400
 
 
401
 
CK_RV
402
 
gck_mock_C_GetInfo (CK_INFO_PTR pInfo)
403
 
{
404
 
        g_return_val_if_fail (pInfo, CKR_ARGUMENTS_BAD);
405
 
        memcpy (pInfo, &TEST_INFO, sizeof (*pInfo));
406
 
        return CKR_OK;
407
 
}
408
 
 
409
 
CK_RV
410
 
gck_mock_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
411
 
{
412
 
        g_return_val_if_fail (list, CKR_ARGUMENTS_BAD);
413
 
        *list = &functionList;
414
 
        return CKR_OK;
415
 
}
416
 
 
417
 
/*
418
 
 * Two slots
419
 
 *  ONE: token present
420
 
 *  TWO: token not present
421
 
 */
422
 
 
423
 
CK_RV
424
 
gck_mock_C_GetSlotList (CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
425
 
{
426
 
        CK_ULONG count;
427
 
 
428
 
        g_return_val_if_fail (pulCount, CKR_ARGUMENTS_BAD);
429
 
 
430
 
        count = tokenPresent ? 1 : 2;
431
 
 
432
 
        /* Application only wants to know the number of slots. */
433
 
        if (pSlotList == NULL) {
434
 
                *pulCount = count;
435
 
                return CKR_OK;
436
 
        }
437
 
 
438
 
        if (*pulCount < count)
439
 
                g_return_val_if_reached (CKR_BUFFER_TOO_SMALL);
440
 
 
441
 
        *pulCount = count;
442
 
        pSlotList[0] = GCK_MOCK_SLOT_ONE_ID;
443
 
        if (!tokenPresent)
444
 
                pSlotList[1] = GCK_MOCK_SLOT_TWO_ID;
445
 
 
446
 
        return CKR_OK;
447
 
}
448
 
 
449
 
/* Update gck-mock.h URIs when updating this */
450
 
 
451
 
static const CK_SLOT_INFO TEST_INFO_ONE = {
452
 
        "TEST SLOT                                                       ",
453
 
        "TEST MANUFACTURER              ",
454
 
        CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE,
455
 
        { 55, 155 },
456
 
        { 65, 165 },
457
 
};
458
 
 
459
 
/* Update gck-mock.h URIs when updating this */
460
 
 
461
 
static const CK_SLOT_INFO TEST_INFO_TWO = {
462
 
        "TEST SLOT                                                       ",
463
 
        "TEST MANUFACTURER              ",
464
 
        CKF_REMOVABLE_DEVICE,
465
 
        { 55, 155 },
466
 
        { 65, 165 },
467
 
};
468
 
 
469
 
CK_RV
470
 
gck_mock_C_GetSlotInfo (CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
471
 
{
472
 
        g_return_val_if_fail (pInfo, CKR_ARGUMENTS_BAD);
473
 
 
474
 
        if (slotID == GCK_MOCK_SLOT_ONE_ID) {
475
 
                memcpy (pInfo, &TEST_INFO_ONE, sizeof (*pInfo));
476
 
                return CKR_OK;
477
 
        } else if (slotID == GCK_MOCK_SLOT_TWO_ID) {
478
 
                memcpy (pInfo, &TEST_INFO_TWO, sizeof (*pInfo));
479
 
                return CKR_OK;
480
 
        } else {
481
 
                g_return_val_if_reached (CKR_SLOT_ID_INVALID);
482
 
        }
483
 
}
484
 
 
485
 
/* Update gck-mock.h URIs when updating this */
486
 
 
487
 
static const CK_TOKEN_INFO TEST_TOKEN_ONE = {
488
 
        "TEST LABEL                      ",
489
 
        "TEST MANUFACTURER               ",
490
 
        "TEST MODEL      ",
491
 
        "TEST SERIAL     ",
492
 
        CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_CLOCK_ON_TOKEN | CKF_TOKEN_INITIALIZED,
493
 
        1,
494
 
        2,
495
 
        3,
496
 
        4,
497
 
        5,
498
 
        6,
499
 
        7,
500
 
        8,
501
 
        9,
502
 
        10,
503
 
        { 75, 175 },
504
 
        { 85, 185 },
505
 
        { '1', '9', '9', '9', '0', '5', '2', '5', '0', '9', '1', '9', '5', '9', '0', '0' }
506
 
};
507
 
 
508
 
CK_RV
509
 
gck_mock_C_GetTokenInfo (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
510
 
{
511
 
        g_return_val_if_fail (pInfo != NULL, CKR_ARGUMENTS_BAD);
512
 
 
513
 
        if (slotID == GCK_MOCK_SLOT_ONE_ID) {
514
 
                memcpy (pInfo, &TEST_TOKEN_ONE, sizeof (*pInfo));
515
 
                return CKR_OK;
516
 
        } else if (slotID == GCK_MOCK_SLOT_TWO_ID) {
517
 
                return CKR_TOKEN_NOT_PRESENT;
518
 
        } else {
519
 
                g_return_val_if_reached (CKR_SLOT_ID_INVALID);
520
 
        }
521
 
}
522
 
 
523
 
CK_RV
524
 
gck_mock_fail_C_GetTokenInfo (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
525
 
{
526
 
        return CKR_GENERAL_ERROR;
527
 
}
528
 
 
529
 
/*
530
 
 * TWO mechanisms:
531
 
 *  CKM_MOCK_CAPITALIZE
532
 
 *  CKM_MOCK_PREFIX
533
 
 */
534
 
 
535
 
CK_RV
536
 
gck_mock_C_GetMechanismList (CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
537
 
                             CK_ULONG_PTR pulCount)
538
 
{
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);
541
 
 
542
 
        /* Application only wants to know the number of slots. */
543
 
        if (pMechanismList == NULL) {
544
 
                *pulCount = 2;
545
 
                return CKR_OK;
546
 
        }
547
 
 
548
 
        if (*pulCount != 2)
549
 
                g_return_val_if_reached (CKR_BUFFER_TOO_SMALL);
550
 
 
551
 
        pMechanismList[0] = CKM_MOCK_CAPITALIZE;
552
 
        pMechanismList[1] = CKM_MOCK_PREFIX;
553
 
        return CKR_OK;
554
 
}
555
 
 
556
 
static const CK_MECHANISM_INFO TEST_MECH_CAPITALIZE = {
557
 
        512, 4096, 0
558
 
};
559
 
 
560
 
static const CK_MECHANISM_INFO TEST_MECH_PREFIX = {
561
 
        2048, 2048, 0
562
 
};
563
 
 
564
 
CK_RV
565
 
gck_mock_C_GetMechanismInfo (CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
566
 
                             CK_MECHANISM_INFO_PTR pInfo)
567
 
{
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);
570
 
 
571
 
        if (type == CKM_MOCK_CAPITALIZE) {
572
 
                memcpy (pInfo, &TEST_MECH_CAPITALIZE, sizeof (*pInfo));
573
 
                return CKR_OK;
574
 
        } else if (type == CKM_MOCK_PREFIX) {
575
 
                memcpy (pInfo, &TEST_MECH_PREFIX, sizeof (*pInfo));
576
 
                return CKR_OK;
577
 
        } else {
578
 
                g_return_val_if_reached (CKR_MECHANISM_INVALID);
579
 
        }
580
 
}
581
 
 
582
 
CK_RV
583
 
gck_mock_specific_args_C_InitToken (CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen,
584
 
                                    CK_UTF8CHAR_PTR pLabel)
585
 
{
586
 
        g_return_val_if_fail (slotID == GCK_MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
587
 
 
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);
593
 
 
594
 
        g_free (the_pin);
595
 
        the_pin = g_strndup ((gchar*)pPin, ulPinLen);
596
 
        n_the_pin = ulPinLen;
597
 
        return CKR_OK;
598
 
}
599
 
 
600
 
CK_RV
601
 
gck_mock_unsupported_C_WaitForSlotEvent (CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
602
 
{
603
 
        return CKR_FUNCTION_NOT_SUPPORTED;
604
 
}
605
 
 
606
 
CK_RV
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)
609
 
{
610
 
        Session *sess;
611
 
 
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);
615
 
 
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;
624
 
 
625
 
        g_hash_table_replace (the_sessions, GUINT_TO_POINTER (sess->handle), sess);
626
 
        return CKR_OK;
627
 
}
628
 
 
629
 
CK_RV
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)
632
 
{
633
 
        return CKR_GENERAL_ERROR;
634
 
}
635
 
 
636
 
CK_RV
637
 
gck_mock_C_CloseSession (CK_SESSION_HANDLE hSession)
638
 
{
639
 
        Session *session;
640
 
 
641
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
642
 
        g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
643
 
 
644
 
        g_hash_table_remove (the_sessions, GUINT_TO_POINTER (hSession));
645
 
        return CKR_OK;
646
 
}
647
 
 
648
 
CK_RV
649
 
gck_mock_C_CloseAllSessions (CK_SLOT_ID slotID)
650
 
{
651
 
        g_return_val_if_fail (slotID == GCK_MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
652
 
 
653
 
        g_hash_table_remove_all (the_sessions);
654
 
        return CKR_OK;
655
 
}
656
 
 
657
 
CK_RV
658
 
gck_mock_C_GetFunctionStatus (CK_SESSION_HANDLE hSession)
659
 
{
660
 
        return CKR_FUNCTION_NOT_PARALLEL;
661
 
}
662
 
 
663
 
CK_RV
664
 
gck_mock_C_CancelFunction (CK_SESSION_HANDLE hSession)
665
 
{
666
 
        return CKR_FUNCTION_NOT_PARALLEL;
667
 
}
668
 
 
669
 
CK_RV
670
 
gck_mock_C_GetSessionInfo (CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
671
 
{
672
 
        Session *session;
673
 
 
674
 
        g_return_val_if_fail (pInfo != NULL, CKR_ARGUMENTS_BAD);
675
 
 
676
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
677
 
        g_assert (session != NULL && "No such session found");
678
 
        if (!session)
679
 
                return CKR_SESSION_HANDLE_INVALID;
680
 
 
681
 
        if (logged_in) {
682
 
                if (session->info.flags & CKF_RW_SESSION)
683
 
                        session->info.state = CKS_RW_USER_FUNCTIONS;
684
 
                else
685
 
                        session->info.state = CKS_RO_USER_FUNCTIONS;
686
 
        } else {
687
 
                if (session->info.flags & CKF_RW_SESSION)
688
 
                        session->info.state = CKS_RW_PUBLIC_SESSION;
689
 
                else
690
 
                        session->info.state = CKS_RO_PUBLIC_SESSION;
691
 
        }
692
 
 
693
 
        memcpy (pInfo, &session->info, sizeof (*pInfo));
694
 
        return CKR_OK;
695
 
}
696
 
 
697
 
CK_RV
698
 
gck_mock_fail_C_GetSessionInfo (CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
699
 
{
700
 
        return CKR_GENERAL_ERROR;
701
 
}
702
 
 
703
 
CK_RV
704
 
gck_mock_C_InitPIN (CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin,
705
 
                    CK_ULONG ulPinLen)
706
 
{
707
 
        Session *session;
708
 
 
709
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
710
 
        g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
711
 
 
712
 
        g_free (the_pin);
713
 
        the_pin = g_strndup ((gchar*)pPin, ulPinLen);
714
 
        n_the_pin = ulPinLen;
715
 
        return CKR_OK;
716
 
}
717
 
 
718
 
CK_RV
719
 
gck_mock_C_SetPIN (CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
720
 
                   CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen)
721
 
{
722
 
        Session *session;
723
 
        gchar *old;
724
 
 
725
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
726
 
        g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
727
 
 
728
 
        old = g_strndup ((gchar*)pOldPin, ulOldLen);
729
 
        if (!old || !g_str_equal (old, the_pin))
730
 
                return CKR_PIN_INCORRECT;
731
 
 
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
739
 
gck_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
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)
749
 
{
750
 
        return CKR_FUNCTION_NOT_SUPPORTED;
751
 
}
752
 
 
753
 
CK_RV
754
 
gck_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
788
 
gck_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
804
 
gck_mock_C_CreateObject (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
805
 
                         CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject)
806
 
{
807
 
        GckAttributes *attrs;
808
 
        Session *session;
809
 
        gboolean token, priv;
810
 
        CK_OBJECT_CLASS klass;
811
 
        CK_OBJECT_HANDLE object;
812
 
        GckAttribute *attr;
813
 
        CK_ULONG i;
814
 
 
815
 
        g_return_val_if_fail (phObject, CKR_ARGUMENTS_BAD);
816
 
 
817
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
818
 
        g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
819
 
 
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);
823
 
 
824
 
        if (gck_attributes_find_boolean (attrs, CKA_PRIVATE, &priv) && priv) {
825
 
                if (!logged_in) {
826
 
                        gck_attributes_unref (attrs);
827
 
                        return CKR_USER_NOT_LOGGED_IN;
828
 
                }
829
 
        }
830
 
 
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;
839
 
                        }
840
 
                }
841
 
        }
842
 
 
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);
846
 
        else
847
 
                g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phObject), attrs);
848
 
 
849
 
        return CKR_OK;
850
 
}
851
 
 
852
 
CK_RV
853
 
gck_mock_fail_C_CreateObject (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
854
 
                              CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject)
855
 
{
856
 
        /* Always fails */
857
 
        return CKR_FUNCTION_FAILED;
858
 
}
859
 
 
860
 
CK_RV
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)
864
 
{
865
 
        return CKR_FUNCTION_NOT_SUPPORTED;
866
 
}
867
 
 
868
 
CK_RV
869
 
gck_mock_C_DestroyObject (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
870
 
{
871
 
        GckAttributes *attrs;
872
 
        Session *session;
873
 
        gboolean priv;
874
 
 
875
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
876
 
        g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
877
 
 
878
 
        attrs = lookup_object (session, hObject);
879
 
        g_return_val_if_fail (attrs, CKR_OBJECT_HANDLE_INVALID);
880
 
 
881
 
        if (gck_attributes_find_boolean (attrs, CKA_PRIVATE, &priv) && priv) {
882
 
                if (!logged_in)
883
 
                        return CKR_USER_NOT_LOGGED_IN;
884
 
        }
885
 
 
886
 
        g_hash_table_remove (the_objects, GUINT_TO_POINTER (hObject));
887
 
        g_hash_table_remove (session->objects, GUINT_TO_POINTER (hObject));
888
 
 
889
 
        return CKR_OK;
890
 
}
891
 
 
892
 
CK_RV
893
 
gck_mock_unsupported_C_GetObjectSize (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
894
 
                                      CK_ULONG_PTR pulSize)
895
 
{
896
 
        return CKR_FUNCTION_NOT_SUPPORTED;
897
 
}
898
 
 
899
 
CK_RV
900
 
gck_mock_C_GetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
901
 
                              CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
902
 
{
903
 
        CK_ATTRIBUTE_PTR result;
904
 
        CK_RV ret = CKR_OK;
905
 
        GckAttributes *attrs;
906
 
        GckAttribute *attr;
907
 
        Session *session;
908
 
        CK_ULONG i;
909
 
 
910
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
911
 
        g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
912
 
 
913
 
        attrs = lookup_object (session, hObject);
914
 
        if (!attrs) {
915
 
                g_assert_not_reached (); /* "invalid object handle passed" */
916
 
                return CKR_OBJECT_HANDLE_INVALID;
917
 
        }
918
 
 
919
 
        for (i = 0; i < ulCount; ++i) {
920
 
                result = pTemplate + i;
921
 
                attr = gck_attributes_find (attrs, result->type);
922
 
                if (!attr) {
923
 
                        result->ulValueLen = (CK_ULONG)-1;
924
 
                        ret = CKR_ATTRIBUTE_TYPE_INVALID;
925
 
                        continue;
926
 
                }
927
 
 
928
 
                if (!result->pValue) {
929
 
                        result->ulValueLen = attr->length;
930
 
                        continue;
931
 
                }
932
 
 
933
 
                if (result->ulValueLen >= attr->length) {
934
 
                        memcpy (result->pValue, attr->value, attr->length);
935
 
                        continue;
936
 
                }
937
 
 
938
 
                result->ulValueLen = (CK_ULONG)-1;
939
 
                ret = CKR_BUFFER_TOO_SMALL;
940
 
        }
941
 
 
942
 
        return ret;
943
 
}
944
 
 
945
 
CK_RV
946
 
gck_mock_fail_C_GetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
947
 
                                   CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
948
 
{
949
 
        return CKR_FUNCTION_FAILED;
950
 
}
951
 
 
952
 
CK_RV
953
 
gck_mock_C_SetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
954
 
                              CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
955
 
{
956
 
        Session *session;
957
 
        GckAttributes *attrs;
958
 
        CK_ATTRIBUTE_PTR set;
959
 
        GckAttribute *attr;
960
 
        CK_ULONG i;
961
 
 
962
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
963
 
        g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
964
 
 
965
 
        attrs = lookup_object (session, hObject);
966
 
        g_return_val_if_fail (attrs, CKR_OBJECT_HANDLE_INVALID);
967
 
 
968
 
        for (i = 0; i < ulCount; ++i) {
969
 
                set = pTemplate + i;
970
 
                attr = gck_attributes_find (attrs, set->type);
971
 
                if (!attr) {
972
 
                        gck_attributes_add_data (attrs, set->type, set->pValue, set->ulValueLen);
973
 
                } else {
974
 
                        gck_attribute_clear (attr);
975
 
                        gck_attribute_init (attr, set->type, set->pValue, set->ulValueLen);
976
 
                }
977
 
        }
978
 
 
979
 
        return CKR_OK;
980
 
}
981
 
 
982
 
typedef struct _FindObjects {
983
 
        CK_ATTRIBUTE_PTR template;
984
 
        CK_ULONG count;
985
 
        Session *session;
986
 
} FindObjects;
987
 
 
988
 
static gboolean
989
 
enumerate_and_find_objects (CK_OBJECT_HANDLE object, GckAttributes *attrs, gpointer user_data)
990
 
{
991
 
        FindObjects *ctx = user_data;
992
 
        CK_ATTRIBUTE_PTR match;
993
 
        GckAttribute *attr;
994
 
        CK_ULONG i;
995
 
 
996
 
        for (i = 0; i < ctx->count; ++i) {
997
 
                match = ctx->template + i;
998
 
                attr = gck_attributes_find (attrs, match->type);
999
 
                if (!attr)
1000
 
                        return TRUE; /* Continue */
1001
 
 
1002
 
                if (attr->length != match->ulValueLen ||
1003
 
                    memcmp (attr->value, match->pValue, attr->length) != 0)
1004
 
                        return TRUE; /* Continue */
1005
 
        }
1006
 
 
1007
 
        ctx->session->matches = g_list_prepend (ctx->session->matches, GUINT_TO_POINTER (object));
1008
 
        return TRUE; /* Continue */
1009
 
}
1010
 
 
1011
 
CK_RV
1012
 
gck_mock_C_FindObjectsInit (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
1013
 
                            CK_ULONG ulCount)
1014
 
{
1015
 
        Session *session;
1016
 
        FindObjects ctx;
1017
 
 
1018
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1019
 
        g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1020
 
 
1021
 
        /* Starting an operation, cancels any previous one */
1022
 
        if (session->operation != 0)
1023
 
                session->operation = 0;
1024
 
 
1025
 
        session->operation = OP_FIND;
1026
 
 
1027
 
        ctx.template = pTemplate;
1028
 
        ctx.count = ulCount;
1029
 
        ctx.session = session;
1030
 
 
1031
 
        gck_mock_module_enumerate_objects (hSession, enumerate_and_find_objects, &ctx);
1032
 
        return CKR_OK;
1033
 
}
1034
 
 
1035
 
CK_RV
1036
 
gck_mock_fail_C_FindObjects (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject,
1037
 
                             CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
1038
 
{
1039
 
        /* Always fails */
1040
 
        return CKR_FUNCTION_FAILED;
1041
 
}
1042
 
 
1043
 
CK_RV
1044
 
gck_mock_C_FindObjects (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject,
1045
 
                        CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
1046
 
{
1047
 
        Session *session;
1048
 
 
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);
1052
 
 
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);
1056
 
 
1057
 
        *pulObjectCount = 0;
1058
 
        while (ulMaxObjectCount > 0 && session->matches) {
1059
 
                *phObject = GPOINTER_TO_UINT (session->matches->data);
1060
 
                ++phObject;
1061
 
                --ulMaxObjectCount;
1062
 
                ++(*pulObjectCount);
1063
 
                session->matches = g_list_remove (session->matches, session->matches->data);
1064
 
        }
1065
 
 
1066
 
        return CKR_OK;
1067
 
}
1068
 
 
1069
 
CK_RV
1070
 
gck_mock_C_FindObjectsFinal (CK_SESSION_HANDLE hSession)
1071
 
{
1072
 
 
1073
 
        Session *session;
1074
 
 
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);
1078
 
 
1079
 
        session->operation = 0;
1080
 
        g_list_free (session->matches);
1081
 
        session->matches = NULL;
1082
 
 
1083
 
        return CKR_OK;
1084
 
}
1085
 
 
1086
 
CK_RV
1087
 
gck_mock_C_EncryptInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1088
 
                        CK_OBJECT_HANDLE hKey)
1089
 
{
1090
 
        Session *session;
1091
 
 
1092
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1093
 
        g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1094
 
 
1095
 
        /* Starting an operation, cancels any previous one */
1096
 
        if (session->operation != 0)
1097
 
                session->operation = 0;
1098
 
 
1099
 
        g_assert (pMechanism);
1100
 
        g_assert (pMechanism->mechanism == CKM_MOCK_CAPITALIZE);
1101
 
        g_assert (hKey == PUBLIC_KEY_CAPITALIZE);
1102
 
 
1103
 
        session->operation = OP_CRYPTO;
1104
 
        session->crypto_method = CKA_ENCRYPT;
1105
 
        session->crypto_mechanism = CKM_MOCK_CAPITALIZE;
1106
 
        session->crypto_key = hKey;
1107
 
        return CKR_OK;
1108
 
}
1109
 
 
1110
 
CK_RV
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)
1113
 
{
1114
 
        Session *session;
1115
 
        CK_ULONG i;
1116
 
 
1117
 
        g_return_val_if_fail (pData, CKR_DATA_INVALID);
1118
 
        g_return_val_if_fail (pulEncryptedDataLen, CKR_ARGUMENTS_BAD);
1119
 
 
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);
1124
 
 
1125
 
        g_assert (session->crypto_mechanism == CKM_MOCK_CAPITALIZE);
1126
 
        g_assert (session->crypto_key == PUBLIC_KEY_CAPITALIZE);
1127
 
 
1128
 
        if (!pEncryptedData) {
1129
 
                *pulEncryptedDataLen = ulDataLen;
1130
 
                return CKR_OK;
1131
 
        }
1132
 
 
1133
 
        if (*pulEncryptedDataLen < ulDataLen) {
1134
 
                *pulEncryptedDataLen = ulDataLen;
1135
 
                return CKR_BUFFER_TOO_SMALL;
1136
 
        }
1137
 
 
1138
 
        for (i = 0; i < ulDataLen; ++i)
1139
 
                pEncryptedData[i] = g_ascii_toupper (pData[i]);
1140
 
        *pulEncryptedDataLen = ulDataLen;
1141
 
 
1142
 
        session->operation = 0;
1143
 
        session->crypto_method = 0;
1144
 
        session->crypto_mechanism = 0;
1145
 
        session->crypto_key = 0;
1146
 
 
1147
 
        return CKR_OK;
1148
 
}
1149
 
 
1150
 
CK_RV
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)
1154
 
{
1155
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1156
 
}
1157
 
 
1158
 
CK_RV
1159
 
gck_mock_unsupported_C_EncryptFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart,
1160
 
                                     CK_ULONG_PTR pulLastEncryptedPartLen)
1161
 
{
1162
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1163
 
}
1164
 
 
1165
 
CK_RV
1166
 
gck_mock_C_DecryptInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1167
 
                        CK_OBJECT_HANDLE hKey)
1168
 
{
1169
 
        Session *session;
1170
 
 
1171
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1172
 
        g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1173
 
 
1174
 
        /* Starting an operation, cancels any previous one */
1175
 
        if (session->operation != 0)
1176
 
                session->operation = 0;
1177
 
 
1178
 
        g_assert (pMechanism);
1179
 
        g_assert (pMechanism->mechanism == CKM_MOCK_CAPITALIZE);
1180
 
        g_assert (hKey == PRIVATE_KEY_CAPITALIZE);
1181
 
 
1182
 
        session->operation = OP_CRYPTO;
1183
 
        session->crypto_method = CKA_DECRYPT;
1184
 
        session->crypto_mechanism = CKM_MOCK_CAPITALIZE;
1185
 
        session->crypto_key = hKey;
1186
 
        return CKR_OK;
1187
 
}
1188
 
 
1189
 
CK_RV
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)
1192
 
{
1193
 
        Session *session;
1194
 
        CK_ULONG i;
1195
 
 
1196
 
        g_return_val_if_fail (pEncryptedData, CKR_ENCRYPTED_DATA_INVALID);
1197
 
        g_return_val_if_fail (pulDataLen, CKR_ARGUMENTS_BAD);
1198
 
 
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);
1203
 
 
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);
1207
 
 
1208
 
        if (!pData) {
1209
 
                *pulDataLen = ulEncryptedDataLen;
1210
 
                return CKR_OK;
1211
 
        }
1212
 
 
1213
 
        if (*pulDataLen < ulEncryptedDataLen) {
1214
 
                *pulDataLen = ulEncryptedDataLen;
1215
 
                return CKR_BUFFER_TOO_SMALL;
1216
 
        }
1217
 
 
1218
 
        for (i = 0; i < ulEncryptedDataLen; ++i)
1219
 
                pData[i] = g_ascii_tolower (pEncryptedData[i]);
1220
 
        *pulDataLen = ulEncryptedDataLen;
1221
 
 
1222
 
        session->operation = 0;
1223
 
        session->crypto_method = 0;
1224
 
        session->crypto_mechanism = 0;
1225
 
        session->crypto_key = 0;
1226
 
 
1227
 
        return CKR_OK;
1228
 
}
1229
 
 
1230
 
CK_RV
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)
1233
 
{
1234
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1235
 
}
1236
 
 
1237
 
CK_RV
1238
 
gck_mock_unsupported_C_DecryptFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart,
1239
 
                                     CK_ULONG_PTR pulLastPartLen)
1240
 
{
1241
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1242
 
}
1243
 
 
1244
 
CK_RV
1245
 
gck_mock_unsupported_C_DigestInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism)
1246
 
{
1247
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1248
 
}
1249
 
 
1250
 
CK_RV
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)
1253
 
{
1254
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1255
 
}
1256
 
 
1257
 
CK_RV
1258
 
gck_mock_unsupported_C_DigestUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
1259
 
{
1260
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1261
 
}
1262
 
 
1263
 
CK_RV
1264
 
gck_mock_unsupported_C_DigestKey (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
1265
 
{
1266
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1267
 
}
1268
 
 
1269
 
CK_RV
1270
 
gck_mock_unsupported_C_DigestFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest,
1271
 
                                    CK_ULONG_PTR pulDigestLen)
1272
 
{
1273
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1274
 
}
1275
 
 
1276
 
CK_RV
1277
 
gck_mock_C_SignInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1278
 
                     CK_OBJECT_HANDLE hKey)
1279
 
{
1280
 
        Session *session;
1281
 
 
1282
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1283
 
        g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1284
 
 
1285
 
        /* Starting an operation, cancels any previous one */
1286
 
        if (session->operation != 0)
1287
 
                session->operation = 0;
1288
 
 
1289
 
        g_assert (pMechanism);
1290
 
        g_assert (pMechanism->mechanism == CKM_MOCK_PREFIX);
1291
 
        g_assert (hKey == PRIVATE_KEY_PREFIX);
1292
 
 
1293
 
        session->operation = OP_CRYPTO;
1294
 
        session->crypto_method = CKA_SIGN;
1295
 
        session->crypto_mechanism = CKM_MOCK_PREFIX;
1296
 
        session->crypto_key = hKey;
1297
 
 
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;
1302
 
        } else {
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);
1306
 
        }
1307
 
 
1308
 
        /* The private key has CKA_ALWAYS_AUTHENTICATE above */
1309
 
        session->want_context_login = CK_TRUE;
1310
 
 
1311
 
        return CKR_OK;
1312
 
}
1313
 
 
1314
 
CK_RV
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)
1317
 
{
1318
 
        Session *session;
1319
 
        CK_ULONG length;
1320
 
 
1321
 
        g_return_val_if_fail (pData, CKR_DATA_INVALID);
1322
 
        g_return_val_if_fail (pulSignatureLen, CKR_ARGUMENTS_BAD);
1323
 
 
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);
1328
 
 
1329
 
        if (session->want_context_login)
1330
 
                return CKR_USER_NOT_LOGGED_IN;
1331
 
 
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);
1335
 
 
1336
 
        length = session->n_sign_prefix + ulDataLen;
1337
 
 
1338
 
        if (!pSignature) {
1339
 
                *pulSignatureLen = length;
1340
 
                return CKR_OK;
1341
 
        }
1342
 
 
1343
 
        if (*pulSignatureLen < length) {
1344
 
                *pulSignatureLen = length;
1345
 
                return CKR_BUFFER_TOO_SMALL;
1346
 
        }
1347
 
 
1348
 
        memcpy (pSignature, session->sign_prefix, session->n_sign_prefix);
1349
 
        memcpy (pSignature + session->n_sign_prefix, pData, ulDataLen);
1350
 
        *pulSignatureLen = length;
1351
 
 
1352
 
        session->operation = 0;
1353
 
        session->crypto_method = 0;
1354
 
        session->crypto_mechanism = 0;
1355
 
        session->crypto_key = 0;
1356
 
 
1357
 
        return CKR_OK;
1358
 
}
1359
 
 
1360
 
CK_RV
1361
 
gck_mock_unsupported_C_SignUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
1362
 
{
1363
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1364
 
}
1365
 
 
1366
 
CK_RV
1367
 
gck_mock_unsupported_C_SignFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
1368
 
                                  CK_ULONG_PTR pulSignatureLen)
1369
 
{
1370
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1371
 
}
1372
 
 
1373
 
CK_RV
1374
 
gck_mock_unsupported_C_SignRecoverInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1375
 
                                        CK_OBJECT_HANDLE hKey)
1376
 
{
1377
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1378
 
}
1379
 
 
1380
 
CK_RV
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)
1383
 
{
1384
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1385
 
}
1386
 
 
1387
 
CK_RV
1388
 
gck_mock_C_VerifyInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1389
 
                       CK_OBJECT_HANDLE hKey)
1390
 
{
1391
 
        Session *session;
1392
 
 
1393
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1394
 
        g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1395
 
 
1396
 
        /* Starting an operation, cancels any previous one */
1397
 
        if (session->operation != 0)
1398
 
                session->operation = 0;
1399
 
 
1400
 
        g_assert (pMechanism);
1401
 
        g_assert (pMechanism->mechanism == CKM_MOCK_PREFIX);
1402
 
        g_assert (hKey == PUBLIC_KEY_PREFIX);
1403
 
 
1404
 
        session->operation = OP_CRYPTO;
1405
 
        session->crypto_method = CKA_VERIFY;
1406
 
        session->crypto_mechanism = CKM_MOCK_PREFIX;
1407
 
        session->crypto_key = hKey;
1408
 
 
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;
1413
 
        } else {
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);
1417
 
        }
1418
 
 
1419
 
        return CKR_OK;
1420
 
}
1421
 
 
1422
 
CK_RV
1423
 
gck_mock_C_Verify (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
1424
 
                   CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
1425
 
{
1426
 
        Session *session;
1427
 
        CK_ULONG length;
1428
 
 
1429
 
        g_return_val_if_fail (pData, CKR_DATA_INVALID);
1430
 
        g_return_val_if_fail (pSignature, CKR_ARGUMENTS_BAD);
1431
 
 
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);
1436
 
 
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);
1440
 
 
1441
 
        length = session->n_sign_prefix + ulDataLen;
1442
 
 
1443
 
        if (ulSignatureLen < length) {
1444
 
                g_assert (FALSE);
1445
 
                return CKR_SIGNATURE_LEN_RANGE;
1446
 
        }
1447
 
 
1448
 
        if (memcmp (pSignature, session->sign_prefix, session->n_sign_prefix) == 0 &&
1449
 
            memcmp (pSignature + session->n_sign_prefix, pData, ulDataLen) == 0)
1450
 
                return CKR_OK;
1451
 
 
1452
 
        return CKR_SIGNATURE_INVALID;
1453
 
}
1454
 
 
1455
 
CK_RV
1456
 
gck_mock_unsupported_C_VerifyUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
1457
 
{
1458
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1459
 
}
1460
 
 
1461
 
CK_RV
1462
 
gck_mock_unsupported_C_VerifyFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
1463
 
                                    CK_ULONG pulSignatureLen)
1464
 
{
1465
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1466
 
}
1467
 
 
1468
 
CK_RV
1469
 
gck_mock_unsupported_C_VerifyRecoverInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
1470
 
                                          CK_OBJECT_HANDLE hKey)
1471
 
{
1472
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1473
 
}
1474
 
 
1475
 
CK_RV
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)
1478
 
{
1479
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1480
 
}
1481
 
 
1482
 
CK_RV
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)
1486
 
{
1487
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1488
 
}
1489
 
 
1490
 
CK_RV
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)
1494
 
{
1495
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1496
 
}
1497
 
 
1498
 
CK_RV
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)
1502
 
{
1503
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1504
 
}
1505
 
 
1506
 
CK_RV
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)
1510
 
{
1511
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1512
 
}
1513
 
 
1514
 
CK_RV
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)
1518
 
{
1519
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1520
 
}
1521
 
 
1522
 
CK_RV
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)
1527
 
{
1528
 
        GckAttributes *attrs;
1529
 
        Session *session;
1530
 
        gboolean token;
1531
 
        CK_ULONG i;
1532
 
 
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);
1540
 
 
1541
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1542
 
        g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1543
 
 
1544
 
        if (pMechanism->mechanism != CKM_MOCK_GENERATE)
1545
 
                return CKR_MECHANISM_INVALID;
1546
 
 
1547
 
        if (!pMechanism->pParameter || pMechanism->ulParameterLen != 9 ||
1548
 
            memcmp (pMechanism->pParameter, "generate", 9) != 0)
1549
 
                g_return_val_if_reached (CKR_MECHANISM_PARAM_INVALID);
1550
 
 
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);
1560
 
        else
1561
 
                g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phPublicKey), attrs);
1562
 
 
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);
1572
 
        else
1573
 
                g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phPrivateKey), attrs);
1574
 
        return CKR_OK;
1575
 
}
1576
 
 
1577
 
CK_RV
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)
1581
 
{
1582
 
        GckAttributes *attrs;
1583
 
        GckAttribute *attr;
1584
 
        Session *session;
1585
 
 
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);
1590
 
 
1591
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1592
 
        g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1593
 
 
1594
 
        attrs = lookup_object (session, hWrappingKey);
1595
 
        g_return_val_if_fail (attrs, CKR_WRAPPING_KEY_HANDLE_INVALID);
1596
 
 
1597
 
        attrs = lookup_object (session, hKey);
1598
 
        g_return_val_if_fail (attrs, CKR_WRAPPED_KEY_INVALID);
1599
 
 
1600
 
        if (pMechanism->mechanism != CKM_MOCK_WRAP)
1601
 
                return CKR_MECHANISM_INVALID;
1602
 
 
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);
1607
 
        }
1608
 
 
1609
 
        attr = gck_attributes_find (attrs, CKA_VALUE);
1610
 
        if (attr == NULL)
1611
 
                return CKR_WRAPPED_KEY_INVALID;
1612
 
 
1613
 
        if (!pWrappedKey) {
1614
 
                *pulWrappedKeyLen = attr->length;
1615
 
                return CKR_OK;
1616
 
        }
1617
 
 
1618
 
        if (*pulWrappedKeyLen < attr->length) {
1619
 
                *pulWrappedKeyLen = attr->length;
1620
 
                return CKR_BUFFER_TOO_SMALL;
1621
 
        }
1622
 
 
1623
 
        memcpy (pWrappedKey, attr->value, attr->length);
1624
 
        *pulWrappedKeyLen = attr->length;
1625
 
 
1626
 
        return CKR_OK;
1627
 
}
1628
 
 
1629
 
CK_RV
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)
1634
 
{
1635
 
        GckAttributes *attrs;
1636
 
        Session *session;
1637
 
        gboolean token;
1638
 
        CK_ULONG i;
1639
 
 
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);
1647
 
 
1648
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1649
 
        g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
1650
 
 
1651
 
        attrs = lookup_object (session, hUnwrappingKey);
1652
 
        g_return_val_if_fail (attrs, CKR_WRAPPING_KEY_HANDLE_INVALID);
1653
 
 
1654
 
        if (pMechanism->mechanism != CKM_MOCK_WRAP)
1655
 
                return CKR_MECHANISM_INVALID;
1656
 
 
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);
1661
 
        }
1662
 
 
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);
1672
 
        else
1673
 
                g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phKey), attrs);
1674
 
 
1675
 
        return CKR_OK;
1676
 
}
1677
 
 
1678
 
CK_RV
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)
1682
 
{
1683
 
        GckAttributes *attrs, *copy;
1684
 
        Session *session;
1685
 
        gboolean token;
1686
 
        CK_ULONG i;
1687
 
 
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);
1692
 
 
1693
 
        session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
1694
 
        g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
1695
 
 
1696
 
        attrs = lookup_object (session, hBaseKey);
1697
 
        g_return_val_if_fail (attrs, CKR_KEY_HANDLE_INVALID);
1698
 
 
1699
 
        if (pMechanism->mechanism != CKM_MOCK_DERIVE)
1700
 
                return CKR_MECHANISM_INVALID;
1701
 
 
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);
1706
 
        }
1707
 
 
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);
1719
 
        else
1720
 
                g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phKey), copy);
1721
 
 
1722
 
        return CKR_OK;
1723
 
}
1724
 
 
1725
 
CK_RV
1726
 
gck_mock_unsupported_C_SeedRandom (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
1727
 
{
1728
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1729
 
}
1730
 
 
1731
 
CK_RV
1732
 
gck_mock_unsupported_C_GenerateRandom (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData,
1733
 
                           CK_ULONG ulRandomLen)
1734
 
{
1735
 
        return CKR_FUNCTION_NOT_SUPPORTED;
1736
 
}
1737
 
 
1738
 
static CK_FUNCTION_LIST functionList = {
1739
 
        { 2, 11 },      /* version */
1740
 
        gck_mock_validate_and_C_Initialize,
1741
 
        gck_mock_C_Finalize,
1742
 
        gck_mock_C_GetInfo,
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,
1750
 
        gck_mock_C_InitPIN,
1751
 
        gck_mock_C_SetPIN,
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,
1758
 
        gck_mock_C_Login,
1759
 
        gck_mock_C_Logout,
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,
1770
 
        gck_mock_C_Encrypt,
1771
 
        gck_mock_unsupported_C_EncryptUpdate,
1772
 
        gck_mock_unsupported_C_EncryptFinal,
1773
 
        gck_mock_C_DecryptInit,
1774
 
        gck_mock_C_Decrypt,
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,
1783
 
        gck_mock_C_Sign,
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,
1789
 
        gck_mock_C_Verify,
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
1808
 
};