better function naming.
[gnutls.git] / lib / pkcs11.c
blob4897f629e956f6008c220e7ea42e77b924729a2b
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 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;
640 * gnutls_pkcs11_set_pin_function:
641 * @fn: The PIN callback, a gnutls_pkcs11_pin_callback_t() function.
642 * @userdata: data to be supplied to callback
644 * This function will set a callback function to be used when a PIN is
645 * required for PKCS 11 operations. See
646 * gnutls_pkcs11_pin_callback_t() on how the callback should behave.
648 * Since: 2.12.0
650 void
651 gnutls_pkcs11_set_pin_function (gnutls_pkcs11_pin_callback_t fn,
652 void *userdata)
654 pin_func = fn;
655 pin_data = userdata;
659 * gnutls_pkcs11_set_token_function:
660 * @fn: The token callback
661 * @userdata: data to be supplied to callback
663 * This function will set a callback function to be used when a token
664 * needs to be inserted to continue PKCS 11 operations.
666 * Since: 2.12.0
668 void
669 gnutls_pkcs11_set_token_function (gnutls_pkcs11_token_callback_t fn,
670 void *userdata)
672 token_func = fn;
673 token_data = userdata;
677 pkcs11_url_to_info (const char *url, struct p11_kit_uri **info)
679 int allocated = 0;
680 int ret;
682 if (*info == NULL)
684 *info = p11_kit_uri_new ();
685 if (*info == NULL)
687 gnutls_assert ();
688 return GNUTLS_E_MEMORY_ERROR;
690 allocated = 1;
693 ret = p11_kit_uri_parse (url, P11_KIT_URI_FOR_ANY, *info);
694 if (ret < 0)
696 if (allocated)
698 p11_kit_uri_free (*info);
699 *info = NULL;
701 gnutls_assert ();
702 return ret == P11_KIT_URI_NO_MEMORY ?
703 GNUTLS_E_MEMORY_ERROR : GNUTLS_E_PARSING_ERROR;
706 return 0;
710 pkcs11_info_to_url (struct p11_kit_uri *info,
711 gnutls_pkcs11_url_type_t detailed, char **url)
713 p11_kit_uri_type_t type = 0;
714 int ret;
716 switch (detailed)
718 case GNUTLS_PKCS11_URL_GENERIC:
719 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN;
720 break;
721 case GNUTLS_PKCS11_URL_LIB:
722 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE;
723 break;
724 case GNUTLS_PKCS11_URL_LIB_VERSION:
725 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE | P11_KIT_URI_FOR_MODULE_WITH_VERSION;
726 break;
729 ret = p11_kit_uri_format (info, type, url);
730 if (ret < 0)
732 gnutls_assert ();
733 return ret == P11_KIT_URI_NO_MEMORY ?
734 GNUTLS_E_MEMORY_ERROR : GNUTLS_E_INTERNAL_ERROR;
737 return 0;
741 * gnutls_pkcs11_obj_init:
742 * @obj: The structure to be initialized
744 * This function will initialize a pkcs11 certificate structure.
746 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
747 * negative error value.
749 * Since: 2.12.0
752 gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t * obj)
754 *obj = gnutls_calloc (1, sizeof (struct gnutls_pkcs11_obj_st));
755 if (*obj == NULL)
757 gnutls_assert ();
758 return GNUTLS_E_MEMORY_ERROR;
761 (*obj)->info = p11_kit_uri_new ();
762 if ((*obj)->info == NULL)
764 free (*obj);
765 gnutls_assert ();
766 return GNUTLS_E_MEMORY_ERROR;
769 return 0;
773 * gnutls_pkcs11_obj_deinit:
774 * @obj: The structure to be initialized
776 * This function will deinitialize a certificate structure.
778 * Since: 2.12.0
780 void
781 gnutls_pkcs11_obj_deinit (gnutls_pkcs11_obj_t obj)
783 _gnutls_free_datum (&obj->raw);
784 p11_kit_uri_free (obj->info);
785 free (obj);
789 * gnutls_pkcs11_obj_export:
790 * @obj: Holds the object
791 * @output_data: will contain a certificate PEM or DER encoded
792 * @output_data_size: holds the size of output_data (and will be
793 * replaced by the actual size of parameters)
795 * This function will export the PKCS11 object data. It is normal for
796 * data to be inaccesible and in that case %GNUTLS_E_INVALID_REQUEST
797 * will be returned.
799 * If the buffer provided is not long enough to hold the output, then
800 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
801 * be returned.
803 * If the structure is PEM encoded, it will have a header
804 * of "BEGIN CERTIFICATE".
806 * Returns: In case of failure a negative error code will be
807 * returned, and %GNUTLS_E_SUCCESS (0) on success.
809 * Since: 2.12.0
812 gnutls_pkcs11_obj_export (gnutls_pkcs11_obj_t obj,
813 void *output_data, size_t * output_data_size)
815 if (obj == NULL || obj->raw.data == NULL)
817 gnutls_assert ();
818 return GNUTLS_E_INVALID_REQUEST;
821 if (output_data == NULL || *output_data_size < obj->raw.size)
823 *output_data_size = obj->raw.size;
824 gnutls_assert ();
825 return GNUTLS_E_SHORT_MEMORY_BUFFER;
827 *output_data_size = obj->raw.size;
829 memcpy (output_data, obj->raw.data, obj->raw.size);
830 return 0;
834 pkcs11_find_object (struct ck_function_list ** _module,
835 ck_session_handle_t * _pks,
836 ck_object_handle_t * _obj,
837 struct p11_kit_uri *info, unsigned int flags)
839 int ret;
840 struct ck_function_list *module;
841 ck_session_handle_t pks;
842 ck_object_handle_t obj;
843 struct ck_attribute *attrs;
844 unsigned long attr_count;
845 unsigned long count;
846 ck_rv_t rv;
848 ret = pkcs11_open_session (&module, &pks, info, flags & SESSION_LOGIN);
849 if (ret < 0)
851 gnutls_assert ();
852 return ret;
855 attrs = p11_kit_uri_get_attributes (info, &attr_count);
856 rv = pkcs11_find_objects_init (module, pks, attrs, attr_count);
857 if (rv != CKR_OK)
859 gnutls_assert ();
860 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
861 ret = pkcs11_rv_to_err (rv);
862 goto fail;
865 if (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
867 *_obj = obj;
868 *_pks = pks;
869 *_module = module;
870 pkcs11_find_objects_final (module, pks);
871 return 0;
874 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
875 pkcs11_find_objects_final (module, pks);
876 fail:
877 pkcs11_close_session (module, pks);
879 return ret;
883 pkcs11_find_slot (struct ck_function_list ** module, ck_slot_id_t * slot,
884 struct p11_kit_uri *info, struct token_info *_tinfo)
886 unsigned int x, z;
888 for (x = 0; x < active_providers; x++)
890 for (z = 0; z < providers[x].nslots; z++)
892 struct token_info tinfo;
894 if (pkcs11_get_token_info
895 (providers[x].module, providers[x].slots[z],
896 &tinfo.tinfo) != CKR_OK)
898 continue;
900 tinfo.sid = providers[x].slots[z];
901 tinfo.prov = &providers[x];
903 if (pkcs11_get_slot_info
904 (providers[x].module, providers[x].slots[z],
905 &tinfo.sinfo) != CKR_OK)
907 continue;
910 if (!p11_kit_uri_match_token_info (info, &tinfo.tinfo) ||
911 !p11_kit_uri_match_module_info (info, &providers[x].info))
913 continue;
916 /* ok found */
917 *module = providers[x].module;
918 *slot = providers[x].slots[z];
920 if (_tinfo != NULL)
921 memcpy (_tinfo, &tinfo, sizeof (tinfo));
923 return 0;
927 gnutls_assert ();
928 return GNUTLS_E_PKCS11_REQUESTED_OBJECT_NOT_AVAILBLE;
932 pkcs11_open_session (struct ck_function_list ** _module, ck_session_handle_t * _pks,
933 struct p11_kit_uri *info, unsigned int flags)
935 ck_rv_t rv;
936 int ret;
937 ck_session_handle_t pks = 0;
938 struct ck_function_list *module;
939 ck_slot_id_t slot;
940 struct token_info tinfo;
942 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
943 if (ret < 0)
945 gnutls_assert ();
946 return ret;
949 rv = (module)->C_OpenSession (slot,
950 ((flags & SESSION_WRITE)
951 ? CKF_RW_SESSION : 0) |
952 CKF_SERIAL_SESSION, NULL, NULL, &pks);
953 if (rv != CKR_OK)
955 gnutls_assert ();
956 return pkcs11_rv_to_err (rv);
959 if (flags & SESSION_LOGIN)
961 ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
962 if (ret < 0)
964 gnutls_assert ();
965 pkcs11_close_session (module, pks);
966 return ret;
970 /* ok found */
971 *_pks = pks;
972 *_module = module;
973 return 0;
978 _pkcs11_traverse_tokens (find_func_t find_func, void *input,
979 struct p11_kit_uri *info, unsigned int flags)
981 ck_rv_t rv;
982 unsigned int found = 0, x, z;
983 int ret;
984 ck_session_handle_t pks = 0;
985 struct ck_function_list *module = NULL;
987 for (x = 0; x < active_providers; x++)
989 module = providers[x].module;
990 for (z = 0; z < providers[x].nslots; z++)
992 struct token_info tinfo;
994 ret = GNUTLS_E_PKCS11_ERROR;
996 if (pkcs11_get_token_info (module, providers[x].slots[z],
997 &tinfo.tinfo) != CKR_OK)
999 continue;
1001 tinfo.sid = providers[x].slots[z];
1002 tinfo.prov = &providers[x];
1004 if (pkcs11_get_slot_info (module, providers[x].slots[z],
1005 &tinfo.sinfo) != CKR_OK)
1007 continue;
1010 rv = (module)->C_OpenSession (providers[x].slots[z],
1011 ((flags & SESSION_WRITE)
1012 ? CKF_RW_SESSION : 0) |
1013 CKF_SERIAL_SESSION, NULL, NULL, &pks);
1014 if (rv != CKR_OK)
1016 continue;
1019 if (flags & SESSION_LOGIN)
1021 ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
1022 if (ret < 0)
1024 gnutls_assert ();
1025 return ret;
1029 ret = find_func (module, pks, &tinfo, &providers[x].info, input);
1031 if (ret == 0)
1033 found = 1;
1034 goto finish;
1036 else
1038 pkcs11_close_session (module, pks);
1039 pks = 0;
1044 finish:
1045 /* final call */
1047 if (found == 0)
1049 if (module)
1050 ret = find_func (module, pks, NULL, NULL, input);
1051 else
1052 ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1054 else
1056 ret = 0;
1059 if (pks != 0 && module != NULL)
1061 pkcs11_close_session (module, pks);
1064 return ret;
1067 /* imports a raw certificate from a token to a pkcs11_obj_t structure.
1069 static int
1070 pkcs11_obj_import (ck_object_class_t class, gnutls_pkcs11_obj_t obj,
1071 const gnutls_datum_t * data,
1072 const gnutls_datum_t * id,
1073 const gnutls_datum_t * label,
1074 struct ck_token_info *tinfo, struct ck_info *lib_info)
1076 struct ck_attribute attr;
1077 int ret;
1079 switch (class)
1081 case CKO_CERTIFICATE:
1082 obj->type = GNUTLS_PKCS11_OBJ_X509_CRT;
1083 break;
1084 case CKO_PUBLIC_KEY:
1085 obj->type = GNUTLS_PKCS11_OBJ_PUBKEY;
1086 break;
1087 case CKO_PRIVATE_KEY:
1088 obj->type = GNUTLS_PKCS11_OBJ_PRIVKEY;
1089 break;
1090 case CKO_SECRET_KEY:
1091 obj->type = GNUTLS_PKCS11_OBJ_SECRET_KEY;
1092 break;
1093 case CKO_DATA:
1094 obj->type = GNUTLS_PKCS11_OBJ_DATA;
1095 break;
1096 default:
1097 obj->type = GNUTLS_PKCS11_OBJ_UNKNOWN;
1100 attr.type = CKA_CLASS;
1101 attr.value = &class;
1102 attr.value_len = sizeof (class);
1103 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1104 if (ret < 0)
1106 gnutls_assert ();
1107 return GNUTLS_E_MEMORY_ERROR;
1110 if (data && data->data)
1112 ret = _gnutls_set_datum (&obj->raw, data->data, data->size);
1113 if (ret < 0)
1115 gnutls_assert ();
1116 return ret;
1120 /* copy the token and library info into the uri */
1121 memcpy (p11_kit_uri_get_token_info (obj->info), tinfo, sizeof (struct ck_token_info));
1122 memcpy (p11_kit_uri_get_module_info (obj->info), lib_info, sizeof (struct ck_info));
1124 if (label && label->data)
1126 attr.type = CKA_LABEL;
1127 attr.value = label->data;
1128 attr.value_len = label->size;
1129 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1130 if (ret < 0)
1132 gnutls_assert ();
1133 return GNUTLS_E_MEMORY_ERROR;
1137 if (id && id->data)
1139 attr.type = CKA_ID;
1140 attr.value = id->data;
1141 attr.value_len = id->size;
1142 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1143 if (ret < 0)
1145 gnutls_assert ();
1146 return GNUTLS_E_MEMORY_ERROR;
1150 return 0;
1153 static int read_pkcs11_pubkey(struct ck_function_list *module,
1154 ck_session_handle_t pks, ck_object_handle_t obj,
1155 ck_key_type_t key_type, gnutls_datum_t * pubkey)
1157 struct ck_attribute a[4];
1158 uint8_t tmp1[2048];
1159 uint8_t tmp2[2048];
1160 int ret;
1162 switch (key_type)
1164 case CKK_RSA:
1165 a[0].type = CKA_MODULUS;
1166 a[0].value = tmp1;
1167 a[0].value_len = sizeof (tmp1);
1168 a[1].type = CKA_PUBLIC_EXPONENT;
1169 a[1].value = tmp2;
1170 a[1].value_len = sizeof (tmp2);
1172 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1175 ret =
1176 _gnutls_set_datum (&pubkey[0],
1177 a[0].value, a[0].value_len);
1179 if (ret >= 0)
1180 ret =
1181 _gnutls_set_datum (&pubkey
1182 [1], a[1].value, a[1].value_len);
1184 if (ret < 0)
1186 gnutls_assert ();
1187 _gnutls_free_datum (&pubkey[1]);
1188 _gnutls_free_datum (&pubkey[0]);
1189 return GNUTLS_E_MEMORY_ERROR;
1192 else
1194 gnutls_assert ();
1195 return GNUTLS_E_PKCS11_ERROR;
1197 break;
1198 case CKK_DSA:
1199 a[0].type = CKA_PRIME;
1200 a[0].value = tmp1;
1201 a[0].value_len = sizeof (tmp1);
1202 a[1].type = CKA_SUBPRIME;
1203 a[1].value = tmp2;
1204 a[1].value_len = sizeof (tmp2);
1206 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1208 ret =
1209 _gnutls_set_datum (&pubkey[0],
1210 a[0].value, a[0].value_len);
1212 if (ret >= 0)
1213 ret =
1214 _gnutls_set_datum (&pubkey
1215 [1], a[1].value, a[1].value_len);
1217 if (ret < 0)
1219 gnutls_assert ();
1220 _gnutls_free_datum (&pubkey[1]);
1221 _gnutls_free_datum (&pubkey[0]);
1222 return GNUTLS_E_MEMORY_ERROR;
1225 else
1227 gnutls_assert ();
1228 return GNUTLS_E_PKCS11_ERROR;
1231 a[0].type = CKA_BASE;
1232 a[0].value = tmp1;
1233 a[0].value_len = sizeof (tmp1);
1234 a[1].type = CKA_VALUE;
1235 a[1].value = tmp2;
1236 a[1].value_len = sizeof (tmp2);
1238 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1240 ret =
1241 _gnutls_set_datum (&pubkey[2],
1242 a[0].value, a[0].value_len);
1244 if (ret >= 0)
1245 ret =
1246 _gnutls_set_datum (&pubkey
1247 [3], a[1].value, a[1].value_len);
1249 if (ret < 0)
1251 gnutls_assert ();
1252 _gnutls_free_datum (&pubkey[0]);
1253 _gnutls_free_datum (&pubkey[1]);
1254 _gnutls_free_datum (&pubkey[2]);
1255 _gnutls_free_datum (&pubkey[3]);
1256 return GNUTLS_E_MEMORY_ERROR;
1259 else
1261 gnutls_assert ();
1262 return GNUTLS_E_PKCS11_ERROR;
1264 break;
1265 case CKK_ECDSA:
1266 a[0].type = CKA_EC_PARAMS;
1267 a[0].value = tmp1;
1268 a[0].value_len = sizeof (tmp1);
1269 a[1].type = CKA_EC_POINT;
1270 a[1].value = tmp2;
1271 a[1].value_len = sizeof (tmp2);
1273 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1275 ret =
1276 _gnutls_set_datum (&pubkey[0],
1277 a[0].value, a[0].value_len);
1279 if (ret >= 0)
1280 ret =
1281 _gnutls_set_datum (&pubkey
1282 [1], a[1].value, a[1].value_len);
1284 if (ret < 0)
1286 gnutls_assert ();
1287 _gnutls_free_datum (&pubkey[1]);
1288 _gnutls_free_datum (&pubkey[0]);
1289 return GNUTLS_E_MEMORY_ERROR;
1292 else
1294 gnutls_assert ();
1295 return GNUTLS_E_PKCS11_ERROR;
1298 break;
1299 default:
1300 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1303 return 0;
1306 static int
1307 pkcs11_obj_import_pubkey (struct ck_function_list *module,
1308 ck_session_handle_t pks,
1309 ck_object_handle_t obj,
1310 gnutls_pkcs11_obj_t crt,
1311 const gnutls_datum_t * id,
1312 const gnutls_datum_t * label,
1313 struct ck_token_info *tinfo,
1314 struct ck_info *lib_info)
1316 struct ck_attribute a[4];
1317 ck_key_type_t key_type;
1318 int ret;
1319 ck_bool_t tval;
1321 a[0].type = CKA_KEY_TYPE;
1322 a[0].value = &key_type;
1323 a[0].value_len = sizeof (key_type);
1325 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1327 crt->pk_algorithm = mech_to_pk(key_type);
1329 ret = read_pkcs11_pubkey(module, pks, obj, key_type, crt->pubkey);
1330 if (ret < 0)
1331 return gnutls_assert_val(ret);
1334 /* read key usage flags */
1335 a[0].type = CKA_ENCRYPT;
1336 a[0].value = &tval;
1337 a[0].value_len = sizeof (tval);
1339 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1341 if (tval != 0)
1343 crt->key_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
1347 a[0].type = CKA_VERIFY;
1348 a[0].value = &tval;
1349 a[0].value_len = sizeof (tval);
1351 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1353 if (tval != 0)
1355 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1356 GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1357 | GNUTLS_KEY_NON_REPUDIATION;
1361 a[0].type = CKA_VERIFY_RECOVER;
1362 a[0].value = &tval;
1363 a[0].value_len = sizeof (tval);
1365 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1367 if (tval != 0)
1369 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1370 GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1371 | GNUTLS_KEY_NON_REPUDIATION;
1375 a[0].type = CKA_DERIVE;
1376 a[0].value = &tval;
1377 a[0].value_len = sizeof (tval);
1379 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1381 if (tval != 0)
1383 crt->key_usage |= GNUTLS_KEY_KEY_AGREEMENT;
1387 a[0].type = CKA_WRAP;
1388 a[0].value = &tval;
1389 a[0].value_len = sizeof (tval);
1391 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1393 if (tval != 0)
1395 crt->key_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
1399 return pkcs11_obj_import (CKO_PUBLIC_KEY, crt, NULL, id, label,
1400 tinfo, lib_info);
1403 static int
1404 find_obj_url (struct ck_function_list *module, ck_session_handle_t pks,
1405 struct token_info *info, struct ck_info *lib_info, void *input)
1407 struct url_find_data_st *find_data = input;
1408 struct ck_attribute a[4];
1409 struct ck_attribute *attr;
1410 ck_object_class_t class = -1;
1411 ck_certificate_type_t type = (ck_certificate_type_t)-1;
1412 ck_rv_t rv;
1413 ck_object_handle_t obj;
1414 unsigned long count, a_vals;
1415 int found = 0, ret;
1416 uint8_t *cert_data = NULL;
1417 char label_tmp[PKCS11_LABEL_SIZE];
1419 if (info == NULL)
1420 { /* we don't support multiple calls */
1421 gnutls_assert ();
1422 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1425 /* do not bother reading the token if basic fields do not match
1427 if (!p11_kit_uri_match_token_info (find_data->crt->info, &info->tinfo) ||
1428 !p11_kit_uri_match_module_info (find_data->crt->info, lib_info))
1430 gnutls_assert ();
1431 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1434 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID);
1435 if (attr == NULL)
1437 gnutls_assert ();
1438 return GNUTLS_E_INVALID_REQUEST;
1441 /* search the token for the id */
1443 cert_data = gnutls_malloc (MAX_CERT_SIZE);
1444 if (cert_data == NULL)
1446 gnutls_assert ();
1447 return GNUTLS_E_MEMORY_ERROR;
1450 /* Find objects with given class and type */
1451 memcpy (a, attr, sizeof (struct ck_attribute));
1452 a_vals = 1;
1454 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_CLASS);
1455 if (attr)
1457 if(attr->value && attr->value_len == sizeof (ck_object_class_t))
1458 class = *((ck_object_class_t*)attr->value);
1459 if (class == CKO_CERTIFICATE)
1460 type = CKC_X_509;
1461 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1462 a_vals++;
1465 if (type != (ck_certificate_type_t)-1)
1467 a[a_vals].type = CKA_CERTIFICATE_TYPE;
1468 a[a_vals].value = &type;
1469 a[a_vals].value_len = sizeof type;
1470 a_vals++;
1473 rv = pkcs11_find_objects_init (module, pks, a, a_vals);
1474 if (rv != CKR_OK)
1476 gnutls_assert ();
1477 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
1478 ret = pkcs11_rv_to_err (rv);
1479 goto cleanup;
1482 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
1485 a[0].type = CKA_VALUE;
1486 a[0].value = cert_data;
1487 a[0].value_len = MAX_CERT_SIZE;
1488 a[1].type = CKA_LABEL;
1489 a[1].value = label_tmp;
1490 a[1].value_len = sizeof (label_tmp);
1492 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1494 gnutls_datum_t id;
1495 gnutls_datum_t data = { a[0].value, a[0].value_len };
1496 gnutls_datum_t label = { a[1].value, a[1].value_len };
1498 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID);
1499 id.data = attr->value;
1500 id.size = attr->value_len;
1502 if (class == CKO_PUBLIC_KEY)
1504 ret =
1505 pkcs11_obj_import_pubkey (module, pks, obj,
1506 find_data->crt,
1507 &id, &label,
1508 &info->tinfo, lib_info);
1510 else
1512 ret =
1513 pkcs11_obj_import (class,
1514 find_data->crt,
1515 &data, &id, &label,
1516 &info->tinfo, lib_info);
1518 if (ret < 0)
1520 gnutls_assert ();
1521 goto cleanup;
1524 found = 1;
1525 break;
1527 else
1529 _gnutls_debug_log ("pk11: Skipped cert, missing attrs.\n");
1533 if (found == 0)
1535 gnutls_assert ();
1536 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1538 else
1540 ret = 0;
1543 cleanup:
1544 gnutls_free (cert_data);
1545 pkcs11_find_objects_final (module, pks);
1547 return ret;
1550 unsigned int
1551 pkcs11_obj_flags_to_int (unsigned int flags)
1553 unsigned int ret_flags = 0;
1555 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN)
1556 ret_flags |= SESSION_LOGIN;
1557 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO)
1558 ret_flags |= SESSION_LOGIN|SESSION_SO;
1560 return ret_flags;
1564 * gnutls_pkcs11_obj_import_url:
1565 * @cert: The structure to store the parsed certificate
1566 * @url: a PKCS 11 url identifying the key
1567 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1569 * This function will "import" a PKCS 11 URL identifying a certificate
1570 * key to the #gnutls_pkcs11_obj_t structure. This does not involve any
1571 * parsing (such as X.509 or OpenPGP) since the #gnutls_pkcs11_obj_t is
1572 * format agnostic. Only data are transferred.
1574 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1575 * negative error value.
1577 * Since: 2.12.0
1580 gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t cert, const char *url,
1581 unsigned int flags)
1583 int ret;
1584 struct url_find_data_st find_data;
1586 /* fill in the find data structure */
1587 find_data.crt = cert;
1589 ret = pkcs11_url_to_info (url, &cert->info);
1590 if (ret < 0)
1592 gnutls_assert ();
1593 return ret;
1596 ret =
1597 _pkcs11_traverse_tokens (find_obj_url, &find_data, cert->info,
1598 pkcs11_obj_flags_to_int (flags));
1600 if (ret < 0)
1602 gnutls_assert ();
1603 return ret;
1606 return 0;
1609 struct token_num
1611 struct p11_kit_uri *info;
1612 unsigned int seq; /* which one we are looking for */
1613 unsigned int current; /* which one are we now */
1616 static int
1617 find_token_num (struct ck_function_list *module,
1618 ck_session_handle_t pks,
1619 struct token_info *tinfo,
1620 struct ck_info *lib_info, void *input)
1622 struct token_num *find_data = input;
1624 if (tinfo == NULL)
1625 { /* we don't support multiple calls */
1626 gnutls_assert ();
1627 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1630 if (find_data->current == find_data->seq)
1632 memcpy (p11_kit_uri_get_token_info (find_data->info), &tinfo->tinfo, sizeof (struct ck_token_info));
1633 memcpy (p11_kit_uri_get_module_info (find_data->info), lib_info, sizeof (struct ck_info));
1634 return 0;
1637 find_data->current++;
1638 /* search the token for the id */
1641 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* non zero is enough */
1645 * gnutls_pkcs11_token_get_url:
1646 * @seq: sequence number starting from 0
1647 * @detailed: non zero if a detailed URL is required
1648 * @url: will contain an allocated url
1650 * This function will return the URL for each token available
1651 * in system. The url has to be released using gnutls_free()
1653 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1654 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if the sequence number
1655 * exceeds the available tokens, otherwise a negative error value.
1657 * Since: 2.12.0
1660 gnutls_pkcs11_token_get_url (unsigned int seq,
1661 gnutls_pkcs11_url_type_t detailed, char **url)
1663 int ret;
1664 struct token_num tn;
1666 memset (&tn, 0, sizeof (tn));
1667 tn.seq = seq;
1668 tn.info = p11_kit_uri_new ();
1670 ret = _pkcs11_traverse_tokens (find_token_num, &tn, NULL, 0);
1671 if (ret < 0)
1673 p11_kit_uri_free (tn.info);
1674 gnutls_assert ();
1675 return ret;
1678 ret = pkcs11_info_to_url (tn.info, detailed, url);
1679 p11_kit_uri_free (tn.info);
1681 if (ret < 0)
1683 gnutls_assert ();
1684 return ret;
1687 return 0;
1692 * gnutls_pkcs11_token_get_info:
1693 * @url: should contain a PKCS 11 URL
1694 * @ttype: Denotes the type of information requested
1695 * @output: where output will be stored
1696 * @output_size: contains the maximum size of the output and will be overwritten with actual
1698 * This function will return information about the PKCS 11 token such
1699 * as the label, id, etc.
1701 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code
1702 * on error.
1704 * Since: 2.12.0
1707 gnutls_pkcs11_token_get_info (const char *url,
1708 gnutls_pkcs11_token_info_t ttype,
1709 void *output, size_t * output_size)
1711 struct p11_kit_uri *info = NULL;
1712 const uint8_t *str;
1713 size_t str_max;
1714 size_t len;
1715 int ret;
1717 ret = pkcs11_url_to_info (url, &info);
1718 if (ret < 0)
1720 gnutls_assert ();
1721 return ret;
1724 switch (ttype)
1726 case GNUTLS_PKCS11_TOKEN_LABEL:
1727 str = p11_kit_uri_get_token_info (info)->label;
1728 str_max = 32;
1729 break;
1730 case GNUTLS_PKCS11_TOKEN_SERIAL:
1731 str = p11_kit_uri_get_token_info (info)->serial_number;
1732 str_max = 16;
1733 break;
1734 case GNUTLS_PKCS11_TOKEN_MANUFACTURER:
1735 str = p11_kit_uri_get_token_info (info)->manufacturer_id;
1736 str_max = 32;
1737 break;
1738 case GNUTLS_PKCS11_TOKEN_MODEL:
1739 str = p11_kit_uri_get_token_info (info)->model;
1740 str_max = 16;
1741 break;
1742 default:
1743 p11_kit_uri_free (info);
1744 gnutls_assert ();
1745 return GNUTLS_E_INVALID_REQUEST;
1748 len = p11_kit_space_strlen (str, str_max);
1750 if (len + 1 > *output_size)
1752 *output_size = len + 1;
1753 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1756 memcpy (output, str, len);
1757 ((char*)output)[len] = '\0';
1759 *output_size = len;
1761 p11_kit_uri_free (info);
1762 return 0;
1766 * gnutls_pkcs11_obj_export_url:
1767 * @obj: Holds the PKCS 11 certificate
1768 * @detailed: non zero if a detailed URL is required
1769 * @url: will contain an allocated url
1771 * This function will export a URL identifying the given certificate.
1773 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1774 * negative error value.
1776 * Since: 2.12.0
1779 gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t obj,
1780 gnutls_pkcs11_url_type_t detailed, char **url)
1782 int ret;
1784 ret = pkcs11_info_to_url (obj->info, detailed, url);
1785 if (ret < 0)
1787 gnutls_assert ();
1788 return ret;
1791 return 0;
1795 * gnutls_pkcs11_obj_get_type:
1796 * @obj: Holds the PKCS 11 object
1798 * This function will return the type of the certificate being
1799 * stored in the structure.
1801 * Returns: The type of the certificate.
1803 * Since: 2.12.0
1805 gnutls_pkcs11_obj_type_t
1806 gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t obj)
1808 return obj->type;
1811 struct pkey_list
1813 gnutls_buffer_st *key_ids;
1814 size_t key_ids_size;
1818 static int
1819 retrieve_pin_from_source (const char *pinfile, struct ck_token_info *token_info,
1820 int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
1822 unsigned int flags = 0;
1823 struct p11_kit_uri *token_uri;
1824 struct p11_kit_pin *result;
1825 char *label;
1827 label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1828 if (label == NULL)
1830 gnutls_assert ();
1831 return GNUTLS_E_MEMORY_ERROR;
1834 token_uri = p11_kit_uri_new ();
1835 if (token_uri == NULL)
1837 free (label);
1838 gnutls_assert ();
1839 return GNUTLS_E_MEMORY_ERROR;
1842 memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1843 sizeof (struct ck_token_info));
1845 if (attempts)
1846 flags |= P11_KIT_PIN_FLAGS_RETRY;
1847 if (user_type == CKU_USER)
1849 flags |= P11_KIT_PIN_FLAGS_USER_LOGIN;
1850 if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1851 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1852 if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1853 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1855 else if (user_type == CKU_SO)
1857 flags |= P11_KIT_PIN_FLAGS_SO_LOGIN;
1858 if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
1859 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1860 if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
1861 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1863 else if (user_type == CKU_CONTEXT_SPECIFIC)
1865 flags |= P11_KIT_PIN_FLAGS_CONTEXT_LOGIN;
1868 result = p11_kit_pin_request (pinfile, token_uri, label, flags);
1869 p11_kit_uri_free (token_uri);
1870 free (label);
1872 if (result == NULL)
1874 gnutls_assert ();
1875 return GNUTLS_E_PKCS11_PIN_ERROR;
1878 *pin = result;
1879 return 0;
1882 static int
1883 retrieve_pin_for_callback (struct ck_token_info *token_info, int attempts,
1884 ck_user_type_t user_type, struct p11_kit_pin **pin)
1886 char pin_value[GNUTLS_PKCS11_MAX_PIN_LEN];
1887 unsigned int flags = 0;
1888 char *token_str;
1889 char *label;
1890 struct p11_kit_uri *token_uri;
1891 int ret = 0;
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));
1910 ret = pkcs11_info_to_url (token_uri, 1, &token_str);
1911 p11_kit_uri_free (token_uri);
1913 if (ret < 0)
1915 free (label);
1916 gnutls_assert ();
1917 return GNUTLS_E_MEMORY_ERROR;
1920 if (user_type == CKU_USER)
1922 flags |= GNUTLS_PKCS11_PIN_USER;
1923 if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1924 flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
1925 if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1926 flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
1928 else if (user_type == CKU_SO)
1930 flags |= GNUTLS_PKCS11_PIN_SO;
1931 if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
1932 flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
1933 if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
1934 flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
1937 if (attempts > 0)
1938 flags |= GNUTLS_PKCS11_PIN_WRONG;
1940 ret = pin_func (pin_data, attempts, (char*)token_str, label,
1941 flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
1942 free (token_str);
1943 free (label);
1945 if (ret < 0)
1946 return gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR);
1948 *pin = p11_kit_pin_new_for_string (pin_value);
1950 if (*pin == NULL)
1951 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1953 return 0;
1956 static int
1957 retrieve_pin (struct p11_kit_uri *info, struct ck_token_info *token_info,
1958 int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
1960 const char *pinfile;
1961 int ret = GNUTLS_E_PKCS11_PIN_ERROR;
1963 *pin = NULL;
1965 /* Check if a pinfile is specified, and use that if possible */
1966 pinfile = p11_kit_uri_get_pinfile (info);
1967 if (pinfile != NULL)
1969 _gnutls_debug_log("pk11: Using pinfile to retrieve PIN\n");
1970 ret = retrieve_pin_from_source (pinfile, token_info, attempts, user_type, pin);
1973 /* The global gnutls pin callback */
1974 if (pin_func && ret < 0)
1975 ret = retrieve_pin_for_callback (token_info, attempts, user_type, pin);
1977 /* Otherwise, PIN entry is necessary for login, so fail if there's
1978 * no callback. */
1980 if (ret < 0)
1982 gnutls_assert ();
1983 _gnutls_debug_log ("pk11: No suitable pin callback but login required.\n");
1986 return ret;
1990 pkcs11_login (struct ck_function_list * module, ck_session_handle_t pks,
1991 const struct token_info *tokinfo, struct p11_kit_uri *info, int so)
1993 struct ck_session_info session_info;
1994 int attempt = 0, ret;
1995 ck_user_type_t user_type;
1996 ck_rv_t rv;
1998 user_type = (so == 0) ? CKU_USER : CKU_SO;
1999 if (so == 0 && (tokinfo->tinfo.flags & CKF_LOGIN_REQUIRED) == 0)
2001 gnutls_assert ();
2002 _gnutls_debug_log ("pk11: No login required.\n");
2003 return 0;
2006 /* For a token with a "protected" (out-of-band) authentication
2007 * path, calling login with a NULL username is all that is
2008 * required. */
2009 if (tokinfo->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
2011 rv = (module)->C_Login (pks, (so == 0) ? CKU_USER : CKU_SO, NULL, 0);
2012 if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
2014 return 0;
2016 else
2018 gnutls_assert ();
2019 _gnutls_debug_log ("pk11: Protected login failed.\n");
2020 ret = GNUTLS_E_PKCS11_ERROR;
2021 goto cleanup;
2027 struct p11_kit_pin *pin;
2028 struct ck_token_info tinfo;
2030 memcpy (&tinfo, &tokinfo->tinfo, sizeof(tinfo));
2032 /* Check whether the session is already logged in, and if so, just skip */
2033 rv = (module)->C_GetSessionInfo (pks, &session_info);
2034 if (rv == CKR_OK && (session_info.state == CKS_RO_USER_FUNCTIONS ||
2035 session_info.state == CKS_RW_USER_FUNCTIONS))
2037 ret = 0;
2038 goto cleanup;
2041 /* If login has been attempted once already, check the token
2042 * status again, the flags might change. */
2043 if (attempt)
2045 if (pkcs11_get_token_info
2046 (tokinfo->prov->module, tokinfo->sid, &tinfo) != CKR_OK)
2048 gnutls_assert ();
2049 _gnutls_debug_log ("pk11: GetTokenInfo failed\n");
2050 ret = GNUTLS_E_PKCS11_ERROR;
2051 goto cleanup;
2055 ret = retrieve_pin (info, &tinfo, attempt++, user_type, &pin);
2056 if (ret < 0)
2058 gnutls_assert ();
2059 goto cleanup;
2062 rv = (module)->C_Login (pks, user_type,
2063 (unsigned char *)p11_kit_pin_get_value (pin, NULL),
2064 p11_kit_pin_get_length (pin));
2066 p11_kit_pin_unref (pin);
2068 while (rv == CKR_PIN_INCORRECT);
2070 _gnutls_debug_log ("pk11: Login result = %lu\n", rv);
2073 ret = (rv == CKR_OK
2074 || rv == CKR_USER_ALREADY_LOGGED_IN) ? 0 : pkcs11_rv_to_err (rv);
2076 cleanup:
2077 return ret;
2081 pkcs11_call_token_func (struct p11_kit_uri *info, const unsigned retry)
2083 struct ck_token_info *tinfo;
2084 char *label;
2085 int ret = 0;
2087 tinfo = p11_kit_uri_get_token_info (info);
2088 label = p11_kit_space_strdup (tinfo->label, sizeof (tinfo->label));
2089 ret = (token_func) (token_data, label, retry);
2090 free (label);
2092 return ret;
2096 static int
2097 find_privkeys (struct ck_function_list *module, ck_session_handle_t pks,
2098 struct token_info *info, struct pkey_list *list)
2100 struct ck_attribute a[3];
2101 ck_object_class_t class;
2102 ck_rv_t rv;
2103 ck_object_handle_t obj;
2104 unsigned long count, current;
2105 char certid_tmp[PKCS11_ID_SIZE];
2107 class = CKO_PRIVATE_KEY;
2109 /* Find an object with private key class and a certificate ID
2110 * which matches the certificate. */
2111 /* FIXME: also match the cert subject. */
2112 a[0].type = CKA_CLASS;
2113 a[0].value = &class;
2114 a[0].value_len = sizeof class;
2116 rv = pkcs11_find_objects_init (module, pks, a, 1);
2117 if (rv != CKR_OK)
2119 gnutls_assert ();
2120 return pkcs11_rv_to_err (rv);
2123 list->key_ids_size = 0;
2124 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
2126 list->key_ids_size++;
2129 pkcs11_find_objects_final (module, pks);
2131 if (list->key_ids_size == 0)
2133 gnutls_assert ();
2134 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2137 list->key_ids =
2138 gnutls_malloc (sizeof (gnutls_buffer_st) * list->key_ids_size);
2139 if (list->key_ids == NULL)
2141 gnutls_assert ();
2142 return GNUTLS_E_MEMORY_ERROR;
2145 /* actual search */
2146 a[0].type = CKA_CLASS;
2147 a[0].value = &class;
2148 a[0].value_len = sizeof class;
2150 rv = pkcs11_find_objects_init (module, pks, a, 1);
2151 if (rv != CKR_OK)
2153 gnutls_assert ();
2154 return pkcs11_rv_to_err (rv);
2157 current = 0;
2158 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
2161 a[0].type = CKA_ID;
2162 a[0].value = certid_tmp;
2163 a[0].value_len = sizeof (certid_tmp);
2165 _gnutls_buffer_init (&list->key_ids[current]);
2167 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2169 _gnutls_buffer_append_data (&list->key_ids[current],
2170 a[0].value, a[0].value_len);
2171 current++;
2174 if (current > list->key_ids_size)
2175 break;
2178 pkcs11_find_objects_final (module, pks);
2180 list->key_ids_size = current - 1;
2182 return 0;
2185 /* Recover certificate list from tokens */
2188 static int
2189 find_objs (struct ck_function_list * module, ck_session_handle_t pks,
2190 struct token_info *info, struct ck_info *lib_info, void *input)
2192 struct crt_find_data_st *find_data = input;
2193 struct ck_attribute a[4];
2194 struct ck_attribute *attr;
2195 ck_object_class_t class = (ck_object_class_t)-1;
2196 ck_certificate_type_t type = (ck_certificate_type_t)-1;
2197 unsigned int trusted;
2198 ck_rv_t rv;
2199 ck_object_handle_t obj;
2200 unsigned long count;
2201 uint8_t *cert_data;
2202 char certid_tmp[PKCS11_ID_SIZE];
2203 char label_tmp[PKCS11_LABEL_SIZE];
2204 int ret;
2205 struct pkey_list plist; /* private key holder */
2206 unsigned int i, tot_values = 0;
2208 if (info == NULL)
2209 { /* final call */
2210 if (find_data->current <= *find_data->n_list)
2211 ret = 0;
2212 else
2213 ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
2215 *find_data->n_list = find_data->current;
2217 return ret;
2220 /* do not bother reading the token if basic fields do not match
2222 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2223 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2225 gnutls_assert ();
2226 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2229 memset (&plist, 0, sizeof (plist));
2231 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2233 ret = find_privkeys (module, pks, info, &plist);
2234 if (ret < 0)
2236 gnutls_assert ();
2237 return ret;
2240 if (plist.key_ids_size == 0)
2242 gnutls_assert ();
2243 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2247 cert_data = gnutls_malloc (MAX_CERT_SIZE);
2248 if (cert_data == NULL)
2250 gnutls_assert ();
2251 return GNUTLS_E_MEMORY_ERROR;
2254 /* Find objects with cert class and X.509 cert type. */
2256 tot_values = 0;
2258 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL
2259 || find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2261 class = CKO_CERTIFICATE;
2262 type = CKC_X_509;
2263 trusted = 1;
2265 a[tot_values].type = CKA_CLASS;
2266 a[tot_values].value = &class;
2267 a[tot_values].value_len = sizeof class;
2268 tot_values++;
2270 a[tot_values].type = CKA_CERTIFICATE_TYPE;
2271 a[tot_values].value = &type;
2272 a[tot_values].value_len = sizeof type;
2273 tot_values++;
2276 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED)
2278 class = CKO_CERTIFICATE;
2279 type = CKC_X_509;
2280 trusted = 1;
2282 a[tot_values].type = CKA_CLASS;
2283 a[tot_values].value = &class;
2284 a[tot_values].value_len = sizeof class;
2285 tot_values++;
2287 a[tot_values].type = CKA_TRUSTED;
2288 a[tot_values].value = &trusted;
2289 a[tot_values].value_len = sizeof trusted;
2290 tot_values++;
2293 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PUBKEY)
2295 class = CKO_PUBLIC_KEY;
2297 a[tot_values].type = CKA_CLASS;
2298 a[tot_values].value = &class;
2299 a[tot_values].value_len = sizeof class;
2300 tot_values++;
2302 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
2304 class = CKO_PRIVATE_KEY;
2306 a[tot_values].type = CKA_CLASS;
2307 a[tot_values].value = &class;
2308 a[tot_values].value_len = sizeof class;
2309 tot_values++;
2311 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2313 if (class != (ck_object_class_t)-1)
2315 a[tot_values].type = CKA_CLASS;
2316 a[tot_values].value = &class;
2317 a[tot_values].value_len = sizeof class;
2318 tot_values++;
2320 if (type != (ck_certificate_type_t)-1)
2322 a[tot_values].type = CKA_CERTIFICATE_TYPE;
2323 a[tot_values].value = &type;
2324 a[tot_values].value_len = sizeof type;
2325 tot_values++;
2328 else
2330 gnutls_assert ();
2331 ret = GNUTLS_E_INVALID_REQUEST;
2332 goto fail;
2335 attr = p11_kit_uri_get_attribute (find_data->info, CKA_ID);
2336 if (attr != NULL)
2338 memcpy (a + tot_values, attr, sizeof (struct ck_attribute));
2339 tot_values++;
2342 rv = pkcs11_find_objects_init (module, pks, a, tot_values);
2343 if (rv != CKR_OK)
2345 gnutls_assert ();
2346 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
2347 return pkcs11_rv_to_err (rv);
2350 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
2352 gnutls_datum_t label, id, value;
2354 a[0].type = CKA_LABEL;
2355 a[0].value = label_tmp;
2356 a[0].value_len = sizeof label_tmp;
2358 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2360 label.data = a[0].value;
2361 label.size = a[0].value_len;
2363 else
2365 label.data = NULL;
2366 label.size = 0;
2369 a[0].type = CKA_ID;
2370 a[0].value = certid_tmp;
2371 a[0].value_len = sizeof certid_tmp;
2373 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2375 id.data = a[0].value;
2376 id.size = a[0].value_len;
2378 else
2380 id.data = NULL;
2381 id.size = 0;
2384 a[0].type = CKA_VALUE;
2385 a[0].value = cert_data;
2386 a[0].value_len = MAX_CERT_SIZE;
2387 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2389 value.data = a[0].value;
2390 value.size = a[0].value_len;
2392 else
2394 value.data = NULL;
2395 value.size = 0;
2398 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2400 a[0].type = CKA_CLASS;
2401 a[0].value = &class;
2402 a[0].value_len = sizeof class;
2404 pkcs11_get_attribute_value (module, pks, obj, a, 1);
2407 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2409 for (i = 0; i < plist.key_ids_size; i++)
2411 if (plist.key_ids[i].length !=
2412 a[1].value_len
2413 || memcmp (plist.key_ids[i].data,
2414 a[1].value, a[1].value_len) != 0)
2416 /* not found */
2417 continue;
2422 if (find_data->current < *find_data->n_list)
2424 ret =
2425 gnutls_pkcs11_obj_init (&find_data->p_list[find_data->current]);
2426 if (ret < 0)
2428 gnutls_assert ();
2429 goto fail;
2432 if (class == CKO_PUBLIC_KEY)
2434 ret =
2435 pkcs11_obj_import_pubkey (module, pks, obj,
2436 find_data->p_list
2437 [find_data->current],
2438 &id, &label,
2439 &info->tinfo, lib_info);
2441 else
2443 ret =
2444 pkcs11_obj_import (class,
2445 find_data->p_list
2446 [find_data->current],
2447 &value, &id, &label,
2448 &info->tinfo, lib_info);
2450 if (ret < 0)
2452 gnutls_assert ();
2453 goto fail;
2457 find_data->current++;
2461 gnutls_free (cert_data);
2462 pkcs11_find_objects_final (module, pks);
2464 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* continue until all tokens have been checked */
2466 fail:
2467 gnutls_free (cert_data);
2468 pkcs11_find_objects_final (module, pks);
2469 if (plist.key_ids != NULL)
2471 for (i = 0; i < plist.key_ids_size; i++)
2473 _gnutls_buffer_clear (&plist.key_ids[i]);
2475 gnutls_free (plist.key_ids);
2477 for (i = 0; i < find_data->current; i++)
2479 gnutls_pkcs11_obj_deinit (find_data->p_list[i]);
2481 find_data->current = 0;
2483 return ret;
2487 * gnutls_pkcs11_obj_list_import_url:
2488 * @p_list: An uninitialized object list (may be NULL)
2489 * @n_list: initially should hold the maximum size of the list. Will contain the actual size.
2490 * @url: A PKCS 11 url identifying a set of objects
2491 * @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
2492 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2494 * This function will initialize and set values to an object list
2495 * by using all objects identified by a PKCS 11 URL.
2497 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2498 * negative error value.
2500 * Since: 2.12.0
2503 gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list,
2504 unsigned int *n_list,
2505 const char *url,
2506 gnutls_pkcs11_obj_attr_t attrs,
2507 unsigned int flags)
2509 int ret;
2510 struct crt_find_data_st find_data;
2512 memset (&find_data, 0, sizeof (find_data));
2514 /* fill in the find data structure */
2515 find_data.p_list = p_list;
2516 find_data.n_list = n_list;
2517 find_data.flags = attrs;
2518 find_data.current = 0;
2520 if (url == NULL || url[0] == 0)
2522 url = "pkcs11:";
2525 ret = pkcs11_url_to_info (url, &find_data.info);
2526 if (ret < 0)
2528 gnutls_assert ();
2529 return ret;
2532 ret =
2533 _pkcs11_traverse_tokens (find_objs, &find_data, find_data.info,
2534 pkcs11_obj_flags_to_int (flags));
2535 p11_kit_uri_free (find_data.info);
2537 if (ret < 0)
2539 gnutls_assert ();
2540 return ret;
2543 return 0;
2547 * gnutls_x509_crt_import_pkcs11_url:
2548 * @crt: A certificate of type #gnutls_x509_crt_t
2549 * @url: A PKCS 11 url
2550 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2552 * This function will import a PKCS 11 certificate directly from a token
2553 * without involving the #gnutls_pkcs11_obj_t structure. This function will
2554 * fail if the certificate stored is not of X.509 type.
2556 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2557 * negative error value.
2559 * Since: 2.12.0
2562 gnutls_x509_crt_import_pkcs11_url (gnutls_x509_crt_t crt,
2563 const char *url, unsigned int flags)
2565 gnutls_pkcs11_obj_t pcrt;
2566 int ret;
2568 ret = gnutls_pkcs11_obj_init (&pcrt);
2569 if (ret < 0)
2571 gnutls_assert ();
2572 return ret;
2575 ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
2576 if (ret < 0)
2578 gnutls_assert ();
2579 goto cleanup;
2582 ret = gnutls_x509_crt_import (crt, &pcrt->raw, GNUTLS_X509_FMT_DER);
2583 if (ret < 0)
2585 gnutls_assert ();
2586 goto cleanup;
2589 ret = 0;
2590 cleanup:
2592 gnutls_pkcs11_obj_deinit (pcrt);
2594 return ret;
2599 * gnutls_x509_crt_import_pkcs11:
2600 * @crt: A certificate of type #gnutls_x509_crt_t
2601 * @pkcs11_crt: A PKCS 11 object that contains a certificate
2603 * This function will import a PKCS 11 certificate to a #gnutls_x509_crt_t
2604 * structure.
2606 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2607 * negative error value.
2609 * Since: 2.12.0
2612 gnutls_x509_crt_import_pkcs11 (gnutls_x509_crt_t crt,
2613 gnutls_pkcs11_obj_t pkcs11_crt)
2615 return gnutls_x509_crt_import (crt, &pkcs11_crt->raw, GNUTLS_X509_FMT_DER);
2619 * gnutls_x509_crt_list_import_pkcs11:
2620 * @certs: A list of certificates of type #gnutls_x509_crt_t
2621 * @cert_max: The maximum size of the list
2622 * @objs: A list of PKCS 11 objects
2623 * @flags: 0 for now
2625 * This function will import a PKCS 11 certificate list to a list of
2626 * #gnutls_x509_crt_t structure. These must not be initialized.
2628 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2629 * negative error value.
2631 * Since: 2.12.0
2634 gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
2635 unsigned int cert_max,
2636 gnutls_pkcs11_obj_t * const objs,
2637 unsigned int flags)
2639 unsigned int i, j;
2640 int ret;
2642 for (i = 0; i < cert_max; i++)
2644 ret = gnutls_x509_crt_init (&certs[i]);
2645 if (ret < 0)
2647 gnutls_assert ();
2648 goto cleanup;
2651 ret = gnutls_x509_crt_import_pkcs11 (certs[i], objs[i]);
2652 if (ret < 0)
2654 gnutls_assert ();
2655 goto cleanup;
2659 return 0;
2661 cleanup:
2662 for (j = 0; j < i; j++)
2664 gnutls_x509_crt_deinit (certs[j]);
2667 return ret;
2670 static int
2671 find_flags (struct ck_function_list * module, ck_session_handle_t pks,
2672 struct token_info *info, struct ck_info *lib_info, void *input)
2674 struct flags_find_data_st *find_data = input;
2676 if (info == NULL)
2677 { /* we don't support multiple calls */
2678 gnutls_assert ();
2679 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2682 /* do not bother reading the token if basic fields do not match
2684 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2685 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2687 gnutls_assert ();
2688 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2691 /* found token! */
2693 find_data->slot_flags = info->sinfo.flags;
2695 return 0;
2699 * gnutls_pkcs11_token_get_flags:
2700 * @url: should contain a PKCS 11 URL
2701 * @flags: The output flags (GNUTLS_PKCS11_TOKEN_*)
2703 * This function will return information about the PKCS 11 token flags.
2704 * The flags from the %gnutls_pkcs11_token_info_t enumeration.
2706 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
2708 * Since: 2.12.0
2711 gnutls_pkcs11_token_get_flags (const char *url, unsigned int *flags)
2713 struct flags_find_data_st find_data;
2714 int ret;
2716 memset (&find_data, 0, sizeof (find_data));
2717 ret = pkcs11_url_to_info (url, &find_data.info);
2718 if (ret < 0)
2720 gnutls_assert ();
2721 return ret;
2724 ret = _pkcs11_traverse_tokens (find_flags, &find_data, find_data.info, 0);
2725 p11_kit_uri_free (find_data.info);
2727 if (ret < 0)
2729 gnutls_assert ();
2730 return ret;
2733 *flags = 0;
2734 if (find_data.slot_flags & CKF_HW_SLOT)
2735 *flags |= GNUTLS_PKCS11_TOKEN_HW;
2737 return 0;
2742 * gnutls_pkcs11_token_get_mechanism:
2743 * @url: should contain a PKCS 11 URL
2744 * @idx: The index of the mechanism
2745 * @mechanism: The PKCS #11 mechanism ID
2747 * This function will return the names of the supported mechanisms
2748 * by the token. It should be called with an increasing index until
2749 * it return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.
2751 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
2753 * Since: 2.12.0
2756 gnutls_pkcs11_token_get_mechanism (const char *url, unsigned int idx,
2757 unsigned long *mechanism)
2759 int ret;
2760 ck_rv_t rv;
2761 struct ck_function_list *module;
2762 ck_slot_id_t slot;
2763 struct token_info tinfo;
2764 struct p11_kit_uri *info = NULL;
2765 unsigned long count;
2766 ck_mechanism_type_t mlist[400];
2768 ret = pkcs11_url_to_info (url, &info);
2769 if (ret < 0)
2771 gnutls_assert ();
2772 return ret;
2776 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
2777 p11_kit_uri_free (info);
2779 if (ret < 0)
2781 gnutls_assert ();
2782 return ret;
2785 count = sizeof (mlist) / sizeof (mlist[0]);
2786 rv = pkcs11_get_mechanism_list (module, slot, mlist, &count);
2787 if (rv != CKR_OK)
2789 gnutls_assert ();
2790 return pkcs11_rv_to_err (rv);
2793 if (idx >= count)
2795 gnutls_assert ();
2796 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2799 *mechanism = mlist[idx];
2801 return 0;
2806 * gnutls_pkcs11_type_get_name:
2807 * @type: Holds the PKCS 11 object type, a #gnutls_pkcs11_obj_type_t.
2809 * This function will return a human readable description of the
2810 * PKCS11 object type @obj. It will return "Unknown" for unknown
2811 * types.
2813 * Returns: human readable string labeling the PKCS11 object type
2814 * @type.
2816 * Since: 2.12.0
2818 const char *
2819 gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t type)
2821 switch (type)
2823 case GNUTLS_PKCS11_OBJ_X509_CRT:
2824 return "X.509 Certificate";
2825 case GNUTLS_PKCS11_OBJ_PUBKEY:
2826 return "Public key";
2827 case GNUTLS_PKCS11_OBJ_PRIVKEY:
2828 return "Private key";
2829 case GNUTLS_PKCS11_OBJ_SECRET_KEY:
2830 return "Secret key";
2831 case GNUTLS_PKCS11_OBJ_DATA:
2832 return "Data";
2833 case GNUTLS_PKCS11_OBJ_UNKNOWN:
2834 default:
2835 return "Unknown";
2839 ck_rv_t
2840 pkcs11_get_slot_list (struct ck_function_list * module, unsigned char token_present,
2841 ck_slot_id_t *slot_list, unsigned long *count)
2843 return (module)->C_GetSlotList (token_present, slot_list, count);
2846 ck_rv_t
2847 pkcs11_get_module_info (struct ck_function_list * module,
2848 struct ck_info * info)
2850 return (module)->C_GetInfo (info);
2853 ck_rv_t
2854 pkcs11_get_slot_info(struct ck_function_list * module,
2855 ck_slot_id_t slot_id,
2856 struct ck_slot_info *info)
2858 return (module)->C_GetSlotInfo (slot_id, info);
2861 ck_rv_t
2862 pkcs11_get_token_info (struct ck_function_list * module,
2863 ck_slot_id_t slot_id,
2864 struct ck_token_info *info)
2866 return (module)->C_GetTokenInfo (slot_id, info);
2869 ck_rv_t
2870 pkcs11_find_objects_init (struct ck_function_list *module,
2871 ck_session_handle_t sess,
2872 struct ck_attribute *templ,
2873 unsigned long count)
2875 return (module)->C_FindObjectsInit (sess, templ, count);
2878 ck_rv_t
2879 pkcs11_find_objects (struct ck_function_list *module,
2880 ck_session_handle_t sess,
2881 ck_object_handle_t *objects,
2882 unsigned long max_object_count,
2883 unsigned long *object_count)
2885 return (module)->C_FindObjects (sess, objects, max_object_count, object_count);
2888 ck_rv_t
2889 pkcs11_find_objects_final (struct ck_function_list *module,
2890 ck_session_handle_t sess)
2892 return (module)->C_FindObjectsFinal (sess);
2895 ck_rv_t
2896 pkcs11_close_session (struct ck_function_list *module,
2897 ck_session_handle_t sess)
2899 return (module)->C_CloseSession (sess);
2902 ck_rv_t
2903 pkcs11_get_attribute_value(struct ck_function_list *module,
2904 ck_session_handle_t sess,
2905 ck_object_handle_t object,
2906 struct ck_attribute *templ,
2907 unsigned long count)
2909 return (module)->C_GetAttributeValue (sess, object, templ, count);
2912 ck_rv_t
2913 pkcs11_get_mechanism_list (struct ck_function_list *module,
2914 ck_slot_id_t slot_id,
2915 ck_mechanism_type_t *mechanism_list,
2916 unsigned long *count)
2918 return (module)->C_GetMechanismList (slot_id, mechanism_list, count);
2921 ck_rv_t
2922 pkcs11_sign_init (struct ck_function_list *module,
2923 ck_session_handle_t sess,
2924 struct ck_mechanism *mechanism,
2925 ck_object_handle_t key)
2927 return (module)->C_SignInit (sess, mechanism, key);
2930 ck_rv_t
2931 pkcs11_sign (struct ck_function_list *module,
2932 ck_session_handle_t sess,
2933 unsigned char *data,
2934 unsigned long data_len,
2935 unsigned char *signature,
2936 unsigned long *signature_len)
2938 return (module)->C_Sign (sess, data, data_len, signature, signature_len);
2941 ck_rv_t
2942 pkcs11_generate_key_pair (struct ck_function_list *module,
2943 ck_session_handle_t sess,
2944 struct ck_mechanism *mechanism,
2945 struct ck_attribute *pub_templ,
2946 unsigned long pub_templ_count,
2947 struct ck_attribute *priv_templ,
2948 unsigned long priv_templ_count,
2949 ck_object_handle_t *pub,
2950 ck_object_handle_t *priv)
2952 return (module)->C_GenerateKeyPair (sess, mechanism, pub_templ, pub_templ_count,
2953 priv_templ, priv_templ_count, pub, priv);
2956 ck_rv_t
2957 pkcs11_decrypt_init (struct ck_function_list *module,
2958 ck_session_handle_t sess,
2959 struct ck_mechanism *mechanism,
2960 ck_object_handle_t key)
2962 return (module)->C_DecryptInit (sess, mechanism, key);
2965 ck_rv_t
2966 pkcs11_decrypt (struct ck_function_list *module,
2967 ck_session_handle_t sess,
2968 unsigned char *encrypted_data,
2969 unsigned long encrypted_data_len,
2970 unsigned char *data, unsigned long *data_len)
2972 return (module)->C_Decrypt (sess, encrypted_data, encrypted_data_len,
2973 data, data_len);
2976 ck_rv_t
2977 pkcs11_create_object (struct ck_function_list *module,
2978 ck_session_handle_t sess,
2979 struct ck_attribute *templ,
2980 unsigned long count,
2981 ck_object_handle_t *object)
2983 return (module)->C_CreateObject (sess, templ, count, object);
2986 ck_rv_t
2987 pkcs11_destroy_object (struct ck_function_list *module,
2988 ck_session_handle_t sess,
2989 ck_object_handle_t object)
2991 return (module)->C_DestroyObject (sess, object);
2994 ck_rv_t
2995 pkcs11_init_token (struct ck_function_list *module,
2996 ck_slot_id_t slot_id, unsigned char *pin,
2997 unsigned long pin_len, unsigned char *label)
2999 return (module)->C_InitToken (slot_id, pin, pin_len, label);
3002 ck_rv_t
3003 pkcs11_init_pin (struct ck_function_list *module,
3004 ck_session_handle_t sess,
3005 unsigned char *pin,
3006 unsigned long pin_len)
3008 return (module)->C_InitPIN (sess, pin, pin_len);
3011 ck_rv_t
3012 pkcs11_set_pin (struct ck_function_list *module,
3013 ck_session_handle_t sess,
3014 const char *old_pin,
3015 unsigned long old_len,
3016 const char *new_pin,
3017 unsigned long new_len)
3019 return (module)->C_SetPIN (sess, (uint8_t*)old_pin, old_len, (uint8_t*)new_pin, new_len);
3022 const char *
3023 pkcs11_strerror (ck_rv_t rv)
3025 return p11_kit_strerror (rv);