certtool is able to set certificate policies via a template
[gnutls.git] / lib / pkcs11.c
bloba4b7728b1646cbaa740bcf2ce4f44ba85a8e7f7b
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>
33 #include <pin.h>
34 #include <pkcs11_int.h>
35 #include <p11-kit/p11-kit.h>
36 #include <p11-kit/pin.h>
38 #define MAX_PROVIDERS 16
40 /* XXX: try to eliminate this */
41 #define MAX_CERT_SIZE 8*1024
43 struct gnutls_pkcs11_provider_s
45 struct ck_function_list *module;
46 unsigned long nslots;
47 ck_slot_id_t *slots;
48 struct ck_info info;
49 unsigned int initialized;
52 struct flags_find_data_st
54 struct p11_kit_uri *info;
55 unsigned int slot_flags;
58 struct url_find_data_st
60 gnutls_pkcs11_obj_t crt;
63 struct crt_find_data_st
65 gnutls_pkcs11_obj_t *p_list;
66 unsigned int *n_list;
67 unsigned int current;
68 gnutls_pkcs11_obj_attr_t flags;
69 struct p11_kit_uri *info;
73 static struct gnutls_pkcs11_provider_s providers[MAX_PROVIDERS];
74 static unsigned int active_providers = 0;
75 static unsigned int initialized_registered = 0;
77 gnutls_pkcs11_token_callback_t _gnutls_token_func;
78 void *_gnutls_token_data;
80 int
81 pkcs11_rv_to_err (ck_rv_t rv)
83 switch (rv)
85 case CKR_OK:
86 return 0;
87 case CKR_HOST_MEMORY:
88 return GNUTLS_E_MEMORY_ERROR;
89 case CKR_SLOT_ID_INVALID:
90 return GNUTLS_E_PKCS11_SLOT_ERROR;
91 case CKR_ARGUMENTS_BAD:
92 case CKR_MECHANISM_PARAM_INVALID:
93 return GNUTLS_E_INVALID_REQUEST;
94 case CKR_NEED_TO_CREATE_THREADS:
95 case CKR_CANT_LOCK:
96 case CKR_FUNCTION_NOT_PARALLEL:
97 case CKR_MUTEX_BAD:
98 case CKR_MUTEX_NOT_LOCKED:
99 return GNUTLS_E_LOCKING_ERROR;
100 case CKR_ATTRIBUTE_READ_ONLY:
101 case CKR_ATTRIBUTE_SENSITIVE:
102 case CKR_ATTRIBUTE_TYPE_INVALID:
103 case CKR_ATTRIBUTE_VALUE_INVALID:
104 return GNUTLS_E_PKCS11_ATTRIBUTE_ERROR;
105 case CKR_DEVICE_ERROR:
106 case CKR_DEVICE_MEMORY:
107 case CKR_DEVICE_REMOVED:
108 return GNUTLS_E_PKCS11_DEVICE_ERROR;
109 case CKR_DATA_INVALID:
110 case CKR_DATA_LEN_RANGE:
111 case CKR_ENCRYPTED_DATA_INVALID:
112 case CKR_ENCRYPTED_DATA_LEN_RANGE:
113 case CKR_OBJECT_HANDLE_INVALID:
114 return GNUTLS_E_PKCS11_DATA_ERROR;
115 case CKR_FUNCTION_NOT_SUPPORTED:
116 case CKR_MECHANISM_INVALID:
117 return GNUTLS_E_PKCS11_UNSUPPORTED_FEATURE_ERROR;
118 case CKR_KEY_HANDLE_INVALID:
119 case CKR_KEY_SIZE_RANGE:
120 case CKR_KEY_TYPE_INCONSISTENT:
121 case CKR_KEY_NOT_NEEDED:
122 case CKR_KEY_CHANGED:
123 case CKR_KEY_NEEDED:
124 case CKR_KEY_INDIGESTIBLE:
125 case CKR_KEY_FUNCTION_NOT_PERMITTED:
126 case CKR_KEY_NOT_WRAPPABLE:
127 case CKR_KEY_UNEXTRACTABLE:
128 return GNUTLS_E_PKCS11_KEY_ERROR;
129 case CKR_PIN_INCORRECT:
130 case CKR_PIN_INVALID:
131 case CKR_PIN_LEN_RANGE:
132 return GNUTLS_E_PKCS11_PIN_ERROR;
133 case CKR_PIN_EXPIRED:
134 return GNUTLS_E_PKCS11_PIN_EXPIRED;
135 case CKR_PIN_LOCKED:
136 return GNUTLS_E_PKCS11_PIN_LOCKED;
137 case CKR_SESSION_CLOSED:
138 case CKR_SESSION_COUNT:
139 case CKR_SESSION_HANDLE_INVALID:
140 case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
141 case CKR_SESSION_READ_ONLY:
142 case CKR_SESSION_EXISTS:
143 case CKR_SESSION_READ_ONLY_EXISTS:
144 case CKR_SESSION_READ_WRITE_SO_EXISTS:
145 return GNUTLS_E_PKCS11_SESSION_ERROR;
146 case CKR_SIGNATURE_INVALID:
147 case CKR_SIGNATURE_LEN_RANGE:
148 return GNUTLS_E_PKCS11_SIGNATURE_ERROR;
149 case CKR_TOKEN_NOT_PRESENT:
150 case CKR_TOKEN_NOT_RECOGNIZED:
151 case CKR_TOKEN_WRITE_PROTECTED:
152 return GNUTLS_E_PKCS11_TOKEN_ERROR;
153 case CKR_USER_ALREADY_LOGGED_IN:
154 case CKR_USER_NOT_LOGGED_IN:
155 case CKR_USER_PIN_NOT_INITIALIZED:
156 case CKR_USER_TYPE_INVALID:
157 case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
158 case CKR_USER_TOO_MANY_TYPES:
159 return GNUTLS_E_PKCS11_USER_ERROR;
160 case CKR_BUFFER_TOO_SMALL:
161 return GNUTLS_E_SHORT_MEMORY_BUFFER;
162 default:
163 return GNUTLS_E_PKCS11_ERROR;
167 /* Fake scan */
168 void
169 pkcs11_rescan_slots (void)
171 unsigned long slots;
173 pkcs11_get_slot_list (providers[active_providers - 1].module, 0,
174 NULL, &slots);
177 static int
178 pkcs11_add_module (const char *name, struct ck_function_list *module)
180 struct ck_info info;
181 unsigned int i;
183 if (active_providers >= MAX_PROVIDERS)
185 gnutls_assert ();
186 return GNUTLS_E_CONSTRAINT_ERROR;
189 /* initially check if this module is a duplicate */
190 memset(&info, 0, sizeof(info));
191 pkcs11_get_module_info (module, &info);
192 for (i=0;i<active_providers;i++)
194 /* already loaded, skip the rest */
195 if (memcmp(&info, &providers[i].info, sizeof(info)) == 0)
197 _gnutls_debug_log("%s is already loaded.\n", name);
198 return GNUTLS_E_INT_RET_0;
202 active_providers++;
203 providers[active_providers - 1].module = module;
205 /* cache the number of slots in this module */
206 if (pkcs11_get_slot_list
207 (providers[active_providers - 1].module, 0, NULL,
208 &providers[active_providers - 1].nslots) != CKR_OK)
210 gnutls_assert ();
211 goto fail;
214 providers[active_providers - 1].slots =
215 gnutls_malloc (sizeof (*providers[active_providers - 1].slots) *
216 providers[active_providers - 1].nslots);
217 if (providers[active_providers - 1].slots == NULL)
219 gnutls_assert ();
220 goto fail;
223 if (pkcs11_get_slot_list
224 (providers[active_providers - 1].module, 0,
225 providers[active_providers - 1].slots,
226 &providers[active_providers - 1].nslots) != CKR_OK)
228 gnutls_assert ();
229 gnutls_free (providers[active_providers - 1].slots);
230 goto fail;
233 memcpy (&providers[active_providers - 1].info, &info, sizeof(info));
235 _gnutls_debug_log ("p11: loaded provider '%s' with %d slots\n",
236 name, (int) providers[active_providers - 1].nslots);
238 return 0;
240 fail:
241 active_providers--;
242 return GNUTLS_E_PKCS11_LOAD_ERROR;
247 * gnutls_pkcs11_add_provider:
248 * @name: The filename of the module
249 * @params: should be NULL
251 * This function will load and add a PKCS 11 module to the module
252 * list used in gnutls. After this function is called the module will
253 * be used for PKCS 11 operations.
255 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
256 * negative error value.
258 * Since: 2.12.0
261 gnutls_pkcs11_add_provider (const char *name, const char *params)
263 struct ck_function_list *module;
264 int ret;
266 active_providers++;
267 if (p11_kit_load_initialize_module (name, &module) != CKR_OK)
269 gnutls_assert ();
270 _gnutls_debug_log ("p11: Cannot load provider %s\n", name);
271 active_providers--;
272 return GNUTLS_E_PKCS11_LOAD_ERROR;
275 ret = pkcs11_add_module (name, module);
276 if (ret == 0)
278 /* Mark this one as having been separately initialized */
279 providers[active_providers - 1].initialized = 1;
281 else
283 if (ret == GNUTLS_E_INT_RET_0) ret = 0;
284 p11_kit_finalize_module (module);
285 gnutls_assert ();
288 return ret;
293 * gnutls_pkcs11_obj_get_info:
294 * @crt: should contain a #gnutls_pkcs11_obj_t structure
295 * @itype: Denotes the type of information requested
296 * @output: where output will be stored
297 * @output_size: contains the maximum size of the output and will be overwritten with actual
299 * This function will return information about the PKCS11 certificate
300 * such as the label, id as well as token information where the key is
301 * stored. When output is text it returns null terminated string
302 * although @output_size contains the size of the actual data only.
304 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
306 * Since: 2.12.0
309 gnutls_pkcs11_obj_get_info (gnutls_pkcs11_obj_t crt,
310 gnutls_pkcs11_obj_info_t itype,
311 void *output, size_t * output_size)
313 return pkcs11_get_info (crt->info, itype, output, output_size);
317 pkcs11_get_info (struct p11_kit_uri *info,
318 gnutls_pkcs11_obj_info_t itype, void *output,
319 size_t * output_size)
321 struct ck_attribute *attr = NULL;
322 struct ck_version *version = NULL;
323 const uint8_t *str = NULL;
324 size_t str_max = 0;
325 int terminate = 0;
326 int hexify = 0;
327 size_t length = 0;
328 const char *data = NULL;
329 char buf[32];
332 * Either attr, str or version is valid by the time switch
333 * finishes
336 switch (itype)
338 case GNUTLS_PKCS11_OBJ_ID:
339 attr = p11_kit_uri_get_attribute (info, CKA_ID);
340 break;
341 case GNUTLS_PKCS11_OBJ_ID_HEX:
342 attr = p11_kit_uri_get_attribute (info, CKA_ID);
343 hexify = 1;
344 terminate = 1;
345 break;
346 case GNUTLS_PKCS11_OBJ_LABEL:
347 attr = p11_kit_uri_get_attribute (info, CKA_LABEL);
348 terminate = 1;
349 break;
350 case GNUTLS_PKCS11_OBJ_TOKEN_LABEL:
351 str = p11_kit_uri_get_token_info (info)->label;
352 str_max = 32;
353 break;
354 case GNUTLS_PKCS11_OBJ_TOKEN_SERIAL:
355 str = p11_kit_uri_get_token_info (info)->serial_number;
356 str_max = 16;
357 break;
358 case GNUTLS_PKCS11_OBJ_TOKEN_MANUFACTURER:
359 str = p11_kit_uri_get_token_info (info)->manufacturer_id;
360 str_max = 32;
361 break;
362 case GNUTLS_PKCS11_OBJ_TOKEN_MODEL:
363 str = p11_kit_uri_get_token_info (info)->model;
364 str_max = 16;
365 break;
366 case GNUTLS_PKCS11_OBJ_LIBRARY_DESCRIPTION:
367 str = p11_kit_uri_get_module_info (info)->library_description;
368 str_max = 32;
369 break;
370 case GNUTLS_PKCS11_OBJ_LIBRARY_VERSION:
371 version = &p11_kit_uri_get_module_info (info)->library_version;
372 break;
373 case GNUTLS_PKCS11_OBJ_LIBRARY_MANUFACTURER:
374 str = p11_kit_uri_get_module_info (info)->manufacturer_id;
375 str_max = 32;
376 break;
377 default:
378 gnutls_assert ();
379 return GNUTLS_E_INVALID_REQUEST;
382 if (attr != NULL)
384 data = attr->value;
385 length = attr->value_len;
387 else if (str != NULL)
389 data = (void*)str;
390 length = p11_kit_space_strlen (str, str_max);
391 terminate = 1;
393 else if (version != NULL)
395 data = buf;
396 length = snprintf (buf, sizeof (buf), "%d.%d", (int)version->major,
397 (int)version->minor);
398 terminate = 1;
400 else
402 *output_size = 0;
403 if (output) ((uint8_t*)output)[0] = 0;
404 return 0;
407 if (hexify)
409 /* terminate is assumed with hexify */
410 if (*output_size < length * 3)
412 *output_size = length * 3;
413 return GNUTLS_E_SHORT_MEMORY_BUFFER;
415 if (output)
416 _gnutls_bin2hex (data, length, output, *output_size, ":");
417 *output_size = length * 3;
418 return 0;
420 else
422 if (*output_size < length + terminate)
424 *output_size = length + terminate;
425 return GNUTLS_E_SHORT_MEMORY_BUFFER;
427 if (output)
429 memcpy (output, data, length);
430 if (terminate)
431 ((unsigned char*)output)[length] = '\0';
433 *output_size = length + terminate;
436 return 0;
439 static int init = 0;
441 /* tries to load modules from /etc/gnutls/pkcs11.conf if it exists
443 static void _pkcs11_compat_init(const char* configfile)
445 FILE *fp;
446 int ret;
447 char line[512];
448 const char *library;
450 if (configfile == NULL)
451 configfile = "/etc/gnutls/pkcs11.conf";
453 fp = fopen (configfile, "r");
454 if (fp == NULL)
456 gnutls_assert ();
457 return;
460 _gnutls_debug_log ("Loading PKCS #11 libraries from %s\n", configfile);
461 while (fgets (line, sizeof (line), fp) != NULL)
463 if (strncmp (line, "load", sizeof ("load") - 1) == 0)
465 char *p;
466 p = strchr (line, '=');
467 if (p == NULL)
468 continue;
470 library = ++p;
471 p = strchr (line, '\n');
472 if (p != NULL)
473 *p = 0;
475 ret = gnutls_pkcs11_add_provider (library, NULL);
476 if (ret < 0)
478 gnutls_assert ();
479 _gnutls_debug_log ("Cannot load provider: %s\n", library);
480 continue;
484 fclose(fp);
486 return;
489 static int
490 initialize_automatic_p11_kit (void)
492 struct ck_function_list **modules;
493 char *name;
494 ck_rv_t rv;
495 int i, ret;
497 rv = p11_kit_initialize_registered ();
498 if (rv != CKR_OK)
500 gnutls_assert ();
501 _gnutls_debug_log ("Cannot initialize registered module: %s\n",
502 p11_kit_strerror (rv));
503 return GNUTLS_E_INTERNAL_ERROR;
506 initialized_registered = 1;
508 modules = p11_kit_registered_modules ();
509 for (i = 0; modules[i] != NULL; i++)
511 name = p11_kit_registered_module_to_name (modules[i]);
512 ret = pkcs11_add_module (name, modules[i]);
513 if (ret != 0 && ret != GNUTLS_E_INT_RET_0)
515 gnutls_assert ();
516 _gnutls_debug_log ("Cannot add registered module: %s\n", name);
518 free(name);
521 free (modules);
522 return 0;
526 * gnutls_pkcs11_init:
527 * @flags: %GNUTLS_PKCS11_FLAG_MANUAL or %GNUTLS_PKCS11_FLAG_AUTO
528 * @deprecated_config_file: either NULL or the location of a deprecated
529 * configuration file
531 * This function will initialize the PKCS 11 subsystem in gnutls. It will
532 * read configuration files if %GNUTLS_PKCS11_FLAG_AUTO is used or allow
533 * you to independently load PKCS 11 modules using gnutls_pkcs11_add_provider()
534 * if %GNUTLS_PKCS11_FLAG_MANUAL is specified.
536 * Normally you don't need to call this function since it is being called
537 * by gnutls_global_init() using the %GNUTLS_PKCS11_FLAG_AUTO. If other option
538 * is required then it must be called before it.
540 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
541 * negative error value.
543 * Since: 2.12.0
546 gnutls_pkcs11_init (unsigned int flags, const char *deprecated_config_file)
548 int ret = 0;
550 if (init != 0)
552 init++;
553 return 0;
555 init++;
557 p11_kit_pin_register_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback,
558 NULL, NULL);
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;
635 gnutls_pkcs11_set_pin_function (NULL, NULL);
636 gnutls_pkcs11_set_token_function (NULL, NULL);
640 * gnutls_pkcs11_set_token_function:
641 * @fn: The token callback
642 * @userdata: data to be supplied to callback
644 * This function will set a callback function to be used when a token
645 * needs to be inserted to continue PKCS 11 operations.
647 * Since: 2.12.0
649 void
650 gnutls_pkcs11_set_token_function (gnutls_pkcs11_token_callback_t fn,
651 void *userdata)
653 _gnutls_token_func = fn;
654 _gnutls_token_data = userdata;
658 pkcs11_url_to_info (const char *url, struct p11_kit_uri **info)
660 int allocated = 0;
661 int ret;
663 if (*info == NULL)
665 *info = p11_kit_uri_new ();
666 if (*info == NULL)
668 gnutls_assert ();
669 return GNUTLS_E_MEMORY_ERROR;
671 allocated = 1;
674 ret = p11_kit_uri_parse (url, P11_KIT_URI_FOR_ANY, *info);
675 if (ret < 0)
677 if (allocated)
679 p11_kit_uri_free (*info);
680 *info = NULL;
682 gnutls_assert ();
683 return ret == P11_KIT_URI_NO_MEMORY ?
684 GNUTLS_E_MEMORY_ERROR : GNUTLS_E_PARSING_ERROR;
687 return 0;
691 pkcs11_info_to_url (struct p11_kit_uri *info,
692 gnutls_pkcs11_url_type_t detailed, char **url)
694 p11_kit_uri_type_t type = 0;
695 int ret;
697 switch (detailed)
699 case GNUTLS_PKCS11_URL_GENERIC:
700 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN;
701 break;
702 case GNUTLS_PKCS11_URL_LIB:
703 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE;
704 break;
705 case GNUTLS_PKCS11_URL_LIB_VERSION:
706 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE | P11_KIT_URI_FOR_MODULE_WITH_VERSION;
707 break;
710 ret = p11_kit_uri_format (info, type, url);
711 if (ret < 0)
713 gnutls_assert ();
714 return ret == P11_KIT_URI_NO_MEMORY ?
715 GNUTLS_E_MEMORY_ERROR : GNUTLS_E_INTERNAL_ERROR;
718 return 0;
722 * gnutls_pkcs11_obj_init:
723 * @obj: The structure to be initialized
725 * This function will initialize a pkcs11 certificate structure.
727 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
728 * negative error value.
730 * Since: 2.12.0
733 gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t * obj)
735 *obj = gnutls_calloc (1, sizeof (struct gnutls_pkcs11_obj_st));
736 if (*obj == NULL)
738 gnutls_assert ();
739 return GNUTLS_E_MEMORY_ERROR;
742 (*obj)->info = p11_kit_uri_new ();
743 if ((*obj)->info == NULL)
745 free (*obj);
746 gnutls_assert ();
747 return GNUTLS_E_MEMORY_ERROR;
750 return 0;
754 * gnutls_pkcs11_obj_set_pin_function:
755 * @obj: The object structure
756 * @fn: the callback
757 * @userdata: data associated with the callback
759 * This function will set a callback function to be used when
760 * required to access the object. This function overrides the global
761 * set using gnutls_pkcs11_set_pin_function().
763 * Since: 3.1.0
765 void
766 gnutls_pkcs11_obj_set_pin_function (gnutls_pkcs11_obj_t obj,
767 gnutls_pin_callback_t fn,
768 void *userdata)
770 obj->pin.cb = fn;
771 obj->pin.data = userdata;
775 * gnutls_pkcs11_obj_deinit:
776 * @obj: The structure to be initialized
778 * This function will deinitialize a certificate structure.
780 * Since: 2.12.0
782 void
783 gnutls_pkcs11_obj_deinit (gnutls_pkcs11_obj_t obj)
785 _gnutls_free_datum (&obj->raw);
786 p11_kit_uri_free (obj->info);
787 free (obj);
791 * gnutls_pkcs11_obj_export:
792 * @obj: Holds the object
793 * @output_data: will contain a certificate PEM or DER encoded
794 * @output_data_size: holds the size of output_data (and will be
795 * replaced by the actual size of parameters)
797 * This function will export the PKCS11 object data. It is normal for
798 * data to be inaccesible and in that case %GNUTLS_E_INVALID_REQUEST
799 * will be returned.
801 * If the buffer provided is not long enough to hold the output, then
802 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
803 * be returned.
805 * If the structure is PEM encoded, it will have a header
806 * of "BEGIN CERTIFICATE".
808 * Returns: In case of failure a negative error code will be
809 * returned, and %GNUTLS_E_SUCCESS (0) on success.
811 * Since: 2.12.0
814 gnutls_pkcs11_obj_export (gnutls_pkcs11_obj_t obj,
815 void *output_data, size_t * output_data_size)
817 if (obj == NULL || obj->raw.data == NULL)
819 gnutls_assert ();
820 return GNUTLS_E_INVALID_REQUEST;
823 if (output_data == NULL || *output_data_size < obj->raw.size)
825 *output_data_size = obj->raw.size;
826 gnutls_assert ();
827 return GNUTLS_E_SHORT_MEMORY_BUFFER;
829 *output_data_size = obj->raw.size;
831 memcpy (output_data, obj->raw.data, obj->raw.size);
832 return 0;
836 * gnutls_pkcs11_obj_export2:
837 * @obj: Holds the object
838 * @out: will contain a certificate PEM or DER encoded
840 * This function will export the PKCS11 object data. It is normal for
841 * data to be inaccesible and in that case %GNUTLS_E_INVALID_REQUEST
842 * will be returned.
844 * The output buffer is allocated using gnutls_malloc().
846 * If the structure is PEM encoded, it will have a header
847 * of "BEGIN CERTIFICATE".
849 * Returns: In case of failure a negative error code will be
850 * returned, and %GNUTLS_E_SUCCESS (0) on success.
852 * Since: 3.1
855 gnutls_pkcs11_obj_export2 (gnutls_pkcs11_obj_t obj,
856 gnutls_datum_t *out)
858 if (obj == NULL || obj->raw.data == NULL)
860 gnutls_assert ();
861 return GNUTLS_E_INVALID_REQUEST;
864 return _gnutls_set_datum(out, obj->raw.data, obj->raw.size);
868 pkcs11_find_slot (struct ck_function_list ** module, ck_slot_id_t * slot,
869 struct p11_kit_uri *info, struct token_info *_tinfo)
871 unsigned int x, z;
873 for (x = 0; x < active_providers; x++)
875 for (z = 0; z < providers[x].nslots; z++)
877 struct token_info tinfo;
879 if (pkcs11_get_token_info
880 (providers[x].module, providers[x].slots[z],
881 &tinfo.tinfo) != CKR_OK)
883 continue;
885 tinfo.sid = providers[x].slots[z];
886 tinfo.prov = &providers[x];
888 if (pkcs11_get_slot_info
889 (providers[x].module, providers[x].slots[z],
890 &tinfo.sinfo) != CKR_OK)
892 continue;
895 if (!p11_kit_uri_match_token_info (info, &tinfo.tinfo) ||
896 !p11_kit_uri_match_module_info (info, &providers[x].info))
898 continue;
901 /* ok found */
902 *module = providers[x].module;
903 *slot = providers[x].slots[z];
905 if (_tinfo != NULL)
906 memcpy (_tinfo, &tinfo, sizeof (tinfo));
908 return 0;
912 gnutls_assert ();
913 return GNUTLS_E_PKCS11_REQUESTED_OBJECT_NOT_AVAILBLE;
917 pkcs11_open_session (struct pkcs11_session_info *sinfo,
918 struct pin_info_st *pin_info,
919 struct p11_kit_uri *info,
920 unsigned int flags)
922 ck_rv_t rv;
923 int ret;
924 ck_session_handle_t pks = 0;
925 struct ck_function_list *module;
926 ck_slot_id_t slot;
927 struct token_info tinfo;
929 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
930 if (ret < 0)
932 gnutls_assert ();
933 return ret;
936 rv = (module)->C_OpenSession (slot,
937 ((flags & SESSION_WRITE)
938 ? CKF_RW_SESSION : 0) |
939 CKF_SERIAL_SESSION, NULL, NULL, &pks);
940 if (rv != CKR_OK)
942 gnutls_assert ();
943 return pkcs11_rv_to_err (rv);
946 /* ok found */
947 sinfo->pks = pks;
948 sinfo->module = module;
949 sinfo->init = 1;
950 memcpy(&sinfo->tinfo, &tinfo.tinfo, sizeof(sinfo->tinfo));
952 if (flags & SESSION_LOGIN)
954 ret = pkcs11_login (sinfo, pin_info, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
955 if (ret < 0)
957 gnutls_assert ();
958 pkcs11_close_session (sinfo);
959 return ret;
963 return 0;
968 _pkcs11_traverse_tokens (find_func_t find_func, void *input,
969 struct p11_kit_uri *info,
970 struct pin_info_st *pin_info,
971 unsigned int flags)
973 ck_rv_t rv;
974 unsigned int found = 0, x, z;
975 int ret;
976 ck_session_handle_t pks = 0;
977 struct pkcs11_session_info sinfo;
978 struct ck_function_list *module = NULL;
980 for (x = 0; x < active_providers; x++)
982 module = providers[x].module;
983 for (z = 0; z < providers[x].nslots; z++)
985 struct token_info tinfo;
987 if (pkcs11_get_token_info (module, providers[x].slots[z],
988 &tinfo.tinfo) != CKR_OK)
990 continue;
992 tinfo.sid = providers[x].slots[z];
993 tinfo.prov = &providers[x];
995 if (pkcs11_get_slot_info (module, providers[x].slots[z],
996 &tinfo.sinfo) != CKR_OK)
998 continue;
1001 rv = (module)->C_OpenSession (providers[x].slots[z],
1002 ((flags & SESSION_WRITE)
1003 ? CKF_RW_SESSION : 0) |
1004 CKF_SERIAL_SESSION, NULL, NULL, &pks);
1005 if (rv != CKR_OK)
1007 continue;
1010 sinfo.module = module;
1011 sinfo.pks = pks;
1013 if (flags & SESSION_LOGIN)
1015 ret = pkcs11_login (&sinfo, pin_info, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
1016 if (ret < 0)
1018 gnutls_assert ();
1019 return ret;
1023 ret = find_func (&sinfo, &tinfo, &providers[x].info, input);
1025 if (ret == 0)
1027 found = 1;
1028 goto finish;
1030 else
1032 pkcs11_close_session (&sinfo);
1033 pks = 0;
1038 finish:
1039 /* final call */
1041 if (found == 0)
1043 if (module)
1045 sinfo.module = module;
1046 sinfo.pks = pks;
1047 ret = find_func (&sinfo, NULL, NULL, input);
1049 else
1050 ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1052 else
1054 ret = 0;
1057 if (pks != 0 && module != NULL)
1059 pkcs11_close_session (&sinfo);
1062 return ret;
1065 /* imports a raw certificate from a token to a pkcs11_obj_t structure.
1067 static int
1068 pkcs11_obj_import (ck_object_class_t class, gnutls_pkcs11_obj_t obj,
1069 const gnutls_datum_t * data,
1070 const gnutls_datum_t * id,
1071 const gnutls_datum_t * label,
1072 struct ck_token_info *tinfo, struct ck_info *lib_info)
1074 struct ck_attribute attr;
1075 int ret;
1077 switch (class)
1079 case CKO_CERTIFICATE:
1080 obj->type = GNUTLS_PKCS11_OBJ_X509_CRT;
1081 break;
1082 case CKO_PUBLIC_KEY:
1083 obj->type = GNUTLS_PKCS11_OBJ_PUBKEY;
1084 break;
1085 case CKO_PRIVATE_KEY:
1086 obj->type = GNUTLS_PKCS11_OBJ_PRIVKEY;
1087 break;
1088 case CKO_SECRET_KEY:
1089 obj->type = GNUTLS_PKCS11_OBJ_SECRET_KEY;
1090 break;
1091 case CKO_DATA:
1092 obj->type = GNUTLS_PKCS11_OBJ_DATA;
1093 break;
1094 default:
1095 obj->type = GNUTLS_PKCS11_OBJ_UNKNOWN;
1098 attr.type = CKA_CLASS;
1099 attr.value = &class;
1100 attr.value_len = sizeof (class);
1101 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1102 if (ret < 0)
1104 gnutls_assert ();
1105 return GNUTLS_E_MEMORY_ERROR;
1108 if (data && data->data)
1110 ret = _gnutls_set_datum (&obj->raw, data->data, data->size);
1111 if (ret < 0)
1113 gnutls_assert ();
1114 return ret;
1118 /* copy the token and library info into the uri */
1119 memcpy (p11_kit_uri_get_token_info (obj->info), tinfo, sizeof (struct ck_token_info));
1120 memcpy (p11_kit_uri_get_module_info (obj->info), lib_info, sizeof (struct ck_info));
1122 if (label && label->data)
1124 attr.type = CKA_LABEL;
1125 attr.value = label->data;
1126 attr.value_len = label->size;
1127 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1128 if (ret < 0)
1130 gnutls_assert ();
1131 return GNUTLS_E_MEMORY_ERROR;
1135 if (id && id->data)
1137 attr.type = CKA_ID;
1138 attr.value = id->data;
1139 attr.value_len = id->size;
1140 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1141 if (ret < 0)
1143 gnutls_assert ();
1144 return GNUTLS_E_MEMORY_ERROR;
1148 return 0;
1151 int pkcs11_read_pubkey(struct ck_function_list *module,
1152 ck_session_handle_t pks, ck_object_handle_t obj,
1153 ck_key_type_t key_type, gnutls_datum_t * pubkey)
1155 struct ck_attribute a[4];
1156 uint8_t tmp1[2048];
1157 uint8_t tmp2[2048];
1158 int ret;
1160 switch (key_type)
1162 case CKK_RSA:
1163 a[0].type = CKA_MODULUS;
1164 a[0].value = tmp1;
1165 a[0].value_len = sizeof (tmp1);
1166 a[1].type = CKA_PUBLIC_EXPONENT;
1167 a[1].value = tmp2;
1168 a[1].value_len = sizeof (tmp2);
1170 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1173 ret =
1174 _gnutls_set_datum (&pubkey[0],
1175 a[0].value, a[0].value_len);
1177 if (ret >= 0)
1178 ret =
1179 _gnutls_set_datum (&pubkey
1180 [1], a[1].value, a[1].value_len);
1182 if (ret < 0)
1184 gnutls_assert ();
1185 _gnutls_free_datum (&pubkey[1]);
1186 _gnutls_free_datum (&pubkey[0]);
1187 return GNUTLS_E_MEMORY_ERROR;
1190 else
1192 gnutls_assert ();
1193 return GNUTLS_E_PKCS11_ERROR;
1195 break;
1196 case CKK_DSA:
1197 a[0].type = CKA_PRIME;
1198 a[0].value = tmp1;
1199 a[0].value_len = sizeof (tmp1);
1200 a[1].type = CKA_SUBPRIME;
1201 a[1].value = tmp2;
1202 a[1].value_len = sizeof (tmp2);
1204 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1206 ret =
1207 _gnutls_set_datum (&pubkey[0],
1208 a[0].value, a[0].value_len);
1210 if (ret >= 0)
1211 ret =
1212 _gnutls_set_datum (&pubkey
1213 [1], a[1].value, a[1].value_len);
1215 if (ret < 0)
1217 gnutls_assert ();
1218 _gnutls_free_datum (&pubkey[1]);
1219 _gnutls_free_datum (&pubkey[0]);
1220 return GNUTLS_E_MEMORY_ERROR;
1223 else
1225 gnutls_assert ();
1226 return GNUTLS_E_PKCS11_ERROR;
1229 a[0].type = CKA_BASE;
1230 a[0].value = tmp1;
1231 a[0].value_len = sizeof (tmp1);
1232 a[1].type = CKA_VALUE;
1233 a[1].value = tmp2;
1234 a[1].value_len = sizeof (tmp2);
1236 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1238 ret =
1239 _gnutls_set_datum (&pubkey[2],
1240 a[0].value, a[0].value_len);
1242 if (ret >= 0)
1243 ret =
1244 _gnutls_set_datum (&pubkey
1245 [3], a[1].value, a[1].value_len);
1247 if (ret < 0)
1249 gnutls_assert ();
1250 _gnutls_free_datum (&pubkey[0]);
1251 _gnutls_free_datum (&pubkey[1]);
1252 _gnutls_free_datum (&pubkey[2]);
1253 _gnutls_free_datum (&pubkey[3]);
1254 return GNUTLS_E_MEMORY_ERROR;
1257 else
1259 gnutls_assert ();
1260 return GNUTLS_E_PKCS11_ERROR;
1262 break;
1263 case CKK_ECDSA:
1264 a[0].type = CKA_EC_PARAMS;
1265 a[0].value = tmp1;
1266 a[0].value_len = sizeof (tmp1);
1267 a[1].type = CKA_EC_POINT;
1268 a[1].value = tmp2;
1269 a[1].value_len = sizeof (tmp2);
1271 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1273 ret =
1274 _gnutls_set_datum (&pubkey[0],
1275 a[0].value, a[0].value_len);
1277 if (ret >= 0)
1278 ret =
1279 _gnutls_set_datum (&pubkey
1280 [1], a[1].value, a[1].value_len);
1282 if (ret < 0)
1284 gnutls_assert ();
1285 _gnutls_free_datum (&pubkey[1]);
1286 _gnutls_free_datum (&pubkey[0]);
1287 return GNUTLS_E_MEMORY_ERROR;
1290 else
1292 gnutls_assert ();
1293 return GNUTLS_E_PKCS11_ERROR;
1296 break;
1297 default:
1298 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1301 return 0;
1304 static int
1305 pkcs11_obj_import_pubkey (struct ck_function_list *module,
1306 ck_session_handle_t pks,
1307 ck_object_handle_t obj,
1308 gnutls_pkcs11_obj_t crt,
1309 const gnutls_datum_t * id,
1310 const gnutls_datum_t * label,
1311 struct ck_token_info *tinfo,
1312 struct ck_info *lib_info)
1314 struct ck_attribute a[4];
1315 ck_key_type_t key_type;
1316 int ret;
1317 ck_bool_t tval;
1319 a[0].type = CKA_KEY_TYPE;
1320 a[0].value = &key_type;
1321 a[0].value_len = sizeof (key_type);
1323 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1325 crt->pk_algorithm = mech_to_pk(key_type);
1327 ret = pkcs11_read_pubkey(module, pks, obj, key_type, crt->pubkey);
1328 if (ret < 0)
1329 return gnutls_assert_val(ret);
1332 /* read key usage flags */
1333 a[0].type = CKA_ENCRYPT;
1334 a[0].value = &tval;
1335 a[0].value_len = sizeof (tval);
1337 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1339 if (tval != 0)
1341 crt->key_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
1345 a[0].type = CKA_VERIFY;
1346 a[0].value = &tval;
1347 a[0].value_len = sizeof (tval);
1349 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1351 if (tval != 0)
1353 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1354 GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1355 | GNUTLS_KEY_NON_REPUDIATION;
1359 a[0].type = CKA_VERIFY_RECOVER;
1360 a[0].value = &tval;
1361 a[0].value_len = sizeof (tval);
1363 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1365 if (tval != 0)
1367 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1368 GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1369 | GNUTLS_KEY_NON_REPUDIATION;
1373 a[0].type = CKA_DERIVE;
1374 a[0].value = &tval;
1375 a[0].value_len = sizeof (tval);
1377 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1379 if (tval != 0)
1381 crt->key_usage |= GNUTLS_KEY_KEY_AGREEMENT;
1385 a[0].type = CKA_WRAP;
1386 a[0].value = &tval;
1387 a[0].value_len = sizeof (tval);
1389 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1391 if (tval != 0)
1393 crt->key_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
1397 return pkcs11_obj_import (CKO_PUBLIC_KEY, crt, NULL, id, label,
1398 tinfo, lib_info);
1401 static int
1402 find_obj_url (struct pkcs11_session_info *sinfo,
1403 struct token_info *info, struct ck_info *lib_info, void *input)
1405 struct url_find_data_st *find_data = input;
1406 struct ck_attribute a[4];
1407 struct ck_attribute *attr;
1408 ck_object_class_t class = -1;
1409 ck_certificate_type_t type = (ck_certificate_type_t)-1;
1410 ck_rv_t rv;
1411 ck_object_handle_t obj;
1412 unsigned long count, a_vals;
1413 int found = 0, ret;
1414 uint8_t *cert_data = NULL;
1415 char label_tmp[PKCS11_LABEL_SIZE];
1416 char id_tmp[PKCS11_ID_SIZE];
1418 if (info == NULL)
1419 { /* we don't support multiple calls */
1420 gnutls_assert ();
1421 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1424 /* do not bother reading the token if basic fields do not match
1426 if (!p11_kit_uri_match_token_info (find_data->crt->info, &info->tinfo) ||
1427 !p11_kit_uri_match_module_info (find_data->crt->info, lib_info))
1429 gnutls_assert ();
1430 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1433 a_vals = 0;
1434 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID);
1435 if (attr)
1437 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1438 a_vals++;
1441 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_LABEL);
1442 if (attr)
1444 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1445 a_vals++;
1448 if (!a_vals)
1450 gnutls_assert ();
1451 return GNUTLS_E_INVALID_REQUEST;
1454 /* search the token for the id */
1456 cert_data = gnutls_malloc (MAX_CERT_SIZE);
1457 if (cert_data == NULL)
1459 gnutls_assert ();
1460 return GNUTLS_E_MEMORY_ERROR;
1463 /* Find objects with given class and type */
1464 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_CLASS);
1465 if (attr)
1467 if(attr->value && attr->value_len == sizeof (ck_object_class_t))
1468 class = *((ck_object_class_t*)attr->value);
1469 if (class == CKO_CERTIFICATE)
1470 type = CKC_X_509;
1471 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1472 a_vals++;
1475 if (type != (ck_certificate_type_t)-1)
1477 a[a_vals].type = CKA_CERTIFICATE_TYPE;
1478 a[a_vals].value = &type;
1479 a[a_vals].value_len = sizeof type;
1480 a_vals++;
1483 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, a, a_vals);
1484 if (rv != CKR_OK)
1486 gnutls_assert ();
1487 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
1488 ret = pkcs11_rv_to_err (rv);
1489 goto cleanup;
1492 while (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
1494 a[0].type = CKA_VALUE;
1495 a[0].value = cert_data;
1496 a[0].value_len = MAX_CERT_SIZE;
1497 a[1].type = CKA_LABEL;
1498 a[1].value = label_tmp;
1499 a[1].value_len = sizeof (label_tmp);
1500 a[2].type = CKA_ID;
1501 a[2].value = id_tmp;
1502 a[2].value_len = sizeof(id_tmp);
1504 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 3) == CKR_OK)
1506 gnutls_datum_t id = { a[2].value, a[2].value_len };
1507 gnutls_datum_t data = { a[0].value, a[0].value_len };
1508 gnutls_datum_t label = { a[1].value, a[1].value_len };
1510 if (class == CKO_PUBLIC_KEY)
1512 ret =
1513 pkcs11_obj_import_pubkey (sinfo->module, sinfo->pks, obj,
1514 find_data->crt,
1515 &id, &label,
1516 &info->tinfo, lib_info);
1518 else
1520 ret =
1521 pkcs11_obj_import (class,
1522 find_data->crt,
1523 &data, &id, &label,
1524 &info->tinfo, lib_info);
1526 if (ret < 0)
1528 gnutls_assert ();
1529 goto cleanup;
1532 found = 1;
1533 break;
1535 else
1537 _gnutls_debug_log ("pk11: Skipped cert, missing attrs.\n");
1541 if (found == 0)
1543 gnutls_assert ();
1544 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1546 else
1548 ret = 0;
1551 cleanup:
1552 gnutls_free (cert_data);
1553 pkcs11_find_objects_final (sinfo);
1555 return ret;
1558 unsigned int
1559 pkcs11_obj_flags_to_int (unsigned int flags)
1561 unsigned int ret_flags = 0;
1563 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN)
1564 ret_flags |= SESSION_LOGIN;
1565 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO)
1566 ret_flags |= SESSION_LOGIN|SESSION_SO;
1568 return ret_flags;
1572 * gnutls_pkcs11_obj_import_url:
1573 * @obj: The structure to store the object
1574 * @url: a PKCS 11 url identifying the key
1575 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1577 * This function will "import" a PKCS 11 URL identifying an object (e.g. certificate)
1578 * to the #gnutls_pkcs11_obj_t structure. This does not involve any
1579 * parsing (such as X.509 or OpenPGP) since the #gnutls_pkcs11_obj_t is
1580 * format agnostic. Only data are transferred.
1582 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1583 * negative error value.
1585 * Since: 2.12.0
1588 gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t obj, const char *url,
1589 unsigned int flags)
1591 int ret;
1592 struct url_find_data_st find_data;
1594 /* fill in the find data structure */
1595 find_data.crt = obj;
1597 ret = pkcs11_url_to_info (url, &obj->info);
1598 if (ret < 0)
1600 gnutls_assert ();
1601 return ret;
1604 ret =
1605 _pkcs11_traverse_tokens (find_obj_url, &find_data, obj->info,
1606 &obj->pin, pkcs11_obj_flags_to_int (flags));
1608 if (ret < 0)
1610 gnutls_assert ();
1611 return ret;
1614 return 0;
1617 struct token_num
1619 struct p11_kit_uri *info;
1620 unsigned int seq; /* which one we are looking for */
1621 unsigned int current; /* which one are we now */
1624 static int
1625 find_token_num (struct pkcs11_session_info* sinfo,
1626 struct token_info *tinfo,
1627 struct ck_info *lib_info, void *input)
1629 struct token_num *find_data = input;
1631 if (tinfo == NULL)
1632 { /* we don't support multiple calls */
1633 gnutls_assert ();
1634 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1637 if (find_data->current == find_data->seq)
1639 memcpy (p11_kit_uri_get_token_info (find_data->info), &tinfo->tinfo, sizeof (struct ck_token_info));
1640 memcpy (p11_kit_uri_get_module_info (find_data->info), lib_info, sizeof (struct ck_info));
1641 return 0;
1644 find_data->current++;
1645 /* search the token for the id */
1648 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* non zero is enough */
1652 * gnutls_pkcs11_token_get_url:
1653 * @seq: sequence number starting from 0
1654 * @detailed: non zero if a detailed URL is required
1655 * @url: will contain an allocated url
1657 * This function will return the URL for each token available
1658 * in system. The url has to be released using gnutls_free()
1660 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1661 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if the sequence number
1662 * exceeds the available tokens, otherwise a negative error value.
1664 * Since: 2.12.0
1667 gnutls_pkcs11_token_get_url (unsigned int seq,
1668 gnutls_pkcs11_url_type_t detailed, char **url)
1670 int ret;
1671 struct token_num tn;
1673 memset (&tn, 0, sizeof (tn));
1674 tn.seq = seq;
1675 tn.info = p11_kit_uri_new ();
1677 ret = _pkcs11_traverse_tokens (find_token_num, &tn, NULL, NULL, 0);
1678 if (ret < 0)
1680 p11_kit_uri_free (tn.info);
1681 gnutls_assert ();
1682 return ret;
1685 ret = pkcs11_info_to_url (tn.info, detailed, url);
1686 p11_kit_uri_free (tn.info);
1688 if (ret < 0)
1690 gnutls_assert ();
1691 return ret;
1694 return 0;
1699 * gnutls_pkcs11_token_get_info:
1700 * @url: should contain a PKCS 11 URL
1701 * @ttype: Denotes the type of information requested
1702 * @output: where output will be stored
1703 * @output_size: contains the maximum size of the output and will be overwritten with actual
1705 * This function will return information about the PKCS 11 token such
1706 * as the label, id, etc.
1708 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code
1709 * on error.
1711 * Since: 2.12.0
1714 gnutls_pkcs11_token_get_info (const char *url,
1715 gnutls_pkcs11_token_info_t ttype,
1716 void *output, size_t * output_size)
1718 struct p11_kit_uri *info = NULL;
1719 const uint8_t *str;
1720 size_t str_max;
1721 size_t len;
1722 int ret;
1724 ret = pkcs11_url_to_info (url, &info);
1725 if (ret < 0)
1727 gnutls_assert ();
1728 return ret;
1731 switch (ttype)
1733 case GNUTLS_PKCS11_TOKEN_LABEL:
1734 str = p11_kit_uri_get_token_info (info)->label;
1735 str_max = 32;
1736 break;
1737 case GNUTLS_PKCS11_TOKEN_SERIAL:
1738 str = p11_kit_uri_get_token_info (info)->serial_number;
1739 str_max = 16;
1740 break;
1741 case GNUTLS_PKCS11_TOKEN_MANUFACTURER:
1742 str = p11_kit_uri_get_token_info (info)->manufacturer_id;
1743 str_max = 32;
1744 break;
1745 case GNUTLS_PKCS11_TOKEN_MODEL:
1746 str = p11_kit_uri_get_token_info (info)->model;
1747 str_max = 16;
1748 break;
1749 default:
1750 p11_kit_uri_free (info);
1751 gnutls_assert ();
1752 return GNUTLS_E_INVALID_REQUEST;
1755 len = p11_kit_space_strlen (str, str_max);
1757 if (len + 1 > *output_size)
1759 *output_size = len + 1;
1760 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1763 memcpy (output, str, len);
1764 ((char*)output)[len] = '\0';
1766 *output_size = len;
1768 p11_kit_uri_free (info);
1769 return 0;
1773 * gnutls_pkcs11_obj_export_url:
1774 * @obj: Holds the PKCS 11 certificate
1775 * @detailed: non zero if a detailed URL is required
1776 * @url: will contain an allocated url
1778 * This function will export a URL identifying the given certificate.
1780 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1781 * negative error value.
1783 * Since: 2.12.0
1786 gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t obj,
1787 gnutls_pkcs11_url_type_t detailed, char **url)
1789 int ret;
1791 ret = pkcs11_info_to_url (obj->info, detailed, url);
1792 if (ret < 0)
1794 gnutls_assert ();
1795 return ret;
1798 return 0;
1802 * gnutls_pkcs11_obj_get_type:
1803 * @obj: Holds the PKCS 11 object
1805 * This function will return the type of the certificate being
1806 * stored in the structure.
1808 * Returns: The type of the certificate.
1810 * Since: 2.12.0
1812 gnutls_pkcs11_obj_type_t
1813 gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t obj)
1815 return obj->type;
1818 struct pkey_list
1820 gnutls_buffer_st *key_ids;
1821 size_t key_ids_size;
1825 static int
1826 retrieve_pin_from_source (const char *pinfile, struct ck_token_info *token_info,
1827 int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
1829 unsigned int flags = 0;
1830 struct p11_kit_uri *token_uri;
1831 struct p11_kit_pin *result;
1832 char *label;
1834 label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1835 if (label == NULL)
1837 gnutls_assert ();
1838 return GNUTLS_E_MEMORY_ERROR;
1841 token_uri = p11_kit_uri_new ();
1842 if (token_uri == NULL)
1844 free (label);
1845 gnutls_assert ();
1846 return GNUTLS_E_MEMORY_ERROR;
1849 memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1850 sizeof (struct ck_token_info));
1852 if (attempts)
1853 flags |= P11_KIT_PIN_FLAGS_RETRY;
1854 if (user_type == CKU_USER)
1856 flags |= P11_KIT_PIN_FLAGS_USER_LOGIN;
1857 if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1858 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1859 if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1860 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1862 else if (user_type == CKU_SO)
1864 flags |= P11_KIT_PIN_FLAGS_SO_LOGIN;
1865 if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
1866 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1867 if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
1868 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1870 else if (user_type == CKU_CONTEXT_SPECIFIC)
1872 flags |= P11_KIT_PIN_FLAGS_CONTEXT_LOGIN;
1875 result = p11_kit_pin_request (pinfile, token_uri, label, flags);
1876 p11_kit_uri_free (token_uri);
1877 free (label);
1879 if (result == NULL)
1881 gnutls_assert ();
1882 return GNUTLS_E_PKCS11_PIN_ERROR;
1885 *pin = result;
1886 return 0;
1889 static int
1890 retrieve_pin_from_callback (const struct pin_info_st *pin_info,
1891 struct ck_token_info *token_info,
1892 int attempts, ck_user_type_t user_type,
1893 struct p11_kit_pin **pin)
1895 char pin_value[GNUTLS_PKCS11_MAX_PIN_LEN];
1896 unsigned int flags = 0;
1897 char *token_str;
1898 char *label;
1899 struct p11_kit_uri *token_uri;
1900 int ret = 0;
1902 label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1903 if (label == NULL)
1905 gnutls_assert ();
1906 return GNUTLS_E_MEMORY_ERROR;
1909 token_uri = p11_kit_uri_new ();
1910 if (token_uri == NULL)
1912 free (label);
1913 gnutls_assert ();
1914 return GNUTLS_E_MEMORY_ERROR;
1917 memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1918 sizeof (struct ck_token_info));
1919 ret = pkcs11_info_to_url (token_uri, 1, &token_str);
1920 p11_kit_uri_free (token_uri);
1922 if (ret < 0)
1924 free (label);
1925 gnutls_assert ();
1926 return GNUTLS_E_MEMORY_ERROR;
1929 if (user_type == CKU_USER)
1931 flags |= GNUTLS_PIN_USER;
1932 if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1933 flags |= GNUTLS_PIN_COUNT_LOW;
1934 if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1935 flags |= GNUTLS_PIN_FINAL_TRY;
1937 else if (user_type == CKU_SO)
1939 flags |= GNUTLS_PIN_SO;
1940 if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
1941 flags |= GNUTLS_PIN_COUNT_LOW;
1942 if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
1943 flags |= GNUTLS_PIN_FINAL_TRY;
1946 if (attempts > 0)
1947 flags |= GNUTLS_PIN_WRONG;
1949 if (pin_info && pin_info->cb)
1950 ret = pin_info->cb (pin_info->data, attempts, (char*)token_str, label,
1951 flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
1952 else if (_gnutls_pin_func)
1953 ret = _gnutls_pin_func (_gnutls_pin_data, attempts, (char*)token_str, label,
1954 flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
1955 else
1956 ret = gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR);
1958 free (token_str);
1959 free (label);
1961 if (ret < 0)
1962 return gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR);
1964 *pin = p11_kit_pin_new_for_string (pin_value);
1966 if (*pin == NULL)
1967 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1969 return 0;
1972 static int
1973 retrieve_pin (struct pin_info_st* pin_info, struct p11_kit_uri *info,
1974 struct ck_token_info *token_info, int attempts,
1975 ck_user_type_t user_type, struct p11_kit_pin **pin)
1977 const char *pinfile;
1978 int ret = GNUTLS_E_PKCS11_PIN_ERROR;
1980 *pin = NULL;
1982 /* Check if a pinfile is specified, and use that if possible */
1983 pinfile = p11_kit_uri_get_pinfile (info);
1984 if (pinfile != NULL)
1986 _gnutls_debug_log("pk11: Using pinfile to retrieve PIN\n");
1987 ret = retrieve_pin_from_source (pinfile, token_info, attempts, user_type, pin);
1990 /* The global gnutls pin callback */
1991 if (ret < 0)
1992 ret = retrieve_pin_from_callback (pin_info, token_info, attempts, user_type, pin);
1994 /* Otherwise, PIN entry is necessary for login, so fail if there's
1995 * no callback. */
1997 if (ret < 0)
1999 gnutls_assert ();
2000 _gnutls_debug_log ("pk11: No suitable pin callback but login required.\n");
2003 return ret;
2007 pkcs11_login (struct pkcs11_session_info * sinfo, struct pin_info_st * pin_info,
2008 const struct token_info *tokinfo, struct p11_kit_uri *info, int so)
2010 struct ck_session_info session_info;
2011 int attempt = 0, ret;
2012 ck_user_type_t user_type;
2013 ck_rv_t rv;
2015 user_type = (so == 0) ? CKU_USER : CKU_SO;
2016 if (so == 0 && (tokinfo->tinfo.flags & CKF_LOGIN_REQUIRED) == 0)
2018 gnutls_assert ();
2019 _gnutls_debug_log ("pk11: No login required.\n");
2020 return 0;
2023 /* For a token with a "protected" (out-of-band) authentication
2024 * path, calling login with a NULL username is all that is
2025 * required. */
2026 if (tokinfo->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
2028 rv = (sinfo->module)->C_Login (sinfo->pks, (so == 0) ? CKU_USER : CKU_SO, NULL, 0);
2029 if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
2031 return 0;
2033 else
2035 gnutls_assert ();
2036 _gnutls_debug_log ("pk11: Protected login failed.\n");
2037 ret = GNUTLS_E_PKCS11_ERROR;
2038 goto cleanup;
2044 struct p11_kit_pin *pin;
2045 struct ck_token_info tinfo;
2047 memcpy (&tinfo, &tokinfo->tinfo, sizeof(tinfo));
2049 /* Check whether the session is already logged in, and if so, just skip */
2050 rv = (sinfo->module)->C_GetSessionInfo (sinfo->pks, &session_info);
2051 if (rv == CKR_OK && (session_info.state == CKS_RO_USER_FUNCTIONS ||
2052 session_info.state == CKS_RW_USER_FUNCTIONS))
2054 ret = 0;
2055 goto cleanup;
2058 /* If login has been attempted once already, check the token
2059 * status again, the flags might change. */
2060 if (attempt)
2062 if (pkcs11_get_token_info
2063 (tokinfo->prov->module, tokinfo->sid, &tinfo) != CKR_OK)
2065 gnutls_assert ();
2066 _gnutls_debug_log ("pk11: GetTokenInfo failed\n");
2067 ret = GNUTLS_E_PKCS11_ERROR;
2068 goto cleanup;
2072 ret = retrieve_pin (pin_info, info, &tinfo, attempt++, user_type, &pin);
2073 if (ret < 0)
2075 gnutls_assert ();
2076 goto cleanup;
2079 rv = (sinfo->module)->C_Login (sinfo->pks, user_type,
2080 (unsigned char *)p11_kit_pin_get_value (pin, NULL),
2081 p11_kit_pin_get_length (pin));
2083 p11_kit_pin_unref (pin);
2085 while (rv == CKR_PIN_INCORRECT);
2087 _gnutls_debug_log ("pk11: Login result = %lu\n", rv);
2090 ret = (rv == CKR_OK
2091 || rv == CKR_USER_ALREADY_LOGGED_IN) ? 0 : pkcs11_rv_to_err (rv);
2093 cleanup:
2094 return ret;
2098 pkcs11_call_token_func (struct p11_kit_uri *info, const unsigned retry)
2100 struct ck_token_info *tinfo;
2101 char *label;
2102 int ret = 0;
2104 tinfo = p11_kit_uri_get_token_info (info);
2105 label = p11_kit_space_strdup (tinfo->label, sizeof (tinfo->label));
2106 ret = (_gnutls_token_func) (_gnutls_token_data, label, retry);
2107 free (label);
2109 return ret;
2113 static int
2114 find_privkeys (struct pkcs11_session_info* sinfo,
2115 struct token_info *info, struct pkey_list *list)
2117 struct ck_attribute a[3];
2118 ck_object_class_t class;
2119 ck_rv_t rv;
2120 ck_object_handle_t obj;
2121 unsigned long count, current;
2122 char certid_tmp[PKCS11_ID_SIZE];
2124 class = CKO_PRIVATE_KEY;
2126 /* Find an object with private key class and a certificate ID
2127 * which matches the certificate. */
2128 /* FIXME: also match the cert subject. */
2129 a[0].type = CKA_CLASS;
2130 a[0].value = &class;
2131 a[0].value_len = sizeof class;
2133 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, a, 1);
2134 if (rv != CKR_OK)
2136 gnutls_assert ();
2137 return pkcs11_rv_to_err (rv);
2140 list->key_ids_size = 0;
2141 while (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
2143 list->key_ids_size++;
2146 pkcs11_find_objects_final (sinfo);
2148 if (list->key_ids_size == 0)
2150 gnutls_assert ();
2151 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2154 list->key_ids =
2155 gnutls_malloc (sizeof (gnutls_buffer_st) * list->key_ids_size);
2156 if (list->key_ids == NULL)
2158 gnutls_assert ();
2159 return GNUTLS_E_MEMORY_ERROR;
2162 /* actual search */
2163 a[0].type = CKA_CLASS;
2164 a[0].value = &class;
2165 a[0].value_len = sizeof class;
2167 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, a, 1);
2168 if (rv != CKR_OK)
2170 gnutls_assert ();
2171 return pkcs11_rv_to_err (rv);
2174 current = 0;
2175 while (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
2178 a[0].type = CKA_ID;
2179 a[0].value = certid_tmp;
2180 a[0].value_len = sizeof (certid_tmp);
2182 _gnutls_buffer_init (&list->key_ids[current]);
2184 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1) == CKR_OK)
2186 _gnutls_buffer_append_data (&list->key_ids[current],
2187 a[0].value, a[0].value_len);
2188 current++;
2191 if (current > list->key_ids_size)
2192 break;
2195 pkcs11_find_objects_final (sinfo);
2197 list->key_ids_size = current - 1;
2199 return 0;
2202 /* Recover certificate list from tokens */
2205 static int
2206 find_objs (struct pkcs11_session_info* sinfo,
2207 struct token_info *info, struct ck_info *lib_info, void *input)
2209 struct crt_find_data_st *find_data = input;
2210 struct ck_attribute a[4];
2211 struct ck_attribute *attr;
2212 ck_object_class_t class = (ck_object_class_t)-1;
2213 ck_certificate_type_t type = (ck_certificate_type_t)-1;
2214 unsigned int trusted;
2215 ck_rv_t rv;
2216 ck_object_handle_t obj;
2217 unsigned long count;
2218 uint8_t *cert_data;
2219 char certid_tmp[PKCS11_ID_SIZE];
2220 char label_tmp[PKCS11_LABEL_SIZE];
2221 int ret;
2222 struct pkey_list plist; /* private key holder */
2223 unsigned int i, tot_values = 0;
2225 if (info == NULL)
2226 { /* final call */
2227 if (find_data->current <= *find_data->n_list)
2228 ret = 0;
2229 else
2230 ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
2232 *find_data->n_list = find_data->current;
2234 return ret;
2237 /* do not bother reading the token if basic fields do not match
2239 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2240 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2242 gnutls_assert ();
2243 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2246 memset (&plist, 0, sizeof (plist));
2248 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2250 ret = find_privkeys (sinfo, info, &plist);
2251 if (ret < 0)
2253 gnutls_assert ();
2254 return ret;
2257 if (plist.key_ids_size == 0)
2259 gnutls_assert ();
2260 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2264 /* Find objects with given class and type */
2265 attr = p11_kit_uri_get_attribute (find_data->info, CKA_CLASS);
2266 if (attr)
2268 if(attr->value && attr->value_len == sizeof (ck_object_class_t))
2269 class = *((ck_object_class_t*)attr->value);
2270 if (class == CKO_CERTIFICATE)
2271 type = CKC_X_509;
2274 cert_data = gnutls_malloc (MAX_CERT_SIZE);
2275 if (cert_data == NULL)
2277 gnutls_assert ();
2278 return GNUTLS_E_MEMORY_ERROR;
2281 /* Find objects with cert class and X.509 cert type. */
2283 tot_values = 0;
2285 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL
2286 || find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2288 class = CKO_CERTIFICATE;
2289 type = CKC_X_509;
2290 trusted = 1;
2292 a[tot_values].type = CKA_CLASS;
2293 a[tot_values].value = &class;
2294 a[tot_values].value_len = sizeof class;
2295 tot_values++;
2297 a[tot_values].type = CKA_CERTIFICATE_TYPE;
2298 a[tot_values].value = &type;
2299 a[tot_values].value_len = sizeof type;
2300 tot_values++;
2303 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED)
2305 class = CKO_CERTIFICATE;
2306 type = CKC_X_509;
2307 trusted = 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 a[tot_values].type = CKA_TRUSTED;
2315 a[tot_values].value = &trusted;
2316 a[tot_values].value_len = sizeof trusted;
2317 tot_values++;
2320 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PUBKEY)
2322 class = CKO_PUBLIC_KEY;
2324 a[tot_values].type = CKA_CLASS;
2325 a[tot_values].value = &class;
2326 a[tot_values].value_len = sizeof class;
2327 tot_values++;
2329 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
2331 class = CKO_PRIVATE_KEY;
2333 a[tot_values].type = CKA_CLASS;
2334 a[tot_values].value = &class;
2335 a[tot_values].value_len = sizeof class;
2336 tot_values++;
2338 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2340 if (class != (ck_object_class_t)-1)
2342 a[tot_values].type = CKA_CLASS;
2343 a[tot_values].value = &class;
2344 a[tot_values].value_len = sizeof class;
2345 tot_values++;
2347 if (type != (ck_certificate_type_t)-1)
2349 a[tot_values].type = CKA_CERTIFICATE_TYPE;
2350 a[tot_values].value = &type;
2351 a[tot_values].value_len = sizeof type;
2352 tot_values++;
2355 else
2357 gnutls_assert ();
2358 ret = GNUTLS_E_INVALID_REQUEST;
2359 goto fail;
2362 attr = p11_kit_uri_get_attribute (find_data->info, CKA_ID);
2363 if (attr != NULL)
2365 memcpy (a + tot_values, attr, sizeof (struct ck_attribute));
2366 tot_values++;
2369 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, a, tot_values);
2370 if (rv != CKR_OK)
2372 gnutls_assert ();
2373 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
2374 return pkcs11_rv_to_err (rv);
2377 while (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
2379 gnutls_datum_t label, id, value;
2381 a[0].type = CKA_LABEL;
2382 a[0].value = label_tmp;
2383 a[0].value_len = sizeof label_tmp;
2385 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1) == CKR_OK)
2387 label.data = a[0].value;
2388 label.size = a[0].value_len;
2390 else
2392 label.data = NULL;
2393 label.size = 0;
2396 a[0].type = CKA_ID;
2397 a[0].value = certid_tmp;
2398 a[0].value_len = sizeof certid_tmp;
2400 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1) == CKR_OK)
2402 id.data = a[0].value;
2403 id.size = a[0].value_len;
2405 else
2407 id.data = NULL;
2408 id.size = 0;
2411 a[0].type = CKA_VALUE;
2412 a[0].value = cert_data;
2413 a[0].value_len = MAX_CERT_SIZE;
2414 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1) == CKR_OK)
2416 value.data = a[0].value;
2417 value.size = a[0].value_len;
2419 else
2421 value.data = NULL;
2422 value.size = 0;
2425 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2427 a[0].type = CKA_CLASS;
2428 a[0].value = &class;
2429 a[0].value_len = sizeof class;
2431 pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1);
2434 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2436 for (i = 0; i < plist.key_ids_size; i++)
2438 if (plist.key_ids[i].length !=
2439 a[1].value_len
2440 || memcmp (plist.key_ids[i].data,
2441 a[1].value, a[1].value_len) != 0)
2443 /* not found */
2444 continue;
2449 if (find_data->current < *find_data->n_list)
2451 ret =
2452 gnutls_pkcs11_obj_init (&find_data->p_list[find_data->current]);
2453 if (ret < 0)
2455 gnutls_assert ();
2456 goto fail;
2459 if (class == CKO_PUBLIC_KEY)
2461 ret =
2462 pkcs11_obj_import_pubkey (sinfo->module, sinfo->pks, obj,
2463 find_data->p_list
2464 [find_data->current],
2465 &id, &label,
2466 &info->tinfo, lib_info);
2468 else
2470 ret =
2471 pkcs11_obj_import (class,
2472 find_data->p_list
2473 [find_data->current],
2474 &value, &id, &label,
2475 &info->tinfo, lib_info);
2477 if (ret < 0)
2479 gnutls_assert ();
2480 goto fail;
2484 find_data->current++;
2488 gnutls_free (cert_data);
2489 pkcs11_find_objects_final (sinfo);
2491 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* continue until all tokens have been checked */
2493 fail:
2494 gnutls_free (cert_data);
2495 pkcs11_find_objects_final (sinfo);
2496 if (plist.key_ids != NULL)
2498 for (i = 0; i < plist.key_ids_size; i++)
2500 _gnutls_buffer_clear (&plist.key_ids[i]);
2502 gnutls_free (plist.key_ids);
2504 for (i = 0; i < find_data->current; i++)
2506 gnutls_pkcs11_obj_deinit (find_data->p_list[i]);
2508 find_data->current = 0;
2510 return ret;
2514 * gnutls_pkcs11_obj_list_import_url:
2515 * @p_list: An uninitialized object list (may be NULL)
2516 * @n_list: initially should hold the maximum size of the list. Will contain the actual size.
2517 * @url: A PKCS 11 url identifying a set of objects
2518 * @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
2519 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2521 * This function will initialize and set values to an object list
2522 * by using all objects identified by a PKCS 11 URL.
2524 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2525 * negative error value.
2527 * Since: 2.12.0
2530 gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list,
2531 unsigned int *n_list,
2532 const char *url,
2533 gnutls_pkcs11_obj_attr_t attrs,
2534 unsigned int flags)
2536 int ret;
2537 struct crt_find_data_st find_data;
2539 memset (&find_data, 0, sizeof (find_data));
2541 /* fill in the find data structure */
2542 find_data.p_list = p_list;
2543 find_data.n_list = n_list;
2544 find_data.flags = attrs;
2545 find_data.current = 0;
2547 if (url == NULL || url[0] == 0)
2549 url = "pkcs11:";
2552 ret = pkcs11_url_to_info (url, &find_data.info);
2553 if (ret < 0)
2555 gnutls_assert ();
2556 return ret;
2559 ret =
2560 _pkcs11_traverse_tokens (find_objs, &find_data, find_data.info,
2561 NULL,
2562 pkcs11_obj_flags_to_int (flags));
2563 p11_kit_uri_free (find_data.info);
2565 if (ret < 0)
2567 gnutls_assert ();
2568 return ret;
2571 return 0;
2575 * gnutls_pkcs11_obj_list_import_url2:
2576 * @p_list: An uninitialized object list (may be NULL)
2577 * @n_list: It will contain the size of the list.
2578 * @url: A PKCS 11 url identifying a set of objects
2579 * @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
2580 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2582 * This function will initialize and set values to an object list
2583 * by using all objects identified by the PKCS 11 URL. The output
2584 * is stored in @p_list, which will be initialized.
2586 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2587 * negative error value.
2589 * Since: 3.1.0
2592 gnutls_pkcs11_obj_list_import_url2 (gnutls_pkcs11_obj_t ** p_list,
2593 unsigned int *n_list,
2594 const char *url,
2595 gnutls_pkcs11_obj_attr_t attrs,
2596 unsigned int flags)
2598 unsigned int init = 1024;
2599 int ret;
2601 *p_list = gnutls_malloc(sizeof(gnutls_pkcs11_obj_t)*init);
2602 if (*p_list == NULL)
2604 gnutls_assert();
2605 return GNUTLS_E_MEMORY_ERROR;
2608 ret = gnutls_pkcs11_obj_list_import_url( *p_list, &init, url, attrs, flags);
2609 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
2611 *p_list = gnutls_realloc_fast(*p_list, sizeof(gnutls_pkcs11_obj_t)*init);
2612 if (*p_list == NULL)
2613 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2615 ret = gnutls_pkcs11_obj_list_import_url( *p_list, &init, url, attrs, flags);
2618 if (ret < 0)
2620 gnutls_assert();
2621 gnutls_free(*p_list);
2622 *p_list = NULL;
2623 return ret;
2626 *n_list = init;
2627 return 0;
2632 * gnutls_x509_crt_import_pkcs11_url:
2633 * @crt: A certificate of type #gnutls_x509_crt_t
2634 * @url: A PKCS 11 url
2635 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2637 * This function will import a PKCS 11 certificate directly from a token
2638 * without involving the #gnutls_pkcs11_obj_t structure. This function will
2639 * fail if the certificate stored is not of X.509 type.
2641 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2642 * negative error value.
2644 * Since: 2.12.0
2647 gnutls_x509_crt_import_pkcs11_url (gnutls_x509_crt_t crt,
2648 const char *url, unsigned int flags)
2650 gnutls_pkcs11_obj_t pcrt;
2651 int ret;
2653 ret = gnutls_pkcs11_obj_init (&pcrt);
2654 if (ret < 0)
2656 gnutls_assert ();
2657 return ret;
2660 if (crt->pin.cb)
2661 gnutls_pkcs11_obj_set_pin_function (pcrt, crt->pin.cb, crt->pin.data);
2663 ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
2664 if (ret < 0)
2666 gnutls_assert ();
2667 goto cleanup;
2670 ret = gnutls_x509_crt_import (crt, &pcrt->raw, GNUTLS_X509_FMT_DER);
2671 if (ret < 0)
2673 gnutls_assert ();
2674 goto cleanup;
2677 ret = 0;
2678 cleanup:
2680 gnutls_pkcs11_obj_deinit (pcrt);
2682 return ret;
2686 * gnutls_x509_crt_import_pkcs11:
2687 * @crt: A certificate of type #gnutls_x509_crt_t
2688 * @pkcs11_crt: A PKCS 11 object that contains a certificate
2690 * This function will import a PKCS 11 certificate to a #gnutls_x509_crt_t
2691 * structure.
2693 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2694 * negative error value.
2696 * Since: 2.12.0
2699 gnutls_x509_crt_import_pkcs11 (gnutls_x509_crt_t crt,
2700 gnutls_pkcs11_obj_t pkcs11_crt)
2702 return gnutls_x509_crt_import (crt, &pkcs11_crt->raw, GNUTLS_X509_FMT_DER);
2706 * gnutls_x509_crt_list_import_pkcs11:
2707 * @certs: A list of certificates of type #gnutls_x509_crt_t
2708 * @cert_max: The maximum size of the list
2709 * @objs: A list of PKCS 11 objects
2710 * @flags: 0 for now
2712 * This function will import a PKCS 11 certificate list to a list of
2713 * #gnutls_x509_crt_t structure. These must not be initialized.
2715 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2716 * negative error value.
2718 * Since: 2.12.0
2721 gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
2722 unsigned int cert_max,
2723 gnutls_pkcs11_obj_t * const objs,
2724 unsigned int flags)
2726 unsigned int i, j;
2727 int ret;
2729 for (i = 0; i < cert_max; i++)
2731 ret = gnutls_x509_crt_init (&certs[i]);
2732 if (ret < 0)
2734 gnutls_assert ();
2735 goto cleanup;
2738 ret = gnutls_x509_crt_import_pkcs11 (certs[i], objs[i]);
2739 if (ret < 0)
2741 gnutls_assert ();
2742 goto cleanup;
2746 return 0;
2748 cleanup:
2749 for (j = 0; j < i; j++)
2751 gnutls_x509_crt_deinit (certs[j]);
2754 return ret;
2757 static int
2758 find_flags (struct pkcs11_session_info* sinfo,
2759 struct token_info *info, struct ck_info *lib_info, void *input)
2761 struct flags_find_data_st *find_data = input;
2763 if (info == NULL)
2764 { /* we don't support multiple calls */
2765 gnutls_assert ();
2766 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2769 /* do not bother reading the token if basic fields do not match
2771 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2772 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2774 gnutls_assert ();
2775 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2778 /* found token! */
2780 find_data->slot_flags = info->sinfo.flags;
2782 return 0;
2786 * gnutls_pkcs11_token_get_flags:
2787 * @url: should contain a PKCS 11 URL
2788 * @flags: The output flags (GNUTLS_PKCS11_TOKEN_*)
2790 * This function will return information about the PKCS 11 token flags.
2791 * The flags from the %gnutls_pkcs11_token_info_t enumeration.
2793 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
2795 * Since: 2.12.0
2798 gnutls_pkcs11_token_get_flags (const char *url, unsigned int *flags)
2800 struct flags_find_data_st find_data;
2801 int ret;
2803 memset (&find_data, 0, sizeof (find_data));
2804 ret = pkcs11_url_to_info (url, &find_data.info);
2805 if (ret < 0)
2807 gnutls_assert ();
2808 return ret;
2811 ret = _pkcs11_traverse_tokens (find_flags, &find_data, find_data.info, NULL, 0);
2812 p11_kit_uri_free (find_data.info);
2814 if (ret < 0)
2816 gnutls_assert ();
2817 return ret;
2820 *flags = 0;
2821 if (find_data.slot_flags & CKF_HW_SLOT)
2822 *flags |= GNUTLS_PKCS11_TOKEN_HW;
2824 return 0;
2829 * gnutls_pkcs11_token_get_mechanism:
2830 * @url: should contain a PKCS 11 URL
2831 * @idx: The index of the mechanism
2832 * @mechanism: The PKCS #11 mechanism ID
2834 * This function will return the names of the supported mechanisms
2835 * by the token. It should be called with an increasing index until
2836 * it return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.
2838 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
2840 * Since: 2.12.0
2843 gnutls_pkcs11_token_get_mechanism (const char *url, unsigned int idx,
2844 unsigned long *mechanism)
2846 int ret;
2847 ck_rv_t rv;
2848 struct ck_function_list *module;
2849 ck_slot_id_t slot;
2850 struct token_info tinfo;
2851 struct p11_kit_uri *info = NULL;
2852 unsigned long count;
2853 ck_mechanism_type_t mlist[400];
2855 ret = pkcs11_url_to_info (url, &info);
2856 if (ret < 0)
2858 gnutls_assert ();
2859 return ret;
2863 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
2864 p11_kit_uri_free (info);
2866 if (ret < 0)
2868 gnutls_assert ();
2869 return ret;
2872 count = sizeof (mlist) / sizeof (mlist[0]);
2873 rv = pkcs11_get_mechanism_list (module, slot, mlist, &count);
2874 if (rv != CKR_OK)
2876 gnutls_assert ();
2877 return pkcs11_rv_to_err (rv);
2880 if (idx >= count)
2882 gnutls_assert ();
2883 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2886 *mechanism = mlist[idx];
2888 return 0;
2893 * gnutls_pkcs11_type_get_name:
2894 * @type: Holds the PKCS 11 object type, a #gnutls_pkcs11_obj_type_t.
2896 * This function will return a human readable description of the
2897 * PKCS11 object type @obj. It will return "Unknown" for unknown
2898 * types.
2900 * Returns: human readable string labeling the PKCS11 object type
2901 * @type.
2903 * Since: 2.12.0
2905 const char *
2906 gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t type)
2908 switch (type)
2910 case GNUTLS_PKCS11_OBJ_X509_CRT:
2911 return "X.509 Certificate";
2912 case GNUTLS_PKCS11_OBJ_PUBKEY:
2913 return "Public key";
2914 case GNUTLS_PKCS11_OBJ_PRIVKEY:
2915 return "Private key";
2916 case GNUTLS_PKCS11_OBJ_SECRET_KEY:
2917 return "Secret key";
2918 case GNUTLS_PKCS11_OBJ_DATA:
2919 return "Data";
2920 case GNUTLS_PKCS11_OBJ_UNKNOWN:
2921 default:
2922 return "Unknown";
2926 ck_rv_t
2927 pkcs11_get_slot_list (struct ck_function_list * module, unsigned char token_present,
2928 ck_slot_id_t *slot_list, unsigned long *count)
2930 return (module)->C_GetSlotList (token_present, slot_list, count);
2933 ck_rv_t
2934 pkcs11_get_module_info (struct ck_function_list * module,
2935 struct ck_info * info)
2937 return (module)->C_GetInfo (info);
2940 ck_rv_t
2941 pkcs11_get_slot_info(struct ck_function_list * module,
2942 ck_slot_id_t slot_id,
2943 struct ck_slot_info *info)
2945 return (module)->C_GetSlotInfo (slot_id, info);
2948 ck_rv_t
2949 pkcs11_get_token_info (struct ck_function_list * module,
2950 ck_slot_id_t slot_id,
2951 struct ck_token_info *info)
2953 return (module)->C_GetTokenInfo (slot_id, info);
2956 ck_rv_t
2957 pkcs11_find_objects_init (struct ck_function_list *module,
2958 ck_session_handle_t sess,
2959 struct ck_attribute *templ,
2960 unsigned long count)
2962 return (module)->C_FindObjectsInit (sess, templ, count);
2965 ck_rv_t
2966 pkcs11_find_objects (struct ck_function_list *module,
2967 ck_session_handle_t sess,
2968 ck_object_handle_t *objects,
2969 unsigned long max_object_count,
2970 unsigned long *object_count)
2972 return (module)->C_FindObjects (sess, objects, max_object_count, object_count);
2975 ck_rv_t
2976 pkcs11_find_objects_final (struct pkcs11_session_info* sinfo)
2978 return (sinfo->module)->C_FindObjectsFinal (sinfo->pks);
2981 ck_rv_t
2982 pkcs11_close_session (struct pkcs11_session_info * sinfo)
2984 sinfo->init = 0;
2985 return (sinfo->module)->C_CloseSession (sinfo->pks);
2988 ck_rv_t
2989 pkcs11_get_attribute_value(struct ck_function_list *module,
2990 ck_session_handle_t sess,
2991 ck_object_handle_t object,
2992 struct ck_attribute *templ,
2993 unsigned long count)
2995 return (module)->C_GetAttributeValue (sess, object, templ, count);
2998 ck_rv_t
2999 pkcs11_get_mechanism_list (struct ck_function_list *module,
3000 ck_slot_id_t slot_id,
3001 ck_mechanism_type_t *mechanism_list,
3002 unsigned long *count)
3004 return (module)->C_GetMechanismList (slot_id, mechanism_list, count);
3007 ck_rv_t
3008 pkcs11_sign_init (struct ck_function_list *module,
3009 ck_session_handle_t sess,
3010 struct ck_mechanism *mechanism,
3011 ck_object_handle_t key)
3013 return (module)->C_SignInit (sess, mechanism, key);
3016 ck_rv_t
3017 pkcs11_sign (struct ck_function_list *module,
3018 ck_session_handle_t sess,
3019 unsigned char *data,
3020 unsigned long data_len,
3021 unsigned char *signature,
3022 unsigned long *signature_len)
3024 return (module)->C_Sign (sess, data, data_len, signature, signature_len);
3027 ck_rv_t
3028 pkcs11_generate_key_pair (struct ck_function_list *module,
3029 ck_session_handle_t sess,
3030 struct ck_mechanism *mechanism,
3031 struct ck_attribute *pub_templ,
3032 unsigned long pub_templ_count,
3033 struct ck_attribute *priv_templ,
3034 unsigned long priv_templ_count,
3035 ck_object_handle_t *pub,
3036 ck_object_handle_t *priv)
3038 return (module)->C_GenerateKeyPair (sess, mechanism, pub_templ, pub_templ_count,
3039 priv_templ, priv_templ_count, pub, priv);
3042 ck_rv_t
3043 pkcs11_decrypt_init (struct ck_function_list *module,
3044 ck_session_handle_t sess,
3045 struct ck_mechanism *mechanism,
3046 ck_object_handle_t key)
3048 return (module)->C_DecryptInit (sess, mechanism, key);
3051 ck_rv_t
3052 pkcs11_decrypt (struct ck_function_list *module,
3053 ck_session_handle_t sess,
3054 unsigned char *encrypted_data,
3055 unsigned long encrypted_data_len,
3056 unsigned char *data, unsigned long *data_len)
3058 return (module)->C_Decrypt (sess, encrypted_data, encrypted_data_len,
3059 data, data_len);
3062 ck_rv_t
3063 pkcs11_create_object (struct ck_function_list *module,
3064 ck_session_handle_t sess,
3065 struct ck_attribute *templ,
3066 unsigned long count,
3067 ck_object_handle_t *object)
3069 return (module)->C_CreateObject (sess, templ, count, object);
3072 ck_rv_t
3073 pkcs11_destroy_object (struct ck_function_list *module,
3074 ck_session_handle_t sess,
3075 ck_object_handle_t object)
3077 return (module)->C_DestroyObject (sess, object);
3080 ck_rv_t
3081 pkcs11_init_token (struct ck_function_list *module,
3082 ck_slot_id_t slot_id, unsigned char *pin,
3083 unsigned long pin_len, unsigned char *label)
3085 return (module)->C_InitToken (slot_id, pin, pin_len, label);
3088 ck_rv_t
3089 pkcs11_init_pin (struct ck_function_list *module,
3090 ck_session_handle_t sess,
3091 unsigned char *pin,
3092 unsigned long pin_len)
3094 return (module)->C_InitPIN (sess, pin, pin_len);
3097 ck_rv_t
3098 pkcs11_set_pin (struct ck_function_list *module,
3099 ck_session_handle_t sess,
3100 const char *old_pin,
3101 unsigned long old_len,
3102 const char *new_pin,
3103 unsigned long new_len)
3105 return (module)->C_SetPIN (sess, (uint8_t*)old_pin, old_len, (uint8_t*)new_pin, new_len);
3108 const char *
3109 pkcs11_strerror (ck_rv_t rv)
3111 return p11_kit_strerror (rv);