2
* GnuTLS PKCS#11 support
3
* Copyright (C) 2010 Free Software Foundation
4
* Copyright (C) 2008, Joe Orton <joe@manyfish.co.uk>
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
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,
28
#include <gnutls_int.h>
29
#include <gnutls/pkcs11.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>
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;
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;
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;
85
pkcs11_rv_to_err (ck_rv_t rv)
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:
100
case CKR_FUNCTION_NOT_PARALLEL:
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:
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;
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;
167
return GNUTLS_E_PKCS11_ERROR;
173
pkcs11_rescan_slots (void)
177
pkcs11_get_slot_list (providers[active_providers - 1].module, 0,
182
pkcs11_add_module (const char *name, struct ck_function_list *module)
187
if (active_providers >= MAX_PROVIDERS)
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);
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)
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)
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)
233
gnutls_free (providers[active_providers - 1].slots);
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);
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;
269
if (p11_kit_load_initialize_module (name, &module) != CKR_OK)
272
_gnutls_debug_log ("p11: Cannot load provider %s\n", name);
274
return GNUTLS_E_PKCS11_LOAD_ERROR;
277
ret = pkcs11_add_module (name, module);
280
/* Mark this one as having been separately initialized */
281
providers[active_providers - 1].initialized = 1;
285
p11_kit_finalize_module (module);
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;
327
const char *data = NULL;
331
* Either attr, str or version is valid by the time switch
337
case GNUTLS_PKCS11_OBJ_ID:
338
attr = p11_kit_uri_get_attribute (info, CKA_ID);
340
case GNUTLS_PKCS11_OBJ_ID_HEX:
341
attr = p11_kit_uri_get_attribute (info, CKA_ID);
345
case GNUTLS_PKCS11_OBJ_LABEL:
346
attr = p11_kit_uri_get_attribute (info, CKA_LABEL);
349
case GNUTLS_PKCS11_OBJ_TOKEN_LABEL:
350
str = p11_kit_uri_get_token_info (info)->label;
353
case GNUTLS_PKCS11_OBJ_TOKEN_SERIAL:
354
str = p11_kit_uri_get_token_info (info)->serial_number;
357
case GNUTLS_PKCS11_OBJ_TOKEN_MANUFACTURER:
358
str = p11_kit_uri_get_token_info (info)->manufacturer_id;
361
case GNUTLS_PKCS11_OBJ_TOKEN_MODEL:
362
str = p11_kit_uri_get_token_info (info)->model;
365
case GNUTLS_PKCS11_OBJ_LIBRARY_DESCRIPTION:
366
str = p11_kit_uri_get_module_info (info)->library_description;
369
case GNUTLS_PKCS11_OBJ_LIBRARY_VERSION:
370
version = &p11_kit_uri_get_module_info (info)->library_version;
372
case GNUTLS_PKCS11_OBJ_LIBRARY_MANUFACTURER:
373
str = p11_kit_uri_get_module_info (info)->manufacturer_id;
378
return GNUTLS_E_INVALID_REQUEST;
384
length = attr->value_len;
386
else if (str != NULL)
389
length = p11_kit_space_strlen (str, str_max);
392
else if (version != NULL)
395
length = snprintf (buf, sizeof (buf), "%d.%d", (int)version->major,
396
(int)version->minor);
402
/* terminate is assumed with hexify */
403
if (*output_size < length * 3)
405
*output_size = length * 3;
406
return GNUTLS_E_SHORT_MEMORY_BUFFER;
409
_gnutls_bin2hex (data, length, output, *output_size, ":");
410
*output_size = length * 3;
415
if (*output_size < length + terminate)
417
*output_size = length + terminate;
418
return GNUTLS_E_SHORT_MEMORY_BUFFER;
422
memcpy (output, data, length);
424
((unsigned char*)output)[length] = '\0';
426
*output_size = length + terminate;
435
initialize_automatic_p11_kit (void)
437
struct ck_function_list **modules;
442
rv = p11_kit_initialize_registered ();
446
_gnutls_debug_log ("Cannot initialize registered module: %s\n",
447
p11_kit_strerror (rv));
448
return GNUTLS_E_INTERNAL_ERROR;
451
initialized_registered = 1;
453
modules = p11_kit_registered_modules ();
454
for (i = 0; modules[i] != NULL; i++)
456
name = p11_kit_registered_module_to_name (modules[i]);
457
ret = pkcs11_add_module (name, modules[i]);
461
_gnutls_debug_log ("Cannot add registered module: %s\n", name);
470
initialize_automatic_legacy (const char *configfile)
477
if (configfile == NULL)
478
configfile = "/etc/gnutls/pkcs11.conf";
480
fp = fopen (configfile, "r");
486
_gnutls_debug_log ("Cannot load %s\n", configfile);
487
return GNUTLS_E_FILE_ERROR;
490
while (fgets (line, sizeof (line), fp) != NULL)
492
if (strncmp (line, "load", sizeof ("load") - 1) == 0)
495
p = strchr (line, '=');
501
p = strchr (line, '\n');
507
ret = gnutls_pkcs11_add_provider (library, NULL);
511
_gnutls_debug_log ("Cannot load provider: %s\n", library);
522
* gnutls_pkcs11_init:
523
* @flags: %GNUTLS_PKCS11_FLAG_MANUAL or %GNUTLS_PKCS11_FLAG_AUTO
524
* @deprecated_config_file: either NULL or the location of a deprecated
527
* This function will initialize the PKCS 11 subsystem in gnutls. It will
528
* read configuration files if %GNUTLS_PKCS11_FLAG_AUTO is used or allow
529
* you to independently load PKCS 11 modules using gnutls_pkcs11_add_provider()
530
* if %GNUTLS_PKCS11_FLAG_MANUAL is specified.
532
* Using a custom configfile is deprecated and will not be supported in future
533
* versions of gnutls.
535
* Normally you don't need to call this function since it is being called
536
* by gnutls_global_init() using the %GNUTLS_PKCS11_FLAG_AUTO. If you need to
537
* call this function, you must call it before gnutls_global_init().
539
* Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
540
* negative error value.
543
gnutls_pkcs11_init (unsigned int flags, const char *deprecated_config_file)
554
if (flags == GNUTLS_PKCS11_FLAG_AUTO)
556
if (deprecated_config_file == NULL)
557
ret = initialize_automatic_p11_kit ();
560
ret = initialize_automatic_legacy (deprecated_config_file);
567
* gnutls_pkcs11_deinit:
569
* This function will deinitialize the PKCS 11 subsystem in gnutls.
573
gnutls_pkcs11_deinit (void)
586
for (i = 0; i < active_providers; i++)
588
if (providers[i].initialized)
589
p11_kit_finalize_module (providers[i].module);
591
active_providers = 0;
593
if (initialized_registered != 0)
594
p11_kit_finalize_registered ();
595
initialized_registered = 0;
599
* gnutls_pkcs11_set_pin_function:
600
* @fn: The PIN callback
601
* @userdata: data to be supplied to callback
603
* This function will set a callback function to be used when a PIN
604
* is required for PKCS 11 operations.
606
* Callback for PKCS#11 PIN entry. The callback provides the PIN code
607
* to unlock the token with label 'token_label', specified by the URL
610
* The PIN code, as a NUL-terminated ASCII string, should be copied
611
* into the 'pin' buffer (of maximum size pin_max), and
612
* return 0 to indicate success. Alternatively, the callback may
613
* return a negative gnutls error code to indicate failure and cancel
614
* PIN entry (in which case, the contents of the 'pin' parameter are ignored).
616
* When a PIN is required, the callback will be invoked repeatedly
617
* (and indefinitely) until either the returned PIN code is correct,
618
* the callback returns failure, or the token refuses login (e.g. when
619
* the token is locked due to too many incorrect PINs!). For the
620
* first such invocation, the 'attempt' counter will have value zero;
621
* it will increase by one for each subsequent attempt.
623
* Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
624
* negative error value.
627
gnutls_pkcs11_set_pin_function (gnutls_pkcs11_pin_callback_t fn,
635
* gnutls_pkcs11_set_token_function:
636
* @fn: The token callback
637
* @userdata: data to be supplied to callback
639
* This function will set a callback function to be used when a token
640
* needs to be inserted to continue PKCS 11 operations.
642
* Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
643
* negative error value.
646
gnutls_pkcs11_set_token_function (gnutls_pkcs11_token_callback_t fn,
650
token_data = userdata;
654
pkcs11_url_to_info (const char *url, struct p11_kit_uri **info)
661
*info = p11_kit_uri_new ();
665
return GNUTLS_E_MEMORY_ERROR;
670
ret = p11_kit_uri_parse (url, P11_KIT_URI_FOR_ANY, *info);
675
p11_kit_uri_free (*info);
679
return ret == P11_KIT_URI_NO_MEMORY ?
680
GNUTLS_E_MEMORY_ERROR : GNUTLS_E_PARSING_ERROR;
687
pkcs11_info_to_url (struct p11_kit_uri *info,
688
gnutls_pkcs11_url_type_t detailed, char **url)
690
p11_kit_uri_type_t type = 0;
695
case GNUTLS_PKCS11_URL_GENERIC:
696
type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN;
698
case GNUTLS_PKCS11_URL_LIB:
699
type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE;
701
case GNUTLS_PKCS11_URL_LIB_VERSION:
702
type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE | P11_KIT_URI_FOR_MODULE_WITH_VERSION;
706
ret = p11_kit_uri_format (info, type, url);
710
return ret == P11_KIT_URI_NO_MEMORY ?
711
GNUTLS_E_MEMORY_ERROR : GNUTLS_E_INTERNAL_ERROR;
718
* gnutls_pkcs11_obj_init:
719
* @obj: The structure to be initialized
721
* This function will initialize a pkcs11 certificate structure.
723
* Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
724
* negative error value.
727
gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t * obj)
729
*obj = gnutls_calloc (1, sizeof (struct gnutls_pkcs11_obj_st));
733
return GNUTLS_E_MEMORY_ERROR;
736
(*obj)->info = p11_kit_uri_new ();
737
if ((*obj)->info == NULL)
741
return GNUTLS_E_MEMORY_ERROR;
748
* gnutls_pkcs11_obj_deinit:
749
* @obj: The structure to be initialized
751
* This function will deinitialize a certificate structure.
754
gnutls_pkcs11_obj_deinit (gnutls_pkcs11_obj_t obj)
756
_gnutls_free_datum (&obj->raw);
757
p11_kit_uri_free (obj->info);
762
* gnutls_pkcs11_obj_export:
763
* @obj: Holds the object
764
* @output_data: will contain a certificate PEM or DER encoded
765
* @output_data_size: holds the size of output_data (and will be
766
* replaced by the actual size of parameters)
768
* This function will export the pkcs11 object data. It is normal
769
* for PKCS #11 data to be inaccesible and in that case %GNUTLS_E_INVALID_REQUEST
772
* If the buffer provided is not long enough to hold the output, then
773
* *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
776
* If the structure is PEM encoded, it will have a header
777
* of "BEGIN CERTIFICATE".
779
* Return value: In case of failure a negative value will be
780
* returned, and 0 on success.
783
gnutls_pkcs11_obj_export (gnutls_pkcs11_obj_t obj,
784
void *output_data, size_t * output_data_size)
786
if (obj == NULL || obj->raw.data == NULL)
789
return GNUTLS_E_INVALID_REQUEST;
792
if (output_data == NULL || *output_data_size < obj->raw.size)
794
*output_data_size = obj->raw.size;
796
return GNUTLS_E_SHORT_MEMORY_BUFFER;
798
*output_data_size = obj->raw.size;
800
memcpy (output_data, obj->raw.data, obj->raw.size);
805
pkcs11_find_object (struct ck_function_list ** _module,
806
ck_session_handle_t * _pks,
807
ck_object_handle_t * _obj,
808
struct p11_kit_uri *info, unsigned int flags)
811
struct ck_function_list *module;
812
ck_session_handle_t pks;
813
ck_object_handle_t obj;
814
struct ck_attribute *attrs;
815
unsigned long attr_count;
819
ret = pkcs11_open_session (&module, &pks, info, flags & SESSION_LOGIN);
826
attrs = p11_kit_uri_get_attributes (info, &attr_count);
827
rv = pkcs11_find_objects_init (module, pks, attrs, attr_count);
831
_gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
832
ret = pkcs11_rv_to_err (rv);
836
if (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
841
pkcs11_find_objects_final (module, pks);
845
ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
846
pkcs11_find_objects_final (module, pks);
848
pkcs11_close_session (module, pks);
854
pkcs11_find_slot (struct ck_function_list ** module, ck_slot_id_t * slot,
855
struct p11_kit_uri *info, struct token_info *_tinfo)
859
for (x = 0; x < active_providers; x++)
861
for (z = 0; z < providers[x].nslots; z++)
863
struct token_info tinfo;
865
if (pkcs11_get_token_info
866
(providers[x].module, providers[x].slots[z],
867
&tinfo.tinfo) != CKR_OK)
871
tinfo.sid = providers[x].slots[z];
872
tinfo.prov = &providers[x];
874
if (pkcs11_get_slot_info
875
(providers[x].module, providers[x].slots[z],
876
&tinfo.sinfo) != CKR_OK)
881
if (!p11_kit_uri_match_token_info (info, &tinfo.tinfo) ||
882
!p11_kit_uri_match_module_info (info, &providers[x].info))
888
*module = providers[x].module;
889
*slot = providers[x].slots[z];
892
memcpy (_tinfo, &tinfo, sizeof (tinfo));
899
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
903
pkcs11_open_session (struct ck_function_list ** _module, ck_session_handle_t * _pks,
904
struct p11_kit_uri *info, unsigned int flags)
908
ck_session_handle_t pks = 0;
909
struct ck_function_list *module;
911
struct token_info tinfo;
913
ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
920
rv = (module)->C_OpenSession (slot,
921
((flags & SESSION_WRITE)
922
? CKF_RW_SESSION : 0) |
923
CKF_SERIAL_SESSION, NULL, NULL, &pks);
927
return pkcs11_rv_to_err (rv);
930
if (flags & SESSION_LOGIN)
932
ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
936
pkcs11_close_session (module, pks);
949
_pkcs11_traverse_tokens (find_func_t find_func, void *input,
950
struct p11_kit_uri *info, unsigned int flags)
953
int found = 0, x, z, ret;
954
ck_session_handle_t pks = 0;
955
struct ck_function_list *module = NULL;
957
for (x = 0; x < active_providers; x++)
959
module = providers[x].module;
960
for (z = 0; z < providers[x].nslots; z++)
962
struct token_info tinfo;
964
ret = GNUTLS_E_PKCS11_ERROR;
966
if (pkcs11_get_token_info (module, providers[x].slots[z],
967
&tinfo.tinfo) != CKR_OK)
971
tinfo.sid = providers[x].slots[z];
972
tinfo.prov = &providers[x];
974
if (pkcs11_get_slot_info (module, providers[x].slots[z],
975
&tinfo.sinfo) != CKR_OK)
980
rv = (module)->C_OpenSession (providers[x].slots[z],
981
((flags & SESSION_WRITE)
982
? CKF_RW_SESSION : 0) |
983
CKF_SERIAL_SESSION, NULL, NULL, &pks);
989
if (flags & SESSION_LOGIN)
991
ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
999
ret = find_func (module, pks, &tinfo, &providers[x].info, input);
1008
pkcs11_close_session (module, pks);
1020
ret = find_func (module, pks, NULL, NULL, input);
1022
ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1029
if (pks != 0 && module != NULL)
1031
pkcs11_close_session (module, pks);
1037
/* imports a raw certificate from a token to a pkcs11_obj_t structure.
1040
pkcs11_obj_import (ck_object_class_t class, gnutls_pkcs11_obj_t obj,
1041
const gnutls_datum_t * data,
1042
const gnutls_datum_t * id,
1043
const gnutls_datum_t * label,
1044
struct ck_token_info *tinfo, struct ck_info *lib_info)
1046
struct ck_attribute attr;
1051
case CKO_CERTIFICATE:
1052
obj->type = GNUTLS_PKCS11_OBJ_X509_CRT;
1054
case CKO_PUBLIC_KEY:
1055
obj->type = GNUTLS_PKCS11_OBJ_PUBKEY;
1057
case CKO_PRIVATE_KEY:
1058
obj->type = GNUTLS_PKCS11_OBJ_PRIVKEY;
1060
case CKO_SECRET_KEY:
1061
obj->type = GNUTLS_PKCS11_OBJ_SECRET_KEY;
1064
obj->type = GNUTLS_PKCS11_OBJ_DATA;
1067
obj->type = GNUTLS_PKCS11_OBJ_UNKNOWN;
1071
attr.type = CKA_CLASS;
1072
attr.value = &class;
1073
attr.value_len = sizeof (class);
1074
ret = p11_kit_uri_set_attribute (obj->info, &attr);
1078
return GNUTLS_E_MEMORY_ERROR;
1081
if (data && data->data)
1083
ret = _gnutls_set_datum (&obj->raw, data->data, data->size);
1091
/* copy the token and library info into the uri */
1092
memcpy (p11_kit_uri_get_token_info (obj->info), tinfo, sizeof (struct ck_token_info));
1093
memcpy (p11_kit_uri_get_module_info (obj->info), lib_info, sizeof (struct ck_info));
1095
if (label && label->data)
1097
attr.type = CKA_LABEL;
1098
attr.value = label->data;
1099
attr.value_len = label->size;
1100
ret = p11_kit_uri_set_attribute (obj->info, &attr);
1104
return GNUTLS_E_MEMORY_ERROR;
1111
attr.value = id->data;
1112
attr.value_len = id->size;
1113
ret = p11_kit_uri_set_attribute (obj->info, &attr);
1117
return GNUTLS_E_MEMORY_ERROR;
1125
pkcs11_obj_import_pubkey (struct ck_function_list *module,
1126
ck_session_handle_t pks,
1127
ck_object_handle_t obj,
1128
gnutls_pkcs11_obj_t crt,
1129
const gnutls_datum_t * id,
1130
const gnutls_datum_t * label,
1131
struct ck_token_info *tinfo,
1132
struct ck_info *lib_info)
1135
struct ck_attribute a[4];
1136
ck_key_type_t key_type;
1142
a[0].type = CKA_KEY_TYPE;
1143
a[0].value = &key_type;
1144
a[0].value_len = sizeof (key_type);
1146
if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1151
a[0].type = CKA_MODULUS;
1153
a[0].value_len = sizeof (tmp1);
1154
a[1].type = CKA_PUBLIC_EXPONENT;
1156
a[1].value_len = sizeof (tmp2);
1158
if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1162
_gnutls_set_datum (&crt->pubkey[0],
1163
a[0].value, a[0].value_len);
1167
_gnutls_set_datum (&crt->pubkey
1168
[1], a[1].value, a[1].value_len);
1173
_gnutls_free_datum (&crt->pubkey[1]);
1174
_gnutls_free_datum (&crt->pubkey[0]);
1175
return GNUTLS_E_MEMORY_ERROR;
1181
return GNUTLS_E_PKCS11_ERROR;
1183
crt->pk_algorithm = GNUTLS_PK_RSA;
1186
a[0].type = CKA_PRIME;
1188
a[0].value_len = sizeof (tmp1);
1189
a[1].type = CKA_SUBPRIME;
1191
a[1].value_len = sizeof (tmp2);
1193
if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1196
_gnutls_set_datum (&crt->pubkey[0],
1197
a[0].value, a[0].value_len);
1201
_gnutls_set_datum (&crt->pubkey
1202
[1], a[1].value, a[1].value_len);
1207
_gnutls_free_datum (&crt->pubkey[1]);
1208
_gnutls_free_datum (&crt->pubkey[0]);
1209
return GNUTLS_E_MEMORY_ERROR;
1215
return GNUTLS_E_PKCS11_ERROR;
1218
a[0].type = CKA_BASE;
1220
a[0].value_len = sizeof (tmp1);
1221
a[1].type = CKA_VALUE;
1223
a[1].value_len = sizeof (tmp2);
1225
if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1228
_gnutls_set_datum (&crt->pubkey[2],
1229
a[0].value, a[0].value_len);
1233
_gnutls_set_datum (&crt->pubkey
1234
[3], a[1].value, a[1].value_len);
1239
_gnutls_free_datum (&crt->pubkey[0]);
1240
_gnutls_free_datum (&crt->pubkey[1]);
1241
_gnutls_free_datum (&crt->pubkey[2]);
1242
_gnutls_free_datum (&crt->pubkey[3]);
1243
return GNUTLS_E_MEMORY_ERROR;
1249
return GNUTLS_E_PKCS11_ERROR;
1251
crt->pk_algorithm = GNUTLS_PK_RSA;
1255
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1259
/* read key usage flags */
1260
a[0].type = CKA_ENCRYPT;
1262
a[0].value_len = sizeof (tval);
1264
if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1268
crt->key_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
1272
a[0].type = CKA_VERIFY;
1274
a[0].value_len = sizeof (tval);
1276
if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1280
crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1281
GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1282
| GNUTLS_KEY_NON_REPUDIATION;
1286
a[0].type = CKA_VERIFY_RECOVER;
1288
a[0].value_len = sizeof (tval);
1290
if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1294
crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
1295
GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
1296
| GNUTLS_KEY_NON_REPUDIATION;
1300
a[0].type = CKA_DERIVE;
1302
a[0].value_len = sizeof (tval);
1304
if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1308
crt->key_usage |= GNUTLS_KEY_KEY_AGREEMENT;
1312
a[0].type = CKA_WRAP;
1314
a[0].value_len = sizeof (tval);
1316
if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
1320
crt->key_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
1324
return pkcs11_obj_import (CKO_PUBLIC_KEY, crt, NULL, id, label,
1329
find_obj_url (struct ck_function_list *module, ck_session_handle_t pks,
1330
struct token_info *info, struct ck_info *lib_info, void *input)
1332
struct url_find_data_st *find_data = input;
1333
struct ck_attribute a[4];
1334
struct ck_attribute *attr;
1335
ck_object_class_t class = -1;
1336
ck_certificate_type_t type = -1;
1338
ck_object_handle_t obj;
1339
unsigned long count, a_vals;
1341
opaque *cert_data = NULL;
1342
char label_tmp[PKCS11_LABEL_SIZE];
1345
{ /* we don't support multiple calls */
1347
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1350
/* do not bother reading the token if basic fields do not match
1352
if (!p11_kit_uri_match_token_info (find_data->crt->info, &info->tinfo) ||
1353
!p11_kit_uri_match_module_info (find_data->crt->info, lib_info))
1356
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1359
attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID);
1363
return GNUTLS_E_INVALID_REQUEST;
1366
/* search the token for the id */
1368
cert_data = gnutls_malloc (MAX_CERT_SIZE);
1369
if (cert_data == NULL)
1372
return GNUTLS_E_MEMORY_ERROR;
1375
/* Find objects with given class and type */
1376
memcpy (a, attr, sizeof (struct ck_attribute));
1379
attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_CLASS);
1382
if(attr->value && attr->value_len == sizeof (ck_object_class_t))
1383
class = *((ck_object_class_t*)attr->value);
1384
if (class == CKO_CERTIFICATE)
1386
memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
1392
a[a_vals].type = CKA_CERTIFICATE_TYPE;
1393
a[a_vals].value = &type;
1394
a[a_vals].value_len = sizeof type;
1398
rv = pkcs11_find_objects_init (module, pks, a, a_vals);
1402
_gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
1403
ret = pkcs11_rv_to_err (rv);
1407
while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
1410
a[0].type = CKA_VALUE;
1411
a[0].value = cert_data;
1412
a[0].value_len = MAX_CERT_SIZE;
1413
a[1].type = CKA_LABEL;
1414
a[1].value = label_tmp;
1415
a[1].value_len = sizeof (label_tmp);
1417
if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
1420
gnutls_datum_t data = { a[0].value, a[0].value_len };
1421
gnutls_datum_t label = { a[1].value, a[1].value_len };
1423
attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID);
1424
id.data = attr->value;
1425
id.size = attr->value_len;
1427
if (class == CKO_PUBLIC_KEY)
1430
pkcs11_obj_import_pubkey (module, pks, obj,
1433
&info->tinfo, lib_info);
1438
pkcs11_obj_import (class,
1441
&info->tinfo, lib_info);
1454
_gnutls_debug_log ("pk11: Skipped cert, missing attrs.\n");
1461
ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1469
gnutls_free (cert_data);
1470
pkcs11_find_objects_final (module, pks);
1476
pkcs11_obj_flags_to_int (unsigned int flags)
1478
unsigned int ret_flags = 0;
1480
if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN)
1481
ret_flags |= SESSION_LOGIN;
1482
if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO)
1483
ret_flags |= SESSION_LOGIN|SESSION_SO;
1489
* gnutls_pkcs11_privkey_import_url:
1490
* @cert: The structure to store the parsed certificate
1491
* @url: a PKCS 11 url identifying the key
1492
* @flags: One of GNUTLS_PKCS11_OBJ_* flags
1494
* This function will "import" a PKCS 11 URL identifying a certificate
1495
* key to the #gnutls_pkcs11_obj_t structure. This does not involve any
1496
* parsing (such as X.509 or OpenPGP) since the #gnutls_pkcs11_obj_t is
1497
* format agnostic. Only data are transferred.
1499
* Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1500
* negative error value.
1503
gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t cert, const char *url,
1507
struct url_find_data_st find_data;
1509
/* fill in the find data structure */
1510
find_data.crt = cert;
1512
ret = pkcs11_url_to_info (url, &cert->info);
1520
_pkcs11_traverse_tokens (find_obj_url, &find_data, cert->info,
1521
pkcs11_obj_flags_to_int (flags));
1534
struct p11_kit_uri *info;
1535
unsigned int seq; /* which one we are looking for */
1536
unsigned int current; /* which one are we now */
1540
find_token_num (struct ck_function_list *module,
1541
ck_session_handle_t pks,
1542
struct token_info *tinfo,
1543
struct ck_info *lib_info, void *input)
1545
struct token_num *find_data = input;
1548
{ /* we don't support multiple calls */
1550
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1553
if (find_data->current == find_data->seq)
1555
memcpy (p11_kit_uri_get_token_info (find_data->info), &tinfo->tinfo, sizeof (struct ck_token_info));
1556
memcpy (p11_kit_uri_get_module_info (find_data->info), lib_info, sizeof (struct ck_info));
1560
find_data->current++;
1561
/* search the token for the id */
1564
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* non zero is enough */
1568
* gnutls_pkcs11_token_get_url:
1569
* @seq: sequence number starting from 0
1570
* @detailed: non zero if a detailed URL is required
1571
* @url: will contain an allocated url
1573
* This function will return the URL for each token available
1574
* in system. The url has to be released using gnutls_free()
1576
* Returns: On success, %GNUTLS_E_SUCCESS is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1577
* if the sequence number exceeds the available tokens, otherwise a negative error value.
1581
gnutls_pkcs11_token_get_url (unsigned int seq,
1582
gnutls_pkcs11_url_type_t detailed, char **url)
1585
struct token_num tn;
1587
memset (&tn, 0, sizeof (tn));
1589
tn.info = p11_kit_uri_new ();
1591
ret = _pkcs11_traverse_tokens (find_token_num, &tn, NULL, 0);
1594
p11_kit_uri_free (tn.info);
1599
ret = pkcs11_info_to_url (tn.info, detailed, url);
1600
p11_kit_uri_free (tn.info);
1613
* gnutls_pkcs11_token_get_info:
1614
* @url: should contain a PKCS 11 URL
1615
* @ttype: Denotes the type of information requested
1616
* @output: where output will be stored
1617
* @output_size: contains the maximum size of the output and will be overwritten with actual
1619
* This function will return information about the PKCS 11 token such
1620
* as the label, id as well as token information where the key is stored.
1622
* Returns: zero on success or a negative value on error.
1625
gnutls_pkcs11_token_get_info (const char *url,
1626
gnutls_pkcs11_token_info_t ttype,
1627
void *output, size_t * output_size)
1629
struct p11_kit_uri *info = NULL;
1635
ret = pkcs11_url_to_info (url, &info);
1644
case GNUTLS_PKCS11_TOKEN_LABEL:
1645
str = p11_kit_uri_get_token_info (info)->label;
1648
case GNUTLS_PKCS11_TOKEN_SERIAL:
1649
str = p11_kit_uri_get_token_info (info)->serial_number;
1652
case GNUTLS_PKCS11_TOKEN_MANUFACTURER:
1653
str = p11_kit_uri_get_token_info (info)->manufacturer_id;
1656
case GNUTLS_PKCS11_TOKEN_MODEL:
1657
str = p11_kit_uri_get_token_info (info)->model;
1661
p11_kit_uri_free (info);
1663
return GNUTLS_E_INVALID_REQUEST;
1666
len = p11_kit_space_strlen (str, str_max);
1668
if (len + 1 > *output_size)
1670
*output_size = len + 1;
1671
return GNUTLS_E_SHORT_MEMORY_BUFFER;
1674
memcpy (output, str, len);
1675
((char*)output)[len] = '\0';
1679
p11_kit_uri_free (info);
1684
* gnutls_pkcs11_obj_export_url:
1685
* @obj: Holds the PKCS 11 certificate
1686
* @detailed: non zero if a detailed URL is required
1687
* @url: will contain an allocated url
1689
* This function will export a URL identifying the given certificate.
1691
* Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1692
* negative error value.
1695
gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t obj,
1696
gnutls_pkcs11_url_type_t detailed, char **url)
1700
ret = pkcs11_info_to_url (obj->info, detailed, url);
1711
* gnutls_pkcs11_obj_get_type:
1712
* @certificate: Holds the PKCS 11 certificate
1714
* This function will return the type of the certificate being
1715
* stored in the structure.
1717
* Returns: The type of the certificate.
1719
gnutls_pkcs11_obj_type_t
1720
gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t obj)
1727
gnutls_buffer_st *key_ids;
1728
size_t key_ids_size;
1733
retrieve_pin_for_pinfile (const char *pinfile, struct ck_token_info *token_info,
1734
int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
1736
unsigned int flags = 0;
1737
struct p11_kit_uri *token_uri;
1738
struct p11_kit_pin *result;
1741
label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1745
return GNUTLS_E_MEMORY_ERROR;
1748
token_uri = p11_kit_uri_new ();
1749
if (token_uri == NULL)
1753
return GNUTLS_E_MEMORY_ERROR;
1756
memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1757
sizeof (struct ck_token_info));
1760
flags |= P11_KIT_PIN_FLAGS_RETRY;
1761
if (user_type == CKU_USER)
1763
flags |= P11_KIT_PIN_FLAGS_USER_LOGIN;
1764
if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1765
flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1766
if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1767
flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1769
else if (user_type == CKU_SO)
1771
flags |= P11_KIT_PIN_FLAGS_SO_LOGIN;
1772
if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
1773
flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
1774
if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
1775
flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
1777
else if (user_type == CKU_CONTEXT_SPECIFIC)
1779
flags |= P11_KIT_PIN_FLAGS_CONTEXT_LOGIN;
1782
result = p11_kit_pin_request (pinfile, token_uri, label, flags);
1783
p11_kit_uri_free (token_uri);
1789
return GNUTLS_E_PKCS11_PIN_ERROR;
1797
retrieve_pin_for_callback (struct ck_token_info *token_info, int attempts,
1798
ck_user_type_t user_type, struct p11_kit_pin **pin)
1800
char pin_value[GNUTLS_PKCS11_MAX_PIN_LEN];
1801
unsigned int flags = 0;
1804
struct p11_kit_uri *token_uri;
1807
label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
1811
return GNUTLS_E_MEMORY_ERROR;
1814
token_uri = p11_kit_uri_new ();
1815
if (token_uri == NULL)
1819
return GNUTLS_E_MEMORY_ERROR;
1822
memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
1823
sizeof (struct ck_token_info));
1824
ret = pkcs11_info_to_url (token_uri, 1, &token_str);
1825
p11_kit_uri_free (token_uri);
1831
return GNUTLS_E_MEMORY_ERROR;
1834
if (user_type == CKU_USER)
1836
flags |= GNUTLS_PKCS11_PIN_USER;
1837
if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
1838
flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
1839
if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
1840
flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
1842
else if (user_type == CKU_SO)
1844
flags |= GNUTLS_PKCS11_PIN_SO;
1845
if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
1846
flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
1847
if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
1848
flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
1852
flags |= GNUTLS_PKCS11_PIN_WRONG;
1854
ret = pin_func (pin_data, attempts, (char*)token_str, label,
1855
flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
1860
return gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR);
1862
*pin = p11_kit_pin_new_for_string (pin_value);
1865
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1871
retrieve_pin (struct p11_kit_uri *info, struct ck_token_info *token_info,
1872
int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
1874
const char *pinfile;
1878
/* Check if a pinfile is specified, and use that if possible */
1879
pinfile = p11_kit_uri_get_pinfile (info);
1880
if (pinfile != NULL)
1882
_gnutls_debug_log("pk11: Using pinfile to retrieve PIN\n");
1883
return retrieve_pin_for_pinfile (pinfile, token_info, attempts, user_type, pin);
1886
/* The global gnutls pin callback */
1888
return retrieve_pin_for_callback (token_info, attempts, user_type, pin);
1890
/* Otherwise, PIN entry is necessary for login, so fail if there's
1895
_gnutls_debug_log ("pk11: No pin callback but login required.\n");
1896
return GNUTLS_E_PKCS11_ERROR;
1901
pkcs11_login (struct ck_function_list * module, ck_session_handle_t pks,
1902
const struct token_info *tokinfo, struct p11_kit_uri *info, int so)
1904
struct ck_session_info session_info;
1905
int attempt = 0, ret;
1906
ck_user_type_t user_type;
1909
user_type = (so == 0) ? CKU_USER : CKU_SO;
1910
if (so == 0 && (tokinfo->tinfo.flags & CKF_LOGIN_REQUIRED) == 0)
1913
_gnutls_debug_log ("pk11: No login required.\n");
1917
/* For a token with a "protected" (out-of-band) authentication
1918
* path, calling login with a NULL username is all that is
1920
if (tokinfo->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
1922
rv = (module)->C_Login (pks, (so == 0) ? CKU_USER : CKU_SO, NULL, 0);
1923
if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
1930
_gnutls_debug_log ("pk11: Protected login failed.\n");
1931
ret = GNUTLS_E_PKCS11_ERROR;
1938
struct p11_kit_pin *pin;
1939
struct ck_token_info tinfo;
1941
memcpy (&tinfo, &tokinfo->tinfo, sizeof(tinfo));
1943
/* Check whether the session is already logged in, and if so, just skip */
1944
rv = (module)->C_GetSessionInfo (pks, &session_info);
1945
if (rv == CKR_OK && (session_info.state == CKS_RO_USER_FUNCTIONS ||
1946
session_info.state == CKS_RW_USER_FUNCTIONS))
1952
/* If login has been attempted once already, check the token
1953
* status again, the flags might change. */
1956
if (pkcs11_get_token_info
1957
(tokinfo->prov->module, tokinfo->sid, &tinfo) != CKR_OK)
1960
_gnutls_debug_log ("pk11: GetTokenInfo failed\n");
1961
ret = GNUTLS_E_PKCS11_ERROR;
1966
ret = retrieve_pin (info, &tinfo, attempt++, user_type, &pin);
1973
rv = (module)->C_Login (pks, user_type,
1974
(unsigned char *)p11_kit_pin_get_value (pin, NULL),
1975
p11_kit_pin_get_length (pin));
1977
p11_kit_pin_unref (pin);
1979
while (rv == CKR_PIN_INCORRECT);
1981
_gnutls_debug_log ("pk11: Login result = %lu\n", rv);
1985
|| rv == CKR_USER_ALREADY_LOGGED_IN) ? 0 : pkcs11_rv_to_err (rv);
1992
pkcs11_call_token_func (struct p11_kit_uri *info, const unsigned retry)
1994
struct ck_token_info *tinfo;
1998
tinfo = p11_kit_uri_get_token_info (info);
1999
label = p11_kit_space_strdup (tinfo->label, sizeof (tinfo->label));
2000
ret = (token_func) (token_data, label, retry);
2008
find_privkeys (struct ck_function_list *module, ck_session_handle_t pks,
2009
struct token_info *info, struct pkey_list *list)
2011
struct ck_attribute a[3];
2012
ck_object_class_t class;
2014
ck_object_handle_t obj;
2015
unsigned long count, current;
2016
char certid_tmp[PKCS11_ID_SIZE];
2018
class = CKO_PRIVATE_KEY;
2020
/* Find an object with private key class and a certificate ID
2021
* which matches the certificate. */
2022
/* FIXME: also match the cert subject. */
2023
a[0].type = CKA_CLASS;
2024
a[0].value = &class;
2025
a[0].value_len = sizeof class;
2027
rv = pkcs11_find_objects_init (module, pks, a, 1);
2031
return pkcs11_rv_to_err (rv);
2034
list->key_ids_size = 0;
2035
while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
2037
list->key_ids_size++;
2040
pkcs11_find_objects_final (module, pks);
2042
if (list->key_ids_size == 0)
2045
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2049
gnutls_malloc (sizeof (gnutls_buffer_st) * list->key_ids_size);
2050
if (list->key_ids == NULL)
2053
return GNUTLS_E_MEMORY_ERROR;
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);
2065
return pkcs11_rv_to_err (rv);
2069
while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
2073
a[0].value = certid_tmp;
2074
a[0].value_len = sizeof (certid_tmp);
2076
_gnutls_buffer_init (&list->key_ids[current]);
2078
if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2080
_gnutls_buffer_append_data (&list->key_ids[current],
2081
a[0].value, a[0].value_len);
2085
if (current > list->key_ids_size)
2089
pkcs11_find_objects_final (module, pks);
2091
list->key_ids_size = current - 1;
2096
/* Recover certificate list from tokens */
2100
find_objs (struct ck_function_list * module, ck_session_handle_t pks,
2101
struct token_info *info, struct ck_info *lib_info, void *input)
2103
struct crt_find_data_st *find_data = input;
2104
struct ck_attribute a[4];
2105
struct ck_attribute *attr;
2106
ck_object_class_t class = -1;
2107
ck_certificate_type_t type = -1;
2108
unsigned int trusted;
2110
ck_object_handle_t obj;
2111
unsigned long count;
2113
char certid_tmp[PKCS11_ID_SIZE];
2114
char label_tmp[PKCS11_LABEL_SIZE];
2116
struct pkey_list plist; /* private key holder */
2121
if (find_data->current <= *find_data->n_list)
2124
ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
2126
*find_data->n_list = find_data->current;
2131
/* do not bother reading the token if basic fields do not match
2133
if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2134
!p11_kit_uri_match_module_info (find_data->info, lib_info))
2137
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2140
memset (&plist, 0, sizeof (plist));
2142
if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2144
ret = find_privkeys (module, pks, info, &plist);
2151
if (plist.key_ids_size == 0)
2154
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2158
cert_data = gnutls_malloc (MAX_CERT_SIZE);
2159
if (cert_data == NULL)
2162
return GNUTLS_E_MEMORY_ERROR;
2165
/* Find objects with cert class and X.509 cert type. */
2169
if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL
2170
|| find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2172
class = CKO_CERTIFICATE;
2176
a[tot_values].type = CKA_CLASS;
2177
a[tot_values].value = &class;
2178
a[tot_values].value_len = sizeof class;
2181
a[tot_values].type = CKA_CERTIFICATE_TYPE;
2182
a[tot_values].value = &type;
2183
a[tot_values].value_len = sizeof type;
2187
else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED)
2189
class = CKO_CERTIFICATE;
2193
a[tot_values].type = CKA_CLASS;
2194
a[tot_values].value = &class;
2195
a[tot_values].value_len = sizeof class;
2198
a[tot_values].type = CKA_TRUSTED;
2199
a[tot_values].value = &trusted;
2200
a[tot_values].value_len = sizeof trusted;
2204
else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PUBKEY)
2206
class = CKO_PUBLIC_KEY;
2208
a[tot_values].type = CKA_CLASS;
2209
a[tot_values].value = &class;
2210
a[tot_values].value_len = sizeof class;
2213
else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
2215
class = CKO_PRIVATE_KEY;
2217
a[tot_values].type = CKA_CLASS;
2218
a[tot_values].value = &class;
2219
a[tot_values].value_len = sizeof class;
2222
else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2226
a[tot_values].type = CKA_CLASS;
2227
a[tot_values].value = &class;
2228
a[tot_values].value_len = sizeof class;
2233
a[tot_values].type = CKA_CERTIFICATE_TYPE;
2234
a[tot_values].value = &type;
2235
a[tot_values].value_len = sizeof type;
2242
ret = GNUTLS_E_INVALID_REQUEST;
2246
attr = p11_kit_uri_get_attribute (find_data->info, CKA_ID);
2249
memcpy (a + tot_values, attr, sizeof (struct ck_attribute));
2253
rv = pkcs11_find_objects_init (module, pks, a, tot_values);
2257
_gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
2258
return pkcs11_rv_to_err (rv);
2261
while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
2263
gnutls_datum_t label, id, value;
2265
a[0].type = CKA_LABEL;
2266
a[0].value = label_tmp;
2267
a[0].value_len = sizeof label_tmp;
2269
if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2271
label.data = a[0].value;
2272
label.size = a[0].value_len;
2281
a[0].value = certid_tmp;
2282
a[0].value_len = sizeof certid_tmp;
2284
if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2286
id.data = a[0].value;
2287
id.size = a[0].value_len;
2295
a[0].type = CKA_VALUE;
2296
a[0].value = cert_data;
2297
a[0].value_len = MAX_CERT_SIZE;
2298
if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
2300
value.data = a[0].value;
2301
value.size = a[0].value_len;
2309
if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
2311
a[0].type = CKA_CLASS;
2312
a[0].value = &class;
2313
a[0].value_len = sizeof class;
2315
pkcs11_get_attribute_value (module, pks, obj, a, 1);
2318
if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
2320
for (i = 0; i < plist.key_ids_size; i++)
2322
if (plist.key_ids[i].length !=
2324
|| memcmp (plist.key_ids[i].data,
2325
a[1].value, a[1].value_len) != 0)
2333
if (find_data->current < *find_data->n_list)
2336
gnutls_pkcs11_obj_init (&find_data->p_list[find_data->current]);
2343
if (class == CKO_PUBLIC_KEY)
2346
pkcs11_obj_import_pubkey (module, pks, obj,
2348
[find_data->current],
2350
&info->tinfo, lib_info);
2355
pkcs11_obj_import (class,
2357
[find_data->current],
2358
&value, &id, &label,
2359
&info->tinfo, lib_info);
2368
find_data->current++;
2372
gnutls_free (cert_data);
2373
pkcs11_find_objects_final (module, pks);
2375
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* continue until all tokens have been checked */
2378
gnutls_free (cert_data);
2379
pkcs11_find_objects_final (module, pks);
2380
if (plist.key_ids != NULL)
2382
for (i = 0; i < plist.key_ids_size; i++)
2384
_gnutls_buffer_clear (&plist.key_ids[i]);
2386
gnutls_free (plist.key_ids);
2388
for (i = 0; i < find_data->current; i++)
2390
gnutls_pkcs11_obj_deinit (find_data->p_list[i]);
2392
find_data->current = 0;
2398
* gnutls_pkcs11_obj_list_import_url:
2399
* @p_list: An uninitialized object list (may be NULL)
2400
* @n_list: initially should hold the maximum size of the list. Will contain the actual size.
2401
* @url: A PKCS 11 url identifying a set of objects
2402
* @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
2403
* @flags: One of GNUTLS_PKCS11_OBJ_* flags
2405
* This function will initialize and set values to an object list
2406
* by using all objects identified by a PKCS 11 URL.
2408
* Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
2409
* negative error value.
2412
gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list,
2413
unsigned int *n_list,
2415
gnutls_pkcs11_obj_attr_t attrs,
2419
struct crt_find_data_st find_data;
2421
memset (&find_data, 0, sizeof (find_data));
2423
/* fill in the find data structure */
2424
find_data.p_list = p_list;
2425
find_data.n_list = n_list;
2426
find_data.flags = attrs;
2427
find_data.current = 0;
2429
if (url == NULL || url[0] == 0)
2434
ret = pkcs11_url_to_info (url, &find_data.info);
2442
_pkcs11_traverse_tokens (find_objs, &find_data, find_data.info,
2443
pkcs11_obj_flags_to_int (flags));
2444
p11_kit_uri_free (find_data.info);
2456
* gnutls_x509_crt_import_pkcs11_url:
2457
* @crt: A certificate of type #gnutls_x509_crt_t
2458
* @url: A PKCS 11 url
2459
* @flags: One of GNUTLS_PKCS11_OBJ_* flags
2461
* This function will import a PKCS 11 certificate directly from a token
2462
* without involving the #gnutls_pkcs11_obj_t structure. This function will
2463
* fail if the certificate stored is not of X.509 type.
2465
* Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
2466
* negative error value.
2469
gnutls_x509_crt_import_pkcs11_url (gnutls_x509_crt_t crt,
2470
const char *url, unsigned int flags)
2472
gnutls_pkcs11_obj_t pcrt;
2475
ret = gnutls_pkcs11_obj_init (&pcrt);
2482
ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
2489
ret = gnutls_x509_crt_import (crt, &pcrt->raw, GNUTLS_X509_FMT_DER);
2499
gnutls_pkcs11_obj_deinit (pcrt);
2506
* gnutls_x509_crt_import_pkcs11:
2507
* @crt: A certificate of type #gnutls_x509_crt_t
2508
* @pkcs11_crt: A PKCS 11 object that contains a certificate
2510
* This function will import a PKCS 11 certificate to a #gnutls_x509_crt_t
2513
* Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
2514
* negative error value.
2517
gnutls_x509_crt_import_pkcs11 (gnutls_x509_crt_t crt,
2518
gnutls_pkcs11_obj_t pkcs11_crt)
2520
return gnutls_x509_crt_import (crt, &pkcs11_crt->raw, GNUTLS_X509_FMT_DER);
2524
* gnutls_x509_crt_list_import_pkcs11:
2525
* @certs: A list of certificates of type #gnutls_x509_crt_t
2526
* @cert_max: The maximum size of the list
2527
* @objs: A list of PKCS 11 objects
2530
* This function will import a PKCS 11 certificate list to a list of
2531
* #gnutls_x509_crt_t structure. These must not be initialized.
2533
* Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
2534
* negative error value.
2537
gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
2538
unsigned int cert_max,
2539
gnutls_pkcs11_obj_t * const objs,
2545
for (i = 0; i < cert_max; i++)
2547
ret = gnutls_x509_crt_init (&certs[i]);
2554
ret = gnutls_x509_crt_import_pkcs11 (certs[i], objs[i]);
2565
for (j = 0; j < i; j++)
2567
gnutls_x509_crt_deinit (certs[j]);
2574
find_flags (struct ck_function_list * module, ck_session_handle_t pks,
2575
struct token_info *info, struct ck_info *lib_info, void *input)
2577
struct flags_find_data_st *find_data = input;
2580
{ /* we don't support multiple calls */
2582
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2585
/* do not bother reading the token if basic fields do not match
2587
if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
2588
!p11_kit_uri_match_module_info (find_data->info, lib_info))
2591
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2596
find_data->slot_flags = info->sinfo.flags;
2602
* gnutls_pkcs11_token_get_flags:
2603
* @url: should contain a PKCS 11 URL
2604
* @flags: The output flags (GNUTLS_PKCS11_TOKEN_*)
2606
* This function will return information about the PKCS 11 token flags.
2608
* Returns: zero on success or a negative value on error.
2611
gnutls_pkcs11_token_get_flags (const char *url, unsigned int *flags)
2613
struct flags_find_data_st find_data;
2616
memset (&find_data, 0, sizeof (find_data));
2617
ret = pkcs11_url_to_info (url, &find_data.info);
2624
ret = _pkcs11_traverse_tokens (find_flags, &find_data, find_data.info, 0);
2625
p11_kit_uri_free (find_data.info);
2634
if (find_data.slot_flags & CKF_HW_SLOT)
2635
*flags |= GNUTLS_PKCS11_TOKEN_HW;
2643
* gnutls_pkcs11_token_get_mechanism:
2644
* @url: should contain a PKCS 11 URL
2645
* @idx: The index of the mechanism
2646
* @mechanism: The PKCS #11 mechanism ID
2648
* This function will return the names of the supported mechanisms
2649
* by the token. It should be called with an increasing index until
2650
* it return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.
2652
* Returns: zero on success or a negative value on error.
2655
gnutls_pkcs11_token_get_mechanism (const char *url, int idx,
2656
unsigned long *mechanism)
2660
struct ck_function_list *module;
2662
struct token_info tinfo;
2663
struct p11_kit_uri *info = NULL;
2664
unsigned long count;
2665
ck_mechanism_type_t mlist[400];
2667
ret = pkcs11_url_to_info (url, &info);
2675
ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
2676
p11_kit_uri_free (info);
2684
count = sizeof (mlist) / sizeof (mlist[0]);
2685
rv = pkcs11_get_mechanism_list (module, slot, mlist, &count);
2689
return pkcs11_rv_to_err (rv);
2695
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2698
*mechanism = mlist[idx];
2706
gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t type)
2710
case GNUTLS_PKCS11_OBJ_X509_CRT:
2711
return "X.509 Certificate";
2712
case GNUTLS_PKCS11_OBJ_PUBKEY:
2713
return "Public key";
2714
case GNUTLS_PKCS11_OBJ_PRIVKEY:
2715
return "Private key";
2716
case GNUTLS_PKCS11_OBJ_SECRET_KEY:
2717
return "Secret key";
2718
case GNUTLS_PKCS11_OBJ_DATA:
2720
case GNUTLS_PKCS11_OBJ_UNKNOWN:
2727
pkcs11_get_slot_list (struct ck_function_list * module, unsigned char token_present,
2728
ck_slot_id_t *slot_list, unsigned long *count)
2730
return (module)->C_GetSlotList (token_present, slot_list, count);
2734
pkcs11_get_module_info (struct ck_function_list * module,
2735
struct ck_info * info)
2737
return (module)->C_GetInfo (info);
2741
pkcs11_get_slot_info(struct ck_function_list * module,
2742
ck_slot_id_t slot_id,
2743
struct ck_slot_info *info)
2745
return (module)->C_GetSlotInfo (slot_id, info);
2749
pkcs11_get_token_info (struct ck_function_list * module,
2750
ck_slot_id_t slot_id,
2751
struct ck_token_info *info)
2753
return (module)->C_GetTokenInfo (slot_id, info);
2757
pkcs11_find_objects_init (struct ck_function_list *module,
2758
ck_session_handle_t sess,
2759
struct ck_attribute *templ,
2760
unsigned long count)
2762
return (module)->C_FindObjectsInit (sess, templ, count);
2766
pkcs11_find_objects (struct ck_function_list *module,
2767
ck_session_handle_t sess,
2768
ck_object_handle_t *objects,
2769
unsigned long max_object_count,
2770
unsigned long *object_count)
2772
return (module)->C_FindObjects (sess, objects, max_object_count, object_count);
2776
pkcs11_find_objects_final (struct ck_function_list *module,
2777
ck_session_handle_t sess)
2779
return (module)->C_FindObjectsFinal (sess);
2783
pkcs11_close_session (struct ck_function_list *module,
2784
ck_session_handle_t sess)
2786
return (module)->C_CloseSession (sess);
2790
pkcs11_get_attribute_value(struct ck_function_list *module,
2791
ck_session_handle_t sess,
2792
ck_object_handle_t object,
2793
struct ck_attribute *templ,
2794
unsigned long count)
2796
return (module)->C_GetAttributeValue (sess, object, templ, count);
2800
pkcs11_get_mechanism_list (struct ck_function_list *module,
2801
ck_slot_id_t slot_id,
2802
ck_mechanism_type_t *mechanism_list,
2803
unsigned long *count)
2805
return (module)->C_GetMechanismList (slot_id, mechanism_list, count);
2809
pkcs11_sign_init (struct ck_function_list *module,
2810
ck_session_handle_t sess,
2811
struct ck_mechanism *mechanism,
2812
ck_object_handle_t key)
2814
return (module)->C_SignInit (sess, mechanism, key);
2818
pkcs11_sign (struct ck_function_list *module,
2819
ck_session_handle_t sess,
2820
unsigned char *data,
2821
unsigned long data_len,
2822
unsigned char *signature,
2823
unsigned long *signature_len)
2825
return (module)->C_Sign (sess, data, data_len, signature, signature_len);
2829
pkcs11_decrypt_init (struct ck_function_list *module,
2830
ck_session_handle_t sess,
2831
struct ck_mechanism *mechanism,
2832
ck_object_handle_t key)
2834
return (module)->C_DecryptInit (sess, mechanism, key);
2838
pkcs11_decrypt (struct ck_function_list *module,
2839
ck_session_handle_t sess,
2840
unsigned char *encrypted_data,
2841
unsigned long encrypted_data_len,
2842
unsigned char *data, unsigned long *data_len)
2844
return (module)->C_Decrypt (sess, encrypted_data, encrypted_data_len,
2849
pkcs11_create_object (struct ck_function_list *module,
2850
ck_session_handle_t sess,
2851
struct ck_attribute *templ,
2852
unsigned long count,
2853
ck_object_handle_t *object)
2855
return (module)->C_CreateObject (sess, templ, count, object);
2859
pkcs11_destroy_object (struct ck_function_list *module,
2860
ck_session_handle_t sess,
2861
ck_object_handle_t object)
2863
return (module)->C_DestroyObject (sess, object);
2867
pkcs11_init_token (struct ck_function_list *module,
2868
ck_slot_id_t slot_id, unsigned char *pin,
2869
unsigned long pin_len, unsigned char *label)
2871
return (module)->C_InitToken (slot_id, pin, pin_len, label);
2875
pkcs11_init_pin (struct ck_function_list *module,
2876
ck_session_handle_t sess,
2878
unsigned long pin_len)
2880
return (module)->C_InitPIN (sess, pin, pin_len);
2884
pkcs11_set_pin (struct ck_function_list *module,
2885
ck_session_handle_t sess,
2886
unsigned char *old_pin,
2887
unsigned long old_len,
2888
unsigned char *new_pin,
2889
unsigned long new_len)
2891
return (module)->C_SetPIN (sess, old_pin, old_len, new_pin, new_len);
2895
pkcs11_strerror (ck_rv_t rv)
2897
return p11_kit_strerror (rv);