]> git.0d.be Git - empathy.git/blob - tests/mock-pkcs11.c
997b3311c543ac2b537388db22cb1f4c51b709c7
[empathy.git] / tests / mock-pkcs11.c
1 /*
2  * Copyright (C) 2010 Stefan Walter
3  * Copyright (C) 2011 Collabora Ltd.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General  License as
7  * published by the Free Software Foundation; either version 2.1 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General  License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18  * 02111-1307, USA.
19  */
20
21 #include "config.h"
22 #include "mock-pkcs11.h"
23
24 #include <gcr/gcr.h>
25 #include <glib.h>
26 #include <string.h>
27
28 /*
29  * This is *NOT* how you'd want to implement a PKCS#11 module. This
30  * fake module simply provides enough for gnutls-pkcs11 backend to test against.
31  * It doesn't pass any tests, or behave as expected from a PKCS#11 module.
32  */
33
34 static gboolean initialized = FALSE;
35
36 typedef enum {
37   OP_FIND = 1,
38 } Operation;
39
40 static CK_OBJECT_HANDLE unique_identifier = 100;
41 static GHashTable *the_sessions = NULL;
42 static GHashTable *the_certificates = NULL;
43 static GHashTable *the_assertions = NULL;
44
45 typedef struct {
46   GcrCertificate *cert;
47   CK_ULONG assertion_type;
48   gchar *purpose;
49   gchar *peer;
50 } Assertion;
51
52 static void
53 free_assertion (gpointer data)
54 {
55   Assertion *assertion = data;
56   g_clear_object (&assertion->cert);
57   g_free (assertion->purpose);
58   g_free (assertion->peer);
59   g_free (assertion);
60 }
61
62 typedef struct {
63   CK_SESSION_HANDLE handle;
64   CK_SESSION_INFO info;
65
66   Operation operation;
67
68   /* For find operations */
69   GList *matches;
70 } Session;
71
72 static void
73 free_session (gpointer data)
74 {
75   Session *sess = (Session*)data;
76   g_list_free (sess->matches);
77   g_free (sess);
78 }
79
80 CK_OBJECT_HANDLE
81 mock_module_add_certificate (GcrCertificate *cert)
82 {
83   CK_OBJECT_HANDLE handle;
84
85   g_return_val_if_fail (GCR_IS_CERTIFICATE (cert), 0);
86
87   handle = unique_identifier++;
88   g_hash_table_insert (the_certificates, GUINT_TO_POINTER (handle), g_object_ref (cert));
89   return handle;
90 }
91
92 CK_OBJECT_HANDLE
93 mock_module_add_assertion (GcrCertificate *cert,
94                            CK_X_ASSERTION_TYPE assertion_type,
95                            const gchar *purpose,
96                            const gchar *peer)
97 {
98   Assertion *assertion;
99   CK_OBJECT_HANDLE handle;
100
101   g_return_val_if_fail (GCR_IS_CERTIFICATE (cert), 0);
102
103   assertion = g_new0 (Assertion, 1);
104   assertion->cert = g_object_ref (cert);
105   assertion->assertion_type = assertion_type;
106   assertion->purpose = g_strdup (purpose);
107   assertion->peer = g_strdup (peer);
108
109   handle = unique_identifier++;
110   g_hash_table_insert (the_assertions, GUINT_TO_POINTER (handle), assertion);
111   return handle;
112 }
113
114 CK_RV
115 mock_C_Initialize (CK_VOID_PTR init_args)
116 {
117   CK_C_INITIALIZE_ARGS_PTR args;
118
119   g_return_val_if_fail (initialized == FALSE, CKR_CRYPTOKI_ALREADY_INITIALIZED);
120
121   args = (CK_C_INITIALIZE_ARGS_PTR)init_args;
122   if (args)
123     {
124       g_return_val_if_fail(
125           (args->CreateMutex == NULL && args->DestroyMutex == NULL &&
126            args->LockMutex == NULL && args->UnlockMutex == NULL) ||
127           (args->CreateMutex != NULL && args->DestroyMutex != NULL &&
128            args->LockMutex != NULL && args->UnlockMutex != NULL),
129           CKR_ARGUMENTS_BAD);
130
131       /* Flags should allow OS locking and os threads */
132       g_return_val_if_fail ((args->flags & CKF_OS_LOCKING_OK), CKR_CANT_LOCK);
133       g_return_val_if_fail ((args->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) == 0, CKR_NEED_TO_CREATE_THREADS);
134     }
135
136   the_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_session);
137   the_certificates = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_object_unref);
138   the_assertions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_assertion);
139
140   initialized = TRUE;
141   return CKR_OK;
142 }
143
144 CK_RV
145 mock_C_Finalize (CK_VOID_PTR reserved)
146 {
147   g_return_val_if_fail (reserved == NULL, CKR_ARGUMENTS_BAD);
148   g_return_val_if_fail (initialized == TRUE, CKR_CRYPTOKI_NOT_INITIALIZED);
149
150   initialized = FALSE;
151
152   g_hash_table_destroy (the_certificates);
153   the_certificates = NULL;
154
155   g_hash_table_destroy (the_assertions);
156   the_assertions = NULL;
157
158   g_hash_table_destroy (the_sessions);
159   the_sessions = NULL;
160
161   return CKR_OK;
162 }
163
164 static const CK_INFO TEST_INFO = {
165   { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
166   "TEST MANUFACTURER              ",
167   0,
168   "TEST LIBRARY                   ",
169   { 45, 145 }
170 };
171
172 CK_RV
173 mock_C_GetInfo (CK_INFO_PTR info)
174 {
175   g_return_val_if_fail (info, CKR_ARGUMENTS_BAD);
176   memcpy (info, &TEST_INFO, sizeof (*info));
177   return CKR_OK;
178 }
179
180 CK_RV
181 mock_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
182 {
183   g_return_val_if_fail (list, CKR_ARGUMENTS_BAD);
184   *list = &mock_default_functions;
185   return CKR_OK;
186 }
187
188 CK_RV
189 mock_C_GetSlotList (CK_BBOOL token_present,
190                     CK_SLOT_ID_PTR slot_list,
191                     CK_ULONG_PTR count)
192 {
193   CK_ULONG num = 1;
194
195   g_return_val_if_fail (count, CKR_ARGUMENTS_BAD);
196
197   /* Application only wants to know the number of slots. */
198   if (slot_list == NULL)
199     {
200       *count = num;
201       return CKR_OK;
202     }
203
204   if (*count < num)
205     g_return_val_if_reached (CKR_BUFFER_TOO_SMALL);
206
207   *count = num;
208   slot_list[0] = MOCK_SLOT_ONE_ID;
209   return CKR_OK;
210 }
211
212 /* Update mock-pkcs11.h URIs when updating this */
213
214 static const CK_SLOT_INFO MOCK_INFO_ONE = {
215   "MOCK SLOT                                                       ",
216   "MOCK MANUFACTURER              ",
217   CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE,
218   { 55, 155 },
219   { 65, 165 },
220 };
221
222 CK_RV
223 mock_C_GetSlotInfo (CK_SLOT_ID slot_id,
224                     CK_SLOT_INFO_PTR info)
225 {
226   g_return_val_if_fail (info, CKR_ARGUMENTS_BAD);
227
228   if (slot_id == MOCK_SLOT_ONE_ID)
229     {
230       memcpy (info, &MOCK_INFO_ONE, sizeof (*info));
231       return CKR_OK;
232     }
233   else
234     {
235       g_return_val_if_reached (CKR_SLOT_ID_INVALID);
236     }
237 }
238
239 /* Update mock-pkcs11.h URIs when updating this */
240
241 static const CK_TOKEN_INFO MOCK_TOKEN_ONE = {
242   "MOCK LABEL                      ",
243   "MOCK MANUFACTURER               ",
244   "MOCK MODEL      ",
245   "MOCK SERIAL     ",
246   CKF_TOKEN_INITIALIZED | CKF_WRITE_PROTECTED,
247   1,
248   2,
249   3,
250   4,
251   5,
252   6,
253   7,
254   8,
255   9,
256   10,
257   { 75, 175 },
258   { 85, 185 },
259   { '1', '9', '9', '9', '0', '5', '2', '5', '0', '9', '1', '9', '5', '9', '0', '0' }
260 };
261
262 CK_RV
263 mock_C_GetTokenInfo (CK_SLOT_ID slot_id,
264                      CK_TOKEN_INFO_PTR info)
265 {
266   g_return_val_if_fail (info != NULL, CKR_ARGUMENTS_BAD);
267
268   if (slot_id == MOCK_SLOT_ONE_ID)
269     {
270       memcpy (info, &MOCK_TOKEN_ONE, sizeof (*info));
271       return CKR_OK;
272     }
273   else
274     {
275       g_return_val_if_reached (CKR_SLOT_ID_INVALID);
276     }
277 }
278
279 CK_RV
280 mock_C_GetMechanismList (CK_SLOT_ID slot_id,
281                          CK_MECHANISM_TYPE_PTR mechanism_list,
282                          CK_ULONG_PTR count)
283 {
284   g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
285   g_return_val_if_fail (count, CKR_ARGUMENTS_BAD);
286
287   /* Application only wants to know the number of slots. */
288   if (mechanism_list == NULL)
289     {
290       *count = 0;
291       return CKR_OK;
292     }
293
294   return CKR_OK;
295 }
296
297 CK_RV
298 mock_C_GetMechanismInfo (CK_SLOT_ID slot_id,
299                          CK_MECHANISM_TYPE type,
300                          CK_MECHANISM_INFO_PTR info)
301 {
302   g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
303   g_return_val_if_fail (info, CKR_ARGUMENTS_BAD);
304
305   g_return_val_if_reached (CKR_MECHANISM_INVALID);
306 }
307
308 CK_RV
309 mock_unsupported_C_InitToken (CK_SLOT_ID slot_id,
310                               CK_UTF8CHAR_PTR pin,
311                               CK_ULONG pin_len,
312                               CK_UTF8CHAR_PTR label)
313 {
314   g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
315   return CKR_FUNCTION_NOT_SUPPORTED;
316 }
317
318 CK_RV
319 mock_unsupported_C_WaitForSlotEvent (CK_FLAGS flags,
320                                      CK_SLOT_ID_PTR slot_id,
321                                      CK_VOID_PTR reserved)
322 {
323   return CKR_FUNCTION_NOT_SUPPORTED;
324 }
325
326 CK_RV
327 mock_C_OpenSession (CK_SLOT_ID slot_id,
328                     CK_FLAGS flags,
329                     CK_VOID_PTR application,
330                     CK_NOTIFY notify,
331                     CK_SESSION_HANDLE_PTR session)
332 {
333   Session *sess;
334
335   g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
336   g_return_val_if_fail (session != NULL, CKR_ARGUMENTS_BAD);
337   g_return_val_if_fail ((flags & CKF_SERIAL_SESSION) == CKF_SERIAL_SESSION, CKR_SESSION_PARALLEL_NOT_SUPPORTED);
338
339   if (flags & CKF_RW_SESSION)
340     return CKR_TOKEN_WRITE_PROTECTED;
341
342   sess = g_new0 (Session, 1);
343   sess->handle = ++unique_identifier;
344   sess->info.flags = flags;
345   sess->info.slotID = slot_id;
346   sess->info.state = CKS_RO_PUBLIC_SESSION;
347   sess->info.ulDeviceError = 0;
348   *session = sess->handle;
349
350   g_hash_table_replace (the_sessions, GUINT_TO_POINTER (sess->handle), sess);
351   return CKR_OK;
352 }
353
354 CK_RV
355 mock_C_CloseSession (CK_SESSION_HANDLE session)
356 {
357   Session *sess;
358
359   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
360   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
361
362   g_hash_table_remove (the_sessions, GUINT_TO_POINTER (sess));
363   return CKR_OK;
364 }
365
366 CK_RV
367 mock_C_CloseAllSessions (CK_SLOT_ID slot_id)
368 {
369   g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
370
371   g_hash_table_remove_all (the_sessions);
372   return CKR_OK;
373 }
374
375 CK_RV
376 mock_C_GetFunctionStatus (CK_SESSION_HANDLE session)
377 {
378   return CKR_FUNCTION_NOT_PARALLEL;
379 }
380
381 CK_RV
382 mock_C_CancelFunction (CK_SESSION_HANDLE session)
383 {
384   return CKR_FUNCTION_NOT_PARALLEL;
385 }
386
387 CK_RV
388 mock_C_GetSessionInfo (CK_SESSION_HANDLE session,
389                        CK_SESSION_INFO_PTR info)
390 {
391   Session *sess;
392
393   g_return_val_if_fail (info != NULL, CKR_ARGUMENTS_BAD);
394
395   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
396   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
397
398   memcpy (info, &sess->info, sizeof (*info));
399   return CKR_OK;
400 }
401
402 CK_RV
403 mock_unsupported_C_InitPIN (CK_SESSION_HANDLE session,
404                             CK_UTF8CHAR_PTR pin,
405                             CK_ULONG pin_len)
406 {
407   return CKR_FUNCTION_NOT_SUPPORTED;
408 }
409
410 CK_RV
411 mock_unsupported_C_SetPIN (CK_SESSION_HANDLE session,
412                            CK_UTF8CHAR_PTR old_pin,
413                            CK_ULONG old_len,
414                            CK_UTF8CHAR_PTR new_pin,
415                            CK_ULONG new_len)
416 {
417   return CKR_FUNCTION_NOT_SUPPORTED;
418 }
419
420 CK_RV
421 mock_unsupported_C_GetOperationState (CK_SESSION_HANDLE session,
422                                       CK_BYTE_PTR operation_state,
423                                       CK_ULONG_PTR operation_state_len)
424 {
425   return CKR_FUNCTION_NOT_SUPPORTED;
426 }
427
428 CK_RV
429 mock_unsupported_C_SetOperationState (CK_SESSION_HANDLE session,
430                                       CK_BYTE_PTR operation_state,
431                                       CK_ULONG operation_state_len,
432                                       CK_OBJECT_HANDLE encryption_key,
433                                       CK_OBJECT_HANDLE authentication_key)
434 {
435   return CKR_FUNCTION_NOT_SUPPORTED;
436 }
437
438 CK_RV
439 mock_unsupported_C_Login (CK_SESSION_HANDLE session,
440                           CK_USER_TYPE user_type,
441                           CK_UTF8CHAR_PTR pin,
442                           CK_ULONG pin_len)
443 {
444   return CKR_FUNCTION_NOT_SUPPORTED;
445 }
446
447 CK_RV
448 mock_unsupported_C_Logout (CK_SESSION_HANDLE session)
449 {
450   return CKR_FUNCTION_NOT_SUPPORTED;
451 }
452
453 CK_RV
454 mock_readonly_C_CreateObject (CK_SESSION_HANDLE session,
455                               CK_ATTRIBUTE_PTR template,
456                               CK_ULONG count,
457                               CK_OBJECT_HANDLE_PTR object)
458 {
459   Session *sess;
460
461   g_return_val_if_fail (object, CKR_ARGUMENTS_BAD);
462
463   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
464   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
465
466   return CKR_TOKEN_WRITE_PROTECTED;
467 }
468
469 CK_RV
470 mock_unsupported_C_CopyObject (CK_SESSION_HANDLE session,
471                                CK_OBJECT_HANDLE object,
472                                CK_ATTRIBUTE_PTR template,
473                                CK_ULONG count,
474                                CK_OBJECT_HANDLE_PTR new_object)
475 {
476   return CKR_FUNCTION_NOT_SUPPORTED;
477 }
478
479 CK_RV
480 mock_readonly_C_DestroyObject (CK_SESSION_HANDLE session,
481                                CK_OBJECT_HANDLE object)
482 {
483   Session *sess;
484
485   g_return_val_if_fail (object, CKR_ARGUMENTS_BAD);
486
487   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
488   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
489
490   return CKR_TOKEN_WRITE_PROTECTED;
491 }
492
493 CK_RV
494 mock_unsupported_C_GetObjectSize (CK_SESSION_HANDLE session,
495                                   CK_OBJECT_HANDLE object,
496                                   CK_ULONG_PTR pulSize)
497 {
498   return CKR_FUNCTION_NOT_SUPPORTED;
499 }
500
501 static CK_RV
502 fill_data_attribute (CK_ATTRIBUTE *attr,
503                      gconstpointer data,
504                      gsize length)
505 {
506   if (!attr->pValue) {
507       attr->ulValueLen = length;
508       return CKR_OK;
509   } else if (attr->ulValueLen < length) {
510       attr->ulValueLen = length;
511       return CKR_BUFFER_TOO_SMALL;
512   } else {
513       memcpy (attr->pValue, data, length);
514       attr->ulValueLen = length;
515       return CKR_OK;
516   }
517 }
518
519 static CK_RV
520 fill_check_value_attribute (CK_ATTRIBUTE *attr,
521                             GcrCertificate *cert)
522 {
523   guchar *data;
524   gsize length;
525   CK_RV rv;
526
527   data = gcr_certificate_get_fingerprint (cert, G_CHECKSUM_SHA1, &length);
528   rv = fill_data_attribute (attr, data, 3);
529   g_free (data);
530
531   return rv;
532 }
533
534 static CK_RV
535 fill_subject_attribute (CK_ATTRIBUTE *attr,
536                         GcrCertificate *cert)
537 {
538   guchar *data;
539   gsize length;
540   CK_RV rv;
541
542   data = gcr_certificate_get_subject_raw (cert, &length);
543   rv = fill_data_attribute (attr, data, length);
544   g_free (data);
545
546   return rv;
547 }
548
549 static CK_RV
550 fill_issuer_attribute (CK_ATTRIBUTE *attr,
551                        GcrCertificate *cert)
552 {
553   guchar *data;
554   gsize length;
555   CK_RV rv;
556
557   data = gcr_certificate_get_issuer_raw (cert, &length);
558   rv = fill_data_attribute (attr, data, length);
559   g_free (data);
560
561   return rv;
562 }
563
564 static CK_RV
565 fill_serial_attribute (CK_ATTRIBUTE *attr,
566                        GcrCertificate *cert)
567 {
568   guchar *data;
569   gsize length;
570   CK_RV rv;
571
572   data = gcr_certificate_get_serial_number (cert, &length);
573   rv = fill_data_attribute (attr, data, length);
574   g_free (data);
575
576   return rv;
577 }
578
579 static CK_RV
580 fill_string_attribute (CK_ATTRIBUTE *attr,
581                        const gchar *data)
582 {
583   return fill_data_attribute (attr, data, strlen (data));
584 }
585
586 static CK_RV
587 fill_id_attribute (CK_ATTRIBUTE *attr,
588                    GcrCertificate *cert)
589 {
590   gchar *data;
591   CK_RV rv;
592
593   data = g_strdup_printf ("%p", cert);
594   rv = fill_string_attribute (attr, data);
595   g_free (data);
596
597   return rv;
598 }
599
600 static CK_RV
601 fill_value_attribute (CK_ATTRIBUTE *attr,
602                       GcrCertificate *cert)
603 {
604   const guchar *data;
605   gsize length;
606
607   data = gcr_certificate_get_der_data (cert, &length);
608   return fill_data_attribute (attr, data, length);
609 }
610
611 static CK_RV
612 fill_ulong_attribute (CK_ATTRIBUTE *attr,
613                       CK_ULONG value)
614 {
615   return fill_data_attribute (attr, &value, sizeof (value));
616 }
617
618 static CK_RV
619 fill_bool_attribute (CK_ATTRIBUTE *attr,
620                      CK_BBOOL value)
621 {
622   return fill_data_attribute (attr, &value, sizeof (value));
623 }
624
625 static CK_RV
626 fill_certificate_attribute (CK_ATTRIBUTE *attr,
627                             GcrCertificate *cert)
628 {
629   switch (attr->type)
630   {
631   case CKA_CLASS:
632     return fill_ulong_attribute (attr, CKO_CERTIFICATE);
633   case CKA_TOKEN:
634     return fill_bool_attribute (attr, CK_TRUE);
635   case CKA_PRIVATE:
636   case CKA_MODIFIABLE:
637   case CKA_TRUSTED:
638     return fill_bool_attribute (attr, CK_FALSE);
639   case CKA_LABEL:
640     return fill_string_attribute (attr, "Certificate");
641   case CKA_CERTIFICATE_TYPE:
642     return fill_ulong_attribute (attr, CKC_X_509);
643   case CKA_CERTIFICATE_CATEGORY:
644     return fill_ulong_attribute (attr, 2);
645   case CKA_CHECK_VALUE:
646     return fill_check_value_attribute (attr, cert);
647   case CKA_START_DATE:
648   case CKA_END_DATE:
649     return fill_data_attribute (attr, "", 0);
650   case CKA_SUBJECT:
651     return fill_subject_attribute (attr, cert);
652   case CKA_ID:
653     return fill_id_attribute (attr, cert);
654   case CKA_ISSUER:
655     return fill_issuer_attribute (attr, cert);
656   case CKA_SERIAL_NUMBER:
657     return fill_serial_attribute (attr, cert);
658   case CKA_VALUE:
659     return fill_value_attribute (attr, cert);
660   case CKA_URL:
661   case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
662   case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
663   case CKA_JAVA_MIDP_SECURITY_DOMAIN:
664   default:
665     return CKR_ATTRIBUTE_TYPE_INVALID;
666   }
667 }
668
669 static CK_RV
670 fill_assertion_attribute (CK_ATTRIBUTE *attr,
671                           Assertion *assertion)
672 {
673   CK_RV rv;
674
675   switch (attr->type)
676   {
677   case CKA_CLASS:
678     return fill_ulong_attribute (attr, CKO_X_TRUST_ASSERTION);
679   case CKA_TOKEN:
680     return fill_bool_attribute (attr, CK_TRUE);
681   case CKA_PRIVATE:
682   case CKA_MODIFIABLE:
683   case CKA_TRUSTED:
684     return fill_bool_attribute (attr, CK_FALSE);
685   case CKA_LABEL:
686     return fill_string_attribute (attr, "Assertion");
687   case CKA_X_ASSERTION_TYPE:
688     return fill_ulong_attribute (attr, assertion->assertion_type);
689   case CKA_X_PURPOSE:
690     return fill_string_attribute (attr, assertion->purpose);
691   case CKA_X_PEER:
692     if (!assertion->peer)
693       return CKR_ATTRIBUTE_TYPE_INVALID;
694     return fill_string_attribute (attr, assertion->peer);
695   case CKA_SERIAL_NUMBER:
696   case CKA_ISSUER:
697     return fill_certificate_attribute (attr, assertion->cert);
698   case CKA_X_CERTIFICATE_VALUE:
699     attr->type = CKA_VALUE;
700     rv = fill_certificate_attribute (attr, assertion->cert);
701     attr->type = CKA_X_CERTIFICATE_VALUE;
702     return rv;
703
704   default:
705     return CKR_ATTRIBUTE_TYPE_INVALID;
706   }
707 }
708
709 CK_RV
710 mock_C_GetAttributeValue (CK_SESSION_HANDLE session,
711                           CK_OBJECT_HANDLE object,
712                           CK_ATTRIBUTE_PTR template,
713                           CK_ULONG count)
714 {
715   CK_RV rv, ret = CKR_OK;
716   GcrCertificate *cert;
717   Assertion *assertion;
718   Session *sess;
719   CK_ULONG i;
720
721   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
722   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
723
724   cert = g_hash_table_lookup (the_certificates, GUINT_TO_POINTER (object));
725   assertion = g_hash_table_lookup (the_assertions, GUINT_TO_POINTER (object));
726
727   if (cert != NULL) {
728       for (i = 0; i < count; i++) {
729           rv = fill_certificate_attribute (template + i, cert);
730           if (rv != CKR_OK)
731             template[i].ulValueLen = (CK_ULONG)-1;
732           if (ret != CKR_OK)
733             ret = rv;
734       }
735   } else if (assertion != NULL) {
736       for (i = 0; i < count; i++) {
737           rv = fill_assertion_attribute (template + i, assertion);
738           if (rv != CKR_OK)
739             template[i].ulValueLen = (CK_ULONG)-1;
740           if (ret != CKR_OK)
741             ret = rv;
742       }
743   } else {
744       ret = CKR_OBJECT_HANDLE_INVALID;
745   }
746
747   return ret;
748 }
749
750 CK_RV
751 mock_readonly_C_SetAttributeValue (CK_SESSION_HANDLE session,
752                                    CK_OBJECT_HANDLE object,
753                                    CK_ATTRIBUTE_PTR template,
754                                    CK_ULONG count)
755 {
756   Session *sess;
757
758   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
759   g_return_val_if_fail (sess, CKR_SESSION_HANDLE_INVALID);
760
761   return CKR_TOKEN_WRITE_PROTECTED;
762 }
763
764 static gboolean
765 match_object_attributes (CK_SESSION_HANDLE session,
766                          CK_ULONG object,
767                          CK_ATTRIBUTE_PTR template,
768                          CK_ULONG count)
769 {
770   CK_ATTRIBUTE_PTR values;
771   gboolean mismatch = FALSE;
772   CK_RV rv;
773   CK_ULONG i;
774
775   values = g_new0 (CK_ATTRIBUTE, count);
776   for (i = 0; i < count; i++) {
777       values[i].type = template[i].type;
778       if (template[i].ulValueLen != 0 &&
779           template[i].ulValueLen != (CK_ULONG)-1)
780           values[i].pValue = g_malloc (template[i].ulValueLen);
781       values[i].ulValueLen = template[i].ulValueLen;
782   }
783
784   rv = mock_C_GetAttributeValue (session, object, values, count);
785
786   if (rv == CKR_OK) {
787       for (i = 0; i < count; i++) {
788           if (gcr_comparable_memcmp (values[i].pValue, values[i].ulValueLen,
789                                      template[i].pValue, template[i].ulValueLen) != 0) {
790             mismatch = TRUE;
791             break;
792           }
793       }
794   }
795
796   for (i = 0; i < count; i++)
797       g_free (values[i].pValue);
798   g_free (values);
799
800   if (rv != CKR_OK)
801     return FALSE;
802
803   return !mismatch;
804 }
805
806 CK_RV
807 mock_C_FindObjectsInit (CK_SESSION_HANDLE session,
808                         CK_ATTRIBUTE_PTR template,
809                         CK_ULONG count)
810 {
811   GList *objects = NULL, *l;
812   Session *sess;
813
814   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
815   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
816
817   /* Starting an operation, cancels any previous one */
818   if (sess->operation != 0)
819     sess->operation = 0;
820
821   sess->operation = OP_FIND;
822   g_list_free (sess->matches);
823   sess->matches = NULL;
824
825   objects = g_list_concat (objects, g_hash_table_get_keys (the_certificates));
826   objects = g_list_concat (objects, g_hash_table_get_keys (the_assertions));
827
828   for (l = objects; l != NULL; l = g_list_next (l)) {
829       if (match_object_attributes (session, GPOINTER_TO_UINT (l->data), template, count))
830         sess->matches = g_list_prepend (sess->matches, l->data);
831   }
832
833   g_list_free (objects);
834   return CKR_OK;
835 }
836
837 CK_RV
838 mock_C_FindObjects (CK_SESSION_HANDLE session,
839                     CK_OBJECT_HANDLE_PTR object,
840                     CK_ULONG max_object_count,
841                     CK_ULONG_PTR object_count)
842 {
843   Session *sess;
844
845   g_return_val_if_fail (object, CKR_ARGUMENTS_BAD);
846   g_return_val_if_fail (object_count, CKR_ARGUMENTS_BAD);
847   g_return_val_if_fail (max_object_count != 0, CKR_ARGUMENTS_BAD);
848
849   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
850   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
851   g_return_val_if_fail (sess->operation == OP_FIND, CKR_OPERATION_NOT_INITIALIZED);
852
853   *object_count = 0;
854   while (max_object_count > 0 && sess->matches)
855     {
856       *object = GPOINTER_TO_UINT (sess->matches->data);
857       ++object;
858       --max_object_count;
859       ++(*object_count);
860       sess->matches = g_list_remove (sess->matches, sess->matches->data);
861     }
862
863   return CKR_OK;
864 }
865
866 CK_RV
867 mock_C_FindObjectsFinal (CK_SESSION_HANDLE session)
868 {
869   Session *sess;
870
871   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
872   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
873   g_return_val_if_fail (sess->operation == OP_FIND, CKR_OPERATION_NOT_INITIALIZED);
874
875   sess->operation = 0;
876   g_list_free (sess->matches);
877   sess->matches = NULL;
878
879   return CKR_OK;
880 }
881
882 CK_RV
883 mock_no_mechanisms_C_EncryptInit (CK_SESSION_HANDLE session,
884                                   CK_MECHANISM_PTR mechanism,
885                                   CK_OBJECT_HANDLE key)
886 {
887   Session *sess;
888
889   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
890   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
891
892   return CKR_MECHANISM_INVALID;
893 }
894
895 CK_RV
896 mock_not_initialized_C_Encrypt (CK_SESSION_HANDLE session,
897                                 CK_BYTE_PTR data,
898                                 CK_ULONG data_len,
899                                 CK_BYTE_PTR encrypted_data,
900                                 CK_ULONG_PTR encrypted_data_len)
901 {
902   return CKR_OPERATION_NOT_INITIALIZED;
903 }
904
905 CK_RV
906 mock_unsupported_C_EncryptUpdate (CK_SESSION_HANDLE session,
907                                   CK_BYTE_PTR part,
908                                   CK_ULONG part_len,
909                                   CK_BYTE_PTR encrypted_part,
910                                   CK_ULONG_PTR encrypted_part_len)
911 {
912   return CKR_FUNCTION_NOT_SUPPORTED;
913 }
914
915 CK_RV
916 mock_unsupported_C_EncryptFinal (CK_SESSION_HANDLE session,
917                                  CK_BYTE_PTR last_encrypted_part,
918                                  CK_ULONG_PTR last_encrypted_part_len)
919 {
920   return CKR_FUNCTION_NOT_SUPPORTED;
921 }
922
923 CK_RV
924 mock_no_mechanisms_C_DecryptInit (CK_SESSION_HANDLE session,
925                                   CK_MECHANISM_PTR mechanism,
926                                   CK_OBJECT_HANDLE key)
927 {
928   Session *sess;
929
930   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
931   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
932
933   return CKR_MECHANISM_INVALID;
934 }
935
936 CK_RV
937 mock_not_initialized_C_Decrypt (CK_SESSION_HANDLE session,
938                                 CK_BYTE_PTR encrypted_data,
939                                 CK_ULONG encrypted_data_len,
940                                 CK_BYTE_PTR data,
941                                 CK_ULONG_PTR data_len)
942 {
943   return CKR_OPERATION_NOT_INITIALIZED;
944 }
945
946 CK_RV
947 mock_unsupported_C_DecryptUpdate (CK_SESSION_HANDLE session,
948                                   CK_BYTE_PTR encrypted_part,
949                                   CK_ULONG encrypted_key_len,
950                                   CK_BYTE_PTR part,
951                                   CK_ULONG_PTR part_len)
952 {
953   return CKR_FUNCTION_NOT_SUPPORTED;
954 }
955
956 CK_RV
957 mock_unsupported_C_DecryptFinal (CK_SESSION_HANDLE session,
958                                  CK_BYTE_PTR last_part,
959                                  CK_ULONG_PTR last_part_len)
960 {
961   return CKR_FUNCTION_NOT_SUPPORTED;
962 }
963
964 CK_RV
965 mock_unsupported_C_DigestInit (CK_SESSION_HANDLE session,
966                                CK_MECHANISM_PTR mechanism)
967 {
968   return CKR_FUNCTION_NOT_SUPPORTED;
969 }
970
971 CK_RV
972 mock_unsupported_C_Digest (CK_SESSION_HANDLE session,
973                            CK_BYTE_PTR data,
974                            CK_ULONG data_len,
975                            CK_BYTE_PTR digest,
976                            CK_ULONG_PTR digest_len)
977 {
978   return CKR_FUNCTION_NOT_SUPPORTED;
979 }
980
981 CK_RV
982 mock_unsupported_C_DigestUpdate (CK_SESSION_HANDLE session,
983                                  CK_BYTE_PTR part,
984                                  CK_ULONG part_len)
985 {
986   return CKR_FUNCTION_NOT_SUPPORTED;
987 }
988
989 CK_RV
990 mock_unsupported_C_DigestKey (CK_SESSION_HANDLE session,
991                               CK_OBJECT_HANDLE key)
992 {
993   return CKR_FUNCTION_NOT_SUPPORTED;
994 }
995
996 CK_RV
997 mock_unsupported_C_DigestFinal (CK_SESSION_HANDLE session,
998                                 CK_BYTE_PTR digest,
999                                 CK_ULONG_PTR digest_len)
1000 {
1001   return CKR_FUNCTION_NOT_SUPPORTED;
1002 }
1003
1004 CK_RV
1005 mock_no_mechanisms_C_SignInit (CK_SESSION_HANDLE session,
1006                                CK_MECHANISM_PTR mechanism,
1007                                CK_OBJECT_HANDLE key)
1008 {
1009   Session *sess;
1010
1011   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1012   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1013
1014   return CKR_MECHANISM_INVALID;
1015 }
1016
1017 CK_RV
1018 mock_not_initialized_C_Sign (CK_SESSION_HANDLE session,
1019                              CK_BYTE_PTR data,
1020                              CK_ULONG data_len,
1021                              CK_BYTE_PTR signature,
1022                              CK_ULONG_PTR signature_len)
1023 {
1024   return CKR_OPERATION_NOT_INITIALIZED;
1025 }
1026
1027 CK_RV
1028 mock_unsupported_C_SignUpdate (CK_SESSION_HANDLE session,
1029                                CK_BYTE_PTR part,
1030                                CK_ULONG part_len)
1031 {
1032   return CKR_FUNCTION_NOT_SUPPORTED;
1033 }
1034
1035 CK_RV
1036 mock_unsupported_C_SignFinal (CK_SESSION_HANDLE session,
1037                               CK_BYTE_PTR signature,
1038                               CK_ULONG_PTR signature_len)
1039 {
1040   return CKR_FUNCTION_NOT_SUPPORTED;
1041 }
1042
1043 CK_RV
1044 mock_unsupported_C_SignRecoverInit (CK_SESSION_HANDLE session,
1045                                     CK_MECHANISM_PTR mechanism,
1046                                     CK_OBJECT_HANDLE key)
1047 {
1048   return CKR_FUNCTION_NOT_SUPPORTED;
1049 }
1050
1051 CK_RV
1052 mock_unsupported_C_SignRecover (CK_SESSION_HANDLE session,
1053                                 CK_BYTE_PTR data,
1054                                 CK_ULONG data_len,
1055                                 CK_BYTE_PTR signature,
1056                                 CK_ULONG_PTR signature_len)
1057 {
1058   return CKR_FUNCTION_NOT_SUPPORTED;
1059 }
1060
1061 CK_RV
1062 mock_no_mechanisms_C_VerifyInit (CK_SESSION_HANDLE session,
1063                                  CK_MECHANISM_PTR mechanism,
1064                                  CK_OBJECT_HANDLE key)
1065 {
1066   Session *sess;
1067
1068   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1069   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1070
1071   return CKR_MECHANISM_INVALID;
1072 }
1073
1074 CK_RV
1075 mock_not_initialized_C_Verify (CK_SESSION_HANDLE session,
1076                                CK_BYTE_PTR data,
1077                                CK_ULONG data_len,
1078                                CK_BYTE_PTR signature,
1079                                CK_ULONG signature_len)
1080 {
1081   return CKR_OPERATION_NOT_INITIALIZED;
1082 }
1083
1084 CK_RV
1085 mock_unsupported_C_VerifyUpdate (CK_SESSION_HANDLE session,
1086                                  CK_BYTE_PTR part,
1087                                  CK_ULONG part_len)
1088 {
1089   return CKR_FUNCTION_NOT_SUPPORTED;
1090 }
1091
1092 CK_RV
1093 mock_unsupported_C_VerifyFinal (CK_SESSION_HANDLE session,
1094                                 CK_BYTE_PTR signature,
1095                                 CK_ULONG signature_len)
1096 {
1097   return CKR_FUNCTION_NOT_SUPPORTED;
1098 }
1099
1100 CK_RV
1101 mock_unsupported_C_VerifyRecoverInit (CK_SESSION_HANDLE session,
1102                                       CK_MECHANISM_PTR mechanism,
1103                                       CK_OBJECT_HANDLE key)
1104 {
1105   return CKR_FUNCTION_NOT_SUPPORTED;
1106 }
1107
1108 CK_RV
1109 mock_unsupported_C_VerifyRecover (CK_SESSION_HANDLE session,
1110                                   CK_BYTE_PTR signature,
1111                                   CK_ULONG signature_len,
1112                                   CK_BYTE_PTR data,
1113                                   CK_ULONG_PTR data_len)
1114 {
1115   return CKR_FUNCTION_NOT_SUPPORTED;
1116 }
1117
1118 CK_RV
1119 mock_unsupported_C_DigestEncryptUpdate (CK_SESSION_HANDLE session,
1120                                         CK_BYTE_PTR part,
1121                                         CK_ULONG part_len,
1122                                         CK_BYTE_PTR encrypted_part,
1123                                         CK_ULONG_PTR encrypted_key_len)
1124 {
1125   return CKR_FUNCTION_NOT_SUPPORTED;
1126 }
1127
1128 CK_RV
1129 mock_unsupported_C_DecryptDigestUpdate (CK_SESSION_HANDLE session,
1130                                         CK_BYTE_PTR encrypted_part,
1131                                         CK_ULONG encrypted_key_len,
1132                                         CK_BYTE_PTR part,
1133                                         CK_ULONG_PTR part_len)
1134 {
1135   return CKR_FUNCTION_NOT_SUPPORTED;
1136 }
1137
1138 CK_RV
1139 mock_unsupported_C_SignEncryptUpdate (CK_SESSION_HANDLE session,
1140                                       CK_BYTE_PTR part,
1141                                       CK_ULONG part_len,
1142                                       CK_BYTE_PTR encrypted_part,
1143                                       CK_ULONG_PTR encrypted_key_len)
1144 {
1145   return CKR_FUNCTION_NOT_SUPPORTED;
1146 }
1147
1148 CK_RV
1149 mock_unsupported_C_DecryptVerifyUpdate (CK_SESSION_HANDLE session,
1150                                         CK_BYTE_PTR encrypted_part,
1151                                         CK_ULONG encrypted_key_len,
1152                                         CK_BYTE_PTR part,
1153                                         CK_ULONG_PTR part_len)
1154 {
1155   return CKR_FUNCTION_NOT_SUPPORTED;
1156 }
1157
1158 CK_RV
1159 mock_unsupported_C_GenerateKey (CK_SESSION_HANDLE session,
1160                                 CK_MECHANISM_PTR mechanism,
1161                                 CK_ATTRIBUTE_PTR template,
1162                                 CK_ULONG count,
1163                                 CK_OBJECT_HANDLE_PTR key)
1164 {
1165   return CKR_FUNCTION_NOT_SUPPORTED;
1166 }
1167
1168 CK_RV
1169 mock_no_mechanisms_C_GenerateKeyPair (CK_SESSION_HANDLE session,
1170                                       CK_MECHANISM_PTR mechanism,
1171                                       CK_ATTRIBUTE_PTR public_key_template,
1172                                       CK_ULONG public_key_attribute_count,
1173                                       CK_ATTRIBUTE_PTR private_key_template,
1174                                       CK_ULONG private_key_attribute_count,
1175                                       CK_OBJECT_HANDLE_PTR public_key,
1176                                       CK_OBJECT_HANDLE_PTR private_key)
1177 {
1178   Session *sess;
1179
1180   g_return_val_if_fail (mechanism, CKR_MECHANISM_INVALID);
1181   g_return_val_if_fail (public_key_template, CKR_TEMPLATE_INCOMPLETE);
1182   g_return_val_if_fail (public_key_attribute_count, CKR_TEMPLATE_INCOMPLETE);
1183   g_return_val_if_fail (private_key_template, CKR_TEMPLATE_INCOMPLETE);
1184   g_return_val_if_fail (private_key_attribute_count, CKR_TEMPLATE_INCOMPLETE);
1185   g_return_val_if_fail (public_key, CKR_ARGUMENTS_BAD);
1186   g_return_val_if_fail (private_key, CKR_ARGUMENTS_BAD);
1187
1188   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1189   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1190
1191   return CKR_MECHANISM_INVALID;
1192 }
1193
1194 CK_RV
1195 mock_no_mechanisms_C_WrapKey (CK_SESSION_HANDLE session,
1196                               CK_MECHANISM_PTR mechanism,
1197                               CK_OBJECT_HANDLE wrapping_key,
1198                               CK_OBJECT_HANDLE key,
1199                               CK_BYTE_PTR wrapped_key,
1200                               CK_ULONG_PTR wrapped_key_len)
1201 {
1202   Session *sess;
1203
1204   g_return_val_if_fail (mechanism, CKR_MECHANISM_INVALID);
1205   g_return_val_if_fail (wrapping_key, CKR_OBJECT_HANDLE_INVALID);
1206   g_return_val_if_fail (key, CKR_OBJECT_HANDLE_INVALID);
1207   g_return_val_if_fail (wrapped_key_len, CKR_WRAPPED_KEY_LEN_RANGE);
1208
1209   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1210   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1211
1212   return CKR_MECHANISM_INVALID;
1213 }
1214
1215 CK_RV
1216 mock_no_mechanisms_C_UnwrapKey (CK_SESSION_HANDLE session,
1217                                 CK_MECHANISM_PTR mechanism,
1218                                 CK_OBJECT_HANDLE unwrapping_key,
1219                                 CK_BYTE_PTR wrapped_key,
1220                                 CK_ULONG wrapped_key_len,
1221                                 CK_ATTRIBUTE_PTR template,
1222                                 CK_ULONG count,
1223                                 CK_OBJECT_HANDLE_PTR key)
1224 {
1225   Session *sess;
1226
1227   g_return_val_if_fail (mechanism, CKR_MECHANISM_INVALID);
1228   g_return_val_if_fail (unwrapping_key, CKR_WRAPPING_KEY_HANDLE_INVALID);
1229   g_return_val_if_fail (wrapped_key, CKR_WRAPPED_KEY_INVALID);
1230   g_return_val_if_fail (wrapped_key_len, CKR_WRAPPED_KEY_LEN_RANGE);
1231   g_return_val_if_fail (key, CKR_ARGUMENTS_BAD);
1232   g_return_val_if_fail (template, CKR_TEMPLATE_INCOMPLETE);
1233   g_return_val_if_fail (count, CKR_TEMPLATE_INCONSISTENT);
1234
1235   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1236   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1237
1238   return CKR_MECHANISM_INVALID;
1239 }
1240
1241 CK_RV
1242 mock_no_mechanisms_C_DeriveKey (CK_SESSION_HANDLE session,
1243                                 CK_MECHANISM_PTR mechanism,
1244                                 CK_OBJECT_HANDLE base_key,
1245                                 CK_ATTRIBUTE_PTR template,
1246                                 CK_ULONG count,
1247                                 CK_OBJECT_HANDLE_PTR key)
1248 {
1249   Session *sess;
1250
1251   g_return_val_if_fail (mechanism, CKR_MECHANISM_INVALID);
1252   g_return_val_if_fail (count, CKR_TEMPLATE_INCOMPLETE);
1253   g_return_val_if_fail (template, CKR_TEMPLATE_INCOMPLETE);
1254   g_return_val_if_fail (key, CKR_ARGUMENTS_BAD);
1255
1256   sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1257   g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1258
1259   return CKR_MECHANISM_INVALID;
1260 }
1261
1262 CK_RV
1263 mock_unsupported_C_SeedRandom (CK_SESSION_HANDLE session,
1264                                CK_BYTE_PTR pSeed,
1265                                CK_ULONG seed_len)
1266 {
1267   return CKR_FUNCTION_NOT_SUPPORTED;
1268 }
1269
1270 CK_RV
1271 mock_unsupported_C_GenerateRandom (CK_SESSION_HANDLE session,
1272                                    CK_BYTE_PTR random_data,
1273                                    CK_ULONG random_len)
1274 {
1275   return CKR_FUNCTION_NOT_SUPPORTED;
1276 }
1277
1278 CK_FUNCTION_LIST mock_default_functions = {
1279   { 2, 11 },    /* version */
1280   mock_C_Initialize,
1281   mock_C_Finalize,
1282   mock_C_GetInfo,
1283   mock_C_GetFunctionList,
1284   mock_C_GetSlotList,
1285   mock_C_GetSlotInfo,
1286   mock_C_GetTokenInfo,
1287   mock_C_GetMechanismList,
1288   mock_C_GetMechanismInfo,
1289   mock_unsupported_C_InitToken,
1290   mock_unsupported_C_InitPIN,
1291   mock_unsupported_C_SetPIN,
1292   mock_C_OpenSession,
1293   mock_C_CloseSession,
1294   mock_C_CloseAllSessions,
1295   mock_C_GetSessionInfo,
1296   mock_unsupported_C_GetOperationState,
1297   mock_unsupported_C_SetOperationState,
1298   mock_unsupported_C_Login,
1299   mock_unsupported_C_Logout,
1300   mock_readonly_C_CreateObject,
1301   mock_unsupported_C_CopyObject,
1302   mock_readonly_C_DestroyObject,
1303   mock_unsupported_C_GetObjectSize,
1304   mock_C_GetAttributeValue,
1305   mock_readonly_C_SetAttributeValue,
1306   mock_C_FindObjectsInit,
1307   mock_C_FindObjects,
1308   mock_C_FindObjectsFinal,
1309   mock_no_mechanisms_C_EncryptInit,
1310   mock_not_initialized_C_Encrypt,
1311   mock_unsupported_C_EncryptUpdate,
1312   mock_unsupported_C_EncryptFinal,
1313   mock_no_mechanisms_C_DecryptInit,
1314   mock_not_initialized_C_Decrypt,
1315   mock_unsupported_C_DecryptUpdate,
1316   mock_unsupported_C_DecryptFinal,
1317   mock_unsupported_C_DigestInit,
1318   mock_unsupported_C_Digest,
1319   mock_unsupported_C_DigestUpdate,
1320   mock_unsupported_C_DigestKey,
1321   mock_unsupported_C_DigestFinal,
1322   mock_no_mechanisms_C_SignInit,
1323   mock_not_initialized_C_Sign,
1324   mock_unsupported_C_SignUpdate,
1325   mock_unsupported_C_SignFinal,
1326   mock_unsupported_C_SignRecoverInit,
1327   mock_unsupported_C_SignRecover,
1328   mock_no_mechanisms_C_VerifyInit,
1329   mock_not_initialized_C_Verify,
1330   mock_unsupported_C_VerifyUpdate,
1331   mock_unsupported_C_VerifyFinal,
1332   mock_unsupported_C_VerifyRecoverInit,
1333   mock_unsupported_C_VerifyRecover,
1334   mock_unsupported_C_DigestEncryptUpdate,
1335   mock_unsupported_C_DecryptDigestUpdate,
1336   mock_unsupported_C_SignEncryptUpdate,
1337   mock_unsupported_C_DecryptVerifyUpdate,
1338   mock_unsupported_C_GenerateKey,
1339   mock_no_mechanisms_C_GenerateKeyPair,
1340   mock_no_mechanisms_C_WrapKey,
1341   mock_no_mechanisms_C_UnwrapKey,
1342   mock_no_mechanisms_C_DeriveKey,
1343   mock_unsupported_C_SeedRandom,
1344   mock_unsupported_C_GenerateRandom,
1345   mock_C_GetFunctionStatus,
1346   mock_C_CancelFunction,
1347   mock_unsupported_C_WaitForSlotEvent
1348 };