File: | lib/pkcs11.c |
Location: | line 426, column 11 |
Description: | Null pointer passed as an argument to a 'nonnull' parameter |
1 | /* | ||
2 | * GnuTLS PKCS#11 support | ||
3 | * Copyright (C) 2010, 2011 Free Software Foundation | ||
4 | * Copyright (C) 2008, Joe Orton <joe@manyfish.co.uk> | ||
5 | * | ||
6 | * Authors: Nikos Mavrogiannopoulos, Stef Walter | ||
7 | * | ||
8 | * Inspired and some parts (pkcs11_login) based on neon PKCS #11 support | ||
9 | * by Joe Orton. More ideas came from the pkcs11-helper library by | ||
10 | * Alon Bar-Lev. | ||
11 | * | ||
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. | ||
16 | * | ||
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. | ||
21 | * | ||
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/> | ||
24 | */ | ||
25 | |||
26 | #include <gnutls_int.h> | ||
27 | #include <gnutls/pkcs11.h> | ||
28 | #include <stdio.h> | ||
29 | #include <string.h> | ||
30 | #include <gnutls_errors.h> | ||
31 | #include <gnutls_datumgnutls_datum_t.h> | ||
32 | |||
33 | |||
34 | #include <pkcs11_int.h> | ||
35 | #include <p11-kit/p11-kit.h> | ||
36 | #include <p11-kit/pin.h> | ||
37 | |||
38 | #define MAX_PROVIDERS16 16 | ||
39 | |||
40 | /* XXX: try to eliminate this */ | ||
41 | #define MAX_CERT_SIZE8*1024 8*1024 | ||
42 | |||
43 | struct gnutls_pkcs11_provider_s | ||
44 | { | ||
45 | struct ck_function_list *module; | ||
46 | unsigned long nslots; | ||
47 | ck_slot_id_t *slots; | ||
48 | struct ck_info info; | ||
49 | int initialized; | ||
50 | }; | ||
51 | |||
52 | struct flags_find_data_st | ||
53 | { | ||
54 | struct p11_kit_uri *info; | ||
55 | unsigned int slot_flags; | ||
56 | }; | ||
57 | |||
58 | struct url_find_data_st | ||
59 | { | ||
60 | gnutls_pkcs11_obj_t crt; | ||
61 | }; | ||
62 | |||
63 | struct crt_find_data_st | ||
64 | { | ||
65 | gnutls_pkcs11_obj_t *p_list; | ||
66 | unsigned int *n_list; | ||
67 | unsigned int current; | ||
68 | gnutls_pkcs11_obj_attr_t flags; | ||
69 | struct p11_kit_uri *info; | ||
70 | }; | ||
71 | |||
72 | |||
73 | static struct gnutls_pkcs11_provider_s providers[MAX_PROVIDERS16]; | ||
74 | static int active_providers = 0; | ||
75 | static int initialized_registered = 0; | ||
76 | |||
77 | static gnutls_pkcs11_pin_callback_t pin_func; | ||
78 | static void *pin_data; | ||
79 | |||
80 | gnutls_pkcs11_token_callback_t token_func; | ||
81 | void *token_data; | ||
82 | |||
83 | int | ||
84 | pkcs11_rv_to_err (ck_rv_t rv) | ||
85 | { | ||
86 | switch (rv) | ||
87 | { | ||
88 | case CKR_OK(0UL): | ||
89 | return 0; | ||
90 | case CKR_HOST_MEMORY(2UL): | ||
91 | return GNUTLS_E_MEMORY_ERROR-25; | ||
92 | case CKR_SLOT_ID_INVALID(3UL): | ||
93 | return GNUTLS_E_PKCS11_SLOT_ERROR-305; | ||
94 | case CKR_ARGUMENTS_BAD(7UL): | ||
95 | case CKR_MECHANISM_PARAM_INVALID(0x71UL): | ||
96 | return GNUTLS_E_INVALID_REQUEST-50; | ||
97 | case CKR_NEED_TO_CREATE_THREADS(9UL): | ||
98 | case CKR_CANT_LOCK(0xaUL): | ||
99 | case CKR_FUNCTION_NOT_PARALLEL(0x51UL): | ||
100 | case CKR_MUTEX_BAD(0x1a0UL): | ||
101 | case CKR_MUTEX_NOT_LOCKED(0x1a1UL): | ||
102 | return GNUTLS_E_LOCKING_ERROR-306; | ||
103 | case CKR_ATTRIBUTE_READ_ONLY(0x10UL): | ||
104 | case CKR_ATTRIBUTE_SENSITIVE(0x11UL): | ||
105 | case CKR_ATTRIBUTE_TYPE_INVALID(0x12UL): | ||
106 | case CKR_ATTRIBUTE_VALUE_INVALID(0x13UL): | ||
107 | return GNUTLS_E_PKCS11_ATTRIBUTE_ERROR-307; | ||
108 | case CKR_DEVICE_ERROR(0x30UL): | ||
109 | case CKR_DEVICE_MEMORY(0x31UL): | ||
110 | case CKR_DEVICE_REMOVED(0x32UL): | ||
111 | return GNUTLS_E_PKCS11_DEVICE_ERROR-308; | ||
112 | case CKR_DATA_INVALID(0x20UL): | ||
113 | case CKR_DATA_LEN_RANGE(0x21UL): | ||
114 | case CKR_ENCRYPTED_DATA_INVALID(0x40UL): | ||
115 | case CKR_ENCRYPTED_DATA_LEN_RANGE(0x41UL): | ||
116 | case CKR_OBJECT_HANDLE_INVALID(0x82UL): | ||
117 | return GNUTLS_E_PKCS11_DATA_ERROR-309; | ||
118 | case CKR_FUNCTION_NOT_SUPPORTED(0x54UL): | ||
119 | case CKR_MECHANISM_INVALID(0x70UL): | ||
120 | return GNUTLS_E_PKCS11_UNSUPPORTED_FEATURE_ERROR-310; | ||
121 | case CKR_KEY_HANDLE_INVALID(0x60UL): | ||
122 | case CKR_KEY_SIZE_RANGE(0x62UL): | ||
123 | case CKR_KEY_TYPE_INCONSISTENT(0x63UL): | ||
124 | case CKR_KEY_NOT_NEEDED(0x64UL): | ||
125 | case CKR_KEY_CHANGED(0x65UL): | ||
126 | case CKR_KEY_NEEDED(0x66UL): | ||
127 | case CKR_KEY_INDIGESTIBLE(0x67UL): | ||
128 | case CKR_KEY_FUNCTION_NOT_PERMITTED(0x68UL): | ||
129 | case CKR_KEY_NOT_WRAPPABLE(0x69UL): | ||
130 | case CKR_KEY_UNEXTRACTABLE(0x6aUL): | ||
131 | return GNUTLS_E_PKCS11_KEY_ERROR-311; | ||
132 | case CKR_PIN_INCORRECT(0xa0UL): | ||
133 | case CKR_PIN_INVALID(0xa1UL): | ||
134 | case CKR_PIN_LEN_RANGE(0xa2UL): | ||
135 | return GNUTLS_E_PKCS11_PIN_ERROR-303; | ||
136 | case CKR_PIN_EXPIRED(0xa3UL): | ||
137 | return GNUTLS_E_PKCS11_PIN_EXPIRED-312; | ||
138 | case CKR_PIN_LOCKED(0xa4UL): | ||
139 | return GNUTLS_E_PKCS11_PIN_LOCKED-313; | ||
140 | case CKR_SESSION_CLOSED(0xb0UL): | ||
141 | case CKR_SESSION_COUNT(0xb1UL): | ||
142 | case CKR_SESSION_HANDLE_INVALID(0xb3UL): | ||
143 | case CKR_SESSION_PARALLEL_NOT_SUPPORTED(0xb4UL): | ||
144 | case CKR_SESSION_READ_ONLY(0xb5UL): | ||
145 | case CKR_SESSION_EXISTS(0xb6UL): | ||
146 | case CKR_SESSION_READ_ONLY_EXISTS(0xb7UL): | ||
147 | case CKR_SESSION_READ_WRITE_SO_EXISTS(0xb8UL): | ||
148 | return GNUTLS_E_PKCS11_SESSION_ERROR-314; | ||
149 | case CKR_SIGNATURE_INVALID(0xc0UL): | ||
150 | case CKR_SIGNATURE_LEN_RANGE(0xc1UL): | ||
151 | return GNUTLS_E_PKCS11_SIGNATURE_ERROR-315; | ||
152 | case CKR_TOKEN_NOT_PRESENT(0xe0UL): | ||
153 | case CKR_TOKEN_NOT_RECOGNIZED(0xe1UL): | ||
154 | case CKR_TOKEN_WRITE_PROTECTED(0xe2UL): | ||
155 | return GNUTLS_E_PKCS11_TOKEN_ERROR-316; | ||
156 | case CKR_USER_ALREADY_LOGGED_IN(0x100UL): | ||
157 | case CKR_USER_NOT_LOGGED_IN(0x101UL): | ||
158 | case CKR_USER_PIN_NOT_INITIALIZED(0x102UL): | ||
159 | case CKR_USER_TYPE_INVALID(0x103UL): | ||
160 | case CKR_USER_ANOTHER_ALREADY_LOGGED_IN(0x104UL): | ||
161 | case CKR_USER_TOO_MANY_TYPES(0x105UL): | ||
162 | return GNUTLS_E_PKCS11_USER_ERROR-317; | ||
163 | case CKR_BUFFER_TOO_SMALL(0x150UL): | ||
164 | return GNUTLS_E_SHORT_MEMORY_BUFFER-51; | ||
165 | default: | ||
166 | return GNUTLS_E_PKCS11_ERROR-300; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | /* Fake scan */ | ||
171 | void | ||
172 | pkcs11_rescan_slots (void) | ||
173 | { | ||
174 | unsigned long slots; | ||
175 | |||
176 | pkcs11_get_slot_list (providers[active_providers - 1].module, 0, | ||
177 | NULL((void*)0), &slots); | ||
178 | } | ||
179 | |||
180 | static int | ||
181 | pkcs11_add_module (const char *name, struct ck_function_list *module) | ||
182 | { | ||
183 | struct ck_info info; | ||
184 | int i; | ||
185 | |||
186 | if (active_providers >= MAX_PROVIDERS16) | ||
187 | { | ||
188 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",188); } while(0);; | ||
189 | return GNUTLS_E_CONSTRAINT_ERROR-101; | ||
190 | } | ||
191 | |||
192 | /* initially check if this module is a duplicate */ | ||
193 | memset(&info, 0, sizeof(info)); | ||
194 | pkcs11_get_module_info (module, &info); | ||
195 | for (i=0;i<active_providers;i++) | ||
196 | { | ||
197 | /* already loaded, skip the rest */ | ||
198 | if (memcmp(&info, &providers[i].info, sizeof(info)) == 0) | ||
199 | { | ||
200 | _gnutls_debug_log("%s is already loaded.\n", name)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "%s is already loaded.\n", name); } while(0); | ||
201 | return GNUTLS_E_INT_RET_0-1251; | ||
202 | } | ||
203 | } | ||
204 | |||
205 | active_providers++; | ||
206 | providers[active_providers - 1].module = module; | ||
207 | |||
208 | /* cache the number of slots in this module */ | ||
209 | if (pkcs11_get_slot_list | ||
210 | (providers[active_providers - 1].module, 0, NULL((void*)0), | ||
211 | &providers[active_providers - 1].nslots) != CKR_OK(0UL)) | ||
212 | { | ||
213 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",213); } while(0);; | ||
214 | goto fail; | ||
215 | } | ||
216 | |||
217 | providers[active_providers - 1].slots = | ||
218 | gnutls_malloc (sizeof (*providers[active_providers - 1].slots) * | ||
219 | providers[active_providers - 1].nslots); | ||
220 | if (providers[active_providers - 1].slots == NULL((void*)0)) | ||
221 | { | ||
222 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",222); } while(0);; | ||
223 | goto fail; | ||
224 | } | ||
225 | |||
226 | if (pkcs11_get_slot_list | ||
227 | (providers[active_providers - 1].module, 0, | ||
228 | providers[active_providers - 1].slots, | ||
229 | &providers[active_providers - 1].nslots) != CKR_OK(0UL)) | ||
230 | { | ||
231 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",231); } while(0);; | ||
232 | gnutls_free (providers[active_providers - 1].slots); | ||
233 | goto fail; | ||
234 | } | ||
235 | |||
236 | memcpy (&providers[active_providers - 1].info, &info, sizeof(info)); | ||
237 | |||
238 | _gnutls_debug_log ("p11: loaded provider '%s' with %d slots\n",do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "p11: loaded provider '%s' with %d slots\n", name, (int) providers[active_providers - 1].nslots); } while(0) | ||
239 | name, (int) providers[active_providers - 1].nslots)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "p11: loaded provider '%s' with %d slots\n", name, (int) providers[active_providers - 1].nslots); } while(0); | ||
240 | |||
241 | return 0; | ||
242 | |||
243 | fail: | ||
244 | active_providers--; | ||
245 | return GNUTLS_E_PKCS11_LOAD_ERROR-301; | ||
246 | } | ||
247 | |||
248 | |||
249 | /** | ||
250 | * gnutls_pkcs11_add_provider: | ||
251 | * @name: The filename of the module | ||
252 | * @params: should be NULL | ||
253 | * | ||
254 | * This function will load and add a PKCS 11 module to the module | ||
255 | * list used in gnutls. After this function is called the module will | ||
256 | * be used for PKCS 11 operations. | ||
257 | * | ||
258 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
259 | * negative error value. | ||
260 | * | ||
261 | * Since: 2.12.0 | ||
262 | **/ | ||
263 | int | ||
264 | gnutls_pkcs11_add_provider (const char *name, const char *params) | ||
265 | { | ||
266 | struct ck_function_list *module; | ||
267 | int ret; | ||
268 | |||
269 | active_providers++; | ||
270 | if (p11_kit_load_initialize_module (name, &module) != CKR_OK(0UL)) | ||
271 | { | ||
272 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",272); } while(0);; | ||
273 | _gnutls_debug_log ("p11: Cannot load provider %s\n", name)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "p11: Cannot load provider %s\n", name); } while(0); | ||
274 | active_providers--; | ||
275 | return GNUTLS_E_PKCS11_LOAD_ERROR-301; | ||
276 | } | ||
277 | |||
278 | ret = pkcs11_add_module (name, module); | ||
279 | if (ret == 0) | ||
280 | { | ||
281 | /* Mark this one as having been separately initialized */ | ||
282 | providers[active_providers - 1].initialized = 1; | ||
283 | } | ||
284 | else | ||
285 | { | ||
286 | if (ret == GNUTLS_E_INT_RET_0-1251) ret = 0; | ||
287 | p11_kit_finalize_module (module); | ||
288 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",288); } while(0);; | ||
289 | } | ||
290 | |||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | |||
295 | /** | ||
296 | * gnutls_pkcs11_obj_get_info: | ||
297 | * @crt: should contain a #gnutls_pkcs11_obj_t structure | ||
298 | * @itype: Denotes the type of information requested | ||
299 | * @output: where output will be stored | ||
300 | * @output_size: contains the maximum size of the output and will be overwritten with actual | ||
301 | * | ||
302 | * This function will return information about the PKCS11 certificate | ||
303 | * such as the label, id as well as token information where the key is | ||
304 | * stored. When output is text it returns null terminated string | ||
305 | * although @output_size contains the size of the actual data only. | ||
306 | * | ||
307 | * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error. | ||
308 | * | ||
309 | * Since: 2.12.0 | ||
310 | **/ | ||
311 | int | ||
312 | gnutls_pkcs11_obj_get_info (gnutls_pkcs11_obj_t crt, | ||
313 | gnutls_pkcs11_obj_info_t itype, | ||
314 | void *output, size_t * output_size) | ||
315 | { | ||
316 | return pkcs11_get_info (crt->info, itype, output, output_size); | ||
317 | } | ||
318 | |||
319 | int | ||
320 | pkcs11_get_info (struct p11_kit_uri *info, | ||
321 | gnutls_pkcs11_obj_info_t itype, void *output, | ||
322 | size_t * output_size) | ||
323 | { | ||
324 | struct ck_attribute *attr = NULL((void*)0); | ||
325 | struct ck_version *version = NULL((void*)0); | ||
326 | const char *str = NULL((void*)0); | ||
327 | size_t str_max = 0; | ||
328 | int terminate = 0; | ||
329 | int hexify = 0; | ||
330 | size_t length = 0; | ||
331 | const char *data = NULL((void*)0); | ||
332 | char buf[32]; | ||
333 | |||
334 | /* | ||
335 | * Either attr, str or version is valid by the time switch | ||
336 | * finishes | ||
337 | */ | ||
338 | |||
339 | switch (itype) | ||
| |||
340 | { | ||
341 | case GNUTLS_PKCS11_OBJ_ID: | ||
342 | attr = p11_kit_uri_get_attribute (info, CKA_ID(0x102UL)); | ||
343 | break; | ||
| |||
344 | case GNUTLS_PKCS11_OBJ_ID_HEX: | ||
345 | attr = p11_kit_uri_get_attribute (info, CKA_ID(0x102UL)); | ||
346 | hexify = 1; | ||
347 | terminate = 1; | ||
348 | break; | ||
349 | case GNUTLS_PKCS11_OBJ_LABEL: | ||
350 | attr = p11_kit_uri_get_attribute (info, CKA_LABEL(3UL)); | ||
351 | terminate = 1; | ||
352 | break; | ||
353 | case GNUTLS_PKCS11_OBJ_TOKEN_LABEL: | ||
354 | str = p11_kit_uri_get_token_info (info)->label; | ||
355 | str_max = 32; | ||
356 | break; | ||
357 | case GNUTLS_PKCS11_OBJ_TOKEN_SERIAL: | ||
358 | str = p11_kit_uri_get_token_info (info)->serial_number; | ||
359 | str_max = 16; | ||
360 | break; | ||
361 | case GNUTLS_PKCS11_OBJ_TOKEN_MANUFACTURER: | ||
362 | str = p11_kit_uri_get_token_info (info)->manufacturer_id; | ||
363 | str_max = 32; | ||
364 | break; | ||
365 | case GNUTLS_PKCS11_OBJ_TOKEN_MODEL: | ||
366 | str = p11_kit_uri_get_token_info (info)->model; | ||
367 | str_max = 16; | ||
368 | break; | ||
369 | case GNUTLS_PKCS11_OBJ_LIBRARY_DESCRIPTION: | ||
370 | str = p11_kit_uri_get_module_info (info)->library_description; | ||
371 | str_max = 32; | ||
372 | break; | ||
373 | case GNUTLS_PKCS11_OBJ_LIBRARY_VERSION: | ||
374 | version = &p11_kit_uri_get_module_info (info)->library_version; | ||
375 | break; | ||
376 | case GNUTLS_PKCS11_OBJ_LIBRARY_MANUFACTURER: | ||
377 | str = p11_kit_uri_get_module_info (info)->manufacturer_id; | ||
378 | str_max = 32; | ||
379 | break; | ||
380 | default: | ||
381 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",381); } while(0);; | ||
382 | return GNUTLS_E_INVALID_REQUEST-50; | ||
383 | } | ||
384 | |||
385 | if (attr != NULL((void*)0)) | ||
| |||
386 | { | ||
387 | data = attr->value; | ||
388 | length = attr->value_len; | ||
389 | } | ||
390 | else if (str != NULL((void*)0)) | ||
| |||
391 | { | ||
392 | data = str; | ||
393 | length = p11_kit_space_strlen (str, str_max); | ||
394 | terminate = 1; | ||
395 | } | ||
396 | else if (version != NULL((void*)0)) | ||
| |||
397 | { | ||
398 | data = buf; | ||
399 | length = snprintf (buf, sizeof (buf), "%d.%d", (int)version->major, | ||
400 | (int)version->minor); | ||
401 | terminate = 1; | ||
402 | } | ||
403 | |||
404 | if (hexify) | ||
| |||
405 | { | ||
406 | /* terminate is assumed with hexify */ | ||
407 | if (*output_size < length * 3) | ||
408 | { | ||
409 | *output_size = length * 3; | ||
410 | return GNUTLS_E_SHORT_MEMORY_BUFFER-51; | ||
411 | } | ||
412 | if (output) | ||
413 | _gnutls_bin2hex (data, length, output, *output_size, ":"); | ||
414 | *output_size = length * 3; | ||
415 | return 0; | ||
416 | } | ||
417 | else | ||
418 | { | ||
419 | if (*output_size < length + terminate) | ||
| |||
420 | { | ||
421 | *output_size = length + terminate; | ||
422 | return GNUTLS_E_SHORT_MEMORY_BUFFER-51; | ||
423 | } | ||
424 | if (output) | ||
| |||
425 | { | ||
426 | memcpy (output, data, length); | ||
| |||
427 | if (terminate) | ||
428 | ((unsigned char*)output)[length] = '\0'; | ||
429 | } | ||
430 | *output_size = length + terminate; | ||
431 | } | ||
432 | |||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | static int init = 0; | ||
437 | |||
438 | /* tries to load modules from /etc/gnutls/pkcs11.conf if it exists | ||
439 | */ | ||
440 | static void _pkcs11_compat_init(const char* configfile) | ||
441 | { | ||
442 | FILE *fp; | ||
443 | int ret; | ||
444 | char line[512]; | ||
445 | const char *library; | ||
446 | |||
447 | if (configfile == NULL((void*)0)) | ||
448 | configfile = "/etc/gnutls/pkcs11.conf"; | ||
449 | |||
450 | fp = fopen (configfile, "r"); | ||
451 | if (fp == NULL((void*)0)) | ||
452 | { | ||
453 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",453); } while(0);; | ||
454 | return; | ||
455 | } | ||
456 | |||
457 | _gnutls_debug_log ("Loading PKCS #11 libraries from %s\n", configfile)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "Loading PKCS #11 libraries from %s\n", configfile); } while (0); | ||
458 | while (fgets (line, sizeof (line), fp) != NULL((void*)0)) | ||
459 | { | ||
460 | if (strncmp (line, "load", sizeof ("load") - 1) == 0) | ||
461 | { | ||
462 | char *p; | ||
463 | p = strchr (line, '='); | ||
464 | if (p == NULL((void*)0)) | ||
465 | continue; | ||
466 | |||
467 | library = ++p; | ||
468 | p = strchr (line, '\n'); | ||
469 | if (p != NULL((void*)0)) | ||
470 | *p = 0; | ||
471 | |||
472 | ret = gnutls_pkcs11_add_provider (library, NULL((void*)0)); | ||
473 | if (ret < 0) | ||
474 | { | ||
475 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",475); } while(0);; | ||
476 | _gnutls_debug_log ("Cannot load provider: %s\n", library)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "Cannot load provider: %s\n", library); } while(0); | ||
477 | continue; | ||
478 | } | ||
479 | } | ||
480 | } | ||
481 | fclose(fp); | ||
482 | |||
483 | return; | ||
484 | } | ||
485 | |||
486 | static int | ||
487 | initialize_automatic_p11_kit (void) | ||
488 | { | ||
489 | struct ck_function_list **modules; | ||
490 | const char *name; | ||
491 | ck_rv_t rv; | ||
492 | int i, ret; | ||
493 | |||
494 | rv = p11_kit_initialize_registered (); | ||
495 | if (rv != CKR_OK(0UL)) | ||
496 | { | ||
497 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",497); } while(0);; | ||
498 | _gnutls_debug_log ("Cannot initialize registered module: %s\n",do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "Cannot initialize registered module: %s\n", p11_kit_strerror (rv)); } while(0) | ||
499 | p11_kit_strerror (rv))do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "Cannot initialize registered module: %s\n", p11_kit_strerror (rv)); } while(0); | ||
500 | return GNUTLS_E_INTERNAL_ERROR-59; | ||
501 | } | ||
502 | |||
503 | initialized_registered = 1; | ||
504 | |||
505 | modules = p11_kit_registered_modules (); | ||
506 | for (i = 0; modules[i] != NULL((void*)0); i++) | ||
507 | { | ||
508 | name = p11_kit_registered_module_to_name (modules[i]); | ||
509 | ret = pkcs11_add_module (name, modules[i]); | ||
510 | if (ret != 0 && ret != GNUTLS_E_INT_RET_0-1251) | ||
511 | { | ||
512 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",512); } while(0);; | ||
513 | _gnutls_debug_log ("Cannot add registered module: %s\n", name)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "Cannot add registered module: %s\n", name); } while(0); | ||
514 | } | ||
515 | } | ||
516 | |||
517 | free (modules); | ||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | /** | ||
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 | ||
525 | * configuration file | ||
526 | * | ||
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. | ||
531 | * | ||
532 | * Normally you don't need to call this function since it is being called | ||
533 | * by gnutls_global_init() using the %GNUTLS_PKCS11_FLAG_AUTO. If other option | ||
534 | * is required then it must be called before it. | ||
535 | * | ||
536 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
537 | * negative error value. | ||
538 | * | ||
539 | * Since: 2.12.0 | ||
540 | **/ | ||
541 | int | ||
542 | gnutls_pkcs11_init (unsigned int flags, const char *deprecated_config_file) | ||
543 | { | ||
544 | int ret = 0; | ||
545 | |||
546 | if (init != 0) | ||
547 | { | ||
548 | init++; | ||
549 | return 0; | ||
550 | } | ||
551 | init++; | ||
552 | |||
553 | if (flags == GNUTLS_PKCS11_FLAG_MANUAL0) | ||
554 | return 0; | ||
555 | else if (flags == GNUTLS_PKCS11_FLAG_AUTO1) | ||
556 | { | ||
557 | if (deprecated_config_file == NULL((void*)0)) | ||
558 | ret = initialize_automatic_p11_kit (); | ||
559 | |||
560 | _pkcs11_compat_init(deprecated_config_file); | ||
561 | |||
562 | return ret; | ||
563 | } | ||
564 | |||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | /** | ||
569 | * gnutls_pkcs11_deinit: | ||
570 | * | ||
571 | * This function will deinitialize the PKCS 11 subsystem in gnutls. | ||
572 | * | ||
573 | * Since: 2.12.0 | ||
574 | **/ | ||
575 | void | ||
576 | gnutls_pkcs11_deinit (void) | ||
577 | { | ||
578 | int i; | ||
579 | |||
580 | init--; | ||
581 | if (init > 0) | ||
582 | return; | ||
583 | if (init < 0) | ||
584 | { | ||
585 | init = 0; | ||
586 | return; | ||
587 | } | ||
588 | |||
589 | for (i = 0; i < active_providers; i++) | ||
590 | { | ||
591 | if (providers[i].initialized) | ||
592 | p11_kit_finalize_module (providers[i].module); | ||
593 | } | ||
594 | active_providers = 0; | ||
595 | |||
596 | if (initialized_registered != 0) | ||
597 | p11_kit_finalize_registered (); | ||
598 | initialized_registered = 0; | ||
599 | } | ||
600 | |||
601 | /** | ||
602 | * gnutls_pkcs11_set_pin_function: | ||
603 | * @fn: The PIN callback, a gnutls_pkcs11_pin_callback_t() function. | ||
604 | * @userdata: data to be supplied to callback | ||
605 | * | ||
606 | * This function will set a callback function to be used when a PIN is | ||
607 | * required for PKCS 11 operations. See | ||
608 | * gnutls_pkcs11_pin_callback_t() on how the callback should behave. | ||
609 | * | ||
610 | * Since: 2.12.0 | ||
611 | **/ | ||
612 | void | ||
613 | gnutls_pkcs11_set_pin_function (gnutls_pkcs11_pin_callback_t fn, | ||
614 | void *userdata) | ||
615 | { | ||
616 | pin_func = fn; | ||
617 | pin_data = userdata; | ||
618 | } | ||
619 | |||
620 | /** | ||
621 | * gnutls_pkcs11_set_token_function: | ||
622 | * @fn: The token callback | ||
623 | * @userdata: data to be supplied to callback | ||
624 | * | ||
625 | * This function will set a callback function to be used when a token | ||
626 | * needs to be inserted to continue PKCS 11 operations. | ||
627 | * | ||
628 | * Since: 2.12.0 | ||
629 | **/ | ||
630 | void | ||
631 | gnutls_pkcs11_set_token_function (gnutls_pkcs11_token_callback_t fn, | ||
632 | void *userdata) | ||
633 | { | ||
634 | token_func = fn; | ||
635 | token_data = userdata; | ||
636 | } | ||
637 | |||
638 | int | ||
639 | pkcs11_url_to_info (const char *url, struct p11_kit_uri **info) | ||
640 | { | ||
641 | int allocated = 0; | ||
642 | int ret; | ||
643 | |||
644 | if (*info == NULL((void*)0)) | ||
645 | { | ||
646 | *info = p11_kit_uri_new (); | ||
647 | if (*info == NULL((void*)0)) | ||
648 | { | ||
649 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",649); } while(0);; | ||
650 | return GNUTLS_E_MEMORY_ERROR-25; | ||
651 | } | ||
652 | allocated = 1; | ||
653 | } | ||
654 | |||
655 | ret = p11_kit_uri_parse (url, P11_KIT_URI_FOR_ANY, *info); | ||
656 | if (ret < 0) | ||
657 | { | ||
658 | if (allocated) | ||
659 | { | ||
660 | p11_kit_uri_free (*info); | ||
661 | *info = NULL((void*)0); | ||
662 | } | ||
663 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",663); } while(0);; | ||
664 | return ret == P11_KIT_URI_NO_MEMORY ? | ||
665 | GNUTLS_E_MEMORY_ERROR-25 : GNUTLS_E_PARSING_ERROR-302; | ||
666 | } | ||
667 | |||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | int | ||
672 | pkcs11_info_to_url (struct p11_kit_uri *info, | ||
673 | gnutls_pkcs11_url_type_t detailed, char **url) | ||
674 | { | ||
675 | p11_kit_uri_type_t type = 0; | ||
676 | int ret; | ||
677 | |||
678 | switch (detailed) | ||
679 | { | ||
680 | case GNUTLS_PKCS11_URL_GENERIC: | ||
681 | type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN; | ||
682 | break; | ||
683 | case GNUTLS_PKCS11_URL_LIB: | ||
684 | type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE; | ||
685 | break; | ||
686 | case GNUTLS_PKCS11_URL_LIB_VERSION: | ||
687 | type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE | P11_KIT_URI_FOR_MODULE_WITH_VERSION; | ||
688 | break; | ||
689 | } | ||
690 | |||
691 | ret = p11_kit_uri_format (info, type, url); | ||
692 | if (ret < 0) | ||
693 | { | ||
694 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",694); } while(0);; | ||
695 | return ret == P11_KIT_URI_NO_MEMORY ? | ||
696 | GNUTLS_E_MEMORY_ERROR-25 : GNUTLS_E_INTERNAL_ERROR-59; | ||
697 | } | ||
698 | |||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | /** | ||
703 | * gnutls_pkcs11_obj_init: | ||
704 | * @obj: The structure to be initialized | ||
705 | * | ||
706 | * This function will initialize a pkcs11 certificate structure. | ||
707 | * | ||
708 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
709 | * negative error value. | ||
710 | * | ||
711 | * Since: 2.12.0 | ||
712 | **/ | ||
713 | int | ||
714 | gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t * obj) | ||
715 | { | ||
716 | *obj = gnutls_calloc (1, sizeof (struct gnutls_pkcs11_obj_st)); | ||
717 | if (*obj == NULL((void*)0)) | ||
718 | { | ||
719 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",719); } while(0);; | ||
720 | return GNUTLS_E_MEMORY_ERROR-25; | ||
721 | } | ||
722 | |||
723 | (*obj)->info = p11_kit_uri_new (); | ||
724 | if ((*obj)->info == NULL((void*)0)) | ||
725 | { | ||
726 | free (*obj); | ||
727 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",727); } while(0);; | ||
728 | return GNUTLS_E_MEMORY_ERROR-25; | ||
729 | } | ||
730 | |||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | /** | ||
735 | * gnutls_pkcs11_obj_deinit: | ||
736 | * @obj: The structure to be initialized | ||
737 | * | ||
738 | * This function will deinitialize a certificate structure. | ||
739 | * | ||
740 | * Since: 2.12.0 | ||
741 | **/ | ||
742 | void | ||
743 | gnutls_pkcs11_obj_deinit (gnutls_pkcs11_obj_t obj) | ||
744 | { | ||
745 | _gnutls_free_datum (&obj->raw)_gnutls_free_datum_m(&obj->raw, gnutls_free); | ||
746 | p11_kit_uri_free (obj->info); | ||
747 | free (obj); | ||
748 | } | ||
749 | |||
750 | /** | ||
751 | * gnutls_pkcs11_obj_export: | ||
752 | * @obj: Holds the object | ||
753 | * @output_data: will contain a certificate PEM or DER encoded | ||
754 | * @output_data_size: holds the size of output_data (and will be | ||
755 | * replaced by the actual size of parameters) | ||
756 | * | ||
757 | * This function will export the PKCS11 object data. It is normal for | ||
758 | * data to be inaccesible and in that case %GNUTLS_E_INVALID_REQUEST | ||
759 | * will be returned. | ||
760 | * | ||
761 | * If the buffer provided is not long enough to hold the output, then | ||
762 | * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will | ||
763 | * be returned. | ||
764 | * | ||
765 | * If the structure is PEM encoded, it will have a header | ||
766 | * of "BEGIN CERTIFICATE". | ||
767 | * | ||
768 | * Returns: In case of failure a negative error code will be | ||
769 | * returned, and %GNUTLS_E_SUCCESS (0) on success. | ||
770 | * | ||
771 | * Since: 2.12.0 | ||
772 | **/ | ||
773 | int | ||
774 | gnutls_pkcs11_obj_export (gnutls_pkcs11_obj_t obj, | ||
775 | void *output_data, size_t * output_data_size) | ||
776 | { | ||
777 | if (obj == NULL((void*)0) || obj->raw.data == NULL((void*)0)) | ||
778 | { | ||
779 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",779); } while(0);; | ||
780 | return GNUTLS_E_INVALID_REQUEST-50; | ||
781 | } | ||
782 | |||
783 | if (output_data == NULL((void*)0) || *output_data_size < obj->raw.size) | ||
784 | { | ||
785 | *output_data_size = obj->raw.size; | ||
786 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",786); } while(0);; | ||
787 | return GNUTLS_E_SHORT_MEMORY_BUFFER-51; | ||
788 | } | ||
789 | *output_data_size = obj->raw.size; | ||
790 | |||
791 | memcpy (output_data, obj->raw.data, obj->raw.size); | ||
792 | return 0; | ||
793 | } | ||
794 | |||
795 | int | ||
796 | pkcs11_find_object (struct ck_function_list ** _module, | ||
797 | ck_session_handle_t * _pks, | ||
798 | ck_object_handle_t * _obj, | ||
799 | struct p11_kit_uri *info, unsigned int flags) | ||
800 | { | ||
801 | int ret; | ||
802 | struct ck_function_list *module; | ||
803 | ck_session_handle_t pks; | ||
804 | ck_object_handle_t obj; | ||
805 | struct ck_attribute *attrs; | ||
806 | unsigned long attr_count; | ||
807 | unsigned long count; | ||
808 | ck_rv_t rv; | ||
809 | |||
810 | ret = pkcs11_open_session (&module, &pks, info, flags & SESSION_LOGIN(1<<1)); | ||
811 | if (ret < 0) | ||
812 | { | ||
813 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",813); } while(0);; | ||
814 | return ret; | ||
815 | } | ||
816 | |||
817 | attrs = p11_kit_uri_get_attributes (info, &attr_count); | ||
818 | rv = pkcs11_find_objects_init (module, pks, attrs, attr_count); | ||
819 | if (rv != CKR_OK(0UL)) | ||
820 | { | ||
821 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",821); } while(0);; | ||
822 | _gnutls_debug_log ("pk11: FindObjectsInit failed.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "pk11: FindObjectsInit failed.\n"); } while(0); | ||
823 | ret = pkcs11_rv_to_err (rv); | ||
824 | goto fail; | ||
825 | } | ||
826 | |||
827 | if (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK(0UL) && count == 1) | ||
828 | { | ||
829 | *_obj = obj; | ||
830 | *_pks = pks; | ||
831 | *_module = module; | ||
832 | pkcs11_find_objects_final (module, pks); | ||
833 | return 0; | ||
834 | } | ||
835 | |||
836 | ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; | ||
837 | pkcs11_find_objects_final (module, pks); | ||
838 | fail: | ||
839 | pkcs11_close_session (module, pks); | ||
840 | |||
841 | return ret; | ||
842 | } | ||
843 | |||
844 | int | ||
845 | pkcs11_find_slot (struct ck_function_list ** module, ck_slot_id_t * slot, | ||
846 | struct p11_kit_uri *info, struct token_info *_tinfo) | ||
847 | { | ||
848 | int x, z; | ||
849 | |||
850 | for (x = 0; x < active_providers; x++) | ||
851 | { | ||
852 | for (z = 0; z < providers[x].nslots; z++) | ||
853 | { | ||
854 | struct token_info tinfo; | ||
855 | |||
856 | if (pkcs11_get_token_info | ||
857 | (providers[x].module, providers[x].slots[z], | ||
858 | &tinfo.tinfo) != CKR_OK(0UL)) | ||
859 | { | ||
860 | continue; | ||
861 | } | ||
862 | tinfo.sid = providers[x].slots[z]; | ||
863 | tinfo.prov = &providers[x]; | ||
864 | |||
865 | if (pkcs11_get_slot_info | ||
866 | (providers[x].module, providers[x].slots[z], | ||
867 | &tinfo.sinfo) != CKR_OK(0UL)) | ||
868 | { | ||
869 | continue; | ||
870 | } | ||
871 | |||
872 | if (!p11_kit_uri_match_token_info (info, &tinfo.tinfo) || | ||
873 | !p11_kit_uri_match_module_info (info, &providers[x].info)) | ||
874 | { | ||
875 | continue; | ||
876 | } | ||
877 | |||
878 | /* ok found */ | ||
879 | *module = providers[x].module; | ||
880 | *slot = providers[x].slots[z]; | ||
881 | |||
882 | if (_tinfo != NULL((void*)0)) | ||
883 | memcpy (_tinfo, &tinfo, sizeof (tinfo)); | ||
884 | |||
885 | return 0; | ||
886 | } | ||
887 | } | ||
888 | |||
889 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",889); } while(0);; | ||
890 | return GNUTLS_E_PKCS11_REQUESTED_OBJECT_NOT_AVAILBLE-323; | ||
891 | } | ||
892 | |||
893 | int | ||
894 | pkcs11_open_session (struct ck_function_list ** _module, ck_session_handle_t * _pks, | ||
895 | struct p11_kit_uri *info, unsigned int flags) | ||
896 | { | ||
897 | ck_rv_t rv; | ||
898 | int ret; | ||
899 | ck_session_handle_t pks = 0; | ||
900 | struct ck_function_list *module; | ||
901 | ck_slot_id_t slot; | ||
902 | struct token_info tinfo; | ||
903 | |||
904 | ret = pkcs11_find_slot (&module, &slot, info, &tinfo); | ||
905 | if (ret < 0) | ||
906 | { | ||
907 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",907); } while(0);; | ||
908 | return ret; | ||
909 | } | ||
910 | |||
911 | rv = (module)->C_OpenSession (slot, | ||
912 | ((flags & SESSION_WRITE(1<<0)) | ||
913 | ? CKF_RW_SESSION(1UL << 1) : 0) | | ||
914 | CKF_SERIAL_SESSION(1UL << 2), NULL((void*)0), NULL((void*)0), &pks); | ||
915 | if (rv != CKR_OK(0UL)) | ||
916 | { | ||
917 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",917); } while(0);; | ||
918 | return pkcs11_rv_to_err (rv); | ||
919 | } | ||
920 | |||
921 | if (flags & SESSION_LOGIN(1<<1)) | ||
922 | { | ||
923 | ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO(1<<2)) ? 1 : 0); | ||
924 | if (ret < 0) | ||
925 | { | ||
926 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",926); } while(0);; | ||
927 | pkcs11_close_session (module, pks); | ||
928 | return ret; | ||
929 | } | ||
930 | } | ||
931 | |||
932 | /* ok found */ | ||
933 | *_pks = pks; | ||
934 | *_module = module; | ||
935 | return 0; | ||
936 | } | ||
937 | |||
938 | |||
939 | int | ||
940 | _pkcs11_traverse_tokens (find_func_t find_func, void *input, | ||
941 | struct p11_kit_uri *info, unsigned int flags) | ||
942 | { | ||
943 | ck_rv_t rv; | ||
944 | int found = 0, x, z, ret; | ||
945 | ck_session_handle_t pks = 0; | ||
946 | struct ck_function_list *module = NULL((void*)0); | ||
947 | |||
948 | for (x = 0; x < active_providers; x++) | ||
949 | { | ||
950 | module = providers[x].module; | ||
951 | for (z = 0; z < providers[x].nslots; z++) | ||
952 | { | ||
953 | struct token_info tinfo; | ||
954 | |||
955 | ret = GNUTLS_E_PKCS11_ERROR-300; | ||
956 | |||
957 | if (pkcs11_get_token_info (module, providers[x].slots[z], | ||
958 | &tinfo.tinfo) != CKR_OK(0UL)) | ||
959 | { | ||
960 | continue; | ||
961 | } | ||
962 | tinfo.sid = providers[x].slots[z]; | ||
963 | tinfo.prov = &providers[x]; | ||
964 | |||
965 | if (pkcs11_get_slot_info (module, providers[x].slots[z], | ||
966 | &tinfo.sinfo) != CKR_OK(0UL)) | ||
967 | { | ||
968 | continue; | ||
969 | } | ||
970 | |||
971 | rv = (module)->C_OpenSession (providers[x].slots[z], | ||
972 | ((flags & SESSION_WRITE(1<<0)) | ||
973 | ? CKF_RW_SESSION(1UL << 1) : 0) | | ||
974 | CKF_SERIAL_SESSION(1UL << 2), NULL((void*)0), NULL((void*)0), &pks); | ||
975 | if (rv != CKR_OK(0UL)) | ||
976 | { | ||
977 | continue; | ||
978 | } | ||
979 | |||
980 | if (flags & SESSION_LOGIN(1<<1)) | ||
981 | { | ||
982 | ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO(1<<2)) ? 1 : 0); | ||
983 | if (ret < 0) | ||
984 | { | ||
985 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",985); } while(0);; | ||
986 | return ret; | ||
987 | } | ||
988 | } | ||
989 | |||
990 | ret = find_func (module, pks, &tinfo, &providers[x].info, input); | ||
991 | |||
992 | if (ret == 0) | ||
993 | { | ||
994 | found = 1; | ||
995 | goto finish; | ||
996 | } | ||
997 | else | ||
998 | { | ||
999 | pkcs11_close_session (module, pks); | ||
1000 | pks = 0; | ||
1001 | } | ||
1002 | } | ||
1003 | } | ||
1004 | |||
1005 | finish: | ||
1006 | /* final call */ | ||
1007 | |||
1008 | if (found == 0) | ||
1009 | { | ||
1010 | if (module) | ||
1011 | ret = find_func (module, pks, NULL((void*)0), NULL((void*)0), input); | ||
1012 | else | ||
1013 | ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)gnutls_assert_val_int(-56, "pkcs11.c", 1013); | ||
1014 | } | ||
1015 | else | ||
1016 | { | ||
1017 | ret = 0; | ||
1018 | } | ||
1019 | |||
1020 | if (pks != 0 && module != NULL((void*)0)) | ||
1021 | { | ||
1022 | pkcs11_close_session (module, pks); | ||
1023 | } | ||
1024 | |||
1025 | return ret; | ||
1026 | } | ||
1027 | |||
1028 | /* imports a raw certificate from a token to a pkcs11_obj_t structure. | ||
1029 | */ | ||
1030 | static int | ||
1031 | pkcs11_obj_import (ck_object_class_t class, gnutls_pkcs11_obj_t obj, | ||
1032 | const gnutls_datum_t * data, | ||
1033 | const gnutls_datum_t * id, | ||
1034 | const gnutls_datum_t * label, | ||
1035 | struct ck_token_info *tinfo, struct ck_info *lib_info) | ||
1036 | { | ||
1037 | struct ck_attribute attr; | ||
1038 | int ret; | ||
1039 | |||
1040 | switch (class) | ||
1041 | { | ||
1042 | case CKO_CERTIFICATE(1UL): | ||
1043 | obj->type = GNUTLS_PKCS11_OBJ_X509_CRT; | ||
1044 | break; | ||
1045 | case CKO_PUBLIC_KEY(2UL): | ||
1046 | obj->type = GNUTLS_PKCS11_OBJ_PUBKEY; | ||
1047 | break; | ||
1048 | case CKO_PRIVATE_KEY(3UL): | ||
1049 | obj->type = GNUTLS_PKCS11_OBJ_PRIVKEY; | ||
1050 | break; | ||
1051 | case CKO_SECRET_KEY(4UL): | ||
1052 | obj->type = GNUTLS_PKCS11_OBJ_SECRET_KEY; | ||
1053 | break; | ||
1054 | case CKO_DATA(0UL): | ||
1055 | obj->type = GNUTLS_PKCS11_OBJ_DATA; | ||
1056 | break; | ||
1057 | default: | ||
1058 | obj->type = GNUTLS_PKCS11_OBJ_UNKNOWN; | ||
1059 | } | ||
1060 | |||
1061 | attr.type = CKA_CLASS(0UL); | ||
1062 | attr.value = &class; | ||
1063 | attr.value_len = sizeof (class); | ||
1064 | ret = p11_kit_uri_set_attribute (obj->info, &attr); | ||
1065 | if (ret < 0) | ||
1066 | { | ||
1067 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1067); } while(0);; | ||
1068 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1069 | } | ||
1070 | |||
1071 | if (data && data->data) | ||
1072 | { | ||
1073 | ret = _gnutls_set_datum (&obj->raw, data->data, data->size)_gnutls_set_datum_m(&obj->raw,data->data,data->size , gnutls_malloc); | ||
1074 | if (ret < 0) | ||
1075 | { | ||
1076 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1076); } while(0);; | ||
1077 | return ret; | ||
1078 | } | ||
1079 | } | ||
1080 | |||
1081 | /* copy the token and library info into the uri */ | ||
1082 | memcpy (p11_kit_uri_get_token_info (obj->info), tinfo, sizeof (struct ck_token_info)); | ||
1083 | memcpy (p11_kit_uri_get_module_info (obj->info), lib_info, sizeof (struct ck_info)); | ||
1084 | |||
1085 | if (label && label->data) | ||
1086 | { | ||
1087 | attr.type = CKA_LABEL(3UL); | ||
1088 | attr.value = label->data; | ||
1089 | attr.value_len = label->size; | ||
1090 | ret = p11_kit_uri_set_attribute (obj->info, &attr); | ||
1091 | if (ret < 0) | ||
1092 | { | ||
1093 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1093); } while(0);; | ||
1094 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1095 | } | ||
1096 | } | ||
1097 | |||
1098 | if (id && id->data) | ||
1099 | { | ||
1100 | attr.type = CKA_ID(0x102UL); | ||
1101 | attr.value = id->data; | ||
1102 | attr.value_len = id->size; | ||
1103 | ret = p11_kit_uri_set_attribute (obj->info, &attr); | ||
1104 | if (ret < 0) | ||
1105 | { | ||
1106 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1106); } while(0);; | ||
1107 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1108 | } | ||
1109 | } | ||
1110 | |||
1111 | return 0; | ||
1112 | } | ||
1113 | |||
1114 | static int read_pkcs11_pubkey(struct ck_function_list *module, | ||
1115 | ck_session_handle_t pks, ck_object_handle_t obj, | ||
1116 | ck_key_type_t key_type, gnutls_datum_t * pubkey) | ||
1117 | { | ||
1118 | struct ck_attribute a[4]; | ||
1119 | opaque tmp1[2048]; | ||
1120 | opaque tmp2[2048]; | ||
1121 | int ret; | ||
1122 | |||
1123 | switch (key_type) | ||
1124 | { | ||
1125 | case CKK_RSA(0UL): | ||
1126 | a[0].type = CKA_MODULUS(0x120UL); | ||
1127 | a[0].value = tmp1; | ||
1128 | a[0].value_len = sizeof (tmp1); | ||
1129 | a[1].type = CKA_PUBLIC_EXPONENT(0x122UL); | ||
1130 | a[1].value = tmp2; | ||
1131 | a[1].value_len = sizeof (tmp2); | ||
1132 | |||
1133 | if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK(0UL)) | ||
1134 | { | ||
1135 | |||
1136 | ret = | ||
1137 | _gnutls_set_datum (&pubkey[0],_gnutls_set_datum_m(&pubkey[0],a[0].value,a[0].value_len, gnutls_malloc) | ||
1138 | a[0].value, a[0].value_len)_gnutls_set_datum_m(&pubkey[0],a[0].value,a[0].value_len, gnutls_malloc); | ||
1139 | |||
1140 | if (ret >= 0) | ||
1141 | ret = | ||
1142 | _gnutls_set_datum (&pubkey_gnutls_set_datum_m(&pubkey [1],a[1].value,a[1].value_len , gnutls_malloc) | ||
1143 | [1], a[1].value, a[1].value_len)_gnutls_set_datum_m(&pubkey [1],a[1].value,a[1].value_len , gnutls_malloc); | ||
1144 | |||
1145 | if (ret < 0) | ||
1146 | { | ||
1147 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1147); } while(0);; | ||
1148 | _gnutls_free_datum (&pubkey[1])_gnutls_free_datum_m(&pubkey[1], gnutls_free); | ||
1149 | _gnutls_free_datum (&pubkey[0])_gnutls_free_datum_m(&pubkey[0], gnutls_free); | ||
1150 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1151 | } | ||
1152 | } | ||
1153 | else | ||
1154 | { | ||
1155 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1155); } while(0);; | ||
1156 | return GNUTLS_E_PKCS11_ERROR-300; | ||
1157 | } | ||
1158 | break; | ||
1159 | case CKK_DSA(1UL): | ||
1160 | a[0].type = CKA_PRIME(0x130UL); | ||
1161 | a[0].value = tmp1; | ||
1162 | a[0].value_len = sizeof (tmp1); | ||
1163 | a[1].type = CKA_SUBPRIME(0x131UL); | ||
1164 | a[1].value = tmp2; | ||
1165 | a[1].value_len = sizeof (tmp2); | ||
1166 | |||
1167 | if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK(0UL)) | ||
1168 | { | ||
1169 | ret = | ||
1170 | _gnutls_set_datum (&pubkey[0],_gnutls_set_datum_m(&pubkey[0],a[0].value,a[0].value_len, gnutls_malloc) | ||
1171 | a[0].value, a[0].value_len)_gnutls_set_datum_m(&pubkey[0],a[0].value,a[0].value_len, gnutls_malloc); | ||
1172 | |||
1173 | if (ret >= 0) | ||
1174 | ret = | ||
1175 | _gnutls_set_datum (&pubkey_gnutls_set_datum_m(&pubkey [1],a[1].value,a[1].value_len , gnutls_malloc) | ||
1176 | [1], a[1].value, a[1].value_len)_gnutls_set_datum_m(&pubkey [1],a[1].value,a[1].value_len , gnutls_malloc); | ||
1177 | |||
1178 | if (ret < 0) | ||
1179 | { | ||
1180 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1180); } while(0);; | ||
1181 | _gnutls_free_datum (&pubkey[1])_gnutls_free_datum_m(&pubkey[1], gnutls_free); | ||
1182 | _gnutls_free_datum (&pubkey[0])_gnutls_free_datum_m(&pubkey[0], gnutls_free); | ||
1183 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1184 | } | ||
1185 | } | ||
1186 | else | ||
1187 | { | ||
1188 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1188); } while(0);; | ||
1189 | return GNUTLS_E_PKCS11_ERROR-300; | ||
1190 | } | ||
1191 | |||
1192 | a[0].type = CKA_BASE(0x132UL); | ||
1193 | a[0].value = tmp1; | ||
1194 | a[0].value_len = sizeof (tmp1); | ||
1195 | a[1].type = CKA_VALUE(0x11UL); | ||
1196 | a[1].value = tmp2; | ||
1197 | a[1].value_len = sizeof (tmp2); | ||
1198 | |||
1199 | if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK(0UL)) | ||
1200 | { | ||
1201 | ret = | ||
1202 | _gnutls_set_datum (&pubkey[2],_gnutls_set_datum_m(&pubkey[2],a[0].value,a[0].value_len, gnutls_malloc) | ||
1203 | a[0].value, a[0].value_len)_gnutls_set_datum_m(&pubkey[2],a[0].value,a[0].value_len, gnutls_malloc); | ||
1204 | |||
1205 | if (ret >= 0) | ||
1206 | ret = | ||
1207 | _gnutls_set_datum (&pubkey_gnutls_set_datum_m(&pubkey [3],a[1].value,a[1].value_len , gnutls_malloc) | ||
1208 | [3], a[1].value, a[1].value_len)_gnutls_set_datum_m(&pubkey [3],a[1].value,a[1].value_len , gnutls_malloc); | ||
1209 | |||
1210 | if (ret < 0) | ||
1211 | { | ||
1212 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1212); } while(0);; | ||
1213 | _gnutls_free_datum (&pubkey[0])_gnutls_free_datum_m(&pubkey[0], gnutls_free); | ||
1214 | _gnutls_free_datum (&pubkey[1])_gnutls_free_datum_m(&pubkey[1], gnutls_free); | ||
1215 | _gnutls_free_datum (&pubkey[2])_gnutls_free_datum_m(&pubkey[2], gnutls_free); | ||
1216 | _gnutls_free_datum (&pubkey[3])_gnutls_free_datum_m(&pubkey[3], gnutls_free); | ||
1217 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1218 | } | ||
1219 | } | ||
1220 | else | ||
1221 | { | ||
1222 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1222); } while(0);; | ||
1223 | return GNUTLS_E_PKCS11_ERROR-300; | ||
1224 | } | ||
1225 | break; | ||
1226 | case CKK_ECDSA(3UL): | ||
1227 | a[0].type = CKA_EC_PARAMS(0x180UL); | ||
1228 | a[0].value = tmp1; | ||
1229 | a[0].value_len = sizeof (tmp1); | ||
1230 | a[1].type = CKA_EC_POINT(0x181UL); | ||
1231 | a[1].value = tmp2; | ||
1232 | a[1].value_len = sizeof (tmp2); | ||
1233 | |||
1234 | if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK(0UL)) | ||
1235 | { | ||
1236 | ret = | ||
1237 | _gnutls_set_datum (&pubkey[0],_gnutls_set_datum_m(&pubkey[0],a[0].value,a[0].value_len, gnutls_malloc) | ||
1238 | a[0].value, a[0].value_len)_gnutls_set_datum_m(&pubkey[0],a[0].value,a[0].value_len, gnutls_malloc); | ||
1239 | |||
1240 | if (ret >= 0) | ||
1241 | ret = | ||
1242 | _gnutls_set_datum (&pubkey_gnutls_set_datum_m(&pubkey [1],a[1].value,a[1].value_len , gnutls_malloc) | ||
1243 | [1], a[1].value, a[1].value_len)_gnutls_set_datum_m(&pubkey [1],a[1].value,a[1].value_len , gnutls_malloc); | ||
1244 | |||
1245 | if (ret < 0) | ||
1246 | { | ||
1247 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1247); } while(0);; | ||
1248 | _gnutls_free_datum (&pubkey[1])_gnutls_free_datum_m(&pubkey[1], gnutls_free); | ||
1249 | _gnutls_free_datum (&pubkey[0])_gnutls_free_datum_m(&pubkey[0], gnutls_free); | ||
1250 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1251 | } | ||
1252 | } | ||
1253 | else | ||
1254 | { | ||
1255 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1255); } while(0);; | ||
1256 | return GNUTLS_E_PKCS11_ERROR-300; | ||
1257 | } | ||
1258 | |||
1259 | break; | ||
1260 | default: | ||
1261 | return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE)gnutls_assert_val_int(-1250, "pkcs11.c", 1261); | ||
1262 | } | ||
1263 | |||
1264 | return 0; | ||
1265 | } | ||
1266 | |||
1267 | static int | ||
1268 | pkcs11_obj_import_pubkey (struct ck_function_list *module, | ||
1269 | ck_session_handle_t pks, | ||
1270 | ck_object_handle_t obj, | ||
1271 | gnutls_pkcs11_obj_t crt, | ||
1272 | const gnutls_datum_t * id, | ||
1273 | const gnutls_datum_t * label, | ||
1274 | struct ck_token_info *tinfo, | ||
1275 | struct ck_info *lib_info) | ||
1276 | { | ||
1277 | struct ck_attribute a[4]; | ||
1278 | ck_key_type_t key_type; | ||
1279 | int ret; | ||
1280 | ck_bool_t tval; | ||
1281 | |||
1282 | a[0].type = CKA_KEY_TYPE(0x100UL); | ||
1283 | a[0].value = &key_type; | ||
1284 | a[0].value_len = sizeof (key_type); | ||
1285 | |||
1286 | if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL)) | ||
1287 | { | ||
1288 | crt->pk_algorithm = mech_to_pk(key_type); | ||
1289 | |||
1290 | ret = read_pkcs11_pubkey(module, pks, obj, key_type, crt->pubkey); | ||
1291 | if (ret < 0) | ||
1292 | return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "pkcs11.c", 1292); | ||
1293 | } | ||
1294 | |||
1295 | /* read key usage flags */ | ||
1296 | a[0].type = CKA_ENCRYPT(0x104UL); | ||
1297 | a[0].value = &tval; | ||
1298 | a[0].value_len = sizeof (tval); | ||
1299 | |||
1300 | if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL)) | ||
1301 | { | ||
1302 | if (tval != 0) | ||
1303 | { | ||
1304 | crt->key_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT16; | ||
1305 | } | ||
1306 | } | ||
1307 | |||
1308 | a[0].type = CKA_VERIFY(0x10aUL); | ||
1309 | a[0].value = &tval; | ||
1310 | a[0].value_len = sizeof (tval); | ||
1311 | |||
1312 | if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL)) | ||
1313 | { | ||
1314 | if (tval != 0) | ||
1315 | { | ||
1316 | crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE128 | | ||
1317 | GNUTLS_KEY_KEY_CERT_SIGN4 | GNUTLS_KEY_CRL_SIGN2 | ||
1318 | | GNUTLS_KEY_NON_REPUDIATION64; | ||
1319 | } | ||
1320 | } | ||
1321 | |||
1322 | a[0].type = CKA_VERIFY_RECOVER(0x10bUL); | ||
1323 | a[0].value = &tval; | ||
1324 | a[0].value_len = sizeof (tval); | ||
1325 | |||
1326 | if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL)) | ||
1327 | { | ||
1328 | if (tval != 0) | ||
1329 | { | ||
1330 | crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE128 | | ||
1331 | GNUTLS_KEY_KEY_CERT_SIGN4 | GNUTLS_KEY_CRL_SIGN2 | ||
1332 | | GNUTLS_KEY_NON_REPUDIATION64; | ||
1333 | } | ||
1334 | } | ||
1335 | |||
1336 | a[0].type = CKA_DERIVE(0x10cUL); | ||
1337 | a[0].value = &tval; | ||
1338 | a[0].value_len = sizeof (tval); | ||
1339 | |||
1340 | if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL)) | ||
1341 | { | ||
1342 | if (tval != 0) | ||
1343 | { | ||
1344 | crt->key_usage |= GNUTLS_KEY_KEY_AGREEMENT8; | ||
1345 | } | ||
1346 | } | ||
1347 | |||
1348 | a[0].type = CKA_WRAP(0x106UL); | ||
1349 | a[0].value = &tval; | ||
1350 | a[0].value_len = sizeof (tval); | ||
1351 | |||
1352 | if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL)) | ||
1353 | { | ||
1354 | if (tval != 0) | ||
1355 | { | ||
1356 | crt->key_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT32; | ||
1357 | } | ||
1358 | } | ||
1359 | |||
1360 | return pkcs11_obj_import (CKO_PUBLIC_KEY(2UL), crt, NULL((void*)0), id, label, | ||
1361 | tinfo, lib_info); | ||
1362 | } | ||
1363 | |||
1364 | static int | ||
1365 | find_obj_url (struct ck_function_list *module, ck_session_handle_t pks, | ||
1366 | struct token_info *info, struct ck_info *lib_info, void *input) | ||
1367 | { | ||
1368 | struct url_find_data_st *find_data = input; | ||
1369 | struct ck_attribute a[4]; | ||
1370 | struct ck_attribute *attr; | ||
1371 | ck_object_class_t class = -1; | ||
1372 | ck_certificate_type_t type = -1; | ||
1373 | ck_rv_t rv; | ||
1374 | ck_object_handle_t obj; | ||
1375 | unsigned long count, a_vals; | ||
1376 | int found = 0, ret; | ||
1377 | opaque *cert_data = NULL((void*)0); | ||
1378 | char label_tmp[PKCS11_LABEL_SIZE128]; | ||
1379 | |||
1380 | if (info == NULL((void*)0)) | ||
1381 | { /* we don't support multiple calls */ | ||
1382 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1382); } while(0);; | ||
1383 | return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; | ||
1384 | } | ||
1385 | |||
1386 | /* do not bother reading the token if basic fields do not match | ||
1387 | */ | ||
1388 | if (!p11_kit_uri_match_token_info (find_data->crt->info, &info->tinfo) || | ||
1389 | !p11_kit_uri_match_module_info (find_data->crt->info, lib_info)) | ||
1390 | { | ||
1391 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1391); } while(0);; | ||
1392 | return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; | ||
1393 | } | ||
1394 | |||
1395 | attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID(0x102UL)); | ||
1396 | if (attr == NULL((void*)0)) | ||
1397 | { | ||
1398 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1398); } while(0);; | ||
1399 | return GNUTLS_E_INVALID_REQUEST-50; | ||
1400 | } | ||
1401 | |||
1402 | /* search the token for the id */ | ||
1403 | |||
1404 | cert_data = gnutls_malloc (MAX_CERT_SIZE8*1024); | ||
1405 | if (cert_data == NULL((void*)0)) | ||
1406 | { | ||
1407 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1407); } while(0);; | ||
1408 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1409 | } | ||
1410 | |||
1411 | /* Find objects with given class and type */ | ||
1412 | memcpy (a, attr, sizeof (struct ck_attribute)); | ||
1413 | a_vals = 1; | ||
1414 | |||
1415 | attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_CLASS(0UL)); | ||
1416 | if (attr) | ||
1417 | { | ||
1418 | if(attr->value && attr->value_len == sizeof (ck_object_class_t)) | ||
1419 | class = *((ck_object_class_t*)attr->value); | ||
1420 | if (class == CKO_CERTIFICATE(1UL)) | ||
1421 | type = CKC_X_509(0UL); | ||
1422 | memcpy (a + a_vals, attr, sizeof (struct ck_attribute)); | ||
1423 | a_vals++; | ||
1424 | } | ||
1425 | |||
1426 | if (type != -1) | ||
1427 | { | ||
1428 | a[a_vals].type = CKA_CERTIFICATE_TYPE(0x80UL); | ||
1429 | a[a_vals].value = &type; | ||
1430 | a[a_vals].value_len = sizeof type; | ||
1431 | a_vals++; | ||
1432 | } | ||
1433 | |||
1434 | rv = pkcs11_find_objects_init (module, pks, a, a_vals); | ||
1435 | if (rv != CKR_OK(0UL)) | ||
1436 | { | ||
1437 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1437); } while(0);; | ||
1438 | _gnutls_debug_log ("pk11: FindObjectsInit failed.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "pk11: FindObjectsInit failed.\n"); } while(0); | ||
1439 | ret = pkcs11_rv_to_err (rv); | ||
1440 | goto cleanup; | ||
1441 | } | ||
1442 | |||
1443 | while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK(0UL) && count == 1) | ||
1444 | { | ||
1445 | |||
1446 | a[0].type = CKA_VALUE(0x11UL); | ||
1447 | a[0].value = cert_data; | ||
1448 | a[0].value_len = MAX_CERT_SIZE8*1024; | ||
1449 | a[1].type = CKA_LABEL(3UL); | ||
1450 | a[1].value = label_tmp; | ||
1451 | a[1].value_len = sizeof (label_tmp); | ||
1452 | |||
1453 | if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK(0UL)) | ||
1454 | { | ||
1455 | gnutls_datum_t id; | ||
1456 | gnutls_datum_t data = { a[0].value, a[0].value_len }; | ||
1457 | gnutls_datum_t label = { a[1].value, a[1].value_len }; | ||
1458 | |||
1459 | attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID(0x102UL)); | ||
1460 | id.data = attr->value; | ||
1461 | id.size = attr->value_len; | ||
1462 | |||
1463 | if (class == CKO_PUBLIC_KEY(2UL)) | ||
1464 | { | ||
1465 | ret = | ||
1466 | pkcs11_obj_import_pubkey (module, pks, obj, | ||
1467 | find_data->crt, | ||
1468 | &id, &label, | ||
1469 | &info->tinfo, lib_info); | ||
1470 | } | ||
1471 | else | ||
1472 | { | ||
1473 | ret = | ||
1474 | pkcs11_obj_import (class, | ||
1475 | find_data->crt, | ||
1476 | &data, &id, &label, | ||
1477 | &info->tinfo, lib_info); | ||
1478 | } | ||
1479 | if (ret < 0) | ||
1480 | { | ||
1481 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1481); } while(0);; | ||
1482 | goto cleanup; | ||
1483 | } | ||
1484 | |||
1485 | found = 1; | ||
1486 | break; | ||
1487 | } | ||
1488 | else | ||
1489 | { | ||
1490 | _gnutls_debug_log ("pk11: Skipped cert, missing attrs.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "pk11: Skipped cert, missing attrs.\n"); } while(0); | ||
1491 | } | ||
1492 | } | ||
1493 | |||
1494 | if (found == 0) | ||
1495 | { | ||
1496 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1496); } while(0);; | ||
1497 | ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; | ||
1498 | } | ||
1499 | else | ||
1500 | { | ||
1501 | ret = 0; | ||
1502 | } | ||
1503 | |||
1504 | cleanup: | ||
1505 | gnutls_free (cert_data); | ||
1506 | pkcs11_find_objects_final (module, pks); | ||
1507 | |||
1508 | return ret; | ||
1509 | } | ||
1510 | |||
1511 | unsigned int | ||
1512 | pkcs11_obj_flags_to_int (unsigned int flags) | ||
1513 | { | ||
1514 | unsigned int ret_flags = 0; | ||
1515 | |||
1516 | if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN(1<<0)) | ||
1517 | ret_flags |= SESSION_LOGIN(1<<1); | ||
1518 | if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO(1<<3)) | ||
1519 | ret_flags |= SESSION_LOGIN(1<<1)|SESSION_SO(1<<2); | ||
1520 | |||
1521 | return ret_flags; | ||
1522 | } | ||
1523 | |||
1524 | /** | ||
1525 | * gnutls_pkcs11_obj_import_url: | ||
1526 | * @cert: The structure to store the parsed certificate | ||
1527 | * @url: a PKCS 11 url identifying the key | ||
1528 | * @flags: One of GNUTLS_PKCS11_OBJ_* flags | ||
1529 | * | ||
1530 | * This function will "import" a PKCS 11 URL identifying a certificate | ||
1531 | * key to the #gnutls_pkcs11_obj_t structure. This does not involve any | ||
1532 | * parsing (such as X.509 or OpenPGP) since the #gnutls_pkcs11_obj_t is | ||
1533 | * format agnostic. Only data are transferred. | ||
1534 | * | ||
1535 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
1536 | * negative error value. | ||
1537 | * | ||
1538 | * Since: 2.12.0 | ||
1539 | **/ | ||
1540 | int | ||
1541 | gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t cert, const char *url, | ||
1542 | unsigned int flags) | ||
1543 | { | ||
1544 | int ret; | ||
1545 | struct url_find_data_st find_data; | ||
1546 | |||
1547 | /* fill in the find data structure */ | ||
1548 | find_data.crt = cert; | ||
1549 | |||
1550 | ret = pkcs11_url_to_info (url, &cert->info); | ||
1551 | if (ret < 0) | ||
1552 | { | ||
1553 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1553); } while(0);; | ||
1554 | return ret; | ||
1555 | } | ||
1556 | |||
1557 | ret = | ||
1558 | _pkcs11_traverse_tokens (find_obj_url, &find_data, cert->info, | ||
1559 | pkcs11_obj_flags_to_int (flags)); | ||
1560 | |||
1561 | if (ret < 0) | ||
1562 | { | ||
1563 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1563); } while(0);; | ||
1564 | return ret; | ||
1565 | } | ||
1566 | |||
1567 | return 0; | ||
1568 | } | ||
1569 | |||
1570 | struct token_num | ||
1571 | { | ||
1572 | struct p11_kit_uri *info; | ||
1573 | unsigned int seq; /* which one we are looking for */ | ||
1574 | unsigned int current; /* which one are we now */ | ||
1575 | }; | ||
1576 | |||
1577 | static int | ||
1578 | find_token_num (struct ck_function_list *module, | ||
1579 | ck_session_handle_t pks, | ||
1580 | struct token_info *tinfo, | ||
1581 | struct ck_info *lib_info, void *input) | ||
1582 | { | ||
1583 | struct token_num *find_data = input; | ||
1584 | |||
1585 | if (tinfo == NULL((void*)0)) | ||
1586 | { /* we don't support multiple calls */ | ||
1587 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1587); } while(0);; | ||
1588 | return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; | ||
1589 | } | ||
1590 | |||
1591 | if (find_data->current == find_data->seq) | ||
1592 | { | ||
1593 | memcpy (p11_kit_uri_get_token_info (find_data->info), &tinfo->tinfo, sizeof (struct ck_token_info)); | ||
1594 | memcpy (p11_kit_uri_get_module_info (find_data->info), lib_info, sizeof (struct ck_info)); | ||
1595 | return 0; | ||
1596 | } | ||
1597 | |||
1598 | find_data->current++; | ||
1599 | /* search the token for the id */ | ||
1600 | |||
1601 | |||
1602 | return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; /* non zero is enough */ | ||
1603 | } | ||
1604 | |||
1605 | /** | ||
1606 | * gnutls_pkcs11_token_get_url: | ||
1607 | * @seq: sequence number starting from 0 | ||
1608 | * @detailed: non zero if a detailed URL is required | ||
1609 | * @url: will contain an allocated url | ||
1610 | * | ||
1611 | * This function will return the URL for each token available | ||
1612 | * in system. The url has to be released using gnutls_free() | ||
1613 | * | ||
1614 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, | ||
1615 | * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if the sequence number | ||
1616 | * exceeds the available tokens, otherwise a negative error value. | ||
1617 | * | ||
1618 | * Since: 2.12.0 | ||
1619 | **/ | ||
1620 | int | ||
1621 | gnutls_pkcs11_token_get_url (unsigned int seq, | ||
1622 | gnutls_pkcs11_url_type_t detailed, char **url) | ||
1623 | { | ||
1624 | int ret; | ||
1625 | struct token_num tn; | ||
1626 | |||
1627 | memset (&tn, 0, sizeof (tn)); | ||
1628 | tn.seq = seq; | ||
1629 | tn.info = p11_kit_uri_new (); | ||
1630 | |||
1631 | ret = _pkcs11_traverse_tokens (find_token_num, &tn, NULL((void*)0), 0); | ||
1632 | if (ret < 0) | ||
1633 | { | ||
1634 | p11_kit_uri_free (tn.info); | ||
1635 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1635); } while(0);; | ||
1636 | return ret; | ||
1637 | } | ||
1638 | |||
1639 | ret = pkcs11_info_to_url (tn.info, detailed, url); | ||
1640 | p11_kit_uri_free (tn.info); | ||
1641 | |||
1642 | if (ret < 0) | ||
1643 | { | ||
1644 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1644); } while(0);; | ||
1645 | return ret; | ||
1646 | } | ||
1647 | |||
1648 | return 0; | ||
1649 | |||
1650 | } | ||
1651 | |||
1652 | /** | ||
1653 | * gnutls_pkcs11_token_get_info: | ||
1654 | * @url: should contain a PKCS 11 URL | ||
1655 | * @ttype: Denotes the type of information requested | ||
1656 | * @output: where output will be stored | ||
1657 | * @output_size: contains the maximum size of the output and will be overwritten with actual | ||
1658 | * | ||
1659 | * This function will return information about the PKCS 11 token such | ||
1660 | * as the label, id, etc. | ||
1661 | * | ||
1662 | * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code | ||
1663 | * on error. | ||
1664 | * | ||
1665 | * Since: 2.12.0 | ||
1666 | **/ | ||
1667 | int | ||
1668 | gnutls_pkcs11_token_get_info (const char *url, | ||
1669 | gnutls_pkcs11_token_info_t ttype, | ||
1670 | void *output, size_t * output_size) | ||
1671 | { | ||
1672 | struct p11_kit_uri *info = NULL((void*)0); | ||
1673 | const char *str; | ||
1674 | size_t str_max; | ||
1675 | size_t len; | ||
1676 | int ret; | ||
1677 | |||
1678 | ret = pkcs11_url_to_info (url, &info); | ||
1679 | if (ret < 0) | ||
1680 | { | ||
1681 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1681); } while(0);; | ||
1682 | return ret; | ||
1683 | } | ||
1684 | |||
1685 | switch (ttype) | ||
1686 | { | ||
1687 | case GNUTLS_PKCS11_TOKEN_LABEL: | ||
1688 | str = p11_kit_uri_get_token_info (info)->label; | ||
1689 | str_max = 32; | ||
1690 | break; | ||
1691 | case GNUTLS_PKCS11_TOKEN_SERIAL: | ||
1692 | str = p11_kit_uri_get_token_info (info)->serial_number; | ||
1693 | str_max = 16; | ||
1694 | break; | ||
1695 | case GNUTLS_PKCS11_TOKEN_MANUFACTURER: | ||
1696 | str = p11_kit_uri_get_token_info (info)->manufacturer_id; | ||
1697 | str_max = 32; | ||
1698 | break; | ||
1699 | case GNUTLS_PKCS11_TOKEN_MODEL: | ||
1700 | str = p11_kit_uri_get_token_info (info)->model; | ||
1701 | str_max = 16; | ||
1702 | break; | ||
1703 | default: | ||
1704 | p11_kit_uri_free (info); | ||
1705 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1705); } while(0);; | ||
1706 | return GNUTLS_E_INVALID_REQUEST-50; | ||
1707 | } | ||
1708 | |||
1709 | len = p11_kit_space_strlen (str, str_max); | ||
1710 | |||
1711 | if (len + 1 > *output_size) | ||
1712 | { | ||
1713 | *output_size = len + 1; | ||
1714 | return GNUTLS_E_SHORT_MEMORY_BUFFER-51; | ||
1715 | } | ||
1716 | |||
1717 | memcpy (output, str, len); | ||
1718 | ((char*)output)[len] = '\0'; | ||
1719 | |||
1720 | *output_size = len; | ||
1721 | |||
1722 | p11_kit_uri_free (info); | ||
1723 | return 0; | ||
1724 | } | ||
1725 | |||
1726 | /** | ||
1727 | * gnutls_pkcs11_obj_export_url: | ||
1728 | * @obj: Holds the PKCS 11 certificate | ||
1729 | * @detailed: non zero if a detailed URL is required | ||
1730 | * @url: will contain an allocated url | ||
1731 | * | ||
1732 | * This function will export a URL identifying the given certificate. | ||
1733 | * | ||
1734 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
1735 | * negative error value. | ||
1736 | * | ||
1737 | * Since: 2.12.0 | ||
1738 | **/ | ||
1739 | int | ||
1740 | gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t obj, | ||
1741 | gnutls_pkcs11_url_type_t detailed, char **url) | ||
1742 | { | ||
1743 | int ret; | ||
1744 | |||
1745 | ret = pkcs11_info_to_url (obj->info, detailed, url); | ||
1746 | if (ret < 0) | ||
1747 | { | ||
1748 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1748); } while(0);; | ||
1749 | return ret; | ||
1750 | } | ||
1751 | |||
1752 | return 0; | ||
1753 | } | ||
1754 | |||
1755 | /** | ||
1756 | * gnutls_pkcs11_obj_get_type: | ||
1757 | * @obj: Holds the PKCS 11 object | ||
1758 | * | ||
1759 | * This function will return the type of the certificate being | ||
1760 | * stored in the structure. | ||
1761 | * | ||
1762 | * Returns: The type of the certificate. | ||
1763 | * | ||
1764 | * Since: 2.12.0 | ||
1765 | **/ | ||
1766 | gnutls_pkcs11_obj_type_t | ||
1767 | gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t obj) | ||
1768 | { | ||
1769 | return obj->type; | ||
1770 | } | ||
1771 | |||
1772 | struct pkey_list | ||
1773 | { | ||
1774 | gnutls_buffer_st *key_ids; | ||
1775 | size_t key_ids_size; | ||
1776 | }; | ||
1777 | |||
1778 | |||
1779 | static int | ||
1780 | retrieve_pin_for_pinfile (const char *pinfile, struct ck_token_info *token_info, | ||
1781 | int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin) | ||
1782 | { | ||
1783 | unsigned int flags = 0; | ||
1784 | struct p11_kit_uri *token_uri; | ||
1785 | struct p11_kit_pin *result; | ||
1786 | char *label; | ||
1787 | |||
1788 | label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label)); | ||
1789 | if (label == NULL((void*)0)) | ||
1790 | { | ||
1791 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1791); } while(0);; | ||
1792 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1793 | } | ||
1794 | |||
1795 | token_uri = p11_kit_uri_new (); | ||
1796 | if (token_uri == NULL((void*)0)) | ||
1797 | { | ||
1798 | free (label); | ||
1799 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1799); } while(0);; | ||
1800 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1801 | } | ||
1802 | |||
1803 | memcpy (p11_kit_uri_get_token_info (token_uri), token_info, | ||
1804 | sizeof (struct ck_token_info)); | ||
1805 | |||
1806 | if (attempts) | ||
1807 | flags |= P11_KIT_PIN_FLAGS_RETRY; | ||
1808 | if (user_type == CKU_USER(1UL)) | ||
1809 | { | ||
1810 | flags |= P11_KIT_PIN_FLAGS_USER_LOGIN; | ||
1811 | if (token_info->flags & CKF_USER_PIN_COUNT_LOW(1UL << 16)) | ||
1812 | flags |= P11_KIT_PIN_FLAGS_MANY_TRIES; | ||
1813 | if (token_info->flags & CKF_USER_PIN_FINAL_TRY(1UL << 17)) | ||
1814 | flags |= P11_KIT_PIN_FLAGS_FINAL_TRY; | ||
1815 | } | ||
1816 | else if (user_type == CKU_SO(0UL)) | ||
1817 | { | ||
1818 | flags |= P11_KIT_PIN_FLAGS_SO_LOGIN; | ||
1819 | if (token_info->flags & CKF_SO_PIN_COUNT_LOW(1UL << 20)) | ||
1820 | flags |= P11_KIT_PIN_FLAGS_MANY_TRIES; | ||
1821 | if (token_info->flags & CKF_SO_PIN_FINAL_TRY(1UL << 21)) | ||
1822 | flags |= P11_KIT_PIN_FLAGS_FINAL_TRY; | ||
1823 | } | ||
1824 | else if (user_type == CKU_CONTEXT_SPECIFIC(2UL)) | ||
1825 | { | ||
1826 | flags |= P11_KIT_PIN_FLAGS_CONTEXT_LOGIN; | ||
1827 | } | ||
1828 | |||
1829 | result = p11_kit_pin_request (pinfile, token_uri, label, flags); | ||
1830 | p11_kit_uri_free (token_uri); | ||
1831 | free (label); | ||
1832 | |||
1833 | if (result == NULL((void*)0)) | ||
1834 | { | ||
1835 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1835); } while(0);; | ||
1836 | return GNUTLS_E_PKCS11_PIN_ERROR-303; | ||
1837 | } | ||
1838 | |||
1839 | *pin = result; | ||
1840 | return 0; | ||
1841 | } | ||
1842 | |||
1843 | static int | ||
1844 | retrieve_pin_for_callback (struct ck_token_info *token_info, int attempts, | ||
1845 | ck_user_type_t user_type, struct p11_kit_pin **pin) | ||
1846 | { | ||
1847 | char pin_value[GNUTLS_PKCS11_MAX_PIN_LEN32]; | ||
1848 | unsigned int flags = 0; | ||
1849 | char *token_str; | ||
1850 | char *label; | ||
1851 | struct p11_kit_uri *token_uri; | ||
1852 | int ret = 0; | ||
1853 | |||
1854 | label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label)); | ||
1855 | if (label == NULL((void*)0)) | ||
1856 | { | ||
1857 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1857); } while(0);; | ||
1858 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1859 | } | ||
1860 | |||
1861 | token_uri = p11_kit_uri_new (); | ||
1862 | if (token_uri == NULL((void*)0)) | ||
1863 | { | ||
1864 | free (label); | ||
1865 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1865); } while(0);; | ||
1866 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1867 | } | ||
1868 | |||
1869 | memcpy (p11_kit_uri_get_token_info (token_uri), token_info, | ||
1870 | sizeof (struct ck_token_info)); | ||
1871 | ret = pkcs11_info_to_url (token_uri, 1, &token_str); | ||
1872 | p11_kit_uri_free (token_uri); | ||
1873 | |||
1874 | if (ret < 0) | ||
1875 | { | ||
1876 | free (label); | ||
1877 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1877); } while(0);; | ||
1878 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1879 | } | ||
1880 | |||
1881 | if (user_type == CKU_USER(1UL)) | ||
1882 | { | ||
1883 | flags |= GNUTLS_PKCS11_PIN_USER; | ||
1884 | if (token_info->flags & CKF_USER_PIN_COUNT_LOW(1UL << 16)) | ||
1885 | flags |= GNUTLS_PKCS11_PIN_COUNT_LOW; | ||
1886 | if (token_info->flags & CKF_USER_PIN_FINAL_TRY(1UL << 17)) | ||
1887 | flags |= GNUTLS_PKCS11_PIN_FINAL_TRY; | ||
1888 | } | ||
1889 | else if (user_type == CKU_SO(0UL)) | ||
1890 | { | ||
1891 | flags |= GNUTLS_PKCS11_PIN_SO; | ||
1892 | if (token_info->flags & CKF_SO_PIN_COUNT_LOW(1UL << 20)) | ||
1893 | flags |= GNUTLS_PKCS11_PIN_COUNT_LOW; | ||
1894 | if (token_info->flags & CKF_SO_PIN_FINAL_TRY(1UL << 21)) | ||
1895 | flags |= GNUTLS_PKCS11_PIN_FINAL_TRY; | ||
1896 | } | ||
1897 | |||
1898 | if (attempts > 0) | ||
1899 | flags |= GNUTLS_PKCS11_PIN_WRONG; | ||
1900 | |||
1901 | ret = pin_func (pin_data, attempts, (char*)token_str, label, | ||
1902 | flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN32); | ||
1903 | free (token_str); | ||
1904 | free (label); | ||
1905 | |||
1906 | if (ret < 0) | ||
1907 | return gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR)gnutls_assert_val_int(-303, "pkcs11.c", 1907); | ||
1908 | |||
1909 | *pin = p11_kit_pin_new_for_string (pin_value); | ||
1910 | |||
1911 | if (*pin == NULL((void*)0)) | ||
1912 | return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR)gnutls_assert_val_int(-59, "pkcs11.c", 1912); | ||
1913 | |||
1914 | return 0; | ||
1915 | } | ||
1916 | |||
1917 | static int | ||
1918 | retrieve_pin (struct p11_kit_uri *info, struct ck_token_info *token_info, | ||
1919 | int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin) | ||
1920 | { | ||
1921 | const char *pinfile; | ||
1922 | |||
1923 | *pin = NULL((void*)0); | ||
1924 | |||
1925 | /* Check if a pinfile is specified, and use that if possible */ | ||
1926 | pinfile = p11_kit_uri_get_pinfile (info); | ||
1927 | if (pinfile != NULL((void*)0)) | ||
1928 | { | ||
1929 | _gnutls_debug_log("pk11: Using pinfile to retrieve PIN\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "pk11: Using pinfile to retrieve PIN\n"); } while(0); | ||
1930 | return retrieve_pin_for_pinfile (pinfile, token_info, attempts, user_type, pin); | ||
1931 | } | ||
1932 | |||
1933 | /* The global gnutls pin callback */ | ||
1934 | else if (pin_func) | ||
1935 | return retrieve_pin_for_callback (token_info, attempts, user_type, pin); | ||
1936 | |||
1937 | /* Otherwise, PIN entry is necessary for login, so fail if there's | ||
1938 | * no callback. */ | ||
1939 | else | ||
1940 | { | ||
1941 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1941); } while(0);; | ||
1942 | _gnutls_debug_log ("pk11: No pin callback but login required.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "pk11: No pin callback but login required.\n"); } while( 0); | ||
1943 | return GNUTLS_E_PKCS11_ERROR-300; | ||
1944 | } | ||
1945 | } | ||
1946 | |||
1947 | int | ||
1948 | pkcs11_login (struct ck_function_list * module, ck_session_handle_t pks, | ||
1949 | const struct token_info *tokinfo, struct p11_kit_uri *info, int so) | ||
1950 | { | ||
1951 | struct ck_session_info session_info; | ||
1952 | int attempt = 0, ret; | ||
1953 | ck_user_type_t user_type; | ||
1954 | ck_rv_t rv; | ||
1955 | |||
1956 | user_type = (so == 0) ? CKU_USER(1UL) : CKU_SO(0UL); | ||
1957 | if (so == 0 && (tokinfo->tinfo.flags & CKF_LOGIN_REQUIRED(1UL << 2)) == 0) | ||
1958 | { | ||
1959 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1959); } while(0);; | ||
1960 | _gnutls_debug_log ("pk11: No login required.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "pk11: No login required.\n"); } while(0); | ||
1961 | return 0; | ||
1962 | } | ||
1963 | |||
1964 | /* For a token with a "protected" (out-of-band) authentication | ||
1965 | * path, calling login with a NULL username is all that is | ||
1966 | * required. */ | ||
1967 | if (tokinfo->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH(1UL << 8)) | ||
1968 | { | ||
1969 | rv = (module)->C_Login (pks, (so == 0) ? CKU_USER(1UL) : CKU_SO(0UL), NULL((void*)0), 0); | ||
1970 | if (rv == CKR_OK(0UL) || rv == CKR_USER_ALREADY_LOGGED_IN(0x100UL)) | ||
1971 | { | ||
1972 | return 0; | ||
1973 | } | ||
1974 | else | ||
1975 | { | ||
1976 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",1976); } while(0);; | ||
1977 | _gnutls_debug_log ("pk11: Protected login failed.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "pk11: Protected login failed.\n"); } while(0); | ||
1978 | ret = GNUTLS_E_PKCS11_ERROR-300; | ||
1979 | goto cleanup; | ||
1980 | } | ||
1981 | } | ||
1982 | |||
1983 | do | ||
1984 | { | ||
1985 | struct p11_kit_pin *pin; | ||
1986 | struct ck_token_info tinfo; | ||
1987 | |||
1988 | memcpy (&tinfo, &tokinfo->tinfo, sizeof(tinfo)); | ||
1989 | |||
1990 | /* Check whether the session is already logged in, and if so, just skip */ | ||
1991 | rv = (module)->C_GetSessionInfo (pks, &session_info); | ||
1992 | if (rv == CKR_OK(0UL) && (session_info.state == CKS_RO_USER_FUNCTIONS(1UL) || | ||
1993 | session_info.state == CKS_RW_USER_FUNCTIONS(3UL))) | ||
1994 | { | ||
1995 | ret = 0; | ||
1996 | goto cleanup; | ||
1997 | } | ||
1998 | |||
1999 | /* If login has been attempted once already, check the token | ||
2000 | * status again, the flags might change. */ | ||
2001 | if (attempt) | ||
2002 | { | ||
2003 | if (pkcs11_get_token_info | ||
2004 | (tokinfo->prov->module, tokinfo->sid, &tinfo) != CKR_OK(0UL)) | ||
2005 | { | ||
2006 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2006); } while(0);; | ||
2007 | _gnutls_debug_log ("pk11: GetTokenInfo failed\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "pk11: GetTokenInfo failed\n"); } while(0); | ||
2008 | ret = GNUTLS_E_PKCS11_ERROR-300; | ||
2009 | goto cleanup; | ||
2010 | } | ||
2011 | } | ||
2012 | |||
2013 | ret = retrieve_pin (info, &tinfo, attempt++, user_type, &pin); | ||
2014 | if (ret < 0) | ||
2015 | { | ||
2016 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2016); } while(0);; | ||
2017 | goto cleanup; | ||
2018 | } | ||
2019 | |||
2020 | rv = (module)->C_Login (pks, user_type, | ||
2021 | (unsigned char *)p11_kit_pin_get_value (pin, NULL((void*)0)), | ||
2022 | p11_kit_pin_get_length (pin)); | ||
2023 | |||
2024 | p11_kit_pin_unref (pin); | ||
2025 | } | ||
2026 | while (rv == CKR_PIN_INCORRECT(0xa0UL)); | ||
2027 | |||
2028 | _gnutls_debug_log ("pk11: Login result = %lu\n", rv)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "pk11: Login result = %lu\n", rv); } while(0); | ||
2029 | |||
2030 | |||
2031 | ret = (rv == CKR_OK(0UL) | ||
2032 | || rv == CKR_USER_ALREADY_LOGGED_IN(0x100UL)) ? 0 : pkcs11_rv_to_err (rv); | ||
2033 | |||
2034 | cleanup: | ||
2035 | return ret; | ||
2036 | } | ||
2037 | |||
2038 | int | ||
2039 | pkcs11_call_token_func (struct p11_kit_uri *info, const unsigned retry) | ||
2040 | { | ||
2041 | struct ck_token_info *tinfo; | ||
2042 | char *label; | ||
2043 | int ret = 0; | ||
2044 | |||
2045 | tinfo = p11_kit_uri_get_token_info (info); | ||
2046 | label = p11_kit_space_strdup (tinfo->label, sizeof (tinfo->label)); | ||
2047 | ret = (token_func) (token_data, label, retry); | ||
2048 | free (label); | ||
2049 | |||
2050 | return ret; | ||
2051 | } | ||
2052 | |||
2053 | |||
2054 | static int | ||
2055 | find_privkeys (struct ck_function_list *module, ck_session_handle_t pks, | ||
2056 | struct token_info *info, struct pkey_list *list) | ||
2057 | { | ||
2058 | struct ck_attribute a[3]; | ||
2059 | ck_object_class_t class; | ||
2060 | ck_rv_t rv; | ||
2061 | ck_object_handle_t obj; | ||
2062 | unsigned long count, current; | ||
2063 | char certid_tmp[PKCS11_ID_SIZE128]; | ||
2064 | |||
2065 | class = CKO_PRIVATE_KEY(3UL); | ||
2066 | |||
2067 | /* Find an object with private key class and a certificate ID | ||
2068 | * which matches the certificate. */ | ||
2069 | /* FIXME: also match the cert subject. */ | ||
2070 | a[0].type = CKA_CLASS(0UL); | ||
2071 | a[0].value = &class; | ||
2072 | a[0].value_len = sizeof class; | ||
2073 | |||
2074 | rv = pkcs11_find_objects_init (module, pks, a, 1); | ||
2075 | if (rv != CKR_OK(0UL)) | ||
2076 | { | ||
2077 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2077); } while(0);; | ||
2078 | return pkcs11_rv_to_err (rv); | ||
2079 | } | ||
2080 | |||
2081 | list->key_ids_size = 0; | ||
2082 | while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK(0UL) && count == 1) | ||
2083 | { | ||
2084 | list->key_ids_size++; | ||
2085 | } | ||
2086 | |||
2087 | pkcs11_find_objects_final (module, pks); | ||
2088 | |||
2089 | if (list->key_ids_size == 0) | ||
2090 | { | ||
2091 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2091); } while(0);; | ||
2092 | return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; | ||
2093 | } | ||
2094 | |||
2095 | list->key_ids = | ||
2096 | gnutls_malloc (sizeof (gnutls_buffer_st) * list->key_ids_size); | ||
2097 | if (list->key_ids == NULL((void*)0)) | ||
2098 | { | ||
2099 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2099); } while(0);; | ||
2100 | return GNUTLS_E_MEMORY_ERROR-25; | ||
2101 | } | ||
2102 | |||
2103 | /* actual search */ | ||
2104 | a[0].type = CKA_CLASS(0UL); | ||
2105 | a[0].value = &class; | ||
2106 | a[0].value_len = sizeof class; | ||
2107 | |||
2108 | rv = pkcs11_find_objects_init (module, pks, a, 1); | ||
2109 | if (rv != CKR_OK(0UL)) | ||
2110 | { | ||
2111 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2111); } while(0);; | ||
2112 | return pkcs11_rv_to_err (rv); | ||
2113 | } | ||
2114 | |||
2115 | current = 0; | ||
2116 | while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK(0UL) && count == 1) | ||
2117 | { | ||
2118 | |||
2119 | a[0].type = CKA_ID(0x102UL); | ||
2120 | a[0].value = certid_tmp; | ||
2121 | a[0].value_len = sizeof (certid_tmp); | ||
2122 | |||
2123 | _gnutls_buffer_init (&list->key_ids[current]); | ||
2124 | |||
2125 | if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL)) | ||
2126 | { | ||
2127 | _gnutls_buffer_append_data (&list->key_ids[current], | ||
2128 | a[0].value, a[0].value_len); | ||
2129 | current++; | ||
2130 | } | ||
2131 | |||
2132 | if (current > list->key_ids_size) | ||
2133 | break; | ||
2134 | } | ||
2135 | |||
2136 | pkcs11_find_objects_final (module, pks); | ||
2137 | |||
2138 | list->key_ids_size = current - 1; | ||
2139 | |||
2140 | return 0; | ||
2141 | } | ||
2142 | |||
2143 | /* Recover certificate list from tokens */ | ||
2144 | |||
2145 | |||
2146 | static int | ||
2147 | find_objs (struct ck_function_list * module, ck_session_handle_t pks, | ||
2148 | struct token_info *info, struct ck_info *lib_info, void *input) | ||
2149 | { | ||
2150 | struct crt_find_data_st *find_data = input; | ||
2151 | struct ck_attribute a[4]; | ||
2152 | struct ck_attribute *attr; | ||
2153 | ck_object_class_t class = -1; | ||
2154 | ck_certificate_type_t type = -1; | ||
2155 | unsigned int trusted; | ||
2156 | ck_rv_t rv; | ||
2157 | ck_object_handle_t obj; | ||
2158 | unsigned long count; | ||
2159 | opaque *cert_data; | ||
2160 | char certid_tmp[PKCS11_ID_SIZE128]; | ||
2161 | char label_tmp[PKCS11_LABEL_SIZE128]; | ||
2162 | int ret, i; | ||
2163 | struct pkey_list plist; /* private key holder */ | ||
2164 | int tot_values = 0; | ||
2165 | |||
2166 | if (info == NULL((void*)0)) | ||
2167 | { /* final call */ | ||
2168 | if (find_data->current <= *find_data->n_list) | ||
2169 | ret = 0; | ||
2170 | else | ||
2171 | ret = GNUTLS_E_SHORT_MEMORY_BUFFER-51; | ||
2172 | |||
2173 | *find_data->n_list = find_data->current; | ||
2174 | |||
2175 | return ret; | ||
2176 | } | ||
2177 | |||
2178 | /* do not bother reading the token if basic fields do not match | ||
2179 | */ | ||
2180 | if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) || | ||
2181 | !p11_kit_uri_match_module_info (find_data->info, lib_info)) | ||
2182 | { | ||
2183 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2183); } while(0);; | ||
2184 | return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; | ||
2185 | } | ||
2186 | |||
2187 | memset (&plist, 0, sizeof (plist)); | ||
2188 | |||
2189 | if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY) | ||
2190 | { | ||
2191 | ret = find_privkeys (module, pks, info, &plist); | ||
2192 | if (ret < 0) | ||
2193 | { | ||
2194 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2194); } while(0);; | ||
2195 | return ret; | ||
2196 | } | ||
2197 | |||
2198 | if (plist.key_ids_size == 0) | ||
2199 | { | ||
2200 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2200); } while(0);; | ||
2201 | return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; | ||
2202 | } | ||
2203 | } | ||
2204 | |||
2205 | cert_data = gnutls_malloc (MAX_CERT_SIZE8*1024); | ||
2206 | if (cert_data == NULL((void*)0)) | ||
2207 | { | ||
2208 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2208); } while(0);; | ||
2209 | return GNUTLS_E_MEMORY_ERROR-25; | ||
2210 | } | ||
2211 | |||
2212 | /* Find objects with cert class and X.509 cert type. */ | ||
2213 | |||
2214 | tot_values = 0; | ||
2215 | |||
2216 | if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL | ||
2217 | || find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY) | ||
2218 | { | ||
2219 | class = CKO_CERTIFICATE(1UL); | ||
2220 | type = CKC_X_509(0UL); | ||
2221 | trusted = 1; | ||
2222 | |||
2223 | a[tot_values].type = CKA_CLASS(0UL); | ||
2224 | a[tot_values].value = &class; | ||
2225 | a[tot_values].value_len = sizeof class; | ||
2226 | tot_values++; | ||
2227 | |||
2228 | a[tot_values].type = CKA_CERTIFICATE_TYPE(0x80UL); | ||
2229 | a[tot_values].value = &type; | ||
2230 | a[tot_values].value_len = sizeof type; | ||
2231 | tot_values++; | ||
2232 | |||
2233 | } | ||
2234 | else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED) | ||
2235 | { | ||
2236 | class = CKO_CERTIFICATE(1UL); | ||
2237 | type = CKC_X_509(0UL); | ||
2238 | trusted = 1; | ||
2239 | |||
2240 | a[tot_values].type = CKA_CLASS(0UL); | ||
2241 | a[tot_values].value = &class; | ||
2242 | a[tot_values].value_len = sizeof class; | ||
2243 | tot_values++; | ||
2244 | |||
2245 | a[tot_values].type = CKA_TRUSTED(0x86UL); | ||
2246 | a[tot_values].value = &trusted; | ||
2247 | a[tot_values].value_len = sizeof trusted; | ||
2248 | tot_values++; | ||
2249 | |||
2250 | } | ||
2251 | else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PUBKEY) | ||
2252 | { | ||
2253 | class = CKO_PUBLIC_KEY(2UL); | ||
2254 | |||
2255 | a[tot_values].type = CKA_CLASS(0UL); | ||
2256 | a[tot_values].value = &class; | ||
2257 | a[tot_values].value_len = sizeof class; | ||
2258 | tot_values++; | ||
2259 | } | ||
2260 | else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY) | ||
2261 | { | ||
2262 | class = CKO_PRIVATE_KEY(3UL); | ||
2263 | |||
2264 | a[tot_values].type = CKA_CLASS(0UL); | ||
2265 | a[tot_values].value = &class; | ||
2266 | a[tot_values].value_len = sizeof class; | ||
2267 | tot_values++; | ||
2268 | } | ||
2269 | else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL) | ||
2270 | { | ||
2271 | if (class != -1) | ||
2272 | { | ||
2273 | a[tot_values].type = CKA_CLASS(0UL); | ||
2274 | a[tot_values].value = &class; | ||
2275 | a[tot_values].value_len = sizeof class; | ||
2276 | tot_values++; | ||
2277 | } | ||
2278 | if (type != -1) | ||
2279 | { | ||
2280 | a[tot_values].type = CKA_CERTIFICATE_TYPE(0x80UL); | ||
2281 | a[tot_values].value = &type; | ||
2282 | a[tot_values].value_len = sizeof type; | ||
2283 | tot_values++; | ||
2284 | } | ||
2285 | } | ||
2286 | else | ||
2287 | { | ||
2288 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2288); } while(0);; | ||
2289 | ret = GNUTLS_E_INVALID_REQUEST-50; | ||
2290 | goto fail; | ||
2291 | } | ||
2292 | |||
2293 | attr = p11_kit_uri_get_attribute (find_data->info, CKA_ID(0x102UL)); | ||
2294 | if (attr != NULL((void*)0)) | ||
2295 | { | ||
2296 | memcpy (a + tot_values, attr, sizeof (struct ck_attribute)); | ||
2297 | tot_values++; | ||
2298 | } | ||
2299 | |||
2300 | rv = pkcs11_find_objects_init (module, pks, a, tot_values); | ||
2301 | if (rv != CKR_OK(0UL)) | ||
2302 | { | ||
2303 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2303); } while(0);; | ||
2304 | _gnutls_debug_log ("pk11: FindObjectsInit failed.\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "pk11: FindObjectsInit failed.\n"); } while(0); | ||
2305 | return pkcs11_rv_to_err (rv); | ||
2306 | } | ||
2307 | |||
2308 | while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK(0UL) && count == 1) | ||
2309 | { | ||
2310 | gnutls_datum_t label, id, value; | ||
2311 | |||
2312 | a[0].type = CKA_LABEL(3UL); | ||
2313 | a[0].value = label_tmp; | ||
2314 | a[0].value_len = sizeof label_tmp; | ||
2315 | |||
2316 | if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL)) | ||
2317 | { | ||
2318 | label.data = a[0].value; | ||
2319 | label.size = a[0].value_len; | ||
2320 | } | ||
2321 | else | ||
2322 | { | ||
2323 | label.data = NULL((void*)0); | ||
2324 | label.size = 0; | ||
2325 | } | ||
2326 | |||
2327 | a[0].type = CKA_ID(0x102UL); | ||
2328 | a[0].value = certid_tmp; | ||
2329 | a[0].value_len = sizeof certid_tmp; | ||
2330 | |||
2331 | if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL)) | ||
2332 | { | ||
2333 | id.data = a[0].value; | ||
2334 | id.size = a[0].value_len; | ||
2335 | } | ||
2336 | else | ||
2337 | { | ||
2338 | id.data = NULL((void*)0); | ||
2339 | id.size = 0; | ||
2340 | } | ||
2341 | |||
2342 | a[0].type = CKA_VALUE(0x11UL); | ||
2343 | a[0].value = cert_data; | ||
2344 | a[0].value_len = MAX_CERT_SIZE8*1024; | ||
2345 | if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK(0UL)) | ||
2346 | { | ||
2347 | value.data = a[0].value; | ||
2348 | value.size = a[0].value_len; | ||
2349 | } | ||
2350 | else | ||
2351 | { | ||
2352 | value.data = NULL((void*)0); | ||
2353 | value.size = 0; | ||
2354 | } | ||
2355 | |||
2356 | if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL) | ||
2357 | { | ||
2358 | a[0].type = CKA_CLASS(0UL); | ||
2359 | a[0].value = &class; | ||
2360 | a[0].value_len = sizeof class; | ||
2361 | |||
2362 | pkcs11_get_attribute_value (module, pks, obj, a, 1); | ||
2363 | } | ||
2364 | |||
2365 | if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY) | ||
2366 | { | ||
2367 | for (i = 0; i < plist.key_ids_size; i++) | ||
2368 | { | ||
2369 | if (plist.key_ids[i].length != | ||
2370 | a[1].value_len | ||
2371 | || memcmp (plist.key_ids[i].data, | ||
2372 | a[1].value, a[1].value_len) != 0) | ||
2373 | { | ||
2374 | /* not found */ | ||
2375 | continue; | ||
2376 | } | ||
2377 | } | ||
2378 | } | ||
2379 | |||
2380 | if (find_data->current < *find_data->n_list) | ||
2381 | { | ||
2382 | ret = | ||
2383 | gnutls_pkcs11_obj_init (&find_data->p_list[find_data->current]); | ||
2384 | if (ret < 0) | ||
2385 | { | ||
2386 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2386); } while(0);; | ||
2387 | goto fail; | ||
2388 | } | ||
2389 | |||
2390 | if (class == CKO_PUBLIC_KEY(2UL)) | ||
2391 | { | ||
2392 | ret = | ||
2393 | pkcs11_obj_import_pubkey (module, pks, obj, | ||
2394 | find_data->p_list | ||
2395 | [find_data->current], | ||
2396 | &id, &label, | ||
2397 | &info->tinfo, lib_info); | ||
2398 | } | ||
2399 | else | ||
2400 | { | ||
2401 | ret = | ||
2402 | pkcs11_obj_import (class, | ||
2403 | find_data->p_list | ||
2404 | [find_data->current], | ||
2405 | &value, &id, &label, | ||
2406 | &info->tinfo, lib_info); | ||
2407 | } | ||
2408 | if (ret < 0) | ||
2409 | { | ||
2410 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2410); } while(0);; | ||
2411 | goto fail; | ||
2412 | } | ||
2413 | } | ||
2414 | |||
2415 | find_data->current++; | ||
2416 | |||
2417 | } | ||
2418 | |||
2419 | gnutls_free (cert_data); | ||
2420 | pkcs11_find_objects_final (module, pks); | ||
2421 | |||
2422 | return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; /* continue until all tokens have been checked */ | ||
2423 | |||
2424 | fail: | ||
2425 | gnutls_free (cert_data); | ||
2426 | pkcs11_find_objects_final (module, pks); | ||
2427 | if (plist.key_ids != NULL((void*)0)) | ||
2428 | { | ||
2429 | for (i = 0; i < plist.key_ids_size; i++) | ||
2430 | { | ||
2431 | _gnutls_buffer_clear (&plist.key_ids[i]); | ||
2432 | } | ||
2433 | gnutls_free (plist.key_ids); | ||
2434 | } | ||
2435 | for (i = 0; i < find_data->current; i++) | ||
2436 | { | ||
2437 | gnutls_pkcs11_obj_deinit (find_data->p_list[i]); | ||
2438 | } | ||
2439 | find_data->current = 0; | ||
2440 | |||
2441 | return ret; | ||
2442 | } | ||
2443 | |||
2444 | /** | ||
2445 | * gnutls_pkcs11_obj_list_import_url: | ||
2446 | * @p_list: An uninitialized object list (may be NULL) | ||
2447 | * @n_list: initially should hold the maximum size of the list. Will contain the actual size. | ||
2448 | * @url: A PKCS 11 url identifying a set of objects | ||
2449 | * @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output | ||
2450 | * @flags: One of GNUTLS_PKCS11_OBJ_* flags | ||
2451 | * | ||
2452 | * This function will initialize and set values to an object list | ||
2453 | * by using all objects identified by a PKCS 11 URL. | ||
2454 | * | ||
2455 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
2456 | * negative error value. | ||
2457 | * | ||
2458 | * Since: 2.12.0 | ||
2459 | **/ | ||
2460 | int | ||
2461 | gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list, | ||
2462 | unsigned int *n_list, | ||
2463 | const char *url, | ||
2464 | gnutls_pkcs11_obj_attr_t attrs, | ||
2465 | unsigned int flags) | ||
2466 | { | ||
2467 | int ret; | ||
2468 | struct crt_find_data_st find_data; | ||
2469 | |||
2470 | memset (&find_data, 0, sizeof (find_data)); | ||
2471 | |||
2472 | /* fill in the find data structure */ | ||
2473 | find_data.p_list = p_list; | ||
2474 | find_data.n_list = n_list; | ||
2475 | find_data.flags = attrs; | ||
2476 | find_data.current = 0; | ||
2477 | |||
2478 | if (url == NULL((void*)0) || url[0] == 0) | ||
2479 | { | ||
2480 | url = "pkcs11:"; | ||
2481 | } | ||
2482 | |||
2483 | ret = pkcs11_url_to_info (url, &find_data.info); | ||
2484 | if (ret < 0) | ||
2485 | { | ||
2486 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2486); } while(0);; | ||
2487 | return ret; | ||
2488 | } | ||
2489 | |||
2490 | ret = | ||
2491 | _pkcs11_traverse_tokens (find_objs, &find_data, find_data.info, | ||
2492 | pkcs11_obj_flags_to_int (flags)); | ||
2493 | p11_kit_uri_free (find_data.info); | ||
2494 | |||
2495 | if (ret < 0) | ||
2496 | { | ||
2497 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2497); } while(0);; | ||
2498 | return ret; | ||
2499 | } | ||
2500 | |||
2501 | return 0; | ||
2502 | } | ||
2503 | |||
2504 | /** | ||
2505 | * gnutls_x509_crt_import_pkcs11_url: | ||
2506 | * @crt: A certificate of type #gnutls_x509_crt_t | ||
2507 | * @url: A PKCS 11 url | ||
2508 | * @flags: One of GNUTLS_PKCS11_OBJ_* flags | ||
2509 | * | ||
2510 | * This function will import a PKCS 11 certificate directly from a token | ||
2511 | * without involving the #gnutls_pkcs11_obj_t structure. This function will | ||
2512 | * fail if the certificate stored is not of X.509 type. | ||
2513 | * | ||
2514 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
2515 | * negative error value. | ||
2516 | * | ||
2517 | * Since: 2.12.0 | ||
2518 | **/ | ||
2519 | int | ||
2520 | gnutls_x509_crt_import_pkcs11_url (gnutls_x509_crt_t crt, | ||
2521 | const char *url, unsigned int flags) | ||
2522 | { | ||
2523 | gnutls_pkcs11_obj_t pcrt; | ||
2524 | int ret; | ||
2525 | |||
2526 | ret = gnutls_pkcs11_obj_init (&pcrt); | ||
2527 | if (ret < 0) | ||
2528 | { | ||
2529 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2529); } while(0);; | ||
2530 | return ret; | ||
2531 | } | ||
2532 | |||
2533 | ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags); | ||
2534 | if (ret < 0) | ||
2535 | { | ||
2536 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2536); } while(0);; | ||
2537 | goto cleanup; | ||
2538 | } | ||
2539 | |||
2540 | ret = gnutls_x509_crt_import (crt, &pcrt->raw, GNUTLS_X509_FMT_DER); | ||
2541 | if (ret < 0) | ||
2542 | { | ||
2543 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2543); } while(0);; | ||
2544 | goto cleanup; | ||
2545 | } | ||
2546 | |||
2547 | ret = 0; | ||
2548 | cleanup: | ||
2549 | |||
2550 | gnutls_pkcs11_obj_deinit (pcrt); | ||
2551 | |||
2552 | return ret; | ||
2553 | } | ||
2554 | |||
2555 | |||
2556 | /** | ||
2557 | * gnutls_x509_crt_import_pkcs11: | ||
2558 | * @crt: A certificate of type #gnutls_x509_crt_t | ||
2559 | * @pkcs11_crt: A PKCS 11 object that contains a certificate | ||
2560 | * | ||
2561 | * This function will import a PKCS 11 certificate to a #gnutls_x509_crt_t | ||
2562 | * structure. | ||
2563 | * | ||
2564 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
2565 | * negative error value. | ||
2566 | * | ||
2567 | * Since: 2.12.0 | ||
2568 | **/ | ||
2569 | int | ||
2570 | gnutls_x509_crt_import_pkcs11 (gnutls_x509_crt_t crt, | ||
2571 | gnutls_pkcs11_obj_t pkcs11_crt) | ||
2572 | { | ||
2573 | return gnutls_x509_crt_import (crt, &pkcs11_crt->raw, GNUTLS_X509_FMT_DER); | ||
2574 | } | ||
2575 | |||
2576 | /** | ||
2577 | * gnutls_x509_crt_list_import_pkcs11: | ||
2578 | * @certs: A list of certificates of type #gnutls_x509_crt_t | ||
2579 | * @cert_max: The maximum size of the list | ||
2580 | * @objs: A list of PKCS 11 objects | ||
2581 | * @flags: 0 for now | ||
2582 | * | ||
2583 | * This function will import a PKCS 11 certificate list to a list of | ||
2584 | * #gnutls_x509_crt_t structure. These must not be initialized. | ||
2585 | * | ||
2586 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
2587 | * negative error value. | ||
2588 | * | ||
2589 | * Since: 2.12.0 | ||
2590 | **/ | ||
2591 | int | ||
2592 | gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs, | ||
2593 | unsigned int cert_max, | ||
2594 | gnutls_pkcs11_obj_t * const objs, | ||
2595 | unsigned int flags) | ||
2596 | { | ||
2597 | int i, j; | ||
2598 | int ret; | ||
2599 | |||
2600 | for (i = 0; i < cert_max; i++) | ||
2601 | { | ||
2602 | ret = gnutls_x509_crt_init (&certs[i]); | ||
2603 | if (ret < 0) | ||
2604 | { | ||
2605 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2605); } while(0);; | ||
2606 | goto cleanup; | ||
2607 | } | ||
2608 | |||
2609 | ret = gnutls_x509_crt_import_pkcs11 (certs[i], objs[i]); | ||
2610 | if (ret < 0) | ||
2611 | { | ||
2612 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2612); } while(0);; | ||
2613 | goto cleanup; | ||
2614 | } | ||
2615 | } | ||
2616 | |||
2617 | return 0; | ||
2618 | |||
2619 | cleanup: | ||
2620 | for (j = 0; j < i; j++) | ||
2621 | { | ||
2622 | gnutls_x509_crt_deinit (certs[j]); | ||
2623 | } | ||
2624 | |||
2625 | return ret; | ||
2626 | } | ||
2627 | |||
2628 | static int | ||
2629 | find_flags (struct ck_function_list * module, ck_session_handle_t pks, | ||
2630 | struct token_info *info, struct ck_info *lib_info, void *input) | ||
2631 | { | ||
2632 | struct flags_find_data_st *find_data = input; | ||
2633 | |||
2634 | if (info == NULL((void*)0)) | ||
2635 | { /* we don't support multiple calls */ | ||
2636 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2636); } while(0);; | ||
2637 | return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; | ||
2638 | } | ||
2639 | |||
2640 | /* do not bother reading the token if basic fields do not match | ||
2641 | */ | ||
2642 | if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) || | ||
2643 | !p11_kit_uri_match_module_info (find_data->info, lib_info)) | ||
2644 | { | ||
2645 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2645); } while(0);; | ||
2646 | return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; | ||
2647 | } | ||
2648 | |||
2649 | /* found token! */ | ||
2650 | |||
2651 | find_data->slot_flags = info->sinfo.flags; | ||
2652 | |||
2653 | return 0; | ||
2654 | } | ||
2655 | |||
2656 | /** | ||
2657 | * gnutls_pkcs11_token_get_flags: | ||
2658 | * @url: should contain a PKCS 11 URL | ||
2659 | * @flags: The output flags (GNUTLS_PKCS11_TOKEN_*) | ||
2660 | * | ||
2661 | * This function will return information about the PKCS 11 token flags. | ||
2662 | * The flags from the %gnutls_pkcs11_token_info_t enumeration. | ||
2663 | * | ||
2664 | * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error. | ||
2665 | * | ||
2666 | * Since: 2.12.0 | ||
2667 | **/ | ||
2668 | int | ||
2669 | gnutls_pkcs11_token_get_flags (const char *url, unsigned int *flags) | ||
2670 | { | ||
2671 | struct flags_find_data_st find_data; | ||
2672 | int ret; | ||
2673 | |||
2674 | memset (&find_data, 0, sizeof (find_data)); | ||
2675 | ret = pkcs11_url_to_info (url, &find_data.info); | ||
2676 | if (ret < 0) | ||
2677 | { | ||
2678 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2678); } while(0);; | ||
2679 | return ret; | ||
2680 | } | ||
2681 | |||
2682 | ret = _pkcs11_traverse_tokens (find_flags, &find_data, find_data.info, 0); | ||
2683 | p11_kit_uri_free (find_data.info); | ||
2684 | |||
2685 | if (ret < 0) | ||
2686 | { | ||
2687 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2687); } while(0);; | ||
2688 | return ret; | ||
2689 | } | ||
2690 | |||
2691 | *flags = 0; | ||
2692 | if (find_data.slot_flags & CKF_HW_SLOT(1UL << 2)) | ||
2693 | *flags |= GNUTLS_PKCS11_TOKEN_HW1; | ||
2694 | |||
2695 | return 0; | ||
2696 | |||
2697 | } | ||
2698 | |||
2699 | /** | ||
2700 | * gnutls_pkcs11_token_get_mechanism: | ||
2701 | * @url: should contain a PKCS 11 URL | ||
2702 | * @idx: The index of the mechanism | ||
2703 | * @mechanism: The PKCS #11 mechanism ID | ||
2704 | * | ||
2705 | * This function will return the names of the supported mechanisms | ||
2706 | * by the token. It should be called with an increasing index until | ||
2707 | * it return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE. | ||
2708 | * | ||
2709 | * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error. | ||
2710 | * | ||
2711 | * Since: 2.12.0 | ||
2712 | **/ | ||
2713 | int | ||
2714 | gnutls_pkcs11_token_get_mechanism (const char *url, int idx, | ||
2715 | unsigned long *mechanism) | ||
2716 | { | ||
2717 | int ret; | ||
2718 | ck_rv_t rv; | ||
2719 | struct ck_function_list *module; | ||
2720 | ck_slot_id_t slot; | ||
2721 | struct token_info tinfo; | ||
2722 | struct p11_kit_uri *info = NULL((void*)0); | ||
2723 | unsigned long count; | ||
2724 | ck_mechanism_type_t mlist[400]; | ||
2725 | |||
2726 | ret = pkcs11_url_to_info (url, &info); | ||
2727 | if (ret < 0) | ||
2728 | { | ||
2729 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2729); } while(0);; | ||
2730 | return ret; | ||
2731 | } | ||
2732 | |||
2733 | |||
2734 | ret = pkcs11_find_slot (&module, &slot, info, &tinfo); | ||
2735 | p11_kit_uri_free (info); | ||
2736 | |||
2737 | if (ret < 0) | ||
2738 | { | ||
2739 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2739); } while(0);; | ||
2740 | return ret; | ||
2741 | } | ||
2742 | |||
2743 | count = sizeof (mlist) / sizeof (mlist[0]); | ||
2744 | rv = pkcs11_get_mechanism_list (module, slot, mlist, &count); | ||
2745 | if (rv != CKR_OK(0UL)) | ||
2746 | { | ||
2747 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2747); } while(0);; | ||
2748 | return pkcs11_rv_to_err (rv); | ||
2749 | } | ||
2750 | |||
2751 | if (idx >= count) | ||
2752 | { | ||
2753 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "pkcs11.c",2753); } while(0);; | ||
2754 | return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56; | ||
2755 | } | ||
2756 | |||
2757 | *mechanism = mlist[idx]; | ||
2758 | |||
2759 | return 0; | ||
2760 | |||
2761 | } | ||
2762 | |||
2763 | /** | ||
2764 | * gnutls_pkcs11_type_get_name: | ||
2765 | * @type: Holds the PKCS 11 object type, a #gnutls_pkcs11_obj_type_t. | ||
2766 | * | ||
2767 | * This function will return a human readable description of the | ||
2768 | * PKCS11 object type @obj. It will return "Unknown" for unknown | ||
2769 | * types. | ||
2770 | * | ||
2771 | * Returns: human readable string labeling the PKCS11 object type | ||
2772 | * @type. | ||
2773 | * | ||
2774 | * Since: 2.12.0 | ||
2775 | **/ | ||
2776 | const char * | ||
2777 | gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t type) | ||
2778 | { | ||
2779 | switch (type) | ||
2780 | { | ||
2781 | case GNUTLS_PKCS11_OBJ_X509_CRT: | ||
2782 | return "X.509 Certificate"; | ||
2783 | case GNUTLS_PKCS11_OBJ_PUBKEY: | ||
2784 | return "Public key"; | ||
2785 | case GNUTLS_PKCS11_OBJ_PRIVKEY: | ||
2786 | return "Private key"; | ||
2787 | case GNUTLS_PKCS11_OBJ_SECRET_KEY: | ||
2788 | return "Secret key"; | ||
2789 | case GNUTLS_PKCS11_OBJ_DATA: | ||
2790 | return "Data"; | ||
2791 | case GNUTLS_PKCS11_OBJ_UNKNOWN: | ||
2792 | default: | ||
2793 | return "Unknown"; | ||
2794 | } | ||
2795 | } | ||
2796 | |||
2797 | ck_rv_t | ||
2798 | pkcs11_get_slot_list (struct ck_function_list * module, unsigned char token_present, | ||
2799 | ck_slot_id_t *slot_list, unsigned long *count) | ||
2800 | { | ||
2801 | return (module)->C_GetSlotList (token_present, slot_list, count); | ||
2802 | } | ||
2803 | |||
2804 | ck_rv_t | ||
2805 | pkcs11_get_module_info (struct ck_function_list * module, | ||
2806 | struct ck_info * info) | ||
2807 | { | ||
2808 | return (module)->C_GetInfo (info); | ||
2809 | } | ||
2810 | |||
2811 | ck_rv_t | ||
2812 | pkcs11_get_slot_info(struct ck_function_list * module, | ||
2813 | ck_slot_id_t slot_id, | ||
2814 | struct ck_slot_info *info) | ||
2815 | { | ||
2816 | return (module)->C_GetSlotInfo (slot_id, info); | ||
2817 | } | ||
2818 | |||
2819 | ck_rv_t | ||
2820 | pkcs11_get_token_info (struct ck_function_list * module, | ||
2821 | ck_slot_id_t slot_id, | ||
2822 | struct ck_token_info *info) | ||
2823 | { | ||
2824 | return (module)->C_GetTokenInfo (slot_id, info); | ||
2825 | } | ||
2826 | |||
2827 | ck_rv_t | ||
2828 | pkcs11_find_objects_init (struct ck_function_list *module, | ||
2829 | ck_session_handle_t sess, | ||
2830 | struct ck_attribute *templ, | ||
2831 | unsigned long count) | ||
2832 | { | ||
2833 | return (module)->C_FindObjectsInit (sess, templ, count); | ||
2834 | } | ||
2835 | |||
2836 | ck_rv_t | ||
2837 | pkcs11_find_objects (struct ck_function_list *module, | ||
2838 | ck_session_handle_t sess, | ||
2839 | ck_object_handle_t *objects, | ||
2840 | unsigned long max_object_count, | ||
2841 | unsigned long *object_count) | ||
2842 | { | ||
2843 | return (module)->C_FindObjects (sess, objects, max_object_count, object_count); | ||
2844 | } | ||
2845 | |||
2846 | ck_rv_t | ||
2847 | pkcs11_find_objects_final (struct ck_function_list *module, | ||
2848 | ck_session_handle_t sess) | ||
2849 | { | ||
2850 | return (module)->C_FindObjectsFinal (sess); | ||
2851 | } | ||
2852 | |||
2853 | ck_rv_t | ||
2854 | pkcs11_close_session (struct ck_function_list *module, | ||
2855 | ck_session_handle_t sess) | ||
2856 | { | ||
2857 | return (module)->C_CloseSession (sess); | ||
2858 | } | ||
2859 | |||
2860 | ck_rv_t | ||
2861 | pkcs11_get_attribute_value(struct ck_function_list *module, | ||
2862 | ck_session_handle_t sess, | ||
2863 | ck_object_handle_t object, | ||
2864 | struct ck_attribute *templ, | ||
2865 | unsigned long count) | ||
2866 | { | ||
2867 | return (module)->C_GetAttributeValue (sess, object, templ, count); | ||
2868 | } | ||
2869 | |||
2870 | ck_rv_t | ||
2871 | pkcs11_get_mechanism_list (struct ck_function_list *module, | ||
2872 | ck_slot_id_t slot_id, | ||
2873 | ck_mechanism_type_t *mechanism_list, | ||
2874 | unsigned long *count) | ||
2875 | { | ||
2876 | return (module)->C_GetMechanismList (slot_id, mechanism_list, count); | ||
2877 | } | ||
2878 | |||
2879 | ck_rv_t | ||
2880 | pkcs11_sign_init (struct ck_function_list *module, | ||
2881 | ck_session_handle_t sess, | ||
2882 | struct ck_mechanism *mechanism, | ||
2883 | ck_object_handle_t key) | ||
2884 | { | ||
2885 | return (module)->C_SignInit (sess, mechanism, key); | ||
2886 | } | ||
2887 | |||
2888 | ck_rv_t | ||
2889 | pkcs11_sign (struct ck_function_list *module, | ||
2890 | ck_session_handle_t sess, | ||
2891 | unsigned char *data, | ||
2892 | unsigned long data_len, | ||
2893 | unsigned char *signature, | ||
2894 | unsigned long *signature_len) | ||
2895 | { | ||
2896 | return (module)->C_Sign (sess, data, data_len, signature, signature_len); | ||
2897 | } | ||
2898 | |||
2899 | ck_rv_t | ||
2900 | pkcs11_generate_key_pair (struct ck_function_list *module, | ||
2901 | ck_session_handle_t sess, | ||
2902 | struct ck_mechanism *mechanism, | ||
2903 | struct ck_attribute *pub_templ, | ||
2904 | unsigned long pub_templ_count, | ||
2905 | struct ck_attribute *priv_templ, | ||
2906 | unsigned long priv_templ_count, | ||
2907 | ck_object_handle_t *pub, | ||
2908 | ck_object_handle_t *priv) | ||
2909 | { | ||
2910 | return (module)->C_GenerateKeyPair (sess, mechanism, pub_templ, pub_templ_count, | ||
2911 | priv_templ, priv_templ_count, pub, priv); | ||
2912 | } | ||
2913 | |||
2914 | ck_rv_t | ||
2915 | pkcs11_decrypt_init (struct ck_function_list *module, | ||
2916 | ck_session_handle_t sess, | ||
2917 | struct ck_mechanism *mechanism, | ||
2918 | ck_object_handle_t key) | ||
2919 | { | ||
2920 | return (module)->C_DecryptInit (sess, mechanism, key); | ||
2921 | } | ||
2922 | |||
2923 | ck_rv_t | ||
2924 | pkcs11_decrypt (struct ck_function_list *module, | ||
2925 | ck_session_handle_t sess, | ||
2926 | unsigned char *encrypted_data, | ||
2927 | unsigned long encrypted_data_len, | ||
2928 | unsigned char *data, unsigned long *data_len) | ||
2929 | { | ||
2930 | return (module)->C_Decrypt (sess, encrypted_data, encrypted_data_len, | ||
2931 | data, data_len); | ||
2932 | } | ||
2933 | |||
2934 | ck_rv_t | ||
2935 | pkcs11_create_object (struct ck_function_list *module, | ||
2936 | ck_session_handle_t sess, | ||
2937 | struct ck_attribute *templ, | ||
2938 | unsigned long count, | ||
2939 | ck_object_handle_t *object) | ||
2940 | { | ||
2941 | return (module)->C_CreateObject (sess, templ, count, object); | ||
2942 | } | ||
2943 | |||
2944 | ck_rv_t | ||
2945 | pkcs11_destroy_object (struct ck_function_list *module, | ||
2946 | ck_session_handle_t sess, | ||
2947 | ck_object_handle_t object) | ||
2948 | { | ||
2949 | return (module)->C_DestroyObject (sess, object); | ||
2950 | } | ||
2951 | |||
2952 | ck_rv_t | ||
2953 | pkcs11_init_token (struct ck_function_list *module, | ||
2954 | ck_slot_id_t slot_id, unsigned char *pin, | ||
2955 | unsigned long pin_len, unsigned char *label) | ||
2956 | { | ||
2957 | return (module)->C_InitToken (slot_id, pin, pin_len, label); | ||
2958 | } | ||
2959 | |||
2960 | ck_rv_t | ||
2961 | pkcs11_init_pin (struct ck_function_list *module, | ||
2962 | ck_session_handle_t sess, | ||
2963 | unsigned char *pin, | ||
2964 | unsigned long pin_len) | ||
2965 | { | ||
2966 | return (module)->C_InitPIN (sess, pin, pin_len); | ||
2967 | } | ||
2968 | |||
2969 | ck_rv_t | ||
2970 | pkcs11_set_pin (struct ck_function_list *module, | ||
2971 | ck_session_handle_t sess, | ||
2972 | unsigned char *old_pin, | ||
2973 | unsigned long old_len, | ||
2974 | unsigned char *new_pin, | ||
2975 | unsigned long new_len) | ||
2976 | { | ||
2977 | return (module)->C_SetPIN (sess, old_pin, old_len, new_pin, new_len); | ||
2978 | } | ||
2979 | |||
2980 | const char * | ||
2981 | pkcs11_strerror (ck_rv_t rv) | ||
2982 | { | ||
2983 | return p11_kit_strerror (rv); | ||
2984 | } |