2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010-2012 Free Software Foundation, Inc.
4 * Copyright (C) 2008, Joe Orton <joe@manyfish.co.uk>
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
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>
30 #include <gnutls_errors.h>
31 #include <gnutls_datum.h>
34 #include <pkcs11_int.h>
35 #include <p11-kit/p11-kit.h>
36 #include <p11-kit/pin.h>
38 #define MAX_PROVIDERS 16
40 /* XXX: try to eliminate this */
41 #define MAX_CERT_SIZE 8*1024
43 struct gnutls_pkcs11_provider_s
45 struct ck_function_list
*module
;
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
;
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
;
81 pkcs11_rv_to_err (ck_rv_t rv
)
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
:
96 case CKR_FUNCTION_NOT_PARALLEL
:
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
:
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
;
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
;
163 return GNUTLS_E_PKCS11_ERROR
;
169 pkcs11_rescan_slots (void)
173 pkcs11_get_slot_list (providers
[active_providers
- 1].module
, 0,
178 pkcs11_add_module (const char *name
, struct ck_function_list
*module
)
183 if (active_providers
>= MAX_PROVIDERS
)
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
;
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
)
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
)
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
)
229 gnutls_free (providers
[active_providers
- 1].slots
);
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
);
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.
261 gnutls_pkcs11_add_provider (const char *name
, const char *params
)
263 struct ck_function_list
*module
;
267 if (p11_kit_load_initialize_module (name
, &module
) != CKR_OK
)
270 _gnutls_debug_log ("p11: Cannot load provider %s\n", name
);
272 return GNUTLS_E_PKCS11_LOAD_ERROR
;
275 ret
= pkcs11_add_module (name
, module
);
278 /* Mark this one as having been separately initialized */
279 providers
[active_providers
- 1].initialized
= 1;
283 if (ret
== GNUTLS_E_INT_RET_0
) ret
= 0;
284 p11_kit_finalize_module (module
);
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.
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
;
328 const char *data
= NULL
;
332 * Either attr, str or version is valid by the time switch
338 case GNUTLS_PKCS11_OBJ_ID
:
339 attr
= p11_kit_uri_get_attribute (info
, CKA_ID
);
341 case GNUTLS_PKCS11_OBJ_ID_HEX
:
342 attr
= p11_kit_uri_get_attribute (info
, CKA_ID
);
346 case GNUTLS_PKCS11_OBJ_LABEL
:
347 attr
= p11_kit_uri_get_attribute (info
, CKA_LABEL
);
350 case GNUTLS_PKCS11_OBJ_TOKEN_LABEL
:
351 str
= p11_kit_uri_get_token_info (info
)->label
;
354 case GNUTLS_PKCS11_OBJ_TOKEN_SERIAL
:
355 str
= p11_kit_uri_get_token_info (info
)->serial_number
;
358 case GNUTLS_PKCS11_OBJ_TOKEN_MANUFACTURER
:
359 str
= p11_kit_uri_get_token_info (info
)->manufacturer_id
;
362 case GNUTLS_PKCS11_OBJ_TOKEN_MODEL
:
363 str
= p11_kit_uri_get_token_info (info
)->model
;
366 case GNUTLS_PKCS11_OBJ_LIBRARY_DESCRIPTION
:
367 str
= p11_kit_uri_get_module_info (info
)->library_description
;
370 case GNUTLS_PKCS11_OBJ_LIBRARY_VERSION
:
371 version
= &p11_kit_uri_get_module_info (info
)->library_version
;
373 case GNUTLS_PKCS11_OBJ_LIBRARY_MANUFACTURER
:
374 str
= p11_kit_uri_get_module_info (info
)->manufacturer_id
;
379 return GNUTLS_E_INVALID_REQUEST
;
385 length
= attr
->value_len
;
387 else if (str
!= NULL
)
390 length
= p11_kit_space_strlen (str
, str_max
);
393 else if (version
!= NULL
)
396 length
= snprintf (buf
, sizeof (buf
), "%d.%d", (int)version
->major
,
397 (int)version
->minor
);
403 if (output
) ((uint8_t*)output
)[0] = 0;
409 /* terminate is assumed with hexify */
410 if (*output_size
< length
* 3)
412 *output_size
= length
* 3;
413 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
416 _gnutls_bin2hex (data
, length
, output
, *output_size
, ":");
417 *output_size
= length
* 3;
422 if (*output_size
< length
+ terminate
)
424 *output_size
= length
+ terminate
;
425 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
429 memcpy (output
, data
, length
);
431 ((unsigned char*)output
)[length
] = '\0';
433 *output_size
= length
+ terminate
;
441 /* tries to load modules from /etc/gnutls/pkcs11.conf if it exists
443 static void _pkcs11_compat_init(const char* configfile
)
450 if (configfile
== NULL
)
451 configfile
= "/etc/gnutls/pkcs11.conf";
453 fp
= fopen (configfile
, "r");
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)
466 p
= strchr (line
, '=');
471 p
= strchr (line
, '\n');
475 ret
= gnutls_pkcs11_add_provider (library
, NULL
);
479 _gnutls_debug_log ("Cannot load provider: %s\n", library
);
490 initialize_automatic_p11_kit (void)
492 struct ck_function_list
**modules
;
497 rv
= p11_kit_initialize_registered ();
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
)
516 _gnutls_debug_log ("Cannot add registered module: %s\n", name
);
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
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.
546 gnutls_pkcs11_init (unsigned int flags
, const char *deprecated_config_file
)
557 p11_kit_pin_register_callback (P11_KIT_PIN_FALLBACK
, p11_kit_pin_file_callback
,
560 if (flags
== GNUTLS_PKCS11_FLAG_MANUAL
)
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
);
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.
587 int gnutls_pkcs11_reinit (void)
591 rv
= p11_kit_initialize_registered ();
595 _gnutls_debug_log ("Cannot initialize registered module: %s\n",
596 p11_kit_strerror (rv
));
597 return GNUTLS_E_INTERNAL_ERROR
;
604 * gnutls_pkcs11_deinit:
606 * This function will deinitialize the PKCS 11 subsystem in gnutls.
611 gnutls_pkcs11_deinit (void)
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.
650 gnutls_pkcs11_set_token_function (gnutls_pkcs11_token_callback_t fn
,
653 _gnutls_token_func
= fn
;
654 _gnutls_token_data
= userdata
;
658 pkcs11_url_to_info (const char *url
, struct p11_kit_uri
**info
)
665 *info
= p11_kit_uri_new ();
669 return GNUTLS_E_MEMORY_ERROR
;
674 ret
= p11_kit_uri_parse (url
, P11_KIT_URI_FOR_ANY
, *info
);
679 p11_kit_uri_free (*info
);
683 return ret
== P11_KIT_URI_NO_MEMORY
?
684 GNUTLS_E_MEMORY_ERROR
: GNUTLS_E_PARSING_ERROR
;
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;
699 case GNUTLS_PKCS11_URL_GENERIC
:
700 type
= P11_KIT_URI_FOR_OBJECT_ON_TOKEN
;
702 case GNUTLS_PKCS11_URL_LIB
:
703 type
= P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE
;
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
;
710 ret
= p11_kit_uri_format (info
, type
, url
);
714 return ret
== P11_KIT_URI_NO_MEMORY
?
715 GNUTLS_E_MEMORY_ERROR
: GNUTLS_E_INTERNAL_ERROR
;
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.
733 gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t
* obj
)
735 *obj
= gnutls_calloc (1, sizeof (struct gnutls_pkcs11_obj_st
));
739 return GNUTLS_E_MEMORY_ERROR
;
742 (*obj
)->info
= p11_kit_uri_new ();
743 if ((*obj
)->info
== NULL
)
747 return GNUTLS_E_MEMORY_ERROR
;
754 * gnutls_pkcs11_obj_set_pin_function:
755 * @obj: The object structure
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().
766 gnutls_pkcs11_obj_set_pin_function (gnutls_pkcs11_obj_t obj
,
767 gnutls_pin_callback_t 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.
783 gnutls_pkcs11_obj_deinit (gnutls_pkcs11_obj_t obj
)
785 _gnutls_free_datum (&obj
->raw
);
786 p11_kit_uri_free (obj
->info
);
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
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
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.
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
)
820 return GNUTLS_E_INVALID_REQUEST
;
823 if (output_data
== NULL
|| *output_data_size
< obj
->raw
.size
)
825 *output_data_size
= obj
->raw
.size
;
827 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
829 *output_data_size
= obj
->raw
.size
;
831 memcpy (output_data
, obj
->raw
.data
, obj
->raw
.size
);
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
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.
855 gnutls_pkcs11_obj_export2 (gnutls_pkcs11_obj_t obj
,
858 if (obj
== NULL
|| obj
->raw
.data
== NULL
)
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
)
874 ck_object_handle_t obj
;
875 struct ck_attribute
*attrs
;
876 unsigned long attr_count
;
880 ret
= pkcs11_open_session (sinfo
, pin_info
, info
, flags
& SESSION_LOGIN
);
887 attrs
= p11_kit_uri_get_attributes (info
, &attr_count
);
888 rv
= pkcs11_find_objects_init (sinfo
->module
, sinfo
->pks
, attrs
, attr_count
);
892 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
893 ret
= pkcs11_rv_to_err (rv
);
897 if (pkcs11_find_objects (sinfo
->module
, sinfo
->pks
, &obj
, 1, &count
) == CKR_OK
&& count
== 1)
900 pkcs11_find_objects_final (sinfo
);
904 ret
= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
905 pkcs11_find_objects_final (sinfo
);
907 pkcs11_close_session (sinfo
);
913 pkcs11_find_slot (struct ck_function_list
** module
, ck_slot_id_t
* slot
,
914 struct p11_kit_uri
*info
, struct token_info
*_tinfo
)
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
)
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
)
940 if (!p11_kit_uri_match_token_info (info
, &tinfo
.tinfo
) ||
941 !p11_kit_uri_match_module_info (info
, &providers
[x
].info
))
947 *module
= providers
[x
].module
;
948 *slot
= providers
[x
].slots
[z
];
951 memcpy (_tinfo
, &tinfo
, sizeof (tinfo
));
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
,
969 ck_session_handle_t pks
= 0;
970 struct ck_function_list
*module
;
972 struct token_info tinfo
;
974 ret
= pkcs11_find_slot (&module
, &slot
, info
, &tinfo
);
981 rv
= (module
)->C_OpenSession (slot
,
982 ((flags
& SESSION_WRITE
)
983 ? CKF_RW_SESSION
: 0) |
984 CKF_SERIAL_SESSION
, NULL
, NULL
, &pks
);
988 return pkcs11_rv_to_err (rv
);
993 sinfo
->module
= module
;
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);
1003 pkcs11_close_session (sinfo
);
1013 _pkcs11_traverse_tokens (find_func_t find_func
, void *input
,
1014 struct p11_kit_uri
*info
,
1015 struct pin_info_st
*pin_info
,
1019 unsigned int found
= 0, x
, z
;
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
)
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
)
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
);
1055 sinfo
.module
= module
;
1058 if (flags
& SESSION_LOGIN
)
1060 ret
= pkcs11_login (&sinfo
, pin_info
, &tinfo
, info
, (flags
& SESSION_SO
) ? 1 : 0);
1068 ret
= find_func (&sinfo
, &tinfo
, &providers
[x
].info
, input
);
1077 pkcs11_close_session (&sinfo
);
1090 sinfo
.module
= module
;
1092 ret
= find_func (&sinfo
, NULL
, NULL
, input
);
1095 ret
= gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
);
1102 if (pks
!= 0 && module
!= NULL
)
1104 pkcs11_close_session (&sinfo
);
1110 /* imports a raw certificate from a token to a pkcs11_obj_t structure.
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
;
1124 case CKO_CERTIFICATE
:
1125 obj
->type
= GNUTLS_PKCS11_OBJ_X509_CRT
;
1127 case CKO_PUBLIC_KEY
:
1128 obj
->type
= GNUTLS_PKCS11_OBJ_PUBKEY
;
1130 case CKO_PRIVATE_KEY
:
1131 obj
->type
= GNUTLS_PKCS11_OBJ_PRIVKEY
;
1133 case CKO_SECRET_KEY
:
1134 obj
->type
= GNUTLS_PKCS11_OBJ_SECRET_KEY
;
1137 obj
->type
= GNUTLS_PKCS11_OBJ_DATA
;
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
);
1150 return GNUTLS_E_MEMORY_ERROR
;
1153 if (data
&& data
->data
)
1155 ret
= _gnutls_set_datum (&obj
->raw
, data
->data
, data
->size
);
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
);
1176 return GNUTLS_E_MEMORY_ERROR
;
1183 attr
.value
= id
->data
;
1184 attr
.value_len
= id
->size
;
1185 ret
= p11_kit_uri_set_attribute (obj
->info
, &attr
);
1189 return GNUTLS_E_MEMORY_ERROR
;
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];
1208 a
[0].type
= CKA_MODULUS
;
1210 a
[0].value_len
= sizeof (tmp1
);
1211 a
[1].type
= CKA_PUBLIC_EXPONENT
;
1213 a
[1].value_len
= sizeof (tmp2
);
1215 if (pkcs11_get_attribute_value (module
, pks
, obj
, a
, 2) == CKR_OK
)
1219 _gnutls_set_datum (&pubkey
[0],
1220 a
[0].value
, a
[0].value_len
);
1224 _gnutls_set_datum (&pubkey
1225 [1], a
[1].value
, a
[1].value_len
);
1230 _gnutls_free_datum (&pubkey
[1]);
1231 _gnutls_free_datum (&pubkey
[0]);
1232 return GNUTLS_E_MEMORY_ERROR
;
1238 return GNUTLS_E_PKCS11_ERROR
;
1242 a
[0].type
= CKA_PRIME
;
1244 a
[0].value_len
= sizeof (tmp1
);
1245 a
[1].type
= CKA_SUBPRIME
;
1247 a
[1].value_len
= sizeof (tmp2
);
1249 if (pkcs11_get_attribute_value (module
, pks
, obj
, a
, 2) == CKR_OK
)
1252 _gnutls_set_datum (&pubkey
[0],
1253 a
[0].value
, a
[0].value_len
);
1257 _gnutls_set_datum (&pubkey
1258 [1], a
[1].value
, a
[1].value_len
);
1263 _gnutls_free_datum (&pubkey
[1]);
1264 _gnutls_free_datum (&pubkey
[0]);
1265 return GNUTLS_E_MEMORY_ERROR
;
1271 return GNUTLS_E_PKCS11_ERROR
;
1274 a
[0].type
= CKA_BASE
;
1276 a
[0].value_len
= sizeof (tmp1
);
1277 a
[1].type
= CKA_VALUE
;
1279 a
[1].value_len
= sizeof (tmp2
);
1281 if (pkcs11_get_attribute_value (module
, pks
, obj
, a
, 2) == CKR_OK
)
1284 _gnutls_set_datum (&pubkey
[2],
1285 a
[0].value
, a
[0].value_len
);
1289 _gnutls_set_datum (&pubkey
1290 [3], a
[1].value
, a
[1].value_len
);
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
;
1305 return GNUTLS_E_PKCS11_ERROR
;
1309 a
[0].type
= CKA_EC_PARAMS
;
1311 a
[0].value_len
= sizeof (tmp1
);
1312 a
[1].type
= CKA_EC_POINT
;
1314 a
[1].value_len
= sizeof (tmp2
);
1316 if (pkcs11_get_attribute_value (module
, pks
, obj
, a
, 2) == CKR_OK
)
1319 _gnutls_set_datum (&pubkey
[0],
1320 a
[0].value
, a
[0].value_len
);
1324 _gnutls_set_datum (&pubkey
1325 [1], a
[1].value
, a
[1].value_len
);
1330 _gnutls_free_datum (&pubkey
[1]);
1331 _gnutls_free_datum (&pubkey
[0]);
1332 return GNUTLS_E_MEMORY_ERROR
;
1338 return GNUTLS_E_PKCS11_ERROR
;
1343 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE
);
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
;
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
);
1374 return gnutls_assert_val(ret
);
1377 /* read key usage flags */
1378 a
[0].type
= CKA_ENCRYPT
;
1380 a
[0].value_len
= sizeof (tval
);
1382 if (pkcs11_get_attribute_value (module
, pks
, obj
, a
, 1) == CKR_OK
)
1386 crt
->key_usage
|= GNUTLS_KEY_DATA_ENCIPHERMENT
;
1390 a
[0].type
= CKA_VERIFY
;
1392 a
[0].value_len
= sizeof (tval
);
1394 if (pkcs11_get_attribute_value (module
, pks
, obj
, a
, 1) == CKR_OK
)
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
;
1406 a
[0].value_len
= sizeof (tval
);
1408 if (pkcs11_get_attribute_value (module
, pks
, obj
, a
, 1) == CKR_OK
)
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
;
1420 a
[0].value_len
= sizeof (tval
);
1422 if (pkcs11_get_attribute_value (module
, pks
, obj
, a
, 1) == CKR_OK
)
1426 crt
->key_usage
|= GNUTLS_KEY_KEY_AGREEMENT
;
1430 a
[0].type
= CKA_WRAP
;
1432 a
[0].value_len
= sizeof (tval
);
1434 if (pkcs11_get_attribute_value (module
, pks
, obj
, a
, 1) == CKR_OK
)
1438 crt
->key_usage
|= GNUTLS_KEY_KEY_ENCIPHERMENT
;
1442 return pkcs11_obj_import (CKO_PUBLIC_KEY
, crt
, NULL
, id
, label
,
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;
1456 ck_object_handle_t obj
;
1457 unsigned long count
, a_vals
;
1459 uint8_t *cert_data
= NULL
;
1460 char label_tmp
[PKCS11_LABEL_SIZE
];
1461 char id_tmp
[PKCS11_ID_SIZE
];
1464 { /* we don't support multiple calls */
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
))
1475 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1479 attr
= p11_kit_uri_get_attribute (find_data
->crt
->info
, CKA_ID
);
1482 memcpy (a
+ a_vals
, attr
, sizeof (struct ck_attribute
));
1486 attr
= p11_kit_uri_get_attribute (find_data
->crt
->info
, CKA_LABEL
);
1489 memcpy (a
+ a_vals
, attr
, sizeof (struct ck_attribute
));
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
)
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
);
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
)
1516 memcpy (a
+ a_vals
, attr
, sizeof (struct ck_attribute
));
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
;
1528 rv
= pkcs11_find_objects_init (sinfo
->module
, sinfo
->pks
, a
, a_vals
);
1532 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
1533 ret
= pkcs11_rv_to_err (rv
);
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
);
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
)
1559 pkcs11_obj_import_pubkey (sinfo
->module
, sinfo
->pks
, obj
,
1562 &info
->tinfo
, lib_info
);
1567 pkcs11_obj_import (class,
1570 &info
->tinfo
, lib_info
);
1583 _gnutls_debug_log ("pk11: Skipped cert, missing attrs.\n");
1590 ret
= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1598 gnutls_free (cert_data
);
1599 pkcs11_find_objects_final (sinfo
);
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
;
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.
1634 gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t obj
, const char *url
,
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
);
1651 _pkcs11_traverse_tokens (find_obj_url
, &find_data
, obj
->info
,
1652 &obj
->pin
, pkcs11_obj_flags_to_int (flags
));
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 */
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
;
1678 { /* we don't support multiple calls */
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
));
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.
1713 gnutls_pkcs11_token_get_url (unsigned int seq
,
1714 gnutls_pkcs11_url_type_t detailed
, char **url
)
1717 struct token_num tn
;
1719 memset (&tn
, 0, sizeof (tn
));
1721 tn
.info
= p11_kit_uri_new ();
1723 ret
= _pkcs11_traverse_tokens (find_token_num
, &tn
, NULL
, NULL
, 0);
1726 p11_kit_uri_free (tn
.info
);
1731 ret
= pkcs11_info_to_url (tn
.info
, detailed
, url
);
1732 p11_kit_uri_free (tn
.info
);
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
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
;
1770 ret
= pkcs11_url_to_info (url
, &info
);
1779 case GNUTLS_PKCS11_TOKEN_LABEL
:
1780 str
= p11_kit_uri_get_token_info (info
)->label
;
1783 case GNUTLS_PKCS11_TOKEN_SERIAL
:
1784 str
= p11_kit_uri_get_token_info (info
)->serial_number
;
1787 case GNUTLS_PKCS11_TOKEN_MANUFACTURER
:
1788 str
= p11_kit_uri_get_token_info (info
)->manufacturer_id
;
1791 case GNUTLS_PKCS11_TOKEN_MODEL
:
1792 str
= p11_kit_uri_get_token_info (info
)->model
;
1796 p11_kit_uri_free (info
);
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';
1814 p11_kit_uri_free (info
);
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.
1832 gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t obj
,
1833 gnutls_pkcs11_url_type_t detailed
, char **url
)
1837 ret
= pkcs11_info_to_url (obj
->info
, detailed
, url
);
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.
1858 gnutls_pkcs11_obj_type_t
1859 gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t obj
)
1866 gnutls_buffer_st
*key_ids
;
1867 size_t key_ids_size
;
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
;
1880 label
= p11_kit_space_strdup (token_info
->label
, sizeof (token_info
->label
));
1884 return GNUTLS_E_MEMORY_ERROR
;
1887 token_uri
= p11_kit_uri_new ();
1888 if (token_uri
== NULL
)
1892 return GNUTLS_E_MEMORY_ERROR
;
1895 memcpy (p11_kit_uri_get_token_info (token_uri
), token_info
,
1896 sizeof (struct ck_token_info
));
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
);
1928 return GNUTLS_E_PKCS11_PIN_ERROR
;
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;
1945 struct p11_kit_uri
*token_uri
;
1948 label
= p11_kit_space_strdup (token_info
->label
, sizeof (token_info
->label
));
1952 return GNUTLS_E_MEMORY_ERROR
;
1955 token_uri
= p11_kit_uri_new ();
1956 if (token_uri
== NULL
)
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
);
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
;
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
);
2002 ret
= gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR
);
2008 return gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR
);
2010 *pin
= p11_kit_pin_new_for_string (pin_value
);
2013 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR
);
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
;
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 */
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
2046 _gnutls_debug_log ("pk11: No suitable pin callback but login required.\n");
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
;
2061 user_type
= (so
== 0) ? CKU_USER
: CKU_SO
;
2062 if (so
== 0 && (tokinfo
->tinfo
.flags
& CKF_LOGIN_REQUIRED
) == 0)
2065 _gnutls_debug_log ("pk11: No login required.\n");
2069 /* For a token with a "protected" (out-of-band) authentication
2070 * path, calling login with a NULL username is all that is
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
)
2082 _gnutls_debug_log ("pk11: Protected login failed.\n");
2083 ret
= GNUTLS_E_PKCS11_ERROR
;
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
))
2104 /* If login has been attempted once already, check the token
2105 * status again, the flags might change. */
2108 if (pkcs11_get_token_info
2109 (tokinfo
->prov
->module
, tokinfo
->sid
, &tinfo
) != CKR_OK
)
2112 _gnutls_debug_log ("pk11: GetTokenInfo failed\n");
2113 ret
= GNUTLS_E_PKCS11_ERROR
;
2118 ret
= retrieve_pin (pin_info
, info
, &tinfo
, attempt
++, user_type
, &pin
);
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
);
2137 || rv
== CKR_USER_ALREADY_LOGGED_IN
) ? 0 : pkcs11_rv_to_err (rv
);
2144 pkcs11_call_token_func (struct p11_kit_uri
*info
, const unsigned retry
)
2146 struct ck_token_info
*tinfo
;
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
);
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;
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);
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)
2197 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2201 gnutls_malloc (sizeof (gnutls_buffer_st
) * list
->key_ids_size
);
2202 if (list
->key_ids
== NULL
)
2205 return GNUTLS_E_MEMORY_ERROR
;
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);
2217 return pkcs11_rv_to_err (rv
);
2221 while (pkcs11_find_objects (sinfo
->module
, sinfo
->pks
, &obj
, 1, &count
) == CKR_OK
&& count
== 1)
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
);
2237 if (current
> list
->key_ids_size
)
2241 pkcs11_find_objects_final (sinfo
);
2243 list
->key_ids_size
= current
- 1;
2248 /* Recover certificate list from tokens */
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
;
2262 ck_object_handle_t obj
;
2263 unsigned long count
;
2265 char certid_tmp
[PKCS11_ID_SIZE
];
2266 char label_tmp
[PKCS11_LABEL_SIZE
];
2268 struct pkey_list plist
; /* private key holder */
2269 unsigned int i
, tot_values
= 0;
2273 if (find_data
->current
<= *find_data
->n_list
)
2276 ret
= GNUTLS_E_SHORT_MEMORY_BUFFER
;
2278 *find_data
->n_list
= find_data
->current
;
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
))
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
);
2303 if (plist
.key_ids_size
== 0)
2306 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2310 cert_data
= gnutls_malloc (MAX_CERT_SIZE
);
2311 if (cert_data
== NULL
)
2314 return GNUTLS_E_MEMORY_ERROR
;
2317 /* Find objects with cert class and X.509 cert type. */
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
;
2328 a
[tot_values
].type
= CKA_CLASS
;
2329 a
[tot_values
].value
= &class;
2330 a
[tot_values
].value_len
= sizeof class;
2333 a
[tot_values
].type
= CKA_CERTIFICATE_TYPE
;
2334 a
[tot_values
].value
= &type
;
2335 a
[tot_values
].value_len
= sizeof type
;
2339 else if (find_data
->flags
== GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED
)
2341 class = CKO_CERTIFICATE
;
2345 a
[tot_values
].type
= CKA_CLASS
;
2346 a
[tot_values
].value
= &class;
2347 a
[tot_values
].value_len
= sizeof class;
2350 a
[tot_values
].type
= CKA_TRUSTED
;
2351 a
[tot_values
].value
= &trusted
;
2352 a
[tot_values
].value_len
= sizeof trusted
;
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;
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;
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;
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
;
2394 ret
= GNUTLS_E_INVALID_REQUEST
;
2398 attr
= p11_kit_uri_get_attribute (find_data
->info
, CKA_ID
);
2401 memcpy (a
+ tot_values
, attr
, sizeof (struct ck_attribute
));
2405 rv
= pkcs11_find_objects_init (sinfo
->module
, sinfo
->pks
, a
, tot_values
);
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
;
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
;
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
;
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
!=
2476 || memcmp (plist
.key_ids
[i
].data
,
2477 a
[1].value
, a
[1].value_len
) != 0)
2485 if (find_data
->current
< *find_data
->n_list
)
2488 gnutls_pkcs11_obj_init (&find_data
->p_list
[find_data
->current
]);
2495 if (class == CKO_PUBLIC_KEY
)
2498 pkcs11_obj_import_pubkey (sinfo
->module
, sinfo
->pks
, obj
,
2500 [find_data
->current
],
2502 &info
->tinfo
, lib_info
);
2507 pkcs11_obj_import (class,
2509 [find_data
->current
],
2510 &value
, &id
, &label
,
2511 &info
->tinfo
, lib_info
);
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 */
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;
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.
2566 gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t
* p_list
,
2567 unsigned int *n_list
,
2569 gnutls_pkcs11_obj_attr_t attrs
,
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)
2588 ret
= pkcs11_url_to_info (url
, &find_data
.info
);
2596 _pkcs11_traverse_tokens (find_objs
, &find_data
, find_data
.info
,
2598 pkcs11_obj_flags_to_int (flags
));
2599 p11_kit_uri_free (find_data
.info
);
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.
2628 gnutls_pkcs11_obj_list_import_url2 (gnutls_pkcs11_obj_t
** p_list
,
2629 unsigned int *n_list
,
2631 gnutls_pkcs11_obj_attr_t attrs
,
2634 unsigned int init
= 1024;
2637 *p_list
= gnutls_malloc(sizeof(gnutls_pkcs11_obj_t
)*init
);
2638 if (*p_list
== NULL
)
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
);
2657 gnutls_free(*p_list
);
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.
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
;
2689 ret
= gnutls_pkcs11_obj_init (&pcrt
);
2697 gnutls_pkcs11_obj_set_pin_function (pcrt
, crt
->pin
.cb
, crt
->pin
.data
);
2699 ret
= gnutls_pkcs11_obj_import_url (pcrt
, url
, flags
);
2706 ret
= gnutls_x509_crt_import (crt
, &pcrt
->raw
, GNUTLS_X509_FMT_DER
);
2716 gnutls_pkcs11_obj_deinit (pcrt
);
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
2729 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2730 * negative error value.
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
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.
2757 gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t
* certs
,
2758 unsigned int cert_max
,
2759 gnutls_pkcs11_obj_t
* const objs
,
2765 for (i
= 0; i
< cert_max
; i
++)
2767 ret
= gnutls_x509_crt_init (&certs
[i
]);
2774 ret
= gnutls_x509_crt_import_pkcs11 (certs
[i
], objs
[i
]);
2785 for (j
= 0; j
< i
; j
++)
2787 gnutls_x509_crt_deinit (certs
[j
]);
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
;
2800 { /* we don't support multiple calls */
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
))
2811 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2816 find_data
->slot_flags
= info
->sinfo
.flags
;
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.
2834 gnutls_pkcs11_token_get_flags (const char *url
, unsigned int *flags
)
2836 struct flags_find_data_st find_data
;
2839 memset (&find_data
, 0, sizeof (find_data
));
2840 ret
= pkcs11_url_to_info (url
, &find_data
.info
);
2847 ret
= _pkcs11_traverse_tokens (find_flags
, &find_data
, find_data
.info
, NULL
, 0);
2848 p11_kit_uri_free (find_data
.info
);
2857 if (find_data
.slot_flags
& CKF_HW_SLOT
)
2858 *flags
|= GNUTLS_PKCS11_TOKEN_HW
;
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.
2879 gnutls_pkcs11_token_get_mechanism (const char *url
, unsigned int idx
,
2880 unsigned long *mechanism
)
2884 struct ck_function_list
*module
;
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
);
2899 ret
= pkcs11_find_slot (&module
, &slot
, info
, &tinfo
);
2900 p11_kit_uri_free (info
);
2908 count
= sizeof (mlist
) / sizeof (mlist
[0]);
2909 rv
= pkcs11_get_mechanism_list (module
, slot
, mlist
, &count
);
2913 return pkcs11_rv_to_err (rv
);
2919 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2922 *mechanism
= mlist
[idx
];
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
2936 * Returns: human readable string labeling the PKCS11 object type
2942 gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t 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
:
2956 case GNUTLS_PKCS11_OBJ_UNKNOWN
:
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
);
2970 pkcs11_get_module_info (struct ck_function_list
* module
,
2971 struct ck_info
* info
)
2973 return (module
)->C_GetInfo (info
);
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
);
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
);
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
);
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
);
3012 pkcs11_find_objects_final (struct pkcs11_session_info
* sinfo
)
3014 return (sinfo
->module
)->C_FindObjectsFinal (sinfo
->pks
);
3018 pkcs11_close_session (struct pkcs11_session_info
* sinfo
)
3021 return (sinfo
->module
)->C_CloseSession (sinfo
->pks
);
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
);
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
);
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
);
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
);
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
);
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
);
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
,
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
);
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
);
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
);
3125 pkcs11_init_pin (struct ck_function_list
*module
,
3126 ck_session_handle_t sess
,
3128 unsigned long pin_len
)
3130 return (module
)->C_InitPIN (sess
, pin
, pin_len
);
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
);
3145 pkcs11_strerror (ck_rv_t rv
)
3147 return p11_kit_strerror (rv
);