PKCS #11 PIN handling fixes.
[gnutls.git] / lib / pkcs11.c
blob32f6a8ae1b643fe34e5dc0f17bfdaa60a02e9d89
1 /*
2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010-2012 Free Software Foundation, Inc.
4 * Copyright (C) 2008, Joe Orton <joe@manyfish.co.uk>
5 *
6 * Authors: Nikos Mavrogiannopoulos, Stef Walter
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.
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.
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.
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/>
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_datum.h>
34 #include <pkcs11_int.h>
35 #include <p11-kit/p11-kit.h>
36 #include <p11-kit/pin.h>
38 #define MAX_PROVIDERS 16
40 /* XXX: try to eliminate this */
41 #define MAX_CERT_SIZE 8*1024
43 struct gnutls_pkcs11_provider_s
45 struct ck_function_list *module;
46 unsigned long nslots;
47 ck_slot_id_t *slots;
48 struct ck_info info;
49 unsigned int initialized;
52 struct flags_find_data_st
54 struct p11_kit_uri *info;
55 unsigned int slot_flags;
58 struct url_find_data_st
60 gnutls_pkcs11_obj_t crt;
63 struct crt_find_data_st
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;
73 static struct gnutls_pkcs11_provider_s providers[MAX_PROVIDERS];
74 static unsigned int active_providers = 0;
75 static unsigned int initialized_registered = 0;
77 gnutls_pin_callback_t _gnutls_pin_func;
78 void *_gnutls_pin_data;
80 gnutls_pkcs11_token_callback_t _gnutls_token_func;
81 void *_gnutls_token_data;
83 int
84 pkcs11_rv_to_err (ck_rv_t rv)
86 switch (rv)
88 case CKR_OK:
89 return 0;
90 case CKR_HOST_MEMORY:
91 return GNUTLS_E_MEMORY_ERROR;
92 case CKR_SLOT_ID_INVALID:
93 return GNUTLS_E_PKCS11_SLOT_ERROR;
94 case CKR_ARGUMENTS_BAD:
95 case CKR_MECHANISM_PARAM_INVALID:
96 return GNUTLS_E_INVALID_REQUEST;
97 case CKR_NEED_TO_CREATE_THREADS:
98 case CKR_CANT_LOCK:
99 case CKR_FUNCTION_NOT_PARALLEL:
100 case CKR_MUTEX_BAD:
101 case CKR_MUTEX_NOT_LOCKED:
102 return GNUTLS_E_LOCKING_ERROR;
103 case CKR_ATTRIBUTE_READ_ONLY:
104 case CKR_ATTRIBUTE_SENSITIVE:
105 case CKR_ATTRIBUTE_TYPE_INVALID:
106 case CKR_ATTRIBUTE_VALUE_INVALID:
107 return GNUTLS_E_PKCS11_ATTRIBUTE_ERROR;
108 case CKR_DEVICE_ERROR:
109 case CKR_DEVICE_MEMORY:
110 case CKR_DEVICE_REMOVED:
111 return GNUTLS_E_PKCS11_DEVICE_ERROR;
112 case CKR_DATA_INVALID:
113 case CKR_DATA_LEN_RANGE:
114 case CKR_ENCRYPTED_DATA_INVALID:
115 case CKR_ENCRYPTED_DATA_LEN_RANGE:
116 case CKR_OBJECT_HANDLE_INVALID:
117 return GNUTLS_E_PKCS11_DATA_ERROR;
118 case CKR_FUNCTION_NOT_SUPPORTED:
119 case CKR_MECHANISM_INVALID:
120 return GNUTLS_E_PKCS11_UNSUPPORTED_FEATURE_ERROR;
121 case CKR_KEY_HANDLE_INVALID:
122 case CKR_KEY_SIZE_RANGE:
123 case CKR_KEY_TYPE_INCONSISTENT:
124 case CKR_KEY_NOT_NEEDED:
125 case CKR_KEY_CHANGED:
126 case CKR_KEY_NEEDED:
127 case CKR_KEY_INDIGESTIBLE:
128 case CKR_KEY_FUNCTION_NOT_PERMITTED:
129 case CKR_KEY_NOT_WRAPPABLE:
130 case CKR_KEY_UNEXTRACTABLE:
131 return GNUTLS_E_PKCS11_KEY_ERROR;
132 case CKR_PIN_INCORRECT:
133 case CKR_PIN_INVALID:
134 case CKR_PIN_LEN_RANGE:
135 return GNUTLS_E_PKCS11_PIN_ERROR;
136 case CKR_PIN_EXPIRED:
137 return GNUTLS_E_PKCS11_PIN_EXPIRED;
138 case CKR_PIN_LOCKED:
139 return GNUTLS_E_PKCS11_PIN_LOCKED;
140 case CKR_SESSION_CLOSED:
141 case CKR_SESSION_COUNT:
142 case CKR_SESSION_HANDLE_INVALID:
143 case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
144 case CKR_SESSION_READ_ONLY:
145 case CKR_SESSION_EXISTS:
146 case CKR_SESSION_READ_ONLY_EXISTS:
147 case CKR_SESSION_READ_WRITE_SO_EXISTS:
148 return GNUTLS_E_PKCS11_SESSION_ERROR;
149 case CKR_SIGNATURE_INVALID:
150 case CKR_SIGNATURE_LEN_RANGE:
151 return GNUTLS_E_PKCS11_SIGNATURE_ERROR;
152 case CKR_TOKEN_NOT_PRESENT:
153 case CKR_TOKEN_NOT_RECOGNIZED:
154 case CKR_TOKEN_WRITE_PROTECTED:
155 return GNUTLS_E_PKCS11_TOKEN_ERROR;
156 case CKR_USER_ALREADY_LOGGED_IN:
157 case CKR_USER_NOT_LOGGED_IN:
158 case CKR_USER_PIN_NOT_INITIALIZED:
159 case CKR_USER_TYPE_INVALID:
160 case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
161 case CKR_USER_TOO_MANY_TYPES:
162 return GNUTLS_E_PKCS11_USER_ERROR;
163 case CKR_BUFFER_TOO_SMALL:
164 return GNUTLS_E_SHORT_MEMORY_BUFFER;
165 default:
166 return GNUTLS_E_PKCS11_ERROR;
170 /* Fake scan */
171 void
172 pkcs11_rescan_slots (void)
174 unsigned long slots;
176 pkcs11_get_slot_list (providers[active_providers - 1].module, 0,
177 NULL, &slots);
180 static int
181 pkcs11_add_module (const char *name, struct ck_function_list *module)
183 struct ck_info info;
184 unsigned int i;
186 if (active_providers >= MAX_PROVIDERS)
188 gnutls_assert ();
189 return GNUTLS_E_CONSTRAINT_ERROR;
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++)
197 /* already loaded, skip the rest */
198 if (memcmp(&info, &providers[i].info, sizeof(info)) == 0)
200 _gnutls_debug_log("%s is already loaded.\n", name);
201 return GNUTLS_E_INT_RET_0;
205 active_providers++;
206 providers[active_providers - 1].module = module;
208 /* cache the number of slots in this module */
209 if (pkcs11_get_slot_list
210 (providers[active_providers - 1].module, 0, NULL,
211 &providers[active_providers - 1].nslots) != CKR_OK)
213 gnutls_assert ();
214 goto fail;
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)
222 gnutls_assert ();
223 goto fail;
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)
231 gnutls_assert ();
232 gnutls_free (providers[active_providers - 1].slots);
233 goto fail;
236 memcpy (&providers[active_providers - 1].info, &info, sizeof(info));
238 _gnutls_debug_log ("p11: loaded provider '%s' with %d slots\n",
239 name, (int) providers[active_providers - 1].nslots);
241 return 0;
243 fail:
244 active_providers--;
245 return GNUTLS_E_PKCS11_LOAD_ERROR;
250 * gnutls_pkcs11_add_provider:
251 * @name: The filename of the module
252 * @params: should be NULL
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.
258 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
259 * negative error value.
261 * Since: 2.12.0
264 gnutls_pkcs11_add_provider (const char *name, const char *params)
266 struct ck_function_list *module;
267 int ret;
269 active_providers++;
270 if (p11_kit_load_initialize_module (name, &module) != CKR_OK)
272 gnutls_assert ();
273 _gnutls_debug_log ("p11: Cannot load provider %s\n", name);
274 active_providers--;
275 return GNUTLS_E_PKCS11_LOAD_ERROR;
278 ret = pkcs11_add_module (name, module);
279 if (ret == 0)
281 /* Mark this one as having been separately initialized */
282 providers[active_providers - 1].initialized = 1;
284 else
286 if (ret == GNUTLS_E_INT_RET_0) ret = 0;
287 p11_kit_finalize_module (module);
288 gnutls_assert ();
291 return ret;
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
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.
307 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
309 * Since: 2.12.0
312 gnutls_pkcs11_obj_get_info (gnutls_pkcs11_obj_t crt,
313 gnutls_pkcs11_obj_info_t itype,
314 void *output, size_t * output_size)
316 return pkcs11_get_info (crt->info, itype, output, output_size);
320 pkcs11_get_info (struct p11_kit_uri *info,
321 gnutls_pkcs11_obj_info_t itype, void *output,
322 size_t * output_size)
324 struct ck_attribute *attr = NULL;
325 struct ck_version *version = NULL;
326 const uint8_t *str = NULL;
327 size_t str_max = 0;
328 int terminate = 0;
329 int hexify = 0;
330 size_t length = 0;
331 const char *data = NULL;
332 char buf[32];
335 * Either attr, str or version is valid by the time switch
336 * finishes
339 switch (itype)
341 case GNUTLS_PKCS11_OBJ_ID:
342 attr = p11_kit_uri_get_attribute (info, CKA_ID);
343 break;
344 case GNUTLS_PKCS11_OBJ_ID_HEX:
345 attr = p11_kit_uri_get_attribute (info, CKA_ID);
346 hexify = 1;
347 terminate = 1;
348 break;
349 case GNUTLS_PKCS11_OBJ_LABEL:
350 attr = p11_kit_uri_get_attribute (info, CKA_LABEL);
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 ();
382 return GNUTLS_E_INVALID_REQUEST;
385 if (attr != NULL)
387 data = attr->value;
388 length = attr->value_len;
390 else if (str != NULL)
392 data = (void*)str;
393 length = p11_kit_space_strlen (str, str_max);
394 terminate = 1;
396 else if (version != NULL)
398 data = buf;
399 length = snprintf (buf, sizeof (buf), "%d.%d", (int)version->major,
400 (int)version->minor);
401 terminate = 1;
403 else
405 *output_size = 0;
406 if (output) ((uint8_t*)output)[0] = 0;
407 return 0;
410 if (hexify)
412 /* terminate is assumed with hexify */
413 if (*output_size < length * 3)
415 *output_size = length * 3;
416 return GNUTLS_E_SHORT_MEMORY_BUFFER;
418 if (output)
419 _gnutls_bin2hex (data, length, output, *output_size, ":");
420 *output_size = length * 3;
421 return 0;
423 else
425 if (*output_size < length + terminate)
427 *output_size = length + terminate;
428 return GNUTLS_E_SHORT_MEMORY_BUFFER;
430 if (output)
432 memcpy (output, data, length);
433 if (terminate)
434 ((unsigned char*)output)[length] = '\0';
436 *output_size = length + terminate;
439 return 0;
442 static int init = 0;
444 /* tries to load modules from /etc/gnutls/pkcs11.conf if it exists
446 static void _pkcs11_compat_init(const char* configfile)
448 FILE *fp;
449 int ret;
450 char line[512];
451 const char *library;
453 if (configfile == NULL)
454 configfile = "/etc/gnutls/pkcs11.conf";
456 fp = fopen (configfile, "r");
457 if (fp == NULL)
459 gnutls_assert ();
460 return;
463 _gnutls_debug_log ("Loading PKCS #11 libraries from %s\n", configfile);
464 while (fgets (line, sizeof (line), fp) != NULL)
466 if (strncmp (line, "load", sizeof ("load") - 1) == 0)
468 char *p;
469 p = strchr (line, '=');
470 if (p == NULL)
471 continue;
473 library = ++p;
474 p = strchr (line, '\n');
475 if (p != NULL)
476 *p = 0;
478 ret = gnutls_pkcs11_add_provider (library, NULL);
479 if (ret < 0)
481 gnutls_assert ();
482 _gnutls_debug_log ("Cannot load provider: %s\n", library);
483 continue;
487 fclose(fp);
489 return;
492 static int
493 initialize_automatic_p11_kit (void)
495 struct ck_function_list **modules;
496 char *name;
497 ck_rv_t rv;
498 int i, ret;
500 rv = p11_kit_initialize_registered ();
501 if (rv != CKR_OK)
503 gnutls_assert ();
504 _gnutls_debug_log ("Cannot initialize registered module: %s\n",
505 p11_kit_strerror (rv));
506 return GNUTLS_E_INTERNAL_ERROR;
509 initialized_registered = 1;
511 modules = p11_kit_registered_modules ();
512 for (i = 0; modules[i] != NULL; i++)
514 name = p11_kit_registered_module_to_name (modules[i]);
515 ret = pkcs11_add_module (name, modules[i]);
516 if (ret != 0 && ret != GNUTLS_E_INT_RET_0)
518 gnutls_assert ();
519 _gnutls_debug_log ("Cannot add registered module: %s\n", name);
521 free(name);
524 free (modules);
525 return 0;
529 * gnutls_pkcs11_init:
530 * @flags: %GNUTLS_PKCS11_FLAG_MANUAL or %GNUTLS_PKCS11_FLAG_AUTO
531 * @deprecated_config_file: either NULL or the location of a deprecated
532 * configuration file
534 * This function will initialize the PKCS 11 subsystem in gnutls. It will
535 * read configuration files if %GNUTLS_PKCS11_FLAG_AUTO is used or allow
536 * you to independently load PKCS 11 modules using gnutls_pkcs11_add_provider()
537 * if %GNUTLS_PKCS11_FLAG_MANUAL is specified.
539 * Normally you don't need to call this function since it is being called
540 * by gnutls_global_init() using the %GNUTLS_PKCS11_FLAG_AUTO. If other option
541 * is required then it must be called before it.
543 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
544 * negative error value.
546 * Since: 2.12.0
549 gnutls_pkcs11_init (unsigned int flags, const char *deprecated_config_file)
551 int ret = 0;
553 if (init != 0)
555 init++;
556 return 0;
558 init++;
560 p11_kit_pin_register_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback,
561 NULL, NULL);
563 if (flags == GNUTLS_PKCS11_FLAG_MANUAL)
564 return 0;
565 else if (flags == GNUTLS_PKCS11_FLAG_AUTO)
567 if (deprecated_config_file == NULL)
568 ret = initialize_automatic_p11_kit ();
570 _pkcs11_compat_init(deprecated_config_file);
572 return ret;
575 return 0;
579 * gnutls_pkcs11_reinit:
581 * This function will reinitialize the PKCS 11 subsystem in gnutls.
582 * This is required by PKCS 11 when an application uses fork(). The
583 * reinitialization function must be called on the child.
585 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
586 * negative error value.
588 * Since: 3.0
590 int gnutls_pkcs11_reinit (void)
592 int rv;
594 rv = p11_kit_initialize_registered ();
595 if (rv != CKR_OK)
597 gnutls_assert ();
598 _gnutls_debug_log ("Cannot initialize registered module: %s\n",
599 p11_kit_strerror (rv));
600 return GNUTLS_E_INTERNAL_ERROR;
603 return 0;
607 * gnutls_pkcs11_deinit:
609 * This function will deinitialize the PKCS 11 subsystem in gnutls.
611 * Since: 2.12.0
613 void
614 gnutls_pkcs11_deinit (void)
616 unsigned int i;
618 init--;
619 if (init > 0)
620 return;
621 if (init < 0)
623 init = 0;
624 return;
627 for (i = 0; i < active_providers; i++)
629 if (providers[i].initialized)
630 p11_kit_finalize_module (providers[i].module);
632 active_providers = 0;
634 if (initialized_registered != 0)
635 p11_kit_finalize_registered ();
636 initialized_registered = 0;
638 gnutls_pkcs11_set_pin_function (NULL, NULL);
639 gnutls_pkcs11_set_token_function (NULL, NULL);
643 * gnutls_pkcs11_set_pin_function:
644 * @fn: The PIN callback, a gnutls_pin_callback_t() function.
645 * @userdata: data to be supplied to callback
647 * This function will set a callback function to be used when a PIN is
648 * required for PKCS 11 operations. See
649 * gnutls_pin_callback_t() on how the callback should behave.
651 * Since: 2.12.0
653 void
654 gnutls_pkcs11_set_pin_function (gnutls_pin_callback_t fn,
655 void *userdata)
657 _gnutls_pin_func = fn;
658 _gnutls_pin_data = userdata;
662 * gnutls_pkcs11_get_pin_function:
663 * @userdata: data to be supplied to callback
665 * This function will return the callback function set using
666 * gnutls_pkcs11_set_pin_function().
668 * Returns: The function set or NULL otherwise.
670 * Since: 3.1.0
672 gnutls_pin_callback_t
673 gnutls_pkcs11_get_pin_function (void **userdata)
675 if (_gnutls_pin_func != NULL)
677 *userdata = _gnutls_pin_data;
678 return _gnutls_pin_func;
680 return NULL;
684 * gnutls_pkcs11_set_token_function:
685 * @fn: The token callback
686 * @userdata: data to be supplied to callback
688 * This function will set a callback function to be used when a token
689 * needs to be inserted to continue PKCS 11 operations.
691 * Since: 2.12.0
693 void
694 gnutls_pkcs11_set_token_function (gnutls_pkcs11_token_callback_t fn,
695 void *userdata)
697 _gnutls_token_func = fn;
698 _gnutls_token_data = userdata;
702 pkcs11_url_to_info (const char *url, struct p11_kit_uri **info)
704 int allocated = 0;
705 int ret;
707 if (*info == NULL)
709 *info = p11_kit_uri_new ();
710 if (*info == NULL)
712 gnutls_assert ();
713 return GNUTLS_E_MEMORY_ERROR;
715 allocated = 1;
718 ret = p11_kit_uri_parse (url, P11_KIT_URI_FOR_ANY, *info);
719 if (ret < 0)
721 if (allocated)
723 p11_kit_uri_free (*info);
724 *info = NULL;
726 gnutls_assert ();
727 return ret == P11_KIT_URI_NO_MEMORY ?
728 GNUTLS_E_MEMORY_ERROR : GNUTLS_E_PARSING_ERROR;
731 return 0;
735 pkcs11_info_to_url (struct p11_kit_uri *info,
736 gnutls_pkcs11_url_type_t detailed, char **url)
738 p11_kit_uri_type_t type = 0;
739 int ret;
741 switch (detailed)
743 case GNUTLS_PKCS11_URL_GENERIC:
744 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN;
745 break;
746 case GNUTLS_PKCS11_URL_LIB:
747 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE;
748 break;
749 case GNUTLS_PKCS11_URL_LIB_VERSION:
750 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE | P11_KIT_URI_FOR_MODULE_WITH_VERSION;
751 break;
754 ret = p11_kit_uri_format (info, type, url);
755 if (ret < 0)
757 gnutls_assert ();
758 return ret == P11_KIT_URI_NO_MEMORY ?
759 GNUTLS_E_MEMORY_ERROR : GNUTLS_E_INTERNAL_ERROR;
762 return 0;
766 * gnutls_pkcs11_obj_init:
767 * @obj: The structure to be initialized
769 * This function will initialize a pkcs11 certificate structure.
771 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
772 * negative error value.
774 * Since: 2.12.0
777 gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t * obj)
779 *obj = gnutls_calloc (1, sizeof (struct gnutls_pkcs11_obj_st));
780 if (*obj == NULL)
782 gnutls_assert ();
783 return GNUTLS_E_MEMORY_ERROR;
786 (*obj)->info = p11_kit_uri_new ();
787 if ((*obj)->info == NULL)
789 free (*obj);
790 gnutls_assert ();
791 return GNUTLS_E_MEMORY_ERROR;
794 return 0;
798 * gnutls_pkcs11_obj_set_pin_function:
799 * @obj: The object structure
800 * @fn: the callback
801 * @userdata: data associated with the callback
803 * This function will set a callback function to be used when
804 * required to access the object. This function overrides the global
805 * set using gnutls_pkcs11_set_pin_function().
807 * Since: 3.1.0
810 void gnutls_pkcs11_obj_set_pin_function (gnutls_pkcs11_obj_t obj,
811 gnutls_pin_callback_t fn, void *userdata)
813 obj->pin.cb = fn;
814 obj->pin.data = userdata;
818 * gnutls_pkcs11_obj_deinit:
819 * @obj: The structure to be initialized
821 * This function will deinitialize a certificate structure.
823 * Since: 2.12.0
825 void
826 gnutls_pkcs11_obj_deinit (gnutls_pkcs11_obj_t obj)
828 _gnutls_free_datum (&obj->raw);
829 p11_kit_uri_free (obj->info);
830 free (obj);
834 * gnutls_pkcs11_obj_export:
835 * @obj: Holds the object
836 * @output_data: will contain a certificate PEM or DER encoded
837 * @output_data_size: holds the size of output_data (and will be
838 * replaced by the actual size of parameters)
840 * This function will export the PKCS11 object data. It is normal for
841 * data to be inaccesible and in that case %GNUTLS_E_INVALID_REQUEST
842 * will be returned.
844 * If the buffer provided is not long enough to hold the output, then
845 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
846 * be returned.
848 * If the structure is PEM encoded, it will have a header
849 * of "BEGIN CERTIFICATE".
851 * Returns: In case of failure a negative error code will be
852 * returned, and %GNUTLS_E_SUCCESS (0) on success.
854 * Since: 2.12.0
857 gnutls_pkcs11_obj_export (gnutls_pkcs11_obj_t obj,
858 void *output_data, size_t * output_data_size)
860 if (obj == NULL || obj->raw.data == NULL)
862 gnutls_assert ();
863 return GNUTLS_E_INVALID_REQUEST;
866 if (output_data == NULL || *output_data_size < obj->raw.size)
868 *output_data_size = obj->raw.size;
869 gnutls_assert ();
870 return GNUTLS_E_SHORT_MEMORY_BUFFER;
872 *output_data_size = obj->raw.size;
874 memcpy (output_data, obj->raw.data, obj->raw.size);
875 return 0;
879 pkcs11_find_object (struct pkcs11_session_info* sinfo,
880 struct pin_info_st * pin_info,
881 ck_object_handle_t * _obj,
882 struct p11_kit_uri *info, unsigned int flags)
884 int ret;
885 ck_object_handle_t obj;
886 struct ck_attribute *attrs;
887 unsigned long attr_count;
888 unsigned long count;
889 ck_rv_t rv;
891 ret = pkcs11_open_session (sinfo, pin_info, info, flags & SESSION_LOGIN);
892 if (ret < 0)
894 gnutls_assert ();
895 return ret;
898 attrs = p11_kit_uri_get_attributes (info, &attr_count);
899 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, attrs, attr_count);
900 if (rv != CKR_OK)
902 gnutls_assert ();
903 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
904 ret = pkcs11_rv_to_err (rv);
905 goto fail;
908 if (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
910 *_obj = obj;
911 pkcs11_find_objects_final (sinfo);
912 return 0;
915 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
916 pkcs11_find_objects_final (sinfo);
917 fail:
918 pkcs11_close_session (sinfo);
920 return ret;
924 pkcs11_find_slot (struct ck_function_list ** module, ck_slot_id_t * slot,
925 struct p11_kit_uri *info, struct token_info *_tinfo)
927 unsigned int x, z;
929 for (x = 0; x < active_providers; x++)
931 for (z = 0; z < providers[x].nslots; z++)
933 struct token_info tinfo;
935 if (pkcs11_get_token_info
936 (providers[x].module, providers[x].slots[z],
937 &tinfo.tinfo) != CKR_OK)
939 continue;
941 tinfo.sid = providers[x].slots[z];
942 tinfo.prov = &providers[x];
944 if (pkcs11_get_slot_info
945 (providers[x].module, providers[x].slots[z],
946 &tinfo.sinfo) != CKR_OK)
948 continue;
951 if (!p11_kit_uri_match_token_info (info, &tinfo.tinfo) ||
952 !p11_kit_uri_match_module_info (info, &providers[x].info))
954 continue;
957 /* ok found */
958 *module = providers[x].module;
959 *slot = providers[x].slots[z];
961 if (_tinfo != NULL)
962 memcpy (_tinfo, &tinfo, sizeof (tinfo));
964 return 0;
968 gnutls_assert ();
969 return GNUTLS_E_PKCS11_REQUESTED_OBJECT_NOT_AVAILBLE;
973 pkcs11_open_session (struct pkcs11_session_info *sinfo,
974 struct pin_info_st *pin_info,
975 struct p11_kit_uri *info,
976 unsigned int flags)
978 ck_rv_t rv;
979 int ret;
980 ck_session_handle_t pks = 0;
981 struct ck_function_list *module;
982 ck_slot_id_t slot;
983 struct token_info tinfo;
985 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
986 if (ret < 0)
988 gnutls_assert ();
989 return ret;
992 rv = (module)->C_OpenSession (slot,
993 ((flags & SESSION_WRITE)
994 ? CKF_RW_SESSION : 0) |
995 CKF_SERIAL_SESSION, NULL, NULL, &pks);
996 if (rv != CKR_OK)
998 gnutls_assert ();
999 return pkcs11_rv_to_err (rv);
1002 /* ok found */
1003 sinfo->pks = pks;
1004 sinfo->module = module;
1005 sinfo->init = 1;
1006 memcpy(&sinfo->tinfo, &tinfo.tinfo, sizeof(sinfo->tinfo));
1008 if (flags & SESSION_LOGIN)
1010 ret = pkcs11_login (sinfo, pin_info, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
1011 if (ret < 0)
1013 gnutls_assert ();
1014 pkcs11_close_session (sinfo);
1015 return ret;
1019 return 0;
1024 _pkcs11_traverse_tokens (find_func_t find_func, void *input,
1025 struct p11_kit_uri *info,
1026 struct pin_info_st *pin_info,
1027 unsigned int flags)
1029 ck_rv_t rv;
1030 unsigned int found = 0, x, z;
1031 int ret;
1032 ck_session_handle_t pks = 0;
1033 struct pkcs11_session_info sinfo;
1034 struct ck_function_list *module = NULL;
1036 for (x = 0; x < active_providers; x++)
1038 module = providers[x].module;
1039 for (z = 0; z < providers[x].nslots; z++)
1041 struct token_info tinfo;
1043 ret = GNUTLS_E_PKCS11_ERROR;
1045 if (pkcs11_get_token_info (module, providers[x].slots[z],
1046 &tinfo.tinfo) != CKR_OK)
1048 continue;
1050 tinfo.sid = providers[x].slots[z];
1051 tinfo.prov = &providers[x];
1053 if (pkcs11_get_slot_info (module, providers[x].slots[z],
1054 &tinfo.sinfo) != CKR_OK)
1056 continue;
1059 rv = (module)->C_OpenSession (providers[x].slots[z],
1060 ((flags & SESSION_WRITE)
1061 ? CKF_RW_SESSION : 0) |
1062 CKF_SERIAL_SESSION, NULL, NULL, &pks);
1063 if (rv != CKR_OK)
1065 continue;
1068 sinfo.module = module;
1069 sinfo.pks = pks;
1071 if (flags & SESSION_LOGIN)
1073 ret = pkcs11_login (&sinfo, pin_info, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
1074 if (ret < 0)
1076 gnutls_assert ();
1077 return ret;
1081 ret = find_func (&sinfo, &tinfo, &providers[x].info, input);
1083 if (ret == 0)
1085 found = 1;
1086 goto finish;
1088 else
1090 pkcs11_close_session (&sinfo);
1091 pks = 0;
1096 finish:
1097 /* final call */
1099 if (found == 0)
1101 if (module)
1103 sinfo.module = module;
1104 sinfo.pks = pks;
1105 ret = find_func (&sinfo, NULL, NULL, input);
1107 else
1108 ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1110 else
1112 ret = 0;
1115 if (pks != 0 && module != NULL)
1117 pkcs11_close_session (&sinfo);
1120 return ret;
1123 /* imports a raw certificate from a token to a pkcs11_obj_t structure.
1125 static int
1126 pkcs11_obj_import (ck_object_class_t class, gnutls_pkcs11_obj_t obj,
1127 const gnutls_datum_t * data,
1128 const gnutls_datum_t * id,
1129 const gnutls_datum_t * label,
1130 struct ck_token_info *tinfo, struct ck_info *lib_info)
1132 struct ck_attribute attr;
1133 int ret;
1135 switch (class)
1137 case CKO_CERTIFICATE:
1138 obj->type = GNUTLS_PKCS11_OBJ_X509_CRT;
1139 break;
1140 case CKO_PUBLIC_KEY:
1141 obj->type = GNUTLS_PKCS11_OBJ_PUBKEY;
1142 break;
1143 case CKO_PRIVATE_KEY:
1144 obj->type = GNUTLS_PKCS11_OBJ_PRIVKEY;
1145 break;
1146 case CKO_SECRET_KEY:
1147 obj->type = GNUTLS_PKCS11_OBJ_SECRET_KEY;
1148 break;
1149 case CKO_DATA:
1150 obj->type = GNUTLS_PKCS11_OBJ_DATA;
1151 break;
1152 default:
1153 obj->type = GNUTLS_PKCS11_OBJ_UNKNOWN;
1156 attr.type = CKA_CLASS;
1157 attr.value = &class;
1158 attr.value_len = sizeof (class);
1159 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1160 if (ret < 0)
1162 gnutls_assert ();
1163 return GNUTLS_E_MEMORY_ERROR;
1166 if (data && data->data)
1168 ret = _gnutls_set_datum (&obj->raw, data->data, data->size);
1169 if (ret < 0)
1171 gnutls_assert ();
1172 return ret;
1176 /* copy the token and library info into the uri */
1177 memcpy (p11_kit_uri_get_token_info (obj->info), tinfo, sizeof (struct ck_token_info));
1178 memcpy (p11_kit_uri_get_module_info (obj->info), lib_info, sizeof (struct ck_info));
1180 if (label && label->data)
1182 attr.type = CKA_LABEL;
1183 attr.value = label->data;
1184 attr.value_len = label->size;
1185 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1186 if (ret < 0)
1188 gnutls_assert ();
1189 return GNUTLS_E_MEMORY_ERROR;
1193 if (id && id->data)
1195 attr.type = CKA_ID;
1196 attr.value = id->data;
1197 attr.value_len = id->size;
1198 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1199 if (ret < 0)
1201 gnutls_assert ();
1202 return GNUTLS_E_MEMORY_ERROR;
1206 return 0;
1209 static int read_pkcs11_pubkey(struct ck_function_list *module,
1210 ck_session_handle_t pks, ck_object_handle_t obj,
1211 ck_key_type_t key_type, gnutls_datum_t * pubkey)
1213 struct ck_attribute a[4];
1214 uint8_t tmp1[2048];
1215 uint8_t tmp2[2048];
1216 int ret;
1218 switch (key_type)
1220 case CKK_RSA:
1221 a[0].type = CKA_MODULUS;
1222 a[0].value = tmp1;
1223 a[0].value_len = sizeof (tmp1);
1224 a[1].type = CKA_PUBLIC_EXPONENT;
1225 a[1].value = tmp2;
1226 a[1].value_len = sizeof (tmp2);
1228 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1231 ret =
1232 _gnutls_set_datum (&pubkey[0],
1233 a[0].value, a[0].value_len);
1235 if (ret >= 0)
1236 ret =
1237 _gnutls_set_datum (&pubkey
1238 [1], a[1].value, a[1].value_len);
1240 if (ret < 0)
1242 gnutls_assert ();
1243 _gnutls_free_datum (&pubkey[1]);
1244 _gnutls_free_datum (&pubkey[0]);
1245 return GNUTLS_E_MEMORY_ERROR;
1248 else
1250 gnutls_assert ();
1251 return GNUTLS_E_PKCS11_ERROR;
1253 break;
1254 case CKK_DSA:
1255 a[0].type = CKA_PRIME;
1256 a[0].value = tmp1;
1257 a[0].value_len = sizeof (tmp1);
1258 a[1].type = CKA_SUBPRIME;
1259 a[1].value = tmp2;
1260 a[1].value_len = sizeof (tmp2);
1262 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1264 ret =
1265 _gnutls_set_datum (&pubkey[0],
1266 a[0].value, a[0].value_len);
1268 if (ret >= 0)
1269 ret =
1270 _gnutls_set_datum (&pubkey
1271 [1], a[1].value, a[1].value_len);
1273 if (ret < 0)
1275 gnutls_assert ();
1276 _gnutls_free_datum (&pubkey[1]);
1277 _gnutls_free_datum (&pubkey[0]);
1278 return GNUTLS_E_MEMORY_ERROR;
1281 else
1283 gnutls_assert ();
1284 return GNUTLS_E_PKCS11_ERROR;
1287 a[0].type = CKA_BASE;
1288 a[0].value = tmp1;
1289 a[0].value_len = sizeof (tmp1);
1290 a[1].type = CKA_VALUE;
1291 a[1].value = tmp2;
1292 a[1].value_len = sizeof (tmp2);
1294 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1296 ret =
1297 _gnutls_set_datum (&pubkey[2],
1298 a[0].value, a[0].value_len);
1300 if (ret >= 0)
1301 ret =
1302 _gnutls_set_datum (&pubkey
1303 [3], a[1].value, a[1].value_len);
1305 if (ret < 0)
1307 gnutls_assert ();
1308 _gnutls_free_datum (&pubkey[0]);
1309 _gnutls_free_datum (&pubkey[1]);
1310 _gnutls_free_datum (&pubkey[2]);
1311 _gnutls_free_datum (&pubkey[3]);
1312 return GNUTLS_E_MEMORY_ERROR;
1315 else
1317 gnutls_assert ();
1318 return GNUTLS_E_PKCS11_ERROR;
1320 break;
1321 case CKK_ECDSA:
1322 a[0].type = CKA_EC_PARAMS;
1323 a[0].value = tmp1;
1324 a[0].value_len = sizeof (tmp1);
1325 a[1].type = CKA_EC_POINT;
1326 a[1].value = tmp2;
1327 a[1].value_len = sizeof (tmp2);
1329 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1331 ret =
1332 _gnutls_set_datum (&pubkey[0],
1333 a[0].value, a[0].value_len);
1335 if (ret >= 0)
1336 ret =
1337 _gnutls_set_datum (&pubkey
1338 [1], a[1].value, a[1].value_len);
1340 if (ret < 0)
1342 gnutls_assert ();
1343 _gnutls_free_datum (&pubkey[1]);
1344 _gnutls_free_datum (&pubkey[0]);
1345 return GNUTLS_E_MEMORY_ERROR;
1348 else
1350 gnutls_assert ();
1351 return GNUTLS_E_PKCS11_ERROR;
1354 break;
1355 default:
1356 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1359 return 0;
1362 static int
1363 pkcs11_obj_import_pubkey (struct ck_function_list *module,
1364 ck_session_handle_t pks,
1365 ck_object_handle_t obj,
1366 gnutls_pkcs11_obj_t crt,
1367 const gnutls_datum_t * id,
1368 const gnutls_datum_t * label,
1369 struct ck_token_info *tinfo,
1370 struct ck_info *lib_info)
1372 struct ck_attribute a[4];
1373 ck_key_type_t key_type;
1374 int ret;
1375 ck_bool_t tval;
1377 a[0].type = CKA_KEY_TYPE;
1378 a[0].value = &key_type;
1379 a[0].value_len = sizeof (key_type);
1381 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1383 crt->pk_algorithm = mech_to_pk(key_type);
1385 ret = read_pkcs11_pubkey(module, pks, obj, key_type, crt->pubkey);
1386 if (ret < 0)
1387 return gnutls_assert_val(ret);
1390 /* read key usage flags */
1391 a[0].type = CKA_ENCRYPT;
1392 a[0].value = &tval;
1393 a[0].value_len = sizeof (tval);
1395 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1397 if (tval != 0)
1399 crt->key_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
1403 a[0].type = CKA_VERIFY;
1404 a[0].value = &tval;
1405 a[0].value_len = sizeof (tval);
1407 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1409 if (tval != 0)
1411 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1412 GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1413 | GNUTLS_KEY_NON_REPUDIATION;
1417 a[0].type = CKA_VERIFY_RECOVER;
1418 a[0].value = &tval;
1419 a[0].value_len = sizeof (tval);
1421 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1423 if (tval != 0)
1425 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1426 GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1427 | GNUTLS_KEY_NON_REPUDIATION;
1431 a[0].type = CKA_DERIVE;
1432 a[0].value = &tval;
1433 a[0].value_len = sizeof (tval);
1435 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1437 if (tval != 0)
1439 crt->key_usage |= GNUTLS_KEY_KEY_AGREEMENT;
1443 a[0].type = CKA_WRAP;
1444 a[0].value = &tval;
1445 a[0].value_len = sizeof (tval);
1447 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1449 if (tval != 0)
1451 crt->key_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
1455 return pkcs11_obj_import (CKO_PUBLIC_KEY, crt, NULL, id, label,
1456 tinfo, lib_info);
1459 static int
1460 find_obj_url (struct pkcs11_session_info *sinfo,
1461 struct token_info *info, struct ck_info *lib_info, void *input)
1463 struct url_find_data_st *find_data = input;
1464 struct ck_attribute a[4];
1465 struct ck_attribute *attr;
1466 ck_object_class_t class = -1;
1467 ck_certificate_type_t type = (ck_certificate_type_t)-1;
1468 ck_rv_t rv;
1469 ck_object_handle_t obj;
1470 unsigned long count, a_vals;
1471 int found = 0, ret;
1472 uint8_t *cert_data = NULL;
1473 char label_tmp[PKCS11_LABEL_SIZE];
1474 char id_tmp[PKCS11_ID_SIZE];
1476 if (info == NULL)
1477 { /* we don't support multiple calls */
1478 gnutls_assert ();
1479 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1482 /* do not bother reading the token if basic fields do not match
1484 if (!p11_kit_uri_match_token_info (find_data->crt->info, &info->tinfo) ||
1485 !p11_kit_uri_match_module_info (find_data->crt->info, lib_info))
1487 gnutls_assert ();
1488 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1491 a_vals = 0;
1492 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID);
1493 if (attr)
1495 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1496 a_vals++;
1499 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_LABEL);
1500 if (attr)
1502 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1503 a_vals++;
1506 if (!a_vals)
1508 gnutls_assert ();
1509 return GNUTLS_E_INVALID_REQUEST;
1512 /* search the token for the id */
1514 cert_data = gnutls_malloc (MAX_CERT_SIZE);
1515 if (cert_data == NULL)
1517 gnutls_assert ();
1518 return GNUTLS_E_MEMORY_ERROR;
1521 /* Find objects with given class and type */
1522 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_CLASS);
1523 if (attr)
1525 if(attr->value && attr->value_len == sizeof (ck_object_class_t))
1526 class = *((ck_object_class_t*)attr->value);
1527 if (class == CKO_CERTIFICATE)
1528 type = CKC_X_509;
1529 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1530 a_vals++;
1533 if (type != (ck_certificate_type_t)-1)
1535 a[a_vals].type = CKA_CERTIFICATE_TYPE;
1536 a[a_vals].value = &type;
1537 a[a_vals].value_len = sizeof type;
1538 a_vals++;
1541 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, a, a_vals);
1542 if (rv != CKR_OK)
1544 gnutls_assert ();
1545 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
1546 ret = pkcs11_rv_to_err (rv);
1547 goto cleanup;
1550 while (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
1553 a[0].type = CKA_VALUE;
1554 a[0].value = cert_data;
1555 a[0].value_len = MAX_CERT_SIZE;
1556 a[1].type = CKA_LABEL;
1557 a[1].value = label_tmp;
1558 a[1].value_len = sizeof (label_tmp);
1559 a[2].type = CKA_ID;
1560 a[2].value = id_tmp;
1561 a[2].value_len = sizeof(id_tmp);
1563 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 3) == CKR_OK)
1565 gnutls_datum_t id = { a[2].value, a[2].value_len };
1566 gnutls_datum_t data = { a[0].value, a[0].value_len };
1567 gnutls_datum_t label = { a[1].value, a[1].value_len };
1569 if (class == CKO_PUBLIC_KEY)
1571 ret =
1572 pkcs11_obj_import_pubkey (sinfo->module, sinfo->pks, obj,
1573 find_data->crt,
1574 &id, &label,
1575 &info->tinfo, lib_info);
1577 else
1579 ret =
1580 pkcs11_obj_import (class,
1581 find_data->crt,
1582 &data, &id, &label,
1583 &info->tinfo, lib_info);
1585 if (ret < 0)
1587 gnutls_assert ();
1588 goto cleanup;
1591 found = 1;
1592 break;
1594 else
1596 _gnutls_debug_log ("pk11: Skipped cert, missing attrs.\n");
1600 if (found == 0)
1602 gnutls_assert ();
1603 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1605 else
1607 ret = 0;
1610 cleanup:
1611 gnutls_free (cert_data);
1612 pkcs11_find_objects_final (sinfo);
1614 return ret;
1617 unsigned int
1618 pkcs11_obj_flags_to_int (unsigned int flags)
1620 unsigned int ret_flags = 0;
1622 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN)
1623 ret_flags |= SESSION_LOGIN;
1624 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO)
1625 ret_flags |= SESSION_LOGIN|SESSION_SO;
1627 return ret_flags;
1631 * gnutls_pkcs11_obj_import_url:
1632 * @obj: The structure to store the object
1633 * @url: a PKCS 11 url identifying the key
1634 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1636 * This function will "import" a PKCS 11 URL identifying an object (e.g. certificate)
1637 * to the #gnutls_pkcs11_obj_t structure. This does not involve any
1638 * parsing (such as X.509 or OpenPGP) since the #gnutls_pkcs11_obj_t is
1639 * format agnostic. Only data are transferred.
1641 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1642 * negative error value.
1644 * Since: 2.12.0
1647 gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t obj, const char *url,
1648 unsigned int flags)
1650 int ret;
1651 struct url_find_data_st find_data;
1653 /* fill in the find data structure */
1654 find_data.crt = obj;
1656 ret = pkcs11_url_to_info (url, &obj->info);
1657 if (ret < 0)
1659 gnutls_assert ();
1660 return ret;
1663 ret =
1664 _pkcs11_traverse_tokens (find_obj_url, &find_data, obj->info,
1665 &obj->pin, pkcs11_obj_flags_to_int (flags));
1667 if (ret < 0)
1669 gnutls_assert ();
1670 return ret;
1673 return 0;
1676 struct token_num
1678 struct p11_kit_uri *info;
1679 unsigned int seq; /* which one we are looking for */
1680 unsigned int current; /* which one are we now */
1683 static int
1684 find_token_num (struct pkcs11_session_info* sinfo,
1685 struct token_info *tinfo,
1686 struct ck_info *lib_info, void *input)
1688 struct token_num *find_data = input;
1690 if (tinfo == NULL)
1691 { /* we don't support multiple calls */
1692 gnutls_assert ();
1693 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1696 if (find_data->current == find_data->seq)
1698 memcpy (p11_kit_uri_get_token_info (find_data->info), &tinfo->tinfo, sizeof (struct ck_token_info));
1699 memcpy (p11_kit_uri_get_module_info (find_data->info), lib_info, sizeof (struct ck_info));
1700 return 0;
1703 find_data->current++;
1704 /* search the token for the id */
1707 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* non zero is enough */
1711 * gnutls_pkcs11_token_get_url:
1712 * @seq: sequence number starting from 0
1713 * @detailed: non zero if a detailed URL is required
1714 * @url: will contain an allocated url
1716 * This function will return the URL for each token available
1717 * in system. The url has to be released using gnutls_free()
1719 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1720 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if the sequence number
1721 * exceeds the available tokens, otherwise a negative error value.
1723 * Since: 2.12.0
1726 gnutls_pkcs11_token_get_url (unsigned int seq,
1727 gnutls_pkcs11_url_type_t detailed, char **url)
1729 int ret;
1730 struct token_num tn;
1732 memset (&tn, 0, sizeof (tn));
1733 tn.seq = seq;
1734 tn.info = p11_kit_uri_new ();
1736 ret = _pkcs11_traverse_tokens (find_token_num, &tn, NULL, NULL, 0);
1737 if (ret < 0)
1739 p11_kit_uri_free (tn.info);
1740 gnutls_assert ();
1741 return ret;
1744 ret = pkcs11_info_to_url (tn.info, detailed, url);
1745 p11_kit_uri_free (tn.info);
1747 if (ret < 0)
1749 gnutls_assert ();
1750 return ret;
1753 return 0;
1758 * gnutls_pkcs11_token_get_info:
1759 * @url: should contain a PKCS 11 URL
1760 * @ttype: Denotes the type of information requested
1761 * @output: where output will be stored
1762 * @output_size: contains the maximum size of the output and will be overwritten with actual
1764 * This function will return information about the PKCS 11 token such
1765 * as the label, id, etc.
1767 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code
1768 * on error.
1770 * Since: 2.12.0
1773 gnutls_pkcs11_token_get_info (const char *url,
1774 gnutls_pkcs11_token_info_t ttype,
1775 void *output, size_t * output_size)
1777 struct p11_kit_uri *info = NULL;
1778 const uint8_t *str;
1779 size_t str_max;
1780 size_t len;
1781 int ret;
1783 ret = pkcs11_url_to_info (url, &info);
1784 if (ret < 0)
1786 gnutls_assert ();
1787 return ret;
1790 switch (ttype)
1792 case GNUTLS_PKCS11_TOKEN_LABEL:
1793 str = p11_kit_uri_get_token_info (info)->label;
1794 str_max = 32;
1795 break;
1796 case GNUTLS_PKCS11_TOKEN_SERIAL:
1797 str = p11_kit_uri_get_token_info (info)->serial_number;
1798 str_max = 16;
1799 break;
1800 case GNUTLS_PKCS11_TOKEN_MANUFACTURER:
1801 str = p11_kit_uri_get_token_info (info)->manufacturer_id;
1802 str_max = 32;
1803 break;
1804 case GNUTLS_PKCS11_TOKEN_MODEL:
1805 str = p11_kit_uri_get_token_info (info)->model;
1806 str_max = 16;
1807 break;
1808 default:
1809 p11_kit_uri_free (info);
1810 gnutls_assert ();
1811 return GNUTLS_E_INVALID_REQUEST;
1814 len = p11_kit_space_strlen (str, str_max);
1816 if (len + 1 > *output_size)
1818 *output_size = len + 1;
1819 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1822 memcpy (output, str, len);
1823 ((char*)output)[len] = '\0';
1825 *output_size = len;
1827 p11_kit_uri_free (info);
1828 return 0;
1832 * gnutls_pkcs11_obj_export_url:
1833 * @obj: Holds the PKCS 11 certificate
1834 * @detailed: non zero if a detailed URL is required
1835 * @url: will contain an allocated url
1837 * This function will export a URL identifying the given certificate.
1839 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1840 * negative error value.
1842 * Since: 2.12.0
1845 gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t obj,
1846 gnutls_pkcs11_url_type_t detailed, char **url)
1848 int ret;
1850 ret = pkcs11_info_to_url (obj->info, detailed, url);
1851 if (ret < 0)
1853 gnutls_assert ();
1854 return ret;
1857 return 0;
1861 * gnutls_pkcs11_obj_get_type:
1862 * @obj: Holds the PKCS 11 object
1864 * This function will return the type of the certificate being
1865 * stored in the structure.
1867 * Returns: The type of the certificate.
1869 * Since: 2.12.0
1871 gnutls_pkcs11_obj_type_t
1872 gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t obj)
1874 return obj->type;
1877 struct pkey_list
1879 gnutls_buffer_st *key_ids;
1880 size_t key_ids_size;
1884 static int
1885 retrieve_pin_from_source (const char *pinfile, struct ck_token_info *token_info,
1886 int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
1888 unsigned int flags = 0;
1889 struct p11_kit_uri *token_uri;
1890 struct p11_kit_pin *result;
1891 char *label;
1893 label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1894 if (label == NULL)
1896 gnutls_assert ();
1897 return GNUTLS_E_MEMORY_ERROR;
1900 token_uri = p11_kit_uri_new ();
1901 if (token_uri == NULL)
1903 free (label);
1904 gnutls_assert ();
1905 return GNUTLS_E_MEMORY_ERROR;
1908 memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1909 sizeof (struct ck_token_info));
1911 if (attempts)
1912 flags |= P11_KIT_PIN_FLAGS_RETRY;
1913 if (user_type == CKU_USER)
1915 flags |= P11_KIT_PIN_FLAGS_USER_LOGIN;
1916 if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1917 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1918 if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1919 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1921 else if (user_type == CKU_SO)
1923 flags |= P11_KIT_PIN_FLAGS_SO_LOGIN;
1924 if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
1925 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1926 if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
1927 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1929 else if (user_type == CKU_CONTEXT_SPECIFIC)
1931 flags |= P11_KIT_PIN_FLAGS_CONTEXT_LOGIN;
1934 result = p11_kit_pin_request (pinfile, token_uri, label, flags);
1935 p11_kit_uri_free (token_uri);
1936 free (label);
1938 if (result == NULL)
1940 gnutls_assert ();
1941 return GNUTLS_E_PKCS11_PIN_ERROR;
1944 *pin = result;
1945 return 0;
1948 static int
1949 retrieve_pin_from_callback (const struct pin_info_st *pin_info,
1950 struct ck_token_info *token_info,
1951 int attempts, ck_user_type_t user_type,
1952 struct p11_kit_pin **pin)
1954 char pin_value[GNUTLS_PKCS11_MAX_PIN_LEN];
1955 unsigned int flags = 0;
1956 char *token_str;
1957 char *label;
1958 struct p11_kit_uri *token_uri;
1959 int ret = 0;
1961 label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1962 if (label == NULL)
1964 gnutls_assert ();
1965 return GNUTLS_E_MEMORY_ERROR;
1968 token_uri = p11_kit_uri_new ();
1969 if (token_uri == NULL)
1971 free (label);
1972 gnutls_assert ();
1973 return GNUTLS_E_MEMORY_ERROR;
1976 memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1977 sizeof (struct ck_token_info));
1978 ret = pkcs11_info_to_url (token_uri, 1, &token_str);
1979 p11_kit_uri_free (token_uri);
1981 if (ret < 0)
1983 free (label);
1984 gnutls_assert ();
1985 return GNUTLS_E_MEMORY_ERROR;
1988 if (user_type == CKU_USER)
1990 flags |= GNUTLS_PKCS11_PIN_USER;
1991 if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1992 flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
1993 if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1994 flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
1996 else if (user_type == CKU_SO)
1998 flags |= GNUTLS_PKCS11_PIN_SO;
1999 if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
2000 flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
2001 if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
2002 flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
2005 if (attempts > 0)
2006 flags |= GNUTLS_PKCS11_PIN_WRONG;
2008 if (pin_info && pin_info->cb)
2009 ret = pin_info->cb (pin_info->data, attempts, (char*)token_str, label,
2010 flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
2011 else if (_gnutls_pin_func)
2012 ret = _gnutls_pin_func (_gnutls_pin_data, attempts, (char*)token_str, label,
2013 flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
2014 else
2015 ret = gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR);
2017 free (token_str);
2018 free (label);
2020 if (ret < 0)
2021 return gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR);
2023 *pin = p11_kit_pin_new_for_string (pin_value);
2025 if (*pin == NULL)
2026 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2028 return 0;
2031 static int
2032 retrieve_pin (struct pin_info_st* pin_info, struct p11_kit_uri *info,
2033 struct ck_token_info *token_info, int attempts,
2034 ck_user_type_t user_type, struct p11_kit_pin **pin)
2036 const char *pinfile;
2037 int ret = GNUTLS_E_PKCS11_PIN_ERROR;
2039 *pin = NULL;
2041 /* Check if a pinfile is specified, and use that if possible */
2042 pinfile = p11_kit_uri_get_pinfile (info);
2043 if (pinfile != NULL)
2045 _gnutls_debug_log("pk11: Using pinfile to retrieve PIN\n");
2046 ret = retrieve_pin_from_source (pinfile, token_info, attempts, user_type, pin);
2049 /* The global gnutls pin callback */
2050 if (ret < 0)
2051 ret = retrieve_pin_from_callback (pin_info, token_info, attempts, user_type, pin);
2053 /* Otherwise, PIN entry is necessary for login, so fail if there's
2054 * no callback. */
2056 if (ret < 0)
2058 gnutls_assert ();
2059 _gnutls_debug_log ("pk11: No suitable pin callback but login required.\n");
2062 return ret;
2066 pkcs11_login (struct pkcs11_session_info * sinfo, struct pin_info_st * pin_info,
2067 const struct token_info *tokinfo, struct p11_kit_uri *info, int so)
2069 struct ck_session_info session_info;
2070 int attempt = 0, ret;
2071 ck_user_type_t user_type;
2072 ck_rv_t rv;
2074 user_type = (so == 0) ? CKU_USER : CKU_SO;
2075 if (so == 0 && (tokinfo->tinfo.flags & CKF_LOGIN_REQUIRED) == 0)
2077 gnutls_assert ();
2078 _gnutls_debug_log ("pk11: No login required.\n");
2079 return 0;
2082 /* For a token with a "protected" (out-of-band) authentication
2083 * path, calling login with a NULL username is all that is
2084 * required. */
2085 if (tokinfo->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
2087 rv = (sinfo->module)->C_Login (sinfo->pks, (so == 0) ? CKU_USER : CKU_SO, NULL, 0);
2088 if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
2090 return 0;
2092 else
2094 gnutls_assert ();
2095 _gnutls_debug_log ("pk11: Protected login failed.\n");
2096 ret = GNUTLS_E_PKCS11_ERROR;
2097 goto cleanup;
2103 struct p11_kit_pin *pin;
2104 struct ck_token_info tinfo;
2106 memcpy (&tinfo, &tokinfo->tinfo, sizeof(tinfo));
2108 /* Check whether the session is already logged in, and if so, just skip */
2109 rv = (sinfo->module)->C_GetSessionInfo (sinfo->pks, &session_info);
2110 if (rv == CKR_OK && (session_info.state == CKS_RO_USER_FUNCTIONS ||
2111 session_info.state == CKS_RW_USER_FUNCTIONS))
2113 ret = 0;
2114 goto cleanup;
2117 /* If login has been attempted once already, check the token
2118 * status again, the flags might change. */
2119 if (attempt)
2121 if (pkcs11_get_token_info
2122 (tokinfo->prov->module, tokinfo->sid, &tinfo) != CKR_OK)
2124 gnutls_assert ();
2125 _gnutls_debug_log ("pk11: GetTokenInfo failed\n");
2126 ret = GNUTLS_E_PKCS11_ERROR;
2127 goto cleanup;
2131 ret = retrieve_pin (pin_info, info, &tinfo, attempt++, user_type, &pin);
2132 if (ret < 0)
2134 gnutls_assert ();
2135 goto cleanup;
2138 rv = (sinfo->module)->C_Login (sinfo->pks, user_type,
2139 (unsigned char *)p11_kit_pin_get_value (pin, NULL),
2140 p11_kit_pin_get_length (pin));
2142 p11_kit_pin_unref (pin);
2144 while (rv == CKR_PIN_INCORRECT);
2146 _gnutls_debug_log ("pk11: Login result = %lu\n", rv);
2149 ret = (rv == CKR_OK
2150 || rv == CKR_USER_ALREADY_LOGGED_IN) ? 0 : pkcs11_rv_to_err (rv);
2152 cleanup:
2153 return ret;
2157 pkcs11_call_token_func (struct p11_kit_uri *info, const unsigned retry)
2159 struct ck_token_info *tinfo;
2160 char *label;
2161 int ret = 0;
2163 tinfo = p11_kit_uri_get_token_info (info);
2164 label = p11_kit_space_strdup (tinfo->label, sizeof (tinfo->label));
2165 ret = (_gnutls_token_func) (_gnutls_token_data, label, retry);
2166 free (label);
2168 return ret;
2172 static int
2173 find_privkeys (struct pkcs11_session_info* sinfo,
2174 struct token_info *info, struct pkey_list *list)
2176 struct ck_attribute a[3];
2177 ck_object_class_t class;
2178 ck_rv_t rv;
2179 ck_object_handle_t obj;
2180 unsigned long count, current;
2181 char certid_tmp[PKCS11_ID_SIZE];
2183 class = CKO_PRIVATE_KEY;
2185 /* Find an object with private key class and a certificate ID
2186 * which matches the certificate. */
2187 /* FIXME: also match the cert subject. */
2188 a[0].type = CKA_CLASS;
2189 a[0].value = &class;
2190 a[0].value_len = sizeof class;
2192 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, a, 1);
2193 if (rv != CKR_OK)
2195 gnutls_assert ();
2196 return pkcs11_rv_to_err (rv);
2199 list->key_ids_size = 0;
2200 while (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
2202 list->key_ids_size++;
2205 pkcs11_find_objects_final (sinfo);
2207 if (list->key_ids_size == 0)
2209 gnutls_assert ();
2210 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2213 list->key_ids =
2214 gnutls_malloc (sizeof (gnutls_buffer_st) * list->key_ids_size);
2215 if (list->key_ids == NULL)
2217 gnutls_assert ();
2218 return GNUTLS_E_MEMORY_ERROR;
2221 /* actual search */
2222 a[0].type = CKA_CLASS;
2223 a[0].value = &class;
2224 a[0].value_len = sizeof class;
2226 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, a, 1);
2227 if (rv != CKR_OK)
2229 gnutls_assert ();
2230 return pkcs11_rv_to_err (rv);
2233 current = 0;
2234 while (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
2237 a[0].type = CKA_ID;
2238 a[0].value = certid_tmp;
2239 a[0].value_len = sizeof (certid_tmp);
2241 _gnutls_buffer_init (&list->key_ids[current]);
2243 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1) == CKR_OK)
2245 _gnutls_buffer_append_data (&list->key_ids[current],
2246 a[0].value, a[0].value_len);
2247 current++;
2250 if (current > list->key_ids_size)
2251 break;
2254 pkcs11_find_objects_final (sinfo);
2256 list->key_ids_size = current - 1;
2258 return 0;
2261 /* Recover certificate list from tokens */
2264 static int
2265 find_objs (struct pkcs11_session_info* sinfo,
2266 struct token_info *info, struct ck_info *lib_info, void *input)
2268 struct crt_find_data_st *find_data = input;
2269 struct ck_attribute a[4];
2270 struct ck_attribute *attr;
2271 ck_object_class_t class = (ck_object_class_t)-1;
2272 ck_certificate_type_t type = (ck_certificate_type_t)-1;
2273 unsigned int trusted;
2274 ck_rv_t rv;
2275 ck_object_handle_t obj;
2276 unsigned long count;
2277 uint8_t *cert_data;
2278 char certid_tmp[PKCS11_ID_SIZE];
2279 char label_tmp[PKCS11_LABEL_SIZE];
2280 int ret;
2281 struct pkey_list plist; /* private key holder */
2282 unsigned int i, tot_values = 0;
2284 if (info == NULL)
2285 { /* final call */
2286 if (find_data->current <= *find_data->n_list)
2287 ret = 0;
2288 else
2289 ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
2291 *find_data->n_list = find_data->current;
2293 return ret;
2296 /* do not bother reading the token if basic fields do not match
2298 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2299 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2301 gnutls_assert ();
2302 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2305 memset (&plist, 0, sizeof (plist));
2307 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2309 ret = find_privkeys (sinfo, info, &plist);
2310 if (ret < 0)
2312 gnutls_assert ();
2313 return ret;
2316 if (plist.key_ids_size == 0)
2318 gnutls_assert ();
2319 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2323 cert_data = gnutls_malloc (MAX_CERT_SIZE);
2324 if (cert_data == NULL)
2326 gnutls_assert ();
2327 return GNUTLS_E_MEMORY_ERROR;
2330 /* Find objects with cert class and X.509 cert type. */
2332 tot_values = 0;
2334 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL
2335 || find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2337 class = CKO_CERTIFICATE;
2338 type = CKC_X_509;
2339 trusted = 1;
2341 a[tot_values].type = CKA_CLASS;
2342 a[tot_values].value = &class;
2343 a[tot_values].value_len = sizeof class;
2344 tot_values++;
2346 a[tot_values].type = CKA_CERTIFICATE_TYPE;
2347 a[tot_values].value = &type;
2348 a[tot_values].value_len = sizeof type;
2349 tot_values++;
2352 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED)
2354 class = CKO_CERTIFICATE;
2355 type = CKC_X_509;
2356 trusted = 1;
2358 a[tot_values].type = CKA_CLASS;
2359 a[tot_values].value = &class;
2360 a[tot_values].value_len = sizeof class;
2361 tot_values++;
2363 a[tot_values].type = CKA_TRUSTED;
2364 a[tot_values].value = &trusted;
2365 a[tot_values].value_len = sizeof trusted;
2366 tot_values++;
2369 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PUBKEY)
2371 class = CKO_PUBLIC_KEY;
2373 a[tot_values].type = CKA_CLASS;
2374 a[tot_values].value = &class;
2375 a[tot_values].value_len = sizeof class;
2376 tot_values++;
2378 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
2380 class = CKO_PRIVATE_KEY;
2382 a[tot_values].type = CKA_CLASS;
2383 a[tot_values].value = &class;
2384 a[tot_values].value_len = sizeof class;
2385 tot_values++;
2387 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2389 if (class != (ck_object_class_t)-1)
2391 a[tot_values].type = CKA_CLASS;
2392 a[tot_values].value = &class;
2393 a[tot_values].value_len = sizeof class;
2394 tot_values++;
2396 if (type != (ck_certificate_type_t)-1)
2398 a[tot_values].type = CKA_CERTIFICATE_TYPE;
2399 a[tot_values].value = &type;
2400 a[tot_values].value_len = sizeof type;
2401 tot_values++;
2404 else
2406 gnutls_assert ();
2407 ret = GNUTLS_E_INVALID_REQUEST;
2408 goto fail;
2411 attr = p11_kit_uri_get_attribute (find_data->info, CKA_ID);
2412 if (attr != NULL)
2414 memcpy (a + tot_values, attr, sizeof (struct ck_attribute));
2415 tot_values++;
2418 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, a, tot_values);
2419 if (rv != CKR_OK)
2421 gnutls_assert ();
2422 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
2423 return pkcs11_rv_to_err (rv);
2426 while (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
2428 gnutls_datum_t label, id, value;
2430 a[0].type = CKA_LABEL;
2431 a[0].value = label_tmp;
2432 a[0].value_len = sizeof label_tmp;
2434 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1) == CKR_OK)
2436 label.data = a[0].value;
2437 label.size = a[0].value_len;
2439 else
2441 label.data = NULL;
2442 label.size = 0;
2445 a[0].type = CKA_ID;
2446 a[0].value = certid_tmp;
2447 a[0].value_len = sizeof certid_tmp;
2449 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1) == CKR_OK)
2451 id.data = a[0].value;
2452 id.size = a[0].value_len;
2454 else
2456 id.data = NULL;
2457 id.size = 0;
2460 a[0].type = CKA_VALUE;
2461 a[0].value = cert_data;
2462 a[0].value_len = MAX_CERT_SIZE;
2463 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1) == CKR_OK)
2465 value.data = a[0].value;
2466 value.size = a[0].value_len;
2468 else
2470 value.data = NULL;
2471 value.size = 0;
2474 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2476 a[0].type = CKA_CLASS;
2477 a[0].value = &class;
2478 a[0].value_len = sizeof class;
2480 pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1);
2483 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2485 for (i = 0; i < plist.key_ids_size; i++)
2487 if (plist.key_ids[i].length !=
2488 a[1].value_len
2489 || memcmp (plist.key_ids[i].data,
2490 a[1].value, a[1].value_len) != 0)
2492 /* not found */
2493 continue;
2498 if (find_data->current < *find_data->n_list)
2500 ret =
2501 gnutls_pkcs11_obj_init (&find_data->p_list[find_data->current]);
2502 if (ret < 0)
2504 gnutls_assert ();
2505 goto fail;
2508 if (class == CKO_PUBLIC_KEY)
2510 ret =
2511 pkcs11_obj_import_pubkey (sinfo->module, sinfo->pks, obj,
2512 find_data->p_list
2513 [find_data->current],
2514 &id, &label,
2515 &info->tinfo, lib_info);
2517 else
2519 ret =
2520 pkcs11_obj_import (class,
2521 find_data->p_list
2522 [find_data->current],
2523 &value, &id, &label,
2524 &info->tinfo, lib_info);
2526 if (ret < 0)
2528 gnutls_assert ();
2529 goto fail;
2533 find_data->current++;
2537 gnutls_free (cert_data);
2538 pkcs11_find_objects_final (sinfo);
2540 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* continue until all tokens have been checked */
2542 fail:
2543 gnutls_free (cert_data);
2544 pkcs11_find_objects_final (sinfo);
2545 if (plist.key_ids != NULL)
2547 for (i = 0; i < plist.key_ids_size; i++)
2549 _gnutls_buffer_clear (&plist.key_ids[i]);
2551 gnutls_free (plist.key_ids);
2553 for (i = 0; i < find_data->current; i++)
2555 gnutls_pkcs11_obj_deinit (find_data->p_list[i]);
2557 find_data->current = 0;
2559 return ret;
2563 * gnutls_pkcs11_obj_list_import_url:
2564 * @p_list: An uninitialized object list (may be NULL)
2565 * @n_list: initially should hold the maximum size of the list. Will contain the actual size.
2566 * @url: A PKCS 11 url identifying a set of objects
2567 * @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
2568 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2570 * This function will initialize and set values to an object list
2571 * by using all objects identified by a PKCS 11 URL.
2573 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2574 * negative error value.
2576 * Since: 2.12.0
2579 gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list,
2580 unsigned int *n_list,
2581 const char *url,
2582 gnutls_pkcs11_obj_attr_t attrs,
2583 unsigned int flags)
2585 int ret;
2586 struct crt_find_data_st find_data;
2588 memset (&find_data, 0, sizeof (find_data));
2590 /* fill in the find data structure */
2591 find_data.p_list = p_list;
2592 find_data.n_list = n_list;
2593 find_data.flags = attrs;
2594 find_data.current = 0;
2596 if (url == NULL || url[0] == 0)
2598 url = "pkcs11:";
2601 ret = pkcs11_url_to_info (url, &find_data.info);
2602 if (ret < 0)
2604 gnutls_assert ();
2605 return ret;
2608 ret =
2609 _pkcs11_traverse_tokens (find_objs, &find_data, find_data.info,
2610 NULL,
2611 pkcs11_obj_flags_to_int (flags));
2612 p11_kit_uri_free (find_data.info);
2614 if (ret < 0)
2616 gnutls_assert ();
2617 return ret;
2620 return 0;
2624 * gnutls_pkcs11_obj_list_import_url2:
2625 * @p_list: An uninitialized object list (may be NULL)
2626 * @n_list: It will contain the size of the list.
2627 * @url: A PKCS 11 url identifying a set of objects
2628 * @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
2629 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2631 * This function will initialize and set values to an object list
2632 * by using all objects identified by the PKCS 11 URL. The output
2633 * is stored in @p_list, which will be initialized.
2635 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2636 * negative error value.
2638 * Since: 3.1.0
2641 gnutls_pkcs11_obj_list_import_url2 (gnutls_pkcs11_obj_t ** p_list,
2642 unsigned int *n_list,
2643 const char *url,
2644 gnutls_pkcs11_obj_attr_t attrs,
2645 unsigned int flags)
2647 unsigned int init = 1024;
2648 int ret;
2650 *p_list = gnutls_malloc(sizeof(gnutls_pkcs11_obj_t)*init);
2651 if (*p_list == NULL)
2653 gnutls_assert();
2654 return GNUTLS_E_MEMORY_ERROR;
2657 ret = gnutls_pkcs11_obj_list_import_url( *p_list, &init, url, attrs, flags);
2658 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
2660 *p_list = gnutls_realloc_fast(*p_list, sizeof(gnutls_pkcs11_obj_t)*init);
2661 if (*p_list == NULL)
2662 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2664 ret = gnutls_pkcs11_obj_list_import_url( *p_list, &init, url, attrs, flags);
2667 if (ret < 0)
2669 gnutls_assert();
2670 gnutls_free(*p_list);
2671 *p_list = NULL;
2672 return ret;
2675 *n_list = init;
2676 return 0;
2681 * gnutls_x509_crt_import_pkcs11_url:
2682 * @crt: A certificate of type #gnutls_x509_crt_t
2683 * @url: A PKCS 11 url
2684 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2686 * This function will import a PKCS 11 certificate directly from a token
2687 * without involving the #gnutls_pkcs11_obj_t structure. This function will
2688 * fail if the certificate stored is not of X.509 type.
2690 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2691 * negative error value.
2693 * Since: 2.12.0
2696 gnutls_x509_crt_import_pkcs11_url (gnutls_x509_crt_t crt,
2697 const char *url, unsigned int flags)
2699 gnutls_pkcs11_obj_t pcrt;
2700 int ret;
2702 ret = gnutls_pkcs11_obj_init (&pcrt);
2703 if (ret < 0)
2705 gnutls_assert ();
2706 return ret;
2709 if (crt->pin.cb)
2710 gnutls_pkcs11_obj_set_pin_function (pcrt, crt->pin.cb, crt->pin.data);
2712 ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
2713 if (ret < 0)
2715 gnutls_assert ();
2716 goto cleanup;
2719 ret = gnutls_x509_crt_import (crt, &pcrt->raw, GNUTLS_X509_FMT_DER);
2720 if (ret < 0)
2722 gnutls_assert ();
2723 goto cleanup;
2726 ret = 0;
2727 cleanup:
2729 gnutls_pkcs11_obj_deinit (pcrt);
2731 return ret;
2735 * gnutls_x509_crt_import_pkcs11:
2736 * @crt: A certificate of type #gnutls_x509_crt_t
2737 * @pkcs11_crt: A PKCS 11 object that contains a certificate
2739 * This function will import a PKCS 11 certificate to a #gnutls_x509_crt_t
2740 * structure.
2742 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2743 * negative error value.
2745 * Since: 2.12.0
2748 gnutls_x509_crt_import_pkcs11 (gnutls_x509_crt_t crt,
2749 gnutls_pkcs11_obj_t pkcs11_crt)
2751 return gnutls_x509_crt_import (crt, &pkcs11_crt->raw, GNUTLS_X509_FMT_DER);
2755 * gnutls_x509_crt_list_import_pkcs11:
2756 * @certs: A list of certificates of type #gnutls_x509_crt_t
2757 * @cert_max: The maximum size of the list
2758 * @objs: A list of PKCS 11 objects
2759 * @flags: 0 for now
2761 * This function will import a PKCS 11 certificate list to a list of
2762 * #gnutls_x509_crt_t structure. These must not be initialized.
2764 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2765 * negative error value.
2767 * Since: 2.12.0
2770 gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
2771 unsigned int cert_max,
2772 gnutls_pkcs11_obj_t * const objs,
2773 unsigned int flags)
2775 unsigned int i, j;
2776 int ret;
2778 for (i = 0; i < cert_max; i++)
2780 ret = gnutls_x509_crt_init (&certs[i]);
2781 if (ret < 0)
2783 gnutls_assert ();
2784 goto cleanup;
2787 ret = gnutls_x509_crt_import_pkcs11 (certs[i], objs[i]);
2788 if (ret < 0)
2790 gnutls_assert ();
2791 goto cleanup;
2795 return 0;
2797 cleanup:
2798 for (j = 0; j < i; j++)
2800 gnutls_x509_crt_deinit (certs[j]);
2803 return ret;
2806 static int
2807 find_flags (struct pkcs11_session_info* sinfo,
2808 struct token_info *info, struct ck_info *lib_info, void *input)
2810 struct flags_find_data_st *find_data = input;
2812 if (info == NULL)
2813 { /* we don't support multiple calls */
2814 gnutls_assert ();
2815 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2818 /* do not bother reading the token if basic fields do not match
2820 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2821 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2823 gnutls_assert ();
2824 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2827 /* found token! */
2829 find_data->slot_flags = info->sinfo.flags;
2831 return 0;
2835 * gnutls_pkcs11_token_get_flags:
2836 * @url: should contain a PKCS 11 URL
2837 * @flags: The output flags (GNUTLS_PKCS11_TOKEN_*)
2839 * This function will return information about the PKCS 11 token flags.
2840 * The flags from the %gnutls_pkcs11_token_info_t enumeration.
2842 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
2844 * Since: 2.12.0
2847 gnutls_pkcs11_token_get_flags (const char *url, unsigned int *flags)
2849 struct flags_find_data_st find_data;
2850 int ret;
2852 memset (&find_data, 0, sizeof (find_data));
2853 ret = pkcs11_url_to_info (url, &find_data.info);
2854 if (ret < 0)
2856 gnutls_assert ();
2857 return ret;
2860 ret = _pkcs11_traverse_tokens (find_flags, &find_data, find_data.info, NULL, 0);
2861 p11_kit_uri_free (find_data.info);
2863 if (ret < 0)
2865 gnutls_assert ();
2866 return ret;
2869 *flags = 0;
2870 if (find_data.slot_flags & CKF_HW_SLOT)
2871 *flags |= GNUTLS_PKCS11_TOKEN_HW;
2873 return 0;
2878 * gnutls_pkcs11_token_get_mechanism:
2879 * @url: should contain a PKCS 11 URL
2880 * @idx: The index of the mechanism
2881 * @mechanism: The PKCS #11 mechanism ID
2883 * This function will return the names of the supported mechanisms
2884 * by the token. It should be called with an increasing index until
2885 * it return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.
2887 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
2889 * Since: 2.12.0
2892 gnutls_pkcs11_token_get_mechanism (const char *url, unsigned int idx,
2893 unsigned long *mechanism)
2895 int ret;
2896 ck_rv_t rv;
2897 struct ck_function_list *module;
2898 ck_slot_id_t slot;
2899 struct token_info tinfo;
2900 struct p11_kit_uri *info = NULL;
2901 unsigned long count;
2902 ck_mechanism_type_t mlist[400];
2904 ret = pkcs11_url_to_info (url, &info);
2905 if (ret < 0)
2907 gnutls_assert ();
2908 return ret;
2912 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
2913 p11_kit_uri_free (info);
2915 if (ret < 0)
2917 gnutls_assert ();
2918 return ret;
2921 count = sizeof (mlist) / sizeof (mlist[0]);
2922 rv = pkcs11_get_mechanism_list (module, slot, mlist, &count);
2923 if (rv != CKR_OK)
2925 gnutls_assert ();
2926 return pkcs11_rv_to_err (rv);
2929 if (idx >= count)
2931 gnutls_assert ();
2932 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2935 *mechanism = mlist[idx];
2937 return 0;
2942 * gnutls_pkcs11_type_get_name:
2943 * @type: Holds the PKCS 11 object type, a #gnutls_pkcs11_obj_type_t.
2945 * This function will return a human readable description of the
2946 * PKCS11 object type @obj. It will return "Unknown" for unknown
2947 * types.
2949 * Returns: human readable string labeling the PKCS11 object type
2950 * @type.
2952 * Since: 2.12.0
2954 const char *
2955 gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t type)
2957 switch (type)
2959 case GNUTLS_PKCS11_OBJ_X509_CRT:
2960 return "X.509 Certificate";
2961 case GNUTLS_PKCS11_OBJ_PUBKEY:
2962 return "Public key";
2963 case GNUTLS_PKCS11_OBJ_PRIVKEY:
2964 return "Private key";
2965 case GNUTLS_PKCS11_OBJ_SECRET_KEY:
2966 return "Secret key";
2967 case GNUTLS_PKCS11_OBJ_DATA:
2968 return "Data";
2969 case GNUTLS_PKCS11_OBJ_UNKNOWN:
2970 default:
2971 return "Unknown";
2975 ck_rv_t
2976 pkcs11_get_slot_list (struct ck_function_list * module, unsigned char token_present,
2977 ck_slot_id_t *slot_list, unsigned long *count)
2979 return (module)->C_GetSlotList (token_present, slot_list, count);
2982 ck_rv_t
2983 pkcs11_get_module_info (struct ck_function_list * module,
2984 struct ck_info * info)
2986 return (module)->C_GetInfo (info);
2989 ck_rv_t
2990 pkcs11_get_slot_info(struct ck_function_list * module,
2991 ck_slot_id_t slot_id,
2992 struct ck_slot_info *info)
2994 return (module)->C_GetSlotInfo (slot_id, info);
2997 ck_rv_t
2998 pkcs11_get_token_info (struct ck_function_list * module,
2999 ck_slot_id_t slot_id,
3000 struct ck_token_info *info)
3002 return (module)->C_GetTokenInfo (slot_id, info);
3005 ck_rv_t
3006 pkcs11_find_objects_init (struct ck_function_list *module,
3007 ck_session_handle_t sess,
3008 struct ck_attribute *templ,
3009 unsigned long count)
3011 return (module)->C_FindObjectsInit (sess, templ, count);
3014 ck_rv_t
3015 pkcs11_find_objects (struct ck_function_list *module,
3016 ck_session_handle_t sess,
3017 ck_object_handle_t *objects,
3018 unsigned long max_object_count,
3019 unsigned long *object_count)
3021 return (module)->C_FindObjects (sess, objects, max_object_count, object_count);
3024 ck_rv_t
3025 pkcs11_find_objects_final (struct pkcs11_session_info* sinfo)
3027 return (sinfo->module)->C_FindObjectsFinal (sinfo->pks);
3030 ck_rv_t
3031 pkcs11_close_session (struct pkcs11_session_info * sinfo)
3033 sinfo->init = 0;
3034 return (sinfo->module)->C_CloseSession (sinfo->pks);
3037 ck_rv_t
3038 pkcs11_get_attribute_value(struct ck_function_list *module,
3039 ck_session_handle_t sess,
3040 ck_object_handle_t object,
3041 struct ck_attribute *templ,
3042 unsigned long count)
3044 return (module)->C_GetAttributeValue (sess, object, templ, count);
3047 ck_rv_t
3048 pkcs11_get_mechanism_list (struct ck_function_list *module,
3049 ck_slot_id_t slot_id,
3050 ck_mechanism_type_t *mechanism_list,
3051 unsigned long *count)
3053 return (module)->C_GetMechanismList (slot_id, mechanism_list, count);
3056 ck_rv_t
3057 pkcs11_sign_init (struct ck_function_list *module,
3058 ck_session_handle_t sess,
3059 struct ck_mechanism *mechanism,
3060 ck_object_handle_t key)
3062 return (module)->C_SignInit (sess, mechanism, key);
3065 ck_rv_t
3066 pkcs11_sign (struct ck_function_list *module,
3067 ck_session_handle_t sess,
3068 unsigned char *data,
3069 unsigned long data_len,
3070 unsigned char *signature,
3071 unsigned long *signature_len)
3073 return (module)->C_Sign (sess, data, data_len, signature, signature_len);
3076 ck_rv_t
3077 pkcs11_generate_key_pair (struct ck_function_list *module,
3078 ck_session_handle_t sess,
3079 struct ck_mechanism *mechanism,
3080 struct ck_attribute *pub_templ,
3081 unsigned long pub_templ_count,
3082 struct ck_attribute *priv_templ,
3083 unsigned long priv_templ_count,
3084 ck_object_handle_t *pub,
3085 ck_object_handle_t *priv)
3087 return (module)->C_GenerateKeyPair (sess, mechanism, pub_templ, pub_templ_count,
3088 priv_templ, priv_templ_count, pub, priv);
3091 ck_rv_t
3092 pkcs11_decrypt_init (struct ck_function_list *module,
3093 ck_session_handle_t sess,
3094 struct ck_mechanism *mechanism,
3095 ck_object_handle_t key)
3097 return (module)->C_DecryptInit (sess, mechanism, key);
3100 ck_rv_t
3101 pkcs11_decrypt (struct ck_function_list *module,
3102 ck_session_handle_t sess,
3103 unsigned char *encrypted_data,
3104 unsigned long encrypted_data_len,
3105 unsigned char *data, unsigned long *data_len)
3107 return (module)->C_Decrypt (sess, encrypted_data, encrypted_data_len,
3108 data, data_len);
3111 ck_rv_t
3112 pkcs11_create_object (struct ck_function_list *module,
3113 ck_session_handle_t sess,
3114 struct ck_attribute *templ,
3115 unsigned long count,
3116 ck_object_handle_t *object)
3118 return (module)->C_CreateObject (sess, templ, count, object);
3121 ck_rv_t
3122 pkcs11_destroy_object (struct ck_function_list *module,
3123 ck_session_handle_t sess,
3124 ck_object_handle_t object)
3126 return (module)->C_DestroyObject (sess, object);
3129 ck_rv_t
3130 pkcs11_init_token (struct ck_function_list *module,
3131 ck_slot_id_t slot_id, unsigned char *pin,
3132 unsigned long pin_len, unsigned char *label)
3134 return (module)->C_InitToken (slot_id, pin, pin_len, label);
3137 ck_rv_t
3138 pkcs11_init_pin (struct ck_function_list *module,
3139 ck_session_handle_t sess,
3140 unsigned char *pin,
3141 unsigned long pin_len)
3143 return (module)->C_InitPIN (sess, pin, pin_len);
3146 ck_rv_t
3147 pkcs11_set_pin (struct ck_function_list *module,
3148 ck_session_handle_t sess,
3149 const char *old_pin,
3150 unsigned long old_len,
3151 const char *new_pin,
3152 unsigned long new_len)
3154 return (module)->C_SetPIN (sess, (uint8_t*)old_pin, old_len, (uint8_t*)new_pin, new_len);
3157 const char *
3158 pkcs11_strerror (ck_rv_t rv)
3160 return p11_kit_strerror (rv);