Bug Summary

File:lib/pkcs11.c
Location:line 426, column 11
Description:Null pointer passed as an argument to a 'nonnull' parameter

Annotated Source Code

1/*
2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010, 2011 Free Software Foundation
4 * Copyright (C) 2008, Joe Orton <joe@manyfish.co.uk>
5 *
6 * Authors: Nikos Mavrogiannopoulos, Stef Walter
7 *
8 * Inspired and some parts (pkcs11_login) based on neon PKCS #11 support
9 * by Joe Orton. More ideas came from the pkcs11-helper library by
10 * Alon Bar-Lev.
11 *
12 * The GnuTLS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 3 of
15 * the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>
24 */
25
26#include <gnutls_int.h>
27#include <gnutls/pkcs11.h>
28#include <stdio.h>
29#include <string.h>
30#include <gnutls_errors.h>
31#include <gnutls_datumgnutls_datum_t.h>
32
33
34#include <pkcs11_int.h>
35#include <p11-kit/p11-kit.h>
36#include <p11-kit/pin.h>
37
38#define MAX_PROVIDERS16 16
39
40/* XXX: try to eliminate this */
41#define MAX_CERT_SIZE8*1024 8*1024
42
43struct gnutls_pkcs11_provider_s
44{
45 struct ck_function_list *module;
46 unsigned long nslots;
47 ck_slot_id_t *slots;
48 struct ck_info info;
49 int initialized;
50};
51
52struct flags_find_data_st
53{
54 struct p11_kit_uri *info;
55 unsigned int slot_flags;
56};
57
58struct url_find_data_st
59{
60 gnutls_pkcs11_obj_t crt;
61};
62
63struct crt_find_data_st
64{
65 gnutls_pkcs11_obj_t *p_list;
66 unsigned int *n_list;
67 unsigned int current;
68 gnutls_pkcs11_obj_attr_t flags;
69 struct p11_kit_uri *info;
70};
71
72
73static struct gnutls_pkcs11_provider_s providers[MAX_PROVIDERS16];
74static int active_providers = 0;
75static int initialized_registered = 0;
76
77static gnutls_pkcs11_pin_callback_t pin_func;
78static void *pin_data;
79
80gnutls_pkcs11_token_callback_t token_func;
81void *token_data;
82
83int
84pkcs11_rv_to_err (ck_rv_t rv)
85{
86 switch (rv)
87 {
88 case CKR_OK(0UL):
89 return 0;
90 case CKR_HOST_MEMORY(2UL):
91 return GNUTLS_E_MEMORY_ERROR-25;
92 case CKR_SLOT_ID_INVALID(3UL):
93 return GNUTLS_E_PKCS11_SLOT_ERROR-305;
94 case CKR_ARGUMENTS_BAD(7UL):
95 case CKR_MECHANISM_PARAM_INVALID(0x71UL):
96 return GNUTLS_E_INVALID_REQUEST-50;
97 case CKR_NEED_TO_CREATE_THREADS(9UL):
98 case CKR_CANT_LOCK(0xaUL):
99 case CKR_FUNCTION_NOT_PARALLEL(0x51UL):
100 case CKR_MUTEX_BAD(0x1a0UL):
101 case CKR_MUTEX_NOT_LOCKED(0x1a1UL):
102 return GNUTLS_E_LOCKING_ERROR-306;
103 case CKR_ATTRIBUTE_READ_ONLY(0x10UL):
104 case CKR_ATTRIBUTE_SENSITIVE(0x11UL):
105 case CKR_ATTRIBUTE_TYPE_INVALID(0x12UL):
106 case CKR_ATTRIBUTE_VALUE_INVALID(0x13UL):
107 return GNUTLS_E_PKCS11_ATTRIBUTE_ERROR-307;
108 case CKR_DEVICE_ERROR(0x30UL):
109 case CKR_DEVICE_MEMORY(0x31UL):
110 case CKR_DEVICE_REMOVED(0x32UL):
111 return GNUTLS_E_PKCS11_DEVICE_ERROR-308;
112 case CKR_DATA_INVALID(0x20UL):
113 case CKR_DATA_LEN_RANGE(0x21UL):
114 case CKR_ENCRYPTED_DATA_INVALID(0x40UL):
115 case CKR_ENCRYPTED_DATA_LEN_RANGE(0x41UL):
116 case CKR_OBJECT_HANDLE_INVALID(0x82UL):
117 return GNUTLS_E_PKCS11_DATA_ERROR-309;
118 case CKR_FUNCTION_NOT_SUPPORTED(0x54UL):
119 case CKR_MECHANISM_INVALID(0x70UL):
120 return GNUTLS_E_PKCS11_UNSUPPORTED_FEATURE_ERROR-310;
121 case CKR_KEY_HANDLE_INVALID(0x60UL):
122 case CKR_KEY_SIZE_RANGE(0x62UL):
123 case CKR_KEY_TYPE_INCONSISTENT(0x63UL):
124 case CKR_KEY_NOT_NEEDED(0x64UL):
125 case CKR_KEY_CHANGED(0x65UL):
126 case CKR_KEY_NEEDED(0x66UL):
127 case CKR_KEY_INDIGESTIBLE(0x67UL):
128 case CKR_KEY_FUNCTION_NOT_PERMITTED(0x68UL):
129 case CKR_KEY_NOT_WRAPPABLE(0x69UL):
130 case CKR_KEY_UNEXTRACTABLE(0x6aUL):
131 return GNUTLS_E_PKCS11_KEY_ERROR-311;
132 case CKR_PIN_INCORRECT(0xa0UL):
133 case CKR_PIN_INVALID(0xa1UL):
134 case CKR_PIN_LEN_RANGE(0xa2UL):
135 return GNUTLS_E_PKCS11_PIN_ERROR-303;
136 case CKR_PIN_EXPIRED(0xa3UL):
137 return GNUTLS_E_PKCS11_PIN_EXPIRED-312;
138 case CKR_PIN_LOCKED(0xa4UL):
139 return GNUTLS_E_PKCS11_PIN_LOCKED-313;
140 case CKR_SESSION_CLOSED(0xb0UL):
141 case CKR_SESSION_COUNT(0xb1UL):
142 case CKR_SESSION_HANDLE_INVALID(0xb3UL):
143 case CKR_SESSION_PARALLEL_NOT_SUPPORTED(0xb4UL):
144 case CKR_SESSION_READ_ONLY(0xb5UL):
145 case CKR_SESSION_EXISTS(0xb6UL):
146 case CKR_SESSION_READ_ONLY_EXISTS(0xb7UL):
147 case CKR_SESSION_READ_WRITE_SO_EXISTS(0xb8UL):
148 return GNUTLS_E_PKCS11_SESSION_ERROR-314;
149 case CKR_SIGNATURE_INVALID(0xc0UL):
150 case CKR_SIGNATURE_LEN_RANGE(0xc1UL):
151 return GNUTLS_E_PKCS11_SIGNATURE_ERROR-315;
152 case CKR_TOKEN_NOT_PRESENT(0xe0UL):
153 case CKR_TOKEN_NOT_RECOGNIZED(0xe1UL):
154 case CKR_TOKEN_WRITE_PROTECTED(0xe2UL):
155 return GNUTLS_E_PKCS11_TOKEN_ERROR-316;
156 case CKR_USER_ALREADY_LOGGED_IN(0x100UL):
157 case CKR_USER_NOT_LOGGED_IN(0x101UL):
158 case CKR_USER_PIN_NOT_INITIALIZED(0x102UL):
159 case CKR_USER_TYPE_INVALID(0x103UL):
160 case CKR_USER_ANOTHER_ALREADY_LOGGED_IN(0x104UL):
161 case CKR_USER_TOO_MANY_TYPES(0x105UL):
162 return GNUTLS_E_PKCS11_USER_ERROR-317;
163 case CKR_BUFFER_TOO_SMALL(0x150UL):
164 return GNUTLS_E_SHORT_MEMORY_BUFFER-51;
165 default:
166 return GNUTLS_E_PKCS11_ERROR-300;
167 }
168}
169
170/* Fake scan */
171void
172pkcs11_rescan_slots (void)
173{
174 unsigned long slots;
175
176 pkcs11_get_slot_list (providers[active_providers - 1].module, 0,
177 NULL((void*)0), &slots);
178}
179
180static int
181pkcs11_add_module (const char *name, struct ck_function_list *module)
182{
183 struct ck_info info;
184 int i;
185
186 if (active_providers >= MAX_PROVIDERS16)
187 {
188 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",188); } while(0);
;
189 return GNUTLS_E_CONSTRAINT_ERROR-101;
190 }
191
192 /* initially check if this module is a duplicate */
193 memset(&info, 0, sizeof(info));
194 pkcs11_get_module_info (module, &info);
195 for (i=0;i<active_providers;i++)
196 {
197 /* already loaded, skip the rest */
198 if (memcmp(&info, &providers[i].info, sizeof(info)) == 0)
199 {
200 _gnutls_debug_log("%s is already loaded.\n", name)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "%s is already loaded.\n", name); } while(0)
;
201 return GNUTLS_E_INT_RET_0-1251;
202 }
203 }
204
205 active_providers++;
206 providers[active_providers - 1].module = module;
207
208 /* cache the number of slots in this module */
209 if (pkcs11_get_slot_list
210 (providers[active_providers - 1].module, 0, NULL((void*)0),
211 &providers[active_providers - 1].nslots) != CKR_OK(0UL))
212 {
213 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",213); } while(0);
;
214 goto fail;
215 }
216
217 providers[active_providers - 1].slots =
218 gnutls_malloc (sizeof (*providers[active_providers - 1].slots) *
219 providers[active_providers - 1].nslots);
220 if (providers[active_providers - 1].slots == NULL((void*)0))
221 {
222 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",222); } while(0);
;
223 goto fail;
224 }
225
226 if (pkcs11_get_slot_list
227 (providers[active_providers - 1].module, 0,
228 providers[active_providers - 1].slots,
229 &providers[active_providers - 1].nslots) != CKR_OK(0UL))
230 {
231 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",231); } while(0);
;
232 gnutls_free (providers[active_providers - 1].slots);
233 goto fail;
234 }
235
236 memcpy (&providers[active_providers - 1].info, &info, sizeof(info));
237
238 _gnutls_debug_log ("p11: loaded provider '%s' with %d slots\n",do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "p11: loaded provider '%s' with %d slots\n", name, (int)
providers[active_providers - 1].nslots); } while(0)
239 name, (int) providers[active_providers - 1].nslots)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "p11: loaded provider '%s' with %d slots\n", name, (int)
providers[active_providers - 1].nslots); } while(0)
;
240
241 return 0;
242
243fail:
244 active_providers--;
245 return GNUTLS_E_PKCS11_LOAD_ERROR-301;
246}
247
248
249/**
250 * gnutls_pkcs11_add_provider:
251 * @name: The filename of the module
252 * @params: should be NULL
253 *
254 * This function will load and add a PKCS 11 module to the module
255 * list used in gnutls. After this function is called the module will
256 * be used for PKCS 11 operations.
257 *
258 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
259 * negative error value.
260 *
261 * Since: 2.12.0
262 **/
263int
264gnutls_pkcs11_add_provider (const char *name, const char *params)
265{
266 struct ck_function_list *module;
267 int ret;
268
269 active_providers++;
270 if (p11_kit_load_initialize_module (name, &module) != CKR_OK(0UL))
271 {
272 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",272); } while(0);
;
273 _gnutls_debug_log ("p11: Cannot load provider %s\n", name)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "p11: Cannot load provider %s\n", name); } while(0)
;
274 active_providers--;
275 return GNUTLS_E_PKCS11_LOAD_ERROR-301;
276 }
277
278 ret = pkcs11_add_module (name, module);
279 if (ret == 0)
280 {
281 /* Mark this one as having been separately initialized */
282 providers[active_providers - 1].initialized = 1;
283 }
284 else
285 {
286 if (ret == GNUTLS_E_INT_RET_0-1251) ret = 0;
287 p11_kit_finalize_module (module);
288 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",288); } while(0);
;
289 }
290
291 return ret;
292}
293
294
295/**
296 * gnutls_pkcs11_obj_get_info:
297 * @crt: should contain a #gnutls_pkcs11_obj_t structure
298 * @itype: Denotes the type of information requested
299 * @output: where output will be stored
300 * @output_size: contains the maximum size of the output and will be overwritten with actual
301 *
302 * This function will return information about the PKCS11 certificate
303 * such as the label, id as well as token information where the key is
304 * stored. When output is text it returns null terminated string
305 * although @output_size contains the size of the actual data only.
306 *
307 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
308 *
309 * Since: 2.12.0
310 **/
311int
312gnutls_pkcs11_obj_get_info (gnutls_pkcs11_obj_t crt,
313 gnutls_pkcs11_obj_info_t itype,
314 void *output, size_t * output_size)
315{
316 return pkcs11_get_info (crt->info, itype, output, output_size);
317}
318
319int
320pkcs11_get_info (struct p11_kit_uri *info,
321 gnutls_pkcs11_obj_info_t itype, void *output,
322 size_t * output_size)
323{
324 struct ck_attribute *attr = NULL((void*)0);
325 struct ck_version *version = NULL((void*)0);
326 const char *str = NULL((void*)0);
327 size_t str_max = 0;
328 int terminate = 0;
329 int hexify = 0;
330 size_t length = 0;
331 const char *data = NULL((void*)0);
332 char buf[32];
333
334 /*
335 * Either attr, str or version is valid by the time switch
336 * finishes
337 */
338
339 switch (itype)
1
Control jumps to 'case GNUTLS_PKCS11_OBJ_ID:' at line 341
340 {
341 case GNUTLS_PKCS11_OBJ_ID:
342 attr = p11_kit_uri_get_attribute (info, CKA_ID(0x102UL));
343 break;
2
Execution continues on line 385
344 case GNUTLS_PKCS11_OBJ_ID_HEX:
345 attr = p11_kit_uri_get_attribute (info, CKA_ID(0x102UL));
346 hexify = 1;
347 terminate = 1;
348 break;
349 case GNUTLS_PKCS11_OBJ_LABEL:
350 attr = p11_kit_uri_get_attribute (info, CKA_LABEL(3UL));
351 terminate = 1;
352 break;
353 case GNUTLS_PKCS11_OBJ_TOKEN_LABEL:
354 str = p11_kit_uri_get_token_info (info)->label;
355 str_max = 32;
356 break;
357 case GNUTLS_PKCS11_OBJ_TOKEN_SERIAL:
358 str = p11_kit_uri_get_token_info (info)->serial_number;
359 str_max = 16;
360 break;
361 case GNUTLS_PKCS11_OBJ_TOKEN_MANUFACTURER:
362 str = p11_kit_uri_get_token_info (info)->manufacturer_id;
363 str_max = 32;
364 break;
365 case GNUTLS_PKCS11_OBJ_TOKEN_MODEL:
366 str = p11_kit_uri_get_token_info (info)->model;
367 str_max = 16;
368 break;
369 case GNUTLS_PKCS11_OBJ_LIBRARY_DESCRIPTION:
370 str = p11_kit_uri_get_module_info (info)->library_description;
371 str_max = 32;
372 break;
373 case GNUTLS_PKCS11_OBJ_LIBRARY_VERSION:
374 version = &p11_kit_uri_get_module_info (info)->library_version;
375 break;
376 case GNUTLS_PKCS11_OBJ_LIBRARY_MANUFACTURER:
377 str = p11_kit_uri_get_module_info (info)->manufacturer_id;
378 str_max = 32;
379 break;
380 default:
381 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",381); } while(0);
;
382 return GNUTLS_E_INVALID_REQUEST-50;
383 }
384
385 if (attr != NULL((void*)0))
3
Taking false branch
386 {
387 data = attr->value;
388 length = attr->value_len;
389 }
390 else if (str != NULL((void*)0))
4
Taking false branch
391 {
392 data = str;
393 length = p11_kit_space_strlen (str, str_max);
394 terminate = 1;
395 }
396 else if (version != NULL((void*)0))
5
Taking false branch
397 {
398 data = buf;
399 length = snprintf (buf, sizeof (buf), "%d.%d", (int)version->major,
400 (int)version->minor);
401 terminate = 1;
402 }
403
404 if (hexify)
6
Taking false branch
405 {
406 /* terminate is assumed with hexify */
407 if (*output_size < length * 3)
408 {
409 *output_size = length * 3;
410 return GNUTLS_E_SHORT_MEMORY_BUFFER-51;
411 }
412 if (output)
413 _gnutls_bin2hex (data, length, output, *output_size, ":");
414 *output_size = length * 3;
415 return 0;
416 }
417 else
418 {
419 if (*output_size < length + terminate)
7
Taking false branch
420 {
421 *output_size = length + terminate;
422 return GNUTLS_E_SHORT_MEMORY_BUFFER-51;
423 }
424 if (output)
8
Taking true branch
425 {
426 memcpy (output, data, length);
9
Null pointer passed as an argument to a 'nonnull' parameter
427 if (terminate)
428 ((unsigned char*)output)[length] = '\0';
429 }
430 *output_size = length + terminate;
431 }
432
433 return 0;
434}
435
436static int init = 0;
437
438/* tries to load modules from /etc/gnutls/pkcs11.conf if it exists
439 */
440static void _pkcs11_compat_init(const char* configfile)
441{
442FILE *fp;
443int ret;
444char line[512];
445const char *library;
446
447 if (configfile == NULL((void*)0))
448 configfile = "/etc/gnutls/pkcs11.conf";
449
450 fp = fopen (configfile, "r");
451 if (fp == NULL((void*)0))
452 {
453 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",453); } while(0);
;
454 return;
455 }
456
457 _gnutls_debug_log ("Loading PKCS #11 libraries from %s\n", configfile)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "Loading PKCS #11 libraries from %s\n", configfile); } while
(0)
;
458 while (fgets (line, sizeof (line), fp) != NULL((void*)0))
459 {
460 if (strncmp (line, "load", sizeof ("load") - 1) == 0)
461 {
462 char *p;
463 p = strchr (line, '=');
464 if (p == NULL((void*)0))
465 continue;
466
467 library = ++p;
468 p = strchr (line, '\n');
469 if (p != NULL((void*)0))
470 *p = 0;
471
472 ret = gnutls_pkcs11_add_provider (library, NULL((void*)0));
473 if (ret < 0)
474 {
475 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",475); } while(0);
;
476 _gnutls_debug_log ("Cannot load provider: %s\n", library)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "Cannot load provider: %s\n", library); } while(0)
;
477 continue;
478 }
479 }
480 }
481 fclose(fp);
482
483 return;
484}
485
486static int
487initialize_automatic_p11_kit (void)
488{
489 struct ck_function_list **modules;
490 const char *name;
491 ck_rv_t rv;
492 int i, ret;
493
494 rv = p11_kit_initialize_registered ();
495 if (rv != CKR_OK(0UL))
496 {
497 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",497); } while(0);
;
498 _gnutls_debug_log ("Cannot initialize registered module: %s\n",do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "Cannot initialize registered module: %s\n", p11_kit_strerror
(rv)); } while(0)
499 p11_kit_strerror (rv))do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "Cannot initialize registered module: %s\n", p11_kit_strerror
(rv)); } while(0)
;
500 return GNUTLS_E_INTERNAL_ERROR-59;
501 }
502
503 initialized_registered = 1;
504
505 modules = p11_kit_registered_modules ();
506 for (i = 0; modules[i] != NULL((void*)0); i++)
507 {
508 name = p11_kit_registered_module_to_name (modules[i]);
509 ret = pkcs11_add_module (name, modules[i]);
510 if (ret != 0 && ret != GNUTLS_E_INT_RET_0-1251)
511 {
512 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",512); } while(0);
;
513 _gnutls_debug_log ("Cannot add registered module: %s\n", name)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "Cannot add registered module: %s\n", name); } while(0)
;
514 }
515 }
516
517 free (modules);
518 return 0;
519}
520
521/**
522 * gnutls_pkcs11_init:
523 * @flags: %GNUTLS_PKCS11_FLAG_MANUAL or %GNUTLS_PKCS11_FLAG_AUTO
524 * @deprecated_config_file: either NULL or the location of a deprecated
525 * configuration file
526 *
527 * This function will initialize the PKCS 11 subsystem in gnutls. It will
528 * read configuration files if %GNUTLS_PKCS11_FLAG_AUTO is used or allow
529 * you to independently load PKCS 11 modules using gnutls_pkcs11_add_provider()
530 * if %GNUTLS_PKCS11_FLAG_MANUAL is specified.
531 *
532 * Normally you don't need to call this function since it is being called
533 * by gnutls_global_init() using the %GNUTLS_PKCS11_FLAG_AUTO. If other option
534 * is required then it must be called before it.
535 *
536 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
537 * negative error value.
538 *
539 * Since: 2.12.0
540 **/
541int
542gnutls_pkcs11_init (unsigned int flags, const char *deprecated_config_file)
543{
544 int ret = 0;
545
546 if (init != 0)
547 {
548 init++;
549 return 0;
550 }
551 init++;
552
553 if (flags == GNUTLS_PKCS11_FLAG_MANUAL0)
554 return 0;
555 else if (flags == GNUTLS_PKCS11_FLAG_AUTO1)
556 {
557 if (deprecated_config_file == NULL((void*)0))
558 ret = initialize_automatic_p11_kit ();
559
560 _pkcs11_compat_init(deprecated_config_file);
561
562 return ret;
563 }
564
565 return 0;
566}
567
568/**
569 * gnutls_pkcs11_deinit:
570 *
571 * This function will deinitialize the PKCS 11 subsystem in gnutls.
572 *
573 * Since: 2.12.0
574 **/
575void
576gnutls_pkcs11_deinit (void)
577{
578 int i;
579
580 init--;
581 if (init > 0)
582 return;
583 if (init < 0)
584 {
585 init = 0;
586 return;
587 }
588
589 for (i = 0; i < active_providers; i++)
590 {
591 if (providers[i].initialized)
592 p11_kit_finalize_module (providers[i].module);
593 }
594 active_providers = 0;
595
596 if (initialized_registered != 0)
597 p11_kit_finalize_registered ();
598 initialized_registered = 0;
599}
600
601/**
602 * gnutls_pkcs11_set_pin_function:
603 * @fn: The PIN callback, a gnutls_pkcs11_pin_callback_t() function.
604 * @userdata: data to be supplied to callback
605 *
606 * This function will set a callback function to be used when a PIN is
607 * required for PKCS 11 operations. See
608 * gnutls_pkcs11_pin_callback_t() on how the callback should behave.
609 *
610 * Since: 2.12.0
611 **/
612void
613gnutls_pkcs11_set_pin_function (gnutls_pkcs11_pin_callback_t fn,
614 void *userdata)
615{
616 pin_func = fn;
617 pin_data = userdata;
618}
619
620/**
621 * gnutls_pkcs11_set_token_function:
622 * @fn: The token callback
623 * @userdata: data to be supplied to callback
624 *
625 * This function will set a callback function to be used when a token
626 * needs to be inserted to continue PKCS 11 operations.
627 *
628 * Since: 2.12.0
629 **/
630void
631gnutls_pkcs11_set_token_function (gnutls_pkcs11_token_callback_t fn,
632 void *userdata)
633{
634 token_func = fn;
635 token_data = userdata;
636}
637
638int
639pkcs11_url_to_info (const char *url, struct p11_kit_uri **info)
640{
641 int allocated = 0;
642 int ret;
643
644 if (*info == NULL((void*)0))
645 {
646 *info = p11_kit_uri_new ();
647 if (*info == NULL((void*)0))
648 {
649 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",649); } while(0);
;
650 return GNUTLS_E_MEMORY_ERROR-25;
651 }
652 allocated = 1;
653 }
654
655 ret = p11_kit_uri_parse (url, P11_KIT_URI_FOR_ANY, *info);
656 if (ret < 0)
657 {
658 if (allocated)
659 {
660 p11_kit_uri_free (*info);
661 *info = NULL((void*)0);
662 }
663 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",663); } while(0);
;
664 return ret == P11_KIT_URI_NO_MEMORY ?
665 GNUTLS_E_MEMORY_ERROR-25 : GNUTLS_E_PARSING_ERROR-302;
666 }
667
668 return 0;
669}
670
671int
672pkcs11_info_to_url (struct p11_kit_uri *info,
673 gnutls_pkcs11_url_type_t detailed, char **url)
674{
675 p11_kit_uri_type_t type = 0;
676 int ret;
677
678 switch (detailed)
679 {
680 case GNUTLS_PKCS11_URL_GENERIC:
681 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN;
682 break;
683 case GNUTLS_PKCS11_URL_LIB:
684 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE;
685 break;
686 case GNUTLS_PKCS11_URL_LIB_VERSION:
687 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE | P11_KIT_URI_FOR_MODULE_WITH_VERSION;
688 break;
689 }
690
691 ret = p11_kit_uri_format (info, type, url);
692 if (ret < 0)
693 {
694 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",694); } while(0);
;
695 return ret == P11_KIT_URI_NO_MEMORY ?
696 GNUTLS_E_MEMORY_ERROR-25 : GNUTLS_E_INTERNAL_ERROR-59;
697 }
698
699 return 0;
700}
701
702/**
703 * gnutls_pkcs11_obj_init:
704 * @obj: The structure to be initialized
705 *
706 * This function will initialize a pkcs11 certificate structure.
707 *
708 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
709 * negative error value.
710 *
711 * Since: 2.12.0
712 **/
713int
714gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t * obj)
715{
716 *obj = gnutls_calloc (1, sizeof (struct gnutls_pkcs11_obj_st));
717 if (*obj == NULL((void*)0))
718 {
719 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",719); } while(0);
;
720 return GNUTLS_E_MEMORY_ERROR-25;
721 }
722
723 (*obj)->info = p11_kit_uri_new ();
724 if ((*obj)->info == NULL((void*)0))
725 {
726 free (*obj);
727 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",727); } while(0);
;
728 return GNUTLS_E_MEMORY_ERROR-25;
729 }
730
731 return 0;
732}
733
734/**
735 * gnutls_pkcs11_obj_deinit:
736 * @obj: The structure to be initialized
737 *
738 * This function will deinitialize a certificate structure.
739 *
740 * Since: 2.12.0
741 **/
742void
743gnutls_pkcs11_obj_deinit (gnutls_pkcs11_obj_t obj)
744{
745 _gnutls_free_datum (&obj->raw)_gnutls_free_datum_m(&obj->raw, gnutls_free);
746 p11_kit_uri_free (obj->info);
747 free (obj);
748}
749
750/**
751 * gnutls_pkcs11_obj_export:
752 * @obj: Holds the object
753 * @output_data: will contain a certificate PEM or DER encoded
754 * @output_data_size: holds the size of output_data (and will be
755 * replaced by the actual size of parameters)
756 *
757 * This function will export the PKCS11 object data. It is normal for
758 * data to be inaccesible and in that case %GNUTLS_E_INVALID_REQUEST
759 * will be returned.
760 *
761 * If the buffer provided is not long enough to hold the output, then
762 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
763 * be returned.
764 *
765 * If the structure is PEM encoded, it will have a header
766 * of "BEGIN CERTIFICATE".
767 *
768 * Returns: In case of failure a negative error code will be
769 * returned, and %GNUTLS_E_SUCCESS (0) on success.
770 *
771 * Since: 2.12.0
772 **/
773int
774gnutls_pkcs11_obj_export (gnutls_pkcs11_obj_t obj,
775 void *output_data, size_t * output_data_size)
776{
777 if (obj == NULL((void*)0) || obj->raw.data == NULL((void*)0))
778 {
779 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",779); } while(0);
;
780 return GNUTLS_E_INVALID_REQUEST-50;
781 }
782
783 if (output_data == NULL((void*)0) || *output_data_size < obj->raw.size)
784 {
785 *output_data_size = obj->raw.size;
786 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",786); } while(0);
;
787 return GNUTLS_E_SHORT_MEMORY_BUFFER-51;
788 }
789 *output_data_size = obj->raw.size;
790
791 memcpy (output_data, obj->raw.data, obj->raw.size);
792 return 0;
793}
794
795int
796pkcs11_find_object (struct ck_function_list ** _module,
797 ck_session_handle_t * _pks,
798 ck_object_handle_t * _obj,
799 struct p11_kit_uri *info, unsigned int flags)
800{
801 int ret;
802 struct ck_function_list *module;
803 ck_session_handle_t pks;
804 ck_object_handle_t obj;
805 struct ck_attribute *attrs;
806 unsigned long attr_count;
807 unsigned long count;
808 ck_rv_t rv;
809
810 ret = pkcs11_open_session (&module, &pks, info, flags & SESSION_LOGIN(1<<1));
811 if (ret < 0)
812 {
813 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",813); } while(0);
;
814 return ret;
815 }
816
817 attrs = p11_kit_uri_get_attributes (info, &attr_count);
818 rv = pkcs11_find_objects_init (module, pks, attrs, attr_count);
819 if (rv != CKR_OK(0UL))
820 {
821 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",821); } while(0);
;
822 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "pk11: FindObjectsInit failed.\n"); } while(0)
;
823 ret = pkcs11_rv_to_err (rv);
824 goto fail;
825 }
826
827 if (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK(0UL) && count == 1)
828 {
829 *_obj = obj;
830 *_pks = pks;
831 *_module = module;
832 pkcs11_find_objects_final (module, pks);
833 return 0;
834 }
835
836 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
837 pkcs11_find_objects_final (module, pks);
838fail:
839 pkcs11_close_session (module, pks);
840
841 return ret;
842}
843
844int
845pkcs11_find_slot (struct ck_function_list ** module, ck_slot_id_t * slot,
846 struct p11_kit_uri *info, struct token_info *_tinfo)
847{
848 int x, z;
849
850 for (x = 0; x < active_providers; x++)
851 {
852 for (z = 0; z < providers[x].nslots; z++)
853 {
854 struct token_info tinfo;
855
856 if (pkcs11_get_token_info
857 (providers[x].module, providers[x].slots[z],
858 &tinfo.tinfo) != CKR_OK(0UL))
859 {
860 continue;
861 }
862 tinfo.sid = providers[x].slots[z];
863 tinfo.prov = &providers[x];
864
865 if (pkcs11_get_slot_info
866 (providers[x].module, providers[x].slots[z],
867 &tinfo.sinfo) != CKR_OK(0UL))
868 {
869 continue;
870 }
871
872 if (!p11_kit_uri_match_token_info (info, &tinfo.tinfo) ||
873 !p11_kit_uri_match_module_info (info, &providers[x].info))
874 {
875 continue;
876 }
877
878 /* ok found */
879 *module = providers[x].module;
880 *slot = providers[x].slots[z];
881
882 if (_tinfo != NULL((void*)0))
883 memcpy (_tinfo, &tinfo, sizeof (tinfo));
884
885 return 0;
886 }
887 }
888
889 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",889); } while(0);
;
890 return GNUTLS_E_PKCS11_REQUESTED_OBJECT_NOT_AVAILBLE-323;
891}
892
893int
894pkcs11_open_session (struct ck_function_list ** _module, ck_session_handle_t * _pks,
895 struct p11_kit_uri *info, unsigned int flags)
896{
897 ck_rv_t rv;
898 int ret;
899 ck_session_handle_t pks = 0;
900 struct ck_function_list *module;
901 ck_slot_id_t slot;
902 struct token_info tinfo;
903
904 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
905 if (ret < 0)
906 {
907 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",907); } while(0);
;
908 return ret;
909 }
910
911 rv = (module)->C_OpenSession (slot,
912 ((flags & SESSION_WRITE(1<<0))
913 ? CKF_RW_SESSION(1UL << 1) : 0) |
914 CKF_SERIAL_SESSION(1UL << 2), NULL((void*)0), NULL((void*)0), &pks);
915 if (rv != CKR_OK(0UL))
916 {
917 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",917); } while(0);
;
918 return pkcs11_rv_to_err (rv);
919 }
920
921 if (flags & SESSION_LOGIN(1<<1))
922 {
923 ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO(1<<2)) ? 1 : 0);
924 if (ret < 0)
925 {
926 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",926); } while(0);
;
927 pkcs11_close_session (module, pks);
928 return ret;
929 }
930 }
931
932 /* ok found */
933 *_pks = pks;
934 *_module = module;
935 return 0;
936}
937
938
939int
940_pkcs11_traverse_tokens (find_func_t find_func, void *input,
941 struct p11_kit_uri *info, unsigned int flags)
942{
943 ck_rv_t rv;
944 int found = 0, x, z, ret;
945 ck_session_handle_t pks = 0;
946 struct ck_function_list *module = NULL((void*)0);
947
948 for (x = 0; x < active_providers; x++)
949 {
950 module = providers[x].module;
951 for (z = 0; z < providers[x].nslots; z++)
952 {
953 struct token_info tinfo;
954
955 ret = GNUTLS_E_PKCS11_ERROR-300;
956
957 if (pkcs11_get_token_info (module, providers[x].slots[z],
958 &tinfo.tinfo) != CKR_OK(0UL))
959 {
960 continue;
961 }
962 tinfo.sid = providers[x].slots[z];
963 tinfo.prov = &providers[x];
964
965 if (pkcs11_get_slot_info (module, providers[x].slots[z],
966 &tinfo.sinfo) != CKR_OK(0UL))
967 {
968 continue;
969 }
970
971 rv = (module)->C_OpenSession (providers[x].slots[z],
972 ((flags & SESSION_WRITE(1<<0))
973 ? CKF_RW_SESSION(1UL << 1) : 0) |
974 CKF_SERIAL_SESSION(1UL << 2), NULL((void*)0), NULL((void*)0), &pks);
975 if (rv != CKR_OK(0UL))
976 {
977 continue;
978 }
979
980 if (flags & SESSION_LOGIN(1<<1))
981 {
982 ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO(1<<2)) ? 1 : 0);
983 if (ret < 0)
984 {
985 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",985); } while(0);
;
986 return ret;
987 }
988 }
989
990 ret = find_func (module, pks, &tinfo, &providers[x].info, input);
991
992 if (ret == 0)
993 {
994 found = 1;
995 goto finish;
996 }
997 else
998 {
999 pkcs11_close_session (module, pks);
1000 pks = 0;
1001 }
1002 }
1003 }
1004
1005finish:
1006 /* final call */
1007
1008 if (found == 0)
1009 {
1010 if (module)
1011 ret = find_func (module, pks, NULL((void*)0), NULL((void*)0), input);
1012 else
1013 ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)gnutls_assert_val_int(-56, "pkcs11.c", 1013);
1014 }
1015 else
1016 {
1017 ret = 0;
1018 }
1019
1020 if (pks != 0 && module != NULL((void*)0))
1021 {
1022 pkcs11_close_session (module, pks);
1023 }
1024
1025 return ret;
1026}
1027
1028/* imports a raw certificate from a token to a pkcs11_obj_t structure.
1029 */
1030static int
1031pkcs11_obj_import (ck_object_class_t class, gnutls_pkcs11_obj_t obj,
1032 const gnutls_datum_t * data,
1033 const gnutls_datum_t * id,
1034 const gnutls_datum_t * label,
1035 struct ck_token_info *tinfo, struct ck_info *lib_info)
1036{
1037 struct ck_attribute attr;
1038 int ret;
1039
1040 switch (class)
1041 {
1042 case CKO_CERTIFICATE(1UL):
1043 obj->type = GNUTLS_PKCS11_OBJ_X509_CRT;
1044 break;
1045 case CKO_PUBLIC_KEY(2UL):
1046 obj->type = GNUTLS_PKCS11_OBJ_PUBKEY;
1047 break;
1048 case CKO_PRIVATE_KEY(3UL):
1049 obj->type = GNUTLS_PKCS11_OBJ_PRIVKEY;
1050 break;
1051 case CKO_SECRET_KEY(4UL):
1052 obj->type = GNUTLS_PKCS11_OBJ_SECRET_KEY;
1053 break;
1054 case CKO_DATA(0UL):
1055 obj->type = GNUTLS_PKCS11_OBJ_DATA;
1056 break;
1057 default:
1058 obj->type = GNUTLS_PKCS11_OBJ_UNKNOWN;
1059 }
1060
1061 attr.type = CKA_CLASS(0UL);
1062 attr.value = &class;
1063 attr.value_len = sizeof (class);
1064 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1065 if (ret < 0)
1066 {
1067 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1067); } while(0);
;
1068 return GNUTLS_E_MEMORY_ERROR-25;
1069 }
1070
1071 if (data && data->data)
1072 {
1073 ret = _gnutls_set_datum (&obj->raw, data->data, data->size)_gnutls_set_datum_m(&obj->raw,data->data,data->size
, gnutls_malloc)
;
1074 if (ret < 0)
1075 {
1076 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1076); } while(0);
;
1077 return ret;
1078 }
1079 }
1080
1081 /* copy the token and library info into the uri */
1082 memcpy (p11_kit_uri_get_token_info (obj->info), tinfo, sizeof (struct ck_token_info));
1083 memcpy (p11_kit_uri_get_module_info (obj->info), lib_info, sizeof (struct ck_info));
1084
1085 if (label && label->data)
1086 {
1087 attr.type = CKA_LABEL(3UL);
1088 attr.value = label->data;
1089 attr.value_len = label->size;
1090 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1091 if (ret < 0)
1092 {
1093 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1093); } while(0);
;
1094 return GNUTLS_E_MEMORY_ERROR-25;
1095 }
1096 }
1097
1098 if (id && id->data)
1099 {
1100 attr.type = CKA_ID(0x102UL);
1101 attr.value = id->data;
1102 attr.value_len = id->size;
1103 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1104 if (ret < 0)
1105 {
1106 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1106); } while(0);
;
1107 return GNUTLS_E_MEMORY_ERROR-25;
1108 }
1109 }
1110
1111 return 0;
1112}
1113
1114static int read_pkcs11_pubkey(struct ck_function_list *module,
1115 ck_session_handle_t pks, ck_object_handle_t obj,
1116 ck_key_type_t key_type, gnutls_datum_t * pubkey)
1117{
1118 struct ck_attribute a[4];
1119 opaque tmp1[2048];
1120 opaque tmp2[2048];
1121 int ret;
1122
1123 switch (key_type)
1124 {
1125 case CKK_RSA(0UL):
1126 a[0].type = CKA_MODULUS(0x120UL);
1127 a[0].value = tmp1;
1128 a[0].value_len = sizeof (tmp1);
1129 a[1].type = CKA_PUBLIC_EXPONENT(0x122UL);
1130 a[1].value = tmp2;
1131 a[1].value_len = sizeof (tmp2);
1132
1133 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK(0UL))
1134 {
1135
1136 ret =
1137 _gnutls_set_datum (&pubkey[0],_gnutls_set_datum_m(&pubkey[0],a[0].value,a[0].value_len,
gnutls_malloc)
1138 a[0].value, a[0].value_len)_gnutls_set_datum_m(&pubkey[0],a[0].value,a[0].value_len,
gnutls_malloc)
;
1139
1140 if (ret >= 0)
1141 ret =
1142 _gnutls_set_datum (&pubkey_gnutls_set_datum_m(&pubkey [1],a[1].value,a[1].value_len
, gnutls_malloc)
1143 [1], a[1].value, a[1].value_len)_gnutls_set_datum_m(&pubkey [1],a[1].value,a[1].value_len
, gnutls_malloc)
;
1144
1145 if (ret < 0)
1146 {
1147 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1147); } while(0);
;
1148 _gnutls_free_datum (&pubkey[1])_gnutls_free_datum_m(&pubkey[1], gnutls_free);
1149 _gnutls_free_datum (&pubkey[0])_gnutls_free_datum_m(&pubkey[0], gnutls_free);
1150 return GNUTLS_E_MEMORY_ERROR-25;
1151 }
1152 }
1153 else
1154 {
1155 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1155); } while(0);
;
1156 return GNUTLS_E_PKCS11_ERROR-300;
1157 }
1158 break;
1159 case CKK_DSA(1UL):
1160 a[0].type = CKA_PRIME(0x130UL);
1161 a[0].value = tmp1;
1162 a[0].value_len = sizeof (tmp1);
1163 a[1].type = CKA_SUBPRIME(0x131UL);
1164 a[1].value = tmp2;
1165 a[1].value_len = sizeof (tmp2);
1166
1167 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK(0UL))
1168 {
1169 ret =
1170 _gnutls_set_datum (&pubkey[0],_gnutls_set_datum_m(&pubkey[0],a[0].value,a[0].value_len,
gnutls_malloc)
1171 a[0].value, a[0].value_len)_gnutls_set_datum_m(&pubkey[0],a[0].value,a[0].value_len,
gnutls_malloc)
;
1172
1173 if (ret >= 0)
1174 ret =
1175 _gnutls_set_datum (&pubkey_gnutls_set_datum_m(&pubkey [1],a[1].value,a[1].value_len
, gnutls_malloc)
1176 [1], a[1].value, a[1].value_len)_gnutls_set_datum_m(&pubkey [1],a[1].value,a[1].value_len
, gnutls_malloc)
;
1177
1178 if (ret < 0)
1179 {
1180 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1180); } while(0);
;
1181 _gnutls_free_datum (&pubkey[1])_gnutls_free_datum_m(&pubkey[1], gnutls_free);
1182 _gnutls_free_datum (&pubkey[0])_gnutls_free_datum_m(&pubkey[0], gnutls_free);
1183 return GNUTLS_E_MEMORY_ERROR-25;
1184 }
1185 }
1186 else
1187 {
1188 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1188); } while(0);
;
1189 return GNUTLS_E_PKCS11_ERROR-300;
1190 }
1191
1192 a[0].type = CKA_BASE(0x132UL);
1193 a[0].value = tmp1;
1194 a[0].value_len = sizeof (tmp1);
1195 a[1].type = CKA_VALUE(0x11UL);
1196 a[1].value = tmp2;
1197 a[1].value_len = sizeof (tmp2);
1198
1199 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK(0UL))
1200 {
1201 ret =
1202 _gnutls_set_datum (&pubkey[2],_gnutls_set_datum_m(&pubkey[2],a[0].value,a[0].value_len,
gnutls_malloc)
1203 a[0].value, a[0].value_len)_gnutls_set_datum_m(&pubkey[2],a[0].value,a[0].value_len,
gnutls_malloc)
;
1204
1205 if (ret >= 0)
1206 ret =
1207 _gnutls_set_datum (&pubkey_gnutls_set_datum_m(&pubkey [3],a[1].value,a[1].value_len
, gnutls_malloc)
1208 [3], a[1].value, a[1].value_len)_gnutls_set_datum_m(&pubkey [3],a[1].value,a[1].value_len
, gnutls_malloc)
;
1209
1210 if (ret < 0)
1211 {
1212 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1212); } while(0);
;
1213 _gnutls_free_datum (&pubkey[0])_gnutls_free_datum_m(&pubkey[0], gnutls_free);
1214 _gnutls_free_datum (&pubkey[1])_gnutls_free_datum_m(&pubkey[1], gnutls_free);
1215 _gnutls_free_datum (&pubkey[2])_gnutls_free_datum_m(&pubkey[2], gnutls_free);
1216 _gnutls_free_datum (&pubkey[3])_gnutls_free_datum_m(&pubkey[3], gnutls_free);
1217 return GNUTLS_E_MEMORY_ERROR-25;
1218 }
1219 }
1220 else
1221 {
1222 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1222); } while(0);
;
1223 return GNUTLS_E_PKCS11_ERROR-300;
1224 }
1225 break;
1226 case CKK_ECDSA(3UL):
1227 a[0].type = CKA_EC_PARAMS(0x180UL);
1228 a[0].value = tmp1;
1229 a[0].value_len = sizeof (tmp1);
1230 a[1].type = CKA_EC_POINT(0x181UL);
1231 a[1].value = tmp2;
1232 a[1].value_len = sizeof (tmp2);
1233
1234 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK(0UL))
1235 {
1236 ret =
1237 _gnutls_set_datum (&pubkey[0],_gnutls_set_datum_m(&pubkey[0],a[0].value,a[0].value_len,
gnutls_malloc)
1238 a[0].value, a[0].value_len)_gnutls_set_datum_m(&pubkey[0],a[0].value,a[0].value_len,
gnutls_malloc)
;
1239
1240 if (ret >= 0)
1241 ret =
1242 _gnutls_set_datum (&pubkey_gnutls_set_datum_m(&pubkey [1],a[1].value,a[1].value_len
, gnutls_malloc)
1243 [1], a[1].value, a[1].value_len)_gnutls_set_datum_m(&pubkey [1],a[1].value,a[1].value_len
, gnutls_malloc)
;
1244
1245 if (ret < 0)
1246 {
1247 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1247); } while(0);
;
1248 _gnutls_free_datum (&pubkey[1])_gnutls_free_datum_m(&pubkey[1], gnutls_free);
1249 _gnutls_free_datum (&pubkey[0])_gnutls_free_datum_m(&pubkey[0], gnutls_free);
1250 return GNUTLS_E_MEMORY_ERROR-25;
1251 }
1252 }
1253 else
1254 {
1255 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1255); } while(0);
;
1256 return GNUTLS_E_PKCS11_ERROR-300;
1257 }
1258
1259 break;
1260 default:
1261 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE)gnutls_assert_val_int(-1250, "pkcs11.c", 1261);
1262 }
1263
1264 return 0;
1265}
1266
1267static int
1268pkcs11_obj_import_pubkey (struct ck_function_list *module,
1269 ck_session_handle_t pks,
1270 ck_object_handle_t obj,
1271 gnutls_pkcs11_obj_t crt,
1272 const gnutls_datum_t * id,
1273 const gnutls_datum_t * label,
1274 struct ck_token_info *tinfo,
1275 struct ck_info *lib_info)
1276{
1277 struct ck_attribute a[4];
1278 ck_key_type_t key_type;
1279 int ret;
1280 ck_bool_t tval;
1281
1282 a[0].type = CKA_KEY_TYPE(0x100UL);
1283 a[0].value = &key_type;
1284 a[0].value_len = sizeof (key_type);
1285
1286 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL))
1287 {
1288 crt->pk_algorithm = mech_to_pk(key_type);
1289
1290 ret = read_pkcs11_pubkey(module, pks, obj, key_type, crt->pubkey);
1291 if (ret < 0)
1292 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "pkcs11.c", 1292);
1293 }
1294
1295 /* read key usage flags */
1296 a[0].type = CKA_ENCRYPT(0x104UL);
1297 a[0].value = &tval;
1298 a[0].value_len = sizeof (tval);
1299
1300 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL))
1301 {
1302 if (tval != 0)
1303 {
1304 crt->key_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT16;
1305 }
1306 }
1307
1308 a[0].type = CKA_VERIFY(0x10aUL);
1309 a[0].value = &tval;
1310 a[0].value_len = sizeof (tval);
1311
1312 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL))
1313 {
1314 if (tval != 0)
1315 {
1316 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE128 |
1317 GNUTLS_KEY_KEY_CERT_SIGN4 | GNUTLS_KEY_CRL_SIGN2
1318 | GNUTLS_KEY_NON_REPUDIATION64;
1319 }
1320 }
1321
1322 a[0].type = CKA_VERIFY_RECOVER(0x10bUL);
1323 a[0].value = &tval;
1324 a[0].value_len = sizeof (tval);
1325
1326 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL))
1327 {
1328 if (tval != 0)
1329 {
1330 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE128 |
1331 GNUTLS_KEY_KEY_CERT_SIGN4 | GNUTLS_KEY_CRL_SIGN2
1332 | GNUTLS_KEY_NON_REPUDIATION64;
1333 }
1334 }
1335
1336 a[0].type = CKA_DERIVE(0x10cUL);
1337 a[0].value = &tval;
1338 a[0].value_len = sizeof (tval);
1339
1340 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL))
1341 {
1342 if (tval != 0)
1343 {
1344 crt->key_usage |= GNUTLS_KEY_KEY_AGREEMENT8;
1345 }
1346 }
1347
1348 a[0].type = CKA_WRAP(0x106UL);
1349 a[0].value = &tval;
1350 a[0].value_len = sizeof (tval);
1351
1352 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL))
1353 {
1354 if (tval != 0)
1355 {
1356 crt->key_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT32;
1357 }
1358 }
1359
1360 return pkcs11_obj_import (CKO_PUBLIC_KEY(2UL), crt, NULL((void*)0), id, label,
1361 tinfo, lib_info);
1362}
1363
1364static int
1365find_obj_url (struct ck_function_list *module, ck_session_handle_t pks,
1366 struct token_info *info, struct ck_info *lib_info, void *input)
1367{
1368 struct url_find_data_st *find_data = input;
1369 struct ck_attribute a[4];
1370 struct ck_attribute *attr;
1371 ck_object_class_t class = -1;
1372 ck_certificate_type_t type = -1;
1373 ck_rv_t rv;
1374 ck_object_handle_t obj;
1375 unsigned long count, a_vals;
1376 int found = 0, ret;
1377 opaque *cert_data = NULL((void*)0);
1378 char label_tmp[PKCS11_LABEL_SIZE128];
1379
1380 if (info == NULL((void*)0))
1381 { /* we don't support multiple calls */
1382 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1382); } while(0);
;
1383 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
1384 }
1385
1386 /* do not bother reading the token if basic fields do not match
1387 */
1388 if (!p11_kit_uri_match_token_info (find_data->crt->info, &info->tinfo) ||
1389 !p11_kit_uri_match_module_info (find_data->crt->info, lib_info))
1390 {
1391 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1391); } while(0);
;
1392 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
1393 }
1394
1395 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID(0x102UL));
1396 if (attr == NULL((void*)0))
1397 {
1398 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1398); } while(0);
;
1399 return GNUTLS_E_INVALID_REQUEST-50;
1400 }
1401
1402 /* search the token for the id */
1403
1404 cert_data = gnutls_malloc (MAX_CERT_SIZE8*1024);
1405 if (cert_data == NULL((void*)0))
1406 {
1407 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1407); } while(0);
;
1408 return GNUTLS_E_MEMORY_ERROR-25;
1409 }
1410
1411 /* Find objects with given class and type */
1412 memcpy (a, attr, sizeof (struct ck_attribute));
1413 a_vals = 1;
1414
1415 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_CLASS(0UL));
1416 if (attr)
1417 {
1418 if(attr->value && attr->value_len == sizeof (ck_object_class_t))
1419 class = *((ck_object_class_t*)attr->value);
1420 if (class == CKO_CERTIFICATE(1UL))
1421 type = CKC_X_509(0UL);
1422 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1423 a_vals++;
1424 }
1425
1426 if (type != -1)
1427 {
1428 a[a_vals].type = CKA_CERTIFICATE_TYPE(0x80UL);
1429 a[a_vals].value = &type;
1430 a[a_vals].value_len = sizeof type;
1431 a_vals++;
1432 }
1433
1434 rv = pkcs11_find_objects_init (module, pks, a, a_vals);
1435 if (rv != CKR_OK(0UL))
1436 {
1437 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1437); } while(0);
;
1438 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "pk11: FindObjectsInit failed.\n"); } while(0)
;
1439 ret = pkcs11_rv_to_err (rv);
1440 goto cleanup;
1441 }
1442
1443 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK(0UL) && count == 1)
1444 {
1445
1446 a[0].type = CKA_VALUE(0x11UL);
1447 a[0].value = cert_data;
1448 a[0].value_len = MAX_CERT_SIZE8*1024;
1449 a[1].type = CKA_LABEL(3UL);
1450 a[1].value = label_tmp;
1451 a[1].value_len = sizeof (label_tmp);
1452
1453 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK(0UL))
1454 {
1455 gnutls_datum_t id;
1456 gnutls_datum_t data = { a[0].value, a[0].value_len };
1457 gnutls_datum_t label = { a[1].value, a[1].value_len };
1458
1459 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID(0x102UL));
1460 id.data = attr->value;
1461 id.size = attr->value_len;
1462
1463 if (class == CKO_PUBLIC_KEY(2UL))
1464 {
1465 ret =
1466 pkcs11_obj_import_pubkey (module, pks, obj,
1467 find_data->crt,
1468 &id, &label,
1469 &info->tinfo, lib_info);
1470 }
1471 else
1472 {
1473 ret =
1474 pkcs11_obj_import (class,
1475 find_data->crt,
1476 &data, &id, &label,
1477 &info->tinfo, lib_info);
1478 }
1479 if (ret < 0)
1480 {
1481 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1481); } while(0);
;
1482 goto cleanup;
1483 }
1484
1485 found = 1;
1486 break;
1487 }
1488 else
1489 {
1490 _gnutls_debug_log ("pk11: Skipped cert, missing attrs.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "pk11: Skipped cert, missing attrs.\n"); } while(0)
;
1491 }
1492 }
1493
1494 if (found == 0)
1495 {
1496 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1496); } while(0);
;
1497 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
1498 }
1499 else
1500 {
1501 ret = 0;
1502 }
1503
1504cleanup:
1505 gnutls_free (cert_data);
1506 pkcs11_find_objects_final (module, pks);
1507
1508 return ret;
1509}
1510
1511unsigned int
1512pkcs11_obj_flags_to_int (unsigned int flags)
1513{
1514 unsigned int ret_flags = 0;
1515
1516 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN(1<<0))
1517 ret_flags |= SESSION_LOGIN(1<<1);
1518 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO(1<<3))
1519 ret_flags |= SESSION_LOGIN(1<<1)|SESSION_SO(1<<2);
1520
1521 return ret_flags;
1522}
1523
1524/**
1525 * gnutls_pkcs11_obj_import_url:
1526 * @cert: The structure to store the parsed certificate
1527 * @url: a PKCS 11 url identifying the key
1528 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1529 *
1530 * This function will "import" a PKCS 11 URL identifying a certificate
1531 * key to the #gnutls_pkcs11_obj_t structure. This does not involve any
1532 * parsing (such as X.509 or OpenPGP) since the #gnutls_pkcs11_obj_t is
1533 * format agnostic. Only data are transferred.
1534 *
1535 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1536 * negative error value.
1537 *
1538 * Since: 2.12.0
1539 **/
1540int
1541gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t cert, const char *url,
1542 unsigned int flags)
1543{
1544 int ret;
1545 struct url_find_data_st find_data;
1546
1547 /* fill in the find data structure */
1548 find_data.crt = cert;
1549
1550 ret = pkcs11_url_to_info (url, &cert->info);
1551 if (ret < 0)
1552 {
1553 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1553); } while(0);
;
1554 return ret;
1555 }
1556
1557 ret =
1558 _pkcs11_traverse_tokens (find_obj_url, &find_data, cert->info,
1559 pkcs11_obj_flags_to_int (flags));
1560
1561 if (ret < 0)
1562 {
1563 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1563); } while(0);
;
1564 return ret;
1565 }
1566
1567 return 0;
1568}
1569
1570struct token_num
1571{
1572 struct p11_kit_uri *info;
1573 unsigned int seq; /* which one we are looking for */
1574 unsigned int current; /* which one are we now */
1575};
1576
1577static int
1578find_token_num (struct ck_function_list *module,
1579 ck_session_handle_t pks,
1580 struct token_info *tinfo,
1581 struct ck_info *lib_info, void *input)
1582{
1583 struct token_num *find_data = input;
1584
1585 if (tinfo == NULL((void*)0))
1586 { /* we don't support multiple calls */
1587 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1587); } while(0);
;
1588 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
1589 }
1590
1591 if (find_data->current == find_data->seq)
1592 {
1593 memcpy (p11_kit_uri_get_token_info (find_data->info), &tinfo->tinfo, sizeof (struct ck_token_info));
1594 memcpy (p11_kit_uri_get_module_info (find_data->info), lib_info, sizeof (struct ck_info));
1595 return 0;
1596 }
1597
1598 find_data->current++;
1599 /* search the token for the id */
1600
1601
1602 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; /* non zero is enough */
1603}
1604
1605/**
1606 * gnutls_pkcs11_token_get_url:
1607 * @seq: sequence number starting from 0
1608 * @detailed: non zero if a detailed URL is required
1609 * @url: will contain an allocated url
1610 *
1611 * This function will return the URL for each token available
1612 * in system. The url has to be released using gnutls_free()
1613 *
1614 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1615 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if the sequence number
1616 * exceeds the available tokens, otherwise a negative error value.
1617 *
1618 * Since: 2.12.0
1619 **/
1620int
1621gnutls_pkcs11_token_get_url (unsigned int seq,
1622 gnutls_pkcs11_url_type_t detailed, char **url)
1623{
1624 int ret;
1625 struct token_num tn;
1626
1627 memset (&tn, 0, sizeof (tn));
1628 tn.seq = seq;
1629 tn.info = p11_kit_uri_new ();
1630
1631 ret = _pkcs11_traverse_tokens (find_token_num, &tn, NULL((void*)0), 0);
1632 if (ret < 0)
1633 {
1634 p11_kit_uri_free (tn.info);
1635 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1635); } while(0);
;
1636 return ret;
1637 }
1638
1639 ret = pkcs11_info_to_url (tn.info, detailed, url);
1640 p11_kit_uri_free (tn.info);
1641
1642 if (ret < 0)
1643 {
1644 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1644); } while(0);
;
1645 return ret;
1646 }
1647
1648 return 0;
1649
1650}
1651
1652/**
1653 * gnutls_pkcs11_token_get_info:
1654 * @url: should contain a PKCS 11 URL
1655 * @ttype: Denotes the type of information requested
1656 * @output: where output will be stored
1657 * @output_size: contains the maximum size of the output and will be overwritten with actual
1658 *
1659 * This function will return information about the PKCS 11 token such
1660 * as the label, id, etc.
1661 *
1662 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code
1663 * on error.
1664 *
1665 * Since: 2.12.0
1666 **/
1667int
1668gnutls_pkcs11_token_get_info (const char *url,
1669 gnutls_pkcs11_token_info_t ttype,
1670 void *output, size_t * output_size)
1671{
1672 struct p11_kit_uri *info = NULL((void*)0);
1673 const char *str;
1674 size_t str_max;
1675 size_t len;
1676 int ret;
1677
1678 ret = pkcs11_url_to_info (url, &info);
1679 if (ret < 0)
1680 {
1681 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1681); } while(0);
;
1682 return ret;
1683 }
1684
1685 switch (ttype)
1686 {
1687 case GNUTLS_PKCS11_TOKEN_LABEL:
1688 str = p11_kit_uri_get_token_info (info)->label;
1689 str_max = 32;
1690 break;
1691 case GNUTLS_PKCS11_TOKEN_SERIAL:
1692 str = p11_kit_uri_get_token_info (info)->serial_number;
1693 str_max = 16;
1694 break;
1695 case GNUTLS_PKCS11_TOKEN_MANUFACTURER:
1696 str = p11_kit_uri_get_token_info (info)->manufacturer_id;
1697 str_max = 32;
1698 break;
1699 case GNUTLS_PKCS11_TOKEN_MODEL:
1700 str = p11_kit_uri_get_token_info (info)->model;
1701 str_max = 16;
1702 break;
1703 default:
1704 p11_kit_uri_free (info);
1705 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1705); } while(0);
;
1706 return GNUTLS_E_INVALID_REQUEST-50;
1707 }
1708
1709 len = p11_kit_space_strlen (str, str_max);
1710
1711 if (len + 1 > *output_size)
1712 {
1713 *output_size = len + 1;
1714 return GNUTLS_E_SHORT_MEMORY_BUFFER-51;
1715 }
1716
1717 memcpy (output, str, len);
1718 ((char*)output)[len] = '\0';
1719
1720 *output_size = len;
1721
1722 p11_kit_uri_free (info);
1723 return 0;
1724}
1725
1726/**
1727 * gnutls_pkcs11_obj_export_url:
1728 * @obj: Holds the PKCS 11 certificate
1729 * @detailed: non zero if a detailed URL is required
1730 * @url: will contain an allocated url
1731 *
1732 * This function will export a URL identifying the given certificate.
1733 *
1734 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1735 * negative error value.
1736 *
1737 * Since: 2.12.0
1738 **/
1739int
1740gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t obj,
1741 gnutls_pkcs11_url_type_t detailed, char **url)
1742{
1743 int ret;
1744
1745 ret = pkcs11_info_to_url (obj->info, detailed, url);
1746 if (ret < 0)
1747 {
1748 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1748); } while(0);
;
1749 return ret;
1750 }
1751
1752 return 0;
1753}
1754
1755/**
1756 * gnutls_pkcs11_obj_get_type:
1757 * @obj: Holds the PKCS 11 object
1758 *
1759 * This function will return the type of the certificate being
1760 * stored in the structure.
1761 *
1762 * Returns: The type of the certificate.
1763 *
1764 * Since: 2.12.0
1765 **/
1766gnutls_pkcs11_obj_type_t
1767gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t obj)
1768{
1769 return obj->type;
1770}
1771
1772struct pkey_list
1773{
1774 gnutls_buffer_st *key_ids;
1775 size_t key_ids_size;
1776};
1777
1778
1779static int
1780retrieve_pin_for_pinfile (const char *pinfile, struct ck_token_info *token_info,
1781 int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
1782{
1783 unsigned int flags = 0;
1784 struct p11_kit_uri *token_uri;
1785 struct p11_kit_pin *result;
1786 char *label;
1787
1788 label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1789 if (label == NULL((void*)0))
1790 {
1791 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1791); } while(0);
;
1792 return GNUTLS_E_MEMORY_ERROR-25;
1793 }
1794
1795 token_uri = p11_kit_uri_new ();
1796 if (token_uri == NULL((void*)0))
1797 {
1798 free (label);
1799 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1799); } while(0);
;
1800 return GNUTLS_E_MEMORY_ERROR-25;
1801 }
1802
1803 memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1804 sizeof (struct ck_token_info));
1805
1806 if (attempts)
1807 flags |= P11_KIT_PIN_FLAGS_RETRY;
1808 if (user_type == CKU_USER(1UL))
1809 {
1810 flags |= P11_KIT_PIN_FLAGS_USER_LOGIN;
1811 if (token_info->flags & CKF_USER_PIN_COUNT_LOW(1UL << 16))
1812 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1813 if (token_info->flags & CKF_USER_PIN_FINAL_TRY(1UL << 17))
1814 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1815 }
1816 else if (user_type == CKU_SO(0UL))
1817 {
1818 flags |= P11_KIT_PIN_FLAGS_SO_LOGIN;
1819 if (token_info->flags & CKF_SO_PIN_COUNT_LOW(1UL << 20))
1820 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1821 if (token_info->flags & CKF_SO_PIN_FINAL_TRY(1UL << 21))
1822 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1823 }
1824 else if (user_type == CKU_CONTEXT_SPECIFIC(2UL))
1825 {
1826 flags |= P11_KIT_PIN_FLAGS_CONTEXT_LOGIN;
1827 }
1828
1829 result = p11_kit_pin_request (pinfile, token_uri, label, flags);
1830 p11_kit_uri_free (token_uri);
1831 free (label);
1832
1833 if (result == NULL((void*)0))
1834 {
1835 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1835); } while(0);
;
1836 return GNUTLS_E_PKCS11_PIN_ERROR-303;
1837 }
1838
1839 *pin = result;
1840 return 0;
1841}
1842
1843static int
1844retrieve_pin_for_callback (struct ck_token_info *token_info, int attempts,
1845 ck_user_type_t user_type, struct p11_kit_pin **pin)
1846{
1847 char pin_value[GNUTLS_PKCS11_MAX_PIN_LEN32];
1848 unsigned int flags = 0;
1849 char *token_str;
1850 char *label;
1851 struct p11_kit_uri *token_uri;
1852 int ret = 0;
1853
1854 label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1855 if (label == NULL((void*)0))
1856 {
1857 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1857); } while(0);
;
1858 return GNUTLS_E_MEMORY_ERROR-25;
1859 }
1860
1861 token_uri = p11_kit_uri_new ();
1862 if (token_uri == NULL((void*)0))
1863 {
1864 free (label);
1865 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1865); } while(0);
;
1866 return GNUTLS_E_MEMORY_ERROR-25;
1867 }
1868
1869 memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1870 sizeof (struct ck_token_info));
1871 ret = pkcs11_info_to_url (token_uri, 1, &token_str);
1872 p11_kit_uri_free (token_uri);
1873
1874 if (ret < 0)
1875 {
1876 free (label);
1877 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1877); } while(0);
;
1878 return GNUTLS_E_MEMORY_ERROR-25;
1879 }
1880
1881 if (user_type == CKU_USER(1UL))
1882 {
1883 flags |= GNUTLS_PKCS11_PIN_USER;
1884 if (token_info->flags & CKF_USER_PIN_COUNT_LOW(1UL << 16))
1885 flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
1886 if (token_info->flags & CKF_USER_PIN_FINAL_TRY(1UL << 17))
1887 flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
1888 }
1889 else if (user_type == CKU_SO(0UL))
1890 {
1891 flags |= GNUTLS_PKCS11_PIN_SO;
1892 if (token_info->flags & CKF_SO_PIN_COUNT_LOW(1UL << 20))
1893 flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
1894 if (token_info->flags & CKF_SO_PIN_FINAL_TRY(1UL << 21))
1895 flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
1896 }
1897
1898 if (attempts > 0)
1899 flags |= GNUTLS_PKCS11_PIN_WRONG;
1900
1901 ret = pin_func (pin_data, attempts, (char*)token_str, label,
1902 flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN32);
1903 free (token_str);
1904 free (label);
1905
1906 if (ret < 0)
1907 return gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR)gnutls_assert_val_int(-303, "pkcs11.c", 1907);
1908
1909 *pin = p11_kit_pin_new_for_string (pin_value);
1910
1911 if (*pin == NULL((void*)0))
1912 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR)gnutls_assert_val_int(-59, "pkcs11.c", 1912);
1913
1914 return 0;
1915}
1916
1917static int
1918retrieve_pin (struct p11_kit_uri *info, struct ck_token_info *token_info,
1919 int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
1920{
1921 const char *pinfile;
1922
1923 *pin = NULL((void*)0);
1924
1925 /* Check if a pinfile is specified, and use that if possible */
1926 pinfile = p11_kit_uri_get_pinfile (info);
1927 if (pinfile != NULL((void*)0))
1928 {
1929 _gnutls_debug_log("pk11: Using pinfile to retrieve PIN\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "pk11: Using pinfile to retrieve PIN\n"); } while(0)
;
1930 return retrieve_pin_for_pinfile (pinfile, token_info, attempts, user_type, pin);
1931 }
1932
1933 /* The global gnutls pin callback */
1934 else if (pin_func)
1935 return retrieve_pin_for_callback (token_info, attempts, user_type, pin);
1936
1937 /* Otherwise, PIN entry is necessary for login, so fail if there's
1938 * no callback. */
1939 else
1940 {
1941 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1941); } while(0);
;
1942 _gnutls_debug_log ("pk11: No pin callback but login required.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "pk11: No pin callback but login required.\n"); } while(
0)
;
1943 return GNUTLS_E_PKCS11_ERROR-300;
1944 }
1945}
1946
1947int
1948pkcs11_login (struct ck_function_list * module, ck_session_handle_t pks,
1949 const struct token_info *tokinfo, struct p11_kit_uri *info, int so)
1950{
1951 struct ck_session_info session_info;
1952 int attempt = 0, ret;
1953 ck_user_type_t user_type;
1954 ck_rv_t rv;
1955
1956 user_type = (so == 0) ? CKU_USER(1UL) : CKU_SO(0UL);
1957 if (so == 0 && (tokinfo->tinfo.flags & CKF_LOGIN_REQUIRED(1UL << 2)) == 0)
1958 {
1959 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1959); } while(0);
;
1960 _gnutls_debug_log ("pk11: No login required.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "pk11: No login required.\n"); } while(0)
;
1961 return 0;
1962 }
1963
1964 /* For a token with a "protected" (out-of-band) authentication
1965 * path, calling login with a NULL username is all that is
1966 * required. */
1967 if (tokinfo->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH(1UL << 8))
1968 {
1969 rv = (module)->C_Login (pks, (so == 0) ? CKU_USER(1UL) : CKU_SO(0UL), NULL((void*)0), 0);
1970 if (rv == CKR_OK(0UL) || rv == CKR_USER_ALREADY_LOGGED_IN(0x100UL))
1971 {
1972 return 0;
1973 }
1974 else
1975 {
1976 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",1976); } while(0);
;
1977 _gnutls_debug_log ("pk11: Protected login failed.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "pk11: Protected login failed.\n"); } while(0)
;
1978 ret = GNUTLS_E_PKCS11_ERROR-300;
1979 goto cleanup;
1980 }
1981 }
1982
1983 do
1984 {
1985 struct p11_kit_pin *pin;
1986 struct ck_token_info tinfo;
1987
1988 memcpy (&tinfo, &tokinfo->tinfo, sizeof(tinfo));
1989
1990 /* Check whether the session is already logged in, and if so, just skip */
1991 rv = (module)->C_GetSessionInfo (pks, &session_info);
1992 if (rv == CKR_OK(0UL) && (session_info.state == CKS_RO_USER_FUNCTIONS(1UL) ||
1993 session_info.state == CKS_RW_USER_FUNCTIONS(3UL)))
1994 {
1995 ret = 0;
1996 goto cleanup;
1997 }
1998
1999 /* If login has been attempted once already, check the token
2000 * status again, the flags might change. */
2001 if (attempt)
2002 {
2003 if (pkcs11_get_token_info
2004 (tokinfo->prov->module, tokinfo->sid, &tinfo) != CKR_OK(0UL))
2005 {
2006 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2006); } while(0);
;
2007 _gnutls_debug_log ("pk11: GetTokenInfo failed\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "pk11: GetTokenInfo failed\n"); } while(0)
;
2008 ret = GNUTLS_E_PKCS11_ERROR-300;
2009 goto cleanup;
2010 }
2011 }
2012
2013 ret = retrieve_pin (info, &tinfo, attempt++, user_type, &pin);
2014 if (ret < 0)
2015 {
2016 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2016); } while(0);
;
2017 goto cleanup;
2018 }
2019
2020 rv = (module)->C_Login (pks, user_type,
2021 (unsigned char *)p11_kit_pin_get_value (pin, NULL((void*)0)),
2022 p11_kit_pin_get_length (pin));
2023
2024 p11_kit_pin_unref (pin);
2025 }
2026 while (rv == CKR_PIN_INCORRECT(0xa0UL));
2027
2028 _gnutls_debug_log ("pk11: Login result = %lu\n", rv)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "pk11: Login result = %lu\n", rv); } while(0)
;
2029
2030
2031 ret = (rv == CKR_OK(0UL)
2032 || rv == CKR_USER_ALREADY_LOGGED_IN(0x100UL)) ? 0 : pkcs11_rv_to_err (rv);
2033
2034cleanup:
2035 return ret;
2036}
2037
2038int
2039pkcs11_call_token_func (struct p11_kit_uri *info, const unsigned retry)
2040{
2041 struct ck_token_info *tinfo;
2042 char *label;
2043 int ret = 0;
2044
2045 tinfo = p11_kit_uri_get_token_info (info);
2046 label = p11_kit_space_strdup (tinfo->label, sizeof (tinfo->label));
2047 ret = (token_func) (token_data, label, retry);
2048 free (label);
2049
2050 return ret;
2051}
2052
2053
2054static int
2055find_privkeys (struct ck_function_list *module, ck_session_handle_t pks,
2056 struct token_info *info, struct pkey_list *list)
2057{
2058 struct ck_attribute a[3];
2059 ck_object_class_t class;
2060 ck_rv_t rv;
2061 ck_object_handle_t obj;
2062 unsigned long count, current;
2063 char certid_tmp[PKCS11_ID_SIZE128];
2064
2065 class = CKO_PRIVATE_KEY(3UL);
2066
2067 /* Find an object with private key class and a certificate ID
2068 * which matches the certificate. */
2069 /* FIXME: also match the cert subject. */
2070 a[0].type = CKA_CLASS(0UL);
2071 a[0].value = &class;
2072 a[0].value_len = sizeof class;
2073
2074 rv = pkcs11_find_objects_init (module, pks, a, 1);
2075 if (rv != CKR_OK(0UL))
2076 {
2077 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2077); } while(0);
;
2078 return pkcs11_rv_to_err (rv);
2079 }
2080
2081 list->key_ids_size = 0;
2082 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK(0UL) && count == 1)
2083 {
2084 list->key_ids_size++;
2085 }
2086
2087 pkcs11_find_objects_final (module, pks);
2088
2089 if (list->key_ids_size == 0)
2090 {
2091 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2091); } while(0);
;
2092 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
2093 }
2094
2095 list->key_ids =
2096 gnutls_malloc (sizeof (gnutls_buffer_st) * list->key_ids_size);
2097 if (list->key_ids == NULL((void*)0))
2098 {
2099 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2099); } while(0);
;
2100 return GNUTLS_E_MEMORY_ERROR-25;
2101 }
2102
2103 /* actual search */
2104 a[0].type = CKA_CLASS(0UL);
2105 a[0].value = &class;
2106 a[0].value_len = sizeof class;
2107
2108 rv = pkcs11_find_objects_init (module, pks, a, 1);
2109 if (rv != CKR_OK(0UL))
2110 {
2111 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2111); } while(0);
;
2112 return pkcs11_rv_to_err (rv);
2113 }
2114
2115 current = 0;
2116 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK(0UL) && count == 1)
2117 {
2118
2119 a[0].type = CKA_ID(0x102UL);
2120 a[0].value = certid_tmp;
2121 a[0].value_len = sizeof (certid_tmp);
2122
2123 _gnutls_buffer_init (&list->key_ids[current]);
2124
2125 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL))
2126 {
2127 _gnutls_buffer_append_data (&list->key_ids[current],
2128 a[0].value, a[0].value_len);
2129 current++;
2130 }
2131
2132 if (current > list->key_ids_size)
2133 break;
2134 }
2135
2136 pkcs11_find_objects_final (module, pks);
2137
2138 list->key_ids_size = current - 1;
2139
2140 return 0;
2141}
2142
2143/* Recover certificate list from tokens */
2144
2145
2146static int
2147find_objs (struct ck_function_list * module, ck_session_handle_t pks,
2148 struct token_info *info, struct ck_info *lib_info, void *input)
2149{
2150 struct crt_find_data_st *find_data = input;
2151 struct ck_attribute a[4];
2152 struct ck_attribute *attr;
2153 ck_object_class_t class = -1;
2154 ck_certificate_type_t type = -1;
2155 unsigned int trusted;
2156 ck_rv_t rv;
2157 ck_object_handle_t obj;
2158 unsigned long count;
2159 opaque *cert_data;
2160 char certid_tmp[PKCS11_ID_SIZE128];
2161 char label_tmp[PKCS11_LABEL_SIZE128];
2162 int ret, i;
2163 struct pkey_list plist; /* private key holder */
2164 int tot_values = 0;
2165
2166 if (info == NULL((void*)0))
2167 { /* final call */
2168 if (find_data->current <= *find_data->n_list)
2169 ret = 0;
2170 else
2171 ret = GNUTLS_E_SHORT_MEMORY_BUFFER-51;
2172
2173 *find_data->n_list = find_data->current;
2174
2175 return ret;
2176 }
2177
2178 /* do not bother reading the token if basic fields do not match
2179 */
2180 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2181 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2182 {
2183 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2183); } while(0);
;
2184 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
2185 }
2186
2187 memset (&plist, 0, sizeof (plist));
2188
2189 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2190 {
2191 ret = find_privkeys (module, pks, info, &plist);
2192 if (ret < 0)
2193 {
2194 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2194); } while(0);
;
2195 return ret;
2196 }
2197
2198 if (plist.key_ids_size == 0)
2199 {
2200 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2200); } while(0);
;
2201 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
2202 }
2203 }
2204
2205 cert_data = gnutls_malloc (MAX_CERT_SIZE8*1024);
2206 if (cert_data == NULL((void*)0))
2207 {
2208 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2208); } while(0);
;
2209 return GNUTLS_E_MEMORY_ERROR-25;
2210 }
2211
2212 /* Find objects with cert class and X.509 cert type. */
2213
2214 tot_values = 0;
2215
2216 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL
2217 || find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2218 {
2219 class = CKO_CERTIFICATE(1UL);
2220 type = CKC_X_509(0UL);
2221 trusted = 1;
2222
2223 a[tot_values].type = CKA_CLASS(0UL);
2224 a[tot_values].value = &class;
2225 a[tot_values].value_len = sizeof class;
2226 tot_values++;
2227
2228 a[tot_values].type = CKA_CERTIFICATE_TYPE(0x80UL);
2229 a[tot_values].value = &type;
2230 a[tot_values].value_len = sizeof type;
2231 tot_values++;
2232
2233 }
2234 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED)
2235 {
2236 class = CKO_CERTIFICATE(1UL);
2237 type = CKC_X_509(0UL);
2238 trusted = 1;
2239
2240 a[tot_values].type = CKA_CLASS(0UL);
2241 a[tot_values].value = &class;
2242 a[tot_values].value_len = sizeof class;
2243 tot_values++;
2244
2245 a[tot_values].type = CKA_TRUSTED(0x86UL);
2246 a[tot_values].value = &trusted;
2247 a[tot_values].value_len = sizeof trusted;
2248 tot_values++;
2249
2250 }
2251 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PUBKEY)
2252 {
2253 class = CKO_PUBLIC_KEY(2UL);
2254
2255 a[tot_values].type = CKA_CLASS(0UL);
2256 a[tot_values].value = &class;
2257 a[tot_values].value_len = sizeof class;
2258 tot_values++;
2259 }
2260 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
2261 {
2262 class = CKO_PRIVATE_KEY(3UL);
2263
2264 a[tot_values].type = CKA_CLASS(0UL);
2265 a[tot_values].value = &class;
2266 a[tot_values].value_len = sizeof class;
2267 tot_values++;
2268 }
2269 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2270 {
2271 if (class != -1)
2272 {
2273 a[tot_values].type = CKA_CLASS(0UL);
2274 a[tot_values].value = &class;
2275 a[tot_values].value_len = sizeof class;
2276 tot_values++;
2277 }
2278 if (type != -1)
2279 {
2280 a[tot_values].type = CKA_CERTIFICATE_TYPE(0x80UL);
2281 a[tot_values].value = &type;
2282 a[tot_values].value_len = sizeof type;
2283 tot_values++;
2284 }
2285 }
2286 else
2287 {
2288 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2288); } while(0);
;
2289 ret = GNUTLS_E_INVALID_REQUEST-50;
2290 goto fail;
2291 }
2292
2293 attr = p11_kit_uri_get_attribute (find_data->info, CKA_ID(0x102UL));
2294 if (attr != NULL((void*)0))
2295 {
2296 memcpy (a + tot_values, attr, sizeof (struct ck_attribute));
2297 tot_values++;
2298 }
2299
2300 rv = pkcs11_find_objects_init (module, pks, a, tot_values);
2301 if (rv != CKR_OK(0UL))
2302 {
2303 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2303); } while(0);
;
2304 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "pk11: FindObjectsInit failed.\n"); } while(0)
;
2305 return pkcs11_rv_to_err (rv);
2306 }
2307
2308 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK(0UL) && count == 1)
2309 {
2310 gnutls_datum_t label, id, value;
2311
2312 a[0].type = CKA_LABEL(3UL);
2313 a[0].value = label_tmp;
2314 a[0].value_len = sizeof label_tmp;
2315
2316 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL))
2317 {
2318 label.data = a[0].value;
2319 label.size = a[0].value_len;
2320 }
2321 else
2322 {
2323 label.data = NULL((void*)0);
2324 label.size = 0;
2325 }
2326
2327 a[0].type = CKA_ID(0x102UL);
2328 a[0].value = certid_tmp;
2329 a[0].value_len = sizeof certid_tmp;
2330
2331 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL))
2332 {
2333 id.data = a[0].value;
2334 id.size = a[0].value_len;
2335 }
2336 else
2337 {
2338 id.data = NULL((void*)0);
2339 id.size = 0;
2340 }
2341
2342 a[0].type = CKA_VALUE(0x11UL);
2343 a[0].value = cert_data;
2344 a[0].value_len = MAX_CERT_SIZE8*1024;
2345 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL))
2346 {
2347 value.data = a[0].value;
2348 value.size = a[0].value_len;
2349 }
2350 else
2351 {
2352 value.data = NULL((void*)0);
2353 value.size = 0;
2354 }
2355
2356 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2357 {
2358 a[0].type = CKA_CLASS(0UL);
2359 a[0].value = &class;
2360 a[0].value_len = sizeof class;
2361
2362 pkcs11_get_attribute_value (module, pks, obj, a, 1);
2363 }
2364
2365 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2366 {
2367 for (i = 0; i < plist.key_ids_size; i++)
2368 {
2369 if (plist.key_ids[i].length !=
2370 a[1].value_len
2371 || memcmp (plist.key_ids[i].data,
2372 a[1].value, a[1].value_len) != 0)
2373 {
2374 /* not found */
2375 continue;
2376 }
2377 }
2378 }
2379
2380 if (find_data->current < *find_data->n_list)
2381 {
2382 ret =
2383 gnutls_pkcs11_obj_init (&find_data->p_list[find_data->current]);
2384 if (ret < 0)
2385 {
2386 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2386); } while(0);
;
2387 goto fail;
2388 }
2389
2390 if (class == CKO_PUBLIC_KEY(2UL))
2391 {
2392 ret =
2393 pkcs11_obj_import_pubkey (module, pks, obj,
2394 find_data->p_list
2395 [find_data->current],
2396 &id, &label,
2397 &info->tinfo, lib_info);
2398 }
2399 else
2400 {
2401 ret =
2402 pkcs11_obj_import (class,
2403 find_data->p_list
2404 [find_data->current],
2405 &value, &id, &label,
2406 &info->tinfo, lib_info);
2407 }
2408 if (ret < 0)
2409 {
2410 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2410); } while(0);
;
2411 goto fail;
2412 }
2413 }
2414
2415 find_data->current++;
2416
2417 }
2418
2419 gnutls_free (cert_data);
2420 pkcs11_find_objects_final (module, pks);
2421
2422 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; /* continue until all tokens have been checked */
2423
2424fail:
2425 gnutls_free (cert_data);
2426 pkcs11_find_objects_final (module, pks);
2427 if (plist.key_ids != NULL((void*)0))
2428 {
2429 for (i = 0; i < plist.key_ids_size; i++)
2430 {
2431 _gnutls_buffer_clear (&plist.key_ids[i]);
2432 }
2433 gnutls_free (plist.key_ids);
2434 }
2435 for (i = 0; i < find_data->current; i++)
2436 {
2437 gnutls_pkcs11_obj_deinit (find_data->p_list[i]);
2438 }
2439 find_data->current = 0;
2440
2441 return ret;
2442}
2443
2444/**
2445 * gnutls_pkcs11_obj_list_import_url:
2446 * @p_list: An uninitialized object list (may be NULL)
2447 * @n_list: initially should hold the maximum size of the list. Will contain the actual size.
2448 * @url: A PKCS 11 url identifying a set of objects
2449 * @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
2450 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2451 *
2452 * This function will initialize and set values to an object list
2453 * by using all objects identified by a PKCS 11 URL.
2454 *
2455 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2456 * negative error value.
2457 *
2458 * Since: 2.12.0
2459 **/
2460int
2461gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list,
2462 unsigned int *n_list,
2463 const char *url,
2464 gnutls_pkcs11_obj_attr_t attrs,
2465 unsigned int flags)
2466{
2467 int ret;
2468 struct crt_find_data_st find_data;
2469
2470 memset (&find_data, 0, sizeof (find_data));
2471
2472 /* fill in the find data structure */
2473 find_data.p_list = p_list;
2474 find_data.n_list = n_list;
2475 find_data.flags = attrs;
2476 find_data.current = 0;
2477
2478 if (url == NULL((void*)0) || url[0] == 0)
2479 {
2480 url = "pkcs11:";
2481 }
2482
2483 ret = pkcs11_url_to_info (url, &find_data.info);
2484 if (ret < 0)
2485 {
2486 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2486); } while(0);
;
2487 return ret;
2488 }
2489
2490 ret =
2491 _pkcs11_traverse_tokens (find_objs, &find_data, find_data.info,
2492 pkcs11_obj_flags_to_int (flags));
2493 p11_kit_uri_free (find_data.info);
2494
2495 if (ret < 0)
2496 {
2497 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2497); } while(0);
;
2498 return ret;
2499 }
2500
2501 return 0;
2502}
2503
2504/**
2505 * gnutls_x509_crt_import_pkcs11_url:
2506 * @crt: A certificate of type #gnutls_x509_crt_t
2507 * @url: A PKCS 11 url
2508 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2509 *
2510 * This function will import a PKCS 11 certificate directly from a token
2511 * without involving the #gnutls_pkcs11_obj_t structure. This function will
2512 * fail if the certificate stored is not of X.509 type.
2513 *
2514 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2515 * negative error value.
2516 *
2517 * Since: 2.12.0
2518 **/
2519int
2520gnutls_x509_crt_import_pkcs11_url (gnutls_x509_crt_t crt,
2521 const char *url, unsigned int flags)
2522{
2523 gnutls_pkcs11_obj_t pcrt;
2524 int ret;
2525
2526 ret = gnutls_pkcs11_obj_init (&pcrt);
2527 if (ret < 0)
2528 {
2529 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2529); } while(0);
;
2530 return ret;
2531 }
2532
2533 ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
2534 if (ret < 0)
2535 {
2536 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2536); } while(0);
;
2537 goto cleanup;
2538 }
2539
2540 ret = gnutls_x509_crt_import (crt, &pcrt->raw, GNUTLS_X509_FMT_DER);
2541 if (ret < 0)
2542 {
2543 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2543); } while(0);
;
2544 goto cleanup;
2545 }
2546
2547 ret = 0;
2548cleanup:
2549
2550 gnutls_pkcs11_obj_deinit (pcrt);
2551
2552 return ret;
2553}
2554
2555
2556/**
2557 * gnutls_x509_crt_import_pkcs11:
2558 * @crt: A certificate of type #gnutls_x509_crt_t
2559 * @pkcs11_crt: A PKCS 11 object that contains a certificate
2560 *
2561 * This function will import a PKCS 11 certificate to a #gnutls_x509_crt_t
2562 * structure.
2563 *
2564 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2565 * negative error value.
2566 *
2567 * Since: 2.12.0
2568 **/
2569int
2570gnutls_x509_crt_import_pkcs11 (gnutls_x509_crt_t crt,
2571 gnutls_pkcs11_obj_t pkcs11_crt)
2572{
2573 return gnutls_x509_crt_import (crt, &pkcs11_crt->raw, GNUTLS_X509_FMT_DER);
2574}
2575
2576/**
2577 * gnutls_x509_crt_list_import_pkcs11:
2578 * @certs: A list of certificates of type #gnutls_x509_crt_t
2579 * @cert_max: The maximum size of the list
2580 * @objs: A list of PKCS 11 objects
2581 * @flags: 0 for now
2582 *
2583 * This function will import a PKCS 11 certificate list to a list of
2584 * #gnutls_x509_crt_t structure. These must not be initialized.
2585 *
2586 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2587 * negative error value.
2588 *
2589 * Since: 2.12.0
2590 **/
2591int
2592gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
2593 unsigned int cert_max,
2594 gnutls_pkcs11_obj_t * const objs,
2595 unsigned int flags)
2596{
2597 int i, j;
2598 int ret;
2599
2600 for (i = 0; i < cert_max; i++)
2601 {
2602 ret = gnutls_x509_crt_init (&certs[i]);
2603 if (ret < 0)
2604 {
2605 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2605); } while(0);
;
2606 goto cleanup;
2607 }
2608
2609 ret = gnutls_x509_crt_import_pkcs11 (certs[i], objs[i]);
2610 if (ret < 0)
2611 {
2612 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2612); } while(0);
;
2613 goto cleanup;
2614 }
2615 }
2616
2617 return 0;
2618
2619cleanup:
2620 for (j = 0; j < i; j++)
2621 {
2622 gnutls_x509_crt_deinit (certs[j]);
2623 }
2624
2625 return ret;
2626}
2627
2628static int
2629find_flags (struct ck_function_list * module, ck_session_handle_t pks,
2630 struct token_info *info, struct ck_info *lib_info, void *input)
2631{
2632 struct flags_find_data_st *find_data = input;
2633
2634 if (info == NULL((void*)0))
2635 { /* we don't support multiple calls */
2636 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2636); } while(0);
;
2637 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
2638 }
2639
2640 /* do not bother reading the token if basic fields do not match
2641 */
2642 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2643 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2644 {
2645 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2645); } while(0);
;
2646 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
2647 }
2648
2649 /* found token! */
2650
2651 find_data->slot_flags = info->sinfo.flags;
2652
2653 return 0;
2654}
2655
2656/**
2657 * gnutls_pkcs11_token_get_flags:
2658 * @url: should contain a PKCS 11 URL
2659 * @flags: The output flags (GNUTLS_PKCS11_TOKEN_*)
2660 *
2661 * This function will return information about the PKCS 11 token flags.
2662 * The flags from the %gnutls_pkcs11_token_info_t enumeration.
2663 *
2664 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
2665 *
2666 * Since: 2.12.0
2667 **/
2668int
2669gnutls_pkcs11_token_get_flags (const char *url, unsigned int *flags)
2670{
2671 struct flags_find_data_st find_data;
2672 int ret;
2673
2674 memset (&find_data, 0, sizeof (find_data));
2675 ret = pkcs11_url_to_info (url, &find_data.info);
2676 if (ret < 0)
2677 {
2678 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2678); } while(0);
;
2679 return ret;
2680 }
2681
2682 ret = _pkcs11_traverse_tokens (find_flags, &find_data, find_data.info, 0);
2683 p11_kit_uri_free (find_data.info);
2684
2685 if (ret < 0)
2686 {
2687 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2687); } while(0);
;
2688 return ret;
2689 }
2690
2691 *flags = 0;
2692 if (find_data.slot_flags & CKF_HW_SLOT(1UL << 2))
2693 *flags |= GNUTLS_PKCS11_TOKEN_HW1;
2694
2695 return 0;
2696
2697}
2698
2699/**
2700 * gnutls_pkcs11_token_get_mechanism:
2701 * @url: should contain a PKCS 11 URL
2702 * @idx: The index of the mechanism
2703 * @mechanism: The PKCS #11 mechanism ID
2704 *
2705 * This function will return the names of the supported mechanisms
2706 * by the token. It should be called with an increasing index until
2707 * it return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.
2708 *
2709 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
2710 *
2711 * Since: 2.12.0
2712 **/
2713int
2714gnutls_pkcs11_token_get_mechanism (const char *url, int idx,
2715 unsigned long *mechanism)
2716{
2717 int ret;
2718 ck_rv_t rv;
2719 struct ck_function_list *module;
2720 ck_slot_id_t slot;
2721 struct token_info tinfo;
2722 struct p11_kit_uri *info = NULL((void*)0);
2723 unsigned long count;
2724 ck_mechanism_type_t mlist[400];
2725
2726 ret = pkcs11_url_to_info (url, &info);
2727 if (ret < 0)
2728 {
2729 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2729); } while(0);
;
2730 return ret;
2731 }
2732
2733
2734 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
2735 p11_kit_uri_free (info);
2736
2737 if (ret < 0)
2738 {
2739 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2739); } while(0);
;
2740 return ret;
2741 }
2742
2743 count = sizeof (mlist) / sizeof (mlist[0]);
2744 rv = pkcs11_get_mechanism_list (module, slot, mlist, &count);
2745 if (rv != CKR_OK(0UL))
2746 {
2747 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2747); } while(0);
;
2748 return pkcs11_rv_to_err (rv);
2749 }
2750
2751 if (idx >= count)
2752 {
2753 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "pkcs11.c",2753); } while(0);
;
2754 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
2755 }
2756
2757 *mechanism = mlist[idx];
2758
2759 return 0;
2760
2761}
2762
2763/**
2764 * gnutls_pkcs11_type_get_name:
2765 * @type: Holds the PKCS 11 object type, a #gnutls_pkcs11_obj_type_t.
2766 *
2767 * This function will return a human readable description of the
2768 * PKCS11 object type @obj. It will return "Unknown" for unknown
2769 * types.
2770 *
2771 * Returns: human readable string labeling the PKCS11 object type
2772 * @type.
2773 *
2774 * Since: 2.12.0
2775 **/
2776const char *
2777gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t type)
2778{
2779 switch (type)
2780 {
2781 case GNUTLS_PKCS11_OBJ_X509_CRT:
2782 return "X.509 Certificate";
2783 case GNUTLS_PKCS11_OBJ_PUBKEY:
2784 return "Public key";
2785 case GNUTLS_PKCS11_OBJ_PRIVKEY:
2786 return "Private key";
2787 case GNUTLS_PKCS11_OBJ_SECRET_KEY:
2788 return "Secret key";
2789 case GNUTLS_PKCS11_OBJ_DATA:
2790 return "Data";
2791 case GNUTLS_PKCS11_OBJ_UNKNOWN:
2792 default:
2793 return "Unknown";
2794 }
2795}
2796
2797ck_rv_t
2798pkcs11_get_slot_list (struct ck_function_list * module, unsigned char token_present,
2799 ck_slot_id_t *slot_list, unsigned long *count)
2800{
2801 return (module)->C_GetSlotList (token_present, slot_list, count);
2802}
2803
2804ck_rv_t
2805pkcs11_get_module_info (struct ck_function_list * module,
2806 struct ck_info * info)
2807{
2808 return (module)->C_GetInfo (info);
2809}
2810
2811ck_rv_t
2812pkcs11_get_slot_info(struct ck_function_list * module,
2813 ck_slot_id_t slot_id,
2814 struct ck_slot_info *info)
2815{
2816 return (module)->C_GetSlotInfo (slot_id, info);
2817}
2818
2819ck_rv_t
2820pkcs11_get_token_info (struct ck_function_list * module,
2821 ck_slot_id_t slot_id,
2822 struct ck_token_info *info)
2823{
2824 return (module)->C_GetTokenInfo (slot_id, info);
2825}
2826
2827ck_rv_t
2828pkcs11_find_objects_init (struct ck_function_list *module,
2829 ck_session_handle_t sess,
2830 struct ck_attribute *templ,
2831 unsigned long count)
2832{
2833 return (module)->C_FindObjectsInit (sess, templ, count);
2834}
2835
2836ck_rv_t
2837pkcs11_find_objects (struct ck_function_list *module,
2838 ck_session_handle_t sess,
2839 ck_object_handle_t *objects,
2840 unsigned long max_object_count,
2841 unsigned long *object_count)
2842{
2843 return (module)->C_FindObjects (sess, objects, max_object_count, object_count);
2844}
2845
2846ck_rv_t
2847pkcs11_find_objects_final (struct ck_function_list *module,
2848 ck_session_handle_t sess)
2849{
2850 return (module)->C_FindObjectsFinal (sess);
2851}
2852
2853ck_rv_t
2854pkcs11_close_session (struct ck_function_list *module,
2855 ck_session_handle_t sess)
2856{
2857 return (module)->C_CloseSession (sess);
2858}
2859
2860ck_rv_t
2861pkcs11_get_attribute_value(struct ck_function_list *module,
2862 ck_session_handle_t sess,
2863 ck_object_handle_t object,
2864 struct ck_attribute *templ,
2865 unsigned long count)
2866{
2867 return (module)->C_GetAttributeValue (sess, object, templ, count);
2868}
2869
2870ck_rv_t
2871pkcs11_get_mechanism_list (struct ck_function_list *module,
2872 ck_slot_id_t slot_id,
2873 ck_mechanism_type_t *mechanism_list,
2874 unsigned long *count)
2875{
2876 return (module)->C_GetMechanismList (slot_id, mechanism_list, count);
2877}
2878
2879ck_rv_t
2880pkcs11_sign_init (struct ck_function_list *module,
2881 ck_session_handle_t sess,
2882 struct ck_mechanism *mechanism,
2883 ck_object_handle_t key)
2884{
2885 return (module)->C_SignInit (sess, mechanism, key);
2886}
2887
2888ck_rv_t
2889pkcs11_sign (struct ck_function_list *module,
2890 ck_session_handle_t sess,
2891 unsigned char *data,
2892 unsigned long data_len,
2893 unsigned char *signature,
2894 unsigned long *signature_len)
2895{
2896 return (module)->C_Sign (sess, data, data_len, signature, signature_len);
2897}
2898
2899ck_rv_t
2900pkcs11_generate_key_pair (struct ck_function_list *module,
2901 ck_session_handle_t sess,
2902 struct ck_mechanism *mechanism,
2903 struct ck_attribute *pub_templ,
2904 unsigned long pub_templ_count,
2905 struct ck_attribute *priv_templ,
2906 unsigned long priv_templ_count,
2907 ck_object_handle_t *pub,
2908 ck_object_handle_t *priv)
2909{
2910 return (module)->C_GenerateKeyPair (sess, mechanism, pub_templ, pub_templ_count,
2911 priv_templ, priv_templ_count, pub, priv);
2912}
2913
2914ck_rv_t
2915pkcs11_decrypt_init (struct ck_function_list *module,
2916 ck_session_handle_t sess,
2917 struct ck_mechanism *mechanism,
2918 ck_object_handle_t key)
2919{
2920 return (module)->C_DecryptInit (sess, mechanism, key);
2921}
2922
2923ck_rv_t
2924pkcs11_decrypt (struct ck_function_list *module,
2925 ck_session_handle_t sess,
2926 unsigned char *encrypted_data,
2927 unsigned long encrypted_data_len,
2928 unsigned char *data, unsigned long *data_len)
2929{
2930 return (module)->C_Decrypt (sess, encrypted_data, encrypted_data_len,
2931 data, data_len);
2932}
2933
2934ck_rv_t
2935pkcs11_create_object (struct ck_function_list *module,
2936 ck_session_handle_t sess,
2937 struct ck_attribute *templ,
2938 unsigned long count,
2939 ck_object_handle_t *object)
2940{
2941 return (module)->C_CreateObject (sess, templ, count, object);
2942}
2943
2944ck_rv_t
2945pkcs11_destroy_object (struct ck_function_list *module,
2946 ck_session_handle_t sess,
2947 ck_object_handle_t object)
2948{
2949 return (module)->C_DestroyObject (sess, object);
2950}
2951
2952ck_rv_t
2953pkcs11_init_token (struct ck_function_list *module,
2954 ck_slot_id_t slot_id, unsigned char *pin,
2955 unsigned long pin_len, unsigned char *label)
2956{
2957 return (module)->C_InitToken (slot_id, pin, pin_len, label);
2958}
2959
2960ck_rv_t
2961pkcs11_init_pin (struct ck_function_list *module,
2962 ck_session_handle_t sess,
2963 unsigned char *pin,
2964 unsigned long pin_len)
2965{
2966 return (module)->C_InitPIN (sess, pin, pin_len);
2967}
2968
2969ck_rv_t
2970pkcs11_set_pin (struct ck_function_list *module,
2971 ck_session_handle_t sess,
2972 unsigned char *old_pin,
2973 unsigned long old_len,
2974 unsigned char *new_pin,
2975 unsigned long new_len)
2976{
2977 return (module)->C_SetPIN (sess, old_pin, old_len, new_pin, new_len);
2978}
2979
2980const char *
2981pkcs11_strerror (ck_rv_t rv)
2982{
2983 return p11_kit_strerror (rv);
2984}