Added gnutls_pkcs11_reinit().
[gnutls.git] / lib / pkcs11.c
blob6fc55a20214eb06c3796d563f123e883ffa33f60
1 /*
2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010 Free Software Foundation
4 * Copyright (C) 2008, Joe Orton <joe@manyfish.co.uk>
5 *
6 * Author: Nikos Mavrogiannopoulos
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 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Library General Public
14 * License as published by the Free Software Foundation; either
15 * version 2 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Library General Public License for more details.
22 * You should have received a copy of the GNU Library General Public
23 * License along with this library; if not, write to the Free
24 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 * MA 02111-1307, USA
28 #include <gnutls_int.h>
29 #include <gnutls/pkcs11.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <gnutls_errors.h>
33 #include <gnutls_datum.h>
34 #include <pkcs11_int.h>
35 #include <p11-kit/p11-kit.h>
36 #include <p11-kit/pin.h>
37 #include <errno.h>
39 #define MAX_PROVIDERS 16
41 /* XXX: try to eliminate this */
42 #define MAX_CERT_SIZE 8*1024
44 struct gnutls_pkcs11_provider_s
46 struct ck_function_list *module;
47 unsigned long nslots;
48 ck_slot_id_t *slots;
49 struct ck_info info;
50 int initialized;
53 struct flags_find_data_st
55 struct p11_kit_uri *info;
56 unsigned int slot_flags;
59 struct url_find_data_st
61 gnutls_pkcs11_obj_t crt;
64 struct crt_find_data_st
66 gnutls_pkcs11_obj_t *p_list;
67 unsigned int *n_list;
68 unsigned int current;
69 gnutls_pkcs11_obj_attr_t flags;
70 struct p11_kit_uri *info;
74 static struct gnutls_pkcs11_provider_s providers[MAX_PROVIDERS];
75 static int active_providers = 0;
76 static int initialized_registered = 0;
78 static gnutls_pkcs11_pin_callback_t pin_func;
79 static void *pin_data;
81 gnutls_pkcs11_token_callback_t token_func;
82 void *token_data;
84 int
85 pkcs11_rv_to_err (ck_rv_t rv)
87 switch (rv)
89 case CKR_OK:
90 return 0;
91 case CKR_HOST_MEMORY:
92 return GNUTLS_E_MEMORY_ERROR;
93 case CKR_SLOT_ID_INVALID:
94 return GNUTLS_E_PKCS11_SLOT_ERROR;
95 case CKR_ARGUMENTS_BAD:
96 case CKR_MECHANISM_PARAM_INVALID:
97 return GNUTLS_E_INVALID_REQUEST;
98 case CKR_NEED_TO_CREATE_THREADS:
99 case CKR_CANT_LOCK:
100 case CKR_FUNCTION_NOT_PARALLEL:
101 case CKR_MUTEX_BAD:
102 case CKR_MUTEX_NOT_LOCKED:
103 return GNUTLS_E_LOCKING_ERROR;
104 case CKR_ATTRIBUTE_READ_ONLY:
105 case CKR_ATTRIBUTE_SENSITIVE:
106 case CKR_ATTRIBUTE_TYPE_INVALID:
107 case CKR_ATTRIBUTE_VALUE_INVALID:
108 return GNUTLS_E_PKCS11_ATTRIBUTE_ERROR;
109 case CKR_DEVICE_ERROR:
110 case CKR_DEVICE_MEMORY:
111 case CKR_DEVICE_REMOVED:
112 return GNUTLS_E_PKCS11_DEVICE_ERROR;
113 case CKR_DATA_INVALID:
114 case CKR_DATA_LEN_RANGE:
115 case CKR_ENCRYPTED_DATA_INVALID:
116 case CKR_ENCRYPTED_DATA_LEN_RANGE:
117 case CKR_OBJECT_HANDLE_INVALID:
118 return GNUTLS_E_PKCS11_DATA_ERROR;
119 case CKR_FUNCTION_NOT_SUPPORTED:
120 case CKR_MECHANISM_INVALID:
121 return GNUTLS_E_PKCS11_UNSUPPORTED_FEATURE_ERROR;
122 case CKR_KEY_HANDLE_INVALID:
123 case CKR_KEY_SIZE_RANGE:
124 case CKR_KEY_TYPE_INCONSISTENT:
125 case CKR_KEY_NOT_NEEDED:
126 case CKR_KEY_CHANGED:
127 case CKR_KEY_NEEDED:
128 case CKR_KEY_INDIGESTIBLE:
129 case CKR_KEY_FUNCTION_NOT_PERMITTED:
130 case CKR_KEY_NOT_WRAPPABLE:
131 case CKR_KEY_UNEXTRACTABLE:
132 return GNUTLS_E_PKCS11_KEY_ERROR;
133 case CKR_PIN_INCORRECT:
134 case CKR_PIN_INVALID:
135 case CKR_PIN_LEN_RANGE:
136 return GNUTLS_E_PKCS11_PIN_ERROR;
137 case CKR_PIN_EXPIRED:
138 return GNUTLS_E_PKCS11_PIN_EXPIRED;
139 case CKR_PIN_LOCKED:
140 return GNUTLS_E_PKCS11_PIN_LOCKED;
141 case CKR_SESSION_CLOSED:
142 case CKR_SESSION_COUNT:
143 case CKR_SESSION_HANDLE_INVALID:
144 case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
145 case CKR_SESSION_READ_ONLY:
146 case CKR_SESSION_EXISTS:
147 case CKR_SESSION_READ_ONLY_EXISTS:
148 case CKR_SESSION_READ_WRITE_SO_EXISTS:
149 return GNUTLS_E_PKCS11_SESSION_ERROR;
150 case CKR_SIGNATURE_INVALID:
151 case CKR_SIGNATURE_LEN_RANGE:
152 return GNUTLS_E_PKCS11_SIGNATURE_ERROR;
153 case CKR_TOKEN_NOT_PRESENT:
154 case CKR_TOKEN_NOT_RECOGNIZED:
155 case CKR_TOKEN_WRITE_PROTECTED:
156 return GNUTLS_E_PKCS11_TOKEN_ERROR;
157 case CKR_USER_ALREADY_LOGGED_IN:
158 case CKR_USER_NOT_LOGGED_IN:
159 case CKR_USER_PIN_NOT_INITIALIZED:
160 case CKR_USER_TYPE_INVALID:
161 case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
162 case CKR_USER_TOO_MANY_TYPES:
163 return GNUTLS_E_PKCS11_USER_ERROR;
164 case CKR_BUFFER_TOO_SMALL:
165 return GNUTLS_E_SHORT_MEMORY_BUFFER;
166 default:
167 return GNUTLS_E_PKCS11_ERROR;
171 /* Fake scan */
172 void
173 pkcs11_rescan_slots (void)
175 unsigned long slots;
177 pkcs11_get_slot_list (providers[active_providers - 1].module, 0,
178 NULL, &slots);
181 static int
182 pkcs11_add_module (const char *name, struct ck_function_list *module)
184 struct ck_info info;
185 int i;
187 if (active_providers >= MAX_PROVIDERS)
189 gnutls_assert ();
190 return GNUTLS_E_CONSTRAINT_ERROR;
193 /* initially check if this module is a duplicate */
194 memset(&info, 0, sizeof(info));
195 pkcs11_get_module_info (module, &info);
196 for (i=0;i<active_providers;i++)
198 /* already loaded, skip the rest */
199 if (memcmp(&info, &providers[i].info, sizeof(info)) == 0)
201 _gnutls_debug_log("%s is already loaded.\n", name);
202 return 0;
206 active_providers++;
207 providers[active_providers - 1].module = module;
209 /* cache the number of slots in this module */
210 if (pkcs11_get_slot_list
211 (providers[active_providers - 1].module, 0, NULL,
212 &providers[active_providers - 1].nslots) != CKR_OK)
214 gnutls_assert ();
215 goto fail;
218 providers[active_providers - 1].slots =
219 gnutls_malloc (sizeof (*providers[active_providers - 1].slots) *
220 providers[active_providers - 1].nslots);
221 if (providers[active_providers - 1].slots == NULL)
223 gnutls_assert ();
224 goto fail;
227 if (pkcs11_get_slot_list
228 (providers[active_providers - 1].module, 0,
229 providers[active_providers - 1].slots,
230 &providers[active_providers - 1].nslots) != CKR_OK)
232 gnutls_assert ();
233 gnutls_free (providers[active_providers - 1].slots);
234 goto fail;
237 memcpy (&providers[active_providers - 1].info, &info, sizeof(info));
239 _gnutls_debug_log ("p11: loaded provider '%s' with %d slots\n",
240 name, (int) providers[active_providers - 1].nslots);
242 return 0;
244 fail:
245 active_providers--;
246 return GNUTLS_E_PKCS11_LOAD_ERROR;
251 * gnutls_pkcs11_add_provider:
252 * @name: The filename of the module
253 * @params: should be NULL
255 * This function will load and add a PKCS 11 module to the module
256 * list used in gnutls. After this function is called the module will
257 * be used for PKCS 11 operations.
259 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
260 * negative error value.
263 gnutls_pkcs11_add_provider (const char *name, const char *params)
265 struct ck_function_list *module;
266 int ret;
268 active_providers++;
269 if (p11_kit_load_initialize_module (name, &module) != CKR_OK)
271 gnutls_assert ();
272 _gnutls_debug_log ("p11: Cannot load provider %s\n", name);
273 active_providers--;
274 return GNUTLS_E_PKCS11_LOAD_ERROR;
277 ret = pkcs11_add_module (name, module);
278 if (ret == 0)
280 /* Mark this one as having been separately initialized */
281 providers[active_providers - 1].initialized = 1;
283 else
285 p11_kit_finalize_module (module);
286 gnutls_assert ();
289 return ret;
294 * gnutls_pkcs11_obj_get_info:
295 * @crt: should contain a #gnutls_pkcs11_obj_t structure
296 * @itype: Denotes the type of information requested
297 * @output: where output will be stored
298 * @output_size: contains the maximum size of the output and will be overwritten with actual
300 * This function will return information about the PKCS 11 certificatesuch
301 * as the label, id as well as token information where the key is stored. When
302 * output is text it returns null terminated string although %output_size contains
303 * the size of the actual data only.
305 * Returns: zero on success or a negative value on error.
308 gnutls_pkcs11_obj_get_info (gnutls_pkcs11_obj_t crt,
309 gnutls_pkcs11_obj_info_t itype,
310 void *output, size_t * output_size)
312 return pkcs11_get_info (crt->info, itype, output, output_size);
316 pkcs11_get_info (struct p11_kit_uri *info,
317 gnutls_pkcs11_obj_info_t itype, void *output,
318 size_t * output_size)
320 struct ck_attribute *attr = NULL;
321 struct ck_version *version = NULL;
322 const char *str = NULL;
323 size_t str_max = 0;
324 int terminate = 0;
325 int hexify = 0;
326 size_t length = 0;
327 const char *data = NULL;
328 char buf[32];
331 * Either attr, str or version is valid by the time switch
332 * finishes
335 switch (itype)
337 case GNUTLS_PKCS11_OBJ_ID:
338 attr = p11_kit_uri_get_attribute (info, CKA_ID);
339 break;
340 case GNUTLS_PKCS11_OBJ_ID_HEX:
341 attr = p11_kit_uri_get_attribute (info, CKA_ID);
342 hexify = 1;
343 terminate = 1;
344 break;
345 case GNUTLS_PKCS11_OBJ_LABEL:
346 attr = p11_kit_uri_get_attribute (info, CKA_LABEL);
347 terminate = 1;
348 break;
349 case GNUTLS_PKCS11_OBJ_TOKEN_LABEL:
350 str = p11_kit_uri_get_token_info (info)->label;
351 str_max = 32;
352 break;
353 case GNUTLS_PKCS11_OBJ_TOKEN_SERIAL:
354 str = p11_kit_uri_get_token_info (info)->serial_number;
355 str_max = 16;
356 break;
357 case GNUTLS_PKCS11_OBJ_TOKEN_MANUFACTURER:
358 str = p11_kit_uri_get_token_info (info)->manufacturer_id;
359 str_max = 32;
360 break;
361 case GNUTLS_PKCS11_OBJ_TOKEN_MODEL:
362 str = p11_kit_uri_get_token_info (info)->model;
363 str_max = 16;
364 break;
365 case GNUTLS_PKCS11_OBJ_LIBRARY_DESCRIPTION:
366 str = p11_kit_uri_get_module_info (info)->library_description;
367 str_max = 32;
368 break;
369 case GNUTLS_PKCS11_OBJ_LIBRARY_VERSION:
370 version = &p11_kit_uri_get_module_info (info)->library_version;
371 break;
372 case GNUTLS_PKCS11_OBJ_LIBRARY_MANUFACTURER:
373 str = p11_kit_uri_get_module_info (info)->manufacturer_id;
374 str_max = 32;
375 break;
376 default:
377 gnutls_assert ();
378 return GNUTLS_E_INVALID_REQUEST;
381 if (attr != NULL)
383 data = attr->value;
384 length = attr->value_len;
386 else if (str != NULL)
388 data = str;
389 length = p11_kit_space_strlen (str, str_max);
390 terminate = 1;
392 else if (version != NULL)
394 data = buf;
395 length = snprintf (buf, sizeof (buf), "%d.%d", (int)version->major,
396 (int)version->minor);
397 terminate = 1;
399 else
401 *output_size = 0;
402 if (output) ((uint8_t*)output)[0] = 0;
403 return 0;
406 if (hexify)
408 /* terminate is assumed with hexify */
409 if (*output_size < length * 3)
411 *output_size = length * 3;
412 return GNUTLS_E_SHORT_MEMORY_BUFFER;
414 if (output)
415 _gnutls_bin2hex (data, length, output, *output_size, ":");
416 *output_size = length * 3;
417 return 0;
419 else
421 if (*output_size < length + terminate)
423 *output_size = length + terminate;
424 return GNUTLS_E_SHORT_MEMORY_BUFFER;
426 if (output)
428 memcpy (output, data, length);
429 if (terminate)
430 ((unsigned char*)output)[length] = '\0';
432 *output_size = length + terminate;
435 return 0;
438 static int init = 0;
440 static int
441 initialize_automatic_p11_kit (void)
443 struct ck_function_list **modules;
444 const char *name;
445 ck_rv_t rv;
446 int i, ret;
448 rv = p11_kit_initialize_registered ();
449 if (rv != CKR_OK)
451 gnutls_assert ();
452 _gnutls_debug_log ("Cannot initialize registered module: %s\n",
453 p11_kit_strerror (rv));
454 return GNUTLS_E_INTERNAL_ERROR;
457 initialized_registered = 1;
459 modules = p11_kit_registered_modules ();
460 for (i = 0; modules[i] != NULL; i++)
462 name = p11_kit_registered_module_to_name (modules[i]);
463 ret = pkcs11_add_module (name, modules[i]);
464 if (ret != 0)
466 gnutls_assert ();
467 _gnutls_debug_log ("Cannot add registered module: %s\n", name);
471 free (modules);
472 return 0;
475 static int
476 initialize_automatic_legacy (const char *configfile)
478 FILE *fp;
479 char line[512];
480 const char *library;
481 int ret;
483 if (configfile == NULL)
484 configfile = "/etc/gnutls/pkcs11.conf";
486 fp = fopen (configfile, "r");
487 if (fp == NULL)
489 if (errno == ENOENT)
490 return 0;
491 gnutls_assert ();
492 _gnutls_debug_log ("Cannot load %s\n", configfile);
493 return GNUTLS_E_FILE_ERROR;
496 while (fgets (line, sizeof (line), fp) != NULL)
498 if (strncmp (line, "load", sizeof ("load") - 1) == 0)
500 char *p;
501 p = strchr (line, '=');
502 if (p == NULL)
503 continue;
505 library = ++p;
507 p = strchr (line, '\n');
508 if (p != NULL)
510 *p = 0;
513 ret = gnutls_pkcs11_add_provider (library, NULL);
514 if (ret < 0)
516 gnutls_assert ();
517 _gnutls_debug_log ("Cannot load provider: %s\n", library);
518 continue;
523 fclose(fp);
524 return 0;
528 * gnutls_pkcs11_init:
529 * @flags: %GNUTLS_PKCS11_FLAG_MANUAL or %GNUTLS_PKCS11_FLAG_AUTO
530 * @deprecated_config_file: either NULL or the location of a deprecated
531 * configuration file
533 * This function will initialize the PKCS 11 subsystem in gnutls. It will
534 * read configuration files if %GNUTLS_PKCS11_FLAG_AUTO is used or allow
535 * you to independently load PKCS 11 modules using gnutls_pkcs11_add_provider()
536 * if %GNUTLS_PKCS11_FLAG_MANUAL is specified.
538 * Using a custom configfile is deprecated and will not be supported in future
539 * versions of gnutls.
541 * Normally you don't need to call this function since it is being called
542 * by gnutls_global_init() using the %GNUTLS_PKCS11_FLAG_AUTO. If you need to
543 * call this function, you must call it before gnutls_global_init().
545 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
546 * negative error value.
549 gnutls_pkcs11_init (unsigned int flags, const char *deprecated_config_file)
551 int ret = 0;
553 if (init != 0)
555 init++;
556 return 0;
558 init++;
560 if (flags == GNUTLS_PKCS11_FLAG_AUTO)
562 if (deprecated_config_file == NULL)
563 ret = initialize_automatic_p11_kit ();
565 if (ret == 0)
566 ret = initialize_automatic_legacy (deprecated_config_file);
569 return ret;
573 * gnutls_pkcs11_reinit:
575 * This function will reinitialize the PKCS 11 subsystem in gnutls.
576 * This is required by PKCS 11 when an application uses fork(). The
577 * reinitialization function must be called on the child.
579 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
580 * negative error value.
582 * Since: 3.0.0
584 int gnutls_pkcs11_reinit (void)
586 int rv;
588 rv = p11_kit_initialize_registered ();
589 if (rv != CKR_OK)
591 gnutls_assert ();
592 _gnutls_debug_log ("Cannot initialize registered module: %s\n",
593 p11_kit_strerror (rv));
594 return GNUTLS_E_INTERNAL_ERROR;
597 return 0;
601 * gnutls_pkcs11_deinit:
603 * This function will deinitialize the PKCS 11 subsystem in gnutls.
606 void
607 gnutls_pkcs11_deinit (void)
609 int i;
611 init--;
612 if (init > 0)
613 return;
614 if (init < 0)
616 init = 0;
617 return;
620 for (i = 0; i < active_providers; i++)
622 if (providers[i].initialized)
623 p11_kit_finalize_module (providers[i].module);
625 active_providers = 0;
627 if (initialized_registered != 0)
628 p11_kit_finalize_registered ();
629 initialized_registered = 0;
633 * gnutls_pkcs11_set_pin_function:
634 * @fn: The PIN callback
635 * @userdata: data to be supplied to callback
637 * This function will set a callback function to be used when a PIN
638 * is required for PKCS 11 operations.
640 * Callback for PKCS#11 PIN entry. The callback provides the PIN code
641 * to unlock the token with label 'token_label', specified by the URL
642 * 'token_url'.
644 * The PIN code, as a NUL-terminated ASCII string, should be copied
645 * into the 'pin' buffer (of maximum size pin_max), and
646 * return 0 to indicate success. Alternatively, the callback may
647 * return a negative gnutls error code to indicate failure and cancel
648 * PIN entry (in which case, the contents of the 'pin' parameter are ignored).
650 * When a PIN is required, the callback will be invoked repeatedly
651 * (and indefinitely) until either the returned PIN code is correct,
652 * the callback returns failure, or the token refuses login (e.g. when
653 * the token is locked due to too many incorrect PINs!). For the
654 * first such invocation, the 'attempt' counter will have value zero;
655 * it will increase by one for each subsequent attempt.
657 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
658 * negative error value.
660 void
661 gnutls_pkcs11_set_pin_function (gnutls_pkcs11_pin_callback_t fn,
662 void *userdata)
664 pin_func = fn;
665 pin_data = userdata;
669 * gnutls_pkcs11_set_token_function:
670 * @fn: The token callback
671 * @userdata: data to be supplied to callback
673 * This function will set a callback function to be used when a token
674 * needs to be inserted to continue PKCS 11 operations.
676 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
677 * negative error value.
679 void
680 gnutls_pkcs11_set_token_function (gnutls_pkcs11_token_callback_t fn,
681 void *userdata)
683 token_func = fn;
684 token_data = userdata;
688 pkcs11_url_to_info (const char *url, struct p11_kit_uri **info)
690 int allocated = 0;
691 int ret;
693 if (*info == NULL)
695 *info = p11_kit_uri_new ();
696 if (*info == NULL)
698 gnutls_assert ();
699 return GNUTLS_E_MEMORY_ERROR;
701 allocated = 1;
704 ret = p11_kit_uri_parse (url, P11_KIT_URI_FOR_ANY, *info);
705 if (ret < 0)
707 if (allocated)
709 p11_kit_uri_free (*info);
710 *info = NULL;
712 gnutls_assert ();
713 return ret == P11_KIT_URI_NO_MEMORY ?
714 GNUTLS_E_MEMORY_ERROR : GNUTLS_E_PARSING_ERROR;
717 return 0;
721 pkcs11_info_to_url (struct p11_kit_uri *info,
722 gnutls_pkcs11_url_type_t detailed, char **url)
724 p11_kit_uri_type_t type = 0;
725 int ret;
727 switch (detailed)
729 case GNUTLS_PKCS11_URL_GENERIC:
730 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN;
731 break;
732 case GNUTLS_PKCS11_URL_LIB:
733 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE;
734 break;
735 case GNUTLS_PKCS11_URL_LIB_VERSION:
736 type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE | P11_KIT_URI_FOR_MODULE_WITH_VERSION;
737 break;
740 ret = p11_kit_uri_format (info, type, url);
741 if (ret < 0)
743 gnutls_assert ();
744 return ret == P11_KIT_URI_NO_MEMORY ?
745 GNUTLS_E_MEMORY_ERROR : GNUTLS_E_INTERNAL_ERROR;
748 return 0;
752 * gnutls_pkcs11_obj_init:
753 * @obj: The structure to be initialized
755 * This function will initialize a pkcs11 certificate structure.
757 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
758 * negative error value.
761 gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t * obj)
763 *obj = gnutls_calloc (1, sizeof (struct gnutls_pkcs11_obj_st));
764 if (*obj == NULL)
766 gnutls_assert ();
767 return GNUTLS_E_MEMORY_ERROR;
770 (*obj)->info = p11_kit_uri_new ();
771 if ((*obj)->info == NULL)
773 free (*obj);
774 gnutls_assert ();
775 return GNUTLS_E_MEMORY_ERROR;
778 return 0;
782 * gnutls_pkcs11_obj_deinit:
783 * @obj: The structure to be initialized
785 * This function will deinitialize a certificate structure.
787 void
788 gnutls_pkcs11_obj_deinit (gnutls_pkcs11_obj_t obj)
790 _gnutls_free_datum (&obj->raw);
791 p11_kit_uri_free (obj->info);
792 free (obj);
796 * gnutls_pkcs11_obj_export:
797 * @obj: Holds the object
798 * @output_data: will contain a certificate PEM or DER encoded
799 * @output_data_size: holds the size of output_data (and will be
800 * replaced by the actual size of parameters)
802 * This function will export the pkcs11 object data. It is normal
803 * for PKCS #11 data to be inaccesible and in that case %GNUTLS_E_INVALID_REQUEST
804 * will be returned.
806 * If the buffer provided is not long enough to hold the output, then
807 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
808 * be returned.
810 * If the structure is PEM encoded, it will have a header
811 * of "BEGIN CERTIFICATE".
813 * Return value: In case of failure a negative value will be
814 * returned, and 0 on success.
817 gnutls_pkcs11_obj_export (gnutls_pkcs11_obj_t obj,
818 void *output_data, size_t * output_data_size)
820 if (obj == NULL || obj->raw.data == NULL)
822 gnutls_assert ();
823 return GNUTLS_E_INVALID_REQUEST;
826 if (output_data == NULL || *output_data_size < obj->raw.size)
828 *output_data_size = obj->raw.size;
829 gnutls_assert ();
830 return GNUTLS_E_SHORT_MEMORY_BUFFER;
832 *output_data_size = obj->raw.size;
834 memcpy (output_data, obj->raw.data, obj->raw.size);
835 return 0;
839 pkcs11_find_object (struct ck_function_list ** _module,
840 ck_session_handle_t * _pks,
841 ck_object_handle_t * _obj,
842 struct p11_kit_uri *info, unsigned int flags)
844 int ret;
845 struct ck_function_list *module;
846 ck_session_handle_t pks;
847 ck_object_handle_t obj;
848 struct ck_attribute *attrs;
849 unsigned long attr_count;
850 unsigned long count;
851 ck_rv_t rv;
853 ret = pkcs11_open_session (&module, &pks, info, flags & SESSION_LOGIN);
854 if (ret < 0)
856 gnutls_assert ();
857 return ret;
860 attrs = p11_kit_uri_get_attributes (info, &attr_count);
861 rv = pkcs11_find_objects_init (module, pks, attrs, attr_count);
862 if (rv != CKR_OK)
864 gnutls_assert ();
865 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
866 ret = pkcs11_rv_to_err (rv);
867 goto fail;
870 if (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
872 *_obj = obj;
873 *_pks = pks;
874 *_module = module;
875 pkcs11_find_objects_final (module, pks);
876 return 0;
879 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
880 pkcs11_find_objects_final (module, pks);
881 fail:
882 pkcs11_close_session (module, pks);
884 return ret;
888 pkcs11_find_slot (struct ck_function_list ** module, ck_slot_id_t * slot,
889 struct p11_kit_uri *info, struct token_info *_tinfo)
891 int x, z;
893 for (x = 0; x < active_providers; x++)
895 for (z = 0; z < providers[x].nslots; z++)
897 struct token_info tinfo;
899 if (pkcs11_get_token_info
900 (providers[x].module, providers[x].slots[z],
901 &tinfo.tinfo) != CKR_OK)
903 continue;
905 tinfo.sid = providers[x].slots[z];
906 tinfo.prov = &providers[x];
908 if (pkcs11_get_slot_info
909 (providers[x].module, providers[x].slots[z],
910 &tinfo.sinfo) != CKR_OK)
912 continue;
915 if (!p11_kit_uri_match_token_info (info, &tinfo.tinfo) ||
916 !p11_kit_uri_match_module_info (info, &providers[x].info))
918 continue;
921 /* ok found */
922 *module = providers[x].module;
923 *slot = providers[x].slots[z];
925 if (_tinfo != NULL)
926 memcpy (_tinfo, &tinfo, sizeof (tinfo));
928 return 0;
932 gnutls_assert ();
933 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
937 pkcs11_open_session (struct ck_function_list ** _module, ck_session_handle_t * _pks,
938 struct p11_kit_uri *info, unsigned int flags)
940 ck_rv_t rv;
941 int ret;
942 ck_session_handle_t pks = 0;
943 struct ck_function_list *module;
944 ck_slot_id_t slot;
945 struct token_info tinfo;
947 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
948 if (ret < 0)
950 gnutls_assert ();
951 return ret;
954 rv = (module)->C_OpenSession (slot,
955 ((flags & SESSION_WRITE)
956 ? CKF_RW_SESSION : 0) |
957 CKF_SERIAL_SESSION, NULL, NULL, &pks);
958 if (rv != CKR_OK)
960 gnutls_assert ();
961 return pkcs11_rv_to_err (rv);
964 if (flags & SESSION_LOGIN)
966 ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
967 if (ret < 0)
969 gnutls_assert ();
970 pkcs11_close_session (module, pks);
971 return ret;
975 /* ok found */
976 *_pks = pks;
977 *_module = module;
978 return 0;
983 _pkcs11_traverse_tokens (find_func_t find_func, void *input,
984 struct p11_kit_uri *info, unsigned int flags)
986 ck_rv_t rv;
987 int found = 0, x, z, ret;
988 ck_session_handle_t pks = 0;
989 struct ck_function_list *module = NULL;
991 for (x = 0; x < active_providers; x++)
993 module = providers[x].module;
994 for (z = 0; z < providers[x].nslots; z++)
996 struct token_info tinfo;
998 ret = GNUTLS_E_PKCS11_ERROR;
1000 if (pkcs11_get_token_info (module, providers[x].slots[z],
1001 &tinfo.tinfo) != CKR_OK)
1003 continue;
1005 tinfo.sid = providers[x].slots[z];
1006 tinfo.prov = &providers[x];
1008 if (pkcs11_get_slot_info (module, providers[x].slots[z],
1009 &tinfo.sinfo) != CKR_OK)
1011 continue;
1014 rv = (module)->C_OpenSession (providers[x].slots[z],
1015 ((flags & SESSION_WRITE)
1016 ? CKF_RW_SESSION : 0) |
1017 CKF_SERIAL_SESSION, NULL, NULL, &pks);
1018 if (rv != CKR_OK)
1020 continue;
1023 if (flags & SESSION_LOGIN)
1025 ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
1026 if (ret < 0)
1028 gnutls_assert ();
1029 return ret;
1033 ret = find_func (module, pks, &tinfo, &providers[x].info, input);
1035 if (ret == 0)
1037 found = 1;
1038 goto finish;
1040 else
1042 pkcs11_close_session (module, pks);
1043 pks = 0;
1048 finish:
1049 /* final call */
1051 if (found == 0)
1053 if (module)
1054 ret = find_func (module, pks, NULL, NULL, input);
1055 else
1056 ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1058 else
1060 ret = 0;
1063 if (pks != 0 && module != NULL)
1065 pkcs11_close_session (module, pks);
1068 return ret;
1071 /* imports a raw certificate from a token to a pkcs11_obj_t structure.
1073 static int
1074 pkcs11_obj_import (ck_object_class_t class, gnutls_pkcs11_obj_t obj,
1075 const gnutls_datum_t * data,
1076 const gnutls_datum_t * id,
1077 const gnutls_datum_t * label,
1078 struct ck_token_info *tinfo, struct ck_info *lib_info)
1080 struct ck_attribute attr;
1081 int ret;
1083 switch (class)
1085 case CKO_CERTIFICATE:
1086 obj->type = GNUTLS_PKCS11_OBJ_X509_CRT;
1087 break;
1088 case CKO_PUBLIC_KEY:
1089 obj->type = GNUTLS_PKCS11_OBJ_PUBKEY;
1090 break;
1091 case CKO_PRIVATE_KEY:
1092 obj->type = GNUTLS_PKCS11_OBJ_PRIVKEY;
1093 break;
1094 case CKO_SECRET_KEY:
1095 obj->type = GNUTLS_PKCS11_OBJ_SECRET_KEY;
1096 break;
1097 case CKO_DATA:
1098 obj->type = GNUTLS_PKCS11_OBJ_DATA;
1099 break;
1100 default:
1101 obj->type = GNUTLS_PKCS11_OBJ_UNKNOWN;
1102 break;
1105 attr.type = CKA_CLASS;
1106 attr.value = &class;
1107 attr.value_len = sizeof (class);
1108 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1109 if (ret < 0)
1111 gnutls_assert ();
1112 return GNUTLS_E_MEMORY_ERROR;
1115 if (data && data->data)
1117 ret = _gnutls_set_datum (&obj->raw, data->data, data->size);
1118 if (ret < 0)
1120 gnutls_assert ();
1121 return ret;
1125 /* copy the token and library info into the uri */
1126 memcpy (p11_kit_uri_get_token_info (obj->info), tinfo, sizeof (struct ck_token_info));
1127 memcpy (p11_kit_uri_get_module_info (obj->info), lib_info, sizeof (struct ck_info));
1129 if (label && label->data)
1131 attr.type = CKA_LABEL;
1132 attr.value = label->data;
1133 attr.value_len = label->size;
1134 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1135 if (ret < 0)
1137 gnutls_assert ();
1138 return GNUTLS_E_MEMORY_ERROR;
1142 if (id && id->data)
1144 attr.type = CKA_ID;
1145 attr.value = id->data;
1146 attr.value_len = id->size;
1147 ret = p11_kit_uri_set_attribute (obj->info, &attr);
1148 if (ret < 0)
1150 gnutls_assert ();
1151 return GNUTLS_E_MEMORY_ERROR;
1155 return 0;
1158 static int
1159 pkcs11_obj_import_pubkey (struct ck_function_list *module,
1160 ck_session_handle_t pks,
1161 ck_object_handle_t obj,
1162 gnutls_pkcs11_obj_t crt,
1163 const gnutls_datum_t * id,
1164 const gnutls_datum_t * label,
1165 struct ck_token_info *tinfo,
1166 struct ck_info *lib_info)
1169 struct ck_attribute a[4];
1170 ck_key_type_t key_type;
1171 opaque tmp1[2048];
1172 opaque tmp2[2048];
1173 int ret;
1174 ck_bool_t tval;
1176 a[0].type = CKA_KEY_TYPE;
1177 a[0].value = &key_type;
1178 a[0].value_len = sizeof (key_type);
1180 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1182 switch (key_type)
1184 case CKK_RSA:
1185 a[0].type = CKA_MODULUS;
1186 a[0].value = tmp1;
1187 a[0].value_len = sizeof (tmp1);
1188 a[1].type = CKA_PUBLIC_EXPONENT;
1189 a[1].value = tmp2;
1190 a[1].value_len = sizeof (tmp2);
1192 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1195 ret =
1196 _gnutls_set_datum (&crt->pubkey[0],
1197 a[0].value, a[0].value_len);
1199 if (ret >= 0)
1200 ret =
1201 _gnutls_set_datum (&crt->pubkey
1202 [1], a[1].value, a[1].value_len);
1204 if (ret < 0)
1206 gnutls_assert ();
1207 _gnutls_free_datum (&crt->pubkey[1]);
1208 _gnutls_free_datum (&crt->pubkey[0]);
1209 return GNUTLS_E_MEMORY_ERROR;
1212 else
1214 gnutls_assert ();
1215 return GNUTLS_E_PKCS11_ERROR;
1217 crt->pk_algorithm = GNUTLS_PK_RSA;
1218 break;
1219 case CKK_DSA:
1220 a[0].type = CKA_PRIME;
1221 a[0].value = tmp1;
1222 a[0].value_len = sizeof (tmp1);
1223 a[1].type = CKA_SUBPRIME;
1224 a[1].value = tmp2;
1225 a[1].value_len = sizeof (tmp2);
1227 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1229 ret =
1230 _gnutls_set_datum (&crt->pubkey[0],
1231 a[0].value, a[0].value_len);
1233 if (ret >= 0)
1234 ret =
1235 _gnutls_set_datum (&crt->pubkey
1236 [1], a[1].value, a[1].value_len);
1238 if (ret < 0)
1240 gnutls_assert ();
1241 _gnutls_free_datum (&crt->pubkey[1]);
1242 _gnutls_free_datum (&crt->pubkey[0]);
1243 return GNUTLS_E_MEMORY_ERROR;
1246 else
1248 gnutls_assert ();
1249 return GNUTLS_E_PKCS11_ERROR;
1252 a[0].type = CKA_BASE;
1253 a[0].value = tmp1;
1254 a[0].value_len = sizeof (tmp1);
1255 a[1].type = CKA_VALUE;
1256 a[1].value = tmp2;
1257 a[1].value_len = sizeof (tmp2);
1259 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1261 ret =
1262 _gnutls_set_datum (&crt->pubkey[2],
1263 a[0].value, a[0].value_len);
1265 if (ret >= 0)
1266 ret =
1267 _gnutls_set_datum (&crt->pubkey
1268 [3], a[1].value, a[1].value_len);
1270 if (ret < 0)
1272 gnutls_assert ();
1273 _gnutls_free_datum (&crt->pubkey[0]);
1274 _gnutls_free_datum (&crt->pubkey[1]);
1275 _gnutls_free_datum (&crt->pubkey[2]);
1276 _gnutls_free_datum (&crt->pubkey[3]);
1277 return GNUTLS_E_MEMORY_ERROR;
1280 else
1282 gnutls_assert ();
1283 return GNUTLS_E_PKCS11_ERROR;
1285 crt->pk_algorithm = GNUTLS_PK_RSA;
1286 break;
1287 default:
1288 gnutls_assert ();
1289 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1293 /* read key usage flags */
1294 a[0].type = CKA_ENCRYPT;
1295 a[0].value = &tval;
1296 a[0].value_len = sizeof (tval);
1298 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1300 if (tval != 0)
1302 crt->key_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
1306 a[0].type = CKA_VERIFY;
1307 a[0].value = &tval;
1308 a[0].value_len = sizeof (tval);
1310 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1312 if (tval != 0)
1314 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1315 GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1316 | GNUTLS_KEY_NON_REPUDIATION;
1320 a[0].type = CKA_VERIFY_RECOVER;
1321 a[0].value = &tval;
1322 a[0].value_len = sizeof (tval);
1324 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1326 if (tval != 0)
1328 crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1329 GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1330 | GNUTLS_KEY_NON_REPUDIATION;
1334 a[0].type = CKA_DERIVE;
1335 a[0].value = &tval;
1336 a[0].value_len = sizeof (tval);
1338 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1340 if (tval != 0)
1342 crt->key_usage |= GNUTLS_KEY_KEY_AGREEMENT;
1346 a[0].type = CKA_WRAP;
1347 a[0].value = &tval;
1348 a[0].value_len = sizeof (tval);
1350 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1352 if (tval != 0)
1354 crt->key_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
1358 return pkcs11_obj_import (CKO_PUBLIC_KEY, crt, NULL, id, label,
1359 tinfo, lib_info);
1362 static int
1363 find_obj_url (struct ck_function_list *module, ck_session_handle_t pks,
1364 struct token_info *info, struct ck_info *lib_info, void *input)
1366 struct url_find_data_st *find_data = input;
1367 struct ck_attribute a[4];
1368 struct ck_attribute *attr;
1369 ck_object_class_t class = -1;
1370 ck_certificate_type_t type = -1;
1371 ck_rv_t rv;
1372 ck_object_handle_t obj;
1373 unsigned long count, a_vals;
1374 int found = 0, ret;
1375 opaque *cert_data = NULL;
1376 char label_tmp[PKCS11_LABEL_SIZE];
1378 if (info == NULL)
1379 { /* we don't support multiple calls */
1380 gnutls_assert ();
1381 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1384 /* do not bother reading the token if basic fields do not match
1386 if (!p11_kit_uri_match_token_info (find_data->crt->info, &info->tinfo) ||
1387 !p11_kit_uri_match_module_info (find_data->crt->info, lib_info))
1389 gnutls_assert ();
1390 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1393 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID);
1394 if (attr == NULL)
1396 gnutls_assert ();
1397 return GNUTLS_E_INVALID_REQUEST;
1400 /* search the token for the id */
1402 cert_data = gnutls_malloc (MAX_CERT_SIZE);
1403 if (cert_data == NULL)
1405 gnutls_assert ();
1406 return GNUTLS_E_MEMORY_ERROR;
1409 /* Find objects with given class and type */
1410 memcpy (a, attr, sizeof (struct ck_attribute));
1411 a_vals = 1;
1413 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_CLASS);
1414 if (attr)
1416 if(attr->value && attr->value_len == sizeof (ck_object_class_t))
1417 class = *((ck_object_class_t*)attr->value);
1418 if (class == CKO_CERTIFICATE)
1419 type = CKC_X_509;
1420 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1421 a_vals++;
1424 if (type != -1)
1426 a[a_vals].type = CKA_CERTIFICATE_TYPE;
1427 a[a_vals].value = &type;
1428 a[a_vals].value_len = sizeof type;
1429 a_vals++;
1432 rv = pkcs11_find_objects_init (module, pks, a, a_vals);
1433 if (rv != CKR_OK)
1435 gnutls_assert ();
1436 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
1437 ret = pkcs11_rv_to_err (rv);
1438 goto cleanup;
1441 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
1444 a[0].type = CKA_VALUE;
1445 a[0].value = cert_data;
1446 a[0].value_len = MAX_CERT_SIZE;
1447 a[1].type = CKA_LABEL;
1448 a[1].value = label_tmp;
1449 a[1].value_len = sizeof (label_tmp);
1451 if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1453 gnutls_datum_t id;
1454 gnutls_datum_t data = { a[0].value, a[0].value_len };
1455 gnutls_datum_t label = { a[1].value, a[1].value_len };
1457 attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID);
1458 id.data = attr->value;
1459 id.size = attr->value_len;
1461 if (class == CKO_PUBLIC_KEY)
1463 ret =
1464 pkcs11_obj_import_pubkey (module, pks, obj,
1465 find_data->crt,
1466 &id, &label,
1467 &info->tinfo, lib_info);
1469 else
1471 ret =
1472 pkcs11_obj_import (class,
1473 find_data->crt,
1474 &data, &id, &label,
1475 &info->tinfo, lib_info);
1477 if (ret < 0)
1479 gnutls_assert ();
1480 goto cleanup;
1483 found = 1;
1484 break;
1486 else
1488 _gnutls_debug_log ("pk11: Skipped cert, missing attrs.\n");
1492 if (found == 0)
1494 gnutls_assert ();
1495 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1497 else
1499 ret = 0;
1502 cleanup:
1503 gnutls_free (cert_data);
1504 pkcs11_find_objects_final (module, pks);
1506 return ret;
1509 unsigned int
1510 pkcs11_obj_flags_to_int (unsigned int flags)
1512 unsigned int ret_flags = 0;
1514 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN)
1515 ret_flags |= SESSION_LOGIN;
1516 if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO)
1517 ret_flags |= SESSION_LOGIN|SESSION_SO;
1519 return ret_flags;
1523 * gnutls_pkcs11_privkey_import_url:
1524 * @cert: The structure to store the parsed certificate
1525 * @url: a PKCS 11 url identifying the key
1526 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1528 * This function will "import" a PKCS 11 URL identifying a certificate
1529 * key to the #gnutls_pkcs11_obj_t structure. This does not involve any
1530 * parsing (such as X.509 or OpenPGP) since the #gnutls_pkcs11_obj_t is
1531 * format agnostic. Only data are transferred.
1533 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1534 * negative error value.
1537 gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t cert, const char *url,
1538 unsigned int flags)
1540 int ret;
1541 struct url_find_data_st find_data;
1543 /* fill in the find data structure */
1544 find_data.crt = cert;
1546 ret = pkcs11_url_to_info (url, &cert->info);
1547 if (ret < 0)
1549 gnutls_assert ();
1550 return ret;
1553 ret =
1554 _pkcs11_traverse_tokens (find_obj_url, &find_data, cert->info,
1555 pkcs11_obj_flags_to_int (flags));
1557 if (ret < 0)
1559 gnutls_assert ();
1560 return ret;
1563 return 0;
1566 struct token_num
1568 struct p11_kit_uri *info;
1569 unsigned int seq; /* which one we are looking for */
1570 unsigned int current; /* which one are we now */
1573 static int
1574 find_token_num (struct ck_function_list *module,
1575 ck_session_handle_t pks,
1576 struct token_info *tinfo,
1577 struct ck_info *lib_info, void *input)
1579 struct token_num *find_data = input;
1581 if (tinfo == NULL)
1582 { /* we don't support multiple calls */
1583 gnutls_assert ();
1584 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1587 if (find_data->current == find_data->seq)
1589 memcpy (p11_kit_uri_get_token_info (find_data->info), &tinfo->tinfo, sizeof (struct ck_token_info));
1590 memcpy (p11_kit_uri_get_module_info (find_data->info), lib_info, sizeof (struct ck_info));
1591 return 0;
1594 find_data->current++;
1595 /* search the token for the id */
1598 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* non zero is enough */
1602 * gnutls_pkcs11_token_get_url:
1603 * @seq: sequence number starting from 0
1604 * @detailed: non zero if a detailed URL is required
1605 * @url: will contain an allocated url
1607 * This function will return the URL for each token available
1608 * in system. The url has to be released using gnutls_free()
1610 * Returns: On success, %GNUTLS_E_SUCCESS is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1611 * if the sequence number exceeds the available tokens, otherwise a negative error value.
1615 gnutls_pkcs11_token_get_url (unsigned int seq,
1616 gnutls_pkcs11_url_type_t detailed, char **url)
1618 int ret;
1619 struct token_num tn;
1621 memset (&tn, 0, sizeof (tn));
1622 tn.seq = seq;
1623 tn.info = p11_kit_uri_new ();
1625 ret = _pkcs11_traverse_tokens (find_token_num, &tn, NULL, 0);
1626 if (ret < 0)
1628 p11_kit_uri_free (tn.info);
1629 gnutls_assert ();
1630 return ret;
1633 ret = pkcs11_info_to_url (tn.info, detailed, url);
1634 p11_kit_uri_free (tn.info);
1636 if (ret < 0)
1638 gnutls_assert ();
1639 return ret;
1642 return 0;
1647 * gnutls_pkcs11_token_get_info:
1648 * @url: should contain a PKCS 11 URL
1649 * @ttype: Denotes the type of information requested
1650 * @output: where output will be stored
1651 * @output_size: contains the maximum size of the output and will be overwritten with actual
1653 * This function will return information about the PKCS 11 token such
1654 * as the label, id as well as token information where the key is stored.
1656 * Returns: zero on success or a negative value on error.
1659 gnutls_pkcs11_token_get_info (const char *url,
1660 gnutls_pkcs11_token_info_t ttype,
1661 void *output, size_t * output_size)
1663 struct p11_kit_uri *info = NULL;
1664 const char *str;
1665 size_t str_max;
1666 size_t len;
1667 int ret;
1669 ret = pkcs11_url_to_info (url, &info);
1670 if (ret < 0)
1672 gnutls_assert ();
1673 return ret;
1676 switch (ttype)
1678 case GNUTLS_PKCS11_TOKEN_LABEL:
1679 str = p11_kit_uri_get_token_info (info)->label;
1680 str_max = 32;
1681 break;
1682 case GNUTLS_PKCS11_TOKEN_SERIAL:
1683 str = p11_kit_uri_get_token_info (info)->serial_number;
1684 str_max = 16;
1685 break;
1686 case GNUTLS_PKCS11_TOKEN_MANUFACTURER:
1687 str = p11_kit_uri_get_token_info (info)->manufacturer_id;
1688 str_max = 32;
1689 break;
1690 case GNUTLS_PKCS11_TOKEN_MODEL:
1691 str = p11_kit_uri_get_token_info (info)->model;
1692 str_max = 16;
1693 break;
1694 default:
1695 p11_kit_uri_free (info);
1696 gnutls_assert ();
1697 return GNUTLS_E_INVALID_REQUEST;
1700 len = p11_kit_space_strlen (str, str_max);
1702 if (len + 1 > *output_size)
1704 *output_size = len + 1;
1705 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1708 memcpy (output, str, len);
1709 ((char*)output)[len] = '\0';
1711 *output_size = len;
1713 p11_kit_uri_free (info);
1714 return 0;
1718 * gnutls_pkcs11_obj_export_url:
1719 * @obj: Holds the PKCS 11 certificate
1720 * @detailed: non zero if a detailed URL is required
1721 * @url: will contain an allocated url
1723 * This function will export a URL identifying the given certificate.
1725 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1726 * negative error value.
1729 gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t obj,
1730 gnutls_pkcs11_url_type_t detailed, char **url)
1732 int ret;
1734 ret = pkcs11_info_to_url (obj->info, detailed, url);
1735 if (ret < 0)
1737 gnutls_assert ();
1738 return ret;
1741 return 0;
1745 * gnutls_pkcs11_obj_get_type:
1746 * @certificate: Holds the PKCS 11 certificate
1748 * This function will return the type of the certificate being
1749 * stored in the structure.
1751 * Returns: The type of the certificate.
1753 gnutls_pkcs11_obj_type_t
1754 gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t obj)
1756 return obj->type;
1759 struct pkey_list
1761 gnutls_buffer_st *key_ids;
1762 size_t key_ids_size;
1766 static int
1767 retrieve_pin_for_pinfile (const char *pinfile, struct ck_token_info *token_info,
1768 int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
1770 unsigned int flags = 0;
1771 struct p11_kit_uri *token_uri;
1772 struct p11_kit_pin *result;
1773 char *label;
1775 label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1776 if (label == NULL)
1778 gnutls_assert ();
1779 return GNUTLS_E_MEMORY_ERROR;
1782 token_uri = p11_kit_uri_new ();
1783 if (token_uri == NULL)
1785 free (label);
1786 gnutls_assert ();
1787 return GNUTLS_E_MEMORY_ERROR;
1790 memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1791 sizeof (struct ck_token_info));
1793 if (attempts)
1794 flags |= P11_KIT_PIN_FLAGS_RETRY;
1795 if (user_type == CKU_USER)
1797 flags |= P11_KIT_PIN_FLAGS_USER_LOGIN;
1798 if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1799 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1800 if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1801 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1803 else if (user_type == CKU_SO)
1805 flags |= P11_KIT_PIN_FLAGS_SO_LOGIN;
1806 if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
1807 flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1808 if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
1809 flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1811 else if (user_type == CKU_CONTEXT_SPECIFIC)
1813 flags |= P11_KIT_PIN_FLAGS_CONTEXT_LOGIN;
1816 result = p11_kit_pin_request (pinfile, token_uri, label, flags);
1817 p11_kit_uri_free (token_uri);
1818 free (label);
1820 if (result == NULL)
1822 gnutls_assert ();
1823 return GNUTLS_E_PKCS11_PIN_ERROR;
1826 *pin = result;
1827 return 0;
1830 static int
1831 retrieve_pin_for_callback (struct ck_token_info *token_info, int attempts,
1832 ck_user_type_t user_type, struct p11_kit_pin **pin)
1834 char pin_value[GNUTLS_PKCS11_MAX_PIN_LEN];
1835 unsigned int flags = 0;
1836 char *token_str;
1837 char *label;
1838 struct p11_kit_uri *token_uri;
1839 int ret = 0;
1841 label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1842 if (label == NULL)
1844 gnutls_assert ();
1845 return GNUTLS_E_MEMORY_ERROR;
1848 token_uri = p11_kit_uri_new ();
1849 if (token_uri == NULL)
1851 free (label);
1852 gnutls_assert ();
1853 return GNUTLS_E_MEMORY_ERROR;
1856 memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1857 sizeof (struct ck_token_info));
1858 ret = pkcs11_info_to_url (token_uri, 1, &token_str);
1859 p11_kit_uri_free (token_uri);
1861 if (ret < 0)
1863 free (label);
1864 gnutls_assert ();
1865 return GNUTLS_E_MEMORY_ERROR;
1868 if (user_type == CKU_USER)
1870 flags |= GNUTLS_PKCS11_PIN_USER;
1871 if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1872 flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
1873 if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1874 flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
1876 else if (user_type == CKU_SO)
1878 flags |= GNUTLS_PKCS11_PIN_SO;
1879 if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
1880 flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
1881 if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
1882 flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
1885 if (attempts > 0)
1886 flags |= GNUTLS_PKCS11_PIN_WRONG;
1888 ret = pin_func (pin_data, attempts, (char*)token_str, label,
1889 flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
1890 free (token_str);
1891 free (label);
1893 if (ret < 0)
1894 return gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR);
1896 *pin = p11_kit_pin_new_for_string (pin_value);
1898 if (*pin == NULL)
1899 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1901 return 0;
1904 static int
1905 retrieve_pin (struct p11_kit_uri *info, struct ck_token_info *token_info,
1906 int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
1908 const char *pinfile;
1910 *pin = NULL;
1912 /* Check if a pinfile is specified, and use that if possible */
1913 pinfile = p11_kit_uri_get_pinfile (info);
1914 if (pinfile != NULL)
1916 _gnutls_debug_log("pk11: Using pinfile to retrieve PIN\n");
1917 return retrieve_pin_for_pinfile (pinfile, token_info, attempts, user_type, pin);
1920 /* The global gnutls pin callback */
1921 else if (pin_func)
1922 return retrieve_pin_for_callback (token_info, attempts, user_type, pin);
1924 /* Otherwise, PIN entry is necessary for login, so fail if there's
1925 * no callback. */
1926 else
1928 gnutls_assert ();
1929 _gnutls_debug_log ("pk11: No pin callback but login required.\n");
1930 return GNUTLS_E_PKCS11_ERROR;
1935 pkcs11_login (struct ck_function_list * module, ck_session_handle_t pks,
1936 const struct token_info *tokinfo, struct p11_kit_uri *info, int so)
1938 struct ck_session_info session_info;
1939 int attempt = 0, ret;
1940 ck_user_type_t user_type;
1941 ck_rv_t rv;
1943 user_type = (so == 0) ? CKU_USER : CKU_SO;
1944 if (so == 0 && (tokinfo->tinfo.flags & CKF_LOGIN_REQUIRED) == 0)
1946 gnutls_assert ();
1947 _gnutls_debug_log ("pk11: No login required.\n");
1948 return 0;
1951 /* For a token with a "protected" (out-of-band) authentication
1952 * path, calling login with a NULL username is all that is
1953 * required. */
1954 if (tokinfo->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
1956 rv = (module)->C_Login (pks, (so == 0) ? CKU_USER : CKU_SO, NULL, 0);
1957 if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
1959 return 0;
1961 else
1963 gnutls_assert ();
1964 _gnutls_debug_log ("pk11: Protected login failed.\n");
1965 ret = GNUTLS_E_PKCS11_ERROR;
1966 goto cleanup;
1972 struct p11_kit_pin *pin;
1973 struct ck_token_info tinfo;
1975 memcpy (&tinfo, &tokinfo->tinfo, sizeof(tinfo));
1977 /* Check whether the session is already logged in, and if so, just skip */
1978 rv = (module)->C_GetSessionInfo (pks, &session_info);
1979 if (rv == CKR_OK && (session_info.state == CKS_RO_USER_FUNCTIONS ||
1980 session_info.state == CKS_RW_USER_FUNCTIONS))
1982 ret = 0;
1983 goto cleanup;
1986 /* If login has been attempted once already, check the token
1987 * status again, the flags might change. */
1988 if (attempt)
1990 if (pkcs11_get_token_info
1991 (tokinfo->prov->module, tokinfo->sid, &tinfo) != CKR_OK)
1993 gnutls_assert ();
1994 _gnutls_debug_log ("pk11: GetTokenInfo failed\n");
1995 ret = GNUTLS_E_PKCS11_ERROR;
1996 goto cleanup;
2000 ret = retrieve_pin (info, &tinfo, attempt++, user_type, &pin);
2001 if (ret < 0)
2003 gnutls_assert ();
2004 goto cleanup;
2007 rv = (module)->C_Login (pks, user_type,
2008 (unsigned char *)p11_kit_pin_get_value (pin, NULL),
2009 p11_kit_pin_get_length (pin));
2011 p11_kit_pin_unref (pin);
2013 while (rv == CKR_PIN_INCORRECT);
2015 _gnutls_debug_log ("pk11: Login result = %lu\n", rv);
2018 ret = (rv == CKR_OK
2019 || rv == CKR_USER_ALREADY_LOGGED_IN) ? 0 : pkcs11_rv_to_err (rv);
2021 cleanup:
2022 return ret;
2026 pkcs11_call_token_func (struct p11_kit_uri *info, const unsigned retry)
2028 struct ck_token_info *tinfo;
2029 char *label;
2030 int ret = 0;
2032 tinfo = p11_kit_uri_get_token_info (info);
2033 label = p11_kit_space_strdup (tinfo->label, sizeof (tinfo->label));
2034 ret = (token_func) (token_data, label, retry);
2035 free (label);
2037 return ret;
2041 static int
2042 find_privkeys (struct ck_function_list *module, ck_session_handle_t pks,
2043 struct token_info *info, struct pkey_list *list)
2045 struct ck_attribute a[3];
2046 ck_object_class_t class;
2047 ck_rv_t rv;
2048 ck_object_handle_t obj;
2049 unsigned long count, current;
2050 char certid_tmp[PKCS11_ID_SIZE];
2052 class = CKO_PRIVATE_KEY;
2054 /* Find an object with private key class and a certificate ID
2055 * which matches the certificate. */
2056 /* FIXME: also match the cert subject. */
2057 a[0].type = CKA_CLASS;
2058 a[0].value = &class;
2059 a[0].value_len = sizeof class;
2061 rv = pkcs11_find_objects_init (module, pks, a, 1);
2062 if (rv != CKR_OK)
2064 gnutls_assert ();
2065 return pkcs11_rv_to_err (rv);
2068 list->key_ids_size = 0;
2069 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
2071 list->key_ids_size++;
2074 pkcs11_find_objects_final (module, pks);
2076 if (list->key_ids_size == 0)
2078 gnutls_assert ();
2079 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2082 list->key_ids =
2083 gnutls_malloc (sizeof (gnutls_buffer_st) * list->key_ids_size);
2084 if (list->key_ids == NULL)
2086 gnutls_assert ();
2087 return GNUTLS_E_MEMORY_ERROR;
2090 /* actual search */
2091 a[0].type = CKA_CLASS;
2092 a[0].value = &class;
2093 a[0].value_len = sizeof class;
2095 rv = pkcs11_find_objects_init (module, pks, a, 1);
2096 if (rv != CKR_OK)
2098 gnutls_assert ();
2099 return pkcs11_rv_to_err (rv);
2102 current = 0;
2103 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
2106 a[0].type = CKA_ID;
2107 a[0].value = certid_tmp;
2108 a[0].value_len = sizeof (certid_tmp);
2110 _gnutls_buffer_init (&list->key_ids[current]);
2112 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2114 _gnutls_buffer_append_data (&list->key_ids[current],
2115 a[0].value, a[0].value_len);
2116 current++;
2119 if (current > list->key_ids_size)
2120 break;
2123 pkcs11_find_objects_final (module, pks);
2125 list->key_ids_size = current - 1;
2127 return 0;
2130 /* Recover certificate list from tokens */
2133 static int
2134 find_objs (struct ck_function_list * module, ck_session_handle_t pks,
2135 struct token_info *info, struct ck_info *lib_info, void *input)
2137 struct crt_find_data_st *find_data = input;
2138 struct ck_attribute a[4];
2139 struct ck_attribute *attr;
2140 ck_object_class_t class = -1;
2141 ck_certificate_type_t type = -1;
2142 unsigned int trusted;
2143 ck_rv_t rv;
2144 ck_object_handle_t obj;
2145 unsigned long count;
2146 opaque *cert_data;
2147 char certid_tmp[PKCS11_ID_SIZE];
2148 char label_tmp[PKCS11_LABEL_SIZE];
2149 int ret, i;
2150 struct pkey_list plist; /* private key holder */
2151 int tot_values = 0;
2153 if (info == NULL)
2154 { /* final call */
2155 if (find_data->current <= *find_data->n_list)
2156 ret = 0;
2157 else
2158 ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
2160 *find_data->n_list = find_data->current;
2162 return ret;
2165 /* do not bother reading the token if basic fields do not match
2167 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2168 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2170 gnutls_assert ();
2171 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2174 memset (&plist, 0, sizeof (plist));
2176 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2178 ret = find_privkeys (module, pks, info, &plist);
2179 if (ret < 0)
2181 gnutls_assert ();
2182 return ret;
2185 if (plist.key_ids_size == 0)
2187 gnutls_assert ();
2188 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2192 cert_data = gnutls_malloc (MAX_CERT_SIZE);
2193 if (cert_data == NULL)
2195 gnutls_assert ();
2196 return GNUTLS_E_MEMORY_ERROR;
2199 /* Find objects with cert class and X.509 cert type. */
2201 tot_values = 0;
2203 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL
2204 || find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2206 class = CKO_CERTIFICATE;
2207 type = CKC_X_509;
2208 trusted = 1;
2210 a[tot_values].type = CKA_CLASS;
2211 a[tot_values].value = &class;
2212 a[tot_values].value_len = sizeof class;
2213 tot_values++;
2215 a[tot_values].type = CKA_CERTIFICATE_TYPE;
2216 a[tot_values].value = &type;
2217 a[tot_values].value_len = sizeof type;
2218 tot_values++;
2221 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED)
2223 class = CKO_CERTIFICATE;
2224 type = CKC_X_509;
2225 trusted = 1;
2227 a[tot_values].type = CKA_CLASS;
2228 a[tot_values].value = &class;
2229 a[tot_values].value_len = sizeof class;
2230 tot_values++;
2232 a[tot_values].type = CKA_TRUSTED;
2233 a[tot_values].value = &trusted;
2234 a[tot_values].value_len = sizeof trusted;
2235 tot_values++;
2238 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PUBKEY)
2240 class = CKO_PUBLIC_KEY;
2242 a[tot_values].type = CKA_CLASS;
2243 a[tot_values].value = &class;
2244 a[tot_values].value_len = sizeof class;
2245 tot_values++;
2247 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
2249 class = CKO_PRIVATE_KEY;
2251 a[tot_values].type = CKA_CLASS;
2252 a[tot_values].value = &class;
2253 a[tot_values].value_len = sizeof class;
2254 tot_values++;
2256 else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2258 if (class != -1)
2260 a[tot_values].type = CKA_CLASS;
2261 a[tot_values].value = &class;
2262 a[tot_values].value_len = sizeof class;
2263 tot_values++;
2265 if (type != -1)
2267 a[tot_values].type = CKA_CERTIFICATE_TYPE;
2268 a[tot_values].value = &type;
2269 a[tot_values].value_len = sizeof type;
2270 tot_values++;
2273 else
2275 gnutls_assert ();
2276 ret = GNUTLS_E_INVALID_REQUEST;
2277 goto fail;
2280 attr = p11_kit_uri_get_attribute (find_data->info, CKA_ID);
2281 if (attr != NULL)
2283 memcpy (a + tot_values, attr, sizeof (struct ck_attribute));
2284 tot_values++;
2287 rv = pkcs11_find_objects_init (module, pks, a, tot_values);
2288 if (rv != CKR_OK)
2290 gnutls_assert ();
2291 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
2292 return pkcs11_rv_to_err (rv);
2295 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
2297 gnutls_datum_t label, id, value;
2299 a[0].type = CKA_LABEL;
2300 a[0].value = label_tmp;
2301 a[0].value_len = sizeof label_tmp;
2303 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2305 label.data = a[0].value;
2306 label.size = a[0].value_len;
2308 else
2310 label.data = NULL;
2311 label.size = 0;
2314 a[0].type = CKA_ID;
2315 a[0].value = certid_tmp;
2316 a[0].value_len = sizeof certid_tmp;
2318 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2320 id.data = a[0].value;
2321 id.size = a[0].value_len;
2323 else
2325 id.data = NULL;
2326 id.size = 0;
2329 a[0].type = CKA_VALUE;
2330 a[0].value = cert_data;
2331 a[0].value_len = MAX_CERT_SIZE;
2332 if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2334 value.data = a[0].value;
2335 value.size = a[0].value_len;
2337 else
2339 value.data = NULL;
2340 value.size = 0;
2343 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2345 a[0].type = CKA_CLASS;
2346 a[0].value = &class;
2347 a[0].value_len = sizeof class;
2349 pkcs11_get_attribute_value (module, pks, obj, a, 1);
2352 if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2354 for (i = 0; i < plist.key_ids_size; i++)
2356 if (plist.key_ids[i].length !=
2357 a[1].value_len
2358 || memcmp (plist.key_ids[i].data,
2359 a[1].value, a[1].value_len) != 0)
2361 /* not found */
2362 continue;
2367 if (find_data->current < *find_data->n_list)
2369 ret =
2370 gnutls_pkcs11_obj_init (&find_data->p_list[find_data->current]);
2371 if (ret < 0)
2373 gnutls_assert ();
2374 goto fail;
2377 if (class == CKO_PUBLIC_KEY)
2379 ret =
2380 pkcs11_obj_import_pubkey (module, pks, obj,
2381 find_data->p_list
2382 [find_data->current],
2383 &id, &label,
2384 &info->tinfo, lib_info);
2386 else
2388 ret =
2389 pkcs11_obj_import (class,
2390 find_data->p_list
2391 [find_data->current],
2392 &value, &id, &label,
2393 &info->tinfo, lib_info);
2395 if (ret < 0)
2397 gnutls_assert ();
2398 goto fail;
2402 find_data->current++;
2406 gnutls_free (cert_data);
2407 pkcs11_find_objects_final (module, pks);
2409 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* continue until all tokens have been checked */
2411 fail:
2412 gnutls_free (cert_data);
2413 pkcs11_find_objects_final (module, pks);
2414 if (plist.key_ids != NULL)
2416 for (i = 0; i < plist.key_ids_size; i++)
2418 _gnutls_buffer_clear (&plist.key_ids[i]);
2420 gnutls_free (plist.key_ids);
2422 for (i = 0; i < find_data->current; i++)
2424 gnutls_pkcs11_obj_deinit (find_data->p_list[i]);
2426 find_data->current = 0;
2428 return ret;
2432 * gnutls_pkcs11_obj_list_import_url:
2433 * @p_list: An uninitialized object list (may be NULL)
2434 * @n_list: initially should hold the maximum size of the list. Will contain the actual size.
2435 * @url: A PKCS 11 url identifying a set of objects
2436 * @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
2437 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2439 * This function will initialize and set values to an object list
2440 * by using all objects identified by a PKCS 11 URL.
2442 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
2443 * negative error value.
2446 gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list,
2447 unsigned int *n_list,
2448 const char *url,
2449 gnutls_pkcs11_obj_attr_t attrs,
2450 unsigned int flags)
2452 int ret;
2453 struct crt_find_data_st find_data;
2455 memset (&find_data, 0, sizeof (find_data));
2457 /* fill in the find data structure */
2458 find_data.p_list = p_list;
2459 find_data.n_list = n_list;
2460 find_data.flags = attrs;
2461 find_data.current = 0;
2463 if (url == NULL || url[0] == 0)
2465 url = "pkcs11:";
2468 ret = pkcs11_url_to_info (url, &find_data.info);
2469 if (ret < 0)
2471 gnutls_assert ();
2472 return ret;
2475 ret =
2476 _pkcs11_traverse_tokens (find_objs, &find_data, find_data.info,
2477 pkcs11_obj_flags_to_int (flags));
2478 p11_kit_uri_free (find_data.info);
2480 if (ret < 0)
2482 gnutls_assert ();
2483 return ret;
2486 return 0;
2490 * gnutls_x509_crt_import_pkcs11_url:
2491 * @crt: A certificate of type #gnutls_x509_crt_t
2492 * @url: A PKCS 11 url
2493 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
2495 * This function will import a PKCS 11 certificate directly from a token
2496 * without involving the #gnutls_pkcs11_obj_t structure. This function will
2497 * fail if the certificate stored is not of X.509 type.
2499 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
2500 * negative error value.
2503 gnutls_x509_crt_import_pkcs11_url (gnutls_x509_crt_t crt,
2504 const char *url, unsigned int flags)
2506 gnutls_pkcs11_obj_t pcrt;
2507 int ret;
2509 ret = gnutls_pkcs11_obj_init (&pcrt);
2510 if (ret < 0)
2512 gnutls_assert ();
2513 return ret;
2516 ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
2517 if (ret < 0)
2519 gnutls_assert ();
2520 goto cleanup;
2523 ret = gnutls_x509_crt_import (crt, &pcrt->raw, GNUTLS_X509_FMT_DER);
2524 if (ret < 0)
2526 gnutls_assert ();
2527 goto cleanup;
2530 ret = 0;
2531 cleanup:
2533 gnutls_pkcs11_obj_deinit (pcrt);
2535 return ret;
2540 * gnutls_x509_crt_import_pkcs11:
2541 * @crt: A certificate of type #gnutls_x509_crt_t
2542 * @pkcs11_crt: A PKCS 11 object that contains a certificate
2544 * This function will import a PKCS 11 certificate to a #gnutls_x509_crt_t
2545 * structure.
2547 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
2548 * negative error value.
2551 gnutls_x509_crt_import_pkcs11 (gnutls_x509_crt_t crt,
2552 gnutls_pkcs11_obj_t pkcs11_crt)
2554 return gnutls_x509_crt_import (crt, &pkcs11_crt->raw, GNUTLS_X509_FMT_DER);
2558 * gnutls_x509_crt_list_import_pkcs11:
2559 * @certs: A list of certificates of type #gnutls_x509_crt_t
2560 * @cert_max: The maximum size of the list
2561 * @objs: A list of PKCS 11 objects
2562 * @flags: 0 for now
2564 * This function will import a PKCS 11 certificate list to a list of
2565 * #gnutls_x509_crt_t structure. These must not be initialized.
2567 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
2568 * negative error value.
2571 gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
2572 unsigned int cert_max,
2573 gnutls_pkcs11_obj_t * const objs,
2574 unsigned int flags)
2576 int i, j;
2577 int ret;
2579 for (i = 0; i < cert_max; i++)
2581 ret = gnutls_x509_crt_init (&certs[i]);
2582 if (ret < 0)
2584 gnutls_assert ();
2585 goto cleanup;
2588 ret = gnutls_x509_crt_import_pkcs11 (certs[i], objs[i]);
2589 if (ret < 0)
2591 gnutls_assert ();
2592 goto cleanup;
2596 return 0;
2598 cleanup:
2599 for (j = 0; j < i; j++)
2601 gnutls_x509_crt_deinit (certs[j]);
2604 return ret;
2607 static int
2608 find_flags (struct ck_function_list * module, ck_session_handle_t pks,
2609 struct token_info *info, struct ck_info *lib_info, void *input)
2611 struct flags_find_data_st *find_data = input;
2613 if (info == NULL)
2614 { /* we don't support multiple calls */
2615 gnutls_assert ();
2616 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2619 /* do not bother reading the token if basic fields do not match
2621 if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2622 !p11_kit_uri_match_module_info (find_data->info, lib_info))
2624 gnutls_assert ();
2625 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2628 /* found token! */
2630 find_data->slot_flags = info->sinfo.flags;
2632 return 0;
2636 * gnutls_pkcs11_token_get_flags:
2637 * @url: should contain a PKCS 11 URL
2638 * @flags: The output flags (GNUTLS_PKCS11_TOKEN_*)
2640 * This function will return information about the PKCS 11 token flags.
2642 * Returns: zero on success or a negative value on error.
2645 gnutls_pkcs11_token_get_flags (const char *url, unsigned int *flags)
2647 struct flags_find_data_st find_data;
2648 int ret;
2650 memset (&find_data, 0, sizeof (find_data));
2651 ret = pkcs11_url_to_info (url, &find_data.info);
2652 if (ret < 0)
2654 gnutls_assert ();
2655 return ret;
2658 ret = _pkcs11_traverse_tokens (find_flags, &find_data, find_data.info, 0);
2659 p11_kit_uri_free (find_data.info);
2661 if (ret < 0)
2663 gnutls_assert ();
2664 return ret;
2667 *flags = 0;
2668 if (find_data.slot_flags & CKF_HW_SLOT)
2669 *flags |= GNUTLS_PKCS11_TOKEN_HW;
2671 return 0;
2677 * gnutls_pkcs11_token_get_mechanism:
2678 * @url: should contain a PKCS 11 URL
2679 * @idx: The index of the mechanism
2680 * @mechanism: The PKCS #11 mechanism ID
2682 * This function will return the names of the supported mechanisms
2683 * by the token. It should be called with an increasing index until
2684 * it return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.
2686 * Returns: zero on success or a negative value on error.
2689 gnutls_pkcs11_token_get_mechanism (const char *url, int idx,
2690 unsigned long *mechanism)
2692 int ret;
2693 ck_rv_t rv;
2694 struct ck_function_list *module;
2695 ck_slot_id_t slot;
2696 struct token_info tinfo;
2697 struct p11_kit_uri *info = NULL;
2698 unsigned long count;
2699 ck_mechanism_type_t mlist[400];
2701 ret = pkcs11_url_to_info (url, &info);
2702 if (ret < 0)
2704 gnutls_assert ();
2705 return ret;
2709 ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
2710 p11_kit_uri_free (info);
2712 if (ret < 0)
2714 gnutls_assert ();
2715 return ret;
2718 count = sizeof (mlist) / sizeof (mlist[0]);
2719 rv = pkcs11_get_mechanism_list (module, slot, mlist, &count);
2720 if (rv != CKR_OK)
2722 gnutls_assert ();
2723 return pkcs11_rv_to_err (rv);
2726 if (idx >= count)
2728 gnutls_assert ();
2729 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2732 *mechanism = mlist[idx];
2734 return 0;
2739 const char *
2740 gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t type)
2742 switch (type)
2744 case GNUTLS_PKCS11_OBJ_X509_CRT:
2745 return "X.509 Certificate";
2746 case GNUTLS_PKCS11_OBJ_PUBKEY:
2747 return "Public key";
2748 case GNUTLS_PKCS11_OBJ_PRIVKEY:
2749 return "Private key";
2750 case GNUTLS_PKCS11_OBJ_SECRET_KEY:
2751 return "Secret key";
2752 case GNUTLS_PKCS11_OBJ_DATA:
2753 return "Data";
2754 case GNUTLS_PKCS11_OBJ_UNKNOWN:
2755 default:
2756 return "Unknown";
2760 ck_rv_t
2761 pkcs11_get_slot_list (struct ck_function_list * module, unsigned char token_present,
2762 ck_slot_id_t *slot_list, unsigned long *count)
2764 return (module)->C_GetSlotList (token_present, slot_list, count);
2767 ck_rv_t
2768 pkcs11_get_module_info (struct ck_function_list * module,
2769 struct ck_info * info)
2771 return (module)->C_GetInfo (info);
2774 ck_rv_t
2775 pkcs11_get_slot_info(struct ck_function_list * module,
2776 ck_slot_id_t slot_id,
2777 struct ck_slot_info *info)
2779 return (module)->C_GetSlotInfo (slot_id, info);
2782 ck_rv_t
2783 pkcs11_get_token_info (struct ck_function_list * module,
2784 ck_slot_id_t slot_id,
2785 struct ck_token_info *info)
2787 return (module)->C_GetTokenInfo (slot_id, info);
2790 ck_rv_t
2791 pkcs11_find_objects_init (struct ck_function_list *module,
2792 ck_session_handle_t sess,
2793 struct ck_attribute *templ,
2794 unsigned long count)
2796 return (module)->C_FindObjectsInit (sess, templ, count);
2799 ck_rv_t
2800 pkcs11_find_objects (struct ck_function_list *module,
2801 ck_session_handle_t sess,
2802 ck_object_handle_t *objects,
2803 unsigned long max_object_count,
2804 unsigned long *object_count)
2806 return (module)->C_FindObjects (sess, objects, max_object_count, object_count);
2809 ck_rv_t
2810 pkcs11_find_objects_final (struct ck_function_list *module,
2811 ck_session_handle_t sess)
2813 return (module)->C_FindObjectsFinal (sess);
2816 ck_rv_t
2817 pkcs11_close_session (struct ck_function_list *module,
2818 ck_session_handle_t sess)
2820 return (module)->C_CloseSession (sess);
2823 ck_rv_t
2824 pkcs11_get_attribute_value(struct ck_function_list *module,
2825 ck_session_handle_t sess,
2826 ck_object_handle_t object,
2827 struct ck_attribute *templ,
2828 unsigned long count)
2830 return (module)->C_GetAttributeValue (sess, object, templ, count);
2833 ck_rv_t
2834 pkcs11_get_mechanism_list (struct ck_function_list *module,
2835 ck_slot_id_t slot_id,
2836 ck_mechanism_type_t *mechanism_list,
2837 unsigned long *count)
2839 return (module)->C_GetMechanismList (slot_id, mechanism_list, count);
2842 ck_rv_t
2843 pkcs11_sign_init (struct ck_function_list *module,
2844 ck_session_handle_t sess,
2845 struct ck_mechanism *mechanism,
2846 ck_object_handle_t key)
2848 return (module)->C_SignInit (sess, mechanism, key);
2851 ck_rv_t
2852 pkcs11_sign (struct ck_function_list *module,
2853 ck_session_handle_t sess,
2854 unsigned char *data,
2855 unsigned long data_len,
2856 unsigned char *signature,
2857 unsigned long *signature_len)
2859 return (module)->C_Sign (sess, data, data_len, signature, signature_len);
2862 ck_rv_t
2863 pkcs11_decrypt_init (struct ck_function_list *module,
2864 ck_session_handle_t sess,
2865 struct ck_mechanism *mechanism,
2866 ck_object_handle_t key)
2868 return (module)->C_DecryptInit (sess, mechanism, key);
2871 ck_rv_t
2872 pkcs11_decrypt (struct ck_function_list *module,
2873 ck_session_handle_t sess,
2874 unsigned char *encrypted_data,
2875 unsigned long encrypted_data_len,
2876 unsigned char *data, unsigned long *data_len)
2878 return (module)->C_Decrypt (sess, encrypted_data, encrypted_data_len,
2879 data, data_len);
2882 ck_rv_t
2883 pkcs11_create_object (struct ck_function_list *module,
2884 ck_session_handle_t sess,
2885 struct ck_attribute *templ,
2886 unsigned long count,
2887 ck_object_handle_t *object)
2889 return (module)->C_CreateObject (sess, templ, count, object);
2892 ck_rv_t
2893 pkcs11_destroy_object (struct ck_function_list *module,
2894 ck_session_handle_t sess,
2895 ck_object_handle_t object)
2897 return (module)->C_DestroyObject (sess, object);
2900 ck_rv_t
2901 pkcs11_init_token (struct ck_function_list *module,
2902 ck_slot_id_t slot_id, unsigned char *pin,
2903 unsigned long pin_len, unsigned char *label)
2905 return (module)->C_InitToken (slot_id, pin, pin_len, label);
2908 ck_rv_t
2909 pkcs11_init_pin (struct ck_function_list *module,
2910 ck_session_handle_t sess,
2911 unsigned char *pin,
2912 unsigned long pin_len)
2914 return (module)->C_InitPIN (sess, pin, pin_len);
2917 ck_rv_t
2918 pkcs11_set_pin (struct ck_function_list *module,
2919 ck_session_handle_t sess,
2920 unsigned char *old_pin,
2921 unsigned long old_len,
2922 unsigned char *new_pin,
2923 unsigned long new_len)
2925 return (module)->C_SetPIN (sess, old_pin, old_len, new_pin, new_len);
2928 const char *
2929 pkcs11_strerror (ck_rv_t rv)
2931 return p11_kit_strerror (rv);