added new functions
[gnutls.git] / lib / pkcs11.c
blob0357c7ad5df3afd63526101ff4e3f2d204975fd8
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_object (struct pkcs11_session_info* sinfo,
869 struct pin_info_st * pin_info,
870 ck_object_handle_t * _obj,
871 struct p11_kit_uri *info, unsigned int flags)
873 int ret;
874 ck_object_handle_t obj;
875 struct ck_attribute *attrs;
876 unsigned long attr_count;
877 unsigned long count;
878 ck_rv_t rv;
880 ret = pkcs11_open_session (sinfo, pin_info, info, flags & SESSION_LOGIN);
881 if (ret < 0)
883 gnutls_assert ();
884 return ret;
887 attrs = p11_kit_uri_get_attributes (info, &attr_count);
888 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, attrs, attr_count);
889 if (rv != CKR_OK)
891 gnutls_assert ();
892 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
893 ret = pkcs11_rv_to_err (rv);
894 goto fail;
897 if (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
899 *_obj = obj;
900 pkcs11_find_objects_final (sinfo);
901 return 0;
904 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
905 pkcs11_find_objects_final (sinfo);
906 fail:
907 pkcs11_close_session (sinfo);
909 return ret;
913 pkcs11_find_slot (struct ck_function_list ** module, ck_slot_id_t * slot,
914 struct p11_kit_uri *info, struct token_info *_tinfo)
916 unsigned int x, z;
918 for (x = 0; x < active_providers; x++)
920 for (z = 0; z < providers[x].nslots; z++)
922 struct token_info tinfo;
924 if (pkcs11_get_token_info
925 (providers[x].module, providers[x].slots[z],
926 &tinfo.tinfo) != CKR_OK)
928 continue;
930 tinfo.sid = providers[x].slots[z];
931 tinfo.prov = &providers[x];
933 if (pkcs11_get_slot_info
934 (providers[x].module, providers[x].slots[z],
935 &tinfo.sinfo) != CKR_OK)
937 continue;
940 if (!p11_kit_uri_match_token_info (info, &tinfo.tinfo) ||
941 !p11_kit_uri_match_module_info (info, &providers[x].info))
943 continue;
946 /* ok found */
947 *module = providers[x].module;
948 *slot = providers[x].slots[z];
950 if (_tinfo != NULL)
951 memcpy (_tinfo, &tinfo, sizeof (tinfo));
953 return 0;
957 gnutls_assert ();
958 return GNUTLS_E_PKCS11_REQUESTED_OBJECT_NOT_AVAILBLE;
962 pkcs11_open_session (struct pkcs11_session_info *sinfo,
963 struct pin_info_st *pin_info,
964 struct p11_kit_uri *info,
965 unsigned int flags)
967 ck_rv_t rv;
968 int ret;
969 ck_session_handle_t pks = 0;
970 struct ck_function_list *module;
971 ck_slot_id_t slot;
972 struct token_info tinfo;
974 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
975 if (ret < 0)
977 gnutls_assert ();
978 return ret;
981 rv = (module)->C_OpenSession (slot,
982 ((flags & SESSION_WRITE)
983 ? CKF_RW_SESSION : 0) |
984 CKF_SERIAL_SESSION, NULL, NULL, &pks);
985 if (rv != CKR_OK)
987 gnutls_assert ();
988 return pkcs11_rv_to_err (rv);
991 /* ok found */
992 sinfo->pks = pks;
993 sinfo->module = module;
994 sinfo->init = 1;
995 memcpy(&sinfo->tinfo, &tinfo.tinfo, sizeof(sinfo->tinfo));
997 if (flags & SESSION_LOGIN)
999 ret = pkcs11_login (sinfo, pin_info, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
1000 if (ret < 0)
1002 gnutls_assert ();
1003 pkcs11_close_session (sinfo);
1004 return ret;
1008 return 0;
1013 _pkcs11_traverse_tokens (find_func_t find_func, void *input,
1014 struct p11_kit_uri *info,
1015 struct pin_info_st *pin_info,
1016 unsigned int flags)
1018 ck_rv_t rv;
1019 unsigned int found = 0, x, z;
1020 int ret;
1021 ck_session_handle_t pks = 0;
1022 struct pkcs11_session_info sinfo;
1023 struct ck_function_list *module = NULL;
1025 for (x = 0; x < active_providers; x++)
1027 module = providers[x].module;
1028 for (z = 0; z < providers[x].nslots; z++)
1030 struct token_info tinfo;
1032 if (pkcs11_get_token_info (module, providers[x].slots[z],
1033 &tinfo.tinfo) != CKR_OK)
1035 continue;
1037 tinfo.sid = providers[x].slots[z];
1038 tinfo.prov = &providers[x];
1040 if (pkcs11_get_slot_info (module, providers[x].slots[z],
1041 &tinfo.sinfo) != CKR_OK)
1043 continue;
1046 rv = (module)->C_OpenSession (providers[x].slots[z],
1047 ((flags & SESSION_WRITE)
1048 ? CKF_RW_SESSION : 0) |
1049 CKF_SERIAL_SESSION, NULL, NULL, &pks);
1050 if (rv != CKR_OK)
1052 continue;
1055 sinfo.module = module;
1056 sinfo.pks = pks;
1058 if (flags & SESSION_LOGIN)
1060 ret = pkcs11_login (&sinfo, pin_info, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
1061 if (ret < 0)
1063 gnutls_assert ();
1064 return ret;
1068 ret = find_func (&sinfo, &tinfo, &providers[x].info, input);
1070 if (ret == 0)
1072 found = 1;
1073 goto finish;
1075 else
1077 pkcs11_close_session (&sinfo);
1078 pks = 0;
1083 finish:
1084 /* final call */
1086 if (found == 0)
1088 if (module)
1090 sinfo.module = module;
1091 sinfo.pks = pks;
1092 ret = find_func (&sinfo, NULL, NULL, input);
1094 else
1095 ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1097 else
1099 ret = 0;
1102 if (pks != 0 && module != NULL)
1104 pkcs11_close_session (&sinfo);
1107 return ret;
1110 /* imports a raw certificate from a token to a pkcs11_obj_t structure.
1112 static int
1113 pkcs11_obj_import (ck_object_class_t class, gnutls_pkcs11_obj_t obj,
1114 const gnutls_datum_t * data,
1115 const gnutls_datum_t * id,
1116 const gnutls_datum_t * label,
1117 struct ck_token_info *tinfo, struct ck_info *lib_info)
1119 struct ck_attribute attr;
1120 int ret;
1122 switch (class)
1124 case CKO_CERTIFICATE:
1125 obj->type = GNUTLS_PKCS11_OBJ_X509_CRT;
1126 break;
1127 case CKO_PUBLIC_KEY:
1128 obj->type = GNUTLS_PKCS11_OBJ_PUBKEY;
1129 break;
1130 case CKO_PRIVATE_KEY:
1131 obj->type = GNUTLS_PKCS11_OBJ_PRIVKEY;
1132 break;
1133 case CKO_SECRET_KEY:
1134 obj->type = GNUTLS_PKCS11_OBJ_SECRET_KEY;
1135 break;
1136 case CKO_DATA:
1137 obj->type = GNUTLS_PKCS11_OBJ_DATA;
1138 break;
1139 default:
1140 obj->type = GNUTLS_PKCS11_OBJ_UNKNOWN;
1143 attr.type = CKA_CLASS;
1144 attr.value = &class;
1145 attr.value_len = sizeof (class);
1146 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1147 if (ret < 0)
1149 gnutls_assert ();
1150 return GNUTLS_E_MEMORY_ERROR;
1153 if (data && data->data)
1155 ret = _gnutls_set_datum (&obj->raw, data->data, data->size);
1156 if (ret < 0)
1158 gnutls_assert ();
1159 return ret;
1163 /* copy the token and library info into the uri */
1164 memcpy (p11_kit_uri_get_token_info (obj->info), tinfo, sizeof (struct ck_token_info));
1165 memcpy (p11_kit_uri_get_module_info (obj->info), lib_info, sizeof (struct ck_info));
1167 if (label && label->data)
1169 attr.type = CKA_LABEL;
1170 attr.value = label->data;
1171 attr.value_len = label->size;
1172 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1173 if (ret < 0)
1175 gnutls_assert ();
1176 return GNUTLS_E_MEMORY_ERROR;
1180 if (id && id->data)
1182 attr.type = CKA_ID;
1183 attr.value = id->data;
1184 attr.value_len = id->size;
1185 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1186 if (ret < 0)
1188 gnutls_assert ();
1189 return GNUTLS_E_MEMORY_ERROR;
1193 return 0;
1196 static int read_pkcs11_pubkey(struct ck_function_list *module,
1197 ck_session_handle_t pks, ck_object_handle_t obj,
1198 ck_key_type_t key_type, gnutls_datum_t * pubkey)
1200 struct ck_attribute a[4];
1201 uint8_t tmp1[2048];
1202 uint8_t tmp2[2048];
1203 int ret;
1205 switch (key_type)
1207 case CKK_RSA:
1208 a[0].type = CKA_MODULUS;
1209 a[0].value = tmp1;
1210 a[0].value_len = sizeof (tmp1);
1211 a[1].type = CKA_PUBLIC_EXPONENT;
1212 a[1].value = tmp2;
1213 a[1].value_len = sizeof (tmp2);
1215 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1218 ret =
1219 _gnutls_set_datum (&pubkey[0],
1220 a[0].value, a[0].value_len);
1222 if (ret >= 0)
1223 ret =
1224 _gnutls_set_datum (&pubkey
1225 [1], a[1].value, a[1].value_len);
1227 if (ret < 0)
1229 gnutls_assert ();
1230 _gnutls_free_datum (&pubkey[1]);
1231 _gnutls_free_datum (&pubkey[0]);
1232 return GNUTLS_E_MEMORY_ERROR;
1235 else
1237 gnutls_assert ();
1238 return GNUTLS_E_PKCS11_ERROR;
1240 break;
1241 case CKK_DSA:
1242 a[0].type = CKA_PRIME;
1243 a[0].value = tmp1;
1244 a[0].value_len = sizeof (tmp1);
1245 a[1].type = CKA_SUBPRIME;
1246 a[1].value = tmp2;
1247 a[1].value_len = sizeof (tmp2);
1249 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1251 ret =
1252 _gnutls_set_datum (&pubkey[0],
1253 a[0].value, a[0].value_len);
1255 if (ret >= 0)
1256 ret =
1257 _gnutls_set_datum (&pubkey
1258 [1], a[1].value, a[1].value_len);
1260 if (ret < 0)
1262 gnutls_assert ();
1263 _gnutls_free_datum (&pubkey[1]);
1264 _gnutls_free_datum (&pubkey[0]);
1265 return GNUTLS_E_MEMORY_ERROR;
1268 else
1270 gnutls_assert ();
1271 return GNUTLS_E_PKCS11_ERROR;
1274 a[0].type = CKA_BASE;
1275 a[0].value = tmp1;
1276 a[0].value_len = sizeof (tmp1);
1277 a[1].type = CKA_VALUE;
1278 a[1].value = tmp2;
1279 a[1].value_len = sizeof (tmp2);
1281 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1283 ret =
1284 _gnutls_set_datum (&pubkey[2],
1285 a[0].value, a[0].value_len);
1287 if (ret >= 0)
1288 ret =
1289 _gnutls_set_datum (&pubkey
1290 [3], a[1].value, a[1].value_len);
1292 if (ret < 0)
1294 gnutls_assert ();
1295 _gnutls_free_datum (&pubkey[0]);
1296 _gnutls_free_datum (&pubkey[1]);
1297 _gnutls_free_datum (&pubkey[2]);
1298 _gnutls_free_datum (&pubkey[3]);
1299 return GNUTLS_E_MEMORY_ERROR;
1302 else
1304 gnutls_assert ();
1305 return GNUTLS_E_PKCS11_ERROR;
1307 break;
1308 case CKK_ECDSA:
1309 a[0].type = CKA_EC_PARAMS;
1310 a[0].value = tmp1;
1311 a[0].value_len = sizeof (tmp1);
1312 a[1].type = CKA_EC_POINT;
1313 a[1].value = tmp2;
1314 a[1].value_len = sizeof (tmp2);
1316 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1318 ret =
1319 _gnutls_set_datum (&pubkey[0],
1320 a[0].value, a[0].value_len);
1322 if (ret >= 0)
1323 ret =
1324 _gnutls_set_datum (&pubkey
1325 [1], a[1].value, a[1].value_len);
1327 if (ret < 0)
1329 gnutls_assert ();
1330 _gnutls_free_datum (&pubkey[1]);
1331 _gnutls_free_datum (&pubkey[0]);
1332 return GNUTLS_E_MEMORY_ERROR;
1335 else
1337 gnutls_assert ();
1338 return GNUTLS_E_PKCS11_ERROR;
1341 break;
1342 default:
1343 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1346 return 0;
1349 static int
1350 pkcs11_obj_import_pubkey (struct ck_function_list *module,
1351 ck_session_handle_t pks,
1352 ck_object_handle_t obj,
1353 gnutls_pkcs11_obj_t crt,
1354 const gnutls_datum_t * id,
1355 const gnutls_datum_t * label,
1356 struct ck_token_info *tinfo,
1357 struct ck_info *lib_info)
1359 struct ck_attribute a[4];
1360 ck_key_type_t key_type;
1361 int ret;
1362 ck_bool_t tval;
1364 a[0].type = CKA_KEY_TYPE;
1365 a[0].value = &key_type;
1366 a[0].value_len = sizeof (key_type);
1368 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1370 crt->pk_algorithm = mech_to_pk(key_type);
1372 ret = read_pkcs11_pubkey(module, pks, obj, key_type, crt->pubkey);
1373 if (ret < 0)
1374 return gnutls_assert_val(ret);
1377 /* read key usage flags */
1378 a[0].type = CKA_ENCRYPT;
1379 a[0].value = &tval;
1380 a[0].value_len = sizeof (tval);
1382 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1384 if (tval != 0)
1386 crt->key_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
1390 a[0].type = CKA_VERIFY;
1391 a[0].value = &tval;
1392 a[0].value_len = sizeof (tval);
1394 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1396 if (tval != 0)
1398 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1399 GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1400 | GNUTLS_KEY_NON_REPUDIATION;
1404 a[0].type = CKA_VERIFY_RECOVER;
1405 a[0].value = &tval;
1406 a[0].value_len = sizeof (tval);
1408 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1410 if (tval != 0)
1412 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1413 GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1414 | GNUTLS_KEY_NON_REPUDIATION;
1418 a[0].type = CKA_DERIVE;
1419 a[0].value = &tval;
1420 a[0].value_len = sizeof (tval);
1422 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1424 if (tval != 0)
1426 crt->key_usage |= GNUTLS_KEY_KEY_AGREEMENT;
1430 a[0].type = CKA_WRAP;
1431 a[0].value = &tval;
1432 a[0].value_len = sizeof (tval);
1434 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1436 if (tval != 0)
1438 crt->key_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
1442 return pkcs11_obj_import (CKO_PUBLIC_KEY, crt, NULL, id, label,
1443 tinfo, lib_info);
1446 static int
1447 find_obj_url (struct pkcs11_session_info *sinfo,
1448 struct token_info *info, struct ck_info *lib_info, void *input)
1450 struct url_find_data_st *find_data = input;
1451 struct ck_attribute a[4];
1452 struct ck_attribute *attr;
1453 ck_object_class_t class = -1;
1454 ck_certificate_type_t type = (ck_certificate_type_t)-1;
1455 ck_rv_t rv;
1456 ck_object_handle_t obj;
1457 unsigned long count, a_vals;
1458 int found = 0, ret;
1459 uint8_t *cert_data = NULL;
1460 char label_tmp[PKCS11_LABEL_SIZE];
1461 char id_tmp[PKCS11_ID_SIZE];
1463 if (info == NULL)
1464 { /* we don't support multiple calls */
1465 gnutls_assert ();
1466 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1469 /* do not bother reading the token if basic fields do not match
1471 if (!p11_kit_uri_match_token_info (find_data->crt->info, &info->tinfo) ||
1472 !p11_kit_uri_match_module_info (find_data->crt->info, lib_info))
1474 gnutls_assert ();
1475 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1478 a_vals = 0;
1479 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID);
1480 if (attr)
1482 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1483 a_vals++;
1486 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_LABEL);
1487 if (attr)
1489 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1490 a_vals++;
1493 if (!a_vals)
1495 gnutls_assert ();
1496 return GNUTLS_E_INVALID_REQUEST;
1499 /* search the token for the id */
1501 cert_data = gnutls_malloc (MAX_CERT_SIZE);
1502 if (cert_data == NULL)
1504 gnutls_assert ();
1505 return GNUTLS_E_MEMORY_ERROR;
1508 /* Find objects with given class and type */
1509 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_CLASS);
1510 if (attr)
1512 if(attr->value && attr->value_len == sizeof (ck_object_class_t))
1513 class = *((ck_object_class_t*)attr->value);
1514 if (class == CKO_CERTIFICATE)
1515 type = CKC_X_509;
1516 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1517 a_vals++;
1520 if (type != (ck_certificate_type_t)-1)
1522 a[a_vals].type = CKA_CERTIFICATE_TYPE;
1523 a[a_vals].value = &type;
1524 a[a_vals].value_len = sizeof type;
1525 a_vals++;
1528 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, a, a_vals);
1529 if (rv != CKR_OK)
1531 gnutls_assert ();
1532 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
1533 ret = pkcs11_rv_to_err (rv);
1534 goto cleanup;
1537 while (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
1540 a[0].type = CKA_VALUE;
1541 a[0].value = cert_data;
1542 a[0].value_len = MAX_CERT_SIZE;
1543 a[1].type = CKA_LABEL;
1544 a[1].value = label_tmp;
1545 a[1].value_len = sizeof (label_tmp);
1546 a[2].type = CKA_ID;
1547 a[2].value = id_tmp;
1548 a[2].value_len = sizeof(id_tmp);
1550 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 3) == CKR_OK)
1552 gnutls_datum_t id = { a[2].value, a[2].value_len };
1553 gnutls_datum_t data = { a[0].value, a[0].value_len };
1554 gnutls_datum_t label = { a[1].value, a[1].value_len };
1556 if (class == CKO_PUBLIC_KEY)
1558 ret =
1559 pkcs11_obj_import_pubkey (sinfo->module, sinfo->pks, obj,
1560 find_data->crt,
1561 &id, &label,
1562 &info->tinfo, lib_info);
1564 else
1566 ret =
1567 pkcs11_obj_import (class,
1568 find_data->crt,
1569 &data, &id, &label,
1570 &info->tinfo, lib_info);
1572 if (ret < 0)
1574 gnutls_assert ();
1575 goto cleanup;
1578 found = 1;
1579 break;
1581 else
1583 _gnutls_debug_log ("pk11: Skipped cert, missing attrs.\n");
1587 if (found == 0)
1589 gnutls_assert ();
1590 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1592 else
1594 ret = 0;
1597 cleanup:
1598 gnutls_free (cert_data);
1599 pkcs11_find_objects_final (sinfo);
1601 return ret;
1604 unsigned int
1605 pkcs11_obj_flags_to_int (unsigned int flags)
1607 unsigned int ret_flags = 0;
1609 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN)
1610 ret_flags |= SESSION_LOGIN;
1611 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO)
1612 ret_flags |= SESSION_LOGIN|SESSION_SO;
1614 return ret_flags;
1618 * gnutls_pkcs11_obj_import_url:
1619 * @obj: The structure to store the object
1620 * @url: a PKCS 11 url identifying the key
1621 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1623 * This function will "import" a PKCS 11 URL identifying an object (e.g. certificate)
1624 * to the #gnutls_pkcs11_obj_t structure. This does not involve any
1625 * parsing (such as X.509 or OpenPGP) since the #gnutls_pkcs11_obj_t is
1626 * format agnostic. Only data are transferred.
1628 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1629 * negative error value.
1631 * Since: 2.12.0
1634 gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t obj, const char *url,
1635 unsigned int flags)
1637 int ret;
1638 struct url_find_data_st find_data;
1640 /* fill in the find data structure */
1641 find_data.crt = obj;
1643 ret = pkcs11_url_to_info (url, &obj->info);
1644 if (ret < 0)
1646 gnutls_assert ();
1647 return ret;
1650 ret =
1651 _pkcs11_traverse_tokens (find_obj_url, &find_data, obj->info,
1652 &obj->pin, pkcs11_obj_flags_to_int (flags));
1654 if (ret < 0)
1656 gnutls_assert ();
1657 return ret;
1660 return 0;
1663 struct token_num
1665 struct p11_kit_uri *info;
1666 unsigned int seq; /* which one we are looking for */
1667 unsigned int current; /* which one are we now */
1670 static int
1671 find_token_num (struct pkcs11_session_info* sinfo,
1672 struct token_info *tinfo,
1673 struct ck_info *lib_info, void *input)
1675 struct token_num *find_data = input;
1677 if (tinfo == NULL)
1678 { /* we don't support multiple calls */
1679 gnutls_assert ();
1680 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1683 if (find_data->current == find_data->seq)
1685 memcpy (p11_kit_uri_get_token_info (find_data->info), &tinfo->tinfo, sizeof (struct ck_token_info));
1686 memcpy (p11_kit_uri_get_module_info (find_data->info), lib_info, sizeof (struct ck_info));
1687 return 0;
1690 find_data->current++;
1691 /* search the token for the id */
1694 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* non zero is enough */
1698 * gnutls_pkcs11_token_get_url:
1699 * @seq: sequence number starting from 0
1700 * @detailed: non zero if a detailed URL is required
1701 * @url: will contain an allocated url
1703 * This function will return the URL for each token available
1704 * in system. The url has to be released using gnutls_free()
1706 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1707 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if the sequence number
1708 * exceeds the available tokens, otherwise a negative error value.
1710 * Since: 2.12.0
1713 gnutls_pkcs11_token_get_url (unsigned int seq,
1714 gnutls_pkcs11_url_type_t detailed, char **url)
1716 int ret;
1717 struct token_num tn;
1719 memset (&tn, 0, sizeof (tn));
1720 tn.seq = seq;
1721 tn.info = p11_kit_uri_new ();
1723 ret = _pkcs11_traverse_tokens (find_token_num, &tn, NULL, NULL, 0);
1724 if (ret < 0)
1726 p11_kit_uri_free (tn.info);
1727 gnutls_assert ();
1728 return ret;
1731 ret = pkcs11_info_to_url (tn.info, detailed, url);
1732 p11_kit_uri_free (tn.info);
1734 if (ret < 0)
1736 gnutls_assert ();
1737 return ret;
1740 return 0;
1745 * gnutls_pkcs11_token_get_info:
1746 * @url: should contain a PKCS 11 URL
1747 * @ttype: Denotes the type of information requested
1748 * @output: where output will be stored
1749 * @output_size: contains the maximum size of the output and will be overwritten with actual
1751 * This function will return information about the PKCS 11 token such
1752 * as the label, id, etc.
1754 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code
1755 * on error.
1757 * Since: 2.12.0
1760 gnutls_pkcs11_token_get_info (const char *url,
1761 gnutls_pkcs11_token_info_t ttype,
1762 void *output, size_t * output_size)
1764 struct p11_kit_uri *info = NULL;
1765 const uint8_t *str;
1766 size_t str_max;
1767 size_t len;
1768 int ret;
1770 ret = pkcs11_url_to_info (url, &info);
1771 if (ret < 0)
1773 gnutls_assert ();
1774 return ret;
1777 switch (ttype)
1779 case GNUTLS_PKCS11_TOKEN_LABEL:
1780 str = p11_kit_uri_get_token_info (info)->label;
1781 str_max = 32;
1782 break;
1783 case GNUTLS_PKCS11_TOKEN_SERIAL:
1784 str = p11_kit_uri_get_token_info (info)->serial_number;
1785 str_max = 16;
1786 break;
1787 case GNUTLS_PKCS11_TOKEN_MANUFACTURER:
1788 str = p11_kit_uri_get_token_info (info)->manufacturer_id;
1789 str_max = 32;
1790 break;
1791 case GNUTLS_PKCS11_TOKEN_MODEL:
1792 str = p11_kit_uri_get_token_info (info)->model;
1793 str_max = 16;
1794 break;
1795 default:
1796 p11_kit_uri_free (info);
1797 gnutls_assert ();
1798 return GNUTLS_E_INVALID_REQUEST;
1801 len = p11_kit_space_strlen (str, str_max);
1803 if (len + 1 > *output_size)
1805 *output_size = len + 1;
1806 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1809 memcpy (output, str, len);
1810 ((char*)output)[len] = '\0';
1812 *output_size = len;
1814 p11_kit_uri_free (info);
1815 return 0;
1819 * gnutls_pkcs11_obj_export_url:
1820 * @obj: Holds the PKCS 11 certificate
1821 * @detailed: non zero if a detailed URL is required
1822 * @url: will contain an allocated url
1824 * This function will export a URL identifying the given certificate.
1826 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1827 * negative error value.
1829 * Since: 2.12.0
1832 gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t obj,
1833 gnutls_pkcs11_url_type_t detailed, char **url)
1835 int ret;
1837 ret = pkcs11_info_to_url (obj->info, detailed, url);
1838 if (ret < 0)
1840 gnutls_assert ();
1841 return ret;
1844 return 0;
1848 * gnutls_pkcs11_obj_get_type:
1849 * @obj: Holds the PKCS 11 object
1851 * This function will return the type of the certificate being
1852 * stored in the structure.
1854 * Returns: The type of the certificate.
1856 * Since: 2.12.0
1858 gnutls_pkcs11_obj_type_t
1859 gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t obj)
1861 return obj->type;
1864 struct pkey_list
1866 gnutls_buffer_st *key_ids;
1867 size_t key_ids_size;
1871 static int
1872 retrieve_pin_from_source (const char *pinfile, struct ck_token_info *token_info,
1873 int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
1875 unsigned int flags = 0;
1876 struct p11_kit_uri *token_uri;
1877 struct p11_kit_pin *result;
1878 char *label;
1880 label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1881 if (label == NULL)
1883 gnutls_assert ();
1884 return GNUTLS_E_MEMORY_ERROR;
1887 token_uri = p11_kit_uri_new ();
1888 if (token_uri == NULL)
1890 free (label);
1891 gnutls_assert ();
1892 return GNUTLS_E_MEMORY_ERROR;
1895 memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1896 sizeof (struct ck_token_info));
1898 if (attempts)
1899 flags |= P11_KIT_PIN_FLAGS_RETRY;
1900 if (user_type == CKU_USER)
1902 flags |= P11_KIT_PIN_FLAGS_USER_LOGIN;
1903 if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1904 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1905 if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1906 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1908 else if (user_type == CKU_SO)
1910 flags |= P11_KIT_PIN_FLAGS_SO_LOGIN;
1911 if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
1912 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1913 if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
1914 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1916 else if (user_type == CKU_CONTEXT_SPECIFIC)
1918 flags |= P11_KIT_PIN_FLAGS_CONTEXT_LOGIN;
1921 result = p11_kit_pin_request (pinfile, token_uri, label, flags);
1922 p11_kit_uri_free (token_uri);
1923 free (label);
1925 if (result == NULL)
1927 gnutls_assert ();
1928 return GNUTLS_E_PKCS11_PIN_ERROR;
1931 *pin = result;
1932 return 0;
1935 static int
1936 retrieve_pin_from_callback (const struct pin_info_st *pin_info,
1937 struct ck_token_info *token_info,
1938 int attempts, ck_user_type_t user_type,
1939 struct p11_kit_pin **pin)
1941 char pin_value[GNUTLS_PKCS11_MAX_PIN_LEN];
1942 unsigned int flags = 0;
1943 char *token_str;
1944 char *label;
1945 struct p11_kit_uri *token_uri;
1946 int ret = 0;
1948 label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1949 if (label == NULL)
1951 gnutls_assert ();
1952 return GNUTLS_E_MEMORY_ERROR;
1955 token_uri = p11_kit_uri_new ();
1956 if (token_uri == NULL)
1958 free (label);
1959 gnutls_assert ();
1960 return GNUTLS_E_MEMORY_ERROR;
1963 memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1964 sizeof (struct ck_token_info));
1965 ret = pkcs11_info_to_url (token_uri, 1, &token_str);
1966 p11_kit_uri_free (token_uri);
1968 if (ret < 0)
1970 free (label);
1971 gnutls_assert ();
1972 return GNUTLS_E_MEMORY_ERROR;
1975 if (user_type == CKU_USER)
1977 flags |= GNUTLS_PIN_USER;
1978 if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1979 flags |= GNUTLS_PIN_COUNT_LOW;
1980 if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1981 flags |= GNUTLS_PIN_FINAL_TRY;
1983 else if (user_type == CKU_SO)
1985 flags |= GNUTLS_PIN_SO;
1986 if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
1987 flags |= GNUTLS_PIN_COUNT_LOW;
1988 if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
1989 flags |= GNUTLS_PIN_FINAL_TRY;
1992 if (attempts > 0)
1993 flags |= GNUTLS_PIN_WRONG;
1995 if (pin_info && pin_info->cb)
1996 ret = pin_info->cb (pin_info->data, attempts, (char*)token_str, label,
1997 flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
1998 else if (_gnutls_pin_func)
1999 ret = _gnutls_pin_func (_gnutls_pin_data, attempts, (char*)token_str, label,
2000 flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
2001 else
2002 ret = gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR);
2004 free (token_str);
2005 free (label);
2007 if (ret < 0)
2008 return gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR);
2010 *pin = p11_kit_pin_new_for_string (pin_value);
2012 if (*pin == NULL)
2013 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2015 return 0;
2018 static int
2019 retrieve_pin (struct pin_info_st* pin_info, struct p11_kit_uri *info,
2020 struct ck_token_info *token_info, int attempts,
2021 ck_user_type_t user_type, struct p11_kit_pin **pin)
2023 const char *pinfile;
2024 int ret = GNUTLS_E_PKCS11_PIN_ERROR;
2026 *pin = NULL;
2028 /* Check if a pinfile is specified, and use that if possible */
2029 pinfile = p11_kit_uri_get_pinfile (info);
2030 if (pinfile != NULL)
2032 _gnutls_debug_log("pk11: Using pinfile to retrieve PIN\n");
2033 ret = retrieve_pin_from_source (pinfile, token_info, attempts, user_type, pin);
2036 /* The global gnutls pin callback */
2037 if (ret < 0)
2038 ret = retrieve_pin_from_callback (pin_info, token_info, attempts, user_type, pin);
2040 /* Otherwise, PIN entry is necessary for login, so fail if there's
2041 * no callback. */
2043 if (ret < 0)
2045 gnutls_assert ();
2046 _gnutls_debug_log ("pk11: No suitable pin callback but login required.\n");
2049 return ret;
2053 pkcs11_login (struct pkcs11_session_info * sinfo, struct pin_info_st * pin_info,
2054 const struct token_info *tokinfo, struct p11_kit_uri *info, int so)
2056 struct ck_session_info session_info;
2057 int attempt = 0, ret;
2058 ck_user_type_t user_type;
2059 ck_rv_t rv;
2061 user_type = (so == 0) ? CKU_USER : CKU_SO;
2062 if (so == 0 && (tokinfo->tinfo.flags & CKF_LOGIN_REQUIRED) == 0)
2064 gnutls_assert ();
2065 _gnutls_debug_log ("pk11: No login required.\n");
2066 return 0;
2069 /* For a token with a "protected" (out-of-band) authentication
2070 * path, calling login with a NULL username is all that is
2071 * required. */
2072 if (tokinfo->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
2074 rv = (sinfo->module)->C_Login (sinfo->pks, (so == 0) ? CKU_USER : CKU_SO, NULL, 0);
2075 if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
2077 return 0;
2079 else
2081 gnutls_assert ();
2082 _gnutls_debug_log ("pk11: Protected login failed.\n");
2083 ret = GNUTLS_E_PKCS11_ERROR;
2084 goto cleanup;
2090 struct p11_kit_pin *pin;
2091 struct ck_token_info tinfo;
2093 memcpy (&tinfo, &tokinfo->tinfo, sizeof(tinfo));
2095 /* Check whether the session is already logged in, and if so, just skip */
2096 rv = (sinfo->module)->C_GetSessionInfo (sinfo->pks, &session_info);
2097 if (rv == CKR_OK && (session_info.state == CKS_RO_USER_FUNCTIONS ||
2098 session_info.state == CKS_RW_USER_FUNCTIONS))
2100 ret = 0;
2101 goto cleanup;
2104 /* If login has been attempted once already, check the token
2105 * status again, the flags might change. */
2106 if (attempt)
2108 if (pkcs11_get_token_info
2109 (tokinfo->prov->module, tokinfo->sid, &tinfo) != CKR_OK)
2111 gnutls_assert ();
2112 _gnutls_debug_log ("pk11: GetTokenInfo failed\n");
2113 ret = GNUTLS_E_PKCS11_ERROR;
2114 goto cleanup;
2118 ret = retrieve_pin (pin_info, info, &tinfo, attempt++, user_type, &pin);
2119 if (ret < 0)
2121 gnutls_assert ();
2122 goto cleanup;
2125 rv = (sinfo->module)->C_Login (sinfo->pks, user_type,
2126 (unsigned char *)p11_kit_pin_get_value (pin, NULL),
2127 p11_kit_pin_get_length (pin));
2129 p11_kit_pin_unref (pin);
2131 while (rv == CKR_PIN_INCORRECT);
2133 _gnutls_debug_log ("pk11: Login result = %lu\n", rv);
2136 ret = (rv == CKR_OK
2137 || rv == CKR_USER_ALREADY_LOGGED_IN) ? 0 : pkcs11_rv_to_err (rv);
2139 cleanup:
2140 return ret;
2144 pkcs11_call_token_func (struct p11_kit_uri *info, const unsigned retry)
2146 struct ck_token_info *tinfo;
2147 char *label;
2148 int ret = 0;
2150 tinfo = p11_kit_uri_get_token_info (info);
2151 label = p11_kit_space_strdup (tinfo->label, sizeof (tinfo->label));
2152 ret = (_gnutls_token_func) (_gnutls_token_data, label, retry);
2153 free (label);
2155 return ret;
2159 static int
2160 find_privkeys (struct pkcs11_session_info* sinfo,
2161 struct token_info *info, struct pkey_list *list)
2163 struct ck_attribute a[3];
2164 ck_object_class_t class;
2165 ck_rv_t rv;
2166 ck_object_handle_t obj;
2167 unsigned long count, current;
2168 char certid_tmp[PKCS11_ID_SIZE];
2170 class = CKO_PRIVATE_KEY;
2172 /* Find an object with private key class and a certificate ID
2173 * which matches the certificate. */
2174 /* FIXME: also match the cert subject. */
2175 a[0].type = CKA_CLASS;
2176 a[0].value = &class;
2177 a[0].value_len = sizeof class;
2179 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, a, 1);
2180 if (rv != CKR_OK)
2182 gnutls_assert ();
2183 return pkcs11_rv_to_err (rv);
2186 list->key_ids_size = 0;
2187 while (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
2189 list->key_ids_size++;
2192 pkcs11_find_objects_final (sinfo);
2194 if (list->key_ids_size == 0)
2196 gnutls_assert ();
2197 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2200 list->key_ids =
2201 gnutls_malloc (sizeof (gnutls_buffer_st) * list->key_ids_size);
2202 if (list->key_ids == NULL)
2204 gnutls_assert ();
2205 return GNUTLS_E_MEMORY_ERROR;
2208 /* actual search */
2209 a[0].type = CKA_CLASS;
2210 a[0].value = &class;
2211 a[0].value_len = sizeof class;
2213 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, a, 1);
2214 if (rv != CKR_OK)
2216 gnutls_assert ();
2217 return pkcs11_rv_to_err (rv);
2220 current = 0;
2221 while (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
2224 a[0].type = CKA_ID;
2225 a[0].value = certid_tmp;
2226 a[0].value_len = sizeof (certid_tmp);
2228 _gnutls_buffer_init (&list->key_ids[current]);
2230 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1) == CKR_OK)
2232 _gnutls_buffer_append_data (&list->key_ids[current],
2233 a[0].value, a[0].value_len);
2234 current++;
2237 if (current > list->key_ids_size)
2238 break;
2241 pkcs11_find_objects_final (sinfo);
2243 list->key_ids_size = current - 1;
2245 return 0;
2248 /* Recover certificate list from tokens */
2251 static int
2252 find_objs (struct pkcs11_session_info* sinfo,
2253 struct token_info *info, struct ck_info *lib_info, void *input)
2255 struct crt_find_data_st *find_data = input;
2256 struct ck_attribute a[4];
2257 struct ck_attribute *attr;
2258 ck_object_class_t class = (ck_object_class_t)-1;
2259 ck_certificate_type_t type = (ck_certificate_type_t)-1;
2260 unsigned int trusted;
2261 ck_rv_t rv;
2262 ck_object_handle_t obj;
2263 unsigned long count;
2264 uint8_t *cert_data;
2265 char certid_tmp[PKCS11_ID_SIZE];
2266 char label_tmp[PKCS11_LABEL_SIZE];
2267 int ret;
2268 struct pkey_list plist; /* private key holder */
2269 unsigned int i, tot_values = 0;
2271 if (info == NULL)
2272 { /* final call */
2273 if (find_data->current <= *find_data->n_list)
2274 ret = 0;
2275 else
2276 ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
2278 *find_data->n_list = find_data->current;
2280 return ret;
2283 /* do not bother reading the token if basic fields do not match
2285 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2286 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2288 gnutls_assert ();
2289 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2292 memset (&plist, 0, sizeof (plist));
2294 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2296 ret = find_privkeys (sinfo, info, &plist);
2297 if (ret < 0)
2299 gnutls_assert ();
2300 return ret;
2303 if (plist.key_ids_size == 0)
2305 gnutls_assert ();
2306 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2310 cert_data = gnutls_malloc (MAX_CERT_SIZE);
2311 if (cert_data == NULL)
2313 gnutls_assert ();
2314 return GNUTLS_E_MEMORY_ERROR;
2317 /* Find objects with cert class and X.509 cert type. */
2319 tot_values = 0;
2321 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL
2322 || find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2324 class = CKO_CERTIFICATE;
2325 type = CKC_X_509;
2326 trusted = 1;
2328 a[tot_values].type = CKA_CLASS;
2329 a[tot_values].value = &class;
2330 a[tot_values].value_len = sizeof class;
2331 tot_values++;
2333 a[tot_values].type = CKA_CERTIFICATE_TYPE;
2334 a[tot_values].value = &type;
2335 a[tot_values].value_len = sizeof type;
2336 tot_values++;
2339 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED)
2341 class = CKO_CERTIFICATE;
2342 type = CKC_X_509;
2343 trusted = 1;
2345 a[tot_values].type = CKA_CLASS;
2346 a[tot_values].value = &class;
2347 a[tot_values].value_len = sizeof class;
2348 tot_values++;
2350 a[tot_values].type = CKA_TRUSTED;
2351 a[tot_values].value = &trusted;
2352 a[tot_values].value_len = sizeof trusted;
2353 tot_values++;
2356 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PUBKEY)
2358 class = CKO_PUBLIC_KEY;
2360 a[tot_values].type = CKA_CLASS;
2361 a[tot_values].value = &class;
2362 a[tot_values].value_len = sizeof class;
2363 tot_values++;
2365 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
2367 class = CKO_PRIVATE_KEY;
2369 a[tot_values].type = CKA_CLASS;
2370 a[tot_values].value = &class;
2371 a[tot_values].value_len = sizeof class;
2372 tot_values++;
2374 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2376 if (class != (ck_object_class_t)-1)
2378 a[tot_values].type = CKA_CLASS;
2379 a[tot_values].value = &class;
2380 a[tot_values].value_len = sizeof class;
2381 tot_values++;
2383 if (type != (ck_certificate_type_t)-1)
2385 a[tot_values].type = CKA_CERTIFICATE_TYPE;
2386 a[tot_values].value = &type;
2387 a[tot_values].value_len = sizeof type;
2388 tot_values++;
2391 else
2393 gnutls_assert ();
2394 ret = GNUTLS_E_INVALID_REQUEST;
2395 goto fail;
2398 attr = p11_kit_uri_get_attribute (find_data->info, CKA_ID);
2399 if (attr != NULL)
2401 memcpy (a + tot_values, attr, sizeof (struct ck_attribute));
2402 tot_values++;
2405 rv = pkcs11_find_objects_init (sinfo->module, sinfo->pks, a, tot_values);
2406 if (rv != CKR_OK)
2408 gnutls_assert ();
2409 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
2410 return pkcs11_rv_to_err (rv);
2413 while (pkcs11_find_objects (sinfo->module, sinfo->pks, &obj, 1, &count) == CKR_OK && count == 1)
2415 gnutls_datum_t label, id, value;
2417 a[0].type = CKA_LABEL;
2418 a[0].value = label_tmp;
2419 a[0].value_len = sizeof label_tmp;
2421 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1) == CKR_OK)
2423 label.data = a[0].value;
2424 label.size = a[0].value_len;
2426 else
2428 label.data = NULL;
2429 label.size = 0;
2432 a[0].type = CKA_ID;
2433 a[0].value = certid_tmp;
2434 a[0].value_len = sizeof certid_tmp;
2436 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1) == CKR_OK)
2438 id.data = a[0].value;
2439 id.size = a[0].value_len;
2441 else
2443 id.data = NULL;
2444 id.size = 0;
2447 a[0].type = CKA_VALUE;
2448 a[0].value = cert_data;
2449 a[0].value_len = MAX_CERT_SIZE;
2450 if (pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1) == CKR_OK)
2452 value.data = a[0].value;
2453 value.size = a[0].value_len;
2455 else
2457 value.data = NULL;
2458 value.size = 0;
2461 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2463 a[0].type = CKA_CLASS;
2464 a[0].value = &class;
2465 a[0].value_len = sizeof class;
2467 pkcs11_get_attribute_value (sinfo->module, sinfo->pks, obj, a, 1);
2470 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2472 for (i = 0; i < plist.key_ids_size; i++)
2474 if (plist.key_ids[i].length !=
2475 a[1].value_len
2476 || memcmp (plist.key_ids[i].data,
2477 a[1].value, a[1].value_len) != 0)
2479 /* not found */
2480 continue;
2485 if (find_data->current < *find_data->n_list)
2487 ret =
2488 gnutls_pkcs11_obj_init (&find_data->p_list[find_data->current]);
2489 if (ret < 0)
2491 gnutls_assert ();
2492 goto fail;
2495 if (class == CKO_PUBLIC_KEY)
2497 ret =
2498 pkcs11_obj_import_pubkey (sinfo->module, sinfo->pks, obj,
2499 find_data->p_list
2500 [find_data->current],
2501 &id, &label,
2502 &info->tinfo, lib_info);
2504 else
2506 ret =
2507 pkcs11_obj_import (class,
2508 find_data->p_list
2509 [find_data->current],
2510 &value, &id, &label,
2511 &info->tinfo, lib_info);
2513 if (ret < 0)
2515 gnutls_assert ();
2516 goto fail;
2520 find_data->current++;
2524 gnutls_free (cert_data);
2525 pkcs11_find_objects_final (sinfo);
2527 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* continue until all tokens have been checked */
2529 fail:
2530 gnutls_free (cert_data);
2531 pkcs11_find_objects_final (sinfo);
2532 if (plist.key_ids != NULL)
2534 for (i = 0; i < plist.key_ids_size; i++)
2536 _gnutls_buffer_clear (&plist.key_ids[i]);
2538 gnutls_free (plist.key_ids);
2540 for (i = 0; i < find_data->current; i++)
2542 gnutls_pkcs11_obj_deinit (find_data->p_list[i]);
2544 find_data->current = 0;
2546 return ret;
2550 * gnutls_pkcs11_obj_list_import_url:
2551 * @p_list: An uninitialized object list (may be NULL)
2552 * @n_list: initially should hold the maximum size of the list. Will contain the actual size.
2553 * @url: A PKCS 11 url identifying a set of objects
2554 * @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
2555 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2557 * This function will initialize and set values to an object list
2558 * by using all objects identified by a PKCS 11 URL.
2560 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2561 * negative error value.
2563 * Since: 2.12.0
2566 gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list,
2567 unsigned int *n_list,
2568 const char *url,
2569 gnutls_pkcs11_obj_attr_t attrs,
2570 unsigned int flags)
2572 int ret;
2573 struct crt_find_data_st find_data;
2575 memset (&find_data, 0, sizeof (find_data));
2577 /* fill in the find data structure */
2578 find_data.p_list = p_list;
2579 find_data.n_list = n_list;
2580 find_data.flags = attrs;
2581 find_data.current = 0;
2583 if (url == NULL || url[0] == 0)
2585 url = "pkcs11:";
2588 ret = pkcs11_url_to_info (url, &find_data.info);
2589 if (ret < 0)
2591 gnutls_assert ();
2592 return ret;
2595 ret =
2596 _pkcs11_traverse_tokens (find_objs, &find_data, find_data.info,
2597 NULL,
2598 pkcs11_obj_flags_to_int (flags));
2599 p11_kit_uri_free (find_data.info);
2601 if (ret < 0)
2603 gnutls_assert ();
2604 return ret;
2607 return 0;
2611 * gnutls_pkcs11_obj_list_import_url2:
2612 * @p_list: An uninitialized object list (may be NULL)
2613 * @n_list: It will contain the size of the list.
2614 * @url: A PKCS 11 url identifying a set of objects
2615 * @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
2616 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2618 * This function will initialize and set values to an object list
2619 * by using all objects identified by the PKCS 11 URL. The output
2620 * is stored in @p_list, which will be initialized.
2622 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2623 * negative error value.
2625 * Since: 3.1.0
2628 gnutls_pkcs11_obj_list_import_url2 (gnutls_pkcs11_obj_t ** p_list,
2629 unsigned int *n_list,
2630 const char *url,
2631 gnutls_pkcs11_obj_attr_t attrs,
2632 unsigned int flags)
2634 unsigned int init = 1024;
2635 int ret;
2637 *p_list = gnutls_malloc(sizeof(gnutls_pkcs11_obj_t)*init);
2638 if (*p_list == NULL)
2640 gnutls_assert();
2641 return GNUTLS_E_MEMORY_ERROR;
2644 ret = gnutls_pkcs11_obj_list_import_url( *p_list, &init, url, attrs, flags);
2645 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
2647 *p_list = gnutls_realloc_fast(*p_list, sizeof(gnutls_pkcs11_obj_t)*init);
2648 if (*p_list == NULL)
2649 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2651 ret = gnutls_pkcs11_obj_list_import_url( *p_list, &init, url, attrs, flags);
2654 if (ret < 0)
2656 gnutls_assert();
2657 gnutls_free(*p_list);
2658 *p_list = NULL;
2659 return ret;
2662 *n_list = init;
2663 return 0;
2668 * gnutls_x509_crt_import_pkcs11_url:
2669 * @crt: A certificate of type #gnutls_x509_crt_t
2670 * @url: A PKCS 11 url
2671 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2673 * This function will import a PKCS 11 certificate directly from a token
2674 * without involving the #gnutls_pkcs11_obj_t structure. This function will
2675 * fail if the certificate stored is not of X.509 type.
2677 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2678 * negative error value.
2680 * Since: 2.12.0
2683 gnutls_x509_crt_import_pkcs11_url (gnutls_x509_crt_t crt,
2684 const char *url, unsigned int flags)
2686 gnutls_pkcs11_obj_t pcrt;
2687 int ret;
2689 ret = gnutls_pkcs11_obj_init (&pcrt);
2690 if (ret < 0)
2692 gnutls_assert ();
2693 return ret;
2696 if (crt->pin.cb)
2697 gnutls_pkcs11_obj_set_pin_function (pcrt, crt->pin.cb, crt->pin.data);
2699 ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
2700 if (ret < 0)
2702 gnutls_assert ();
2703 goto cleanup;
2706 ret = gnutls_x509_crt_import (crt, &pcrt->raw, GNUTLS_X509_FMT_DER);
2707 if (ret < 0)
2709 gnutls_assert ();
2710 goto cleanup;
2713 ret = 0;
2714 cleanup:
2716 gnutls_pkcs11_obj_deinit (pcrt);
2718 return ret;
2722 * gnutls_x509_crt_import_pkcs11:
2723 * @crt: A certificate of type #gnutls_x509_crt_t
2724 * @pkcs11_crt: A PKCS 11 object that contains a certificate
2726 * This function will import a PKCS 11 certificate to a #gnutls_x509_crt_t
2727 * structure.
2729 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2730 * negative error value.
2732 * Since: 2.12.0
2735 gnutls_x509_crt_import_pkcs11 (gnutls_x509_crt_t crt,
2736 gnutls_pkcs11_obj_t pkcs11_crt)
2738 return gnutls_x509_crt_import (crt, &pkcs11_crt->raw, GNUTLS_X509_FMT_DER);
2742 * gnutls_x509_crt_list_import_pkcs11:
2743 * @certs: A list of certificates of type #gnutls_x509_crt_t
2744 * @cert_max: The maximum size of the list
2745 * @objs: A list of PKCS 11 objects
2746 * @flags: 0 for now
2748 * This function will import a PKCS 11 certificate list to a list of
2749 * #gnutls_x509_crt_t structure. These must not be initialized.
2751 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2752 * negative error value.
2754 * Since: 2.12.0
2757 gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
2758 unsigned int cert_max,
2759 gnutls_pkcs11_obj_t * const objs,
2760 unsigned int flags)
2762 unsigned int i, j;
2763 int ret;
2765 for (i = 0; i < cert_max; i++)
2767 ret = gnutls_x509_crt_init (&certs[i]);
2768 if (ret < 0)
2770 gnutls_assert ();
2771 goto cleanup;
2774 ret = gnutls_x509_crt_import_pkcs11 (certs[i], objs[i]);
2775 if (ret < 0)
2777 gnutls_assert ();
2778 goto cleanup;
2782 return 0;
2784 cleanup:
2785 for (j = 0; j < i; j++)
2787 gnutls_x509_crt_deinit (certs[j]);
2790 return ret;
2793 static int
2794 find_flags (struct pkcs11_session_info* sinfo,
2795 struct token_info *info, struct ck_info *lib_info, void *input)
2797 struct flags_find_data_st *find_data = input;
2799 if (info == NULL)
2800 { /* we don't support multiple calls */
2801 gnutls_assert ();
2802 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2805 /* do not bother reading the token if basic fields do not match
2807 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2808 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2810 gnutls_assert ();
2811 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2814 /* found token! */
2816 find_data->slot_flags = info->sinfo.flags;
2818 return 0;
2822 * gnutls_pkcs11_token_get_flags:
2823 * @url: should contain a PKCS 11 URL
2824 * @flags: The output flags (GNUTLS_PKCS11_TOKEN_*)
2826 * This function will return information about the PKCS 11 token flags.
2827 * The flags from the %gnutls_pkcs11_token_info_t enumeration.
2829 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
2831 * Since: 2.12.0
2834 gnutls_pkcs11_token_get_flags (const char *url, unsigned int *flags)
2836 struct flags_find_data_st find_data;
2837 int ret;
2839 memset (&find_data, 0, sizeof (find_data));
2840 ret = pkcs11_url_to_info (url, &find_data.info);
2841 if (ret < 0)
2843 gnutls_assert ();
2844 return ret;
2847 ret = _pkcs11_traverse_tokens (find_flags, &find_data, find_data.info, NULL, 0);
2848 p11_kit_uri_free (find_data.info);
2850 if (ret < 0)
2852 gnutls_assert ();
2853 return ret;
2856 *flags = 0;
2857 if (find_data.slot_flags & CKF_HW_SLOT)
2858 *flags |= GNUTLS_PKCS11_TOKEN_HW;
2860 return 0;
2865 * gnutls_pkcs11_token_get_mechanism:
2866 * @url: should contain a PKCS 11 URL
2867 * @idx: The index of the mechanism
2868 * @mechanism: The PKCS #11 mechanism ID
2870 * This function will return the names of the supported mechanisms
2871 * by the token. It should be called with an increasing index until
2872 * it return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.
2874 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
2876 * Since: 2.12.0
2879 gnutls_pkcs11_token_get_mechanism (const char *url, unsigned int idx,
2880 unsigned long *mechanism)
2882 int ret;
2883 ck_rv_t rv;
2884 struct ck_function_list *module;
2885 ck_slot_id_t slot;
2886 struct token_info tinfo;
2887 struct p11_kit_uri *info = NULL;
2888 unsigned long count;
2889 ck_mechanism_type_t mlist[400];
2891 ret = pkcs11_url_to_info (url, &info);
2892 if (ret < 0)
2894 gnutls_assert ();
2895 return ret;
2899 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
2900 p11_kit_uri_free (info);
2902 if (ret < 0)
2904 gnutls_assert ();
2905 return ret;
2908 count = sizeof (mlist) / sizeof (mlist[0]);
2909 rv = pkcs11_get_mechanism_list (module, slot, mlist, &count);
2910 if (rv != CKR_OK)
2912 gnutls_assert ();
2913 return pkcs11_rv_to_err (rv);
2916 if (idx >= count)
2918 gnutls_assert ();
2919 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2922 *mechanism = mlist[idx];
2924 return 0;
2929 * gnutls_pkcs11_type_get_name:
2930 * @type: Holds the PKCS 11 object type, a #gnutls_pkcs11_obj_type_t.
2932 * This function will return a human readable description of the
2933 * PKCS11 object type @obj. It will return "Unknown" for unknown
2934 * types.
2936 * Returns: human readable string labeling the PKCS11 object type
2937 * @type.
2939 * Since: 2.12.0
2941 const char *
2942 gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t type)
2944 switch (type)
2946 case GNUTLS_PKCS11_OBJ_X509_CRT:
2947 return "X.509 Certificate";
2948 case GNUTLS_PKCS11_OBJ_PUBKEY:
2949 return "Public key";
2950 case GNUTLS_PKCS11_OBJ_PRIVKEY:
2951 return "Private key";
2952 case GNUTLS_PKCS11_OBJ_SECRET_KEY:
2953 return "Secret key";
2954 case GNUTLS_PKCS11_OBJ_DATA:
2955 return "Data";
2956 case GNUTLS_PKCS11_OBJ_UNKNOWN:
2957 default:
2958 return "Unknown";
2962 ck_rv_t
2963 pkcs11_get_slot_list (struct ck_function_list * module, unsigned char token_present,
2964 ck_slot_id_t *slot_list, unsigned long *count)
2966 return (module)->C_GetSlotList (token_present, slot_list, count);
2969 ck_rv_t
2970 pkcs11_get_module_info (struct ck_function_list * module,
2971 struct ck_info * info)
2973 return (module)->C_GetInfo (info);
2976 ck_rv_t
2977 pkcs11_get_slot_info(struct ck_function_list * module,
2978 ck_slot_id_t slot_id,
2979 struct ck_slot_info *info)
2981 return (module)->C_GetSlotInfo (slot_id, info);
2984 ck_rv_t
2985 pkcs11_get_token_info (struct ck_function_list * module,
2986 ck_slot_id_t slot_id,
2987 struct ck_token_info *info)
2989 return (module)->C_GetTokenInfo (slot_id, info);
2992 ck_rv_t
2993 pkcs11_find_objects_init (struct ck_function_list *module,
2994 ck_session_handle_t sess,
2995 struct ck_attribute *templ,
2996 unsigned long count)
2998 return (module)->C_FindObjectsInit (sess, templ, count);
3001 ck_rv_t
3002 pkcs11_find_objects (struct ck_function_list *module,
3003 ck_session_handle_t sess,
3004 ck_object_handle_t *objects,
3005 unsigned long max_object_count,
3006 unsigned long *object_count)
3008 return (module)->C_FindObjects (sess, objects, max_object_count, object_count);
3011 ck_rv_t
3012 pkcs11_find_objects_final (struct pkcs11_session_info* sinfo)
3014 return (sinfo->module)->C_FindObjectsFinal (sinfo->pks);
3017 ck_rv_t
3018 pkcs11_close_session (struct pkcs11_session_info * sinfo)
3020 sinfo->init = 0;
3021 return (sinfo->module)->C_CloseSession (sinfo->pks);
3024 ck_rv_t
3025 pkcs11_get_attribute_value(struct ck_function_list *module,
3026 ck_session_handle_t sess,
3027 ck_object_handle_t object,
3028 struct ck_attribute *templ,
3029 unsigned long count)
3031 return (module)->C_GetAttributeValue (sess, object, templ, count);
3034 ck_rv_t
3035 pkcs11_get_mechanism_list (struct ck_function_list *module,
3036 ck_slot_id_t slot_id,
3037 ck_mechanism_type_t *mechanism_list,
3038 unsigned long *count)
3040 return (module)->C_GetMechanismList (slot_id, mechanism_list, count);
3043 ck_rv_t
3044 pkcs11_sign_init (struct ck_function_list *module,
3045 ck_session_handle_t sess,
3046 struct ck_mechanism *mechanism,
3047 ck_object_handle_t key)
3049 return (module)->C_SignInit (sess, mechanism, key);
3052 ck_rv_t
3053 pkcs11_sign (struct ck_function_list *module,
3054 ck_session_handle_t sess,
3055 unsigned char *data,
3056 unsigned long data_len,
3057 unsigned char *signature,
3058 unsigned long *signature_len)
3060 return (module)->C_Sign (sess, data, data_len, signature, signature_len);
3063 ck_rv_t
3064 pkcs11_generate_key_pair (struct ck_function_list *module,
3065 ck_session_handle_t sess,
3066 struct ck_mechanism *mechanism,
3067 struct ck_attribute *pub_templ,
3068 unsigned long pub_templ_count,
3069 struct ck_attribute *priv_templ,
3070 unsigned long priv_templ_count,
3071 ck_object_handle_t *pub,
3072 ck_object_handle_t *priv)
3074 return (module)->C_GenerateKeyPair (sess, mechanism, pub_templ, pub_templ_count,
3075 priv_templ, priv_templ_count, pub, priv);
3078 ck_rv_t
3079 pkcs11_decrypt_init (struct ck_function_list *module,
3080 ck_session_handle_t sess,
3081 struct ck_mechanism *mechanism,
3082 ck_object_handle_t key)
3084 return (module)->C_DecryptInit (sess, mechanism, key);
3087 ck_rv_t
3088 pkcs11_decrypt (struct ck_function_list *module,
3089 ck_session_handle_t sess,
3090 unsigned char *encrypted_data,
3091 unsigned long encrypted_data_len,
3092 unsigned char *data, unsigned long *data_len)
3094 return (module)->C_Decrypt (sess, encrypted_data, encrypted_data_len,
3095 data, data_len);
3098 ck_rv_t
3099 pkcs11_create_object (struct ck_function_list *module,
3100 ck_session_handle_t sess,
3101 struct ck_attribute *templ,
3102 unsigned long count,
3103 ck_object_handle_t *object)
3105 return (module)->C_CreateObject (sess, templ, count, object);
3108 ck_rv_t
3109 pkcs11_destroy_object (struct ck_function_list *module,
3110 ck_session_handle_t sess,
3111 ck_object_handle_t object)
3113 return (module)->C_DestroyObject (sess, object);
3116 ck_rv_t
3117 pkcs11_init_token (struct ck_function_list *module,
3118 ck_slot_id_t slot_id, unsigned char *pin,
3119 unsigned long pin_len, unsigned char *label)
3121 return (module)->C_InitToken (slot_id, pin, pin_len, label);
3124 ck_rv_t
3125 pkcs11_init_pin (struct ck_function_list *module,
3126 ck_session_handle_t sess,
3127 unsigned char *pin,
3128 unsigned long pin_len)
3130 return (module)->C_InitPIN (sess, pin, pin_len);
3133 ck_rv_t
3134 pkcs11_set_pin (struct ck_function_list *module,
3135 ck_session_handle_t sess,
3136 const char *old_pin,
3137 unsigned long old_len,
3138 const char *new_pin,
3139 unsigned long new_len)
3141 return (module)->C_SetPIN (sess, (uint8_t*)old_pin, old_len, (uint8_t*)new_pin, new_len);
3144 const char *
3145 pkcs11_strerror (ck_rv_t rv)
3147 return p11_kit_strerror (rv);