Provide compatibility inline functions for gnutls_session_get_server_random() and...
[gnutls.git] / lib / pkcs11.c
blobfee702384dedae685a086718481358960dfbb646
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 static gnutls_pkcs11_pin_callback_t pin_func;
78 static void *pin_data;
80 gnutls_pkcs11_token_callback_t token_func;
81 void *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 if (flags == GNUTLS_PKCS11_FLAG_MANUAL)
561 return 0;
562 else if (flags == GNUTLS_PKCS11_FLAG_AUTO)
564 if (deprecated_config_file == NULL)
565 ret = initialize_automatic_p11_kit ();
567 _pkcs11_compat_init(deprecated_config_file);
569 return ret;
572 return 0;
576 * gnutls_pkcs11_reinit:
578 * This function will reinitialize the PKCS 11 subsystem in gnutls.
579 * This is required by PKCS 11 when an application uses fork(). The
580 * reinitialization function must be called on the child.
582 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
583 * negative error value.
585 * Since: 3.0
587 int gnutls_pkcs11_reinit (void)
589 int rv;
591 rv = p11_kit_initialize_registered ();
592 if (rv != CKR_OK)
594 gnutls_assert ();
595 _gnutls_debug_log ("Cannot initialize registered module: %s\n",
596 p11_kit_strerror (rv));
597 return GNUTLS_E_INTERNAL_ERROR;
600 return 0;
604 * gnutls_pkcs11_deinit:
606 * This function will deinitialize the PKCS 11 subsystem in gnutls.
608 * Since: 2.12.0
610 void
611 gnutls_pkcs11_deinit (void)
613 unsigned int i;
615 init--;
616 if (init > 0)
617 return;
618 if (init < 0)
620 init = 0;
621 return;
624 for (i = 0; i < active_providers; i++)
626 if (providers[i].initialized)
627 p11_kit_finalize_module (providers[i].module);
629 active_providers = 0;
631 if (initialized_registered != 0)
632 p11_kit_finalize_registered ();
633 initialized_registered = 0;
637 * gnutls_pkcs11_set_pin_function:
638 * @fn: The PIN callback, a gnutls_pkcs11_pin_callback_t() function.
639 * @userdata: data to be supplied to callback
641 * This function will set a callback function to be used when a PIN is
642 * required for PKCS 11 operations. See
643 * gnutls_pkcs11_pin_callback_t() on how the callback should behave.
645 * Since: 2.12.0
647 void
648 gnutls_pkcs11_set_pin_function (gnutls_pkcs11_pin_callback_t fn,
649 void *userdata)
651 pin_func = fn;
652 pin_data = userdata;
656 * gnutls_pkcs11_set_token_function:
657 * @fn: The token callback
658 * @userdata: data to be supplied to callback
660 * This function will set a callback function to be used when a token
661 * needs to be inserted to continue PKCS 11 operations.
663 * Since: 2.12.0
665 void
666 gnutls_pkcs11_set_token_function (gnutls_pkcs11_token_callback_t fn,
667 void *userdata)
669 token_func = fn;
670 token_data = userdata;
674 pkcs11_url_to_info (const char *url, struct p11_kit_uri **info)
676 int allocated = 0;
677 int ret;
679 if (*info == NULL)
681 *info = p11_kit_uri_new ();
682 if (*info == NULL)
684 gnutls_assert ();
685 return GNUTLS_E_MEMORY_ERROR;
687 allocated = 1;
690 ret = p11_kit_uri_parse (url, P11_KIT_URI_FOR_ANY, *info);
691 if (ret < 0)
693 if (allocated)
695 p11_kit_uri_free (*info);
696 *info = NULL;
698 gnutls_assert ();
699 return ret == P11_KIT_URI_NO_MEMORY ?
700 GNUTLS_E_MEMORY_ERROR : GNUTLS_E_PARSING_ERROR;
703 return 0;
707 pkcs11_info_to_url (struct p11_kit_uri *info,
708 gnutls_pkcs11_url_type_t detailed, char **url)
710 p11_kit_uri_type_t type = 0;
711 int ret;
713 switch (detailed)
715 case GNUTLS_PKCS11_URL_GENERIC:
716 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN;
717 break;
718 case GNUTLS_PKCS11_URL_LIB:
719 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE;
720 break;
721 case GNUTLS_PKCS11_URL_LIB_VERSION:
722 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE | P11_KIT_URI_FOR_MODULE_WITH_VERSION;
723 break;
726 ret = p11_kit_uri_format (info, type, url);
727 if (ret < 0)
729 gnutls_assert ();
730 return ret == P11_KIT_URI_NO_MEMORY ?
731 GNUTLS_E_MEMORY_ERROR : GNUTLS_E_INTERNAL_ERROR;
734 return 0;
738 * gnutls_pkcs11_obj_init:
739 * @obj: The structure to be initialized
741 * This function will initialize a pkcs11 certificate structure.
743 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
744 * negative error value.
746 * Since: 2.12.0
749 gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t * obj)
751 *obj = gnutls_calloc (1, sizeof (struct gnutls_pkcs11_obj_st));
752 if (*obj == NULL)
754 gnutls_assert ();
755 return GNUTLS_E_MEMORY_ERROR;
758 (*obj)->info = p11_kit_uri_new ();
759 if ((*obj)->info == NULL)
761 free (*obj);
762 gnutls_assert ();
763 return GNUTLS_E_MEMORY_ERROR;
766 return 0;
770 * gnutls_pkcs11_obj_deinit:
771 * @obj: The structure to be initialized
773 * This function will deinitialize a certificate structure.
775 * Since: 2.12.0
777 void
778 gnutls_pkcs11_obj_deinit (gnutls_pkcs11_obj_t obj)
780 _gnutls_free_datum (&obj->raw);
781 p11_kit_uri_free (obj->info);
782 free (obj);
786 * gnutls_pkcs11_obj_export:
787 * @obj: Holds the object
788 * @output_data: will contain a certificate PEM or DER encoded
789 * @output_data_size: holds the size of output_data (and will be
790 * replaced by the actual size of parameters)
792 * This function will export the PKCS11 object data. It is normal for
793 * data to be inaccesible and in that case %GNUTLS_E_INVALID_REQUEST
794 * will be returned.
796 * If the buffer provided is not long enough to hold the output, then
797 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
798 * be returned.
800 * If the structure is PEM encoded, it will have a header
801 * of "BEGIN CERTIFICATE".
803 * Returns: In case of failure a negative error code will be
804 * returned, and %GNUTLS_E_SUCCESS (0) on success.
806 * Since: 2.12.0
809 gnutls_pkcs11_obj_export (gnutls_pkcs11_obj_t obj,
810 void *output_data, size_t * output_data_size)
812 if (obj == NULL || obj->raw.data == NULL)
814 gnutls_assert ();
815 return GNUTLS_E_INVALID_REQUEST;
818 if (output_data == NULL || *output_data_size < obj->raw.size)
820 *output_data_size = obj->raw.size;
821 gnutls_assert ();
822 return GNUTLS_E_SHORT_MEMORY_BUFFER;
824 *output_data_size = obj->raw.size;
826 memcpy (output_data, obj->raw.data, obj->raw.size);
827 return 0;
831 pkcs11_find_object (struct ck_function_list ** _module,
832 ck_session_handle_t * _pks,
833 ck_object_handle_t * _obj,
834 struct p11_kit_uri *info, unsigned int flags)
836 int ret;
837 struct ck_function_list *module;
838 ck_session_handle_t pks;
839 ck_object_handle_t obj;
840 struct ck_attribute *attrs;
841 unsigned long attr_count;
842 unsigned long count;
843 ck_rv_t rv;
845 ret = pkcs11_open_session (&module, &pks, info, flags & SESSION_LOGIN);
846 if (ret < 0)
848 gnutls_assert ();
849 return ret;
852 attrs = p11_kit_uri_get_attributes (info, &attr_count);
853 rv = pkcs11_find_objects_init (module, pks, attrs, attr_count);
854 if (rv != CKR_OK)
856 gnutls_assert ();
857 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
858 ret = pkcs11_rv_to_err (rv);
859 goto fail;
862 if (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
864 *_obj = obj;
865 *_pks = pks;
866 *_module = module;
867 pkcs11_find_objects_final (module, pks);
868 return 0;
871 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
872 pkcs11_find_objects_final (module, pks);
873 fail:
874 pkcs11_close_session (module, pks);
876 return ret;
880 pkcs11_find_slot (struct ck_function_list ** module, ck_slot_id_t * slot,
881 struct p11_kit_uri *info, struct token_info *_tinfo)
883 unsigned int x, z;
885 for (x = 0; x < active_providers; x++)
887 for (z = 0; z < providers[x].nslots; z++)
889 struct token_info tinfo;
891 if (pkcs11_get_token_info
892 (providers[x].module, providers[x].slots[z],
893 &tinfo.tinfo) != CKR_OK)
895 continue;
897 tinfo.sid = providers[x].slots[z];
898 tinfo.prov = &providers[x];
900 if (pkcs11_get_slot_info
901 (providers[x].module, providers[x].slots[z],
902 &tinfo.sinfo) != CKR_OK)
904 continue;
907 if (!p11_kit_uri_match_token_info (info, &tinfo.tinfo) ||
908 !p11_kit_uri_match_module_info (info, &providers[x].info))
910 continue;
913 /* ok found */
914 *module = providers[x].module;
915 *slot = providers[x].slots[z];
917 if (_tinfo != NULL)
918 memcpy (_tinfo, &tinfo, sizeof (tinfo));
920 return 0;
924 gnutls_assert ();
925 return GNUTLS_E_PKCS11_REQUESTED_OBJECT_NOT_AVAILBLE;
929 pkcs11_open_session (struct ck_function_list ** _module, ck_session_handle_t * _pks,
930 struct p11_kit_uri *info, unsigned int flags)
932 ck_rv_t rv;
933 int ret;
934 ck_session_handle_t pks = 0;
935 struct ck_function_list *module;
936 ck_slot_id_t slot;
937 struct token_info tinfo;
939 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
940 if (ret < 0)
942 gnutls_assert ();
943 return ret;
946 rv = (module)->C_OpenSession (slot,
947 ((flags & SESSION_WRITE)
948 ? CKF_RW_SESSION : 0) |
949 CKF_SERIAL_SESSION, NULL, NULL, &pks);
950 if (rv != CKR_OK)
952 gnutls_assert ();
953 return pkcs11_rv_to_err (rv);
956 if (flags & SESSION_LOGIN)
958 ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
959 if (ret < 0)
961 gnutls_assert ();
962 pkcs11_close_session (module, pks);
963 return ret;
967 /* ok found */
968 *_pks = pks;
969 *_module = module;
970 return 0;
975 _pkcs11_traverse_tokens (find_func_t find_func, void *input,
976 struct p11_kit_uri *info, unsigned int flags)
978 ck_rv_t rv;
979 unsigned int found = 0, x, z;
980 int ret;
981 ck_session_handle_t pks = 0;
982 struct ck_function_list *module = NULL;
984 for (x = 0; x < active_providers; x++)
986 module = providers[x].module;
987 for (z = 0; z < providers[x].nslots; z++)
989 struct token_info tinfo;
991 ret = GNUTLS_E_PKCS11_ERROR;
993 if (pkcs11_get_token_info (module, providers[x].slots[z],
994 &tinfo.tinfo) != CKR_OK)
996 continue;
998 tinfo.sid = providers[x].slots[z];
999 tinfo.prov = &providers[x];
1001 if (pkcs11_get_slot_info (module, providers[x].slots[z],
1002 &tinfo.sinfo) != CKR_OK)
1004 continue;
1007 rv = (module)->C_OpenSession (providers[x].slots[z],
1008 ((flags & SESSION_WRITE)
1009 ? CKF_RW_SESSION : 0) |
1010 CKF_SERIAL_SESSION, NULL, NULL, &pks);
1011 if (rv != CKR_OK)
1013 continue;
1016 if (flags & SESSION_LOGIN)
1018 ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
1019 if (ret < 0)
1021 gnutls_assert ();
1022 return ret;
1026 ret = find_func (module, pks, &tinfo, &providers[x].info, input);
1028 if (ret == 0)
1030 found = 1;
1031 goto finish;
1033 else
1035 pkcs11_close_session (module, pks);
1036 pks = 0;
1041 finish:
1042 /* final call */
1044 if (found == 0)
1046 if (module)
1047 ret = find_func (module, pks, NULL, NULL, input);
1048 else
1049 ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1051 else
1053 ret = 0;
1056 if (pks != 0 && module != NULL)
1058 pkcs11_close_session (module, pks);
1061 return ret;
1064 /* imports a raw certificate from a token to a pkcs11_obj_t structure.
1066 static int
1067 pkcs11_obj_import (ck_object_class_t class, gnutls_pkcs11_obj_t obj,
1068 const gnutls_datum_t * data,
1069 const gnutls_datum_t * id,
1070 const gnutls_datum_t * label,
1071 struct ck_token_info *tinfo, struct ck_info *lib_info)
1073 struct ck_attribute attr;
1074 int ret;
1076 switch (class)
1078 case CKO_CERTIFICATE:
1079 obj->type = GNUTLS_PKCS11_OBJ_X509_CRT;
1080 break;
1081 case CKO_PUBLIC_KEY:
1082 obj->type = GNUTLS_PKCS11_OBJ_PUBKEY;
1083 break;
1084 case CKO_PRIVATE_KEY:
1085 obj->type = GNUTLS_PKCS11_OBJ_PRIVKEY;
1086 break;
1087 case CKO_SECRET_KEY:
1088 obj->type = GNUTLS_PKCS11_OBJ_SECRET_KEY;
1089 break;
1090 case CKO_DATA:
1091 obj->type = GNUTLS_PKCS11_OBJ_DATA;
1092 break;
1093 default:
1094 obj->type = GNUTLS_PKCS11_OBJ_UNKNOWN;
1097 attr.type = CKA_CLASS;
1098 attr.value = &class;
1099 attr.value_len = sizeof (class);
1100 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1101 if (ret < 0)
1103 gnutls_assert ();
1104 return GNUTLS_E_MEMORY_ERROR;
1107 if (data && data->data)
1109 ret = _gnutls_set_datum (&obj->raw, data->data, data->size);
1110 if (ret < 0)
1112 gnutls_assert ();
1113 return ret;
1117 /* copy the token and library info into the uri */
1118 memcpy (p11_kit_uri_get_token_info (obj->info), tinfo, sizeof (struct ck_token_info));
1119 memcpy (p11_kit_uri_get_module_info (obj->info), lib_info, sizeof (struct ck_info));
1121 if (label && label->data)
1123 attr.type = CKA_LABEL;
1124 attr.value = label->data;
1125 attr.value_len = label->size;
1126 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1127 if (ret < 0)
1129 gnutls_assert ();
1130 return GNUTLS_E_MEMORY_ERROR;
1134 if (id && id->data)
1136 attr.type = CKA_ID;
1137 attr.value = id->data;
1138 attr.value_len = id->size;
1139 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1140 if (ret < 0)
1142 gnutls_assert ();
1143 return GNUTLS_E_MEMORY_ERROR;
1147 return 0;
1150 static int read_pkcs11_pubkey(struct ck_function_list *module,
1151 ck_session_handle_t pks, ck_object_handle_t obj,
1152 ck_key_type_t key_type, gnutls_datum_t * pubkey)
1154 struct ck_attribute a[4];
1155 uint8_t tmp1[2048];
1156 uint8_t tmp2[2048];
1157 int ret;
1159 switch (key_type)
1161 case CKK_RSA:
1162 a[0].type = CKA_MODULUS;
1163 a[0].value = tmp1;
1164 a[0].value_len = sizeof (tmp1);
1165 a[1].type = CKA_PUBLIC_EXPONENT;
1166 a[1].value = tmp2;
1167 a[1].value_len = sizeof (tmp2);
1169 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1172 ret =
1173 _gnutls_set_datum (&pubkey[0],
1174 a[0].value, a[0].value_len);
1176 if (ret >= 0)
1177 ret =
1178 _gnutls_set_datum (&pubkey
1179 [1], a[1].value, a[1].value_len);
1181 if (ret < 0)
1183 gnutls_assert ();
1184 _gnutls_free_datum (&pubkey[1]);
1185 _gnutls_free_datum (&pubkey[0]);
1186 return GNUTLS_E_MEMORY_ERROR;
1189 else
1191 gnutls_assert ();
1192 return GNUTLS_E_PKCS11_ERROR;
1194 break;
1195 case CKK_DSA:
1196 a[0].type = CKA_PRIME;
1197 a[0].value = tmp1;
1198 a[0].value_len = sizeof (tmp1);
1199 a[1].type = CKA_SUBPRIME;
1200 a[1].value = tmp2;
1201 a[1].value_len = sizeof (tmp2);
1203 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1205 ret =
1206 _gnutls_set_datum (&pubkey[0],
1207 a[0].value, a[0].value_len);
1209 if (ret >= 0)
1210 ret =
1211 _gnutls_set_datum (&pubkey
1212 [1], a[1].value, a[1].value_len);
1214 if (ret < 0)
1216 gnutls_assert ();
1217 _gnutls_free_datum (&pubkey[1]);
1218 _gnutls_free_datum (&pubkey[0]);
1219 return GNUTLS_E_MEMORY_ERROR;
1222 else
1224 gnutls_assert ();
1225 return GNUTLS_E_PKCS11_ERROR;
1228 a[0].type = CKA_BASE;
1229 a[0].value = tmp1;
1230 a[0].value_len = sizeof (tmp1);
1231 a[1].type = CKA_VALUE;
1232 a[1].value = tmp2;
1233 a[1].value_len = sizeof (tmp2);
1235 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1237 ret =
1238 _gnutls_set_datum (&pubkey[2],
1239 a[0].value, a[0].value_len);
1241 if (ret >= 0)
1242 ret =
1243 _gnutls_set_datum (&pubkey
1244 [3], a[1].value, a[1].value_len);
1246 if (ret < 0)
1248 gnutls_assert ();
1249 _gnutls_free_datum (&pubkey[0]);
1250 _gnutls_free_datum (&pubkey[1]);
1251 _gnutls_free_datum (&pubkey[2]);
1252 _gnutls_free_datum (&pubkey[3]);
1253 return GNUTLS_E_MEMORY_ERROR;
1256 else
1258 gnutls_assert ();
1259 return GNUTLS_E_PKCS11_ERROR;
1261 break;
1262 case CKK_ECDSA:
1263 a[0].type = CKA_EC_PARAMS;
1264 a[0].value = tmp1;
1265 a[0].value_len = sizeof (tmp1);
1266 a[1].type = CKA_EC_POINT;
1267 a[1].value = tmp2;
1268 a[1].value_len = sizeof (tmp2);
1270 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1272 ret =
1273 _gnutls_set_datum (&pubkey[0],
1274 a[0].value, a[0].value_len);
1276 if (ret >= 0)
1277 ret =
1278 _gnutls_set_datum (&pubkey
1279 [1], a[1].value, a[1].value_len);
1281 if (ret < 0)
1283 gnutls_assert ();
1284 _gnutls_free_datum (&pubkey[1]);
1285 _gnutls_free_datum (&pubkey[0]);
1286 return GNUTLS_E_MEMORY_ERROR;
1289 else
1291 gnutls_assert ();
1292 return GNUTLS_E_PKCS11_ERROR;
1295 break;
1296 default:
1297 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1300 return 0;
1303 static int
1304 pkcs11_obj_import_pubkey (struct ck_function_list *module,
1305 ck_session_handle_t pks,
1306 ck_object_handle_t obj,
1307 gnutls_pkcs11_obj_t crt,
1308 const gnutls_datum_t * id,
1309 const gnutls_datum_t * label,
1310 struct ck_token_info *tinfo,
1311 struct ck_info *lib_info)
1313 struct ck_attribute a[4];
1314 ck_key_type_t key_type;
1315 int ret;
1316 ck_bool_t tval;
1318 a[0].type = CKA_KEY_TYPE;
1319 a[0].value = &key_type;
1320 a[0].value_len = sizeof (key_type);
1322 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1324 crt->pk_algorithm = mech_to_pk(key_type);
1326 ret = read_pkcs11_pubkey(module, pks, obj, key_type, crt->pubkey);
1327 if (ret < 0)
1328 return gnutls_assert_val(ret);
1331 /* read key usage flags */
1332 a[0].type = CKA_ENCRYPT;
1333 a[0].value = &tval;
1334 a[0].value_len = sizeof (tval);
1336 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1338 if (tval != 0)
1340 crt->key_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
1344 a[0].type = CKA_VERIFY;
1345 a[0].value = &tval;
1346 a[0].value_len = sizeof (tval);
1348 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1350 if (tval != 0)
1352 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1353 GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1354 | GNUTLS_KEY_NON_REPUDIATION;
1358 a[0].type = CKA_VERIFY_RECOVER;
1359 a[0].value = &tval;
1360 a[0].value_len = sizeof (tval);
1362 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1364 if (tval != 0)
1366 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1367 GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1368 | GNUTLS_KEY_NON_REPUDIATION;
1372 a[0].type = CKA_DERIVE;
1373 a[0].value = &tval;
1374 a[0].value_len = sizeof (tval);
1376 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1378 if (tval != 0)
1380 crt->key_usage |= GNUTLS_KEY_KEY_AGREEMENT;
1384 a[0].type = CKA_WRAP;
1385 a[0].value = &tval;
1386 a[0].value_len = sizeof (tval);
1388 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1390 if (tval != 0)
1392 crt->key_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
1396 return pkcs11_obj_import (CKO_PUBLIC_KEY, crt, NULL, id, label,
1397 tinfo, lib_info);
1400 static int
1401 find_obj_url (struct ck_function_list *module, ck_session_handle_t pks,
1402 struct token_info *info, struct ck_info *lib_info, void *input)
1404 struct url_find_data_st *find_data = input;
1405 struct ck_attribute a[4];
1406 struct ck_attribute *attr;
1407 ck_object_class_t class = -1;
1408 ck_certificate_type_t type = (ck_certificate_type_t)-1;
1409 ck_rv_t rv;
1410 ck_object_handle_t obj;
1411 unsigned long count, a_vals;
1412 int found = 0, ret;
1413 uint8_t *cert_data = NULL;
1414 char label_tmp[PKCS11_LABEL_SIZE];
1416 if (info == NULL)
1417 { /* we don't support multiple calls */
1418 gnutls_assert ();
1419 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1422 /* do not bother reading the token if basic fields do not match
1424 if (!p11_kit_uri_match_token_info (find_data->crt->info, &info->tinfo) ||
1425 !p11_kit_uri_match_module_info (find_data->crt->info, lib_info))
1427 gnutls_assert ();
1428 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1431 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID);
1432 if (attr == NULL)
1434 gnutls_assert ();
1435 return GNUTLS_E_INVALID_REQUEST;
1438 /* search the token for the id */
1440 cert_data = gnutls_malloc (MAX_CERT_SIZE);
1441 if (cert_data == NULL)
1443 gnutls_assert ();
1444 return GNUTLS_E_MEMORY_ERROR;
1447 /* Find objects with given class and type */
1448 memcpy (a, attr, sizeof (struct ck_attribute));
1449 a_vals = 1;
1451 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_CLASS);
1452 if (attr)
1454 if(attr->value && attr->value_len == sizeof (ck_object_class_t))
1455 class = *((ck_object_class_t*)attr->value);
1456 if (class == CKO_CERTIFICATE)
1457 type = CKC_X_509;
1458 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1459 a_vals++;
1462 if (type != (ck_certificate_type_t)-1)
1464 a[a_vals].type = CKA_CERTIFICATE_TYPE;
1465 a[a_vals].value = &type;
1466 a[a_vals].value_len = sizeof type;
1467 a_vals++;
1470 rv = pkcs11_find_objects_init (module, pks, a, a_vals);
1471 if (rv != CKR_OK)
1473 gnutls_assert ();
1474 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
1475 ret = pkcs11_rv_to_err (rv);
1476 goto cleanup;
1479 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
1482 a[0].type = CKA_VALUE;
1483 a[0].value = cert_data;
1484 a[0].value_len = MAX_CERT_SIZE;
1485 a[1].type = CKA_LABEL;
1486 a[1].value = label_tmp;
1487 a[1].value_len = sizeof (label_tmp);
1489 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1491 gnutls_datum_t id;
1492 gnutls_datum_t data = { a[0].value, a[0].value_len };
1493 gnutls_datum_t label = { a[1].value, a[1].value_len };
1495 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID);
1496 id.data = attr->value;
1497 id.size = attr->value_len;
1499 if (class == CKO_PUBLIC_KEY)
1501 ret =
1502 pkcs11_obj_import_pubkey (module, pks, obj,
1503 find_data->crt,
1504 &id, &label,
1505 &info->tinfo, lib_info);
1507 else
1509 ret =
1510 pkcs11_obj_import (class,
1511 find_data->crt,
1512 &data, &id, &label,
1513 &info->tinfo, lib_info);
1515 if (ret < 0)
1517 gnutls_assert ();
1518 goto cleanup;
1521 found = 1;
1522 break;
1524 else
1526 _gnutls_debug_log ("pk11: Skipped cert, missing attrs.\n");
1530 if (found == 0)
1532 gnutls_assert ();
1533 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1535 else
1537 ret = 0;
1540 cleanup:
1541 gnutls_free (cert_data);
1542 pkcs11_find_objects_final (module, pks);
1544 return ret;
1547 unsigned int
1548 pkcs11_obj_flags_to_int (unsigned int flags)
1550 unsigned int ret_flags = 0;
1552 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN)
1553 ret_flags |= SESSION_LOGIN;
1554 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO)
1555 ret_flags |= SESSION_LOGIN|SESSION_SO;
1557 return ret_flags;
1561 * gnutls_pkcs11_obj_import_url:
1562 * @cert: The structure to store the parsed certificate
1563 * @url: a PKCS 11 url identifying the key
1564 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1566 * This function will "import" a PKCS 11 URL identifying a certificate
1567 * key to the #gnutls_pkcs11_obj_t structure. This does not involve any
1568 * parsing (such as X.509 or OpenPGP) since the #gnutls_pkcs11_obj_t is
1569 * format agnostic. Only data are transferred.
1571 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1572 * negative error value.
1574 * Since: 2.12.0
1577 gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t cert, const char *url,
1578 unsigned int flags)
1580 int ret;
1581 struct url_find_data_st find_data;
1583 /* fill in the find data structure */
1584 find_data.crt = cert;
1586 ret = pkcs11_url_to_info (url, &cert->info);
1587 if (ret < 0)
1589 gnutls_assert ();
1590 return ret;
1593 ret =
1594 _pkcs11_traverse_tokens (find_obj_url, &find_data, cert->info,
1595 pkcs11_obj_flags_to_int (flags));
1597 if (ret < 0)
1599 gnutls_assert ();
1600 return ret;
1603 return 0;
1606 struct token_num
1608 struct p11_kit_uri *info;
1609 unsigned int seq; /* which one we are looking for */
1610 unsigned int current; /* which one are we now */
1613 static int
1614 find_token_num (struct ck_function_list *module,
1615 ck_session_handle_t pks,
1616 struct token_info *tinfo,
1617 struct ck_info *lib_info, void *input)
1619 struct token_num *find_data = input;
1621 if (tinfo == NULL)
1622 { /* we don't support multiple calls */
1623 gnutls_assert ();
1624 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1627 if (find_data->current == find_data->seq)
1629 memcpy (p11_kit_uri_get_token_info (find_data->info), &tinfo->tinfo, sizeof (struct ck_token_info));
1630 memcpy (p11_kit_uri_get_module_info (find_data->info), lib_info, sizeof (struct ck_info));
1631 return 0;
1634 find_data->current++;
1635 /* search the token for the id */
1638 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* non zero is enough */
1642 * gnutls_pkcs11_token_get_url:
1643 * @seq: sequence number starting from 0
1644 * @detailed: non zero if a detailed URL is required
1645 * @url: will contain an allocated url
1647 * This function will return the URL for each token available
1648 * in system. The url has to be released using gnutls_free()
1650 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1651 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if the sequence number
1652 * exceeds the available tokens, otherwise a negative error value.
1654 * Since: 2.12.0
1657 gnutls_pkcs11_token_get_url (unsigned int seq,
1658 gnutls_pkcs11_url_type_t detailed, char **url)
1660 int ret;
1661 struct token_num tn;
1663 memset (&tn, 0, sizeof (tn));
1664 tn.seq = seq;
1665 tn.info = p11_kit_uri_new ();
1667 ret = _pkcs11_traverse_tokens (find_token_num, &tn, NULL, 0);
1668 if (ret < 0)
1670 p11_kit_uri_free (tn.info);
1671 gnutls_assert ();
1672 return ret;
1675 ret = pkcs11_info_to_url (tn.info, detailed, url);
1676 p11_kit_uri_free (tn.info);
1678 if (ret < 0)
1680 gnutls_assert ();
1681 return ret;
1684 return 0;
1689 * gnutls_pkcs11_token_get_info:
1690 * @url: should contain a PKCS 11 URL
1691 * @ttype: Denotes the type of information requested
1692 * @output: where output will be stored
1693 * @output_size: contains the maximum size of the output and will be overwritten with actual
1695 * This function will return information about the PKCS 11 token such
1696 * as the label, id, etc.
1698 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code
1699 * on error.
1701 * Since: 2.12.0
1704 gnutls_pkcs11_token_get_info (const char *url,
1705 gnutls_pkcs11_token_info_t ttype,
1706 void *output, size_t * output_size)
1708 struct p11_kit_uri *info = NULL;
1709 const uint8_t *str;
1710 size_t str_max;
1711 size_t len;
1712 int ret;
1714 ret = pkcs11_url_to_info (url, &info);
1715 if (ret < 0)
1717 gnutls_assert ();
1718 return ret;
1721 switch (ttype)
1723 case GNUTLS_PKCS11_TOKEN_LABEL:
1724 str = p11_kit_uri_get_token_info (info)->label;
1725 str_max = 32;
1726 break;
1727 case GNUTLS_PKCS11_TOKEN_SERIAL:
1728 str = p11_kit_uri_get_token_info (info)->serial_number;
1729 str_max = 16;
1730 break;
1731 case GNUTLS_PKCS11_TOKEN_MANUFACTURER:
1732 str = p11_kit_uri_get_token_info (info)->manufacturer_id;
1733 str_max = 32;
1734 break;
1735 case GNUTLS_PKCS11_TOKEN_MODEL:
1736 str = p11_kit_uri_get_token_info (info)->model;
1737 str_max = 16;
1738 break;
1739 default:
1740 p11_kit_uri_free (info);
1741 gnutls_assert ();
1742 return GNUTLS_E_INVALID_REQUEST;
1745 len = p11_kit_space_strlen (str, str_max);
1747 if (len + 1 > *output_size)
1749 *output_size = len + 1;
1750 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1753 memcpy (output, str, len);
1754 ((char*)output)[len] = '\0';
1756 *output_size = len;
1758 p11_kit_uri_free (info);
1759 return 0;
1763 * gnutls_pkcs11_obj_export_url:
1764 * @obj: Holds the PKCS 11 certificate
1765 * @detailed: non zero if a detailed URL is required
1766 * @url: will contain an allocated url
1768 * This function will export a URL identifying the given certificate.
1770 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1771 * negative error value.
1773 * Since: 2.12.0
1776 gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t obj,
1777 gnutls_pkcs11_url_type_t detailed, char **url)
1779 int ret;
1781 ret = pkcs11_info_to_url (obj->info, detailed, url);
1782 if (ret < 0)
1784 gnutls_assert ();
1785 return ret;
1788 return 0;
1792 * gnutls_pkcs11_obj_get_type:
1793 * @obj: Holds the PKCS 11 object
1795 * This function will return the type of the certificate being
1796 * stored in the structure.
1798 * Returns: The type of the certificate.
1800 * Since: 2.12.0
1802 gnutls_pkcs11_obj_type_t
1803 gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t obj)
1805 return obj->type;
1808 struct pkey_list
1810 gnutls_buffer_st *key_ids;
1811 size_t key_ids_size;
1815 static int
1816 retrieve_pin_for_pinfile (const char *pinfile, struct ck_token_info *token_info,
1817 int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
1819 unsigned int flags = 0;
1820 struct p11_kit_uri *token_uri;
1821 struct p11_kit_pin *result;
1822 char *label;
1824 label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1825 if (label == NULL)
1827 gnutls_assert ();
1828 return GNUTLS_E_MEMORY_ERROR;
1831 token_uri = p11_kit_uri_new ();
1832 if (token_uri == NULL)
1834 free (label);
1835 gnutls_assert ();
1836 return GNUTLS_E_MEMORY_ERROR;
1839 memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1840 sizeof (struct ck_token_info));
1842 if (attempts)
1843 flags |= P11_KIT_PIN_FLAGS_RETRY;
1844 if (user_type == CKU_USER)
1846 flags |= P11_KIT_PIN_FLAGS_USER_LOGIN;
1847 if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1848 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1849 if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1850 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1852 else if (user_type == CKU_SO)
1854 flags |= P11_KIT_PIN_FLAGS_SO_LOGIN;
1855 if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
1856 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1857 if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
1858 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1860 else if (user_type == CKU_CONTEXT_SPECIFIC)
1862 flags |= P11_KIT_PIN_FLAGS_CONTEXT_LOGIN;
1865 result = p11_kit_pin_request (pinfile, token_uri, label, flags);
1866 p11_kit_uri_free (token_uri);
1867 free (label);
1869 if (result == NULL)
1871 gnutls_assert ();
1872 return GNUTLS_E_PKCS11_PIN_ERROR;
1875 *pin = result;
1876 return 0;
1879 static int
1880 retrieve_pin_for_callback (struct ck_token_info *token_info, int attempts,
1881 ck_user_type_t user_type, struct p11_kit_pin **pin)
1883 char pin_value[GNUTLS_PKCS11_MAX_PIN_LEN];
1884 unsigned int flags = 0;
1885 char *token_str;
1886 char *label;
1887 struct p11_kit_uri *token_uri;
1888 int ret = 0;
1890 label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1891 if (label == NULL)
1893 gnutls_assert ();
1894 return GNUTLS_E_MEMORY_ERROR;
1897 token_uri = p11_kit_uri_new ();
1898 if (token_uri == NULL)
1900 free (label);
1901 gnutls_assert ();
1902 return GNUTLS_E_MEMORY_ERROR;
1905 memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1906 sizeof (struct ck_token_info));
1907 ret = pkcs11_info_to_url (token_uri, 1, &token_str);
1908 p11_kit_uri_free (token_uri);
1910 if (ret < 0)
1912 free (label);
1913 gnutls_assert ();
1914 return GNUTLS_E_MEMORY_ERROR;
1917 if (user_type == CKU_USER)
1919 flags |= GNUTLS_PKCS11_PIN_USER;
1920 if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1921 flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
1922 if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1923 flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
1925 else if (user_type == CKU_SO)
1927 flags |= GNUTLS_PKCS11_PIN_SO;
1928 if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
1929 flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
1930 if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
1931 flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
1934 if (attempts > 0)
1935 flags |= GNUTLS_PKCS11_PIN_WRONG;
1937 ret = pin_func (pin_data, attempts, (char*)token_str, label,
1938 flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
1939 free (token_str);
1940 free (label);
1942 if (ret < 0)
1943 return gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR);
1945 *pin = p11_kit_pin_new_for_string (pin_value);
1947 if (*pin == NULL)
1948 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1950 return 0;
1953 static int
1954 retrieve_pin (struct p11_kit_uri *info, struct ck_token_info *token_info,
1955 int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
1957 const char *pinfile;
1959 *pin = NULL;
1961 /* Check if a pinfile is specified, and use that if possible */
1962 pinfile = p11_kit_uri_get_pinfile (info);
1963 if (pinfile != NULL)
1965 _gnutls_debug_log("pk11: Using pinfile to retrieve PIN\n");
1966 return retrieve_pin_for_pinfile (pinfile, token_info, attempts, user_type, pin);
1969 /* The global gnutls pin callback */
1970 else if (pin_func)
1971 return retrieve_pin_for_callback (token_info, attempts, user_type, pin);
1973 /* Otherwise, PIN entry is necessary for login, so fail if there's
1974 * no callback. */
1975 else
1977 gnutls_assert ();
1978 _gnutls_debug_log ("pk11: No pin callback but login required.\n");
1979 return GNUTLS_E_PKCS11_ERROR;
1984 pkcs11_login (struct ck_function_list * module, ck_session_handle_t pks,
1985 const struct token_info *tokinfo, struct p11_kit_uri *info, int so)
1987 struct ck_session_info session_info;
1988 int attempt = 0, ret;
1989 ck_user_type_t user_type;
1990 ck_rv_t rv;
1992 user_type = (so == 0) ? CKU_USER : CKU_SO;
1993 if (so == 0 && (tokinfo->tinfo.flags & CKF_LOGIN_REQUIRED) == 0)
1995 gnutls_assert ();
1996 _gnutls_debug_log ("pk11: No login required.\n");
1997 return 0;
2000 /* For a token with a "protected" (out-of-band) authentication
2001 * path, calling login with a NULL username is all that is
2002 * required. */
2003 if (tokinfo->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
2005 rv = (module)->C_Login (pks, (so == 0) ? CKU_USER : CKU_SO, NULL, 0);
2006 if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
2008 return 0;
2010 else
2012 gnutls_assert ();
2013 _gnutls_debug_log ("pk11: Protected login failed.\n");
2014 ret = GNUTLS_E_PKCS11_ERROR;
2015 goto cleanup;
2021 struct p11_kit_pin *pin;
2022 struct ck_token_info tinfo;
2024 memcpy (&tinfo, &tokinfo->tinfo, sizeof(tinfo));
2026 /* Check whether the session is already logged in, and if so, just skip */
2027 rv = (module)->C_GetSessionInfo (pks, &session_info);
2028 if (rv == CKR_OK && (session_info.state == CKS_RO_USER_FUNCTIONS ||
2029 session_info.state == CKS_RW_USER_FUNCTIONS))
2031 ret = 0;
2032 goto cleanup;
2035 /* If login has been attempted once already, check the token
2036 * status again, the flags might change. */
2037 if (attempt)
2039 if (pkcs11_get_token_info
2040 (tokinfo->prov->module, tokinfo->sid, &tinfo) != CKR_OK)
2042 gnutls_assert ();
2043 _gnutls_debug_log ("pk11: GetTokenInfo failed\n");
2044 ret = GNUTLS_E_PKCS11_ERROR;
2045 goto cleanup;
2049 ret = retrieve_pin (info, &tinfo, attempt++, user_type, &pin);
2050 if (ret < 0)
2052 gnutls_assert ();
2053 goto cleanup;
2056 rv = (module)->C_Login (pks, user_type,
2057 (unsigned char *)p11_kit_pin_get_value (pin, NULL),
2058 p11_kit_pin_get_length (pin));
2060 p11_kit_pin_unref (pin);
2062 while (rv == CKR_PIN_INCORRECT);
2064 _gnutls_debug_log ("pk11: Login result = %lu\n", rv);
2067 ret = (rv == CKR_OK
2068 || rv == CKR_USER_ALREADY_LOGGED_IN) ? 0 : pkcs11_rv_to_err (rv);
2070 cleanup:
2071 return ret;
2075 pkcs11_call_token_func (struct p11_kit_uri *info, const unsigned retry)
2077 struct ck_token_info *tinfo;
2078 char *label;
2079 int ret = 0;
2081 tinfo = p11_kit_uri_get_token_info (info);
2082 label = p11_kit_space_strdup (tinfo->label, sizeof (tinfo->label));
2083 ret = (token_func) (token_data, label, retry);
2084 free (label);
2086 return ret;
2090 static int
2091 find_privkeys (struct ck_function_list *module, ck_session_handle_t pks,
2092 struct token_info *info, struct pkey_list *list)
2094 struct ck_attribute a[3];
2095 ck_object_class_t class;
2096 ck_rv_t rv;
2097 ck_object_handle_t obj;
2098 unsigned long count, current;
2099 char certid_tmp[PKCS11_ID_SIZE];
2101 class = CKO_PRIVATE_KEY;
2103 /* Find an object with private key class and a certificate ID
2104 * which matches the certificate. */
2105 /* FIXME: also match the cert subject. */
2106 a[0].type = CKA_CLASS;
2107 a[0].value = &class;
2108 a[0].value_len = sizeof class;
2110 rv = pkcs11_find_objects_init (module, pks, a, 1);
2111 if (rv != CKR_OK)
2113 gnutls_assert ();
2114 return pkcs11_rv_to_err (rv);
2117 list->key_ids_size = 0;
2118 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
2120 list->key_ids_size++;
2123 pkcs11_find_objects_final (module, pks);
2125 if (list->key_ids_size == 0)
2127 gnutls_assert ();
2128 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2131 list->key_ids =
2132 gnutls_malloc (sizeof (gnutls_buffer_st) * list->key_ids_size);
2133 if (list->key_ids == NULL)
2135 gnutls_assert ();
2136 return GNUTLS_E_MEMORY_ERROR;
2139 /* actual search */
2140 a[0].type = CKA_CLASS;
2141 a[0].value = &class;
2142 a[0].value_len = sizeof class;
2144 rv = pkcs11_find_objects_init (module, pks, a, 1);
2145 if (rv != CKR_OK)
2147 gnutls_assert ();
2148 return pkcs11_rv_to_err (rv);
2151 current = 0;
2152 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
2155 a[0].type = CKA_ID;
2156 a[0].value = certid_tmp;
2157 a[0].value_len = sizeof (certid_tmp);
2159 _gnutls_buffer_init (&list->key_ids[current]);
2161 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2163 _gnutls_buffer_append_data (&list->key_ids[current],
2164 a[0].value, a[0].value_len);
2165 current++;
2168 if (current > list->key_ids_size)
2169 break;
2172 pkcs11_find_objects_final (module, pks);
2174 list->key_ids_size = current - 1;
2176 return 0;
2179 /* Recover certificate list from tokens */
2182 static int
2183 find_objs (struct ck_function_list * module, ck_session_handle_t pks,
2184 struct token_info *info, struct ck_info *lib_info, void *input)
2186 struct crt_find_data_st *find_data = input;
2187 struct ck_attribute a[4];
2188 struct ck_attribute *attr;
2189 ck_object_class_t class = (ck_object_class_t)-1;
2190 ck_certificate_type_t type = (ck_certificate_type_t)-1;
2191 unsigned int trusted;
2192 ck_rv_t rv;
2193 ck_object_handle_t obj;
2194 unsigned long count;
2195 uint8_t *cert_data;
2196 char certid_tmp[PKCS11_ID_SIZE];
2197 char label_tmp[PKCS11_LABEL_SIZE];
2198 int ret;
2199 struct pkey_list plist; /* private key holder */
2200 unsigned int i, tot_values = 0;
2202 if (info == NULL)
2203 { /* final call */
2204 if (find_data->current <= *find_data->n_list)
2205 ret = 0;
2206 else
2207 ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
2209 *find_data->n_list = find_data->current;
2211 return ret;
2214 /* do not bother reading the token if basic fields do not match
2216 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2217 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2219 gnutls_assert ();
2220 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2223 memset (&plist, 0, sizeof (plist));
2225 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2227 ret = find_privkeys (module, pks, info, &plist);
2228 if (ret < 0)
2230 gnutls_assert ();
2231 return ret;
2234 if (plist.key_ids_size == 0)
2236 gnutls_assert ();
2237 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2241 cert_data = gnutls_malloc (MAX_CERT_SIZE);
2242 if (cert_data == NULL)
2244 gnutls_assert ();
2245 return GNUTLS_E_MEMORY_ERROR;
2248 /* Find objects with cert class and X.509 cert type. */
2250 tot_values = 0;
2252 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL
2253 || find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2255 class = CKO_CERTIFICATE;
2256 type = CKC_X_509;
2257 trusted = 1;
2259 a[tot_values].type = CKA_CLASS;
2260 a[tot_values].value = &class;
2261 a[tot_values].value_len = sizeof class;
2262 tot_values++;
2264 a[tot_values].type = CKA_CERTIFICATE_TYPE;
2265 a[tot_values].value = &type;
2266 a[tot_values].value_len = sizeof type;
2267 tot_values++;
2270 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED)
2272 class = CKO_CERTIFICATE;
2273 type = CKC_X_509;
2274 trusted = 1;
2276 a[tot_values].type = CKA_CLASS;
2277 a[tot_values].value = &class;
2278 a[tot_values].value_len = sizeof class;
2279 tot_values++;
2281 a[tot_values].type = CKA_TRUSTED;
2282 a[tot_values].value = &trusted;
2283 a[tot_values].value_len = sizeof trusted;
2284 tot_values++;
2287 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PUBKEY)
2289 class = CKO_PUBLIC_KEY;
2291 a[tot_values].type = CKA_CLASS;
2292 a[tot_values].value = &class;
2293 a[tot_values].value_len = sizeof class;
2294 tot_values++;
2296 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
2298 class = CKO_PRIVATE_KEY;
2300 a[tot_values].type = CKA_CLASS;
2301 a[tot_values].value = &class;
2302 a[tot_values].value_len = sizeof class;
2303 tot_values++;
2305 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2307 if (class != (ck_object_class_t)-1)
2309 a[tot_values].type = CKA_CLASS;
2310 a[tot_values].value = &class;
2311 a[tot_values].value_len = sizeof class;
2312 tot_values++;
2314 if (type != (ck_certificate_type_t)-1)
2316 a[tot_values].type = CKA_CERTIFICATE_TYPE;
2317 a[tot_values].value = &type;
2318 a[tot_values].value_len = sizeof type;
2319 tot_values++;
2322 else
2324 gnutls_assert ();
2325 ret = GNUTLS_E_INVALID_REQUEST;
2326 goto fail;
2329 attr = p11_kit_uri_get_attribute (find_data->info, CKA_ID);
2330 if (attr != NULL)
2332 memcpy (a + tot_values, attr, sizeof (struct ck_attribute));
2333 tot_values++;
2336 rv = pkcs11_find_objects_init (module, pks, a, tot_values);
2337 if (rv != CKR_OK)
2339 gnutls_assert ();
2340 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
2341 return pkcs11_rv_to_err (rv);
2344 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
2346 gnutls_datum_t label, id, value;
2348 a[0].type = CKA_LABEL;
2349 a[0].value = label_tmp;
2350 a[0].value_len = sizeof label_tmp;
2352 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2354 label.data = a[0].value;
2355 label.size = a[0].value_len;
2357 else
2359 label.data = NULL;
2360 label.size = 0;
2363 a[0].type = CKA_ID;
2364 a[0].value = certid_tmp;
2365 a[0].value_len = sizeof certid_tmp;
2367 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2369 id.data = a[0].value;
2370 id.size = a[0].value_len;
2372 else
2374 id.data = NULL;
2375 id.size = 0;
2378 a[0].type = CKA_VALUE;
2379 a[0].value = cert_data;
2380 a[0].value_len = MAX_CERT_SIZE;
2381 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2383 value.data = a[0].value;
2384 value.size = a[0].value_len;
2386 else
2388 value.data = NULL;
2389 value.size = 0;
2392 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2394 a[0].type = CKA_CLASS;
2395 a[0].value = &class;
2396 a[0].value_len = sizeof class;
2398 pkcs11_get_attribute_value (module, pks, obj, a, 1);
2401 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2403 for (i = 0; i < plist.key_ids_size; i++)
2405 if (plist.key_ids[i].length !=
2406 a[1].value_len
2407 || memcmp (plist.key_ids[i].data,
2408 a[1].value, a[1].value_len) != 0)
2410 /* not found */
2411 continue;
2416 if (find_data->current < *find_data->n_list)
2418 ret =
2419 gnutls_pkcs11_obj_init (&find_data->p_list[find_data->current]);
2420 if (ret < 0)
2422 gnutls_assert ();
2423 goto fail;
2426 if (class == CKO_PUBLIC_KEY)
2428 ret =
2429 pkcs11_obj_import_pubkey (module, pks, obj,
2430 find_data->p_list
2431 [find_data->current],
2432 &id, &label,
2433 &info->tinfo, lib_info);
2435 else
2437 ret =
2438 pkcs11_obj_import (class,
2439 find_data->p_list
2440 [find_data->current],
2441 &value, &id, &label,
2442 &info->tinfo, lib_info);
2444 if (ret < 0)
2446 gnutls_assert ();
2447 goto fail;
2451 find_data->current++;
2455 gnutls_free (cert_data);
2456 pkcs11_find_objects_final (module, pks);
2458 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* continue until all tokens have been checked */
2460 fail:
2461 gnutls_free (cert_data);
2462 pkcs11_find_objects_final (module, pks);
2463 if (plist.key_ids != NULL)
2465 for (i = 0; i < plist.key_ids_size; i++)
2467 _gnutls_buffer_clear (&plist.key_ids[i]);
2469 gnutls_free (plist.key_ids);
2471 for (i = 0; i < find_data->current; i++)
2473 gnutls_pkcs11_obj_deinit (find_data->p_list[i]);
2475 find_data->current = 0;
2477 return ret;
2481 * gnutls_pkcs11_obj_list_import_url:
2482 * @p_list: An uninitialized object list (may be NULL)
2483 * @n_list: initially should hold the maximum size of the list. Will contain the actual size.
2484 * @url: A PKCS 11 url identifying a set of objects
2485 * @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
2486 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2488 * This function will initialize and set values to an object list
2489 * by using all objects identified by a PKCS 11 URL.
2491 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2492 * negative error value.
2494 * Since: 2.12.0
2497 gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list,
2498 unsigned int *n_list,
2499 const char *url,
2500 gnutls_pkcs11_obj_attr_t attrs,
2501 unsigned int flags)
2503 int ret;
2504 struct crt_find_data_st find_data;
2506 memset (&find_data, 0, sizeof (find_data));
2508 /* fill in the find data structure */
2509 find_data.p_list = p_list;
2510 find_data.n_list = n_list;
2511 find_data.flags = attrs;
2512 find_data.current = 0;
2514 if (url == NULL || url[0] == 0)
2516 url = "pkcs11:";
2519 ret = pkcs11_url_to_info (url, &find_data.info);
2520 if (ret < 0)
2522 gnutls_assert ();
2523 return ret;
2526 ret =
2527 _pkcs11_traverse_tokens (find_objs, &find_data, find_data.info,
2528 pkcs11_obj_flags_to_int (flags));
2529 p11_kit_uri_free (find_data.info);
2531 if (ret < 0)
2533 gnutls_assert ();
2534 return ret;
2537 return 0;
2541 * gnutls_x509_crt_import_pkcs11_url:
2542 * @crt: A certificate of type #gnutls_x509_crt_t
2543 * @url: A PKCS 11 url
2544 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2546 * This function will import a PKCS 11 certificate directly from a token
2547 * without involving the #gnutls_pkcs11_obj_t structure. This function will
2548 * fail if the certificate stored is not of X.509 type.
2550 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2551 * negative error value.
2553 * Since: 2.12.0
2556 gnutls_x509_crt_import_pkcs11_url (gnutls_x509_crt_t crt,
2557 const char *url, unsigned int flags)
2559 gnutls_pkcs11_obj_t pcrt;
2560 int ret;
2562 ret = gnutls_pkcs11_obj_init (&pcrt);
2563 if (ret < 0)
2565 gnutls_assert ();
2566 return ret;
2569 ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
2570 if (ret < 0)
2572 gnutls_assert ();
2573 goto cleanup;
2576 ret = gnutls_x509_crt_import (crt, &pcrt->raw, GNUTLS_X509_FMT_DER);
2577 if (ret < 0)
2579 gnutls_assert ();
2580 goto cleanup;
2583 ret = 0;
2584 cleanup:
2586 gnutls_pkcs11_obj_deinit (pcrt);
2588 return ret;
2593 * gnutls_x509_crt_import_pkcs11:
2594 * @crt: A certificate of type #gnutls_x509_crt_t
2595 * @pkcs11_crt: A PKCS 11 object that contains a certificate
2597 * This function will import a PKCS 11 certificate to a #gnutls_x509_crt_t
2598 * structure.
2600 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2601 * negative error value.
2603 * Since: 2.12.0
2606 gnutls_x509_crt_import_pkcs11 (gnutls_x509_crt_t crt,
2607 gnutls_pkcs11_obj_t pkcs11_crt)
2609 return gnutls_x509_crt_import (crt, &pkcs11_crt->raw, GNUTLS_X509_FMT_DER);
2613 * gnutls_x509_crt_list_import_pkcs11:
2614 * @certs: A list of certificates of type #gnutls_x509_crt_t
2615 * @cert_max: The maximum size of the list
2616 * @objs: A list of PKCS 11 objects
2617 * @flags: 0 for now
2619 * This function will import a PKCS 11 certificate list to a list of
2620 * #gnutls_x509_crt_t structure. These must not be initialized.
2622 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2623 * negative error value.
2625 * Since: 2.12.0
2628 gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
2629 unsigned int cert_max,
2630 gnutls_pkcs11_obj_t * const objs,
2631 unsigned int flags)
2633 unsigned int i, j;
2634 int ret;
2636 for (i = 0; i < cert_max; i++)
2638 ret = gnutls_x509_crt_init (&certs[i]);
2639 if (ret < 0)
2641 gnutls_assert ();
2642 goto cleanup;
2645 ret = gnutls_x509_crt_import_pkcs11 (certs[i], objs[i]);
2646 if (ret < 0)
2648 gnutls_assert ();
2649 goto cleanup;
2653 return 0;
2655 cleanup:
2656 for (j = 0; j < i; j++)
2658 gnutls_x509_crt_deinit (certs[j]);
2661 return ret;
2664 static int
2665 find_flags (struct ck_function_list * module, ck_session_handle_t pks,
2666 struct token_info *info, struct ck_info *lib_info, void *input)
2668 struct flags_find_data_st *find_data = input;
2670 if (info == NULL)
2671 { /* we don't support multiple calls */
2672 gnutls_assert ();
2673 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2676 /* do not bother reading the token if basic fields do not match
2678 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2679 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2681 gnutls_assert ();
2682 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2685 /* found token! */
2687 find_data->slot_flags = info->sinfo.flags;
2689 return 0;
2693 * gnutls_pkcs11_token_get_flags:
2694 * @url: should contain a PKCS 11 URL
2695 * @flags: The output flags (GNUTLS_PKCS11_TOKEN_*)
2697 * This function will return information about the PKCS 11 token flags.
2698 * The flags from the %gnutls_pkcs11_token_info_t enumeration.
2700 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
2702 * Since: 2.12.0
2705 gnutls_pkcs11_token_get_flags (const char *url, unsigned int *flags)
2707 struct flags_find_data_st find_data;
2708 int ret;
2710 memset (&find_data, 0, sizeof (find_data));
2711 ret = pkcs11_url_to_info (url, &find_data.info);
2712 if (ret < 0)
2714 gnutls_assert ();
2715 return ret;
2718 ret = _pkcs11_traverse_tokens (find_flags, &find_data, find_data.info, 0);
2719 p11_kit_uri_free (find_data.info);
2721 if (ret < 0)
2723 gnutls_assert ();
2724 return ret;
2727 *flags = 0;
2728 if (find_data.slot_flags & CKF_HW_SLOT)
2729 *flags |= GNUTLS_PKCS11_TOKEN_HW;
2731 return 0;
2736 * gnutls_pkcs11_token_get_mechanism:
2737 * @url: should contain a PKCS 11 URL
2738 * @idx: The index of the mechanism
2739 * @mechanism: The PKCS #11 mechanism ID
2741 * This function will return the names of the supported mechanisms
2742 * by the token. It should be called with an increasing index until
2743 * it return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.
2745 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
2747 * Since: 2.12.0
2750 gnutls_pkcs11_token_get_mechanism (const char *url, unsigned int idx,
2751 unsigned long *mechanism)
2753 int ret;
2754 ck_rv_t rv;
2755 struct ck_function_list *module;
2756 ck_slot_id_t slot;
2757 struct token_info tinfo;
2758 struct p11_kit_uri *info = NULL;
2759 unsigned long count;
2760 ck_mechanism_type_t mlist[400];
2762 ret = pkcs11_url_to_info (url, &info);
2763 if (ret < 0)
2765 gnutls_assert ();
2766 return ret;
2770 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
2771 p11_kit_uri_free (info);
2773 if (ret < 0)
2775 gnutls_assert ();
2776 return ret;
2779 count = sizeof (mlist) / sizeof (mlist[0]);
2780 rv = pkcs11_get_mechanism_list (module, slot, mlist, &count);
2781 if (rv != CKR_OK)
2783 gnutls_assert ();
2784 return pkcs11_rv_to_err (rv);
2787 if (idx >= count)
2789 gnutls_assert ();
2790 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2793 *mechanism = mlist[idx];
2795 return 0;
2800 * gnutls_pkcs11_type_get_name:
2801 * @type: Holds the PKCS 11 object type, a #gnutls_pkcs11_obj_type_t.
2803 * This function will return a human readable description of the
2804 * PKCS11 object type @obj. It will return "Unknown" for unknown
2805 * types.
2807 * Returns: human readable string labeling the PKCS11 object type
2808 * @type.
2810 * Since: 2.12.0
2812 const char *
2813 gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t type)
2815 switch (type)
2817 case GNUTLS_PKCS11_OBJ_X509_CRT:
2818 return "X.509 Certificate";
2819 case GNUTLS_PKCS11_OBJ_PUBKEY:
2820 return "Public key";
2821 case GNUTLS_PKCS11_OBJ_PRIVKEY:
2822 return "Private key";
2823 case GNUTLS_PKCS11_OBJ_SECRET_KEY:
2824 return "Secret key";
2825 case GNUTLS_PKCS11_OBJ_DATA:
2826 return "Data";
2827 case GNUTLS_PKCS11_OBJ_UNKNOWN:
2828 default:
2829 return "Unknown";
2833 ck_rv_t
2834 pkcs11_get_slot_list (struct ck_function_list * module, unsigned char token_present,
2835 ck_slot_id_t *slot_list, unsigned long *count)
2837 return (module)->C_GetSlotList (token_present, slot_list, count);
2840 ck_rv_t
2841 pkcs11_get_module_info (struct ck_function_list * module,
2842 struct ck_info * info)
2844 return (module)->C_GetInfo (info);
2847 ck_rv_t
2848 pkcs11_get_slot_info(struct ck_function_list * module,
2849 ck_slot_id_t slot_id,
2850 struct ck_slot_info *info)
2852 return (module)->C_GetSlotInfo (slot_id, info);
2855 ck_rv_t
2856 pkcs11_get_token_info (struct ck_function_list * module,
2857 ck_slot_id_t slot_id,
2858 struct ck_token_info *info)
2860 return (module)->C_GetTokenInfo (slot_id, info);
2863 ck_rv_t
2864 pkcs11_find_objects_init (struct ck_function_list *module,
2865 ck_session_handle_t sess,
2866 struct ck_attribute *templ,
2867 unsigned long count)
2869 return (module)->C_FindObjectsInit (sess, templ, count);
2872 ck_rv_t
2873 pkcs11_find_objects (struct ck_function_list *module,
2874 ck_session_handle_t sess,
2875 ck_object_handle_t *objects,
2876 unsigned long max_object_count,
2877 unsigned long *object_count)
2879 return (module)->C_FindObjects (sess, objects, max_object_count, object_count);
2882 ck_rv_t
2883 pkcs11_find_objects_final (struct ck_function_list *module,
2884 ck_session_handle_t sess)
2886 return (module)->C_FindObjectsFinal (sess);
2889 ck_rv_t
2890 pkcs11_close_session (struct ck_function_list *module,
2891 ck_session_handle_t sess)
2893 return (module)->C_CloseSession (sess);
2896 ck_rv_t
2897 pkcs11_get_attribute_value(struct ck_function_list *module,
2898 ck_session_handle_t sess,
2899 ck_object_handle_t object,
2900 struct ck_attribute *templ,
2901 unsigned long count)
2903 return (module)->C_GetAttributeValue (sess, object, templ, count);
2906 ck_rv_t
2907 pkcs11_get_mechanism_list (struct ck_function_list *module,
2908 ck_slot_id_t slot_id,
2909 ck_mechanism_type_t *mechanism_list,
2910 unsigned long *count)
2912 return (module)->C_GetMechanismList (slot_id, mechanism_list, count);
2915 ck_rv_t
2916 pkcs11_sign_init (struct ck_function_list *module,
2917 ck_session_handle_t sess,
2918 struct ck_mechanism *mechanism,
2919 ck_object_handle_t key)
2921 return (module)->C_SignInit (sess, mechanism, key);
2924 ck_rv_t
2925 pkcs11_sign (struct ck_function_list *module,
2926 ck_session_handle_t sess,
2927 unsigned char *data,
2928 unsigned long data_len,
2929 unsigned char *signature,
2930 unsigned long *signature_len)
2932 return (module)->C_Sign (sess, data, data_len, signature, signature_len);
2935 ck_rv_t
2936 pkcs11_generate_key_pair (struct ck_function_list *module,
2937 ck_session_handle_t sess,
2938 struct ck_mechanism *mechanism,
2939 struct ck_attribute *pub_templ,
2940 unsigned long pub_templ_count,
2941 struct ck_attribute *priv_templ,
2942 unsigned long priv_templ_count,
2943 ck_object_handle_t *pub,
2944 ck_object_handle_t *priv)
2946 return (module)->C_GenerateKeyPair (sess, mechanism, pub_templ, pub_templ_count,
2947 priv_templ, priv_templ_count, pub, priv);
2950 ck_rv_t
2951 pkcs11_decrypt_init (struct ck_function_list *module,
2952 ck_session_handle_t sess,
2953 struct ck_mechanism *mechanism,
2954 ck_object_handle_t key)
2956 return (module)->C_DecryptInit (sess, mechanism, key);
2959 ck_rv_t
2960 pkcs11_decrypt (struct ck_function_list *module,
2961 ck_session_handle_t sess,
2962 unsigned char *encrypted_data,
2963 unsigned long encrypted_data_len,
2964 unsigned char *data, unsigned long *data_len)
2966 return (module)->C_Decrypt (sess, encrypted_data, encrypted_data_len,
2967 data, data_len);
2970 ck_rv_t
2971 pkcs11_create_object (struct ck_function_list *module,
2972 ck_session_handle_t sess,
2973 struct ck_attribute *templ,
2974 unsigned long count,
2975 ck_object_handle_t *object)
2977 return (module)->C_CreateObject (sess, templ, count, object);
2980 ck_rv_t
2981 pkcs11_destroy_object (struct ck_function_list *module,
2982 ck_session_handle_t sess,
2983 ck_object_handle_t object)
2985 return (module)->C_DestroyObject (sess, object);
2988 ck_rv_t
2989 pkcs11_init_token (struct ck_function_list *module,
2990 ck_slot_id_t slot_id, unsigned char *pin,
2991 unsigned long pin_len, unsigned char *label)
2993 return (module)->C_InitToken (slot_id, pin, pin_len, label);
2996 ck_rv_t
2997 pkcs11_init_pin (struct ck_function_list *module,
2998 ck_session_handle_t sess,
2999 unsigned char *pin,
3000 unsigned long pin_len)
3002 return (module)->C_InitPIN (sess, pin, pin_len);
3005 ck_rv_t
3006 pkcs11_set_pin (struct ck_function_list *module,
3007 ck_session_handle_t sess,
3008 const char *old_pin,
3009 unsigned long old_len,
3010 const char *new_pin,
3011 unsigned long new_len)
3013 return (module)->C_SetPIN (sess, (uint8_t*)old_pin, old_len, (uint8_t*)new_pin, new_len);
3016 const char *
3017 pkcs11_strerror (ck_rv_t rv)
3019 return p11_kit_strerror (rv);