LCOV - code coverage report
Current view: top level - pkcs11/wrap-layer - gkm-wrap-layer.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 49.0 % 604 296
Test Date: 2024-04-08 13:24:42 Functions: 42.7 % 89 38

            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-wrap-layer.h"
      24              : #include "gkm-wrap-prompt.h"
      25              : 
      26              : #include "pkcs11/pkcs11.h"
      27              : #include "pkcs11/pkcs11i.h"
      28              : 
      29              : #include <glib.h>
      30              : 
      31              : #include <string.h>
      32              : 
      33              : typedef struct _Mapping {
      34              :         CK_SLOT_ID wrap_slot;
      35              :         CK_SLOT_ID real_slot;
      36              :         CK_FUNCTION_LIST_PTR funcs;
      37              : } Mapping;
      38              : 
      39              : typedef struct _Session {
      40              :         gint wrap_session;
      41              :         CK_SESSION_HANDLE real_session;
      42              :         CK_G_APPLICATION_ID app_id;
      43              :         CK_SLOT_ID wrap_slot;
      44              :         CK_OBJECT_HANDLE specific;
      45              : } Session;
      46              : 
      47              : G_LOCK_DEFINE_STATIC (wrap_layer);
      48              : 
      49              : static GList *wrap_modules = NULL;
      50              : static Mapping *wrap_mappings = NULL;
      51              : static guint n_wrap_mappings = 0;
      52              : static GHashTable *wrap_sessions = NULL;
      53              : static gint last_handle = 16;
      54              : 
      55              : #define MANUFACTURER_ID         "GNOME Keyring                   "
      56              : #define LIBRARY_DESCRIPTION     "GNOME Keyring Daemon Core       "
      57              : #define LIBRARY_VERSION_MAJOR   1
      58              : #define LIBRARY_VERSION_MINOR   1
      59              : 
      60              : /* Start wrap slots slightly higher for testing */
      61              : #define PLEX_MAPPING_OFFSET 0x10
      62              : 
      63              : static CK_RV
      64         2311 : map_slot_unlocked (CK_SLOT_ID slot, Mapping *mapping)
      65              : {
      66         2311 :         if (!wrap_mappings)
      67            0 :                 return CKR_CRYPTOKI_NOT_INITIALIZED;
      68              : 
      69         2311 :         if (slot < PLEX_MAPPING_OFFSET)
      70            0 :                 return CKR_SLOT_ID_INVALID;
      71         2311 :         slot -= PLEX_MAPPING_OFFSET;
      72              : 
      73         2311 :         g_assert (mapping);
      74              : 
      75         2311 :         if (slot > n_wrap_mappings) {
      76            0 :                 return CKR_SLOT_ID_INVALID;
      77              :         } else {
      78         2311 :                 memcpy (mapping, &wrap_mappings[slot], sizeof (Mapping));
      79         2311 :                 return CKR_OK;
      80              :         }
      81              : }
      82              : 
      83              : static CK_RV
      84          255 : map_slot_to_real (CK_SLOT_ID_PTR slot, Mapping *mapping)
      85              : {
      86              :         CK_RV rv;
      87              : 
      88          255 :         g_assert (mapping);
      89              : 
      90          255 :         G_LOCK (wrap_layer);
      91              : 
      92          255 :                 rv = map_slot_unlocked (*slot, mapping);
      93          255 :                 if (rv == CKR_OK)
      94          255 :                         *slot = mapping->real_slot;
      95              : 
      96          255 :         G_UNLOCK (wrap_layer);
      97              : 
      98          255 :         return rv;
      99              : }
     100              : 
     101              : static CK_RV
     102         2056 : map_session_to_real (CK_SESSION_HANDLE_PTR handle, Mapping *mapping, Session *session)
     103              : {
     104         2056 :         CK_RV rv = CKR_OK;
     105              :         Session *sess;
     106              : 
     107         2056 :         g_assert (handle);
     108         2056 :         g_assert (mapping);
     109              : 
     110         2056 :         G_LOCK (wrap_layer);
     111              : 
     112         2056 :                 if (!wrap_sessions) {
     113            0 :                         rv = CKR_CRYPTOKI_NOT_INITIALIZED;
     114              :                 } else {
     115         2056 :                         sess = g_hash_table_lookup (wrap_sessions, GINT_TO_POINTER ((gint)*handle));
     116         2056 :                         if (sess != NULL) {
     117         2056 :                                 *handle = sess->real_session;
     118         2056 :                                 rv = map_slot_unlocked (sess->wrap_slot, mapping);
     119         2056 :                                 if (session != NULL)
     120            0 :                                         memcpy (session, sess, sizeof (Session));
     121              :                         } else {
     122            0 :                                 rv = CKR_SESSION_HANDLE_INVALID;
     123              :                         }
     124              :                 }
     125              : 
     126         2056 :         G_UNLOCK (wrap_layer);
     127              : 
     128         2056 :         return rv;
     129              : }
     130              : 
     131              : static void
     132           59 : lookup_session_specific (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE_PTR key)
     133              : {
     134              :         Session *sess;
     135              : 
     136           59 :         g_assert (key);
     137           59 :         *key = 0;
     138              : 
     139           59 :         G_LOCK (wrap_layer);
     140              : 
     141           59 :                 if (wrap_sessions) {
     142           59 :                         sess = g_hash_table_lookup (wrap_sessions, GINT_TO_POINTER ((gint)handle));
     143           59 :                         if (sess == NULL)
     144            0 :                                 g_warning ("sessions out of sync with lower layer");
     145              :                         else
     146           59 :                                 *key = sess->specific;
     147              :                 }
     148              : 
     149           59 :         G_UNLOCK (wrap_layer);
     150           59 : }
     151              : 
     152              : static void
     153            8 : store_session_specific (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE key)
     154              : {
     155              :         Session *sess;
     156              : 
     157            8 :         G_LOCK (wrap_layer);
     158              : 
     159            8 :                 if (wrap_sessions) {
     160            8 :                         sess = g_hash_table_lookup (wrap_sessions, GINT_TO_POINTER ((gint)handle));
     161            8 :                         if (sess == NULL)
     162            0 :                                 g_warning ("sessions out of sync with lower layer");
     163              :                         else
     164            8 :                                 sess->specific = key;
     165              :                 }
     166              : 
     167            8 :         G_UNLOCK (wrap_layer);
     168            8 : }
     169              : 
     170              : static CK_RV
     171           57 : wrap_C_Initialize (CK_VOID_PTR init_args)
     172              : {
     173              :         CK_FUNCTION_LIST_PTR funcs;
     174           57 :         GArray *mappings = NULL;
     175              :         CK_SLOT_ID_PTR slots;
     176              :         Mapping mapping;
     177              :         CK_ULONG i, count;
     178           57 :         CK_RV rv = CKR_OK;
     179              :         GList *l;
     180              : 
     181           57 :         mappings = g_array_new (FALSE, TRUE, sizeof (Mapping));
     182              : 
     183           57 :         G_LOCK (wrap_layer);
     184              : 
     185           57 :                 if (wrap_mappings)
     186            0 :                         rv = CKR_CRYPTOKI_ALREADY_INITIALIZED;
     187              : 
     188          195 :                 for (l = wrap_modules; rv == CKR_OK && l != NULL; l = g_list_next (l)) {
     189          138 :                         funcs = l->data;
     190              : 
     191              :                         /* Initialize each module */
     192          138 :                         rv = (funcs->C_Initialize) (init_args);
     193          138 :                         if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED)
     194            0 :                                 rv = CKR_OK;
     195          138 :                         if (rv != CKR_OK)
     196            0 :                                 break;
     197              : 
     198              :                         /* And then ask it for its slots */
     199          138 :                         rv = (funcs->C_GetSlotList) (FALSE, NULL, &count);
     200          138 :                         if (rv != CKR_OK)
     201            0 :                                 break;
     202          138 :                         if (!count)
     203            0 :                                 continue;
     204          138 :                         slots = g_new0 (CK_SLOT_ID, count);
     205          138 :                         rv = (funcs->C_GetSlotList) (FALSE, slots, &count);
     206          138 :                         if (rv != CKR_OK) {
     207            0 :                                  g_free (slots);
     208            0 :                                  break;
     209              :                         }
     210              : 
     211              :                         /* And now add a mapping for each of those slots */
     212          306 :                         for (i = 0; i < count; ++i) {
     213          168 :                                 memset (&mapping, 0, sizeof (mapping));
     214          168 :                                 mapping.wrap_slot = mappings->len + PLEX_MAPPING_OFFSET;
     215          168 :                                 mapping.real_slot = slots[i];
     216          168 :                                 mapping.funcs = funcs;
     217          168 :                                 g_array_append_val (mappings, mapping);
     218              :                         }
     219              : 
     220          138 :                         g_free (slots);
     221              :                 }
     222              : 
     223              :                 /* If failed, then finalize all the ones that succeeded */
     224           57 :                 if (rv != CKR_OK && l != NULL) {
     225            0 :                         for (l = g_list_previous (l); l; l = g_list_previous (l)) {
     226            0 :                                 funcs = l->data;
     227            0 :                                 (funcs->C_Finalize) (NULL);
     228              :                         }
     229              :                 }
     230              : 
     231              :                 /* If succeeded then swap in mappings */
     232           57 :                 if (rv == CKR_OK) {
     233           57 :                         g_assert (!wrap_mappings);
     234           57 :                         n_wrap_mappings = mappings->len;
     235           57 :                         wrap_mappings = (Mapping*)g_array_free (mappings, FALSE);
     236           57 :                         mappings = NULL;
     237           57 :                         wrap_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
     238              :                 }
     239              : 
     240           57 :         G_UNLOCK (wrap_layer);
     241              : 
     242              :         /* If failed or somehow unused then free */
     243           57 :         if (mappings)
     244            0 :                 g_array_free (mappings, TRUE);
     245              : 
     246           57 :         return rv;
     247              : }
     248              : 
     249              : static CK_RV
     250           57 : wrap_C_Finalize (CK_VOID_PTR reserved)
     251              : {
     252              :         CK_FUNCTION_LIST_PTR funcs;
     253              :         GList *l;
     254              : 
     255           57 :         G_LOCK (wrap_layer);
     256              : 
     257          195 :                 for (l = wrap_modules; l != NULL; l = g_list_next (l)) {
     258          138 :                         funcs = l->data;
     259          138 :                         (funcs->C_Finalize) (NULL);
     260              :                 }
     261           57 :                 g_free (wrap_mappings);
     262           57 :                 wrap_mappings = NULL;
     263              : 
     264           57 :                 g_hash_table_destroy (wrap_sessions);
     265           57 :                 wrap_sessions = NULL;
     266              : 
     267           57 :         G_UNLOCK (wrap_layer);
     268              : 
     269           57 :         return CKR_OK;
     270              : }
     271              : 
     272              : static CK_RV
     273           29 : wrap_C_GetInfo (CK_INFO_PTR info)
     274              : {
     275           29 :         if (info == NULL)
     276            0 :                 return CKR_ARGUMENTS_BAD;
     277              : 
     278           29 :         info->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR;
     279           29 :         info->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR;
     280           29 :         info->libraryVersion.major = LIBRARY_VERSION_MAJOR;
     281           29 :         info->libraryVersion.minor = LIBRARY_VERSION_MINOR;
     282           29 :         info->flags = 0;
     283           29 :         memcpy ((char*)info->manufacturerID, MANUFACTURER_ID, 32);
     284           29 :         memcpy ((char*)info->libraryDescription, LIBRARY_DESCRIPTION, 32);
     285           29 :         return CKR_OK;
     286              : }
     287              : 
     288              : static CK_RV
     289            0 : wrap_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
     290              : {
     291            0 :         if (!list)
     292            0 :                 return CKR_ARGUMENTS_BAD;
     293            0 :         *list = gkm_wrap_layer_get_functions_no_prompts ();
     294            0 :         return CKR_OK;
     295              : }
     296              : 
     297              : static CK_RV
     298            0 : auth_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
     299              : {
     300            0 :         if (!list)
     301            0 :                 return CKR_ARGUMENTS_BAD;
     302            0 :         *list = gkm_wrap_layer_get_functions ();
     303            0 :         return CKR_OK;
     304              : }
     305              : 
     306              : static CK_RV
     307          202 : wrap_C_GetSlotList (CK_BBOOL token_present, CK_SLOT_ID_PTR slot_list, CK_ULONG_PTR count)
     308              : {
     309              :         CK_SLOT_INFO info;
     310              :         Mapping *mapping;
     311              :         CK_ULONG index;
     312              :         CK_RV rv;
     313              : 
     314              :         guint i;
     315              : 
     316          202 :         if (!count)
     317            0 :                 return CKR_ARGUMENTS_BAD;
     318              : 
     319          202 :         G_LOCK (wrap_layer);
     320              : 
     321          202 :                 rv = CKR_OK;
     322          202 :                 index = 0;
     323              : 
     324              :                 /* Go through and build up a map */
     325          738 :                 for (i = 0; i < n_wrap_mappings; ++i) {
     326          536 :                         mapping = &wrap_mappings[i];
     327              : 
     328              :                         /* Skip ones without a token if requested */
     329          536 :                         if (token_present) {
     330          536 :                                 rv = (mapping->funcs->C_GetSlotInfo) (mapping->real_slot, &info);
     331          536 :                                 if (rv != CKR_OK)
     332            0 :                                         break;
     333          536 :                                 if (!(info.flags & CKF_TOKEN_PRESENT))
     334          136 :                                         continue;
     335              :                         }
     336              : 
     337              :                         /* Fill in the slot if we can */
     338          400 :                         if (slot_list && *count > index)
     339          209 :                                 slot_list[index] = mapping->wrap_slot;
     340              : 
     341          400 :                         ++index;
     342              :                 }
     343              : 
     344          202 :                 if (slot_list && *count < index)
     345            0 :                         rv = CKR_BUFFER_TOO_SMALL;
     346              : 
     347          202 :                 *count = index;
     348              : 
     349          202 :         G_UNLOCK (wrap_layer);
     350              : 
     351          202 :         return rv;
     352              : }
     353              : 
     354              : static CK_RV
     355            0 : wrap_C_GetSlotInfo (CK_SLOT_ID id, CK_SLOT_INFO_PTR info)
     356              : {
     357              :         Mapping map;
     358              :         CK_RV rv;
     359              : 
     360            0 :         rv = map_slot_to_real (&id, &map);
     361            0 :         if (rv != CKR_OK)
     362            0 :                 return rv;
     363            0 :         return (map.funcs->C_GetSlotInfo) (id, info);
     364              : }
     365              : 
     366              : static CK_RV
     367          115 : wrap_C_GetTokenInfo (CK_SLOT_ID id, CK_TOKEN_INFO_PTR info)
     368              : {
     369              :         Mapping map;
     370              :         CK_RV rv;
     371              : 
     372          115 :         rv = map_slot_to_real (&id, &map);
     373          115 :         if (rv != CKR_OK)
     374            0 :                 return rv;
     375          115 :         return (map.funcs->C_GetTokenInfo) (id, info);
     376              : }
     377              : 
     378              : static CK_RV
     379           91 : auth_C_GetTokenInfo (CK_SLOT_ID id, CK_TOKEN_INFO_PTR info)
     380              : {
     381           91 :         CK_RV rv = wrap_C_GetTokenInfo (id, info);
     382           91 :         if (rv == CKR_OK)
     383           91 :                 info->flags |= CKF_PROTECTED_AUTHENTICATION_PATH;
     384           91 :         return rv;
     385              : }
     386              : 
     387              : static CK_RV
     388            0 : wrap_C_GetMechanismList (CK_SLOT_ID id, CK_MECHANISM_TYPE_PTR mechanism_list, CK_ULONG_PTR count)
     389              : {
     390              :         Mapping map;
     391              :         CK_RV rv;
     392              : 
     393            0 :         rv = map_slot_to_real (&id, &map);
     394            0 :         if (rv != CKR_OK)
     395            0 :                 return rv;
     396            0 :         return (map.funcs->C_GetMechanismList) (id, mechanism_list, count);
     397              : }
     398              : 
     399              : static CK_RV
     400            0 : wrap_C_GetMechanismInfo (CK_SLOT_ID id, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR info)
     401              : {
     402              :         Mapping map;
     403              :         CK_RV rv;
     404              : 
     405            0 :         rv = map_slot_to_real (&id, &map);
     406            0 :         if (rv != CKR_OK)
     407            0 :                 return rv;
     408            0 :         return (map.funcs->C_GetMechanismInfo) (id, type, info);
     409              : }
     410              : 
     411              : static CK_RV
     412            0 : wrap_C_InitToken (CK_SLOT_ID id, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len, CK_UTF8CHAR_PTR label)
     413              : {
     414              :         Mapping map;
     415              :         CK_RV rv;
     416              : 
     417            0 :         rv = map_slot_to_real (&id, &map);
     418            0 :         if (rv != CKR_OK)
     419            0 :                 return rv;
     420            0 :         return (map.funcs->C_InitToken) (id, pin, pin_len, label);
     421              : }
     422              : 
     423              : static CK_RV
     424            0 : wrap_C_WaitForSlotEvent (CK_FLAGS flags, CK_SLOT_ID_PTR slot, CK_VOID_PTR reserved)
     425              : {
     426              :         /* TODO: We could implement this by polling, esp. the nonblock case. */
     427            0 :         return CKR_NO_EVENT;
     428              : }
     429              : 
     430              : static CK_RV
     431          140 : wrap_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data, CK_NOTIFY callback, CK_SESSION_HANDLE_PTR handle)
     432              : {
     433              :         Session *sess;
     434              :         Mapping map;
     435              :         CK_RV rv;
     436              : 
     437          140 :         if (handle == NULL)
     438            0 :                 return CKR_ARGUMENTS_BAD;
     439              : 
     440          140 :         rv = map_slot_to_real (&id, &map);
     441          140 :         if (rv != CKR_OK)
     442            0 :                 return rv;
     443              : 
     444          140 :         rv = (map.funcs->C_OpenSession) (id, flags, user_data, callback, handle);
     445              : 
     446          140 :         if (rv == CKR_OK) {
     447          139 :                 G_LOCK (wrap_layer);
     448              : 
     449          139 :                         sess = g_new (Session, 1);
     450          139 :                         if (flags & CKF_G_APPLICATION_SESSION)
     451           16 :                                 sess->app_id = ((CK_G_APPLICATION_PTR)user_data)->applicationId;
     452          139 :                         sess->wrap_slot = map.wrap_slot;
     453          139 :                         sess->real_session = *handle;
     454          139 :                         sess->wrap_session = ++last_handle; /* TODO: Handle wrapping, and then collisions */
     455          139 :                         g_hash_table_replace (wrap_sessions, GINT_TO_POINTER (sess->wrap_session), sess);
     456              : 
     457          139 :                         *handle = (CK_ULONG)sess->wrap_session;
     458              : 
     459          139 :                 G_UNLOCK (wrap_layer);
     460              :         }
     461              : 
     462          140 :         return rv;
     463              : }
     464              : 
     465              : static CK_RV
     466          136 : wrap_C_CloseSession (CK_SESSION_HANDLE handle)
     467              : {
     468          136 :         gint key = (gint)handle;
     469              :         Mapping map;
     470              :         CK_RV rv;
     471              : 
     472          136 :         rv = map_session_to_real (&handle, &map, NULL);
     473          136 :         if (rv != CKR_OK)
     474            0 :                 return rv;
     475          136 :         rv = (map.funcs->C_CloseSession) (handle);
     476              : 
     477          136 :         if (rv == CKR_OK) {
     478          136 :                 G_LOCK (wrap_layer);
     479              : 
     480          136 :                         g_hash_table_remove (wrap_sessions, GINT_TO_POINTER (key));
     481              : 
     482          136 :                 G_UNLOCK (wrap_layer);
     483              :         }
     484              : 
     485          136 :         return rv;
     486              : }
     487              : 
     488              : static CK_RV
     489            0 : wrap_C_CloseAllSessions (CK_SLOT_ID id)
     490              : {
     491              :         GHashTableIter iter;
     492              :         CK_SESSION_HANDLE handle;
     493              :         gpointer key, value;
     494              :         Session *sess;
     495              :         GArray *to_close;
     496              :         gint i;
     497              : 
     498            0 :         to_close = g_array_new (FALSE, FALSE, sizeof (CK_SESSION_HANDLE));
     499              : 
     500            0 :         G_LOCK (wrap_layer);
     501              : 
     502            0 :                 g_hash_table_iter_init (&iter, wrap_sessions);
     503            0 :                 while (g_hash_table_iter_next (&iter, &key, &value)) {
     504            0 :                         sess = value;
     505            0 :                         if ((sess->app_id | sess->wrap_slot) == id) {
     506            0 :                                 handle = (CK_SESSION_HANDLE)sess->wrap_session;
     507            0 :                                 g_array_append_val (to_close, handle);
     508              :                         }
     509              :                 }
     510              : 
     511            0 :         G_UNLOCK (wrap_layer);
     512              : 
     513            0 :         for (i = 0; i < to_close->len; ++i)
     514            0 :                 wrap_C_CloseSession (g_array_index (to_close, CK_SESSION_HANDLE, i));
     515              : 
     516            0 :         g_array_free (to_close, TRUE);
     517            0 :         return CKR_OK;
     518              : }
     519              : 
     520              : static CK_RV
     521            0 : wrap_C_GetFunctionStatus (CK_SESSION_HANDLE handle)
     522              : {
     523              :         Mapping map;
     524              :         CK_RV rv;
     525              : 
     526            0 :         rv = map_session_to_real (&handle, &map, NULL);
     527            0 :         if (rv != CKR_OK)
     528            0 :                 return rv;
     529            0 :         return (map.funcs->C_GetFunctionStatus) (handle);
     530              : }
     531              : 
     532              : static CK_RV
     533            0 : wrap_C_CancelFunction (CK_SESSION_HANDLE handle)
     534              : {
     535              :         Mapping map;
     536              :         CK_RV rv;
     537              : 
     538            0 :         rv = map_session_to_real (&handle, &map, NULL);
     539            0 :         if (rv != CKR_OK)
     540            0 :                 return rv;
     541            0 :         return (map.funcs->C_CancelFunction) (handle);
     542              : }
     543              : 
     544              : static CK_RV
     545          128 : wrap_C_GetSessionInfo (CK_SESSION_HANDLE handle, CK_SESSION_INFO_PTR info)
     546              : {
     547              :         Mapping map;
     548              :         CK_RV rv;
     549              : 
     550          128 :         if (info == NULL)
     551            0 :                 return CKR_ARGUMENTS_BAD;
     552              : 
     553          128 :         rv = map_session_to_real (&handle, &map, NULL);
     554          128 :         if (rv != CKR_OK)
     555            0 :                 return rv;
     556              : 
     557          128 :         rv = (map.funcs->C_GetSessionInfo) (handle, info);
     558          128 :         if (rv == CKR_OK)
     559          127 :                 info->slotID = map.wrap_slot;
     560              : 
     561          128 :         return rv;
     562              : }
     563              : 
     564              : static CK_RV
     565            5 : wrap_C_InitPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
     566              : {
     567              :         Mapping map;
     568              :         CK_RV rv;
     569              : 
     570            5 :         rv = map_session_to_real (&handle, &map, NULL);
     571            5 :         if (rv != CKR_OK)
     572            0 :                 return rv;
     573              : 
     574            5 :         return (map.funcs->C_InitPIN) (handle, pin, pin_len);
     575              : }
     576              : 
     577              : static CK_RV
     578            1 : auth_C_InitPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
     579              : {
     580              :         GkmWrapPrompt *prompt;
     581            1 :         CK_RV rv = CKR_OK;
     582              : 
     583            1 :         prompt = gkm_wrap_prompt_for_init_pin (gkm_wrap_layer_get_functions_no_prompts(),
     584              :                                                handle, pin, pin_len);
     585              : 
     586              :         for (;;) {
     587            1 :                 if (prompt && !gkm_wrap_prompt_do_init_pin (prompt, rv, &pin, &pin_len))
     588            0 :                         break;
     589              : 
     590            1 :                 rv = wrap_C_InitPIN (handle, pin, pin_len);
     591              : 
     592            1 :                 if (!prompt || rv != CKR_PIN_INVALID || rv != CKR_PIN_LEN_RANGE)
     593              :                         break;
     594              :         }
     595              : 
     596            1 :         if (prompt) {
     597            1 :                 gkm_wrap_prompt_done_init_pin (prompt, rv);
     598            1 :                 g_object_unref (prompt);
     599              :         }
     600              : 
     601            1 :         return rv;
     602              : }
     603              : 
     604              : static CK_RV
     605            1 : wrap_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR old_pin, CK_ULONG old_pin_len,
     606              :                CK_UTF8CHAR_PTR new_pin, CK_ULONG new_pin_len)
     607              : {
     608              :         Mapping map;
     609              :         CK_RV rv;
     610              : 
     611            1 :         rv = map_session_to_real (&handle, &map, NULL);
     612            1 :         if (rv != CKR_OK)
     613            0 :                 return rv;
     614              : 
     615            1 :         return (map.funcs->C_SetPIN) (handle, old_pin, old_pin_len, new_pin, new_pin_len);
     616              : }
     617              : 
     618              : static CK_RV
     619            1 : auth_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR old_pin, CK_ULONG old_pin_len,
     620              :                CK_UTF8CHAR_PTR new_pin, CK_ULONG new_pin_len)
     621              : {
     622              :         GkmWrapPrompt *prompt;
     623            1 :         CK_RV rv = CKR_OK;
     624              : 
     625            1 :         prompt = gkm_wrap_prompt_for_set_pin (gkm_wrap_layer_get_functions_no_prompts(),
     626              :                                               handle, old_pin, old_pin_len, new_pin, new_pin_len);
     627              : 
     628              :         for (;;) {
     629            1 :                 if (prompt && !gkm_wrap_prompt_do_set_pin (prompt, rv, &old_pin, &old_pin_len,
     630              :                                                            &new_pin, &new_pin_len))
     631            0 :                         break;
     632              : 
     633            1 :                 rv = wrap_C_SetPIN (handle, old_pin, old_pin_len, new_pin, new_pin_len);
     634              : 
     635            1 :                 if (!prompt || rv != CKR_PIN_INCORRECT ||
     636            0 :                     rv != CKR_PIN_INVALID || rv != CKR_PIN_LEN_RANGE)
     637              :                         break;
     638              :         }
     639              : 
     640            1 :         if (prompt) {
     641            1 :                 gkm_wrap_prompt_done_set_pin (prompt, rv);
     642            1 :                 g_object_unref (prompt);
     643              :         }
     644              : 
     645            1 :         return rv;
     646              : }
     647              : 
     648              : static CK_RV
     649            0 : wrap_C_GetOperationState (CK_SESSION_HANDLE handle, CK_BYTE_PTR operation_state, CK_ULONG_PTR operation_state_len)
     650              : {
     651              :         Mapping map;
     652              :         CK_RV rv;
     653              : 
     654            0 :         rv = map_session_to_real (&handle, &map, NULL);
     655            0 :         if (rv != CKR_OK)
     656            0 :                 return rv;
     657            0 :         return (map.funcs->C_GetOperationState) (handle, operation_state, operation_state_len);
     658              : }
     659              : 
     660              : static CK_RV
     661            0 : wrap_C_SetOperationState (CK_SESSION_HANDLE handle, CK_BYTE_PTR operation_state,
     662              :                           CK_ULONG operation_state_len, CK_OBJECT_HANDLE encryption_key,
     663              :                           CK_OBJECT_HANDLE authentication_key)
     664              : {
     665              :         Mapping map;
     666              :         CK_RV rv;
     667              : 
     668            0 :         rv = map_session_to_real (&handle, &map, NULL);
     669            0 :         if (rv != CKR_OK)
     670            0 :                 return rv;
     671            0 :         return (map.funcs->C_SetOperationState) (handle, operation_state, operation_state_len, encryption_key, authentication_key);
     672              : }
     673              : 
     674              : static CK_RV
     675          146 : wrap_C_Login (CK_SESSION_HANDLE handle, CK_USER_TYPE user_type,
     676              :               CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
     677              : {
     678              :         Mapping map;
     679              :         CK_RV rv;
     680              : 
     681          146 :         rv = map_session_to_real (&handle, &map, NULL);
     682          146 :         if (rv != CKR_OK)
     683            0 :                 return rv;
     684              : 
     685          146 :         return (map.funcs->C_Login) (handle, user_type, pin, pin_len);
     686              : }
     687              : 
     688              : static CK_RV
     689           59 : auth_C_Login (CK_SESSION_HANDLE handle, CK_USER_TYPE user_type,
     690              :               CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
     691              : {
     692              :         GkmWrapPrompt *prompt;
     693              :         CK_OBJECT_HANDLE specific;
     694              :         CK_RV rv;
     695              : 
     696           59 :         lookup_session_specific (handle, &specific);
     697           59 :         prompt = gkm_wrap_prompt_for_login (gkm_wrap_layer_get_functions_no_prompts(),
     698              :                                             user_type, handle, specific, pin, pin_len);
     699              : 
     700              :         for (;;) {
     701           71 :                 rv = wrap_C_Login (handle, user_type, pin, pin_len);
     702              : 
     703           71 :                 if (!prompt || rv != CKR_PIN_INCORRECT)
     704              :                         break;
     705              : 
     706           18 :                 if (!gkm_wrap_prompt_do_login (prompt, user_type, rv, &pin, &pin_len))
     707            6 :                         break;
     708              :         }
     709              : 
     710           59 :         if (prompt) {
     711           55 :                 gkm_wrap_prompt_done_login (prompt, user_type, rv);
     712           55 :                 g_object_unref (prompt);
     713              :         }
     714              : 
     715           59 :         return rv;
     716              : }
     717              : 
     718              : static CK_RV
     719            2 : wrap_C_Logout (CK_SESSION_HANDLE handle)
     720              : {
     721              :         Mapping map;
     722              :         CK_RV rv;
     723              : 
     724            2 :         rv = map_session_to_real (&handle, &map, NULL);
     725            2 :         if (rv != CKR_OK)
     726            0 :                 return rv;
     727            2 :         return (map.funcs->C_Logout) (handle);
     728              : }
     729              : 
     730              : static CK_RV
     731           78 : wrap_C_CreateObject (CK_SESSION_HANDLE handle, CK_ATTRIBUTE_PTR template,
     732              :                      CK_ULONG count, CK_OBJECT_HANDLE_PTR new_object)
     733              : {
     734              :         Mapping map;
     735              :         CK_RV rv;
     736              : 
     737           78 :         rv = map_session_to_real (&handle, &map, NULL);
     738           78 :         if (rv != CKR_OK)
     739            0 :                 return rv;
     740              : 
     741           78 :         return (map.funcs->C_CreateObject) (handle, template, count, new_object);
     742              : }
     743              : 
     744              : static CK_RV
     745           37 : auth_C_CreateObject (CK_SESSION_HANDLE handle, CK_ATTRIBUTE_PTR template,
     746              :                      CK_ULONG count, CK_OBJECT_HANDLE_PTR new_object)
     747              : {
     748           37 :         GkmWrapPrompt *prompt = NULL;
     749              :         CK_RV rv;
     750              : 
     751              :         for (;;) {
     752           45 :                 rv = wrap_C_CreateObject (handle, template, count, new_object);
     753              : 
     754           45 :                 if (rv != CKR_PIN_INCORRECT)
     755           34 :                         break;
     756              : 
     757           11 :                 if (!prompt) {
     758            9 :                         prompt = gkm_wrap_prompt_for_credential (gkm_wrap_layer_get_functions_no_prompts(),
     759              :                                                                  handle, template, count);
     760            9 :                         if (prompt == NULL)
     761            1 :                                 break;
     762              :                 }
     763              : 
     764           10 :                 if (!gkm_wrap_prompt_do_credential (prompt, &template, &count))
     765            2 :                         break;
     766              :         }
     767              : 
     768              : 
     769           37 :         if (prompt) {
     770            8 :                 gkm_wrap_prompt_done_credential (prompt, rv);
     771            8 :                 g_object_unref (prompt);
     772              :         }
     773              : 
     774           37 :         return rv;
     775              : }
     776              : 
     777              : static CK_RV
     778            0 : wrap_C_CopyObject (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object,
     779              :                    CK_ATTRIBUTE_PTR template, CK_ULONG count,
     780              :                    CK_OBJECT_HANDLE_PTR new_object)
     781              : {
     782              :         Mapping map;
     783              :         CK_RV rv;
     784              : 
     785            0 :         rv = map_session_to_real (&handle, &map, NULL);
     786            0 :         if (rv != CKR_OK)
     787            0 :                 return rv;
     788            0 :         return (map.funcs->C_CopyObject) (handle, object, template, count, new_object);
     789              : }
     790              : 
     791              : static CK_RV
     792           41 : wrap_C_DestroyObject (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object)
     793              : {
     794              :         Mapping map;
     795              :         CK_RV rv;
     796              : 
     797           41 :         rv = map_session_to_real (&handle, &map, NULL);
     798           41 :         if (rv != CKR_OK)
     799            0 :                 return rv;
     800           41 :         return (map.funcs->C_DestroyObject) (handle, object);
     801              : }
     802              : 
     803              : static CK_RV
     804            0 : wrap_C_GetObjectSize (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object,
     805              :                       CK_ULONG_PTR size)
     806              : {
     807              :         Mapping map;
     808              :         CK_RV rv;
     809              : 
     810            0 :         rv = map_session_to_real (&handle, &map, NULL);
     811            0 :         if (rv != CKR_OK)
     812            0 :                 return rv;
     813            0 :         return (map.funcs->C_GetObjectSize) (handle, object, size);
     814              : }
     815              : 
     816              : static CK_RV
     817          650 : wrap_C_GetAttributeValue (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object,
     818              :                           CK_ATTRIBUTE_PTR template, CK_ULONG count)
     819              : {
     820              :         Mapping map;
     821              :         CK_RV rv;
     822              : 
     823          650 :         rv = map_session_to_real (&handle, &map, NULL);
     824          650 :         if (rv != CKR_OK)
     825            0 :                 return rv;
     826          650 :         return (map.funcs->C_GetAttributeValue) (handle, object, template, count);
     827              : }
     828              : 
     829              : static CK_RV
     830            8 : wrap_C_SetAttributeValue (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object,
     831              :                          CK_ATTRIBUTE_PTR template, CK_ULONG count)
     832              : {
     833              :         Mapping map;
     834              :         CK_RV rv;
     835              : 
     836            8 :         rv = map_session_to_real (&handle, &map, NULL);
     837            8 :         if (rv != CKR_OK)
     838            0 :                 return rv;
     839            8 :         return (map.funcs->C_SetAttributeValue) (handle, object, template, count);
     840              : }
     841              : 
     842              : static CK_RV
     843          237 : wrap_C_FindObjectsInit (CK_SESSION_HANDLE handle, CK_ATTRIBUTE_PTR template,
     844              :                         CK_ULONG count)
     845              : {
     846              :         Mapping map;
     847              :         CK_RV rv;
     848              : 
     849          237 :         rv = map_session_to_real (&handle, &map, NULL);
     850          237 :         if (rv != CKR_OK)
     851            0 :                 return rv;
     852          237 :         return (map.funcs->C_FindObjectsInit) (handle, template, count);
     853              : }
     854              : 
     855              : static CK_RV
     856          357 : wrap_C_FindObjects (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE_PTR objects,
     857              :                     CK_ULONG max_count, CK_ULONG_PTR count)
     858              : {
     859              :         Mapping map;
     860              :         CK_RV rv;
     861              : 
     862          357 :         rv = map_session_to_real (&handle, &map, NULL);
     863          357 :         if (rv != CKR_OK)
     864            0 :                 return rv;
     865          357 :         return (map.funcs->C_FindObjects) (handle, objects, max_count, count);
     866              : }
     867              : 
     868              : static CK_RV
     869          237 : wrap_C_FindObjectsFinal (CK_SESSION_HANDLE handle)
     870              : {
     871              :         Mapping map;
     872              :         CK_RV rv;
     873              : 
     874          237 :         rv = map_session_to_real (&handle, &map, NULL);
     875          237 :         if (rv != CKR_OK)
     876            0 :                 return rv;
     877          237 :         return (map.funcs->C_FindObjectsFinal) (handle);
     878              : }
     879              : 
     880              : static CK_RV
     881            0 : wrap_C_EncryptInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
     882              :                     CK_OBJECT_HANDLE key)
     883              : {
     884              :         Mapping map;
     885              :         CK_RV rv;
     886              : 
     887            0 :         rv = map_session_to_real (&handle, &map, NULL);
     888            0 :         if (rv != CKR_OK)
     889            0 :                 return rv;
     890            0 :         return (map.funcs->C_EncryptInit) (handle, mechanism, key);
     891              : }
     892              : 
     893              : static CK_RV
     894            0 : auth_C_EncryptInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
     895              :                     CK_OBJECT_HANDLE key)
     896              : {
     897            0 :         CK_RV rv = wrap_C_EncryptInit (handle, mechanism, key);
     898            0 :         if (rv == CKR_OK)
     899            0 :                 store_session_specific (handle, key);
     900            0 :         return rv;
     901              : }
     902              : 
     903              : static CK_RV
     904            0 : wrap_C_Encrypt (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len,
     905              :                 CK_BYTE_PTR encrypted_data, CK_ULONG_PTR encrypted_data_len)
     906              : {
     907              :         Mapping map;
     908              :         CK_RV rv;
     909              : 
     910            0 :         rv = map_session_to_real (&handle, &map, NULL);
     911            0 :         if (rv != CKR_OK)
     912            0 :                 return rv;
     913            0 :         return (map.funcs->C_Encrypt) (handle, data, data_len, encrypted_data, encrypted_data_len);
     914              : }
     915              : 
     916              : static CK_RV
     917            0 : wrap_C_EncryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part,
     918              :                       CK_ULONG part_len, CK_BYTE_PTR encrypted_part,
     919              :                       CK_ULONG_PTR encrypted_part_len)
     920              : {
     921              :         Mapping map;
     922              :         CK_RV rv;
     923              : 
     924            0 :         rv = map_session_to_real (&handle, &map, NULL);
     925            0 :         if (rv != CKR_OK)
     926            0 :                 return rv;
     927            0 :         return (map.funcs->C_EncryptUpdate) (handle, part, part_len, encrypted_part, encrypted_part_len);
     928              : }
     929              : 
     930              : static CK_RV
     931            0 : wrap_C_EncryptFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR last_part,
     932              :                      CK_ULONG_PTR last_part_len)
     933              : {
     934              :         Mapping map;
     935              :         CK_RV rv;
     936              : 
     937            0 :         rv = map_session_to_real (&handle, &map, NULL);
     938            0 :         if (rv != CKR_OK)
     939            0 :                 return rv;
     940            0 :         return (map.funcs->C_EncryptFinal) (handle, last_part, last_part_len);
     941              : }
     942              : 
     943              : static CK_RV
     944            0 : wrap_C_DecryptInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
     945              :                     CK_OBJECT_HANDLE key)
     946              : {
     947              :         Mapping map;
     948              :         CK_RV rv;
     949              : 
     950            0 :         rv = map_session_to_real (&handle, &map, NULL);
     951            0 :         if (rv != CKR_OK)
     952            0 :                 return rv;
     953            0 :         return (map.funcs->C_DecryptInit) (handle, mechanism, key);
     954              : }
     955              : 
     956              : static CK_RV
     957            0 : auth_C_DecryptInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
     958              :                     CK_OBJECT_HANDLE key)
     959              : {
     960            0 :         CK_RV rv = wrap_C_DecryptInit (handle, mechanism, key);
     961            0 :         if (rv == CKR_OK)
     962            0 :                 store_session_specific (handle, key);
     963            0 :         return rv;
     964              : }
     965              : 
     966              : static CK_RV
     967            0 : wrap_C_Decrypt (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_data,
     968              :                 CK_ULONG enc_data_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len)
     969              : {
     970              :         Mapping map;
     971              :         CK_RV rv;
     972              : 
     973            0 :         rv = map_session_to_real (&handle, &map, NULL);
     974            0 :         if (rv != CKR_OK)
     975            0 :                 return rv;
     976            0 :         return (map.funcs->C_Decrypt) (handle, enc_data, enc_data_len, data, data_len);
     977              : }
     978              : 
     979              : static CK_RV
     980            0 : wrap_C_DecryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_part,
     981              :                      CK_ULONG enc_part_len, CK_BYTE_PTR part, CK_ULONG_PTR part_len)
     982              : {
     983              :         Mapping map;
     984              :         CK_RV rv;
     985              : 
     986            0 :         rv = map_session_to_real (&handle, &map, NULL);
     987            0 :         if (rv != CKR_OK)
     988            0 :                 return rv;
     989            0 :         return (map.funcs->C_DecryptUpdate) (handle, enc_part, enc_part_len, part, part_len);
     990              : }
     991              : 
     992              : static CK_RV
     993            0 : wrap_C_DecryptFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR last_part,
     994              :                      CK_ULONG_PTR last_part_len)
     995              : {
     996              :         Mapping map;
     997              :         CK_RV rv;
     998              : 
     999            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1000            0 :         if (rv != CKR_OK)
    1001            0 :                 return rv;
    1002            0 :         return (map.funcs->C_DecryptFinal) (handle, last_part, last_part_len);
    1003              : }
    1004              : 
    1005              : static CK_RV
    1006            0 : wrap_C_DigestInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism)
    1007              : {
    1008              :         Mapping map;
    1009              :         CK_RV rv;
    1010              : 
    1011            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1012            0 :         if (rv != CKR_OK)
    1013            0 :                 return rv;
    1014            0 :         return (map.funcs->C_DigestInit) (handle, mechanism);
    1015              : }
    1016              : 
    1017              : static CK_RV
    1018            0 : wrap_C_Digest (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len,
    1019              :                CK_BYTE_PTR digest, CK_ULONG_PTR digest_len)
    1020              : {
    1021              :         Mapping map;
    1022              :         CK_RV rv;
    1023              : 
    1024            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1025            0 :         if (rv != CKR_OK)
    1026            0 :                 return rv;
    1027            0 :         return (map.funcs->C_Digest) (handle, data, data_len, digest, digest_len);
    1028              : }
    1029              : 
    1030              : static CK_RV
    1031            0 : wrap_C_DigestUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, CK_ULONG part_len)
    1032              : {
    1033              :         Mapping map;
    1034              :         CK_RV rv;
    1035              : 
    1036            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1037            0 :         if (rv != CKR_OK)
    1038            0 :                 return rv;
    1039            0 :         return (map.funcs->C_DigestUpdate) (handle, part, part_len);
    1040              : }
    1041              : 
    1042              : static CK_RV
    1043            0 : wrap_C_DigestKey (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE key)
    1044              : {
    1045              :         Mapping map;
    1046              :         CK_RV rv;
    1047              : 
    1048            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1049            0 :         if (rv != CKR_OK)
    1050            0 :                 return rv;
    1051            0 :         return (map.funcs->C_DigestKey) (handle, key);
    1052              : }
    1053              : 
    1054              : static CK_RV
    1055            0 : wrap_C_DigestFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR digest,
    1056              :                     CK_ULONG_PTR digest_len)
    1057              : {
    1058              :         Mapping map;
    1059              :         CK_RV rv;
    1060              : 
    1061            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1062            0 :         if (rv != CKR_OK)
    1063            0 :                 return rv;
    1064            0 :         return (map.funcs->C_DigestFinal) (handle, digest, digest_len);
    1065              : }
    1066              : 
    1067              : static CK_RV
    1068            8 : wrap_C_SignInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
    1069              :                  CK_OBJECT_HANDLE key)
    1070              : {
    1071              :         Mapping map;
    1072              :         CK_RV rv;
    1073              : 
    1074            8 :         rv = map_session_to_real (&handle, &map, NULL);
    1075            8 :         if (rv != CKR_OK)
    1076            0 :                 return rv;
    1077            8 :         return (map.funcs->C_SignInit) (handle, mechanism, key);
    1078              : }
    1079              : 
    1080              : static CK_RV
    1081            8 : auth_C_SignInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
    1082              :                  CK_OBJECT_HANDLE key)
    1083              : {
    1084            8 :         CK_RV rv = wrap_C_SignInit (handle, mechanism, key);
    1085            8 :         if (rv == CKR_OK)
    1086            8 :                 store_session_specific (handle, key);
    1087            8 :         return rv;
    1088              : }
    1089              : 
    1090              : static CK_RV
    1091            0 : wrap_C_Sign (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len,
    1092              :              CK_BYTE_PTR signature, CK_ULONG_PTR signature_len)
    1093              : {
    1094              :         Mapping map;
    1095              :         CK_RV rv;
    1096              : 
    1097            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1098            0 :         if (rv != CKR_OK)
    1099            0 :                 return rv;
    1100            0 :         return (map.funcs->C_Sign) (handle, data, data_len, signature, signature_len);
    1101              : }
    1102              : 
    1103              : static CK_RV
    1104            0 : wrap_C_SignUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, CK_ULONG part_len)
    1105              : {
    1106              :         Mapping map;
    1107              :         CK_RV rv;
    1108              : 
    1109            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1110            0 :         if (rv != CKR_OK)
    1111            0 :                 return rv;
    1112            0 :         return (map.funcs->C_SignUpdate) (handle, part, part_len);
    1113              : }
    1114              : 
    1115              : static CK_RV
    1116            0 : wrap_C_SignFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR signature,
    1117              :                   CK_ULONG_PTR signature_len)
    1118              : {
    1119              :         Mapping map;
    1120              :         CK_RV rv;
    1121              : 
    1122            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1123            0 :         if (rv != CKR_OK)
    1124            0 :                 return rv;
    1125            0 :         return (map.funcs->C_SignFinal) (handle, signature, signature_len);
    1126              : }
    1127              : 
    1128              : static CK_RV
    1129            0 : wrap_C_SignRecoverInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
    1130              :                         CK_OBJECT_HANDLE key)
    1131              : {
    1132              :         Mapping map;
    1133              :         CK_RV rv;
    1134              : 
    1135            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1136            0 :         if (rv != CKR_OK)
    1137            0 :                 return rv;
    1138            0 :         return (map.funcs->C_SignRecoverInit) (handle, mechanism, key);
    1139              : }
    1140              : 
    1141              : static CK_RV
    1142            0 : auth_C_SignRecoverInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
    1143              :                         CK_OBJECT_HANDLE key)
    1144              : {
    1145            0 :         CK_RV rv = wrap_C_SignRecoverInit (handle, mechanism, key);
    1146            0 :         if (rv == CKR_OK)
    1147            0 :                 store_session_specific (handle, key);
    1148            0 :         return rv;
    1149              : }
    1150              : 
    1151              : static CK_RV
    1152            0 : wrap_C_SignRecover (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len,
    1153              :                     CK_BYTE_PTR signature, CK_ULONG_PTR signature_len)
    1154              : {
    1155              :         Mapping map;
    1156              :         CK_RV rv;
    1157              : 
    1158            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1159            0 :         if (rv != CKR_OK)
    1160            0 :                 return rv;
    1161            0 :         return (map.funcs->C_SignRecover) (handle, data, data_len, signature, signature_len);
    1162              : }
    1163              : 
    1164              : static CK_RV
    1165            0 : wrap_C_VerifyInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
    1166              :                    CK_OBJECT_HANDLE key)
    1167              : {
    1168              :         Mapping map;
    1169              :         CK_RV rv;
    1170              : 
    1171            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1172            0 :         if (rv != CKR_OK)
    1173            0 :                 return rv;
    1174            0 :         return (map.funcs->C_VerifyInit) (handle, mechanism, key);
    1175              : }
    1176              : 
    1177              : static CK_RV
    1178            0 : auth_C_VerifyInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
    1179              :                    CK_OBJECT_HANDLE key)
    1180              : {
    1181            0 :         CK_RV rv = wrap_C_VerifyInit (handle, mechanism, key);
    1182            0 :         if (rv == CKR_OK)
    1183            0 :                 store_session_specific (handle, key);
    1184            0 :         return rv;
    1185              : }
    1186              : 
    1187              : static CK_RV
    1188            0 : wrap_C_Verify (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len,
    1189              :                CK_BYTE_PTR signature, CK_ULONG signature_len)
    1190              : {
    1191              :         Mapping map;
    1192              :         CK_RV rv;
    1193              : 
    1194            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1195            0 :         if (rv != CKR_OK)
    1196            0 :                 return rv;
    1197            0 :         return (map.funcs->C_Verify) (handle, data, data_len, signature, signature_len);
    1198              : }
    1199              : 
    1200              : static CK_RV
    1201            0 : wrap_C_VerifyUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, CK_ULONG part_len)
    1202              : {
    1203              :         Mapping map;
    1204              :         CK_RV rv;
    1205              : 
    1206            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1207            0 :         if (rv != CKR_OK)
    1208            0 :                 return rv;
    1209            0 :         return (map.funcs->C_VerifyUpdate) (handle, part, part_len);
    1210              : }
    1211              : 
    1212              : static CK_RV
    1213            0 : wrap_C_VerifyFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR signature,
    1214              :                     CK_ULONG signature_len)
    1215              : {
    1216              :         Mapping map;
    1217              :         CK_RV rv;
    1218              : 
    1219            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1220            0 :         if (rv != CKR_OK)
    1221            0 :                 return rv;
    1222            0 :         return (map.funcs->C_VerifyFinal) (handle, signature, signature_len);
    1223              : }
    1224              : 
    1225              : static CK_RV
    1226            0 : wrap_C_VerifyRecoverInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
    1227              :                           CK_OBJECT_HANDLE key)
    1228              : {
    1229              :         Mapping map;
    1230              :         CK_RV rv;
    1231              : 
    1232            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1233            0 :         if (rv != CKR_OK)
    1234            0 :                 return rv;
    1235            0 :         return (map.funcs->C_VerifyRecoverInit) (handle, mechanism, key);
    1236              : }
    1237              : 
    1238              : static CK_RV
    1239            0 : auth_C_VerifyRecoverInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
    1240              :                           CK_OBJECT_HANDLE key)
    1241              : {
    1242            0 :         CK_RV rv = wrap_C_VerifyInit (handle, mechanism, key);
    1243            0 :         if (rv == CKR_OK)
    1244            0 :                 store_session_specific (handle, key);
    1245            0 :         return rv;
    1246              : }
    1247              : 
    1248              : static CK_RV
    1249            0 : wrap_C_VerifyRecover (CK_SESSION_HANDLE handle, CK_BYTE_PTR signature,
    1250              :                      CK_ULONG signature_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len)
    1251              : {
    1252              :         Mapping map;
    1253              :         CK_RV rv;
    1254              : 
    1255            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1256            0 :         if (rv != CKR_OK)
    1257            0 :                 return rv;
    1258            0 :         return (map.funcs->C_VerifyRecover) (handle, signature, signature_len, data, data_len);
    1259              : }
    1260              : 
    1261              : static CK_RV
    1262            0 : wrap_C_DigestEncryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part,
    1263              :                             CK_ULONG part_len, CK_BYTE_PTR enc_part,
    1264              :                             CK_ULONG_PTR enc_part_len)
    1265              : {
    1266              :         Mapping map;
    1267              :         CK_RV rv;
    1268              : 
    1269            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1270            0 :         if (rv != CKR_OK)
    1271            0 :                 return rv;
    1272            0 :         return (map.funcs->C_DigestEncryptUpdate) (handle, part, part_len, enc_part, enc_part_len);
    1273              : }
    1274              : 
    1275              : static CK_RV
    1276            0 : wrap_C_DecryptDigestUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_part,
    1277              :                             CK_ULONG enc_part_len, CK_BYTE_PTR part,
    1278              :                             CK_ULONG_PTR part_len)
    1279              : {
    1280              :         Mapping map;
    1281              :         CK_RV rv;
    1282              : 
    1283            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1284            0 :         if (rv != CKR_OK)
    1285            0 :                 return rv;
    1286            0 :         return (map.funcs->C_DecryptDigestUpdate) (handle, enc_part, enc_part_len, part, part_len);
    1287              : }
    1288              : 
    1289              : static CK_RV
    1290            0 : wrap_C_SignEncryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part,
    1291              :                           CK_ULONG part_len, CK_BYTE_PTR enc_part,
    1292              :                           CK_ULONG_PTR enc_part_len)
    1293              : {
    1294              :         Mapping map;
    1295              :         CK_RV rv;
    1296              : 
    1297            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1298            0 :         if (rv != CKR_OK)
    1299            0 :                 return rv;
    1300            0 :         return (map.funcs->C_SignEncryptUpdate) (handle, part, part_len, enc_part, enc_part_len);
    1301              : }
    1302              : 
    1303              : static CK_RV
    1304            0 : wrap_C_DecryptVerifyUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_part,
    1305              :                             CK_ULONG enc_part_len, CK_BYTE_PTR part,
    1306              :                             CK_ULONG_PTR part_len)
    1307              : {
    1308              :         Mapping map;
    1309              :         CK_RV rv;
    1310              : 
    1311            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1312            0 :         if (rv != CKR_OK)
    1313            0 :                 return rv;
    1314            0 :         return (map.funcs->C_DecryptVerifyUpdate) (handle, enc_part, enc_part_len, part, part_len);
    1315              : }
    1316              : 
    1317              : static CK_RV
    1318            0 : wrap_C_GenerateKey (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
    1319              :                     CK_ATTRIBUTE_PTR template, CK_ULONG count,
    1320              :                     CK_OBJECT_HANDLE_PTR key)
    1321              : {
    1322              :         Mapping map;
    1323              :         CK_RV rv;
    1324              : 
    1325            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1326            0 :         if (rv != CKR_OK)
    1327            0 :                 return rv;
    1328            0 :         return (map.funcs->C_GenerateKey) (handle, mechanism, template, count, key);
    1329              : }
    1330              : 
    1331              : static CK_RV
    1332            1 : wrap_C_GenerateKeyPair (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
    1333              :                         CK_ATTRIBUTE_PTR pub_template, CK_ULONG pub_count,
    1334              :                         CK_ATTRIBUTE_PTR priv_template, CK_ULONG priv_count,
    1335              :                         CK_OBJECT_HANDLE_PTR pub_key, CK_OBJECT_HANDLE_PTR priv_key)
    1336              : {
    1337              :         Mapping map;
    1338              :         CK_RV rv;
    1339              : 
    1340            1 :         rv = map_session_to_real (&handle, &map, NULL);
    1341            1 :         if (rv != CKR_OK)
    1342            0 :                 return rv;
    1343            1 :         return (map.funcs->C_GenerateKeyPair) (handle, mechanism, pub_template, pub_count, priv_template, priv_count, pub_key, priv_key);
    1344              : }
    1345              : 
    1346              : static CK_RV
    1347            0 : wrap_C_WrapKey (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
    1348              :                 CK_OBJECT_HANDLE wrapping_key, CK_OBJECT_HANDLE key,
    1349              :                 CK_BYTE_PTR wrapped_key, CK_ULONG_PTR wrapped_key_len)
    1350              : {
    1351              :         Mapping map;
    1352              :         CK_RV rv;
    1353              : 
    1354            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1355            0 :         if (rv != CKR_OK)
    1356            0 :                 return rv;
    1357            0 :         return (map.funcs->C_WrapKey) (handle, mechanism, wrapping_key, key, wrapped_key, wrapped_key_len);
    1358              : }
    1359              : 
    1360              : static CK_RV
    1361           19 : wrap_C_UnwrapKey (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
    1362              :                   CK_OBJECT_HANDLE unwrapping_key, CK_BYTE_PTR wrapped_key,
    1363              :                   CK_ULONG wrapped_key_len, CK_ATTRIBUTE_PTR template,
    1364              :                   CK_ULONG count, CK_OBJECT_HANDLE_PTR key)
    1365              : {
    1366              :         Mapping map;
    1367              :         CK_RV rv;
    1368              : 
    1369           19 :         rv = map_session_to_real (&handle, &map, NULL);
    1370           19 :         if (rv != CKR_OK)
    1371            0 :                 return rv;
    1372           19 :         return (map.funcs->C_UnwrapKey) (handle, mechanism, unwrapping_key, wrapped_key, wrapped_key_len, template, count, key);
    1373              : }
    1374              : 
    1375              : static CK_RV
    1376            2 : wrap_C_DeriveKey (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
    1377              :                   CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE_PTR template,
    1378              :                   CK_ULONG count, CK_OBJECT_HANDLE_PTR key)
    1379              : {
    1380              :         Mapping map;
    1381              :         CK_RV rv;
    1382              : 
    1383            2 :         rv = map_session_to_real (&handle, &map, NULL);
    1384            2 :         if (rv != CKR_OK)
    1385            0 :                 return rv;
    1386            2 :         return (map.funcs->C_DeriveKey) (handle, mechanism, base_key, template, count, key);
    1387              : }
    1388              : 
    1389              : static CK_RV
    1390            0 : wrap_C_SeedRandom (CK_SESSION_HANDLE handle, CK_BYTE_PTR seed, CK_ULONG seed_len)
    1391              : {
    1392              :         Mapping map;
    1393              :         CK_RV rv;
    1394              : 
    1395            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1396            0 :         if (rv != CKR_OK)
    1397            0 :                 return rv;
    1398            0 :         return (map.funcs->C_SeedRandom) (handle, seed, seed_len);
    1399              : }
    1400              : 
    1401              : static CK_RV
    1402            0 : wrap_C_GenerateRandom (CK_SESSION_HANDLE handle, CK_BYTE_PTR random_data,
    1403              :                       CK_ULONG random_len)
    1404              : {
    1405              :         Mapping map;
    1406              :         CK_RV rv;
    1407              : 
    1408            0 :         rv = map_session_to_real (&handle, &map, NULL);
    1409            0 :         if (rv != CKR_OK)
    1410            0 :                 return rv;
    1411            0 :         return (map.funcs->C_GenerateRandom) (handle, random_data, random_len);
    1412              : }
    1413              : 
    1414              : /* --------------------------------------------------------------------
    1415              :  * MODULE ENTRY POINT
    1416              :  */
    1417              : 
    1418              : static CK_FUNCTION_LIST wrap_function_list = {
    1419              :         { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },  /* version */
    1420              :         wrap_C_Initialize,
    1421              :         wrap_C_Finalize,
    1422              :         wrap_C_GetInfo,
    1423              :         wrap_C_GetFunctionList,
    1424              :         wrap_C_GetSlotList,
    1425              :         wrap_C_GetSlotInfo,
    1426              :         wrap_C_GetTokenInfo,
    1427              :         wrap_C_GetMechanismList,
    1428              :         wrap_C_GetMechanismInfo,
    1429              :         wrap_C_InitToken,
    1430              :         wrap_C_InitPIN,
    1431              :         wrap_C_SetPIN,
    1432              :         wrap_C_OpenSession,
    1433              :         wrap_C_CloseSession,
    1434              :         wrap_C_CloseAllSessions,
    1435              :         wrap_C_GetSessionInfo,
    1436              :         wrap_C_GetOperationState,
    1437              :         wrap_C_SetOperationState,
    1438              :         wrap_C_Login,
    1439              :         wrap_C_Logout,
    1440              :         wrap_C_CreateObject,
    1441              :         wrap_C_CopyObject,
    1442              :         wrap_C_DestroyObject,
    1443              :         wrap_C_GetObjectSize,
    1444              :         wrap_C_GetAttributeValue,
    1445              :         wrap_C_SetAttributeValue,
    1446              :         wrap_C_FindObjectsInit,
    1447              :         wrap_C_FindObjects,
    1448              :         wrap_C_FindObjectsFinal,
    1449              :         wrap_C_EncryptInit,
    1450              :         wrap_C_Encrypt,
    1451              :         wrap_C_EncryptUpdate,
    1452              :         wrap_C_EncryptFinal,
    1453              :         wrap_C_DecryptInit,
    1454              :         wrap_C_Decrypt,
    1455              :         wrap_C_DecryptUpdate,
    1456              :         wrap_C_DecryptFinal,
    1457              :         wrap_C_DigestInit,
    1458              :         wrap_C_Digest,
    1459              :         wrap_C_DigestUpdate,
    1460              :         wrap_C_DigestKey,
    1461              :         wrap_C_DigestFinal,
    1462              :         wrap_C_SignInit,
    1463              :         wrap_C_Sign,
    1464              :         wrap_C_SignUpdate,
    1465              :         wrap_C_SignFinal,
    1466              :         wrap_C_SignRecoverInit,
    1467              :         wrap_C_SignRecover,
    1468              :         wrap_C_VerifyInit,
    1469              :         wrap_C_Verify,
    1470              :         wrap_C_VerifyUpdate,
    1471              :         wrap_C_VerifyFinal,
    1472              :         wrap_C_VerifyRecoverInit,
    1473              :         wrap_C_VerifyRecover,
    1474              :         wrap_C_DigestEncryptUpdate,
    1475              :         wrap_C_DecryptDigestUpdate,
    1476              :         wrap_C_SignEncryptUpdate,
    1477              :         wrap_C_DecryptVerifyUpdate,
    1478              :         wrap_C_GenerateKey,
    1479              :         wrap_C_GenerateKeyPair,
    1480              :         wrap_C_WrapKey,
    1481              :         wrap_C_UnwrapKey,
    1482              :         wrap_C_DeriveKey,
    1483              :         wrap_C_SeedRandom,
    1484              :         wrap_C_GenerateRandom,
    1485              :         wrap_C_GetFunctionStatus,
    1486              :         wrap_C_CancelFunction,
    1487              :         wrap_C_WaitForSlotEvent
    1488              : };
    1489              : 
    1490              : static CK_FUNCTION_LIST auth_function_list = {
    1491              :         { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },  /* version */
    1492              :         wrap_C_Initialize,
    1493              :         wrap_C_Finalize,
    1494              :         wrap_C_GetInfo,
    1495              :         auth_C_GetFunctionList,
    1496              :         wrap_C_GetSlotList,
    1497              :         wrap_C_GetSlotInfo,
    1498              :         auth_C_GetTokenInfo,
    1499              :         wrap_C_GetMechanismList,
    1500              :         wrap_C_GetMechanismInfo,
    1501              :         wrap_C_InitToken,
    1502              :         auth_C_InitPIN,
    1503              :         auth_C_SetPIN,
    1504              :         wrap_C_OpenSession,
    1505              :         wrap_C_CloseSession,
    1506              :         wrap_C_CloseAllSessions,
    1507              :         wrap_C_GetSessionInfo,
    1508              :         wrap_C_GetOperationState,
    1509              :         wrap_C_SetOperationState,
    1510              :         auth_C_Login,
    1511              :         wrap_C_Logout,
    1512              :         auth_C_CreateObject,
    1513              :         wrap_C_CopyObject,
    1514              :         wrap_C_DestroyObject,
    1515              :         wrap_C_GetObjectSize,
    1516              :         wrap_C_GetAttributeValue,
    1517              :         wrap_C_SetAttributeValue,
    1518              :         wrap_C_FindObjectsInit,
    1519              :         wrap_C_FindObjects,
    1520              :         wrap_C_FindObjectsFinal,
    1521              :         auth_C_EncryptInit,
    1522              :         wrap_C_Encrypt,
    1523              :         wrap_C_EncryptUpdate,
    1524              :         wrap_C_EncryptFinal,
    1525              :         auth_C_DecryptInit,
    1526              :         wrap_C_Decrypt,
    1527              :         wrap_C_DecryptUpdate,
    1528              :         wrap_C_DecryptFinal,
    1529              :         wrap_C_DigestInit,
    1530              :         wrap_C_Digest,
    1531              :         wrap_C_DigestUpdate,
    1532              :         wrap_C_DigestKey,
    1533              :         wrap_C_DigestFinal,
    1534              :         auth_C_SignInit,
    1535              :         wrap_C_Sign,
    1536              :         wrap_C_SignUpdate,
    1537              :         wrap_C_SignFinal,
    1538              :         auth_C_SignRecoverInit,
    1539              :         wrap_C_SignRecover,
    1540              :         auth_C_VerifyInit,
    1541              :         wrap_C_Verify,
    1542              :         wrap_C_VerifyUpdate,
    1543              :         wrap_C_VerifyFinal,
    1544              :         auth_C_VerifyRecoverInit,
    1545              :         wrap_C_VerifyRecover,
    1546              :         wrap_C_DigestEncryptUpdate,
    1547              :         wrap_C_DecryptDigestUpdate,
    1548              :         wrap_C_SignEncryptUpdate,
    1549              :         wrap_C_DecryptVerifyUpdate,
    1550              :         wrap_C_GenerateKey,
    1551              :         wrap_C_GenerateKeyPair,
    1552              :         wrap_C_WrapKey,
    1553              :         wrap_C_UnwrapKey,
    1554              :         wrap_C_DeriveKey,
    1555              :         wrap_C_SeedRandom,
    1556              :         wrap_C_GenerateRandom,
    1557              :         wrap_C_GetFunctionStatus,
    1558              :         wrap_C_CancelFunction,
    1559              :         wrap_C_WaitForSlotEvent
    1560              : };
    1561              : 
    1562              : /* -----------------------------------------------------------------------------------------
    1563              :  * PUBLIC FUNCTIONS
    1564              :  */
    1565              : 
    1566              : CK_FUNCTION_LIST_PTR
    1567           57 : gkm_wrap_layer_get_functions (void)
    1568              : {
    1569           57 :         return &auth_function_list;
    1570              : }
    1571              : 
    1572              : CK_FUNCTION_LIST_PTR
    1573          160 : gkm_wrap_layer_get_functions_no_prompts (void)
    1574              : {
    1575          160 :         return &wrap_function_list;
    1576              : }
    1577              : 
    1578              : void
    1579           30 : gkm_wrap_layer_reset_modules (void)
    1580              : {
    1581           30 :         G_LOCK (wrap_layer);
    1582              : 
    1583           30 :                 g_assert (!wrap_mappings);
    1584           30 :                 g_assert (!wrap_sessions);
    1585           30 :                 g_list_free (wrap_modules);
    1586           30 :                 wrap_modules = NULL;
    1587              : 
    1588           30 :         G_UNLOCK (wrap_layer);
    1589           30 : }
    1590              : 
    1591              : void
    1592          138 : gkm_wrap_layer_add_module (CK_FUNCTION_LIST_PTR funcs)
    1593              : {
    1594          138 :         g_assert (funcs);
    1595              : 
    1596          138 :         G_LOCK (wrap_layer);
    1597              : 
    1598          138 :                 g_assert (!wrap_mappings);
    1599          138 :                 g_assert (!wrap_sessions);
    1600          138 :                 wrap_modules = g_list_append (wrap_modules, funcs);
    1601              : 
    1602          138 :         G_UNLOCK (wrap_layer);
    1603          138 : }
        

Generated by: LCOV version 2.0-1