2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010 Free Software Foundation
5 * Author: Nikos Mavrogiannopoulos
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <gnutls_int.h>
24 #include <gnutls/pkcs11.h>
27 #include <gnutls_errors.h>
28 #include <gnutls_datum.h>
29 #include <pkcs11_int.h>
32 * gnutls_pkcs11_copy_x509_crt:
33 * @token_url: A PKCS #11 URL specifying a token
35 * @label: A name to be used for the stored data
36 * @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
38 * This function will copy a certificate into a PKCS #11 token specified by
39 * a URL. The certificate can be marked as trusted or not.
41 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
42 * negative error value.
45 gnutls_pkcs11_copy_x509_crt (const char *token_url,
46 gnutls_x509_crt_t crt, const char *label,
50 struct ck_function_list *module;
51 ck_session_handle_t pks;
52 struct p11_kit_uri *info = NULL;
54 size_t der_size, id_size;
57 struct ck_attribute a[16];
58 ck_object_class_t class = CKO_CERTIFICATE;
59 ck_certificate_type_t type = CKC_X_509;
60 ck_object_handle_t obj;
64 gnutls_datum_t subject = { NULL, 0 };
66 ret = pkcs11_url_to_info (token_url, &info);
74 pkcs11_open_session (&module, &pks, info,
75 SESSION_WRITE | pkcs11_obj_flags_to_int (flags));
76 p11_kit_uri_free (info);
84 ret = gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_DER, NULL, &der_size);
85 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
91 der = gnutls_malloc (der_size);
95 ret = GNUTLS_E_MEMORY_ERROR;
99 ret = gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_DER, der, &der_size);
106 id_size = sizeof (id);
107 ret = gnutls_x509_crt_get_key_id (crt, 0, id, &id_size);
114 ret = gnutls_x509_crt_get_raw_dn (crt, &subject);
121 /* FIXME: copy key usage flags */
123 a[0].type = CKA_CLASS;
125 a[0].value_len = sizeof (class);
128 a[1].value_len = id_size;
129 a[2].type = CKA_VALUE;
131 a[2].value_len = der_size;
132 a[3].type = CKA_TOKEN;
134 a[3].value_len = sizeof (tval);
135 a[4].type = CKA_CERTIFICATE_TYPE;
137 a[4].value_len = sizeof (type);
141 a[a_val].type = CKA_SUBJECT;
142 a[a_val].value = subject.data;
143 a[a_val].value_len = subject.size;
149 a[a_val].type = CKA_LABEL;
150 a[a_val].value = (void *) label;
151 a[a_val].value_len = strlen (label);
155 if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED)
157 a[a_val].type = CKA_TRUSTED;
158 a[a_val].value = &tval;
159 a[a_val].value_len = sizeof (tval);
162 a[a_val].type = CKA_PRIVATE;
163 a[a_val].value = &fval;
164 a[a_val].value_len = sizeof(fval);
168 rv = pkcs11_create_object (module, pks, a, a_val, &obj);
172 _gnutls_debug_log ("pkcs11: %s\n", pkcs11_strerror (rv));
173 ret = pkcs11_rv_to_err (rv);
184 _gnutls_free_datum(&subject);
185 pkcs11_close_session (module, pks);
192 * gnutls_pkcs11_copy_x509_privkey:
193 * @token_url: A PKCS #11 URL specifying a token
194 * @key: A private key
195 * @label: A name to be used for the stored data
196 * @key_usage: One of GNUTLS_KEY_*
197 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
199 * This function will copy a private key into a PKCS #11 token specified by
200 * a URL. It is highly recommended flags to contain %GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE
201 * unless there is a strong reason not to.
203 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
204 * negative error value.
207 gnutls_pkcs11_copy_x509_privkey (const char *token_url,
208 gnutls_x509_privkey_t key,
210 unsigned int key_usage, unsigned int flags)
213 struct ck_function_list *module;
214 ck_session_handle_t pks = 0;
215 struct p11_kit_uri *info = NULL;
219 struct ck_attribute a[16];
220 ck_object_class_t class = CKO_PRIVATE_KEY;
221 ck_object_handle_t obj;
225 gnutls_pk_algorithm_t pk;
226 gnutls_datum_t p, q, g, y, x;
227 gnutls_datum_t m, e, d, u, exp1, exp2;
230 ret = pkcs11_url_to_info (token_url, &info);
237 id_size = sizeof (id);
238 ret = gnutls_x509_privkey_get_key_id (key, 0, id, &id_size);
241 p11_kit_uri_free (info);
247 pkcs11_open_session (&module, &pks, info,
248 SESSION_WRITE | pkcs11_obj_flags_to_int (flags));
249 p11_kit_uri_free (info);
257 /* FIXME: copy key usage flags */
259 a[a_val].type = CKA_CLASS;
260 a[a_val].value = &class;
261 a[a_val].value_len = sizeof (class);
264 a[a_val].type = CKA_ID;
266 a[a_val].value_len = id_size;
269 a[a_val].type = CKA_KEY_TYPE;
270 a[a_val].value = &type;
271 a[a_val].value_len = sizeof (type);
274 a[a_val].type = CKA_TOKEN;
275 a[a_val].value = &tval;
276 a[a_val].value_len = sizeof (tval);
279 a[a_val].type = CKA_PRIVATE;
280 a[a_val].value = &tval;
281 a[a_val].value_len = sizeof (tval);
286 a[a_val].type = CKA_LABEL;
287 a[a_val].value = (void *) label;
288 a[a_val].value_len = strlen (label);
292 if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE)
297 a[a_val].type = CKA_SENSITIVE;
298 a[a_val].value = &tval;
299 a[a_val].value_len = sizeof (tval);
302 pk = gnutls_x509_privkey_get_pk_algorithm (key);
309 gnutls_x509_privkey_export_rsa_raw2 (key, &m,
311 &q, &u, &exp1, &exp2);
320 a[a_val].type = CKA_MODULUS;
321 a[a_val].value = m.data;
322 a[a_val].value_len = m.size;
325 a[a_val].type = CKA_PUBLIC_EXPONENT;
326 a[a_val].value = e.data;
327 a[a_val].value_len = e.size;
330 a[a_val].type = CKA_PRIVATE_EXPONENT;
331 a[a_val].value = d.data;
332 a[a_val].value_len = d.size;
335 a[a_val].type = CKA_PRIME_1;
336 a[a_val].value = p.data;
337 a[a_val].value_len = p.size;
340 a[a_val].type = CKA_PRIME_2;
341 a[a_val].value = q.data;
342 a[a_val].value_len = q.size;
345 a[a_val].type = CKA_COEFFICIENT;
346 a[a_val].value = u.data;
347 a[a_val].value_len = u.size;
350 a[a_val].type = CKA_EXPONENT_1;
351 a[a_val].value = exp1.data;
352 a[a_val].value_len = exp1.size;
355 a[a_val].type = CKA_EXPONENT_2;
356 a[a_val].value = exp2.data;
357 a[a_val].value_len = exp2.size;
364 ret = gnutls_x509_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x);
373 a[a_val].type = CKA_PRIME;
374 a[a_val].value = p.data;
375 a[a_val].value_len = p.size;
378 a[a_val].type = CKA_SUBPRIME;
379 a[a_val].value = q.data;
380 a[a_val].value_len = q.size;
383 a[a_val].type = CKA_BASE;
384 a[a_val].value = g.data;
385 a[a_val].value_len = g.size;
388 a[a_val].type = CKA_VALUE;
389 a[a_val].value = x.data;
390 a[a_val].value_len = x.size;
397 ret = GNUTLS_E_INVALID_REQUEST;
401 rv = pkcs11_create_object (module, pks, a, a_val, &obj);
405 _gnutls_debug_log ("pkcs11: %s\n", pkcs11_strerror (rv));
406 ret = pkcs11_rv_to_err (rv);
417 gnutls_free (m.data);
418 gnutls_free (e.data);
419 gnutls_free (d.data);
420 gnutls_free (p.data);
421 gnutls_free (q.data);
422 gnutls_free (u.data);
423 gnutls_free (exp1.data);
424 gnutls_free (exp2.data);
429 gnutls_free (p.data);
430 gnutls_free (q.data);
431 gnutls_free (g.data);
432 gnutls_free (y.data);
433 gnutls_free (x.data);
438 ret = GNUTLS_E_INVALID_REQUEST;
446 pkcs11_close_session (module, pks);
452 struct delete_data_st
454 struct p11_kit_uri *info;
455 unsigned int deleted; /* how many */
459 delete_obj_url (struct ck_function_list *module,
460 ck_session_handle_t pks,
461 struct token_info *info,
462 struct ck_info *lib_info, void *input)
464 struct delete_data_st *find_data = input;
465 struct ck_attribute a[4];
466 struct ck_attribute *attr;
467 ck_object_class_t class;
468 ck_certificate_type_t type = -1;
470 ck_object_handle_t obj;
471 unsigned long count, a_vals;
476 { /* we don't support multiple calls */
478 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
481 /* do not bother reading the token if basic fields do not match
483 if (!p11_kit_uri_match_module_info (find_data->info, lib_info) ||
484 !p11_kit_uri_match_token_info (find_data->info, &info->tinfo))
487 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
490 /* Find objects with given class and type */
491 class = CKO_CERTIFICATE; /* default */
494 attr = p11_kit_uri_get_attribute (find_data->info, CKA_CLASS);
497 if(attr->value && attr->value_len == sizeof (ck_object_class_t))
498 class = *((ck_object_class_t*)attr->value);
499 if (class == CKO_CERTIFICATE)
503 a[a_vals].type = CKA_CLASS;
504 a[a_vals].value = &class;
505 a[a_vals].value_len = sizeof (class);
508 attr = p11_kit_uri_get_attribute (find_data->info, CKA_ID);
511 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
517 a[a_vals].type = CKA_CERTIFICATE_TYPE;
518 a[a_vals].value = &type;
519 a[a_vals].value_len = sizeof type;
523 attr = p11_kit_uri_get_attribute (find_data->info, CKA_LABEL);
526 memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
530 rv = pkcs11_find_objects_init (module, pks, a, a_vals);
534 _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
535 ret = pkcs11_rv_to_err (rv);
539 while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
541 rv = pkcs11_destroy_object (module, pks, obj);
545 ("pkcs11: Cannot destroy object: %s\n", pkcs11_strerror (rv));
549 find_data->deleted++;
558 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
566 pkcs11_find_objects_final (module, pks);
573 * gnutls_pkcs11_delete_url:
574 * @object_url: The URL of the object to delete.
575 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
577 * This function will delete objects matching the given URL.
579 * Returns: On success, the number of objects deleted is returned, otherwise a
580 * negative error value.
583 gnutls_pkcs11_delete_url (const char *object_url, unsigned int flags)
586 struct delete_data_st find_data;
588 memset (&find_data, 0, sizeof (find_data));
590 ret = pkcs11_url_to_info (object_url, &find_data.info);
598 _pkcs11_traverse_tokens (delete_obj_url, &find_data, find_data.info,
599 SESSION_WRITE | pkcs11_obj_flags_to_int (flags));
600 p11_kit_uri_free (find_data.info);
608 return find_data.deleted;
613 * gnutls_pkcs11_token_init:
614 * @token_url: A PKCS #11 URL specifying a token
615 * @so_pin: Security Officer's PIN
616 * @label: A name to be used for the token
618 * This function will initialize (format) a token. If the token is
619 * at a factory defaults state the security officer's PIN given will be
620 * set to be the default. Otherwise it should match the officer's PIN.
622 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
623 * negative error value.
626 gnutls_pkcs11_token_init (const char *token_url,
627 const char *so_pin, const char *label)
630 struct p11_kit_uri *info = NULL;
632 struct ck_function_list *module;
636 ret = pkcs11_url_to_info (token_url, &info);
643 ret = pkcs11_find_slot (&module, &slot, info, NULL);
644 p11_kit_uri_free (info);
652 /* so it seems memset has other uses than zeroing! */
653 memset (flabel, ' ', sizeof (flabel));
655 memcpy (flabel, label, strlen (label));
658 pkcs11_init_token (module, slot, (char *) so_pin, strlen (so_pin),
663 _gnutls_debug_log ("pkcs11: %s\n", pkcs11_strerror (rv));
664 return pkcs11_rv_to_err (rv);
672 * gnutls_pkcs11_token_set_pin:
673 * @token_url: A PKCS #11 URL specifying a token
674 * @oldpin: old user's PIN
675 * @newpin: new user's PIN
676 * @flags: one of gnutls_pkcs11_pin_flag_t
678 * This function will modify or set a user's PIN for the given token.
679 * If it is called to set a user pin for first time the oldpin must
682 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
683 * negative error value.
686 gnutls_pkcs11_token_set_pin (const char *token_url,
688 const char *newpin, unsigned int flags)
691 struct ck_function_list *module;
692 ck_session_handle_t pks;
693 struct p11_kit_uri *info = NULL;
695 unsigned int ses_flags;
697 ret = pkcs11_url_to_info (token_url, &info);
704 if (((flags & GNUTLS_PKCS11_PIN_USER) && oldpin == NULL) ||
705 (flags & GNUTLS_PKCS11_PIN_SO))
706 ses_flags = SESSION_WRITE | SESSION_LOGIN | SESSION_SO;
708 ses_flags = SESSION_WRITE | SESSION_LOGIN;
710 ret = pkcs11_open_session (&module, &pks, info, ses_flags);
711 p11_kit_uri_free (info);
721 rv = pkcs11_init_pin (module, pks, (char *) newpin, strlen (newpin));
725 _gnutls_debug_log ("pkcs11: %s\n", pkcs11_strerror (rv));
726 ret = pkcs11_rv_to_err (rv);
732 rv = pkcs11_set_pin (module, pks,
733 (char *) oldpin, strlen (oldpin),
734 (char *) newpin, strlen (newpin));
738 _gnutls_debug_log ("pkcs11: %s\n", pkcs11_strerror (rv));
739 ret = pkcs11_rv_to_err (rv);
747 pkcs11_close_session (module, pks);