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 : }
|