LCOV - code coverage report
Current view: top level - pkcs11/gkm - gkm-mock.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 56.9 % 705 401
Test Date: 2024-04-08 13:24:42 Functions: 44.0 % 84 37

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

Generated by: LCOV version 2.0-1