Line data Source code
1 : /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 : /* gkm-rpc-dispatch.h - receiver of our PKCS#11 protocol.
3 :
4 : Copyright (C) 2008, Stef 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 : #include "pkcs11/pkcs11i.h"
30 :
31 : #include "egg/egg-error.h"
32 : #include "egg/egg-unix-credentials.h"
33 :
34 : #include <glib.h>
35 :
36 : #include <sys/types.h>
37 : #include <sys/param.h>
38 : #include <sys/socket.h>
39 : #include <sys/un.h>
40 : #include <pthread.h>
41 :
42 : #include <stdlib.h>
43 : #include <string.h>
44 : #include <unistd.h>
45 : #include <errno.h>
46 : #include <stdio.h>
47 :
48 : #include <glib.h>
49 :
50 : /* Where we dispatch the calls to */
51 : static CK_FUNCTION_LIST_PTR pkcs11_module = NULL;
52 :
53 : /* The error returned on protocol failures */
54 : #define PARSE_ERROR CKR_DEVICE_ERROR
55 : #define PREP_ERROR CKR_DEVICE_MEMORY
56 :
57 : /* -----------------------------------------------------------------------------
58 : * LOGGING and DEBUGGING
59 : */
60 :
61 : #if DEBUG_OUTPUT
62 : #define debug(x) gkm_rpc_debug x
63 : #else
64 : #define debug(x)
65 : #endif
66 :
67 : #define warning(x) gkm_rpc_warn x
68 :
69 : #define return_val_if_fail(x, v) \
70 : if (!(x)) { rpc_warn ("'%s' not true at %s", #x, __func__); return v; }
71 :
72 : void
73 0 : gkm_rpc_log (const char *line)
74 : {
75 0 : g_message ("%s", line);
76 0 : }
77 :
78 : /* -------------------------------------------------------------------------------
79 : * CALL STRUCTURES
80 : */
81 :
82 : typedef struct _ClientInstance {
83 : struct _ClientInstance *next;
84 : CK_G_APPLICATION application;
85 : pid_t pid;
86 : uid_t uid;
87 : int refcount;
88 : } ClientInstance;
89 :
90 : typedef struct _CallState {
91 : GkmRpcMessage *req;
92 : GkmRpcMessage *resp;
93 : void *allocated;
94 : ClientInstance *client;
95 : } CallState;
96 :
97 : static ClientInstance *clients = NULL;
98 : static pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER;
99 :
100 : static int
101 2 : call_init (CallState *cs, uid_t uid, pid_t pid)
102 : {
103 : ClientInstance *cl;
104 :
105 2 : assert (cs);
106 :
107 2 : cs->req = gkm_rpc_message_new ((EggBufferAllocator)realloc);
108 2 : cs->resp = gkm_rpc_message_new ((EggBufferAllocator)realloc);
109 2 : if (!cs->req || !cs->resp) {
110 0 : gkm_rpc_message_free (cs->req);
111 0 : gkm_rpc_message_free (cs->resp);
112 0 : return 0;
113 : }
114 :
115 2 : pthread_mutex_lock (&clients_mutex);
116 :
117 2 : for (cl = clients; cl; cl = cl->next) {
118 0 : if (cl->uid == uid && cl->pid == pid) {
119 0 : cl->refcount++;
120 0 : break;
121 : }
122 : }
123 2 : if (!cl) {
124 2 : cl = malloc (sizeof (*cl));
125 2 : if (!cl) {
126 0 : pthread_mutex_unlock (&clients_mutex);
127 0 : return 0;
128 : }
129 2 : cl->next = clients;
130 2 : clients = cl;
131 :
132 2 : cl->uid = uid;
133 2 : cl->pid = pid;
134 2 : cl->refcount = 1;
135 :
136 2 : memset (&cl->application, 0, sizeof (cl->application));
137 2 : cl->application.applicationData = cl;
138 : }
139 :
140 2 : pthread_mutex_unlock (&clients_mutex);
141 :
142 2 : cs->client = cl;
143 2 : cs->allocated = NULL;
144 2 : return 1;
145 : }
146 :
147 : static void*
148 0 : call_alloc (CallState *cs, size_t length)
149 : {
150 : void **data;
151 :
152 0 : assert (cs);
153 :
154 0 : if (length > 0x7fffffff)
155 0 : return NULL;
156 :
157 0 : data = malloc (sizeof (void*) + length);
158 0 : if (!data)
159 0 : return NULL;
160 :
161 : /* Munch up the memory to help catch bugs */
162 0 : memset (data, 0xff, sizeof (void*) + length);
163 :
164 : /* Store pointer to next allocated block at beginning */
165 0 : *data = cs->allocated;
166 0 : cs->allocated = data;
167 :
168 : /* Data starts after first pointer */
169 0 : return (void*)(data + 1);
170 : }
171 :
172 : static void
173 10 : call_reset (CallState *cs)
174 : {
175 : void *allocated;
176 : void **data;
177 :
178 10 : assert (cs);
179 :
180 10 : allocated = cs->allocated;
181 10 : while (allocated) {
182 0 : data = (void**)allocated;
183 :
184 : /* Pointer to the next allocation */
185 0 : allocated = *data;
186 0 : free (data);
187 : }
188 :
189 10 : cs->allocated = NULL;
190 10 : gkm_rpc_message_reset (cs->req);
191 10 : gkm_rpc_message_reset (cs->resp);
192 10 : }
193 :
194 : static void
195 2 : call_uninit (CallState *cs)
196 : {
197 2 : assert (cs);
198 :
199 2 : call_reset (cs);
200 :
201 2 : gkm_rpc_message_free (cs->req);
202 2 : gkm_rpc_message_free (cs->resp);
203 2 : }
204 :
205 : /* -------------------------------------------------------------------
206 : * PROTOCOL CODE
207 : */
208 :
209 : static CK_RV
210 0 : proto_read_byte_buffer (CallState *cs, CK_BYTE_PTR* buffer, CK_ULONG* n_buffer)
211 : {
212 : GkmRpcMessage *msg;
213 : uint32_t length;
214 :
215 0 : assert (cs);
216 0 : assert (buffer);
217 0 : assert (n_buffer);
218 :
219 0 : msg = cs->req;
220 :
221 : /* Check that we're supposed to be reading this at this point */
222 0 : assert (!msg->signature || gkm_rpc_message_verify_part (msg, "fy"));
223 :
224 : /* The number of ulongs there's room for on the other end */
225 0 : if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, &length))
226 0 : return PARSE_ERROR;
227 :
228 0 : *n_buffer = length;
229 0 : *buffer = NULL;
230 :
231 : /* If set to zero, then they just want the length */
232 0 : if (!length)
233 0 : return CKR_OK;
234 :
235 0 : *buffer = call_alloc (cs, length * sizeof (CK_BYTE));
236 0 : if (!*buffer)
237 0 : return CKR_DEVICE_MEMORY;
238 :
239 0 : return CKR_OK;
240 : }
241 :
242 : static CK_RV
243 2 : proto_read_byte_array (CallState *cs, CK_BYTE_PTR* array, CK_ULONG* n_array)
244 : {
245 : GkmRpcMessage *msg;
246 : const unsigned char *data;
247 : unsigned char valid;
248 : size_t n_data;
249 :
250 2 : assert (cs);
251 :
252 2 : msg = cs->req;
253 :
254 : /* Check that we're supposed to have this at this point */
255 2 : assert (!msg->signature || gkm_rpc_message_verify_part (msg, "ay"));
256 :
257 : /* Read out the byte which says whether data is present or not */
258 2 : if (!egg_buffer_get_byte (&msg->buffer, msg->parsed, &msg->parsed, &valid))
259 0 : return PARSE_ERROR;
260 :
261 2 : if (!valid) {
262 0 : *array = NULL;
263 0 : *n_array = 0;
264 0 : return CKR_OK;
265 : }
266 :
267 : /* Point our arguments into the buffer */
268 2 : if (!egg_buffer_get_byte_array (&msg->buffer, msg->parsed, &msg->parsed,
269 : &data, &n_data))
270 0 : return PARSE_ERROR;
271 :
272 2 : *array = (CK_BYTE_PTR)data;
273 2 : *n_array = n_data;
274 2 : return CKR_OK;
275 : }
276 :
277 : static CK_RV
278 0 : proto_write_byte_array (CallState *cs, CK_BYTE_PTR array, CK_ULONG len, CK_RV ret)
279 : {
280 0 : assert (cs);
281 :
282 : /*
283 : * When returning an byte array, in many cases we need to pass
284 : * an invalid array along with a length, which signifies CKR_BUFFER_TOO_SMALL.
285 : */
286 :
287 0 : switch (ret) {
288 0 : case CKR_BUFFER_TOO_SMALL:
289 0 : array = NULL;
290 : /* fall through */
291 0 : case CKR_OK:
292 0 : break;
293 :
294 : /* Pass all other errors straight through */
295 0 : default:
296 0 : return ret;
297 : };
298 :
299 0 : if (!gkm_rpc_message_write_byte_array (cs->resp, array, len))
300 0 : return PREP_ERROR;
301 :
302 0 : return CKR_OK;
303 : }
304 :
305 : static CK_RV
306 0 : proto_read_ulong_buffer (CallState *cs, CK_ULONG_PTR* buffer, CK_ULONG* n_buffer)
307 : {
308 : GkmRpcMessage *msg;
309 : uint32_t length;
310 :
311 0 : assert (cs);
312 0 : assert (buffer);
313 0 : assert (n_buffer);
314 :
315 0 : msg = cs->req;
316 :
317 : /* Check that we're supposed to be reading this at this point */
318 0 : assert (!msg->signature || gkm_rpc_message_verify_part (msg, "fu"));
319 :
320 : /* The number of ulongs there's room for on the other end */
321 0 : if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, &length))
322 0 : return PARSE_ERROR;
323 :
324 0 : *n_buffer = length;
325 0 : *buffer = NULL;
326 :
327 : /* If set to zero, then they just want the length */
328 0 : if (!length)
329 0 : return CKR_OK;
330 :
331 0 : *buffer = call_alloc (cs, length * sizeof (CK_ULONG));
332 0 : if (!*buffer)
333 0 : return CKR_DEVICE_MEMORY;
334 :
335 0 : return CKR_OK;
336 : }
337 :
338 : static CK_RV
339 0 : proto_write_ulong_array (CallState *cs, CK_ULONG_PTR array, CK_ULONG len, CK_RV ret)
340 : {
341 0 : assert (cs);
342 :
343 : /*
344 : * When returning an ulong array, in many cases we need to pass
345 : * an invalid array along with a length, which signifies CKR_BUFFER_TOO_SMALL.
346 : */
347 :
348 0 : switch (ret) {
349 0 : case CKR_BUFFER_TOO_SMALL:
350 0 : array = NULL;
351 : /* fall through */
352 0 : case CKR_OK:
353 0 : break;
354 :
355 : /* Pass all other errors straight through */
356 0 : default:
357 0 : return ret;
358 : };
359 :
360 0 : if (!gkm_rpc_message_write_ulong_array (cs->resp, array, len))
361 0 : return PREP_ERROR;
362 :
363 0 : return CKR_OK;
364 : }
365 :
366 : static CK_RV
367 0 : proto_read_attribute_buffer (CallState *cs, CK_ATTRIBUTE_PTR* result, CK_ULONG* n_result)
368 : {
369 : CK_ATTRIBUTE_PTR attrs;
370 : GkmRpcMessage *msg;
371 : uint32_t n_attrs, i;
372 : uint32_t value;
373 :
374 0 : assert (cs);
375 0 : assert (result);
376 0 : assert (n_result);
377 :
378 0 : msg = cs->req;
379 :
380 : /* Make sure this is in the rigth order */
381 0 : assert (!msg->signature || gkm_rpc_message_verify_part (msg, "fA"));
382 :
383 : /* Read the number of attributes */
384 0 : if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, &n_attrs))
385 0 : return PARSE_ERROR;
386 :
387 : /* Allocate memory for the attribute structures */
388 0 : attrs = call_alloc (cs, n_attrs * sizeof (CK_ATTRIBUTE));
389 0 : if (!attrs)
390 0 : return CKR_DEVICE_MEMORY;
391 :
392 : /* Now go through and fill in each one */
393 0 : for (i = 0; i < n_attrs; ++i) {
394 :
395 : /* The attribute type */
396 0 : if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, &value))
397 0 : return PARSE_ERROR;
398 :
399 0 : attrs[i].type = value;
400 :
401 : /* The number of bytes to allocate */
402 0 : if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, &value))
403 0 : return PARSE_ERROR;
404 :
405 0 : if (value == 0) {
406 0 : attrs[i].pValue = NULL;
407 0 : attrs[i].ulValueLen = 0;
408 : } else {
409 0 : attrs[i].pValue = call_alloc (cs, value);
410 0 : if (!attrs[i].pValue)
411 0 : return CKR_DEVICE_MEMORY;
412 0 : attrs[i].ulValueLen = value;
413 : }
414 : }
415 :
416 0 : *result = attrs;
417 0 : *n_result = n_attrs;
418 0 : return CKR_OK;
419 : }
420 :
421 : static CK_RV
422 0 : proto_read_attribute_array (CallState *cs, CK_ATTRIBUTE_PTR* result, CK_ULONG* n_result)
423 : {
424 : CK_ATTRIBUTE_PTR attrs;
425 : const unsigned char *data;
426 : unsigned char valid;
427 : GkmRpcMessage *msg;
428 : uint32_t n_attrs, i;
429 : uint32_t value;
430 : size_t n_data;
431 :
432 0 : assert (cs);
433 0 : assert (result);
434 0 : assert (n_result);
435 :
436 0 : msg = cs->req;
437 :
438 : /* Make sure this is in the rigth order */
439 0 : assert (!msg->signature || gkm_rpc_message_verify_part (msg, "aA"));
440 :
441 : /* Read the number of attributes */
442 0 : if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, &n_attrs))
443 0 : return PARSE_ERROR;
444 :
445 : /* Allocate memory for the attribute structures */
446 0 : attrs = call_alloc (cs, n_attrs * sizeof (CK_ATTRIBUTE));
447 0 : if (!attrs)
448 0 : return CKR_DEVICE_MEMORY;
449 :
450 : /* Now go through and fill in each one */
451 0 : for (i = 0; i < n_attrs; ++i) {
452 :
453 : /* The attribute type */
454 0 : if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, &value))
455 0 : return PARSE_ERROR;
456 :
457 0 : attrs[i].type = value;
458 :
459 : /* Whether this one is valid or not */
460 0 : if (!egg_buffer_get_byte (&msg->buffer, msg->parsed, &msg->parsed, &valid))
461 0 : return PARSE_ERROR;
462 :
463 0 : if (valid) {
464 0 : if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, &value))
465 0 : return PARSE_ERROR;
466 0 : if (!egg_buffer_get_byte_array (&msg->buffer, msg->parsed, &msg->parsed, &data, &n_data))
467 0 : return PARSE_ERROR;
468 :
469 0 : if (data != NULL && n_data != value) {
470 0 : g_warning ("attribute length and data do not match");
471 0 : return PARSE_ERROR;
472 : }
473 :
474 0 : attrs[i].pValue = (CK_VOID_PTR)data;
475 0 : attrs[i].ulValueLen = value;
476 : } else {
477 0 : attrs[i].pValue = NULL;
478 0 : attrs[i].ulValueLen = -1;
479 : }
480 : }
481 :
482 0 : *result = attrs;
483 0 : *n_result = n_attrs;
484 0 : return CKR_OK;
485 : }
486 :
487 : static CK_RV
488 0 : proto_write_attribute_array (CallState *cs, CK_ATTRIBUTE_PTR array, CK_ULONG len, CK_RV ret)
489 : {
490 0 : assert (cs);
491 :
492 : /*
493 : * When returning an attribute array, certain errors aren't
494 : * actually real errors, these are passed through to the other
495 : * side along with the attribute array.
496 : */
497 :
498 0 : switch (ret) {
499 0 : case CKR_ATTRIBUTE_SENSITIVE:
500 : case CKR_ATTRIBUTE_TYPE_INVALID:
501 : case CKR_BUFFER_TOO_SMALL:
502 : case CKR_OK:
503 0 : break;
504 :
505 : /* Pass all other errors straight through */
506 0 : default:
507 0 : return ret;
508 : };
509 :
510 0 : if (!gkm_rpc_message_write_attribute_array (cs->resp, array, len) ||
511 0 : !gkm_rpc_message_write_ulong (cs->resp, ret))
512 0 : return PREP_ERROR;
513 :
514 0 : return CKR_OK;
515 : }
516 :
517 : static CK_RV
518 0 : proto_read_null_string (CallState *cs, CK_UTF8CHAR_PTR* val)
519 : {
520 : GkmRpcMessage *msg;
521 : const unsigned char *data;
522 : size_t n_data;
523 :
524 0 : assert (cs);
525 0 : assert (val);
526 :
527 0 : msg = cs->req;
528 :
529 : /* Check that we're supposed to have this at this point */
530 0 : assert (!msg->signature || gkm_rpc_message_verify_part (msg, "z"));
531 :
532 0 : if (!egg_buffer_get_byte_array (&msg->buffer, msg->parsed, &msg->parsed, &data, &n_data))
533 0 : return PARSE_ERROR;
534 :
535 : /* Allocate a block of memory for it */
536 0 : *val = call_alloc (cs, n_data);
537 0 : if (!*val)
538 0 : return CKR_DEVICE_MEMORY;
539 :
540 0 : memcpy (*val, data, n_data);
541 0 : (*val)[n_data] = 0;
542 :
543 0 : return CKR_OK;
544 : }
545 :
546 : static CK_RV
547 0 : proto_read_mechanism (CallState *cs, CK_MECHANISM_PTR mech)
548 : {
549 : GkmRpcMessage *msg;
550 : const unsigned char *data;
551 : uint32_t value;
552 : size_t n_data;
553 :
554 0 : assert (cs);
555 0 : assert (mech);
556 :
557 0 : msg = cs->req;
558 :
559 : /* Make sure this is in the right order */
560 0 : assert (!msg->signature || gkm_rpc_message_verify_part (msg, "M"));
561 :
562 : /* The mechanism type */
563 0 : if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, &value))
564 0 : return PARSE_ERROR;
565 :
566 : /* The mechanism data */
567 0 : if (!egg_buffer_get_byte_array (&msg->buffer, msg->parsed, &msg->parsed, &data, &n_data))
568 0 : return PARSE_ERROR;
569 :
570 0 : mech->mechanism = value;
571 0 : mech->pParameter = (CK_VOID_PTR)data;
572 0 : mech->ulParameterLen = n_data;
573 0 : return CKR_OK;
574 : }
575 :
576 : static CK_RV
577 2 : proto_write_info (CallState *cs, CK_INFO_PTR info)
578 : {
579 : GkmRpcMessage *msg;
580 :
581 2 : assert (cs);
582 2 : assert (info);
583 :
584 2 : msg = cs->resp;
585 :
586 4 : if (!gkm_rpc_message_write_version (msg, &info->cryptokiVersion) ||
587 4 : !gkm_rpc_message_write_space_string (msg, info->manufacturerID, 32) ||
588 4 : !gkm_rpc_message_write_ulong (msg, info->flags) ||
589 4 : !gkm_rpc_message_write_space_string (msg, info->libraryDescription, 32) ||
590 2 : !gkm_rpc_message_write_version (msg, &info->libraryVersion))
591 0 : return PREP_ERROR;
592 :
593 2 : return CKR_OK;
594 : }
595 :
596 : static CK_RV
597 0 : proto_write_slot_info (CallState *cs, CK_SLOT_INFO_PTR info)
598 : {
599 : GkmRpcMessage *msg;
600 :
601 0 : assert (cs);
602 0 : assert (info);
603 :
604 0 : msg = cs->resp;
605 :
606 0 : if (!gkm_rpc_message_write_space_string (msg, info->slotDescription, 64) ||
607 0 : !gkm_rpc_message_write_space_string (msg, info->manufacturerID, 32) ||
608 0 : !gkm_rpc_message_write_ulong (msg, info->flags) ||
609 0 : !gkm_rpc_message_write_version (msg, &info->hardwareVersion) ||
610 0 : !gkm_rpc_message_write_version (msg, &info->firmwareVersion))
611 0 : return PREP_ERROR;
612 :
613 0 : return CKR_OK;
614 : }
615 :
616 : static CK_RV
617 0 : proto_write_token_info (CallState *cs, CK_TOKEN_INFO_PTR info)
618 : {
619 : GkmRpcMessage *msg;
620 :
621 0 : assert (cs);
622 0 : assert (info);
623 :
624 0 : msg = cs->resp;
625 :
626 0 : if (!gkm_rpc_message_write_space_string (msg, info->label, 32) ||
627 0 : !gkm_rpc_message_write_space_string (msg, info->manufacturerID, 32) ||
628 0 : !gkm_rpc_message_write_space_string (msg, info->model, 16) ||
629 0 : !gkm_rpc_message_write_space_string (msg, info->serialNumber, 16) ||
630 0 : !gkm_rpc_message_write_ulong (msg, info->flags) ||
631 0 : !gkm_rpc_message_write_ulong (msg, info->ulMaxSessionCount) ||
632 0 : !gkm_rpc_message_write_ulong (msg, info->ulSessionCount) ||
633 0 : !gkm_rpc_message_write_ulong (msg, info->ulMaxRwSessionCount) ||
634 0 : !gkm_rpc_message_write_ulong (msg, info->ulRwSessionCount) ||
635 0 : !gkm_rpc_message_write_ulong (msg, info->ulMaxPinLen) ||
636 0 : !gkm_rpc_message_write_ulong (msg, info->ulMinPinLen) ||
637 0 : !gkm_rpc_message_write_ulong (msg, info->ulTotalPublicMemory) ||
638 0 : !gkm_rpc_message_write_ulong (msg, info->ulFreePublicMemory) ||
639 0 : !gkm_rpc_message_write_ulong (msg, info->ulTotalPrivateMemory) ||
640 0 : !gkm_rpc_message_write_ulong (msg, info->ulFreePrivateMemory) ||
641 0 : !gkm_rpc_message_write_version (msg, &info->hardwareVersion) ||
642 0 : !gkm_rpc_message_write_version (msg, &info->firmwareVersion) ||
643 0 : !gkm_rpc_message_write_space_string (msg, info->utcTime, 16))
644 0 : return PREP_ERROR;
645 :
646 0 : return CKR_OK;
647 : }
648 :
649 : static CK_RV
650 0 : proto_write_mechanism_info (CallState *cs, CK_MECHANISM_INFO_PTR info)
651 : {
652 : GkmRpcMessage *msg;
653 :
654 0 : assert (cs);
655 0 : assert (info);
656 :
657 0 : msg = cs->resp;
658 :
659 0 : if (!gkm_rpc_message_write_ulong (msg, info->ulMinKeySize) ||
660 0 : !gkm_rpc_message_write_ulong (msg, info->ulMaxKeySize) ||
661 0 : !gkm_rpc_message_write_ulong (msg, info->flags))
662 0 : return PREP_ERROR;
663 :
664 0 : return CKR_OK;
665 : }
666 :
667 : static CK_RV
668 0 : proto_write_session_info (CallState *cs, CK_SESSION_INFO_PTR info)
669 : {
670 : GkmRpcMessage *msg;
671 :
672 0 : assert (cs);
673 0 : assert (info);
674 :
675 0 : msg = cs->resp;
676 :
677 0 : if (!gkm_rpc_message_write_ulong (msg, info->slotID) ||
678 0 : !gkm_rpc_message_write_ulong (msg, info->state) ||
679 0 : !gkm_rpc_message_write_ulong (msg, info->flags) ||
680 0 : !gkm_rpc_message_write_ulong (msg, info->ulDeviceError))
681 0 : return PREP_ERROR;
682 :
683 0 : return CKR_OK;
684 : }
685 :
686 : /* -------------------------------------------------------------------
687 : * CALL MACROS
688 : */
689 :
690 : #define BEGIN_CALL(call_id) \
691 : debug ((#call_id ": enter")); \
692 : assert (cs); \
693 : assert (pkcs11_module); \
694 : { \
695 : CK_ ## call_id _func = pkcs11_module-> call_id; \
696 : CK_RV _ret = CKR_OK; \
697 : if (!_func) { _ret = CKR_GENERAL_ERROR; goto _cleanup; }
698 :
699 : #define PROCESS_CALL(args)\
700 : assert (gkm_rpc_message_is_verified (cs->req)); \
701 : _ret = _func args
702 :
703 : #define END_CALL \
704 : _cleanup: \
705 : debug (("ret: %d", _ret)); \
706 : return _ret; \
707 : }
708 :
709 : #define IN_BYTE(val) \
710 : if (!gkm_rpc_message_read_byte (cs->req, &val)) \
711 : { _ret = PARSE_ERROR; goto _cleanup; }
712 :
713 : #define IN_ULONG(val) \
714 : if (!gkm_rpc_message_read_ulong (cs->req, &val)) \
715 : { _ret = PARSE_ERROR; goto _cleanup; }
716 :
717 : #define IN_STRING(val) \
718 : _ret = proto_read_null_string (cs, &val); \
719 : if (_ret != CKR_OK) goto _cleanup;
720 :
721 : #define IN_BYTE_BUFFER(buffer, buffer_len) \
722 : _ret = proto_read_byte_buffer (cs, &buffer, &buffer_len); \
723 : if (_ret != CKR_OK) goto _cleanup;
724 :
725 : #define IN_BYTE_ARRAY(buffer, buffer_len) \
726 : _ret = proto_read_byte_array (cs, &buffer, &buffer_len); \
727 : if (_ret != CKR_OK) goto _cleanup;
728 :
729 : #define IN_ULONG_BUFFER(buffer, buffer_len) \
730 : _ret = proto_read_ulong_buffer (cs, &buffer, &buffer_len); \
731 : if (_ret != CKR_OK) goto _cleanup;
732 :
733 : #define IN_ATTRIBUTE_BUFFER(buffer, buffer_len) \
734 : _ret = proto_read_attribute_buffer (cs, &buffer, &buffer_len); \
735 : if (_ret != CKR_OK) goto _cleanup;
736 :
737 : #define IN_ATTRIBUTE_ARRAY(attrs, n_attrs) \
738 : _ret = proto_read_attribute_array (cs, &attrs, &n_attrs); \
739 : if (_ret != CKR_OK) goto _cleanup;
740 :
741 : #define IN_MECHANISM(mech) \
742 : _ret = proto_read_mechanism (cs, &mech); \
743 : if (_ret != CKR_OK) goto _cleanup;
744 :
745 :
746 : #define OUT_ULONG(val) \
747 : if (_ret == CKR_OK && !gkm_rpc_message_write_ulong (cs->resp, val)) \
748 : _ret = PREP_ERROR;
749 :
750 : #define OUT_BYTE_ARRAY(array, len) \
751 : /* Note how we filter return codes */ \
752 : _ret = proto_write_byte_array (cs, array, len, _ret);
753 :
754 : #define OUT_ULONG_ARRAY(array, len) \
755 : /* Note how we filter return codes */ \
756 : _ret = proto_write_ulong_array (cs, array, len, _ret);
757 :
758 : #define OUT_ATTRIBUTE_ARRAY(array, len) \
759 : /* Note how we filter return codes */ \
760 : _ret = proto_write_attribute_array (cs, array, len, _ret);
761 :
762 : #define OUT_INFO(val) \
763 : if (_ret == CKR_OK) \
764 : _ret = proto_write_info (cs, &val);
765 :
766 : #define OUT_SLOT_INFO(val) \
767 : if (_ret == CKR_OK) \
768 : _ret = proto_write_slot_info (cs, &val);
769 :
770 : #define OUT_TOKEN_INFO(val) \
771 : if (_ret == CKR_OK) \
772 : _ret = proto_write_token_info (cs, &val);
773 :
774 : #define OUT_MECHANISM_INFO(val) \
775 : if (_ret == CKR_OK) \
776 : _ret = proto_write_mechanism_info (cs, &val);
777 :
778 : #define OUT_SESSION_INFO(val) \
779 : if (_ret == CKR_OK) \
780 : _ret = proto_write_session_info (cs, &val);
781 :
782 : /* ---------------------------------------------------------------------------
783 : * DISPATCH SPECIFIC CALLS
784 : */
785 :
786 : static CK_RV
787 2 : rpc_C_Initialize (CallState *cs)
788 : {
789 : CK_BYTE_PTR handshake;
790 : CK_ULONG n_handshake;
791 2 : CK_RV ret = CKR_OK;
792 :
793 : debug (("C_Initialize: enter"));
794 :
795 2 : assert (cs);
796 2 : assert (pkcs11_module);
797 :
798 2 : ret = proto_read_byte_array (cs, &handshake, &n_handshake);
799 2 : if (ret == CKR_OK) {
800 :
801 : /* Check to make sure the header matches */
802 2 : if (n_handshake != GKM_RPC_HANDSHAKE_LEN ||
803 2 : memcmp (handshake, GKM_RPC_HANDSHAKE, n_handshake) != 0) {
804 0 : gkm_rpc_warn ("invalid handshake received from connecting module");
805 0 : ret = CKR_GENERAL_ERROR;
806 : }
807 :
808 2 : assert (gkm_rpc_message_is_verified (cs->req));
809 : }
810 :
811 : /*
812 : * We don't actually C_Initialize lower layers. It's assumed
813 : * that they'll already be initialzied by the code that loaded us.
814 : */
815 :
816 : debug (("ret: %d", ret));
817 2 : return ret;
818 : }
819 :
820 : static CK_RV
821 2 : rpc_C_Finalize (CallState *cs)
822 : {
823 : CK_SLOT_ID_PTR slots;
824 : CK_ULONG n_slots, i;
825 2 : CK_RV ret = CKR_OK;
826 :
827 : debug (("C_Finalize: enter"));
828 :
829 2 : assert (cs);
830 2 : assert (pkcs11_module);
831 :
832 : /*
833 : * We don't actually C_Finalize lower layers, since this would finalize
834 : * for all appartments, client applications. Anyway this is done by
835 : * the code that loaded us.
836 : *
837 : * But we do need to cleanup resources used by this client, so instead
838 : * we call C_CloseAllSessions for each slot for this client application.
839 : */
840 :
841 2 : if (cs->client->application.applicationId) {
842 0 : ret = (pkcs11_module->C_GetSlotList) (TRUE, NULL, &n_slots);
843 0 : if (ret == CKR_OK) {
844 0 : slots = calloc (n_slots, sizeof (CK_SLOT_ID));
845 0 : if (slots == NULL) {
846 0 : ret = CKR_DEVICE_MEMORY;
847 : } else {
848 0 : ret = (pkcs11_module->C_GetSlotList) (TRUE, slots, &n_slots);
849 0 : for (i = 0; ret == CKR_OK && i < n_slots; ++i)
850 0 : ret = (pkcs11_module->C_CloseAllSessions) (slots[i] | cs->client->application.applicationId);
851 0 : free (slots);
852 : }
853 : }
854 : }
855 :
856 : debug (("ret: %d", ret));
857 2 : return ret;
858 : }
859 :
860 : static CK_RV
861 2 : rpc_C_GetInfo (CallState *cs)
862 : {
863 : CK_INFO info;
864 :
865 2 : BEGIN_CALL (C_GetInfo);
866 2 : PROCESS_CALL ((&info));
867 2 : OUT_INFO (info);
868 2 : END_CALL;
869 : }
870 :
871 : static CK_RV
872 0 : rpc_C_GetSlotList (CallState *cs)
873 : {
874 : CK_BBOOL token_present;
875 : CK_SLOT_ID_PTR slot_list;
876 : CK_ULONG count;
877 :
878 0 : BEGIN_CALL (C_GetSlotList);
879 0 : IN_BYTE (token_present);
880 0 : IN_ULONG_BUFFER (slot_list, count);
881 0 : PROCESS_CALL ((token_present, slot_list, &count));
882 0 : OUT_ULONG_ARRAY (slot_list, count);
883 0 : END_CALL;
884 : }
885 :
886 : static CK_RV
887 0 : rpc_C_GetSlotInfo (CallState *cs)
888 : {
889 : CK_SLOT_ID slot_id;
890 : CK_SLOT_INFO info;
891 :
892 : /* Slot id becomes appartment so lower layers can tell clients apart. */
893 :
894 0 : BEGIN_CALL (C_GetSlotInfo);
895 0 : IN_ULONG (slot_id);
896 0 : PROCESS_CALL ((slot_id, &info));
897 0 : OUT_SLOT_INFO (info);
898 0 : END_CALL;
899 : }
900 :
901 : static CK_RV
902 0 : rpc_C_GetTokenInfo (CallState *cs)
903 : {
904 : CK_SLOT_ID slot_id;
905 : CK_TOKEN_INFO info;
906 :
907 : /* Slot id becomes appartment so lower layers can tell clients apart. */
908 :
909 0 : BEGIN_CALL (C_GetTokenInfo);
910 0 : IN_ULONG (slot_id);
911 0 : PROCESS_CALL ((slot_id, &info));
912 0 : OUT_TOKEN_INFO (info);
913 0 : END_CALL;
914 : }
915 :
916 : static CK_RV
917 0 : rpc_C_GetMechanismList (CallState *cs)
918 : {
919 : CK_SLOT_ID slot_id;
920 : CK_MECHANISM_TYPE_PTR mechanism_list;
921 : CK_ULONG count;
922 :
923 : /* Slot id becomes appartment so lower layers can tell clients apart. */
924 :
925 0 : BEGIN_CALL (C_GetMechanismList);
926 0 : IN_ULONG (slot_id);
927 0 : IN_ULONG_BUFFER (mechanism_list, count);
928 0 : PROCESS_CALL ((slot_id, mechanism_list, &count));
929 0 : OUT_ULONG_ARRAY (mechanism_list, count);
930 0 : END_CALL;
931 : }
932 :
933 : static CK_RV
934 0 : rpc_C_GetMechanismInfo (CallState *cs)
935 : {
936 : CK_SLOT_ID slot_id;
937 : CK_MECHANISM_TYPE type;
938 : CK_MECHANISM_INFO info;
939 :
940 : /* Slot id becomes appartment so lower layers can tell clients apart. */
941 :
942 0 : BEGIN_CALL (C_GetMechanismInfo);
943 0 : IN_ULONG (slot_id);
944 0 : IN_ULONG (type);
945 0 : PROCESS_CALL ((slot_id, type, &info));
946 0 : OUT_MECHANISM_INFO (info);
947 0 : END_CALL;
948 : }
949 :
950 : static CK_RV
951 0 : rpc_C_InitToken (CallState *cs)
952 : {
953 : CK_SLOT_ID slot_id;
954 : CK_UTF8CHAR_PTR pin;
955 : CK_ULONG pin_len;
956 : CK_UTF8CHAR_PTR label;
957 :
958 : /* Slot id becomes appartment so lower layers can tell clients apart. */
959 :
960 0 : BEGIN_CALL (C_InitToken);
961 0 : IN_ULONG (slot_id);
962 0 : IN_BYTE_ARRAY (pin, pin_len);
963 0 : IN_STRING (label);
964 0 : PROCESS_CALL ((slot_id, pin, pin_len, label));
965 0 : END_CALL;
966 : }
967 :
968 : static CK_RV
969 0 : rpc_C_WaitForSlotEvent (CallState *cs)
970 : {
971 : CK_FLAGS flags;
972 : CK_SLOT_ID slot_id;
973 :
974 : /* Get slot id from appartment lower layers use. */
975 :
976 0 : BEGIN_CALL (C_WaitForSlotEvent);
977 0 : IN_ULONG (flags);
978 0 : PROCESS_CALL ((flags, &slot_id, NULL));
979 0 : OUT_ULONG (slot_id);
980 0 : END_CALL;
981 : }
982 :
983 : static CK_RV
984 0 : rpc_C_OpenSession (CallState *cs)
985 : {
986 : CK_SLOT_ID slot_id;
987 : CK_FLAGS flags;
988 : CK_SESSION_HANDLE session;
989 :
990 : /* Slot id becomes appartment so lower layers can tell clients apart. */
991 :
992 : /*
993 : * IMPORTANT: When we open sessions on behalf of a client caller
994 : * we always specify CKF_G_APPLICATION_SESSION. This allows the module
995 : * to know whether they're talking to the daemon or a client app.
996 : *
997 : * This is a security feature.
998 : */
999 :
1000 0 : BEGIN_CALL (C_OpenSession);
1001 0 : IN_ULONG (slot_id);
1002 0 : IN_ULONG (flags);
1003 0 : flags |= CKF_G_APPLICATION_SESSION;
1004 0 : PROCESS_CALL ((slot_id, flags, &cs->client->application, NULL, &session));
1005 0 : OUT_ULONG (session);
1006 0 : END_CALL;
1007 : }
1008 :
1009 :
1010 : static CK_RV
1011 0 : rpc_C_CloseSession (CallState *cs)
1012 : {
1013 : CK_SESSION_HANDLE session;
1014 :
1015 0 : BEGIN_CALL (C_CloseSession);
1016 0 : IN_ULONG (session);
1017 0 : PROCESS_CALL ((session));
1018 0 : END_CALL;
1019 : }
1020 :
1021 : static CK_RV
1022 0 : rpc_C_CloseAllSessions (CallState *cs)
1023 : {
1024 : CK_SLOT_ID slot_id;
1025 :
1026 : /* Slot id becomes appartment so lower layers can tell clients apart. */
1027 :
1028 0 : BEGIN_CALL (C_CloseAllSessions);
1029 0 : IN_ULONG (slot_id);
1030 0 : slot_id |= cs->client->application.applicationId;
1031 0 : PROCESS_CALL ((slot_id));
1032 0 : END_CALL;
1033 : }
1034 :
1035 : static CK_RV
1036 0 : rpc_C_GetFunctionStatus (CallState *cs)
1037 : {
1038 : CK_SESSION_HANDLE session;
1039 :
1040 0 : BEGIN_CALL (C_GetFunctionStatus);
1041 0 : IN_ULONG (session);
1042 0 : PROCESS_CALL ((session));
1043 0 : END_CALL;
1044 : }
1045 :
1046 : static CK_RV
1047 0 : rpc_C_CancelFunction (CallState *cs)
1048 : {
1049 : CK_SESSION_HANDLE session;
1050 :
1051 0 : BEGIN_CALL (C_CancelFunction);
1052 0 : IN_ULONG (session);
1053 0 : PROCESS_CALL ((session));
1054 0 : END_CALL;
1055 : }
1056 :
1057 : static CK_RV
1058 0 : rpc_C_GetSessionInfo (CallState *cs)
1059 : {
1060 : CK_SESSION_HANDLE session;
1061 : CK_SESSION_INFO info;
1062 :
1063 : /* Get slot id from appartment lower layers use. */
1064 :
1065 0 : BEGIN_CALL (C_GetSessionInfo);
1066 0 : IN_ULONG (session);
1067 0 : PROCESS_CALL ((session, &info));
1068 0 : OUT_SESSION_INFO (info);
1069 0 : END_CALL;
1070 : }
1071 :
1072 : static CK_RV
1073 0 : rpc_C_InitPIN (CallState *cs)
1074 : {
1075 : CK_SESSION_HANDLE session;
1076 : CK_UTF8CHAR_PTR pin;
1077 : CK_ULONG pin_len;
1078 :
1079 0 : BEGIN_CALL (C_InitPIN);
1080 0 : IN_ULONG (session);
1081 0 : IN_BYTE_ARRAY (pin, pin_len);
1082 0 : PROCESS_CALL ((session, pin, pin_len));
1083 0 : END_CALL;
1084 : }
1085 :
1086 : static CK_RV
1087 0 : rpc_C_SetPIN (CallState *cs)
1088 : {
1089 : CK_SESSION_HANDLE session;
1090 : CK_UTF8CHAR_PTR old_pin;
1091 : CK_ULONG old_len;
1092 : CK_UTF8CHAR_PTR new_pin;
1093 : CK_ULONG new_len;
1094 :
1095 0 : BEGIN_CALL (C_SetPIN);
1096 0 : IN_ULONG (session);
1097 0 : IN_BYTE_ARRAY (old_pin, old_len);
1098 0 : IN_BYTE_ARRAY (new_pin, new_len);
1099 0 : PROCESS_CALL ((session, old_pin, old_len, new_pin, new_len));
1100 0 : END_CALL;
1101 : }
1102 :
1103 : static CK_RV
1104 0 : rpc_C_GetOperationState (CallState *cs)
1105 : {
1106 : CK_SESSION_HANDLE session;
1107 : CK_BYTE_PTR operation_state;
1108 : CK_ULONG operation_state_len;
1109 :
1110 0 : BEGIN_CALL (C_GetOperationState);
1111 0 : IN_ULONG (session);
1112 0 : IN_BYTE_BUFFER (operation_state, operation_state_len);
1113 0 : PROCESS_CALL ((session, operation_state, &operation_state_len));
1114 0 : OUT_BYTE_ARRAY (operation_state, operation_state_len);
1115 0 : END_CALL;
1116 : }
1117 :
1118 : static CK_RV
1119 0 : rpc_C_SetOperationState (CallState *cs)
1120 : {
1121 : CK_SESSION_HANDLE session;
1122 : CK_BYTE_PTR operation_state;
1123 : CK_ULONG operation_state_len;
1124 : CK_OBJECT_HANDLE encryption_key;
1125 : CK_OBJECT_HANDLE authentication_key;
1126 :
1127 0 : BEGIN_CALL (C_SetOperationState);
1128 0 : IN_ULONG (session);
1129 0 : IN_BYTE_ARRAY (operation_state, operation_state_len);
1130 0 : IN_ULONG (encryption_key);
1131 0 : IN_ULONG (authentication_key);
1132 0 : PROCESS_CALL ((session, operation_state, operation_state_len, encryption_key, authentication_key));
1133 0 : END_CALL;
1134 : }
1135 :
1136 : static CK_RV
1137 0 : rpc_C_Login (CallState *cs)
1138 : {
1139 : CK_SESSION_HANDLE session;
1140 : CK_USER_TYPE user_type;
1141 : CK_UTF8CHAR_PTR pin;
1142 : CK_ULONG pin_len;
1143 :
1144 0 : BEGIN_CALL (C_Login);
1145 0 : IN_ULONG (session);
1146 0 : IN_ULONG (user_type);
1147 0 : IN_BYTE_ARRAY (pin, pin_len);
1148 0 : PROCESS_CALL ((session, user_type, pin, pin_len));
1149 0 : END_CALL;
1150 : }
1151 :
1152 : static CK_RV
1153 0 : rpc_C_Logout (CallState *cs)
1154 : {
1155 : CK_SESSION_HANDLE session;
1156 :
1157 0 : BEGIN_CALL (C_Logout);
1158 0 : IN_ULONG (session);
1159 0 : PROCESS_CALL ((session));
1160 0 : END_CALL;
1161 : }
1162 :
1163 : /* -----------------------------------------------------------------------------
1164 : * OBJECT OPERATIONS
1165 : */
1166 :
1167 : static CK_RV
1168 0 : rpc_C_CreateObject (CallState *cs)
1169 : {
1170 : CK_SESSION_HANDLE session;
1171 : CK_ATTRIBUTE_PTR template;
1172 : CK_ULONG count;
1173 : CK_OBJECT_HANDLE new_object;
1174 :
1175 0 : BEGIN_CALL (C_CreateObject);
1176 0 : IN_ULONG (session);
1177 0 : IN_ATTRIBUTE_ARRAY (template, count);
1178 0 : PROCESS_CALL ((session, template, count, &new_object));
1179 0 : OUT_ULONG (new_object);
1180 0 : END_CALL;
1181 : }
1182 :
1183 : static CK_RV
1184 0 : rpc_C_CopyObject (CallState *cs)
1185 : {
1186 : CK_SESSION_HANDLE session;
1187 : CK_OBJECT_HANDLE object;
1188 : CK_ATTRIBUTE_PTR template;
1189 : CK_ULONG count;
1190 : CK_OBJECT_HANDLE new_object;
1191 :
1192 0 : BEGIN_CALL (C_CopyObject);
1193 0 : IN_ULONG (session);
1194 0 : IN_ULONG (object);
1195 0 : IN_ATTRIBUTE_ARRAY (template, count);
1196 0 : PROCESS_CALL ((session, object, template, count, &new_object));
1197 0 : OUT_ULONG (new_object);
1198 0 : END_CALL;
1199 : }
1200 :
1201 : static CK_RV
1202 0 : rpc_C_DestroyObject (CallState *cs)
1203 : {
1204 : CK_SESSION_HANDLE session;
1205 : CK_OBJECT_HANDLE object;
1206 :
1207 0 : BEGIN_CALL (C_DestroyObject);
1208 0 : IN_ULONG (session);
1209 0 : IN_ULONG (object);
1210 0 : PROCESS_CALL ((session, object));
1211 0 : END_CALL;
1212 : }
1213 :
1214 : static CK_RV
1215 0 : rpc_C_GetObjectSize (CallState *cs)
1216 : {
1217 : CK_SESSION_HANDLE session;
1218 : CK_OBJECT_HANDLE object;
1219 : CK_ULONG size;
1220 :
1221 0 : BEGIN_CALL (C_GetObjectSize);
1222 0 : IN_ULONG (session);
1223 0 : IN_ULONG (object);
1224 0 : PROCESS_CALL ((session, object, &size));
1225 0 : OUT_ULONG (size);
1226 0 : END_CALL;
1227 : }
1228 :
1229 : static CK_RV
1230 0 : rpc_C_GetAttributeValue (CallState *cs)
1231 : {
1232 : CK_SESSION_HANDLE session;
1233 : CK_OBJECT_HANDLE object;
1234 : CK_ATTRIBUTE_PTR template;
1235 : CK_ULONG count;
1236 :
1237 0 : BEGIN_CALL (C_GetAttributeValue);
1238 0 : IN_ULONG (session);
1239 0 : IN_ULONG (object);
1240 0 : IN_ATTRIBUTE_BUFFER (template, count);
1241 0 : PROCESS_CALL ((session, object, template, count));
1242 0 : OUT_ATTRIBUTE_ARRAY (template, count);
1243 0 : END_CALL;
1244 : }
1245 :
1246 : static CK_RV
1247 0 : rpc_C_SetAttributeValue (CallState *cs)
1248 : {
1249 : CK_SESSION_HANDLE session;
1250 : CK_OBJECT_HANDLE object;
1251 : CK_ATTRIBUTE_PTR template;
1252 : CK_ULONG count;
1253 :
1254 0 : BEGIN_CALL (C_SetAttributeValue);
1255 0 : IN_ULONG (session);
1256 0 : IN_ULONG (object);
1257 0 : IN_ATTRIBUTE_ARRAY (template, count);
1258 0 : PROCESS_CALL ((session, object, template, count));
1259 0 : END_CALL;
1260 : }
1261 :
1262 : static CK_RV
1263 0 : rpc_C_FindObjectsInit (CallState *cs)
1264 : {
1265 : CK_SESSION_HANDLE session;
1266 : CK_ATTRIBUTE_PTR template;
1267 : CK_ULONG count;
1268 :
1269 0 : BEGIN_CALL (C_FindObjectsInit);
1270 0 : IN_ULONG (session);
1271 0 : IN_ATTRIBUTE_ARRAY (template, count);
1272 0 : PROCESS_CALL ((session, template, count));
1273 0 : END_CALL;
1274 : }
1275 :
1276 : static CK_RV
1277 0 : rpc_C_FindObjects (CallState *cs)
1278 : {
1279 : CK_SESSION_HANDLE session;
1280 : CK_OBJECT_HANDLE_PTR objects;
1281 : CK_ULONG max_object_count;
1282 : CK_ULONG object_count;
1283 :
1284 0 : BEGIN_CALL (C_FindObjects);
1285 0 : IN_ULONG (session);
1286 0 : IN_ULONG_BUFFER (objects, max_object_count);
1287 0 : PROCESS_CALL ((session, objects, max_object_count, &object_count));
1288 0 : OUT_ULONG_ARRAY (objects, object_count);
1289 0 : END_CALL;
1290 : }
1291 :
1292 : static CK_RV
1293 0 : rpc_C_FindObjectsFinal (CallState *cs)
1294 : {
1295 : CK_SESSION_HANDLE session;
1296 :
1297 0 : BEGIN_CALL (C_FindObjectsFinal);
1298 0 : IN_ULONG (session);
1299 0 : PROCESS_CALL ((session));
1300 0 : END_CALL;
1301 : }
1302 :
1303 : static CK_RV
1304 0 : rpc_C_EncryptInit (CallState *cs)
1305 : {
1306 : CK_SESSION_HANDLE session;
1307 : CK_MECHANISM mechanism;
1308 : CK_OBJECT_HANDLE key;
1309 :
1310 0 : BEGIN_CALL (C_EncryptInit);
1311 0 : IN_ULONG (session);
1312 0 : IN_MECHANISM (mechanism);
1313 0 : IN_ULONG (key);
1314 0 : PROCESS_CALL ((session, &mechanism, key));
1315 0 : END_CALL;
1316 :
1317 : }
1318 :
1319 : static CK_RV
1320 0 : rpc_C_Encrypt (CallState *cs)
1321 : {
1322 : CK_SESSION_HANDLE session;
1323 : CK_BYTE_PTR data;
1324 : CK_ULONG data_len;
1325 : CK_BYTE_PTR encrypted_data;
1326 : CK_ULONG encrypted_data_len;
1327 :
1328 0 : BEGIN_CALL (C_Encrypt);
1329 0 : IN_ULONG (session);
1330 0 : IN_BYTE_ARRAY (data, data_len);
1331 0 : IN_BYTE_BUFFER (encrypted_data, encrypted_data_len);
1332 0 : PROCESS_CALL ((session, data, data_len, encrypted_data, &encrypted_data_len));
1333 0 : OUT_BYTE_ARRAY (encrypted_data, encrypted_data_len);
1334 0 : END_CALL;
1335 : }
1336 :
1337 : static CK_RV
1338 0 : rpc_C_EncryptUpdate (CallState *cs)
1339 : {
1340 : CK_SESSION_HANDLE session;
1341 : CK_BYTE_PTR part;
1342 : CK_ULONG part_len;
1343 : CK_BYTE_PTR encrypted_part;
1344 : CK_ULONG encrypted_part_len;
1345 :
1346 0 : BEGIN_CALL (C_EncryptUpdate);
1347 0 : IN_ULONG (session);
1348 0 : IN_BYTE_ARRAY (part, part_len);
1349 0 : IN_BYTE_BUFFER (encrypted_part, encrypted_part_len);
1350 0 : PROCESS_CALL ((session, part, part_len, encrypted_part, &encrypted_part_len));
1351 0 : OUT_BYTE_ARRAY (encrypted_part, encrypted_part_len);
1352 0 : END_CALL;
1353 : }
1354 :
1355 : static CK_RV
1356 0 : rpc_C_EncryptFinal (CallState *cs)
1357 : {
1358 : CK_SESSION_HANDLE session;
1359 : CK_BYTE_PTR last_encrypted_part;
1360 : CK_ULONG last_encrypted_part_len;
1361 :
1362 0 : BEGIN_CALL (C_EncryptFinal);
1363 0 : IN_ULONG (session);
1364 0 : IN_BYTE_BUFFER (last_encrypted_part, last_encrypted_part_len);
1365 0 : PROCESS_CALL ((session, last_encrypted_part, &last_encrypted_part_len));
1366 0 : OUT_BYTE_ARRAY (last_encrypted_part, last_encrypted_part_len);
1367 0 : END_CALL;
1368 : }
1369 :
1370 : static CK_RV
1371 0 : rpc_C_DecryptInit (CallState *cs)
1372 : {
1373 : CK_SESSION_HANDLE session;
1374 : CK_MECHANISM mechanism;
1375 : CK_OBJECT_HANDLE key;
1376 :
1377 0 : BEGIN_CALL (C_DecryptInit);
1378 0 : IN_ULONG (session);
1379 0 : IN_MECHANISM (mechanism);
1380 0 : IN_ULONG (key);
1381 0 : PROCESS_CALL ((session, &mechanism, key));
1382 0 : END_CALL;
1383 : }
1384 :
1385 : static CK_RV
1386 0 : rpc_C_Decrypt (CallState *cs)
1387 : {
1388 : CK_SESSION_HANDLE session;
1389 : CK_BYTE_PTR encrypted_data;
1390 : CK_ULONG encrypted_data_len;
1391 : CK_BYTE_PTR data;
1392 : CK_ULONG data_len;
1393 :
1394 0 : BEGIN_CALL (C_Decrypt);
1395 0 : IN_ULONG (session);
1396 0 : IN_BYTE_ARRAY (encrypted_data, encrypted_data_len);
1397 0 : IN_BYTE_BUFFER (data, data_len);
1398 0 : PROCESS_CALL ((session, encrypted_data, encrypted_data_len, data, &data_len));
1399 0 : OUT_BYTE_ARRAY (data, data_len);
1400 0 : END_CALL;
1401 : }
1402 :
1403 : static CK_RV
1404 0 : rpc_C_DecryptUpdate (CallState *cs)
1405 : {
1406 : CK_SESSION_HANDLE session;
1407 : CK_BYTE_PTR encrypted_part;
1408 : CK_ULONG encrypted_part_len;
1409 : CK_BYTE_PTR part;
1410 : CK_ULONG part_len;
1411 :
1412 0 : BEGIN_CALL (C_DecryptUpdate);
1413 0 : IN_ULONG (session);
1414 0 : IN_BYTE_ARRAY (encrypted_part, encrypted_part_len);
1415 0 : IN_BYTE_BUFFER (part, part_len);
1416 0 : PROCESS_CALL ((session, encrypted_part, encrypted_part_len, part, &part_len));
1417 0 : OUT_BYTE_ARRAY (part, part_len);
1418 0 : END_CALL;
1419 : }
1420 :
1421 : static CK_RV
1422 0 : rpc_C_DecryptFinal (CallState *cs)
1423 : {
1424 : CK_SESSION_HANDLE session;
1425 : CK_BYTE_PTR last_part;
1426 : CK_ULONG last_part_len;
1427 :
1428 0 : BEGIN_CALL (C_DecryptFinal);
1429 0 : IN_ULONG (session);
1430 0 : IN_BYTE_BUFFER (last_part, last_part_len);
1431 0 : PROCESS_CALL ((session, last_part, &last_part_len));
1432 0 : OUT_BYTE_ARRAY (last_part, last_part_len);
1433 0 : END_CALL;
1434 : }
1435 :
1436 : static CK_RV
1437 0 : rpc_C_DigestInit (CallState *cs)
1438 : {
1439 : CK_SESSION_HANDLE session;
1440 : CK_MECHANISM mechanism;
1441 :
1442 0 : BEGIN_CALL (C_DigestInit);
1443 0 : IN_ULONG (session);
1444 0 : IN_MECHANISM (mechanism);
1445 0 : PROCESS_CALL ((session, &mechanism));
1446 0 : END_CALL;
1447 : }
1448 :
1449 : static CK_RV
1450 0 : rpc_C_Digest (CallState *cs)
1451 : {
1452 : CK_SESSION_HANDLE session;
1453 : CK_BYTE_PTR data;
1454 : CK_ULONG data_len;
1455 : CK_BYTE_PTR digest;
1456 : CK_ULONG digest_len;
1457 :
1458 0 : BEGIN_CALL (C_Digest);
1459 0 : IN_ULONG (session);
1460 0 : IN_BYTE_ARRAY (data, data_len);
1461 0 : IN_BYTE_BUFFER (digest, digest_len);
1462 0 : PROCESS_CALL ((session, data, data_len, digest, &digest_len));
1463 0 : OUT_BYTE_ARRAY (digest, digest_len);
1464 0 : END_CALL;
1465 : }
1466 :
1467 : static CK_RV
1468 0 : rpc_C_DigestUpdate (CallState *cs)
1469 : {
1470 : CK_SESSION_HANDLE session;
1471 : CK_BYTE_PTR part;
1472 : CK_ULONG part_len;
1473 :
1474 0 : BEGIN_CALL (C_DigestUpdate);
1475 0 : IN_ULONG (session);
1476 0 : IN_BYTE_ARRAY (part, part_len);
1477 0 : PROCESS_CALL ((session, part, part_len));
1478 0 : END_CALL;
1479 : }
1480 :
1481 : static CK_RV
1482 0 : rpc_C_DigestKey (CallState *cs)
1483 : {
1484 : CK_SESSION_HANDLE session;
1485 : CK_OBJECT_HANDLE key;
1486 :
1487 0 : BEGIN_CALL (C_DigestKey);
1488 0 : IN_ULONG (session);
1489 0 : IN_ULONG (key);
1490 0 : PROCESS_CALL ((session, key));
1491 0 : END_CALL;
1492 : }
1493 :
1494 : static CK_RV
1495 0 : rpc_C_DigestFinal (CallState *cs)
1496 : {
1497 : CK_SESSION_HANDLE session;
1498 : CK_BYTE_PTR digest;
1499 : CK_ULONG digest_len;
1500 :
1501 0 : BEGIN_CALL (C_DigestFinal);
1502 0 : IN_ULONG (session);
1503 0 : IN_BYTE_BUFFER (digest, digest_len);
1504 0 : PROCESS_CALL ((session, digest, &digest_len));
1505 0 : OUT_BYTE_ARRAY (digest, digest_len);
1506 0 : END_CALL;
1507 : }
1508 :
1509 : static CK_RV
1510 0 : rpc_C_SignInit (CallState *cs)
1511 : {
1512 : CK_SESSION_HANDLE session;
1513 : CK_MECHANISM mechanism;
1514 : CK_OBJECT_HANDLE key;
1515 :
1516 0 : BEGIN_CALL (C_SignInit);
1517 0 : IN_ULONG (session);
1518 0 : IN_MECHANISM (mechanism);
1519 0 : IN_ULONG (key);
1520 0 : PROCESS_CALL ((session, &mechanism, key));
1521 0 : END_CALL;
1522 : }
1523 :
1524 : static CK_RV
1525 0 : rpc_C_Sign (CallState *cs)
1526 : {
1527 : CK_SESSION_HANDLE session;
1528 : CK_BYTE_PTR part;
1529 : CK_ULONG part_len;
1530 : CK_BYTE_PTR signature;
1531 : CK_ULONG signature_len;
1532 :
1533 0 : BEGIN_CALL (C_Sign);
1534 0 : IN_ULONG (session);
1535 0 : IN_BYTE_ARRAY (part, part_len);
1536 0 : IN_BYTE_BUFFER (signature, signature_len);
1537 0 : PROCESS_CALL ((session, part, part_len, signature, &signature_len));
1538 0 : OUT_BYTE_ARRAY (signature, signature_len);
1539 0 : END_CALL;
1540 :
1541 : }
1542 :
1543 : static CK_RV
1544 0 : rpc_C_SignUpdate (CallState *cs)
1545 : {
1546 : CK_SESSION_HANDLE session;
1547 : CK_BYTE_PTR part;
1548 : CK_ULONG part_len;
1549 :
1550 0 : BEGIN_CALL (C_SignUpdate);
1551 0 : IN_ULONG (session);
1552 0 : IN_BYTE_ARRAY (part, part_len);
1553 0 : PROCESS_CALL ((session, part, part_len));
1554 0 : END_CALL;
1555 : }
1556 :
1557 : static CK_RV
1558 0 : rpc_C_SignFinal (CallState *cs)
1559 : {
1560 : CK_SESSION_HANDLE session;
1561 : CK_BYTE_PTR signature;
1562 : CK_ULONG signature_len;
1563 :
1564 0 : BEGIN_CALL (C_SignFinal);
1565 0 : IN_ULONG (session);
1566 0 : IN_BYTE_BUFFER (signature, signature_len);
1567 0 : PROCESS_CALL ((session, signature, &signature_len));
1568 0 : OUT_BYTE_ARRAY (signature, signature_len);
1569 0 : END_CALL;
1570 : }
1571 :
1572 : static CK_RV
1573 0 : rpc_C_SignRecoverInit (CallState *cs)
1574 : {
1575 : CK_SESSION_HANDLE session;
1576 : CK_MECHANISM mechanism;
1577 : CK_OBJECT_HANDLE key;
1578 :
1579 0 : BEGIN_CALL (C_SignRecoverInit);
1580 0 : IN_ULONG (session);
1581 0 : IN_MECHANISM (mechanism);
1582 0 : IN_ULONG (key);
1583 0 : PROCESS_CALL ((session, &mechanism, key));
1584 0 : END_CALL;
1585 : }
1586 :
1587 : static CK_RV
1588 0 : rpc_C_SignRecover (CallState *cs)
1589 : {
1590 : CK_SESSION_HANDLE session;
1591 : CK_BYTE_PTR data;
1592 : CK_ULONG data_len;
1593 : CK_BYTE_PTR signature;
1594 : CK_ULONG signature_len;
1595 :
1596 0 : BEGIN_CALL (C_SignRecover);
1597 0 : IN_ULONG (session);
1598 0 : IN_BYTE_ARRAY (data, data_len);
1599 0 : IN_BYTE_BUFFER (signature, signature_len);
1600 0 : PROCESS_CALL ((session, data, data_len, signature, &signature_len));
1601 0 : OUT_BYTE_ARRAY (signature, signature_len);
1602 0 : END_CALL;
1603 : }
1604 :
1605 : static CK_RV
1606 0 : rpc_C_VerifyInit (CallState *cs)
1607 : {
1608 : CK_SESSION_HANDLE session;
1609 : CK_MECHANISM mechanism;
1610 : CK_OBJECT_HANDLE key;
1611 :
1612 0 : BEGIN_CALL (C_VerifyInit);
1613 0 : IN_ULONG (session);
1614 0 : IN_MECHANISM (mechanism);
1615 0 : IN_ULONG (key);
1616 0 : PROCESS_CALL ((session, &mechanism, key));
1617 0 : END_CALL;
1618 : }
1619 :
1620 : static CK_RV
1621 0 : rpc_C_Verify (CallState *cs)
1622 : {
1623 : CK_SESSION_HANDLE session;
1624 : CK_BYTE_PTR data;
1625 : CK_ULONG data_len;
1626 : CK_BYTE_PTR signature;
1627 : CK_ULONG signature_len;
1628 :
1629 0 : BEGIN_CALL (C_Verify);
1630 0 : IN_ULONG (session);
1631 0 : IN_BYTE_ARRAY (data, data_len);
1632 0 : IN_BYTE_ARRAY (signature, signature_len);
1633 0 : PROCESS_CALL ((session, data, data_len, signature, signature_len));
1634 0 : END_CALL;
1635 : }
1636 :
1637 : static CK_RV
1638 0 : rpc_C_VerifyUpdate (CallState *cs)
1639 : {
1640 : CK_SESSION_HANDLE session;
1641 : CK_BYTE_PTR part;
1642 : CK_ULONG part_len;
1643 :
1644 0 : BEGIN_CALL (C_VerifyUpdate);
1645 0 : IN_ULONG (session);
1646 0 : IN_BYTE_ARRAY (part, part_len);
1647 0 : PROCESS_CALL ((session, part, part_len));
1648 0 : END_CALL;
1649 : }
1650 :
1651 : static CK_RV
1652 0 : rpc_C_VerifyFinal (CallState *cs)
1653 : {
1654 : CK_SESSION_HANDLE session;
1655 : CK_BYTE_PTR signature;
1656 : CK_ULONG signature_len;
1657 :
1658 0 : BEGIN_CALL (C_VerifyFinal);
1659 0 : IN_ULONG (session);
1660 0 : IN_BYTE_ARRAY (signature, signature_len);
1661 0 : PROCESS_CALL ((session, signature, signature_len));
1662 0 : END_CALL;
1663 : }
1664 :
1665 : static CK_RV
1666 0 : rpc_C_VerifyRecoverInit (CallState *cs)
1667 : {
1668 : CK_SESSION_HANDLE session;
1669 : CK_MECHANISM mechanism;
1670 : CK_OBJECT_HANDLE key;
1671 :
1672 0 : BEGIN_CALL (C_VerifyRecoverInit);
1673 0 : IN_ULONG (session);
1674 0 : IN_MECHANISM (mechanism);
1675 0 : IN_ULONG (key);
1676 0 : PROCESS_CALL ((session, &mechanism, key));
1677 0 : END_CALL;
1678 : }
1679 :
1680 : static CK_RV
1681 0 : rpc_C_VerifyRecover (CallState *cs)
1682 : {
1683 : CK_SESSION_HANDLE session;
1684 : CK_BYTE_PTR signature;
1685 : CK_ULONG signature_len;
1686 : CK_BYTE_PTR data;
1687 : CK_ULONG data_len;
1688 :
1689 0 : BEGIN_CALL (C_VerifyRecover);
1690 0 : IN_ULONG (session);
1691 0 : IN_BYTE_ARRAY (signature, signature_len);
1692 0 : IN_BYTE_BUFFER (data, data_len);
1693 0 : PROCESS_CALL ((session, signature, signature_len, data, &data_len));
1694 0 : OUT_BYTE_ARRAY (data, data_len);
1695 0 : END_CALL;
1696 : }
1697 :
1698 : static CK_RV
1699 0 : rpc_C_DigestEncryptUpdate (CallState *cs)
1700 : {
1701 : CK_SESSION_HANDLE session;
1702 : CK_BYTE_PTR part;
1703 : CK_ULONG part_len;
1704 : CK_BYTE_PTR encrypted_part;
1705 : CK_ULONG encrypted_part_len;
1706 :
1707 0 : BEGIN_CALL (C_DigestEncryptUpdate);
1708 0 : IN_ULONG (session);
1709 0 : IN_BYTE_ARRAY (part, part_len);
1710 0 : IN_BYTE_BUFFER (encrypted_part, encrypted_part_len);
1711 0 : PROCESS_CALL ((session, part, part_len, encrypted_part, &encrypted_part_len));
1712 0 : OUT_BYTE_ARRAY (encrypted_part, encrypted_part_len);
1713 0 : END_CALL;
1714 : }
1715 :
1716 : static CK_RV
1717 0 : rpc_C_DecryptDigestUpdate (CallState *cs)
1718 : {
1719 : CK_SESSION_HANDLE session;
1720 : CK_BYTE_PTR encrypted_part;
1721 : CK_ULONG encrypted_part_len;
1722 : CK_BYTE_PTR part;
1723 : CK_ULONG part_len;
1724 :
1725 0 : BEGIN_CALL (C_DecryptDigestUpdate);
1726 0 : IN_ULONG (session);
1727 0 : IN_BYTE_ARRAY (encrypted_part, encrypted_part_len);
1728 0 : IN_BYTE_BUFFER (part, part_len);
1729 0 : PROCESS_CALL ((session, encrypted_part, encrypted_part_len, part, &part_len));
1730 0 : OUT_BYTE_ARRAY (part, part_len);
1731 0 : END_CALL;
1732 : }
1733 :
1734 : static CK_RV
1735 0 : rpc_C_SignEncryptUpdate (CallState *cs)
1736 : {
1737 : CK_SESSION_HANDLE session;
1738 : CK_BYTE_PTR part;
1739 : CK_ULONG part_len;
1740 : CK_BYTE_PTR encrypted_part;
1741 : CK_ULONG encrypted_part_len;
1742 :
1743 0 : BEGIN_CALL (C_SignEncryptUpdate);
1744 0 : IN_ULONG (session);
1745 0 : IN_BYTE_ARRAY (part, part_len);
1746 0 : IN_BYTE_BUFFER (encrypted_part, encrypted_part_len);
1747 0 : PROCESS_CALL ((session, part, part_len, encrypted_part, &encrypted_part_len));
1748 0 : OUT_BYTE_ARRAY (encrypted_part, encrypted_part_len);
1749 0 : END_CALL;
1750 : }
1751 :
1752 : static CK_RV
1753 0 : rpc_C_DecryptVerifyUpdate (CallState *cs)
1754 : {
1755 : CK_SESSION_HANDLE session;
1756 : CK_BYTE_PTR encrypted_part;
1757 : CK_ULONG encrypted_part_len;
1758 : CK_BYTE_PTR part;
1759 : CK_ULONG part_len;
1760 :
1761 0 : BEGIN_CALL (C_DecryptVerifyUpdate);
1762 0 : IN_ULONG (session);
1763 0 : IN_BYTE_ARRAY (encrypted_part, encrypted_part_len);
1764 0 : IN_BYTE_BUFFER (part, part_len);
1765 0 : PROCESS_CALL ((session, encrypted_part, encrypted_part_len, part, &part_len));
1766 0 : OUT_BYTE_ARRAY (part, part_len);
1767 0 : END_CALL;
1768 : }
1769 :
1770 : /* -----------------------------------------------------------------------------
1771 : * KEY OPERATIONS
1772 : */
1773 :
1774 : static CK_RV
1775 0 : rpc_C_GenerateKey (CallState *cs)
1776 : {
1777 : CK_SESSION_HANDLE session;
1778 : CK_MECHANISM mechanism;
1779 : CK_ATTRIBUTE_PTR template;
1780 : CK_ULONG count;
1781 : CK_OBJECT_HANDLE key;
1782 :
1783 0 : BEGIN_CALL (C_GenerateKey);
1784 0 : IN_ULONG (session);
1785 0 : IN_MECHANISM (mechanism);
1786 0 : IN_ATTRIBUTE_ARRAY (template, count);
1787 0 : PROCESS_CALL ((session, &mechanism, template, count, &key));
1788 0 : OUT_ULONG (key);
1789 0 : END_CALL;
1790 : }
1791 :
1792 : static CK_RV
1793 0 : rpc_C_GenerateKeyPair (CallState *cs)
1794 : {
1795 : CK_SESSION_HANDLE session;
1796 : CK_MECHANISM mechanism;
1797 : CK_ATTRIBUTE_PTR public_key_template;
1798 : CK_ULONG public_key_attribute_count;
1799 : CK_ATTRIBUTE_PTR private_key_template;
1800 : CK_ULONG private_key_attribute_count;
1801 : CK_OBJECT_HANDLE public_key;
1802 : CK_OBJECT_HANDLE private_key;
1803 :
1804 0 : BEGIN_CALL (C_GenerateKeyPair);
1805 0 : IN_ULONG (session);
1806 0 : IN_MECHANISM (mechanism);
1807 0 : IN_ATTRIBUTE_ARRAY (public_key_template, public_key_attribute_count);
1808 0 : IN_ATTRIBUTE_ARRAY (private_key_template, private_key_attribute_count);
1809 0 : PROCESS_CALL ((session, &mechanism, public_key_template, public_key_attribute_count, private_key_template, private_key_attribute_count, &public_key, &private_key));
1810 0 : OUT_ULONG (public_key);
1811 0 : OUT_ULONG (private_key);
1812 0 : END_CALL;
1813 :
1814 : }
1815 :
1816 : static CK_RV
1817 0 : rpc_C_WrapKey (CallState *cs)
1818 : {
1819 : CK_SESSION_HANDLE session;
1820 : CK_MECHANISM mechanism;
1821 : CK_OBJECT_HANDLE wrapping_key;
1822 : CK_OBJECT_HANDLE key;
1823 : CK_BYTE_PTR wrapped_key;
1824 : CK_ULONG wrapped_key_len;
1825 :
1826 0 : BEGIN_CALL (C_WrapKey);
1827 0 : IN_ULONG (session);
1828 0 : IN_MECHANISM (mechanism);
1829 0 : IN_ULONG (wrapping_key);
1830 0 : IN_ULONG (key);
1831 0 : IN_BYTE_BUFFER (wrapped_key, wrapped_key_len);
1832 0 : PROCESS_CALL ((session, &mechanism, wrapping_key, key, wrapped_key, &wrapped_key_len));
1833 0 : OUT_BYTE_ARRAY (wrapped_key, wrapped_key_len);
1834 0 : END_CALL;
1835 : }
1836 :
1837 : static CK_RV
1838 0 : rpc_C_UnwrapKey (CallState *cs)
1839 : {
1840 : CK_SESSION_HANDLE session;
1841 : CK_MECHANISM mechanism;
1842 : CK_OBJECT_HANDLE unwrapping_key;
1843 : CK_BYTE_PTR wrapped_key;
1844 : CK_ULONG wrapped_key_len;
1845 : CK_ATTRIBUTE_PTR template;
1846 : CK_ULONG attribute_count;
1847 : CK_OBJECT_HANDLE key;
1848 :
1849 0 : BEGIN_CALL (C_UnwrapKey);
1850 0 : IN_ULONG (session);
1851 0 : IN_MECHANISM (mechanism);
1852 0 : IN_ULONG (unwrapping_key);
1853 0 : IN_BYTE_ARRAY (wrapped_key, wrapped_key_len);
1854 0 : IN_ATTRIBUTE_ARRAY (template, attribute_count);
1855 0 : PROCESS_CALL ((session, &mechanism, unwrapping_key, wrapped_key, wrapped_key_len, template, attribute_count, &key));
1856 0 : OUT_ULONG (key);
1857 0 : END_CALL;
1858 : }
1859 :
1860 : static CK_RV
1861 0 : rpc_C_DeriveKey (CallState *cs)
1862 : {
1863 : CK_SESSION_HANDLE session;
1864 : CK_MECHANISM mechanism;
1865 : CK_OBJECT_HANDLE base_key;
1866 : CK_ATTRIBUTE_PTR template;
1867 : CK_ULONG attribute_count;
1868 : CK_OBJECT_HANDLE key;
1869 :
1870 0 : BEGIN_CALL (C_DeriveKey);
1871 0 : IN_ULONG (session);
1872 0 : IN_MECHANISM (mechanism);
1873 0 : IN_ULONG (base_key);
1874 0 : IN_ATTRIBUTE_ARRAY (template, attribute_count);
1875 0 : PROCESS_CALL ((session, &mechanism, base_key, template, attribute_count, &key));
1876 0 : OUT_ULONG (key);
1877 0 : END_CALL;
1878 : }
1879 :
1880 : static CK_RV
1881 0 : rpc_C_SeedRandom (CallState *cs)
1882 : {
1883 : CK_SESSION_HANDLE session;
1884 : CK_BYTE_PTR seed;
1885 : CK_ULONG seed_len;
1886 :
1887 0 : BEGIN_CALL (C_SeedRandom);
1888 0 : IN_ULONG (session);
1889 0 : IN_BYTE_ARRAY (seed, seed_len);
1890 0 : PROCESS_CALL ((session, seed, seed_len));
1891 0 : END_CALL;
1892 : }
1893 :
1894 : static CK_RV
1895 0 : rpc_C_GenerateRandom (CallState *cs)
1896 : {
1897 : CK_SESSION_HANDLE session;
1898 : CK_BYTE_PTR random_data;
1899 : CK_ULONG random_len;
1900 :
1901 0 : BEGIN_CALL (C_GenerateRandom);
1902 0 : IN_ULONG (session);
1903 0 : IN_BYTE_BUFFER (random_data, random_len);
1904 0 : PROCESS_CALL ((session, random_data, random_len));
1905 0 : OUT_BYTE_ARRAY (random_data, random_len);
1906 0 : END_CALL;
1907 : }
1908 :
1909 : /* ---------------------------------------------------------------------------
1910 : * DISPATCH THREAD HANDLING
1911 : */
1912 :
1913 : static int
1914 6 : dispatch_call (CallState *cs)
1915 : {
1916 : GkmRpcMessage *req, *resp;
1917 6 : CK_RV ret = CKR_OK;
1918 :
1919 6 : assert (cs);
1920 :
1921 6 : req = cs->req;
1922 6 : resp = cs->resp;
1923 :
1924 : /* This should have been checked by the parsing code */
1925 6 : assert (req->call_id > GKM_RPC_CALL_ERROR);
1926 6 : assert (req->call_id < GKM_RPC_CALL_MAX);
1927 :
1928 : /* Prepare a response for the function to fill in */
1929 6 : if (!gkm_rpc_message_prep (resp, req->call_id, GKM_RPC_RESPONSE)) {
1930 0 : gkm_rpc_warn ("couldn't prepare message");
1931 0 : return 0;
1932 : }
1933 :
1934 6 : switch(req->call_id) {
1935 :
1936 : #define CASE_CALL(name) \
1937 : case GKM_RPC_CALL_##name: \
1938 : ret = rpc_##name (cs); \
1939 : break;
1940 2 : CASE_CALL(C_Initialize)
1941 2 : CASE_CALL(C_Finalize)
1942 2 : CASE_CALL(C_GetInfo)
1943 0 : CASE_CALL(C_GetSlotList)
1944 0 : CASE_CALL(C_GetSlotInfo)
1945 0 : CASE_CALL(C_GetTokenInfo)
1946 0 : CASE_CALL(C_GetMechanismList)
1947 0 : CASE_CALL(C_GetMechanismInfo)
1948 0 : CASE_CALL(C_InitToken)
1949 0 : CASE_CALL(C_WaitForSlotEvent)
1950 0 : CASE_CALL(C_OpenSession)
1951 0 : CASE_CALL(C_CloseSession)
1952 0 : CASE_CALL(C_CloseAllSessions)
1953 0 : CASE_CALL(C_GetFunctionStatus)
1954 0 : CASE_CALL(C_CancelFunction)
1955 0 : CASE_CALL(C_GetSessionInfo)
1956 0 : CASE_CALL(C_InitPIN)
1957 0 : CASE_CALL(C_SetPIN)
1958 0 : CASE_CALL(C_GetOperationState)
1959 0 : CASE_CALL(C_SetOperationState)
1960 0 : CASE_CALL(C_Login)
1961 0 : CASE_CALL(C_Logout)
1962 0 : CASE_CALL(C_CreateObject)
1963 0 : CASE_CALL(C_CopyObject)
1964 0 : CASE_CALL(C_DestroyObject)
1965 0 : CASE_CALL(C_GetObjectSize)
1966 0 : CASE_CALL(C_GetAttributeValue)
1967 0 : CASE_CALL(C_SetAttributeValue)
1968 0 : CASE_CALL(C_FindObjectsInit)
1969 0 : CASE_CALL(C_FindObjects)
1970 0 : CASE_CALL(C_FindObjectsFinal)
1971 0 : CASE_CALL(C_EncryptInit)
1972 0 : CASE_CALL(C_Encrypt)
1973 0 : CASE_CALL(C_EncryptUpdate)
1974 0 : CASE_CALL(C_EncryptFinal)
1975 0 : CASE_CALL(C_DecryptInit)
1976 0 : CASE_CALL(C_Decrypt)
1977 0 : CASE_CALL(C_DecryptUpdate)
1978 0 : CASE_CALL(C_DecryptFinal)
1979 0 : CASE_CALL(C_DigestInit)
1980 0 : CASE_CALL(C_Digest)
1981 0 : CASE_CALL(C_DigestUpdate)
1982 0 : CASE_CALL(C_DigestKey)
1983 0 : CASE_CALL(C_DigestFinal)
1984 0 : CASE_CALL(C_SignInit)
1985 0 : CASE_CALL(C_Sign)
1986 0 : CASE_CALL(C_SignUpdate)
1987 0 : CASE_CALL(C_SignFinal)
1988 0 : CASE_CALL(C_SignRecoverInit)
1989 0 : CASE_CALL(C_SignRecover)
1990 0 : CASE_CALL(C_VerifyInit)
1991 0 : CASE_CALL(C_Verify)
1992 0 : CASE_CALL(C_VerifyUpdate)
1993 0 : CASE_CALL(C_VerifyFinal)
1994 0 : CASE_CALL(C_VerifyRecoverInit)
1995 0 : CASE_CALL(C_VerifyRecover)
1996 0 : CASE_CALL(C_DigestEncryptUpdate)
1997 0 : CASE_CALL(C_DecryptDigestUpdate)
1998 0 : CASE_CALL(C_SignEncryptUpdate)
1999 0 : CASE_CALL(C_DecryptVerifyUpdate)
2000 0 : CASE_CALL(C_GenerateKey)
2001 0 : CASE_CALL(C_GenerateKeyPair)
2002 0 : CASE_CALL(C_WrapKey)
2003 0 : CASE_CALL(C_UnwrapKey)
2004 0 : CASE_CALL(C_DeriveKey)
2005 0 : CASE_CALL(C_SeedRandom)
2006 0 : CASE_CALL(C_GenerateRandom)
2007 : #undef CASE_CALL
2008 :
2009 0 : default:
2010 : /* This should have been caught by the parse code */
2011 0 : assert (0 && "Unchecked call");
2012 : break;
2013 : };
2014 :
2015 6 : if (ret == CKR_OK) {
2016 :
2017 : /* Parsing errors? */
2018 6 : if (gkm_rpc_message_buffer_error (req)) {
2019 0 : gkm_rpc_warn ("invalid request from module, probably too short");
2020 0 : ret = PARSE_ERROR;
2021 : }
2022 :
2023 : /* Out of memory errors? */
2024 6 : if (gkm_rpc_message_buffer_error (resp)) {
2025 0 : gkm_rpc_warn ("out of memory error putting together message");
2026 0 : ret = PREP_ERROR;
2027 : }
2028 : }
2029 :
2030 : /* A filled in response */
2031 6 : if (ret == CKR_OK) {
2032 :
2033 : /*
2034 : * Since we're dealing with many many functions above generating
2035 : * these messages we want to make sure each of them actually
2036 : * does what it's supposed to.
2037 : */
2038 :
2039 6 : assert (gkm_rpc_message_is_verified (resp));
2040 6 : assert (resp->call_type == GKM_RPC_RESPONSE);
2041 6 : assert (resp->call_id == req->call_id);
2042 6 : assert (gkm_rpc_calls[resp->call_id].response);
2043 6 : assert (strcmp (gkm_rpc_calls[resp->call_id].response,
2044 : resp->signature) == 0);
2045 :
2046 : /* Fill in an error respnose */
2047 : } else {
2048 0 : if (!gkm_rpc_message_prep (resp, GKM_RPC_CALL_ERROR, GKM_RPC_RESPONSE) ||
2049 0 : !gkm_rpc_message_write_ulong (resp, (uint32_t)ret) ||
2050 0 : gkm_rpc_message_buffer_error (resp)) {
2051 0 : gkm_rpc_warn ("out of memory responding with error");
2052 0 : return 0;
2053 : }
2054 : }
2055 :
2056 6 : return 1;
2057 : }
2058 :
2059 : static int
2060 14 : read_all (int sock, unsigned char* data, size_t len)
2061 : {
2062 : int r;
2063 :
2064 14 : assert (sock >= 0);
2065 14 : assert (data);
2066 14 : assert (len > 0);
2067 :
2068 26 : while (len > 0) {
2069 :
2070 14 : r = read (sock, data, len);
2071 :
2072 14 : if (r == 0) {
2073 : /* Connection was closed on client */
2074 2 : return 0;
2075 12 : } else if (r == -1) {
2076 0 : if (errno != EAGAIN && errno != EINTR) {
2077 0 : gkm_rpc_warn ("couldn't receive data: %s", strerror (errno));
2078 0 : return 0;
2079 : }
2080 : } else {
2081 12 : data += r;
2082 12 : len -= r;
2083 : }
2084 : }
2085 :
2086 12 : return 1;
2087 : }
2088 :
2089 : static int
2090 12 : write_all (int sock, unsigned char* data, size_t len)
2091 : {
2092 : int r;
2093 :
2094 12 : assert (sock >= 0);
2095 12 : assert (data);
2096 12 : assert (len > 0);
2097 :
2098 24 : while (len > 0) {
2099 :
2100 12 : r = write (sock, data, len);
2101 :
2102 12 : if (r == -1) {
2103 0 : if (errno == EPIPE) {
2104 : /* Connection closed from client */
2105 0 : return 0;
2106 0 : } else if (errno != EAGAIN && errno != EINTR) {
2107 0 : gkm_rpc_warn ("couldn't send data: %s", strerror (errno));
2108 0 : return 0;
2109 : }
2110 : } else {
2111 12 : data += r;
2112 12 : len -= r;
2113 : }
2114 : }
2115 :
2116 12 : return 1;
2117 : }
2118 :
2119 : static void
2120 2 : run_dispatch_loop (int sock)
2121 : {
2122 : CallState cs;
2123 : pid_t pid;
2124 : uid_t uid;
2125 : unsigned char buf[4];
2126 : uint32_t len;
2127 :
2128 2 : assert (sock != -1);
2129 :
2130 2 : if (egg_unix_credentials_read (sock, &pid, &uid) < 0) {
2131 0 : gkm_rpc_warn ("couldn't read socket credentials");
2132 0 : return;
2133 : }
2134 :
2135 : /* Setup our buffers */
2136 2 : if (!call_init (&cs, uid, pid)) {
2137 0 : gkm_rpc_warn ("out of memory");
2138 0 : return;
2139 : }
2140 :
2141 : /* The main thread loop */
2142 : while (TRUE) {
2143 :
2144 8 : call_reset (&cs);
2145 :
2146 : /* Read the number of bytes ... */
2147 8 : if (!read_all (sock, buf, 4))
2148 2 : break;
2149 :
2150 : /* Calculate the number of bytes */
2151 6 : len = egg_buffer_decode_uint32 (buf);
2152 6 : if (len >= 0x0FFFFFFF) {
2153 0 : gkm_rpc_warn ("invalid message size from module: %u bytes", len);
2154 0 : break;
2155 : }
2156 :
2157 : /* Allocate memory */
2158 6 : egg_buffer_reserve (&cs.req->buffer, cs.req->buffer.len + len);
2159 6 : if (egg_buffer_has_error (&cs.req->buffer)) {
2160 0 : gkm_rpc_warn ("error allocating buffer for message");
2161 0 : break;
2162 : }
2163 :
2164 : /* ... and read/parse in the actual message */
2165 6 : if (!read_all (sock, cs.req->buffer.buf, len))
2166 0 : break;
2167 :
2168 6 : egg_buffer_add_empty (&cs.req->buffer, len);
2169 :
2170 6 : if (!gkm_rpc_message_parse (cs.req, GKM_RPC_REQUEST))
2171 0 : break;
2172 :
2173 : /* ... send for processing ... */
2174 6 : if (!dispatch_call (&cs))
2175 0 : break;
2176 :
2177 : /* .. send back response length, and then response data */
2178 6 : egg_buffer_encode_uint32 (buf, cs.resp->buffer.len);
2179 12 : if(!write_all (sock, buf, 4) ||
2180 6 : !write_all (sock, cs.resp->buffer.buf, cs.resp->buffer.len))
2181 : break;
2182 : }
2183 :
2184 : /*
2185 : * Close all sessions for the client application
2186 : *
2187 : * EXTENSION: In our extended application PKCS#11 model
2188 : * C_CloseAllSessions accepts an application identifier as well
2189 : * as slot ids. Calling with an application identifier closes all
2190 : * sessions for just that application identifier.
2191 : */
2192 2 : pthread_mutex_lock (&clients_mutex);
2193 :
2194 2 : if (!--cs.client->refcount) {
2195 2 : ClientInstance **cl = &clients;
2196 :
2197 2 : while (*cl) {
2198 2 : if (*cl == cs.client) {
2199 2 : *cl = cs.client->next;
2200 2 : break;
2201 : }
2202 0 : cl = &(*cl)->next;
2203 : }
2204 2 : if (cs.client->application.applicationId)
2205 0 : (pkcs11_module->C_CloseAllSessions) (cs.client->application.applicationId);
2206 2 : free (cs.client);
2207 2 : cs.client = NULL;
2208 : }
2209 :
2210 2 : pthread_mutex_unlock (&clients_mutex);
2211 :
2212 2 : call_uninit (&cs);
2213 : }
2214 :
2215 : static void*
2216 2 : run_dispatch_thread (void *arg)
2217 : {
2218 2 : int *sock = arg;
2219 2 : assert (*sock != -1);
2220 :
2221 2 : run_dispatch_loop (*sock);
2222 :
2223 : /* The thread closes the socket and marks as done */
2224 2 : assert (*sock != -1);
2225 2 : close (*sock);
2226 2 : *sock = -1;
2227 :
2228 2 : return NULL;
2229 : }
2230 :
2231 : /* ---------------------------------------------------------------------------
2232 : * MAIN THREAD
2233 : */
2234 :
2235 : typedef struct _DispatchState {
2236 : struct _DispatchState *next;
2237 : GThread *thread;
2238 : int socket;
2239 : } DispatchState;
2240 :
2241 : /* The main daemon socket that we're listening on */
2242 : static int pkcs11_socket = -1;
2243 :
2244 : /* The unix socket path, that we listen on */
2245 : static char *pkcs11_socket_path = NULL;
2246 :
2247 : /* A linked list of dispatcher threads */
2248 : static DispatchState *pkcs11_dispatchers = NULL;
2249 :
2250 : void
2251 2 : gkm_rpc_layer_accept (void)
2252 : {
2253 : struct sockaddr_un addr;
2254 : DispatchState *ds, **here;
2255 2 : GError *error = NULL;
2256 : socklen_t addrlen;
2257 : int new_fd;
2258 :
2259 2 : assert (pkcs11_socket != -1);
2260 :
2261 : /* Cleanup any completed dispatch threads */
2262 2 : for (here = &pkcs11_dispatchers, ds = *here; ds != NULL; ds = *here) {
2263 0 : if (ds->socket == -1) {
2264 0 : g_thread_join (ds->thread);
2265 0 : *here = ds->next;
2266 0 : free (ds);
2267 : } else {
2268 0 : here = &ds->next;
2269 : }
2270 : }
2271 :
2272 2 : addrlen = sizeof (addr);
2273 2 : new_fd = accept (pkcs11_socket, (struct sockaddr*) &addr, &addrlen);
2274 2 : if (new_fd < 0) {
2275 0 : gkm_rpc_warn ("cannot accept pkcs11 connection: %s", strerror (errno));
2276 0 : return;
2277 : }
2278 :
2279 2 : ds = calloc (1, sizeof (DispatchState));
2280 2 : if (ds == NULL) {
2281 0 : gkm_rpc_warn ("out of memory");
2282 0 : close (new_fd);
2283 0 : return;
2284 : }
2285 :
2286 2 : ds->socket = new_fd;
2287 :
2288 2 : ds->thread = g_thread_new ("dispatch", run_dispatch_thread, &(ds->socket));
2289 2 : if (!ds->thread) {
2290 0 : gkm_rpc_warn ("couldn't start thread: %s", egg_error_message (error));
2291 0 : close (new_fd);
2292 0 : free (ds);
2293 0 : return;
2294 : }
2295 :
2296 2 : ds->next = pkcs11_dispatchers;
2297 2 : pkcs11_dispatchers = ds;
2298 : }
2299 :
2300 : int
2301 27 : gkm_rpc_layer_initialize (CK_FUNCTION_LIST_PTR module)
2302 : {
2303 27 : assert (module);
2304 :
2305 : /* cannot be called more than once */
2306 27 : assert (!pkcs11_module);
2307 27 : pkcs11_module = module;
2308 27 : return 1;
2309 : }
2310 :
2311 : void
2312 27 : gkm_rpc_layer_uninitialize (void)
2313 : {
2314 : DispatchState *ds, *next;
2315 :
2316 27 : if (!pkcs11_module)
2317 0 : return;
2318 :
2319 : /* Close our main listening socket */
2320 27 : if (pkcs11_socket != -1)
2321 0 : close (pkcs11_socket);
2322 27 : pkcs11_socket = -1;
2323 :
2324 : /* Delete our unix socket */
2325 27 : if(pkcs11_socket_path) {
2326 0 : unlink (pkcs11_socket_path);
2327 0 : free (pkcs11_socket_path);
2328 0 : pkcs11_socket_path = NULL;
2329 : }
2330 :
2331 27 : ds = pkcs11_dispatchers;
2332 27 : pkcs11_dispatchers = NULL;
2333 :
2334 : /* Stop all of the dispatch threads */
2335 27 : for (; ds; ds = next) {
2336 0 : next = ds->next;
2337 :
2338 : /* Forcibly shutdown the connection */
2339 0 : if (ds->socket)
2340 0 : shutdown (ds->socket, SHUT_RDWR);
2341 0 : g_thread_join (ds->thread);
2342 :
2343 : /* This is always closed by dispatch thread */
2344 0 : assert (ds->socket == -1);
2345 0 : free (ds);
2346 : }
2347 :
2348 27 : pkcs11_module = NULL;
2349 : }
2350 :
2351 : int
2352 11 : gkm_rpc_layer_startup (const char *prefix)
2353 : {
2354 : struct sockaddr_un addr;
2355 : int sock;
2356 :
2357 : #ifdef _DEBUG
2358 759 : GKM_RPC_CHECK_CALLS ();
2359 : #endif
2360 :
2361 11 : assert (prefix);
2362 :
2363 : /* cannot be called more than once */
2364 11 : assert (pkcs11_socket == -1);
2365 11 : assert (pkcs11_dispatchers == NULL);
2366 :
2367 11 : free (pkcs11_socket_path);
2368 11 : pkcs11_socket_path = malloc (strlen (prefix) + strlen ("/pkcs11") + 1);
2369 11 : if (pkcs11_socket_path == NULL) {
2370 0 : gkm_rpc_warn ("couldn't allocate memory");
2371 0 : return -1;
2372 : }
2373 11 : sprintf (pkcs11_socket_path, "%s/pkcs11", prefix);
2374 :
2375 11 : sock = socket(AF_UNIX, SOCK_STREAM, 0);
2376 11 : if (sock < 0) {
2377 0 : gkm_rpc_warn ("couldn't create pkcs11 socket: %s", strerror (errno));
2378 0 : return -1;
2379 : }
2380 :
2381 11 : memset(&addr, 0, sizeof(addr));
2382 11 : addr.sun_family = AF_UNIX;
2383 11 : unlink (pkcs11_socket_path);
2384 11 : g_strlcpy (addr.sun_path, pkcs11_socket_path, sizeof (addr.sun_path));
2385 11 : if (bind (sock, (struct sockaddr*)&addr, sizeof (addr)) < 0) {
2386 0 : gkm_rpc_warn ("couldn't bind to pkcs11 socket: %s: %s",
2387 0 : pkcs11_socket_path, strerror (errno));
2388 0 : return -1;
2389 : }
2390 :
2391 11 : if (listen (sock, 128) < 0) {
2392 0 : gkm_rpc_warn ("couldn't listen on pkcs11 socket: %s: %s",
2393 0 : pkcs11_socket_path, strerror (errno));
2394 0 : return -1;
2395 : }
2396 :
2397 11 : pkcs11_socket = sock;
2398 11 : pkcs11_dispatchers = NULL;
2399 :
2400 11 : return sock;
2401 : }
2402 :
2403 : void
2404 11 : gkm_rpc_layer_shutdown (void)
2405 : {
2406 : DispatchState *ds, *next;
2407 :
2408 : /* Close our main listening socket */
2409 11 : if (pkcs11_socket != -1)
2410 11 : close (pkcs11_socket);
2411 11 : pkcs11_socket = -1;
2412 :
2413 : /* Delete our unix socket */
2414 11 : if(pkcs11_socket_path) {
2415 11 : unlink (pkcs11_socket_path);
2416 11 : free (pkcs11_socket_path);
2417 11 : pkcs11_socket_path = NULL;
2418 : }
2419 :
2420 11 : ds = pkcs11_dispatchers;
2421 11 : pkcs11_dispatchers = NULL;
2422 :
2423 : /* Stop all of the dispatch threads */
2424 13 : for (; ds; ds = next) {
2425 2 : next = ds->next;
2426 :
2427 : /* Forcibly shutdown the connection */
2428 2 : if (ds->socket)
2429 2 : shutdown (ds->socket, SHUT_RDWR);
2430 2 : g_thread_join (ds->thread);
2431 :
2432 : /* This is always closed by dispatch thread */
2433 2 : assert (ds->socket == -1);
2434 2 : free (ds);
2435 : }
2436 11 : }
|