LCOV - code coverage report
Current view: top level - pkcs11/rpc-layer - gkm-rpc-module.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 24.2 % 1021 247
Test Date: 2024-05-07 18:02:03 Functions: 18.3 % 93 17

            Line data    Source code
       1              : /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
       2              : /* gkr-pkcs11-rpc-module.c - a PKCS#11 module which communicates with another process
       3              : 
       4              :    Copyright (C) 2008, Stefan Walter
       5              : 
       6              :    The Gnome Keyring Library is free software; you can redistribute it and/or
       7              :    modify it under the terms of the GNU Library General Public License as
       8              :    published by the Free Software Foundation; either version 2 of the
       9              :    License, or (at your option) any later version.
      10              : 
      11              :    The Gnome Keyring Library is distributed in the hope that it will be useful,
      12              :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14              :    Library General Public License for more details.
      15              : 
      16              :    You should have received a copy of the GNU Library General Public
      17              :    License along with the Gnome Library; see the file COPYING.LIB.  If not,
      18              :    <http://www.gnu.org/licenses/>.
      19              : 
      20              :    Author: Stef Walter <stef@memberwebs.com>
      21              : */
      22              : 
      23              : #include "config.h"
      24              : 
      25              : #include "gkm-rpc-layer.h"
      26              : #include "gkm-rpc-private.h"
      27              : 
      28              : #include "pkcs11/pkcs11.h"
      29              : 
      30              : #include "egg/egg-unix-credentials.h"
      31              : 
      32              : #include <glib.h>
      33              : 
      34              : #include <sys/types.h>
      35              : #include <sys/param.h>
      36              : #include <sys/socket.h>
      37              : #include <sys/un.h>
      38              : 
      39              : #include <stdlib.h>
      40              : #include <limits.h>
      41              : #include <ctype.h>
      42              : #include <stdint.h>
      43              : #include <pthread.h>
      44              : #include <unistd.h>
      45              : #include <fcntl.h>
      46              : #include <errno.h>
      47              : #include <stdarg.h>
      48              : #include <stdio.h>
      49              : #include <string.h>
      50              : 
      51              : /* -------------------------------------------------------------------
      52              :  * GLOBALS / DEFINES
      53              :  */
      54              : 
      55              : /* Various mutexes */
      56              : static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
      57              : 
      58              : /* Whether we've been initialized, and on what process id it happened */
      59              : static int pkcs11_initialized = 0;
      60              : static pid_t pkcs11_initialized_pid = 0;
      61              : 
      62              : /* The socket to connect to */
      63              : static char *pkcs11_socket_path = NULL;
      64              : 
      65              : /* The error used by us when parsing of rpc message fails */
      66              : #define PARSE_ERROR   CKR_DEVICE_ERROR
      67              : 
      68              : /* -----------------------------------------------------------------------------
      69              :  * LOGGING and DEBUGGING
      70              :  */
      71              : 
      72              : #if DEBUG_OUTPUT
      73              : #define debug(x) gkm_rpc_debug x
      74              : #else
      75              : #define debug(x)
      76              : #endif
      77              : #define warning(x) gkm_rpc_warn x
      78              : 
      79              : #define return_val_if_fail(x, v) \
      80              :         if (!(x)) { gkm_rpc_warn ("'%s' not true at %s", #x, __func__); return v; }
      81              : 
      82              : void
      83            0 : gkm_rpc_log (const char *line)
      84              : {
      85            0 :         fprintf (stderr, "%s\n", line);
      86            0 : }
      87              : 
      88              : /* -----------------------------------------------------------------------------
      89              :  * MODULE ARGUMENTS
      90              :  */
      91              : 
      92              : static void
      93            0 : parse_argument (char *arg)
      94              : {
      95              :         char *value;
      96              : 
      97            0 :         value = arg + strcspn (arg, ":=");
      98            0 :         if (!*value)
      99            0 :                 value = NULL;
     100              :         else
     101            0 :                 *(value++) = 0;
     102              : 
     103              :         /* Setup the socket path from the arguments */
     104            0 :         if (strcmp (arg, "socket") == 0) {
     105            0 :                 free (pkcs11_socket_path);
     106            0 :                 pkcs11_socket_path = strdup (value);
     107              :         } else {
     108            0 :                 warning (("unrecognized argument: %s", arg));
     109              :         }
     110            0 : }
     111              : 
     112              : static void
     113            0 : parse_arguments (const char *string)
     114              : {
     115            0 :         char quote = '\0';
     116              :         char *src, *dup, *at, *arg;
     117              : 
     118            0 :         if (!string)
     119            0 :                 return;
     120              : 
     121            0 :         src = dup = strdup (string);
     122            0 :         if (!dup) {
     123            0 :                 warning (("couldn't allocate memory for argument string"));
     124            0 :                 return;
     125              :         }
     126              : 
     127            0 :         arg = at = src;
     128            0 :         for (src = dup; *src; src++) {
     129              : 
     130              :                 /* Matching quote */
     131            0 :                 if (quote == *src) {
     132            0 :                         quote = '\0';
     133              : 
     134              :                 /* Inside of quotes */
     135            0 :                 } else if (quote != '\0') {
     136            0 :                         if (*src == '\\') {
     137            0 :                                 *at++ = *src++;
     138            0 :                                 if (!*src) {
     139            0 :                                         warning (("couldn't parse argument string: %s", string));
     140            0 :                                         goto done;
     141              :                                 }
     142            0 :                                 if (*src != quote)
     143            0 :                                         *at++ = '\\';
     144              :                         }
     145            0 :                         *at++ = *src;
     146              : 
     147              :                 /* Space, not inside of quotes */
     148            0 :                 } else if (isspace(*src)) {
     149            0 :                         *at = 0;
     150            0 :                         parse_argument (arg);
     151            0 :                         arg = at;
     152              : 
     153              :                 /* Other character outside of quotes */
     154              :                 } else {
     155            0 :                         switch (*src) {
     156            0 :                         case '\'':
     157              :                         case '"':
     158            0 :                                 quote = *src;
     159            0 :                                 break;
     160            0 :                         case '\\':
     161            0 :                                 *at++ = *src++;
     162            0 :                                 if (!*src) {
     163            0 :                                         warning (("couldn't parse argument string: %s", string));
     164            0 :                                         goto done;
     165              :                                 }
     166              :                                 /* fall through */
     167              :                         default:
     168            0 :                                 *at++ = *src;
     169            0 :                                 break;
     170              :                         }
     171              :                 }
     172              :         }
     173              : 
     174              : 
     175            0 :         if (at != arg)
     176            0 :                 parse_argument (arg);
     177              : 
     178            0 : done:
     179            0 :         free (dup);
     180              : }
     181              : 
     182              : /* -----------------------------------------------------------------------------
     183              :  * CALL SESSION
     184              :  */
     185              : 
     186              : enum CallStatus {
     187              :         CALL_INVALID,
     188              :         CALL_READY,
     189              :         CALL_PREP,
     190              :         CALL_TRANSIT,
     191              :         CALL_PARSE
     192              : };
     193              : 
     194              : typedef struct _CallState {
     195              :         int socket;                  /* The connection we're sending on */
     196              :         GkmRpcMessage *req;          /* The current request */
     197              :         GkmRpcMessage *resp;         /* The current response */
     198              :         int call_status;
     199              :         struct _CallState *next;     /* For pooling of completed sockets */
     200              : } CallState;
     201              : 
     202              : /* Maximum number of idle calls */
     203              : #define MAX_CALL_STATE_POOL 8
     204              : 
     205              : /* All call unused call states are in this list */
     206              : static CallState *call_state_pool = NULL;
     207              : static unsigned int n_call_state_pool = 0;
     208              : 
     209              : /* Mutex to protect above call state list */
     210              : static pthread_mutex_t call_state_mutex = PTHREAD_MUTEX_INITIALIZER;
     211              : 
     212              : /* Allocator for call session buffers */
     213              : static void*
     214           18 : call_allocator (void* p, size_t sz)
     215              : {
     216           18 :         void* res = realloc (p, (size_t)sz);
     217           18 :         if (!res && sz)
     218            0 :                 warning (("memory allocation of %lu bytes failed", sz));
     219           18 :         return res;
     220              : }
     221              : 
     222              : static CK_RV
     223            3 : call_connect (CallState *cs)
     224              : {
     225              :         struct sockaddr_un addr;
     226              :         int sock;
     227              : 
     228            3 :         assert (cs);
     229            3 :         assert (cs->socket == -1);
     230            3 :         assert (cs->call_status == CALL_INVALID);
     231              : 
     232            3 :         if (!pkcs11_socket_path)
     233            1 :                 return CKR_DEVICE_REMOVED;
     234              : 
     235              :         debug (("connecting to: %s", pkcs11_socket_path));
     236              : 
     237            2 :         addr.sun_family = AF_UNIX;
     238            2 :         g_strlcpy (addr.sun_path, pkcs11_socket_path, sizeof (addr.sun_path));
     239              : 
     240            2 :         sock = socket (AF_UNIX, SOCK_STREAM, 0);
     241            2 :         if (sock < 0) {
     242            0 :                 warning (("couldn't open socket: %s", strerror (errno)));
     243            0 :                 return CKR_DEVICE_ERROR;
     244              :         }
     245              : 
     246              :         /* close on exec */
     247            2 :         if (fcntl (sock, F_SETFD, 1) == -1) {
     248            0 :                 close (sock);
     249            0 :                 warning (("couldn't secure socket: %s", strerror (errno)));
     250            0 :                 return CKR_DEVICE_ERROR;
     251              :         }
     252              : 
     253            2 :         if (connect (sock, (struct sockaddr*) &addr, sizeof (addr)) < 0) {
     254            0 :                 close (sock);
     255            0 :                 if (errno == ENOENT) {
     256              :                         debug (("couldn't connect to: %s: %s", pkcs11_socket_path, strerror (errno)));
     257            0 :                         return CKR_DEVICE_REMOVED;
     258              :                 } else {
     259            0 :                         warning (("couldn't connect to: %s: %s", pkcs11_socket_path, strerror (errno)));
     260            0 :                         return CKR_DEVICE_ERROR;
     261              :                 }
     262              :         }
     263              : 
     264            2 :         if (egg_unix_credentials_write (sock) < 0) {
     265            0 :                 close (sock);
     266            0 :                 warning (("couldn't send socket credentials: %s", strerror (errno)));
     267            0 :                 return CKR_DEVICE_ERROR;
     268              :         }
     269              : 
     270            2 :         cs->socket = sock;
     271            2 :         cs->call_status = CALL_READY;
     272              :         debug (("connected socket"));
     273              : 
     274            2 :         return CKR_OK;
     275              : }
     276              : 
     277              : static void
     278            2 : call_disconnect (CallState *cs)
     279              : {
     280            2 :         assert (cs);
     281              : 
     282            2 :         if (cs->socket != -1) {
     283              :                 debug (("disconnected socket"));
     284            2 :                 close (cs->socket);
     285            2 :                 cs->socket = -1;
     286              :         }
     287            2 : }
     288              : 
     289              : static void
     290            2 : call_destroy (void *value)
     291              : {
     292            2 :         CallState *cs = value;
     293              : 
     294            2 :         if (value) {
     295            2 :                 call_disconnect (cs);
     296            2 :                 assert (cs->socket == -1);
     297              : 
     298            2 :                 gkm_rpc_message_free (cs->req);
     299            2 :                 gkm_rpc_message_free (cs->resp);
     300              : 
     301            2 :                 free (cs);
     302              : 
     303              :                 debug (("destroyed state"));
     304              :         }
     305            2 : }
     306              : 
     307              : static CK_RV
     308            7 : call_lookup (CallState **ret)
     309              : {
     310            7 :         CallState *cs = NULL;
     311              :         CK_RV rv;
     312              : 
     313            7 :         assert (ret);
     314              : 
     315            7 :         pthread_mutex_lock (&call_state_mutex);
     316              : 
     317              :                 /* Pop one from the pool if possible */
     318            7 :                 if (call_state_pool != NULL) {
     319            4 :                         cs = call_state_pool;
     320            4 :                         call_state_pool = cs->next;
     321            4 :                         cs->next = NULL;
     322            4 :                         assert (n_call_state_pool > 0);
     323            4 :                         --n_call_state_pool;
     324              :                 }
     325              : 
     326            7 :         pthread_mutex_unlock (&call_state_mutex);
     327              : 
     328            7 :         if (cs == NULL) {
     329            3 :                 cs = calloc(1, sizeof (CallState));
     330            3 :                 if (cs == NULL)
     331            0 :                         return CKR_HOST_MEMORY;
     332            3 :                 cs->socket = -1;
     333            3 :                 cs->call_status = CALL_INVALID;
     334              : 
     335              :                 /* Try to connect the call */
     336            3 :                 rv = call_connect (cs);
     337            3 :                 if (rv != CKR_OK) {
     338            1 :                         free (cs);
     339            1 :                         return rv;
     340              :                 }
     341              :         }
     342              : 
     343            6 :         assert (cs->call_status == CALL_READY);
     344            6 :         assert (cs->socket != -1);
     345            6 :         assert (cs->next == NULL);
     346            6 :         *ret = cs;
     347            6 :         return CKR_OK;
     348              : }
     349              : 
     350              : /* Perform the initial setup for a new call. */
     351              : static CK_RV
     352            6 : call_prepare (CallState *cs, int call_id)
     353              : {
     354            6 :         assert (cs);
     355            6 :         assert (cs->call_status == CALL_READY);
     356              : 
     357              :         /* Allocate a new request if we've lost the old one */
     358            6 :         if (!cs->req) {
     359            2 :                 cs->req = gkm_rpc_message_new (call_allocator);
     360            2 :                 if (!cs->req) {
     361            0 :                         warning (("cannot allocate request buffer: out of memory"));
     362            0 :                         return CKR_HOST_MEMORY;
     363              :                 }
     364              :         }
     365              : 
     366              :         /* Put in the Call ID and signature */
     367            6 :         gkm_rpc_message_reset (cs->req);
     368            6 :         if (!gkm_rpc_message_prep (cs->req, call_id, GKM_RPC_REQUEST))
     369            0 :                 return CKR_HOST_MEMORY;
     370              : 
     371              :         debug (("prepared call: %d", call_id));
     372              : 
     373              :         /* Ready to fill in arguments */
     374            6 :         cs->call_status = CALL_PREP;
     375            6 :         return CKR_OK;
     376              : }
     377              : 
     378              : /* Write all data to session socket.  */
     379              : static CK_RV
     380           12 : call_write (CallState *cs, unsigned char* data, size_t len)
     381              : {
     382              :         int fd, r;
     383              : 
     384           12 :         assert (cs);
     385           12 :         assert (data);
     386           12 :         assert (len > 0);
     387              : 
     388           24 :         while (len > 0) {
     389              : 
     390           12 :                 fd = cs->socket;
     391           12 :                 if (fd == -1) {
     392            0 :                         warning (("couldn't send data: socket has been closed"));
     393            0 :                         return CKR_DEVICE_ERROR;
     394              :                 }
     395              : 
     396           12 :                 r = write (fd, data, len);
     397              : 
     398           12 :                 if (r == -1) {
     399            0 :                         if (errno == EPIPE) {
     400            0 :                                 warning (("couldn't send data: daemon closed connection"));
     401            0 :                                 call_disconnect (cs);
     402            0 :                                 return CKR_DEVICE_ERROR;
     403            0 :                         } else if (errno != EAGAIN && errno != EINTR) {
     404            0 :                                 warning (("couldn't send data: %s", strerror (errno)));
     405            0 :                                 return CKR_DEVICE_ERROR;
     406              :                         }
     407              :                 } else {
     408              :                         debug (("wrote %d bytes", r));
     409           12 :                         data += r;
     410           12 :                         len -= r;
     411              :                 }
     412              :         }
     413              : 
     414           12 :         return CKR_OK;
     415              : }
     416              : 
     417              : /* Read a certain amount of data from session socket. */
     418              : static CK_RV
     419           12 : call_read (CallState *cs, unsigned char* data, size_t len)
     420              : {
     421              :         int fd, r;
     422              : 
     423           12 :         assert (cs);
     424           12 :         assert (data);
     425           12 :         assert (len > 0);
     426              : 
     427           24 :         while (len > 0) {
     428              : 
     429           12 :                 fd = cs->socket;
     430           12 :                 if (fd == -1) {
     431            0 :                         warning (("couldn't receive data: session socket has been closed"));
     432            0 :                         return CKR_DEVICE_ERROR;
     433              :                 }
     434              : 
     435           12 :                 r = read (fd, data, len);
     436              : 
     437           12 :                 if (r == 0) {
     438            0 :                         warning (("couldn't receive data: daemon closed connection"));
     439            0 :                         call_disconnect (cs);
     440            0 :                         return CKR_DEVICE_ERROR;
     441           12 :                 } else if (r == -1) {
     442            0 :                         if (errno != EAGAIN && errno != EINTR) {
     443            0 :                                 warning (("couldn't receive data: %s", strerror (errno)));
     444            0 :                                 return CKR_DEVICE_ERROR;
     445              :                         }
     446              :                 } else {
     447              :                         debug (("read %d bytes", r));
     448           12 :                         data += r;
     449           12 :                         len -= r;
     450              :                 }
     451              :         }
     452              : 
     453           12 :         return CKR_OK;
     454              : }
     455              : 
     456              : /*
     457              :  * Used by call_session_do_call() to actually send the message to the daemon.
     458              :  * Note how we unlock and relock the session during the call.
     459              :  */
     460              : static CK_RV
     461            6 : call_send_recv (CallState *cs)
     462              : {
     463              :         GkmRpcMessage *req, *resp;
     464              :         unsigned char buf[4];
     465              :         uint32_t len;
     466              :         CK_RV ret;
     467              : 
     468            6 :         assert (cs);
     469            6 :         assert (cs->req);
     470            6 :         assert (cs->call_status == CALL_PREP);
     471              : 
     472            6 :         cs->call_status = CALL_TRANSIT;
     473              : 
     474              :         /* Setup the response buffer properly */
     475            6 :         if (!cs->resp) {
     476              :                 /* TODO: Do secrets or passwords ever flow through here? */
     477            2 :                 cs->resp = gkm_rpc_message_new (call_allocator);
     478            2 :                 if (!cs->resp) {
     479            0 :                         warning (("couldn't allocate response buffer: out of memory"));
     480            0 :                         return CKR_HOST_MEMORY;
     481              :                 }
     482              :         }
     483            6 :         gkm_rpc_message_reset (cs->resp);
     484              : 
     485              :         /*
     486              :          * Now as an additional check to make sure nothing nasty will
     487              :          * happen while we are unlocked, we remove the request and
     488              :          * response from the session during the action.
     489              :          */
     490            6 :         req = cs->req;
     491            6 :         resp = cs->resp;
     492            6 :         cs->req = cs->resp = NULL;
     493              : 
     494              :         /* Send the number of bytes, and then the data */
     495            6 :         egg_buffer_encode_uint32 (buf, req->buffer.len);
     496            6 :         ret = call_write (cs, buf, 4);
     497            6 :         if (ret != CKR_OK)
     498            0 :                 goto cleanup;
     499            6 :         ret = call_write (cs, req->buffer.buf, req->buffer.len);
     500            6 :         if (ret != CKR_OK)
     501            0 :                 goto cleanup;
     502              : 
     503              :         /* Now read out the number of bytes, and then the data */
     504            6 :         ret = call_read (cs, buf, 4);
     505            6 :         if (ret != CKR_OK)
     506            0 :                 goto cleanup;
     507            6 :         len = egg_buffer_decode_uint32 (buf);
     508            6 :         if (!egg_buffer_reserve (&resp->buffer, len + resp->buffer.len)) {
     509            0 :                 warning (("couldn't allocate %u byte response area: out of memory", len));
     510            0 :                 ret = CKR_HOST_MEMORY;
     511            0 :                 goto cleanup;
     512              :         }
     513            6 :         ret = call_read (cs, resp->buffer.buf, len);
     514            6 :         if (ret != CKR_OK)
     515            0 :                 goto cleanup;
     516              : 
     517            6 :         egg_buffer_add_empty (&resp->buffer, len);
     518            6 :         if (!gkm_rpc_message_parse (resp, GKM_RPC_RESPONSE))
     519            0 :                 goto cleanup;
     520              : 
     521              :         debug (("received response from daemon"));
     522              : 
     523            6 : cleanup:
     524              :         /* Make sure nobody else used this thread while unlocked */
     525            6 :         assert (cs->call_status == CALL_TRANSIT);
     526            6 :         assert (cs->resp == NULL);
     527            6 :         cs->resp = resp;
     528            6 :         assert (cs->req == NULL);
     529            6 :         cs->req = req;
     530              : 
     531            6 :         return ret;
     532              : }
     533              : 
     534              : /*
     535              :  * At this point the request is ready. So we validate it, and we send it to
     536              :  * the daemon for a response.
     537              :  */
     538              : static CK_RV
     539            6 : call_run (CallState *cs)
     540              : {
     541            6 :         CK_RV ret = CKR_OK;
     542              :         CK_ULONG ckerr;
     543              : 
     544            6 :         assert (cs);
     545            6 :         assert (cs->req);
     546            6 :         assert (cs->call_status == CALL_PREP);
     547            6 :         assert (cs->socket != -1);
     548              : 
     549              :         /* Did building the call fail? */
     550            6 :         if (gkm_rpc_message_buffer_error (cs->req)) {
     551            0 :                 warning (("couldn't allocate request area: out of memory"));
     552            0 :                 return CKR_HOST_MEMORY;
     553              :         }
     554              : 
     555              :         /* Make sure that the signature is valid */
     556            6 :         assert (gkm_rpc_message_is_verified (cs->req));
     557              : 
     558              :         /* Do the dialog with daemon */
     559            6 :         ret = call_send_recv (cs);
     560              : 
     561            6 :         cs->call_status = CALL_PARSE;
     562              : 
     563            6 :         if (ret != CKR_OK)
     564            0 :                 return ret;
     565              : 
     566              :         /* If it's an error code then return it */
     567            6 :         if (cs->resp->call_id == GKM_RPC_CALL_ERROR) {
     568              : 
     569            0 :                 if (!gkm_rpc_message_read_ulong (cs->resp, &ckerr)) {
     570            0 :                         warning (("invalid error response from gnome-keyring-daemon: too short"));
     571            0 :                         return CKR_DEVICE_ERROR;
     572              :                 }
     573              : 
     574            0 :                 if (ckerr <= CKR_OK) {
     575            0 :                         warning (("invalid error response from gnome-keyring-daemon: bad error code"));
     576            0 :                         return CKR_DEVICE_ERROR;
     577              :                 }
     578              : 
     579              :                 /* An error code from the daemon */
     580            0 :                 return (CK_RV)ckerr;
     581              :         }
     582              : 
     583              :         /* Make sure daemon answered the right call */
     584            6 :         if (cs->req->call_id != cs->resp->call_id) {
     585            0 :                 warning (("invalid response from gnome-keyring-daemon: call mismatch"));
     586            0 :                 return CKR_DEVICE_ERROR;
     587              :         }
     588              : 
     589            6 :         assert (!gkm_rpc_message_buffer_error (cs->resp));
     590              :         debug (("parsing response values"));
     591              : 
     592            6 :         return CKR_OK;
     593              : }
     594              : 
     595              : static CK_RV
     596            6 : call_done (CallState *cs, CK_RV ret)
     597              : {
     598            6 :         assert (cs);
     599            6 :         assert (cs->call_status > CALL_INVALID);
     600              : 
     601            6 :         if (cs->call_status == CALL_PARSE && cs->req && cs->resp) {
     602              : 
     603              :                 /* Check for parsing errors that were not caught elsewhere */
     604            6 :                 if (ret == CKR_OK) {
     605              : 
     606            6 :                         if (gkm_rpc_message_buffer_error (cs->resp)) {
     607            0 :                                 warning (("invalid response from gnome-keyring-daemon: bad argument data"));
     608            0 :                                 ret = CKR_GENERAL_ERROR;
     609              :                         } else {
     610              :                                 /* Double check that the signature matched our decoding */
     611            6 :                                 assert (gkm_rpc_message_is_verified (cs->resp));
     612              :                         }
     613              :                 }
     614              :         }
     615              : 
     616              :         /* Certain error codes cause us to discard the conenction */
     617            6 :         if (ret != CKR_DEVICE_ERROR && ret != CKR_DEVICE_REMOVED && cs->socket != -1) {
     618              : 
     619              :                 /* Try and stash it away for later use */
     620            6 :                 pthread_mutex_lock (&call_state_mutex);
     621              : 
     622            6 :                         if (n_call_state_pool < MAX_CALL_STATE_POOL) {
     623            6 :                                 cs->call_status = CALL_READY;
     624            6 :                                 assert (cs->next == NULL);
     625            6 :                                 cs->next = call_state_pool;
     626            6 :                                 call_state_pool = cs;
     627            6 :                                 ++n_call_state_pool;
     628            6 :                                 cs = NULL;
     629              :                         }
     630              : 
     631            6 :                 pthread_mutex_unlock (&call_state_mutex);
     632              :         }
     633              : 
     634            6 :         if (cs != NULL)
     635            0 :                 call_destroy (cs);
     636              : 
     637            6 :         return ret;
     638              : }
     639              : 
     640              : /* -----------------------------------------------------------------------------
     641              :  * MODULE SPECIFIC PROTOCOL CODE
     642              :  */
     643              : 
     644              : static CK_RV
     645            0 : proto_read_attribute_array (GkmRpcMessage *msg, CK_ATTRIBUTE_PTR arr, CK_ULONG len)
     646              : {
     647              :         uint32_t i, num, value, type;
     648              :         CK_ATTRIBUTE_PTR attr;
     649              :         const unsigned char *attrval;
     650              :         size_t attrlen;
     651              :         unsigned char validity;
     652              :         CK_RV ret;
     653              : 
     654            0 :         assert (len);
     655            0 :         assert (msg);
     656              : 
     657              :         /* Make sure this is in the right order */
     658            0 :         assert (!msg->signature || gkm_rpc_message_verify_part (msg, "aA"));
     659              : 
     660              :         /* Get the number of items. We need this value to be correct */
     661            0 :         if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, &num))
     662            0 :                 return PARSE_ERROR;
     663              : 
     664            0 :         if (len != num) {
     665              : 
     666              :                 /*
     667              :                  * This should never happen in normal operation. It denotes a goof up
     668              :                  * on the other side of our RPC. We should be indicating the exact number
     669              :                  * of attributes to the other side. And it should respond with the same
     670              :                  * number.
     671              :                  */
     672              : 
     673            0 :                 warning (("received an attribute array with wrong number of attributes"));
     674            0 :                 return PARSE_ERROR;
     675              :         }
     676              : 
     677            0 :         ret = CKR_OK;
     678              : 
     679              :         /* We need to go ahead and read everything in all cases */
     680            0 :         for (i = 0; i < num; ++i) {
     681              : 
     682              :                 /* The attribute type */
     683            0 :                 egg_buffer_get_uint32 (&msg->buffer, msg->parsed,
     684              :                                        &msg->parsed, &type);
     685              : 
     686              :                 /* Attribute validity */
     687            0 :                 egg_buffer_get_byte (&msg->buffer, msg->parsed,
     688              :                                      &msg->parsed, &validity);
     689              : 
     690              :                 /* And the data itself */
     691            0 :                 if (validity) {
     692            0 :                         if (egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, &value) &&
     693            0 :                             egg_buffer_get_byte_array (&msg->buffer, msg->parsed, &msg->parsed, &attrval, &attrlen)) {
     694            0 :                                 if (attrval && value != attrlen) {
     695            0 :                                         warning (("attribute length does not match attribute data"));
     696            0 :                                         return PARSE_ERROR;
     697              :                                 }
     698            0 :                                 attrlen = value;
     699              :                         }
     700              :                 }
     701              : 
     702              :                 /* Don't act on this data unless no errors */
     703            0 :                 if (egg_buffer_has_error (&msg->buffer))
     704            0 :                         break;
     705              : 
     706              :                 /* Try and stuff it in the output data */
     707            0 :                 if (arr) {
     708            0 :                         attr = &(arr[i]);
     709            0 :                         if (attr->type != type) {
     710            0 :                                 warning (("returned attributes in invalid order"));
     711            0 :                                 return PARSE_ERROR;
     712              :                         }
     713              : 
     714            0 :                         if (validity) {
     715              :                                 /* Just requesting the attribute size */
     716            0 :                                 if (!attr->pValue) {
     717            0 :                                         attr->ulValueLen = attrlen;
     718              : 
     719              :                                 /* Wants attribute data, but too small */
     720            0 :                                 } else if (attr->ulValueLen < attrlen) {
     721            0 :                                         attr->ulValueLen = attrlen;
     722            0 :                                         ret = CKR_BUFFER_TOO_SMALL;
     723              : 
     724              :                                 /* Wants attribute data, value is null */
     725            0 :                                 } else if (attrval == NULL) {
     726            0 :                                         attr->ulValueLen = 0;
     727              : 
     728              :                                 /* Wants attribute data, enough space */
     729              :                                 } else {
     730            0 :                                         attr->ulValueLen = attrlen;
     731            0 :                                         memcpy (attr->pValue, attrval, attrlen);
     732              :                                 }
     733              : 
     734              :                         /* Not a valid attribute */
     735              :                         } else {
     736            0 :                                 attr->ulValueLen = ((CK_ULONG)-1);
     737              :                         }
     738              :                 }
     739              :         }
     740              : 
     741            0 :         if (egg_buffer_has_error (&msg->buffer))
     742            0 :                 return PARSE_ERROR;
     743              : 
     744              :         /* Read in the code that goes along with these attributes */
     745            0 :         if (!gkm_rpc_message_read_ulong (msg, &ret))
     746            0 :                 return PARSE_ERROR;
     747              : 
     748            0 :         return ret;
     749              : }
     750              : 
     751              : static CK_RV
     752            0 : proto_read_byte_array (GkmRpcMessage *msg, CK_BYTE_PTR arr,
     753              :                        CK_ULONG_PTR len, CK_ULONG max)
     754              : {
     755              :         const unsigned char *val;
     756              :         unsigned char valid;
     757              :         uint32_t length;
     758              :         size_t vlen;
     759              : 
     760            0 :         assert (len);
     761            0 :         assert (msg);
     762              : 
     763              :         /* Make sure this is in the right order */
     764            0 :         assert (!msg->signature || gkm_rpc_message_verify_part (msg, "ay"));
     765              : 
     766              :         /* A single byte which determines whether valid or not */
     767            0 :         if (!egg_buffer_get_byte (&msg->buffer, msg->parsed, &msg->parsed, &valid))
     768            0 :                 return PARSE_ERROR;
     769              : 
     770              :         /* If not valid, then just the length is encoded, this can signify CKR_BUFFER_TOO_SMALL */
     771            0 :         if (!valid) {
     772            0 :                 if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, &length))
     773            0 :                         return PARSE_ERROR;
     774              : 
     775            0 :                 *len = length;
     776              : 
     777            0 :                 if (arr)
     778            0 :                         return CKR_BUFFER_TOO_SMALL;
     779              :                 else
     780            0 :                         return CKR_OK;
     781              :         }
     782              : 
     783              :         /* Get the actual bytes */
     784            0 :         if (!egg_buffer_get_byte_array (&msg->buffer, msg->parsed, &msg->parsed, &val, &vlen))
     785            0 :                 return PARSE_ERROR;
     786              : 
     787            0 :         *len = vlen;
     788              : 
     789              :         /* Just asking us for size */
     790            0 :         if (!arr)
     791            0 :                 return CKR_OK;
     792              : 
     793            0 :         if (max < vlen)
     794            0 :                 return CKR_BUFFER_TOO_SMALL;
     795              : 
     796              :         /* Enough space, yay */
     797            0 :         memcpy (arr, val, vlen);
     798            0 :         return CKR_OK;
     799              : }
     800              : 
     801              : static CK_RV
     802            0 : proto_read_ulong_array (GkmRpcMessage *msg, CK_ULONG_PTR arr,
     803              :                         CK_ULONG_PTR len, CK_ULONG max)
     804              : {
     805              :         uint32_t i, num;
     806              :         uint64_t val;
     807              :         unsigned char valid;
     808              : 
     809            0 :         assert (len);
     810            0 :         assert (msg);
     811              : 
     812              :         /* Make sure this is in the right order */
     813            0 :         assert (!msg->signature || gkm_rpc_message_verify_part (msg, "au"));
     814              : 
     815              :         /* A single byte which determines whether valid or not */
     816            0 :         if (!egg_buffer_get_byte (&msg->buffer, msg->parsed, &msg->parsed, &valid))
     817            0 :                 return PARSE_ERROR;
     818              : 
     819              :         /* Get the number of items. */
     820            0 :         if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, &num))
     821            0 :                 return PARSE_ERROR;
     822              : 
     823            0 :         *len = num;
     824              : 
     825              :         /* If not valid, then just the length is encoded, this can signify CKR_BUFFER_TOO_SMALL */
     826            0 :         if (!valid) {
     827            0 :                 if (arr)
     828            0 :                         return CKR_BUFFER_TOO_SMALL;
     829              :                 else
     830            0 :                         return CKR_OK;
     831              :         }
     832              : 
     833            0 :         if (max < num)
     834            0 :                 return CKR_BUFFER_TOO_SMALL;
     835              : 
     836              :         /* We need to go ahead and read everything in all cases */
     837            0 :         for (i = 0; i < num; ++i) {
     838            0 :                 egg_buffer_get_uint64 (&msg->buffer, msg->parsed, &msg->parsed, &val);
     839            0 :                 if (arr)
     840            0 :                         arr[i] = (CK_ULONG)val;
     841              :         }
     842              : 
     843            0 :         return egg_buffer_has_error (&msg->buffer) ? PARSE_ERROR : CKR_OK;
     844              : }
     845              : 
     846              : static CK_RV
     847            0 : proto_write_mechanism (GkmRpcMessage *msg, CK_MECHANISM_PTR mech)
     848              : {
     849            0 :         assert (msg);
     850            0 :         assert (mech);
     851              : 
     852              :         /* Make sure this is in the right order */
     853            0 :         assert (!msg->signature || gkm_rpc_message_verify_part (msg, "M"));
     854              : 
     855              :         /* The mechanism type */
     856            0 :         egg_buffer_add_uint32 (&msg->buffer, mech->mechanism);
     857              : 
     858              :         /*
     859              :          * PKCS#11 mechanism parameters are not easy to serialize. They're
     860              :          * completely different for so many mechanisms, they contain
     861              :          * pointers to arbitrary memory, and many callers don't initialize
     862              :          * them completely or properly.
     863              :          *
     864              :          * We only support certain mechanisms.
     865              :          *
     866              :          * Also callers do yucky things like leaving parts of the structure
     867              :          * pointing to garbage if they don't think it's going to be used.
     868              :          */
     869              : 
     870            0 :         if (gkm_rpc_mechanism_has_no_parameters (mech->mechanism))
     871            0 :                 egg_buffer_add_byte_array (&msg->buffer, NULL, 0);
     872            0 :         else if (gkm_rpc_mechanism_has_sane_parameters (mech->mechanism))
     873            0 :                 egg_buffer_add_byte_array (&msg->buffer, mech->pParameter,
     874              :                                            mech->ulParameterLen);
     875              :         else
     876            0 :                 return CKR_MECHANISM_INVALID;
     877              : 
     878            0 :         return egg_buffer_has_error (&msg->buffer) ? CKR_HOST_MEMORY : CKR_OK;
     879              : }
     880              : 
     881              : static CK_RV
     882            2 : proto_read_info (GkmRpcMessage *msg, CK_INFO_PTR info)
     883              : {
     884            2 :         assert (msg);
     885            2 :         assert (info);
     886              : 
     887            4 :         if (!gkm_rpc_message_read_version (msg, &info->cryptokiVersion) ||
     888            4 :             !gkm_rpc_message_read_space_string (msg, info->manufacturerID, 32) ||
     889            4 :             !gkm_rpc_message_read_ulong (msg, &info->flags) ||
     890            4 :             !gkm_rpc_message_read_space_string (msg, info->libraryDescription, 32) ||
     891            2 :             !gkm_rpc_message_read_version (msg, &info->libraryVersion))
     892            0 :                 return PARSE_ERROR;
     893              : 
     894            2 :         return CKR_OK;
     895              : }
     896              : 
     897              : static CK_RV
     898            0 : proto_read_slot_info (GkmRpcMessage *msg, CK_SLOT_INFO_PTR info)
     899              : {
     900            0 :         assert (msg);
     901            0 :         assert (info);
     902              : 
     903            0 :         if (!gkm_rpc_message_read_space_string (msg, info->slotDescription, 64) ||
     904            0 :             !gkm_rpc_message_read_space_string (msg, info->manufacturerID, 32) ||
     905            0 :             !gkm_rpc_message_read_ulong (msg, &info->flags) ||
     906            0 :             !gkm_rpc_message_read_version (msg, &info->hardwareVersion) ||
     907            0 :             !gkm_rpc_message_read_version (msg, &info->firmwareVersion))
     908            0 :                 return PARSE_ERROR;
     909              : 
     910            0 :         return CKR_OK;
     911              : }
     912              : 
     913              : static CK_RV
     914            0 : proto_read_token_info (GkmRpcMessage *msg, CK_TOKEN_INFO_PTR info)
     915              : {
     916            0 :         assert (msg);
     917            0 :         assert (info);
     918              : 
     919            0 :         if (!gkm_rpc_message_read_space_string (msg, info->label, 32) ||
     920            0 :             !gkm_rpc_message_read_space_string (msg, info->manufacturerID, 32) ||
     921            0 :             !gkm_rpc_message_read_space_string (msg, info->model, 16) ||
     922            0 :             !gkm_rpc_message_read_space_string (msg, info->serialNumber, 16) ||
     923            0 :             !gkm_rpc_message_read_ulong (msg, &info->flags) ||
     924            0 :             !gkm_rpc_message_read_ulong (msg, &info->ulMaxSessionCount) ||
     925            0 :             !gkm_rpc_message_read_ulong (msg, &info->ulSessionCount) ||
     926            0 :             !gkm_rpc_message_read_ulong (msg, &info->ulMaxRwSessionCount) ||
     927            0 :             !gkm_rpc_message_read_ulong (msg, &info->ulRwSessionCount) ||
     928            0 :             !gkm_rpc_message_read_ulong (msg, &info->ulMaxPinLen) ||
     929            0 :             !gkm_rpc_message_read_ulong (msg, &info->ulMinPinLen) ||
     930            0 :             !gkm_rpc_message_read_ulong (msg, &info->ulTotalPublicMemory) ||
     931            0 :             !gkm_rpc_message_read_ulong (msg, &info->ulFreePublicMemory) ||
     932            0 :             !gkm_rpc_message_read_ulong (msg, &info->ulTotalPrivateMemory) ||
     933            0 :             !gkm_rpc_message_read_ulong (msg, &info->ulFreePrivateMemory) ||
     934            0 :             !gkm_rpc_message_read_version (msg, &info->hardwareVersion) ||
     935            0 :             !gkm_rpc_message_read_version (msg, &info->firmwareVersion) ||
     936            0 :             !gkm_rpc_message_read_space_string (msg, info->utcTime, 16))
     937            0 :                 return PARSE_ERROR;
     938              : 
     939            0 :         return CKR_OK;
     940              : }
     941              : 
     942              : static CK_RV
     943            0 : proto_read_mechanism_info (GkmRpcMessage *msg, CK_MECHANISM_INFO_PTR info)
     944              : {
     945            0 :         assert (msg);
     946            0 :         assert (info);
     947              : 
     948            0 :         if (!gkm_rpc_message_read_ulong (msg, &info->ulMinKeySize) ||
     949            0 :             !gkm_rpc_message_read_ulong (msg, &info->ulMaxKeySize) ||
     950            0 :             !gkm_rpc_message_read_ulong (msg, &info->flags))
     951            0 :                 return PARSE_ERROR;
     952              : 
     953            0 :         return CKR_OK;
     954              : }
     955              : 
     956              : static CK_RV
     957            0 : proto_read_sesssion_info (GkmRpcMessage *msg, CK_SESSION_INFO_PTR info)
     958              : {
     959            0 :         assert (msg);
     960            0 :         assert (info);
     961              : 
     962            0 :         if (!gkm_rpc_message_read_ulong (msg, &info->slotID) ||
     963            0 :             !gkm_rpc_message_read_ulong (msg, &info->state) ||
     964            0 :             !gkm_rpc_message_read_ulong (msg, &info->flags) ||
     965            0 :             !gkm_rpc_message_read_ulong (msg, &info->ulDeviceError))
     966            0 :                 return PARSE_ERROR;
     967              : 
     968            0 :         return CKR_OK;
     969              : }
     970              : 
     971              : /* -------------------------------------------------------------------
     972              :  * CALL MACROS
     973              :  */
     974              : 
     975              : #define BEGIN_CALL_OR(call_id, if_no_daemon) \
     976              :         debug ((#call_id ": enter")); \
     977              :         return_val_if_fail (pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); \
     978              :         {  \
     979              :                 CallState *_cs; \
     980              :                 CK_RV _ret = CKR_OK; \
     981              :                 _ret = call_lookup (&_cs); \
     982              :                 if (_ret == CKR_DEVICE_REMOVED) return (if_no_daemon); \
     983              :                 if (_ret != CKR_OK) return _ret; \
     984              :                 _ret = call_prepare (_cs, GKM_RPC_CALL_##call_id); \
     985              :                 if (_ret != CKR_OK) goto _cleanup;
     986              : 
     987              : #define PROCESS_CALL \
     988              :                 _ret = call_run (_cs); \
     989              :                 if (_ret != CKR_OK) goto _cleanup;
     990              : 
     991              : #define RETURN(ret) \
     992              :                 _ret = ret; \
     993              :                 goto _cleanup;
     994              : 
     995              : #define END_CALL \
     996              :         _cleanup: \
     997              :                 _ret = call_done (_cs, _ret); \
     998              :                 debug (("ret: %d", _ret)); \
     999              :                 return _ret; \
    1000              :         }
    1001              : 
    1002              : #define IN_BYTE(val) \
    1003              :         if (!gkm_rpc_message_write_byte (_cs->req, val)) \
    1004              :                 { _ret = CKR_HOST_MEMORY; goto _cleanup; }
    1005              : 
    1006              : #define IN_ULONG(val) \
    1007              :         if (!gkm_rpc_message_write_ulong (_cs->req, val)) \
    1008              :                 { _ret = CKR_HOST_MEMORY; goto _cleanup; }
    1009              : 
    1010              : #define IN_STRING(val) \
    1011              :         if (!gkm_rpc_message_write_zero_string (_cs->req, val)) \
    1012              :                 { _ret = CKR_HOST_MEMORY; goto _cleanup; }
    1013              : 
    1014              : #define IN_BYTE_BUFFER(arr, len) \
    1015              :         if (len == NULL) \
    1016              :                 { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \
    1017              :         if (!gkm_rpc_message_write_byte_buffer (_cs->req, arr ? *len : 0)) \
    1018              :                 { _ret = CKR_HOST_MEMORY; goto _cleanup; }
    1019              : 
    1020              : #define IN_BYTE_ARRAY(arr, len) \
    1021              :         if (len != 0 && arr == NULL) \
    1022              :                 { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \
    1023              :         if (!gkm_rpc_message_write_byte_array (_cs->req, arr, len)) \
    1024              :                 { _ret = CKR_HOST_MEMORY; goto _cleanup; }
    1025              : 
    1026              : #define IN_ULONG_BUFFER(arr, len) \
    1027              :         if (len == NULL) \
    1028              :                 { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \
    1029              :         if (!gkm_rpc_message_write_ulong_buffer (_cs->req, arr ? *len : 0)) \
    1030              :                 { _ret = CKR_HOST_MEMORY; goto _cleanup; }
    1031              : 
    1032              : #define IN_ULONG_ARRAY(arr, len) \
    1033              :         if (len != 0 && arr == NULL) \
    1034              :                 { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; }\
    1035              :         if (!gkm_rpc_message_write_ulong_array (_cs->req, arr, len)) \
    1036              :                 { _ret = CKR_HOST_MEMORY; goto _cleanup; }
    1037              : 
    1038              : #define IN_ATTRIBUTE_BUFFER(arr, num) \
    1039              :         if (num != 0 && arr == NULL) \
    1040              :                 { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \
    1041              :         if (!gkm_rpc_message_write_attribute_buffer (_cs->req, (arr), (num))) \
    1042              :                 { _ret = CKR_HOST_MEMORY; goto _cleanup; }
    1043              : 
    1044              : #define IN_ATTRIBUTE_ARRAY(arr, num) \
    1045              :         if (num != 0 && arr == NULL) \
    1046              :                 { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \
    1047              :         if (!gkm_rpc_message_write_attribute_array (_cs->req, (arr), (num))) \
    1048              :                 { _ret = CKR_HOST_MEMORY; goto _cleanup; }
    1049              : 
    1050              : #define IN_MECHANISM_TYPE(val) \
    1051              :         if(!gkm_rpc_mechanism_is_supported (val)) \
    1052              :                 { _ret = CKR_MECHANISM_INVALID; goto _cleanup; } \
    1053              :         if (!gkm_rpc_message_write_ulong (_cs->req, val)) \
    1054              :                 { _ret = CKR_HOST_MEMORY; goto _cleanup; }
    1055              : 
    1056              : #define IN_MECHANISM(val) \
    1057              :         if (val == NULL) \
    1058              :                 { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \
    1059              :         _ret = proto_write_mechanism (_cs->req, val); \
    1060              :         if (_ret != CKR_OK) goto _cleanup;
    1061              : 
    1062              : 
    1063              : 
    1064              : #define OUT_ULONG(val) \
    1065              :         if (val == NULL) \
    1066              :                 _ret = CKR_ARGUMENTS_BAD; \
    1067              :         if (_ret == CKR_OK && !gkm_rpc_message_read_ulong (_cs->resp, val)) \
    1068              :                 _ret = PARSE_ERROR;
    1069              : 
    1070              : #define OUT_BYTE_ARRAY(arr, len)  \
    1071              :         if (len == NULL) \
    1072              :                 _ret = CKR_ARGUMENTS_BAD; \
    1073              :         if (_ret == CKR_OK) \
    1074              :                 _ret = proto_read_byte_array (_cs->resp, (arr), (len), *(len));
    1075              : 
    1076              : #define OUT_ULONG_ARRAY(a, len) \
    1077              :         if (len == NULL) \
    1078              :                 _ret = CKR_ARGUMENTS_BAD; \
    1079              :         if (_ret == CKR_OK) \
    1080              :                 _ret = proto_read_ulong_array (_cs->resp, (a), (len), *(len));
    1081              : 
    1082              : #define OUT_ATTRIBUTE_ARRAY(arr, num) \
    1083              :         if (_ret == CKR_OK) \
    1084              :                 _ret = proto_read_attribute_array (_cs->resp, (arr), (num));
    1085              : 
    1086              : #define OUT_INFO(info) \
    1087              :         if (info == NULL) \
    1088              :                 _ret = CKR_ARGUMENTS_BAD; \
    1089              :         if (_ret == CKR_OK) \
    1090              :                 _ret = proto_read_info (_cs->resp, info);
    1091              : 
    1092              : #define OUT_SLOT_INFO(info) \
    1093              :         if (info == NULL) \
    1094              :                 _ret = CKR_ARGUMENTS_BAD; \
    1095              :         if (_ret == CKR_OK) \
    1096              :                 _ret = proto_read_slot_info (_cs->resp, info);
    1097              : 
    1098              : #define OUT_TOKEN_INFO(info) \
    1099              :         if (info == NULL) \
    1100              :                 _ret = CKR_ARGUMENTS_BAD; \
    1101              :         if (_ret == CKR_OK) \
    1102              :                 _ret = proto_read_token_info (_cs->resp, info);
    1103              : 
    1104              : #define OUT_SESSION_INFO(info) \
    1105              :         if (info == NULL) \
    1106              :                 _ret = CKR_ARGUMENTS_BAD; \
    1107              :         if (_ret == CKR_OK) \
    1108              :                 _ret = proto_read_sesssion_info (_cs->resp, info);
    1109              : 
    1110              : #define OUT_MECHANISM_TYPE_ARRAY(arr, len) \
    1111              :         if (len == NULL) \
    1112              :                 _ret = CKR_ARGUMENTS_BAD; \
    1113              :         if (_ret == CKR_OK) \
    1114              :                 _ret = proto_read_ulong_array (_cs->resp, (arr), (len), *(len)); \
    1115              :         if (_ret == CKR_OK && arr) \
    1116              :                 gkm_rpc_mechanism_list_purge (arr, len);
    1117              : 
    1118              : #define OUT_MECHANISM_INFO(info) \
    1119              :         if (info == NULL) \
    1120              :                 _ret = CKR_ARGUMENTS_BAD; \
    1121              :         if (_ret == CKR_OK) \
    1122              :                 _ret = proto_read_mechanism_info (_cs->resp, info);
    1123              : 
    1124              : 
    1125              : /* -------------------------------------------------------------------
    1126              :  * INITIALIZATION and 'GLOBAL' CALLS
    1127              :  */
    1128              : 
    1129              : static CK_RV
    1130            3 : rpc_C_Initialize (CK_VOID_PTR init_args)
    1131              : {
    1132            3 :         CK_C_INITIALIZE_ARGS_PTR args = NULL;
    1133            3 :         CK_RV ret = CKR_OK;
    1134              :         const char *path;
    1135              :         CallState *cs;
    1136              :         pid_t pid;
    1137              : 
    1138              :         debug (("C_Initialize: enter"));
    1139              : 
    1140              : #ifdef _DEBUG
    1141          207 :         GKM_RPC_CHECK_CALLS();
    1142              : #endif
    1143              : 
    1144            3 :         pthread_mutex_lock (&init_mutex);
    1145              : 
    1146            3 :                 if (init_args != NULL) {
    1147              :                         int supplied_ok;
    1148              : 
    1149              :                         /* pReserved must be NULL */
    1150            3 :                         args = init_args;
    1151              : 
    1152              :                         /* ALL supplied function pointers need to have the value either NULL or non-NULL. */
    1153            0 :                         supplied_ok = (args->CreateMutex == NULL && args->DestroyMutex == NULL &&
    1154            6 :                                        args->LockMutex == NULL && args->UnlockMutex == NULL) ||
    1155            3 :                                       (args->CreateMutex != NULL && args->DestroyMutex != NULL &&
    1156            3 :                                        args->LockMutex != NULL && args->UnlockMutex != NULL);
    1157            3 :                         if (!supplied_ok) {
    1158            0 :                                 warning (("invalid set of mutex calls supplied"));
    1159            0 :                                 ret = CKR_ARGUMENTS_BAD;
    1160            0 :                                 goto done;
    1161              :                         }
    1162              : 
    1163              :                         /*
    1164              :                          * When the CKF_OS_LOCKING_OK flag isn't set return an error.
    1165              :                          * We must be able to use our pthread functionality.
    1166              :                          */
    1167            3 :                         if (!(args->flags & CKF_OS_LOCKING_OK)) {
    1168            0 :                                 warning (("can't do without os locking"));
    1169            0 :                                 ret = CKR_CANT_LOCK;
    1170            0 :                                 goto done;
    1171              :                         }
    1172              : 
    1173              :                         /*
    1174              :                          * We support setting the socket path and other arguments from from the
    1175              :                          * pReserved pointer, similar to how NSS PKCS#11 components are initialized.
    1176              :                          */
    1177            3 :                         if (args->pReserved)
    1178            0 :                                 parse_arguments ((const char*)args->pReserved);
    1179              :                 }
    1180              : 
    1181            3 :                 pid = getpid ();
    1182            3 :                 if (pkcs11_initialized) {
    1183              : 
    1184              :                         /* This process has called C_Initialize already */
    1185            0 :                         if (pid == pkcs11_initialized_pid) {
    1186            0 :                                 warning (("C_Initialize called twice for same process"));
    1187            0 :                                 ret = CKR_CRYPTOKI_ALREADY_INITIALIZED;
    1188            0 :                                 goto done;
    1189              :                         }
    1190              :                 }
    1191              : 
    1192              :                 /* Lookup the socket path, append '/pkcs11' */
    1193            3 :                 if (pkcs11_socket_path == NULL) {
    1194            3 :                         path = getenv ("GNOME_KEYRING_CONTROL");
    1195            3 :                         if (path && path[0]) {
    1196            1 :                                 pkcs11_socket_path = malloc (strlen (path) + strlen ("/pkcs11") + 1);
    1197            1 :                                 if (pkcs11_socket_path == NULL) {
    1198            0 :                                         warning (("can't malloc memory"));
    1199            0 :                                         ret = CKR_HOST_MEMORY;
    1200            0 :                                         goto done;
    1201              :                                 }
    1202            1 :                                 sprintf (pkcs11_socket_path, "%s/pkcs11", path);
    1203              :                         } else {
    1204            2 :                                 path = getenv ("XDG_RUNTIME_DIR");
    1205            2 :                                 if (path) {
    1206            1 :                                         pkcs11_socket_path = malloc (strlen (path) + strlen ("/keyring/pkcs11") + 1);
    1207            1 :                                         if (pkcs11_socket_path == NULL) {
    1208            0 :                                                 warning (("can't malloc memory"));
    1209            0 :                                                 ret = CKR_HOST_MEMORY;
    1210            0 :                                                 goto done;
    1211              :                                         }
    1212            1 :                                         sprintf (pkcs11_socket_path, "%s/keyring/pkcs11", path);
    1213              :                                 }
    1214              :                         }
    1215              :                 }
    1216              : 
    1217              :                 /* Call through and initialize the daemon if available */
    1218            3 :                 if (pkcs11_socket_path != NULL) {
    1219            2 :                         ret = call_lookup (&cs);
    1220            2 :                         if (ret == CKR_OK) {
    1221            2 :                                 ret = call_prepare (cs, GKM_RPC_CALL_C_Initialize);
    1222            2 :                                 if (ret == CKR_OK)
    1223            2 :                                         if (!gkm_rpc_message_write_byte_array (cs->req, GKM_RPC_HANDSHAKE, GKM_RPC_HANDSHAKE_LEN))
    1224            0 :                                                 ret = CKR_HOST_MEMORY;
    1225            2 :                                 if (ret == CKR_OK)
    1226            2 :                                         ret = call_run (cs);
    1227            2 :                                 call_done (cs, ret);
    1228              : 
    1229              :                         /* No daemon available */
    1230            0 :                         } else if (ret == CKR_DEVICE_REMOVED) {
    1231            0 :                                 ret = CKR_OK;
    1232              :                         }
    1233              :                 }
    1234              : 
    1235            1 : done:
    1236              :                 /* Mark us as officially initialized */
    1237            3 :                 if (ret == CKR_OK) {
    1238            3 :                         pkcs11_initialized = 1;
    1239            3 :                         pkcs11_initialized_pid = pid;
    1240            0 :                 } else if (ret != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
    1241            0 :                         pkcs11_initialized = 0;
    1242            0 :                         pkcs11_initialized_pid = 0;
    1243            0 :                         free (pkcs11_socket_path);
    1244            0 :                         pkcs11_socket_path = NULL;
    1245              :                 }
    1246              : 
    1247            3 :         pthread_mutex_unlock (&init_mutex);
    1248              : 
    1249              :         debug (("C_Initialize: %d", ret));
    1250            3 :         return ret;
    1251              : }
    1252              : 
    1253              : static CK_RV
    1254            3 : rpc_C_Finalize (CK_VOID_PTR reserved)
    1255              : {
    1256              :         CallState *cs;
    1257            3 :         CK_RV ret = CKR_OK;
    1258              : 
    1259              :         debug (("C_Finalize: enter"));
    1260            3 :         return_val_if_fail (pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
    1261            3 :         return_val_if_fail (!reserved, CKR_ARGUMENTS_BAD);
    1262              : 
    1263            3 :         pthread_mutex_lock (&init_mutex);
    1264              : 
    1265            3 :                 if (pkcs11_socket_path != NULL) {
    1266            2 :                         ret = call_lookup (&cs);
    1267            2 :                         if (ret == CKR_OK) {
    1268            2 :                                 ret = call_prepare (cs, GKM_RPC_CALL_C_Finalize);
    1269            2 :                                 if (ret == CKR_OK)
    1270            2 :                                         ret = call_run (cs);
    1271            2 :                                 call_done (cs, ret);
    1272              : 
    1273              :                         /* No daemon available */
    1274            0 :                         } else if (ret == CKR_DEVICE_REMOVED) {
    1275            0 :                                 ret = CKR_OK;
    1276              :                         }
    1277              : 
    1278              : 
    1279            2 :                         if (ret != CKR_OK)
    1280            0 :                                 warning (("finalizing the daemon returned an error: %d", ret));
    1281              :                 }
    1282              : 
    1283              :                 /* Cleanup the call state pool */
    1284            5 :                 while (call_state_pool) {
    1285            2 :                         cs = call_state_pool;
    1286            2 :                         call_state_pool = cs->next;
    1287            2 :                         call_destroy (cs);
    1288              :                 }
    1289              : 
    1290              :                 /* This should stop all other calls in */
    1291            3 :                 pkcs11_initialized = 0;
    1292            3 :                 pkcs11_initialized_pid = 0;
    1293            3 :                 free (pkcs11_socket_path);
    1294            3 :                 pkcs11_socket_path = NULL;
    1295              : 
    1296            3 :         pthread_mutex_unlock (&init_mutex);
    1297              : 
    1298              :         debug (("C_Finalize: %d", CKR_OK));
    1299            3 :         return CKR_OK;
    1300              : }
    1301              : 
    1302              : static CK_RV
    1303            1 : fill_stand_in_info (CK_INFO_PTR info)
    1304              : {
    1305              :         static CK_INFO stand_in_info = {
    1306              :                 { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
    1307              :                 "GNOME Keyring                   ",
    1308              :                 0,
    1309              :                 "GNOME Keyring (without daemon)  ",
    1310              :                 { 1, 1 },
    1311              :         };
    1312            1 :         memcpy (info, &stand_in_info, sizeof (CK_INFO));
    1313            1 :         return CKR_OK;
    1314              : 
    1315              : }
    1316              : 
    1317              : static CK_RV
    1318            3 : rpc_C_GetInfo (CK_INFO_PTR info)
    1319              : {
    1320            3 :         return_val_if_fail (info, CKR_ARGUMENTS_BAD);
    1321              : 
    1322            3 :         BEGIN_CALL_OR (C_GetInfo, fill_stand_in_info (info));
    1323            2 :         PROCESS_CALL;
    1324            2 :                 OUT_INFO (info);
    1325            2 :         END_CALL;
    1326              : }
    1327              : 
    1328              : static CK_RV
    1329            0 : rpc_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
    1330              : {
    1331              :         /* This would be a strange call to receive */
    1332            0 :         return C_GetFunctionList (list);
    1333              : }
    1334              : 
    1335              : static CK_RV
    1336            0 : rpc_C_GetSlotList (CK_BBOOL token_present, CK_SLOT_ID_PTR slot_list, CK_ULONG_PTR count)
    1337              : {
    1338            0 :         return_val_if_fail (count, CKR_ARGUMENTS_BAD);
    1339              : 
    1340            0 :         BEGIN_CALL_OR (C_GetSlotList, (*count = 0, CKR_OK));
    1341            0 :                 IN_BYTE (token_present);
    1342            0 :                 IN_ULONG_BUFFER (slot_list, count);
    1343            0 :         PROCESS_CALL;
    1344            0 :                 OUT_ULONG_ARRAY (slot_list, count);
    1345            0 :         END_CALL;
    1346              : }
    1347              : 
    1348              : static CK_RV
    1349            0 : rpc_C_GetSlotInfo (CK_SLOT_ID id, CK_SLOT_INFO_PTR info)
    1350              : {
    1351            0 :         return_val_if_fail (info, CKR_ARGUMENTS_BAD);
    1352              : 
    1353            0 :         BEGIN_CALL_OR (C_GetSlotInfo, CKR_SLOT_ID_INVALID);
    1354            0 :                 IN_ULONG (id);
    1355            0 :         PROCESS_CALL;
    1356            0 :                 OUT_SLOT_INFO (info);
    1357            0 :         END_CALL;
    1358              : }
    1359              : 
    1360              : static CK_RV
    1361            0 : rpc_C_GetTokenInfo (CK_SLOT_ID id, CK_TOKEN_INFO_PTR info)
    1362              : {
    1363            0 :         return_val_if_fail (info, CKR_ARGUMENTS_BAD);
    1364              : 
    1365            0 :         BEGIN_CALL_OR (C_GetTokenInfo, CKR_SLOT_ID_INVALID);
    1366            0 :                 IN_ULONG (id);
    1367            0 :         PROCESS_CALL;
    1368            0 :                 OUT_TOKEN_INFO (info);
    1369            0 :         END_CALL;
    1370              : }
    1371              : 
    1372              : static CK_RV
    1373            0 : rpc_C_GetMechanismList (CK_SLOT_ID id, CK_MECHANISM_TYPE_PTR mechanism_list,
    1374              :                         CK_ULONG_PTR count)
    1375              : {
    1376            0 :         return_val_if_fail (count, CKR_ARGUMENTS_BAD);
    1377              : 
    1378            0 :         BEGIN_CALL_OR (C_GetMechanismList, CKR_SLOT_ID_INVALID);
    1379            0 :                 IN_ULONG (id);
    1380            0 :                 IN_ULONG_BUFFER (mechanism_list, count);
    1381            0 :         PROCESS_CALL;
    1382            0 :                 OUT_MECHANISM_TYPE_ARRAY (mechanism_list, count);
    1383            0 :         END_CALL;
    1384              : 
    1385              : }
    1386              : 
    1387              : static CK_RV
    1388            0 : rpc_C_GetMechanismInfo (CK_SLOT_ID id, CK_MECHANISM_TYPE type,
    1389              :                         CK_MECHANISM_INFO_PTR info)
    1390              : {
    1391            0 :         return_val_if_fail (info, CKR_ARGUMENTS_BAD);
    1392              : 
    1393            0 :         BEGIN_CALL_OR (C_GetMechanismInfo, CKR_SLOT_ID_INVALID);
    1394            0 :                 IN_ULONG (id);
    1395            0 :                 IN_MECHANISM_TYPE (type);
    1396            0 :         PROCESS_CALL;
    1397            0 :                 OUT_MECHANISM_INFO (info);
    1398            0 :         END_CALL;
    1399              : }
    1400              : 
    1401              : static CK_RV
    1402            0 : rpc_C_InitToken (CK_SLOT_ID id, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len,
    1403              :                  CK_UTF8CHAR_PTR label)
    1404              : {
    1405            0 :         BEGIN_CALL_OR (C_InitToken, CKR_SLOT_ID_INVALID);
    1406            0 :                 IN_ULONG (id);
    1407            0 :                 IN_BYTE_ARRAY (pin, pin_len);
    1408            0 :                 IN_STRING (label);
    1409            0 :         PROCESS_CALL;
    1410            0 :         END_CALL;
    1411              : }
    1412              : 
    1413              : static CK_RV
    1414            0 : rpc_C_WaitForSlotEvent (CK_FLAGS flags, CK_SLOT_ID_PTR slot, CK_VOID_PTR reserved)
    1415              : {
    1416            0 :         return_val_if_fail (slot, CKR_ARGUMENTS_BAD);
    1417              : 
    1418            0 :         BEGIN_CALL_OR (C_WaitForSlotEvent, CKR_DEVICE_REMOVED);
    1419            0 :                 IN_ULONG (flags);
    1420            0 :         PROCESS_CALL;
    1421            0 :                 OUT_ULONG (slot);
    1422            0 :         END_CALL;
    1423              : }
    1424              : 
    1425              : static CK_RV
    1426            0 : rpc_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data,
    1427              :                    CK_NOTIFY callback, CK_SESSION_HANDLE_PTR session)
    1428              : {
    1429            0 :         return_val_if_fail (session, CKR_ARGUMENTS_BAD);
    1430              : 
    1431            0 :         BEGIN_CALL_OR (C_OpenSession, CKR_SLOT_ID_INVALID);
    1432            0 :                 IN_ULONG (id);
    1433            0 :                 IN_ULONG (flags);
    1434            0 :         PROCESS_CALL;
    1435            0 :                 OUT_ULONG (session);
    1436            0 :         END_CALL;
    1437              : }
    1438              : 
    1439              : static CK_RV
    1440            0 : rpc_C_CloseSession (CK_SESSION_HANDLE session)
    1441              : {
    1442            0 :         BEGIN_CALL_OR (C_CloseSession, CKR_SESSION_HANDLE_INVALID);
    1443            0 :                 IN_ULONG (session);
    1444            0 :         PROCESS_CALL;
    1445            0 :         END_CALL;
    1446              : }
    1447              : 
    1448              : static CK_RV
    1449            0 : rpc_C_CloseAllSessions (CK_SLOT_ID id)
    1450              : {
    1451            0 :         BEGIN_CALL_OR (C_CloseAllSessions, CKR_SLOT_ID_INVALID);
    1452            0 :                 IN_ULONG (id);
    1453            0 :         PROCESS_CALL;
    1454            0 :         END_CALL;
    1455              : }
    1456              : 
    1457              : static CK_RV
    1458            0 : rpc_C_GetFunctionStatus (CK_SESSION_HANDLE session)
    1459              : {
    1460            0 :         BEGIN_CALL_OR (C_GetFunctionStatus, CKR_SESSION_HANDLE_INVALID);
    1461            0 :                 IN_ULONG (session);
    1462            0 :         PROCESS_CALL;
    1463            0 :         END_CALL;
    1464              : }
    1465              : 
    1466              : static CK_RV
    1467            0 : rpc_C_CancelFunction (CK_SESSION_HANDLE session)
    1468              : {
    1469            0 :         BEGIN_CALL_OR (C_CancelFunction, CKR_SESSION_HANDLE_INVALID);
    1470            0 :                 IN_ULONG (session);
    1471            0 :         PROCESS_CALL;
    1472            0 :         END_CALL;
    1473              : }
    1474              : 
    1475              : static CK_RV
    1476            0 : rpc_C_GetSessionInfo(CK_SESSION_HANDLE session, CK_SESSION_INFO_PTR info)
    1477              : {
    1478            0 :         return_val_if_fail (info, CKR_ARGUMENTS_BAD);
    1479              : 
    1480            0 :         BEGIN_CALL_OR (C_GetSessionInfo, CKR_SESSION_HANDLE_INVALID);
    1481            0 :                 IN_ULONG (session);
    1482            0 :         PROCESS_CALL;
    1483            0 :                 OUT_SESSION_INFO (info);
    1484            0 :         END_CALL;
    1485              : }
    1486              : 
    1487              : static CK_RV
    1488            0 : rpc_C_InitPIN (CK_SESSION_HANDLE session, CK_UTF8CHAR_PTR pin,
    1489              :                CK_ULONG pin_len)
    1490              : {
    1491            0 :         BEGIN_CALL_OR (C_InitPIN, CKR_SESSION_HANDLE_INVALID);
    1492            0 :                 IN_ULONG (session);
    1493            0 :                 IN_BYTE_ARRAY (pin, pin_len);
    1494            0 :         PROCESS_CALL;
    1495            0 :         END_CALL;
    1496              : }
    1497              : 
    1498              : static CK_RV
    1499            0 : rpc_C_SetPIN (CK_SESSION_HANDLE session, CK_UTF8CHAR_PTR old_pin,
    1500              :               CK_ULONG old_pin_len, CK_UTF8CHAR_PTR new_pin, CK_ULONG new_pin_len)
    1501              : {
    1502            0 :         BEGIN_CALL_OR (C_SetPIN, CKR_SESSION_HANDLE_INVALID);
    1503            0 :                 IN_ULONG (session);
    1504            0 :                 IN_BYTE_ARRAY (old_pin, old_pin_len);
    1505            0 :                 IN_BYTE_ARRAY (new_pin, old_pin_len);
    1506            0 :         PROCESS_CALL;
    1507            0 :         END_CALL;
    1508              : }
    1509              : 
    1510              : static CK_RV
    1511            0 : rpc_C_GetOperationState (CK_SESSION_HANDLE session, CK_BYTE_PTR operation_state,
    1512              :                          CK_ULONG_PTR operation_state_len)
    1513              : {
    1514            0 :         return_val_if_fail (operation_state_len, CKR_ARGUMENTS_BAD);
    1515              : 
    1516            0 :         BEGIN_CALL_OR (C_GetOperationState, CKR_SESSION_HANDLE_INVALID);
    1517            0 :                 IN_ULONG (session);
    1518            0 :                 IN_BYTE_BUFFER (operation_state, operation_state_len);
    1519            0 :         PROCESS_CALL;
    1520            0 :                 OUT_BYTE_ARRAY (operation_state, operation_state_len);
    1521            0 :         END_CALL;
    1522              : }
    1523              : 
    1524              : static CK_RV
    1525            0 : rpc_C_SetOperationState (CK_SESSION_HANDLE session, CK_BYTE_PTR operation_state,
    1526              :                          CK_ULONG operation_state_len, CK_OBJECT_HANDLE encryption_key,
    1527              :                          CK_OBJECT_HANDLE authentication_key)
    1528              : {
    1529            0 :         BEGIN_CALL_OR (C_SetOperationState, CKR_SESSION_HANDLE_INVALID);
    1530            0 :                 IN_ULONG (session);
    1531            0 :                 IN_BYTE_ARRAY (operation_state, operation_state_len);
    1532            0 :                 IN_ULONG (encryption_key);
    1533            0 :                 IN_ULONG (authentication_key);
    1534            0 :         PROCESS_CALL;
    1535            0 :         END_CALL;
    1536              : }
    1537              : 
    1538              : static CK_RV
    1539            0 : rpc_C_Login (CK_SESSION_HANDLE session, CK_USER_TYPE user_type,
    1540              :              CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
    1541              : {
    1542            0 :         BEGIN_CALL_OR (C_Login, CKR_SESSION_HANDLE_INVALID);
    1543            0 :                 IN_ULONG (session);
    1544            0 :                 IN_ULONG (user_type);
    1545            0 :                 IN_BYTE_ARRAY (pin, pin_len);
    1546            0 :         PROCESS_CALL;
    1547            0 :         END_CALL;
    1548              : }
    1549              : 
    1550              : static CK_RV
    1551            0 : rpc_C_Logout (CK_SESSION_HANDLE session)
    1552              : {
    1553            0 :         BEGIN_CALL_OR (C_Logout, CKR_SESSION_HANDLE_INVALID);
    1554            0 :                 IN_ULONG (session);
    1555            0 :         PROCESS_CALL;
    1556            0 :         END_CALL;
    1557              : }
    1558              : 
    1559              : static CK_RV
    1560            0 : rpc_C_CreateObject (CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR template,
    1561              :                     CK_ULONG count, CK_OBJECT_HANDLE_PTR new_object)
    1562              : {
    1563            0 :         return_val_if_fail (new_object, CKR_ARGUMENTS_BAD);
    1564              : 
    1565            0 :         BEGIN_CALL_OR (C_CreateObject, CKR_SESSION_HANDLE_INVALID);
    1566            0 :                 IN_ULONG (session);
    1567            0 :                 IN_ATTRIBUTE_ARRAY (template, count);
    1568            0 :         PROCESS_CALL;
    1569            0 :                 OUT_ULONG (new_object);
    1570            0 :         END_CALL;
    1571              : }
    1572              : 
    1573              : static CK_RV
    1574            0 : rpc_C_CopyObject (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
    1575              :                   CK_ATTRIBUTE_PTR template, CK_ULONG count,
    1576              :                   CK_OBJECT_HANDLE_PTR new_object)
    1577              : {
    1578            0 :         return_val_if_fail (new_object, CKR_ARGUMENTS_BAD);
    1579              : 
    1580            0 :         BEGIN_CALL_OR (C_CopyObject, CKR_SESSION_HANDLE_INVALID);
    1581            0 :                 IN_ULONG (session);
    1582            0 :                 IN_ULONG (object);
    1583            0 :                 IN_ATTRIBUTE_ARRAY (template, count);
    1584            0 :         PROCESS_CALL;
    1585            0 :                 OUT_ULONG (new_object);
    1586            0 :         END_CALL;
    1587              : }
    1588              : 
    1589              : 
    1590              : static CK_RV
    1591            0 : rpc_C_DestroyObject (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object)
    1592              : {
    1593            0 :         BEGIN_CALL_OR (C_DestroyObject, CKR_SESSION_HANDLE_INVALID);
    1594            0 :                 IN_ULONG (session);
    1595            0 :                 IN_ULONG (object);
    1596            0 :         PROCESS_CALL;
    1597            0 :         END_CALL;
    1598              : }
    1599              : 
    1600              : static CK_RV
    1601            0 : rpc_C_GetObjectSize (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
    1602              :                      CK_ULONG_PTR size)
    1603              : {
    1604            0 :         return_val_if_fail (size, CKR_ARGUMENTS_BAD);
    1605              : 
    1606            0 :         BEGIN_CALL_OR (C_GetObjectSize, CKR_SESSION_HANDLE_INVALID);
    1607            0 :                 IN_ULONG (session);
    1608            0 :                 IN_ULONG (object);
    1609            0 :         PROCESS_CALL;
    1610            0 :                 OUT_ULONG (size);
    1611            0 :         END_CALL;
    1612              : }
    1613              : 
    1614              : static CK_RV
    1615            0 : rpc_C_GetAttributeValue (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
    1616              :                          CK_ATTRIBUTE_PTR template, CK_ULONG count)
    1617              : {
    1618            0 :         BEGIN_CALL_OR (C_GetAttributeValue, CKR_SESSION_HANDLE_INVALID);
    1619            0 :                 IN_ULONG (session);
    1620            0 :                 IN_ULONG (object);
    1621            0 :                 IN_ATTRIBUTE_BUFFER (template, count);
    1622            0 :         PROCESS_CALL;
    1623            0 :                 OUT_ATTRIBUTE_ARRAY (template, count);
    1624            0 :         END_CALL;
    1625              : }
    1626              : 
    1627              : static CK_RV
    1628            0 : rpc_C_SetAttributeValue (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
    1629              :                          CK_ATTRIBUTE_PTR template, CK_ULONG count)
    1630              : {
    1631            0 :         BEGIN_CALL_OR (C_SetAttributeValue, CKR_SESSION_HANDLE_INVALID);
    1632            0 :                 IN_ULONG (session);
    1633            0 :                 IN_ULONG (object);
    1634            0 :                 IN_ATTRIBUTE_ARRAY (template, count);
    1635            0 :         PROCESS_CALL;
    1636            0 :         END_CALL;
    1637              : }
    1638              : 
    1639              : static CK_RV
    1640            0 : rpc_C_FindObjectsInit (CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR template,
    1641              :                        CK_ULONG count)
    1642              : {
    1643            0 :         BEGIN_CALL_OR (C_FindObjectsInit, CKR_SESSION_HANDLE_INVALID);
    1644            0 :                 IN_ULONG (session);
    1645            0 :                 IN_ATTRIBUTE_ARRAY (template, count);
    1646            0 :         PROCESS_CALL;
    1647            0 :         END_CALL;
    1648              : }
    1649              : 
    1650              : static CK_RV
    1651            0 : rpc_C_FindObjects (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR objects,
    1652              :                    CK_ULONG max_count, CK_ULONG_PTR count)
    1653              : {
    1654              :         /* HACK: To fix a stupid gcc warning */
    1655            0 :         CK_ULONG_PTR address_of_max_count = &max_count;
    1656              : 
    1657            0 :         return_val_if_fail (count, CKR_ARGUMENTS_BAD);
    1658              : 
    1659            0 :         BEGIN_CALL_OR (C_FindObjects, CKR_SESSION_HANDLE_INVALID);
    1660            0 :                 IN_ULONG (session);
    1661            0 :                 IN_ULONG_BUFFER (objects, address_of_max_count);
    1662            0 :         PROCESS_CALL;
    1663            0 :                 *count = max_count;
    1664            0 :                 OUT_ULONG_ARRAY (objects, count);
    1665            0 :         END_CALL;
    1666              : }
    1667              : 
    1668              : static CK_RV
    1669            0 : rpc_C_FindObjectsFinal (CK_SESSION_HANDLE session)
    1670              : {
    1671            0 :         BEGIN_CALL_OR (C_FindObjectsFinal, CKR_SESSION_HANDLE_INVALID);
    1672            0 :                 IN_ULONG (session);
    1673            0 :         PROCESS_CALL;
    1674            0 :         END_CALL;
    1675              : }
    1676              : 
    1677              : static CK_RV
    1678            0 : rpc_C_EncryptInit (CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
    1679              :                    CK_OBJECT_HANDLE key)
    1680              : {
    1681            0 :         BEGIN_CALL_OR (C_EncryptInit, CKR_SESSION_HANDLE_INVALID);
    1682            0 :                 IN_ULONG (session);
    1683            0 :                 IN_MECHANISM (mechanism);
    1684            0 :                 IN_ULONG (key);
    1685            0 :         PROCESS_CALL;
    1686            0 :         END_CALL;
    1687              : }
    1688              : 
    1689              : static CK_RV
    1690            0 : rpc_C_Encrypt (CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len,
    1691              :                CK_BYTE_PTR encrypted_data, CK_ULONG_PTR encrypted_data_len)
    1692              : {
    1693            0 :         return_val_if_fail (encrypted_data_len, CKR_ARGUMENTS_BAD);
    1694              : 
    1695            0 :         BEGIN_CALL_OR (C_Encrypt, CKR_SESSION_HANDLE_INVALID);
    1696            0 :                 IN_ULONG (session);
    1697            0 :                 IN_BYTE_ARRAY (data, data_len);
    1698            0 :                 IN_BYTE_BUFFER (encrypted_data, encrypted_data_len);
    1699            0 :         PROCESS_CALL;
    1700            0 :                 OUT_BYTE_ARRAY (encrypted_data, encrypted_data_len);
    1701            0 :         END_CALL;
    1702              : }
    1703              : 
    1704              : static CK_RV
    1705            0 : rpc_C_EncryptUpdate (CK_SESSION_HANDLE session, CK_BYTE_PTR part,
    1706              :                      CK_ULONG part_len, CK_BYTE_PTR encrypted_part,
    1707              :                      CK_ULONG_PTR encrypted_part_len)
    1708              : {
    1709            0 :         return_val_if_fail (encrypted_part_len, CKR_ARGUMENTS_BAD);
    1710              : 
    1711            0 :         BEGIN_CALL_OR (C_EncryptUpdate, CKR_SESSION_HANDLE_INVALID);
    1712            0 :                 IN_ULONG (session);
    1713            0 :                 IN_BYTE_ARRAY (part, part_len);
    1714            0 :                 IN_BYTE_BUFFER (encrypted_part, encrypted_part_len);
    1715            0 :         PROCESS_CALL;
    1716            0 :                 OUT_BYTE_ARRAY (encrypted_part, encrypted_part_len);
    1717            0 :         END_CALL;
    1718              : }
    1719              : 
    1720              : static CK_RV
    1721            0 : rpc_C_EncryptFinal (CK_SESSION_HANDLE session, CK_BYTE_PTR last_part,
    1722              :                     CK_ULONG_PTR last_part_len)
    1723              : {
    1724            0 :         return_val_if_fail (last_part_len, CKR_ARGUMENTS_BAD);
    1725              : 
    1726            0 :         BEGIN_CALL_OR (C_EncryptFinal, CKR_SESSION_HANDLE_INVALID);
    1727            0 :                 IN_ULONG (session);
    1728            0 :                 IN_BYTE_BUFFER (last_part, last_part_len);
    1729            0 :         PROCESS_CALL;
    1730            0 :                 OUT_BYTE_ARRAY (last_part, last_part_len);
    1731            0 :         END_CALL;
    1732              : }
    1733              : 
    1734              : static CK_RV
    1735            0 : rpc_C_DecryptInit (CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
    1736              :                    CK_OBJECT_HANDLE key)
    1737              : {
    1738            0 :         BEGIN_CALL_OR (C_DecryptInit, CKR_SESSION_HANDLE_INVALID);
    1739            0 :                 IN_ULONG (session);
    1740            0 :                 IN_MECHANISM (mechanism);
    1741            0 :                 IN_ULONG (key);
    1742            0 :         PROCESS_CALL;
    1743            0 :         END_CALL;
    1744              : }
    1745              : 
    1746              : static CK_RV
    1747            0 : rpc_C_Decrypt (CK_SESSION_HANDLE session, CK_BYTE_PTR enc_data,
    1748              :                CK_ULONG enc_data_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len)
    1749              : {
    1750            0 :         return_val_if_fail (data_len, CKR_ARGUMENTS_BAD);
    1751              : 
    1752            0 :         BEGIN_CALL_OR (C_Decrypt, CKR_SESSION_HANDLE_INVALID);
    1753            0 :                 IN_ULONG (session);
    1754            0 :                 IN_BYTE_ARRAY (enc_data, enc_data_len);
    1755            0 :                 IN_BYTE_BUFFER (data, data_len);
    1756            0 :         PROCESS_CALL;
    1757            0 :                 OUT_BYTE_ARRAY (data, data_len);
    1758            0 :         END_CALL;
    1759              : }
    1760              : 
    1761              : static CK_RV
    1762            0 : rpc_C_DecryptUpdate (CK_SESSION_HANDLE session, CK_BYTE_PTR enc_part,
    1763              :                      CK_ULONG enc_part_len, CK_BYTE_PTR part, CK_ULONG_PTR part_len)
    1764              : {
    1765            0 :         return_val_if_fail (part_len, CKR_ARGUMENTS_BAD);
    1766              : 
    1767            0 :         BEGIN_CALL_OR (C_DecryptUpdate, CKR_SESSION_HANDLE_INVALID);
    1768            0 :                 IN_ULONG (session);
    1769            0 :                 IN_BYTE_ARRAY (enc_part, enc_part_len);
    1770            0 :                 IN_BYTE_BUFFER (part, part_len);
    1771            0 :         PROCESS_CALL;
    1772            0 :                 OUT_BYTE_ARRAY (part, part_len);
    1773            0 :         END_CALL;
    1774              : }
    1775              : 
    1776              : static CK_RV
    1777            0 : rpc_C_DecryptFinal (CK_SESSION_HANDLE session, CK_BYTE_PTR last_part,
    1778              :                     CK_ULONG_PTR last_part_len)
    1779              : {
    1780            0 :         return_val_if_fail (last_part_len, CKR_ARGUMENTS_BAD);
    1781              : 
    1782            0 :         BEGIN_CALL_OR (C_DecryptFinal, CKR_SESSION_HANDLE_INVALID);
    1783            0 :                 IN_ULONG (session);
    1784            0 :                 IN_BYTE_BUFFER (last_part, last_part_len);
    1785            0 :         PROCESS_CALL;
    1786            0 :                 OUT_BYTE_ARRAY (last_part, last_part_len);
    1787            0 :         END_CALL;
    1788              : }
    1789              : 
    1790              : static CK_RV
    1791            0 : rpc_C_DigestInit (CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism)
    1792              : {
    1793            0 :         BEGIN_CALL_OR (C_DigestInit, CKR_SESSION_HANDLE_INVALID);
    1794            0 :                 IN_ULONG (session);
    1795            0 :                 IN_MECHANISM (mechanism);
    1796            0 :         PROCESS_CALL;
    1797            0 :         END_CALL;
    1798              : }
    1799              : 
    1800              : static CK_RV
    1801            0 : rpc_C_Digest (CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len,
    1802              :               CK_BYTE_PTR digest, CK_ULONG_PTR digest_len)
    1803              : {
    1804            0 :         return_val_if_fail (digest_len, CKR_ARGUMENTS_BAD);
    1805              : 
    1806            0 :         BEGIN_CALL_OR (C_Digest, CKR_SESSION_HANDLE_INVALID);
    1807            0 :                 IN_ULONG (session);
    1808            0 :                 IN_BYTE_ARRAY (data, data_len);
    1809            0 :                 IN_BYTE_BUFFER (digest, digest_len);
    1810            0 :         PROCESS_CALL;
    1811            0 :                 OUT_BYTE_ARRAY (digest, digest_len);
    1812            0 :         END_CALL;
    1813              : }
    1814              : 
    1815              : static CK_RV
    1816            0 : rpc_C_DigestUpdate (CK_SESSION_HANDLE session, CK_BYTE_PTR part, CK_ULONG part_len)
    1817              : {
    1818            0 :         BEGIN_CALL_OR (C_DigestUpdate, CKR_SESSION_HANDLE_INVALID);
    1819            0 :                 IN_ULONG (session);
    1820            0 :                 IN_BYTE_ARRAY (part, part_len);
    1821            0 :         PROCESS_CALL;
    1822            0 :         END_CALL;
    1823              : }
    1824              : 
    1825              : static CK_RV
    1826            0 : rpc_C_DigestKey (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key)
    1827              : {
    1828            0 :         BEGIN_CALL_OR (C_DigestKey, CKR_SESSION_HANDLE_INVALID);
    1829            0 :                 IN_ULONG (session);
    1830            0 :                 IN_ULONG (key);
    1831            0 :         PROCESS_CALL;
    1832            0 :         END_CALL;
    1833              : }
    1834              : 
    1835              : static CK_RV
    1836            0 : rpc_C_DigestFinal (CK_SESSION_HANDLE session, CK_BYTE_PTR digest,
    1837              :                    CK_ULONG_PTR digest_len)
    1838              : {
    1839            0 :         return_val_if_fail (digest_len, CKR_ARGUMENTS_BAD);
    1840              : 
    1841            0 :         BEGIN_CALL_OR (C_DigestFinal, CKR_SESSION_HANDLE_INVALID);
    1842            0 :                 IN_ULONG (session);
    1843            0 :                 IN_BYTE_BUFFER (digest, digest_len);
    1844            0 :         PROCESS_CALL;
    1845            0 :                 OUT_BYTE_ARRAY (digest, digest_len);
    1846            0 :         END_CALL;
    1847              : }
    1848              : 
    1849              : static CK_RV
    1850            0 : rpc_C_SignInit (CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
    1851              :                 CK_OBJECT_HANDLE key)
    1852              : {
    1853            0 :         BEGIN_CALL_OR (C_SignInit, CKR_SESSION_HANDLE_INVALID);
    1854            0 :                 IN_ULONG (session);
    1855            0 :                 IN_MECHANISM (mechanism);
    1856            0 :                 IN_ULONG (key);
    1857            0 :         PROCESS_CALL;
    1858            0 :         END_CALL;
    1859              : }
    1860              : 
    1861              : static CK_RV
    1862            0 : rpc_C_Sign (CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len,
    1863              :             CK_BYTE_PTR signature, CK_ULONG_PTR signature_len)
    1864              : {
    1865            0 :         return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD);
    1866              : 
    1867            0 :         BEGIN_CALL_OR (C_Sign, CKR_SESSION_HANDLE_INVALID);
    1868            0 :                 IN_ULONG (session);
    1869            0 :                 IN_BYTE_ARRAY (data, data_len);
    1870            0 :                 IN_BYTE_BUFFER (signature, signature_len);
    1871            0 :         PROCESS_CALL;
    1872            0 :                 OUT_BYTE_ARRAY (signature, signature_len);
    1873            0 :         END_CALL;
    1874              : }
    1875              : 
    1876              : static CK_RV
    1877            0 : rpc_C_SignUpdate (CK_SESSION_HANDLE session, CK_BYTE_PTR part, CK_ULONG part_len)
    1878              : {
    1879            0 :         return_val_if_fail (part_len, CKR_ARGUMENTS_BAD);
    1880              : 
    1881            0 :         BEGIN_CALL_OR (C_SignUpdate, CKR_SESSION_HANDLE_INVALID);
    1882            0 :                 IN_ULONG (session);
    1883            0 :                 IN_BYTE_ARRAY (part, part_len);
    1884            0 :         PROCESS_CALL;
    1885            0 :         END_CALL;
    1886              : }
    1887              : 
    1888              : static CK_RV
    1889            0 : rpc_C_SignFinal (CK_SESSION_HANDLE session, CK_BYTE_PTR signature,
    1890              :                  CK_ULONG_PTR signature_len)
    1891              : {
    1892            0 :         return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD);
    1893              : 
    1894            0 :         BEGIN_CALL_OR (C_SignFinal, CKR_SESSION_HANDLE_INVALID);
    1895            0 :                 IN_ULONG (session);
    1896            0 :                 IN_BYTE_BUFFER (signature, signature_len);
    1897            0 :         PROCESS_CALL;
    1898            0 :                 OUT_BYTE_ARRAY (signature, signature_len);
    1899            0 :         END_CALL;
    1900              : }
    1901              : 
    1902              : static CK_RV
    1903            0 : rpc_C_SignRecoverInit (CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
    1904              :                        CK_OBJECT_HANDLE key)
    1905              : {
    1906            0 :         BEGIN_CALL_OR (C_SignRecoverInit, CKR_SESSION_HANDLE_INVALID);
    1907            0 :                 IN_ULONG (session);
    1908            0 :                 IN_MECHANISM (mechanism);
    1909            0 :                 IN_ULONG (key);
    1910            0 :         PROCESS_CALL;
    1911            0 :         END_CALL;
    1912              : }
    1913              : 
    1914              : static CK_RV
    1915            0 : rpc_C_SignRecover (CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len,
    1916              :                    CK_BYTE_PTR signature, CK_ULONG_PTR signature_len)
    1917              : {
    1918            0 :         return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD);
    1919              : 
    1920            0 :         BEGIN_CALL_OR (C_SignRecover, CKR_SESSION_HANDLE_INVALID);
    1921            0 :                 IN_ULONG (session);
    1922            0 :                 IN_BYTE_ARRAY (data, data_len);
    1923            0 :                 IN_BYTE_BUFFER (signature, signature_len);
    1924            0 :         PROCESS_CALL;
    1925            0 :                 OUT_BYTE_ARRAY (signature, signature_len);
    1926            0 :         END_CALL;
    1927              : }
    1928              : 
    1929              : static CK_RV
    1930            0 : rpc_C_VerifyInit (CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
    1931              :                   CK_OBJECT_HANDLE key)
    1932              : {
    1933            0 :         BEGIN_CALL_OR (C_VerifyInit, CKR_SESSION_HANDLE_INVALID);
    1934            0 :                 IN_ULONG (session);
    1935            0 :                 IN_MECHANISM (mechanism);
    1936            0 :                 IN_ULONG (key);
    1937            0 :         PROCESS_CALL;
    1938            0 :         END_CALL;
    1939              : }
    1940              : 
    1941              : static CK_RV
    1942            0 : rpc_C_Verify (CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len,
    1943              :               CK_BYTE_PTR signature, CK_ULONG signature_len)
    1944              : {
    1945            0 :         BEGIN_CALL_OR (C_Verify, CKR_SESSION_HANDLE_INVALID);
    1946            0 :                 IN_ULONG (session);
    1947            0 :                 IN_BYTE_ARRAY (data, data_len);
    1948            0 :                 IN_BYTE_ARRAY (signature, signature_len);
    1949            0 :         PROCESS_CALL;
    1950            0 :         END_CALL;
    1951              : }
    1952              : 
    1953              : static CK_RV
    1954            0 : rpc_C_VerifyUpdate (CK_SESSION_HANDLE session, CK_BYTE_PTR part, CK_ULONG part_len)
    1955              : {
    1956            0 :         BEGIN_CALL_OR (C_VerifyUpdate, CKR_SESSION_HANDLE_INVALID);
    1957            0 :                 IN_ULONG (session);
    1958            0 :                 IN_BYTE_ARRAY (part, part_len);
    1959            0 :         PROCESS_CALL;
    1960            0 :         END_CALL;
    1961              : }
    1962              : 
    1963              : static CK_RV
    1964            0 : rpc_C_VerifyFinal (CK_SESSION_HANDLE session, CK_BYTE_PTR signature,
    1965              :                    CK_ULONG signature_len)
    1966              : {
    1967            0 :         BEGIN_CALL_OR (C_VerifyFinal, CKR_SESSION_HANDLE_INVALID);
    1968            0 :                 IN_ULONG (session);
    1969            0 :                 IN_BYTE_ARRAY (signature, signature_len);
    1970            0 :         PROCESS_CALL;
    1971            0 :         END_CALL;
    1972              : }
    1973              : 
    1974              : static CK_RV
    1975            0 : rpc_C_VerifyRecoverInit (CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
    1976              :                          CK_OBJECT_HANDLE key)
    1977              : {
    1978            0 :         BEGIN_CALL_OR (C_VerifyRecoverInit, CKR_SESSION_HANDLE_INVALID);
    1979            0 :                 IN_ULONG (session);
    1980            0 :                 IN_MECHANISM (mechanism);
    1981            0 :                 IN_ULONG (key);
    1982            0 :         PROCESS_CALL;
    1983            0 :         END_CALL;
    1984              : }
    1985              : 
    1986              : static CK_RV
    1987            0 : rpc_C_VerifyRecover (CK_SESSION_HANDLE session, CK_BYTE_PTR signature,
    1988              :                      CK_ULONG signature_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len)
    1989              : {
    1990            0 :         return_val_if_fail (data_len, CKR_ARGUMENTS_BAD);
    1991              : 
    1992            0 :         BEGIN_CALL_OR (C_VerifyRecover, CKR_SESSION_HANDLE_INVALID);
    1993            0 :                 IN_ULONG (session);
    1994            0 :                 IN_BYTE_ARRAY (signature, signature_len);
    1995            0 :                 IN_BYTE_BUFFER (data, data_len);
    1996            0 :         PROCESS_CALL;
    1997            0 :                 OUT_BYTE_ARRAY (data, data_len);
    1998            0 :         END_CALL;
    1999              : }
    2000              : 
    2001              : static CK_RV
    2002            0 : rpc_C_DigestEncryptUpdate (CK_SESSION_HANDLE session, CK_BYTE_PTR part,
    2003              :                            CK_ULONG part_len, CK_BYTE_PTR enc_part,
    2004              :                            CK_ULONG_PTR enc_part_len)
    2005              : {
    2006            0 :         return_val_if_fail (enc_part_len, CKR_ARGUMENTS_BAD);
    2007              : 
    2008            0 :         BEGIN_CALL_OR (C_DigestEncryptUpdate, CKR_SESSION_HANDLE_INVALID);
    2009            0 :                 IN_ULONG (session);
    2010            0 :                 IN_BYTE_ARRAY (part, part_len);
    2011            0 :                 IN_BYTE_BUFFER (enc_part, enc_part_len);
    2012            0 :         PROCESS_CALL;
    2013            0 :                 OUT_BYTE_ARRAY (enc_part, enc_part_len);
    2014            0 :         END_CALL;
    2015              : }
    2016              : 
    2017              : static CK_RV
    2018            0 : rpc_C_DecryptDigestUpdate (CK_SESSION_HANDLE session, CK_BYTE_PTR enc_part,
    2019              :                            CK_ULONG enc_part_len, CK_BYTE_PTR part,
    2020              :                            CK_ULONG_PTR part_len)
    2021              : {
    2022            0 :         return_val_if_fail (part_len, CKR_ARGUMENTS_BAD);
    2023              : 
    2024            0 :         BEGIN_CALL_OR (C_DecryptDigestUpdate, CKR_SESSION_HANDLE_INVALID);
    2025            0 :                 IN_ULONG (session);
    2026            0 :                 IN_BYTE_ARRAY (enc_part, enc_part_len);
    2027            0 :                 IN_BYTE_BUFFER (part, part_len);
    2028            0 :         PROCESS_CALL;
    2029            0 :                 OUT_BYTE_ARRAY (part, part_len);
    2030            0 :         END_CALL;
    2031              : }
    2032              : 
    2033              : static CK_RV
    2034            0 : rpc_C_SignEncryptUpdate (CK_SESSION_HANDLE session, CK_BYTE_PTR part,
    2035              :                          CK_ULONG part_len, CK_BYTE_PTR enc_part,
    2036              :                          CK_ULONG_PTR enc_part_len)
    2037              : {
    2038            0 :         return_val_if_fail (enc_part_len, CKR_ARGUMENTS_BAD);
    2039              : 
    2040            0 :         BEGIN_CALL_OR (C_SignEncryptUpdate, CKR_SESSION_HANDLE_INVALID);
    2041            0 :                 IN_ULONG (session);
    2042            0 :                 IN_BYTE_ARRAY (part, part_len);
    2043            0 :                 IN_BYTE_BUFFER (enc_part, enc_part_len);
    2044            0 :         PROCESS_CALL;
    2045            0 :                 OUT_BYTE_ARRAY (enc_part, enc_part_len);
    2046            0 :         END_CALL;
    2047              : }
    2048              : 
    2049              : static CK_RV
    2050            0 : rpc_C_DecryptVerifyUpdate (CK_SESSION_HANDLE session, CK_BYTE_PTR enc_part,
    2051              :                            CK_ULONG enc_part_len, CK_BYTE_PTR part,
    2052              :                            CK_ULONG_PTR part_len)
    2053              : {
    2054            0 :         return_val_if_fail (part_len, CKR_ARGUMENTS_BAD);
    2055              : 
    2056            0 :         BEGIN_CALL_OR (C_DecryptVerifyUpdate, CKR_SESSION_HANDLE_INVALID);
    2057            0 :                 IN_ULONG (session);
    2058            0 :                 IN_BYTE_ARRAY (enc_part, enc_part_len);
    2059            0 :                 IN_BYTE_BUFFER (part, part_len);
    2060            0 :         PROCESS_CALL;
    2061            0 :                 OUT_BYTE_ARRAY (part, part_len);
    2062            0 :         END_CALL;
    2063              : }
    2064              : 
    2065              : static CK_RV
    2066            0 : rpc_C_GenerateKey (CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
    2067              :                    CK_ATTRIBUTE_PTR template, CK_ULONG count,
    2068              :                    CK_OBJECT_HANDLE_PTR key)
    2069              : {
    2070            0 :         BEGIN_CALL_OR (C_GenerateKey, CKR_SESSION_HANDLE_INVALID);
    2071            0 :                 IN_ULONG (session);
    2072            0 :                 IN_MECHANISM (mechanism);
    2073            0 :                 IN_ATTRIBUTE_ARRAY (template, count);
    2074            0 :         PROCESS_CALL;
    2075            0 :                 OUT_ULONG (key);
    2076            0 :         END_CALL;
    2077              : }
    2078              : 
    2079              : static CK_RV
    2080            0 : rpc_C_GenerateKeyPair (CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
    2081              :                        CK_ATTRIBUTE_PTR pub_template, CK_ULONG pub_count,
    2082              :                        CK_ATTRIBUTE_PTR priv_template, CK_ULONG priv_count,
    2083              :                        CK_OBJECT_HANDLE_PTR pub_key, CK_OBJECT_HANDLE_PTR priv_key)
    2084              : {
    2085            0 :         BEGIN_CALL_OR (C_GenerateKeyPair, CKR_SESSION_HANDLE_INVALID);
    2086            0 :                 IN_ULONG (session);
    2087            0 :                 IN_MECHANISM (mechanism);
    2088            0 :                 IN_ATTRIBUTE_ARRAY (pub_template, pub_count);
    2089            0 :                 IN_ATTRIBUTE_ARRAY (priv_template, priv_count);
    2090            0 :         PROCESS_CALL;
    2091            0 :                 OUT_ULONG (pub_key);
    2092            0 :                 OUT_ULONG (priv_key);
    2093            0 :         END_CALL;
    2094              : }
    2095              : 
    2096              : static CK_RV
    2097            0 : rpc_C_WrapKey (CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
    2098              :                CK_OBJECT_HANDLE wrapping_key, CK_OBJECT_HANDLE key,
    2099              :                CK_BYTE_PTR wrapped_key, CK_ULONG_PTR wrapped_key_len)
    2100              : {
    2101            0 :         return_val_if_fail (wrapped_key_len, CKR_ARGUMENTS_BAD);
    2102              : 
    2103            0 :         BEGIN_CALL_OR (C_WrapKey, CKR_SESSION_HANDLE_INVALID);
    2104            0 :                 IN_ULONG (session);
    2105            0 :                 IN_MECHANISM (mechanism);
    2106            0 :                 IN_ULONG (wrapping_key);
    2107            0 :                 IN_ULONG (key);
    2108            0 :                 IN_BYTE_BUFFER (wrapped_key, wrapped_key_len);
    2109            0 :         PROCESS_CALL;
    2110            0 :                 OUT_BYTE_ARRAY (wrapped_key, wrapped_key_len);
    2111            0 :         END_CALL;
    2112              : }
    2113              : 
    2114              : static CK_RV
    2115            0 : rpc_C_UnwrapKey (CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
    2116              :                  CK_OBJECT_HANDLE unwrapping_key, CK_BYTE_PTR wrapped_key,
    2117              :                  CK_ULONG wrapped_key_len, CK_ATTRIBUTE_PTR template,
    2118              :                  CK_ULONG count, CK_OBJECT_HANDLE_PTR key)
    2119              : {
    2120            0 :         BEGIN_CALL_OR (C_UnwrapKey, CKR_SESSION_HANDLE_INVALID);
    2121            0 :                 IN_ULONG (session);
    2122            0 :                 IN_MECHANISM (mechanism);
    2123            0 :                 IN_ULONG (unwrapping_key);
    2124            0 :                 IN_BYTE_ARRAY (wrapped_key, wrapped_key_len);
    2125            0 :                 IN_ATTRIBUTE_ARRAY (template, count);
    2126            0 :         PROCESS_CALL;
    2127            0 :                 OUT_ULONG (key);
    2128            0 :         END_CALL;
    2129              : }
    2130              : 
    2131              : static CK_RV
    2132            0 : rpc_C_DeriveKey (CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
    2133              :                  CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE_PTR template,
    2134              :                  CK_ULONG count, CK_OBJECT_HANDLE_PTR key)
    2135              : {
    2136            0 :         BEGIN_CALL_OR (C_DeriveKey, CKR_SESSION_HANDLE_INVALID);
    2137            0 :                 IN_ULONG (session);
    2138            0 :                 IN_MECHANISM (mechanism);
    2139            0 :                 IN_ULONG (base_key);
    2140            0 :                 IN_ATTRIBUTE_ARRAY (template, count);
    2141            0 :         PROCESS_CALL;
    2142            0 :                 OUT_ULONG (key);
    2143            0 :         END_CALL;
    2144              : }
    2145              : 
    2146              : static CK_RV
    2147            0 : rpc_C_SeedRandom (CK_SESSION_HANDLE session, CK_BYTE_PTR seed, CK_ULONG seed_len)
    2148              : {
    2149            0 :         BEGIN_CALL_OR (C_SeedRandom, CKR_SESSION_HANDLE_INVALID);
    2150            0 :                 IN_ULONG (session);
    2151            0 :                 IN_BYTE_ARRAY (seed, seed_len);
    2152            0 :         PROCESS_CALL;
    2153            0 :         END_CALL;
    2154              : }
    2155              : 
    2156              : static CK_RV
    2157            0 : rpc_C_GenerateRandom (CK_SESSION_HANDLE session, CK_BYTE_PTR random_data,
    2158              :                       CK_ULONG random_len)
    2159              : {
    2160            0 :         CK_ULONG_PTR address = &random_len;
    2161            0 :         BEGIN_CALL_OR (C_GenerateRandom, CKR_SESSION_HANDLE_INVALID);
    2162            0 :                 IN_ULONG (session);
    2163            0 :                 IN_BYTE_BUFFER (random_data, address);
    2164            0 :         PROCESS_CALL;
    2165            0 :                 OUT_BYTE_ARRAY (random_data, address);
    2166            0 :         END_CALL;
    2167              : }
    2168              : 
    2169              : /* --------------------------------------------------------------------
    2170              :  * MODULE ENTRY POINT
    2171              :  */
    2172              : 
    2173              : /*
    2174              :  * PKCS#11 is broken here. It states that Unix compilers automatically byte
    2175              :  * pack structures. This is wrong. GCC on Linux aligns to 4 by default.
    2176              :  *
    2177              :  * This results in incompatibilities. Where this structure's first version
    2178              :  * members take up too much or too little space depending on how this module
    2179              :  * is compiled.
    2180              :  */
    2181              : 
    2182              : static CK_FUNCTION_LIST functionList = {
    2183              :         { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },  /* version */
    2184              :         rpc_C_Initialize,
    2185              :         rpc_C_Finalize,
    2186              :         rpc_C_GetInfo,
    2187              :         rpc_C_GetFunctionList,
    2188              :         rpc_C_GetSlotList,
    2189              :         rpc_C_GetSlotInfo,
    2190              :         rpc_C_GetTokenInfo,
    2191              :         rpc_C_GetMechanismList,
    2192              :         rpc_C_GetMechanismInfo,
    2193              :         rpc_C_InitToken,
    2194              :         rpc_C_InitPIN,
    2195              :         rpc_C_SetPIN,
    2196              :         rpc_C_OpenSession,
    2197              :         rpc_C_CloseSession,
    2198              :         rpc_C_CloseAllSessions,
    2199              :         rpc_C_GetSessionInfo,
    2200              :         rpc_C_GetOperationState,
    2201              :         rpc_C_SetOperationState,
    2202              :         rpc_C_Login,
    2203              :         rpc_C_Logout,
    2204              :         rpc_C_CreateObject,
    2205              :         rpc_C_CopyObject,
    2206              :         rpc_C_DestroyObject,
    2207              :         rpc_C_GetObjectSize,
    2208              :         rpc_C_GetAttributeValue,
    2209              :         rpc_C_SetAttributeValue,
    2210              :         rpc_C_FindObjectsInit,
    2211              :         rpc_C_FindObjects,
    2212              :         rpc_C_FindObjectsFinal,
    2213              :         rpc_C_EncryptInit,
    2214              :         rpc_C_Encrypt,
    2215              :         rpc_C_EncryptUpdate,
    2216              :         rpc_C_EncryptFinal,
    2217              :         rpc_C_DecryptInit,
    2218              :         rpc_C_Decrypt,
    2219              :         rpc_C_DecryptUpdate,
    2220              :         rpc_C_DecryptFinal,
    2221              :         rpc_C_DigestInit,
    2222              :         rpc_C_Digest,
    2223              :         rpc_C_DigestUpdate,
    2224              :         rpc_C_DigestKey,
    2225              :         rpc_C_DigestFinal,
    2226              :         rpc_C_SignInit,
    2227              :         rpc_C_Sign,
    2228              :         rpc_C_SignUpdate,
    2229              :         rpc_C_SignFinal,
    2230              :         rpc_C_SignRecoverInit,
    2231              :         rpc_C_SignRecover,
    2232              :         rpc_C_VerifyInit,
    2233              :         rpc_C_Verify,
    2234              :         rpc_C_VerifyUpdate,
    2235              :         rpc_C_VerifyFinal,
    2236              :         rpc_C_VerifyRecoverInit,
    2237              :         rpc_C_VerifyRecover,
    2238              :         rpc_C_DigestEncryptUpdate,
    2239              :         rpc_C_DecryptDigestUpdate,
    2240              :         rpc_C_SignEncryptUpdate,
    2241              :         rpc_C_DecryptVerifyUpdate,
    2242              :         rpc_C_GenerateKey,
    2243              :         rpc_C_GenerateKeyPair,
    2244              :         rpc_C_WrapKey,
    2245              :         rpc_C_UnwrapKey,
    2246              :         rpc_C_DeriveKey,
    2247              :         rpc_C_SeedRandom,
    2248              :         rpc_C_GenerateRandom,
    2249              :         rpc_C_GetFunctionStatus,
    2250              :         rpc_C_CancelFunction,
    2251              :         rpc_C_WaitForSlotEvent
    2252              : };
    2253              : 
    2254              : CK_RV
    2255            3 : C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
    2256              : {
    2257            3 :         return_val_if_fail (list, CKR_ARGUMENTS_BAD);
    2258              : 
    2259            3 :         *list = &functionList;
    2260            3 :         return CKR_OK;
    2261              : }
        

Generated by: LCOV version 2.0-1