2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010-2012 Free Software Foundation, Inc.
5 * Authors: Nikos Mavrogiannopoulos, Stef Walter
7 * The GnuTLS is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>
21 #include <gnutls_int.h>
22 #include <gnutls/pkcs11.h>
25 #include <gnutls_errors.h>
26 #include <gnutls_datum.h>
27 #include <pkcs11_int.h>
28 #include <gnutls_sig.h>
29 #include <gnutls_pk.h>
32 #include <p11-kit/uri.h>
34 /* In case of a fork, it will invalidate the open session
35 * in the privkey and start another */
36 #define PKCS11_CHECK_INIT_PRIVKEY(k) \
37 ret = _gnutls_pkcs11_check_init(); \
39 return gnutls_assert_val(ret); \
41 memset(&k->sinfo, 0, sizeof(k->sinfo)); \
45 #define FIND_OBJECT(key) \
49 ret = find_object (&key->sinfo, &key->pin, &key->ref, key->uinfo, \
51 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { \
52 if (_gnutls_token_func) \
54 rret = pkcs11_call_token_func (key->uinfo, retries++); \
55 if (rret == 0) continue; \
57 return gnutls_assert_val(ret); \
58 } else if (ret < 0) { \
59 return gnutls_assert_val(ret); \
64 struct gnutls_pkcs11_privkey_st {
65 gnutls_pk_algorithm_t pk_algorithm;
67 struct p11_kit_uri *uinfo;
70 struct pkcs11_session_info sinfo;
71 ck_object_handle_t ref; /* the key in the session */
72 unsigned reauth; /* whether we need to login on each operation */
74 struct pin_info_st pin;
78 * gnutls_pkcs11_privkey_init:
79 * @key: A pointer to the type to be initialized
81 * This function will initialize an private key structure.
83 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
84 * negative error value.
86 int gnutls_pkcs11_privkey_init(gnutls_pkcs11_privkey_t * key)
90 *key = gnutls_calloc(1, sizeof(struct gnutls_pkcs11_privkey_st));
93 return GNUTLS_E_MEMORY_ERROR;
96 (*key)->uinfo = p11_kit_uri_new();
97 if ((*key)->uinfo == NULL) {
100 return GNUTLS_E_MEMORY_ERROR;
107 * gnutls_pkcs11_privkey_cpy:
108 * @dst: The destination key, which should be initialized.
109 * @src: The source key
111 * This function will copy a private key from source to destination
112 * key. Destination has to be initialized.
114 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
115 * negative error value.
120 gnutls_pkcs11_privkey_cpy(gnutls_pkcs11_privkey_t dst,
121 gnutls_pkcs11_privkey_t src)
123 return gnutls_pkcs11_privkey_import_url(dst, src->url, src->flags);
127 * gnutls_pkcs11_privkey_deinit:
128 * @key: the key to be deinitialized
130 * This function will deinitialize a private key structure.
132 void gnutls_pkcs11_privkey_deinit(gnutls_pkcs11_privkey_t key)
134 p11_kit_uri_free(key->uinfo);
135 gnutls_free(key->url);
136 if (key->sinfo.init != 0)
137 pkcs11_close_session(&key->sinfo);
142 * gnutls_pkcs11_privkey_get_pk_algorithm:
143 * @key: should contain a #gnutls_pkcs11_privkey_t type
144 * @bits: if bits is non null it will hold the size of the parameters' in bits
146 * This function will return the public key algorithm of a private
149 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
150 * success, or a negative error code on error.
153 gnutls_pkcs11_privkey_get_pk_algorithm(gnutls_pkcs11_privkey_t key,
157 *bits = 0; /* FIXME */
158 return key->pk_algorithm;
162 * gnutls_pkcs11_privkey_get_info:
163 * @pkey: should contain a #gnutls_pkcs11_privkey_t type
164 * @itype: Denotes the type of information requested
165 * @output: where output will be stored
166 * @output_size: contains the maximum size of the output and will be overwritten with actual
168 * This function will return information about the PKCS 11 private key such
169 * as the label, id as well as token information where the key is stored. When
170 * output is text it returns null terminated string although #output_size contains
171 * the size of the actual data only.
173 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
176 gnutls_pkcs11_privkey_get_info(gnutls_pkcs11_privkey_t pkey,
177 gnutls_pkcs11_obj_info_t itype,
178 void *output, size_t * output_size)
180 return pkcs11_get_info(pkey->uinfo, itype, output, output_size);
184 find_object(struct pkcs11_session_info *sinfo,
185 struct pin_info_st *pin_info,
186 ck_object_handle_t * _obj,
187 struct p11_kit_uri *info, unsigned int flags)
190 ck_object_handle_t obj;
191 struct ck_attribute *attrs;
192 unsigned long attr_count;
197 pkcs11_open_session(sinfo, pin_info, info,
198 flags & SESSION_LOGIN);
204 attrs = p11_kit_uri_get_attributes(info, &attr_count);
205 rv = pkcs11_find_objects_init(sinfo->module, sinfo->pks, attrs,
209 _gnutls_debug_log("p11: FindObjectsInit failed.\n");
210 ret = pkcs11_rv_to_err(rv);
214 if (pkcs11_find_objects(sinfo->module, sinfo->pks, &obj, 1, &count)
215 == CKR_OK && count == 1) {
217 pkcs11_find_objects_final(sinfo);
221 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
222 pkcs11_find_objects_final(sinfo);
224 pkcs11_close_session(sinfo);
232 * _gnutls_pkcs11_privkey_sign_hash:
233 * @key: Holds the key
234 * @hash: holds the data to be signed (should be output of a hash)
235 * @signature: will contain the signature allocated with gnutls_malloc()
237 * This function will sign the given data using a signature algorithm
238 * supported by the private key. It is assumed that the given data
239 * are the output of a hash function.
241 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
242 * negative error value.
245 _gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key,
246 const gnutls_datum_t * hash,
247 gnutls_datum_t * signature)
251 struct ck_mechanism mech;
252 gnutls_datum_t tmp = { NULL, 0 };
253 unsigned long siglen;
254 struct pkcs11_session_info *sinfo;
256 PKCS11_CHECK_INIT_PRIVKEY(key);
260 mech.mechanism = pk_to_mech(key->pk_algorithm);
261 mech.parameter = NULL;
262 mech.parameter_len = 0;
264 /* Initialize signing operation; using the private key discovered
266 rv = pkcs11_sign_init(sinfo->module, sinfo->pks, &mech, key->ref);
269 ret = pkcs11_rv_to_err(rv);
275 pkcs11_login(&key->sinfo, &key->pin,
279 _gnutls_debug_log("PKCS #11 login failed, trying operation anyway\n");
280 /* let's try the operation anyway */
284 /* Work out how long the signature must be: */
285 rv = pkcs11_sign(sinfo->module, sinfo->pks, hash->data, hash->size,
289 ret = pkcs11_rv_to_err(rv);
293 tmp.data = gnutls_malloc(siglen);
296 rv = pkcs11_sign(sinfo->module, sinfo->pks, hash->data, hash->size,
300 ret = pkcs11_rv_to_err(rv);
305 if (key->pk_algorithm == GNUTLS_PK_EC
306 || key->pk_algorithm == GNUTLS_PK_DSA) {
307 unsigned int hlen = siglen / 2;
310 if (siglen % 2 != 0) {
312 ret = GNUTLS_E_PK_SIGN_FAILED;
319 s.data = &tmp.data[hlen];
322 ret = _gnutls_encode_ber_rs_raw(signature, &r, &s);
328 gnutls_free(tmp.data);
331 signature->size = siglen;
332 signature->data = tmp.data;
338 if (sinfo != &key->sinfo)
339 pkcs11_close_session(sinfo);
341 gnutls_free(tmp.data);
347 * gnutls_pkcs11_privkey_status:
348 * @key: Holds the key
350 * Checks the status of the private key token.
352 * Returns: this function will return non-zero if the token
353 * holding the private key is still available (inserted), and zero otherwise.
358 int gnutls_pkcs11_privkey_status(gnutls_pkcs11_privkey_t key)
362 struct ck_session_info session_info;
364 PKCS11_CHECK_INIT_PRIVKEY(key);
366 rv = (key->sinfo.module)->C_GetSessionInfo(key->sinfo.pks, &session_info);
379 * gnutls_pkcs11_privkey_import_url:
380 * @pkey: The private key
381 * @url: a PKCS 11 url identifying the key
382 * @flags: Or sequence of GNUTLS_PKCS11_OBJ_* flags
384 * This function will "import" a PKCS 11 URL identifying a private
385 * key to the #gnutls_pkcs11_privkey_t type. In reality since
386 * in most cases keys cannot be exported, the private key structure
387 * is being associated with the available operations on the token.
389 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
390 * negative error value.
393 gnutls_pkcs11_privkey_import_url(gnutls_pkcs11_privkey_t pkey,
394 const char *url, unsigned int flags)
397 struct ck_attribute *attr;
398 struct ck_attribute a[4];
399 ck_key_type_t key_type;
400 ck_bool_t reauth = 0;
404 memset(&pkey->sinfo, 0, sizeof(pkey->sinfo));
407 gnutls_free(pkey->url);
412 p11_kit_uri_free(pkey->uinfo);
416 pkey->url = gnutls_strdup(url);
417 if (pkey->url == NULL)
418 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
420 ret = pkcs11_url_to_info(pkey->url, &pkey->uinfo, flags|GNUTLS_PKCS11_OBJ_FLAG_EXPECT_PRIVKEY);
428 attr = p11_kit_uri_get_attribute(pkey->uinfo, CKA_CLASS);
429 if (!attr || attr->value_len != sizeof(ck_object_class_t) ||
430 *(ck_object_class_t *) attr->value != CKO_PRIVATE_KEY) {
432 ret = GNUTLS_E_INVALID_REQUEST;
436 attr = p11_kit_uri_get_attribute(pkey->uinfo, CKA_ID);
438 attr = p11_kit_uri_get_attribute(pkey->uinfo, CKA_LABEL);
441 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
448 a[0].type = CKA_KEY_TYPE;
449 a[0].value = &key_type;
450 a[0].value_len = sizeof(key_type);
452 if (pkcs11_get_attribute_value(pkey->sinfo.module, pkey->sinfo.pks, pkey->ref, a, 1)
454 pkey->pk_algorithm = key_type_to_pk(key_type);
455 if (pkey->pk_algorithm == GNUTLS_PK_UNKNOWN) {
457 ("Cannot determine PKCS #11 key algorithm\n");
458 ret = GNUTLS_E_UNKNOWN_ALGORITHM;
463 a[0].type = CKA_ALWAYS_AUTHENTICATE;
464 a[0].value = &reauth;
465 a[0].value_len = sizeof(reauth);
467 if (pkcs11_get_attribute_value(pkey->sinfo.module, pkey->sinfo.pks, pkey->ref, a, 1)
469 pkey->reauth = reauth;
477 if (pkey->uinfo != NULL) {
478 p11_kit_uri_free(pkey->uinfo);
481 gnutls_free(pkey->url);
488 * _gnutls_pkcs11_privkey_decrypt_data:
489 * @key: Holds the key
490 * @flags: should be 0 for now
491 * @ciphertext: holds the data to be signed
492 * @plaintext: will contain the plaintext, allocated with gnutls_malloc()
494 * This function will decrypt the given data using the public key algorithm
495 * supported by the private key.
497 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
498 * negative error value.
501 _gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key,
503 const gnutls_datum_t * ciphertext,
504 gnutls_datum_t * plaintext)
508 struct ck_mechanism mech;
509 unsigned long siglen;
511 PKCS11_CHECK_INIT_PRIVKEY(key);
513 if (key->pk_algorithm != GNUTLS_PK_RSA)
514 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
516 mech.mechanism = CKM_RSA_PKCS;
517 mech.parameter = NULL;
518 mech.parameter_len = 0;
520 /* Initialize signing operation; using the private key discovered
522 rv = pkcs11_decrypt_init(key->sinfo.module, key->sinfo.pks, &mech, key->ref);
525 ret = pkcs11_rv_to_err(rv);
531 pkcs11_login(&key->sinfo, &key->pin,
535 _gnutls_debug_log("PKCS #11 login failed, trying operation anyway\n");
536 /* let's try the operation anyway */
540 /* Work out how long the plaintext must be: */
541 rv = pkcs11_decrypt(key->sinfo.module, key->sinfo.pks, ciphertext->data,
542 ciphertext->size, NULL, &siglen);
545 ret = pkcs11_rv_to_err(rv);
549 plaintext->data = gnutls_malloc(siglen);
550 plaintext->size = siglen;
552 rv = pkcs11_decrypt(key->sinfo.module, key->sinfo.pks, ciphertext->data,
553 ciphertext->size, plaintext->data, &siglen);
555 gnutls_free(plaintext->data);
557 ret = pkcs11_rv_to_err(rv);
561 plaintext->size = siglen;
570 * gnutls_pkcs11_privkey_export_url:
571 * @key: Holds the PKCS 11 key
572 * @detailed: non zero if a detailed URL is required
573 * @url: will contain an allocated url
575 * This function will export a URL identifying the given key.
577 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
578 * negative error value.
581 gnutls_pkcs11_privkey_export_url(gnutls_pkcs11_privkey_t key,
582 gnutls_pkcs11_url_type_t detailed,
587 ret = pkcs11_info_to_url(key->uinfo, detailed, url);
598 * gnutls_pkcs11_privkey_generate:
600 * @pk: the public key algorithm
601 * @bits: the security bits
603 * @flags: should be zero
605 * This function will generate a private key in the specified
606 * by the @url token. The private key will be generate within
607 * the token and will not be exportable.
609 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
610 * negative error value.
615 gnutls_pkcs11_privkey_generate(const char *url, gnutls_pk_algorithm_t pk,
616 unsigned int bits, const char *label,
623 * gnutls_pkcs11_privkey_generate2:
625 * @pk: the public key algorithm
626 * @bits: the security bits
628 * @fmt: the format of output params. PEM or DER
629 * @pubkey: will hold the public key (may be %NULL)
630 * @flags: zero or an OR'ed sequence of %GNUTLS_PKCS11_OBJ_FLAGs
632 * This function will generate a private key in the specified
633 * by the @url token. The private key will be generate within
634 * the token and will not be exportable. This function will
635 * store the DER-encoded public key in the SubjectPublicKeyInfo format
636 * in @pubkey. The @pubkey should be deinitialized using gnutls_free().
638 * Note that when generating an elliptic curve key, the curve
639 * can be substituted in the place of the bits parameter using the
640 * GNUTLS_CURVE_TO_BITS() macro.
642 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
643 * negative error value.
648 gnutls_pkcs11_privkey_generate2(const char *url, gnutls_pk_algorithm_t pk,
649 unsigned int bits, const char *label,
650 gnutls_x509_crt_fmt_t fmt,
651 gnutls_datum_t * pubkey,
659 /* FIPS 186-3 maximal size for L and N length pair is (3072,256). */
661 uint8_t subprime[32];
662 uint8_t generator[384];
666 _dsa_params_generate(struct ck_function_list *module, ck_session_handle_t session,
667 unsigned long bits, struct dsa_params *params,
668 struct ck_attribute *a, int *a_val)
670 struct ck_mechanism mech = { CKM_DSA_PARAMETER_GEN };
671 struct ck_attribute attr = { CKA_PRIME_BITS, &bits, sizeof(bits) };
672 ck_object_handle_t key;
675 /* Generate DSA parameters from prime length. */
677 rv = pkcs11_generate_key(module, session, &mech, &attr, 1, &key);
680 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
681 return pkcs11_rv_to_err(rv);
684 /* Retrieve generated parameters to be used with the new key pair. */
686 a[*a_val + 0].type = CKA_PRIME;
687 a[*a_val + 0].value = params->prime;
688 a[*a_val + 0].value_len = sizeof(params->prime);
690 a[*a_val + 1].type = CKA_SUBPRIME;
691 a[*a_val + 1].value = params->subprime;
692 a[*a_val + 1].value_len = sizeof(params->subprime);
694 a[*a_val + 2].type = CKA_BASE;
695 a[*a_val + 2].value = params->generator;
696 a[*a_val + 2].value_len = sizeof(params->generator);
698 rv = pkcs11_get_attribute_value(module, session, key, &a[*a_val], 3);
701 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
702 return pkcs11_rv_to_err(rv);
711 * gnutls_pkcs11_privkey_generate3:
713 * @pk: the public key algorithm
714 * @bits: the security bits
716 * @cid: The CKA_ID to use for the new object
717 * @fmt: the format of output params. PEM or DER
718 * @pubkey: will hold the public key (may be %NULL)
719 * @key_usage: One of GNUTLS_KEY_*
720 * @flags: zero or an OR'ed sequence of %GNUTLS_PKCS11_OBJ_FLAGs
722 * This function will generate a private key in the specified
723 * by the @url token. The private key will be generate within
724 * the token and will not be exportable. This function will
725 * store the DER-encoded public key in the SubjectPublicKeyInfo format
726 * in @pubkey. The @pubkey should be deinitialized using gnutls_free().
728 * Note that when generating an elliptic curve key, the curve
729 * can be substituted in the place of the bits parameter using the
730 * GNUTLS_CURVE_TO_BITS() macro.
732 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
733 * negative error value.
738 gnutls_pkcs11_privkey_generate3(const char *url, gnutls_pk_algorithm_t pk,
739 unsigned int bits, const char *label,
740 const gnutls_datum_t *cid,
741 gnutls_x509_crt_fmt_t fmt,
742 gnutls_datum_t * pubkey,
743 unsigned int key_usage,
747 const ck_bool_t tval = 1;
748 const ck_bool_t fval = 0;
749 struct pkcs11_session_info sinfo;
750 struct p11_kit_uri *info = NULL;
752 struct ck_attribute a[22], p[22];
753 ck_object_handle_t pub, priv;
754 unsigned long _bits = bits;
756 struct ck_mechanism mech;
757 gnutls_pubkey_t pkey = NULL;
758 gnutls_pkcs11_obj_t obj = NULL;
759 gnutls_datum_t der = {NULL, 0};
760 ck_key_type_t key_type;
761 char pubEx[3] = { 1,0,1 }; // 65537 = 0x10001
763 struct dsa_params dsa_params;
766 FIX_KEY_USAGE(pk, key_usage);
768 memset(&sinfo, 0, sizeof(sinfo));
770 ret = pkcs11_url_to_info(url, &info, 0);
777 pkcs11_open_session(&sinfo, NULL, info,
779 pkcs11_obj_flags_to_int(flags));
780 p11_kit_uri_free(info);
787 /* a holds the public key template
788 * and p the private key */
790 mech.parameter = NULL;
791 mech.parameter_len = 0;
792 mech.mechanism = pk_to_genmech(pk, &key_type);
794 if (!(flags & GNUTLS_PKCS11_OBJ_FLAG_NO_STORE_PUBKEY)) {
795 a[a_val].type = CKA_TOKEN;
796 a[a_val].value = (void *) &tval;
797 a[a_val].value_len = sizeof(tval);
800 a[a_val].type = CKA_PRIVATE;
801 a[a_val].value = (void *) &fval;
802 a[a_val].value_len = sizeof(fval);
806 a[a_val].type = CKA_ID;
807 if (cid == NULL || cid->size == 0) {
808 ret = gnutls_rnd(GNUTLS_RND_NONCE, id, sizeof(id));
814 a[a_val].value = (void *) id;
815 a[a_val].value_len = sizeof(id);
817 a[a_val].value = (void *) cid->data;
818 a[a_val].value_len = cid->size;
821 p[p_val].type = CKA_ID;
822 p[p_val].value = a[a_val].value;
823 p[p_val].value_len = a[a_val].value_len;
829 p[p_val].type = CKA_DECRYPT;
830 if (key_usage & (GNUTLS_KEY_DECIPHER_ONLY|GNUTLS_KEY_ENCIPHER_ONLY)) {
831 p[p_val].value = (void *) &tval;
832 p[p_val].value_len = sizeof(tval);
834 p[p_val].value = (void *) &fval;
835 p[p_val].value_len = sizeof(fval);
839 p[p_val].type = CKA_SIGN;
840 if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE) {
841 p[p_val].value = (void *) &tval;
842 p[p_val].value_len = sizeof(tval);
844 p[p_val].value = (void *) &fval;
845 p[p_val].value_len = sizeof(fval);
849 a[a_val].type = CKA_ENCRYPT;
850 a[a_val].value = (void *) &tval;
851 a[a_val].value_len = sizeof(tval);
854 a[a_val].type = CKA_VERIFY;
855 a[a_val].value = (void *) &tval;
856 a[a_val].value_len = sizeof(tval);
859 a[a_val].type = CKA_MODULUS_BITS;
860 a[a_val].value = &_bits;
861 a[a_val].value_len = sizeof(_bits);
864 a[a_val].type = CKA_PUBLIC_EXPONENT;
865 a[a_val].value = pubEx;
866 a[a_val].value_len = sizeof(pubEx);
871 p[p_val].type = CKA_SIGN;
872 if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE) {
873 p[p_val].value = (void *) &tval;
874 p[p_val].value_len = sizeof(tval);
876 p[p_val].value = (void *) &fval;
877 p[p_val].value_len = sizeof(fval);
881 a[a_val].type = CKA_VERIFY;
882 a[a_val].value = (void *) &tval;
883 a[a_val].value_len = sizeof(tval);
886 ret = _dsa_params_generate(sinfo.module, sinfo.pks, _bits,
887 &dsa_params, a, &a_val);
894 p[p_val].type = CKA_SIGN;
895 if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE) {
896 p[p_val].value = (void *) &tval;
897 p[p_val].value_len = sizeof(tval);
899 p[p_val].value = (void *) &fval;
900 p[p_val].value_len = sizeof(fval);
904 a[a_val].type = CKA_VERIFY;
905 a[a_val].value = (void *) &tval;
906 a[a_val].value_len = sizeof(tval);
909 if (GNUTLS_BITS_ARE_CURVE(bits)) {
910 bits = GNUTLS_BITS_TO_CURVE(bits);
912 bits = _gnutls_ecc_bits_to_curve(bits);
915 ret = _gnutls_x509_write_ecc_params(bits, &der);
921 a[a_val].type = CKA_EC_PARAMS;
922 a[a_val].value = der.data;
923 a[a_val].value_len = der.size;
927 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
932 * on request, add the CKA_WRAP/CKA_UNWRAP key attribute
934 if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_KEY_WRAP) {
935 p[p_val].type = CKA_UNWRAP;
936 p[p_val].value = (void*)&tval;
937 p[p_val].value_len = sizeof(tval);
939 a[a_val].type = CKA_WRAP;
940 a[a_val].value = (void*)&tval;
941 a[a_val].value_len = sizeof(tval);
945 /* a private key is set always as private unless
946 * requested otherwise
948 if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE) {
949 p[p_val].type = CKA_PRIVATE;
950 p[p_val].value = (void *) &fval;
951 p[p_val].value_len = sizeof(fval);
954 p[p_val].type = CKA_PRIVATE;
955 p[p_val].value = (void *) &tval;
956 p[p_val].value_len = sizeof(tval);
960 p[p_val].type = CKA_TOKEN;
961 p[p_val].value = (void *) &tval;
962 p[p_val].value_len = sizeof(tval);
966 p[p_val].type = CKA_LABEL;
967 p[p_val].value = (void *) label;
968 p[p_val].value_len = strlen(label);
971 a[a_val].type = CKA_LABEL;
972 a[a_val].value = (void *) label;
973 a[a_val].value_len = strlen(label);
977 if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE) {
978 p[p_val].type = CKA_SENSITIVE;
979 p[p_val].value = (void *) &tval;
980 p[p_val].value_len = sizeof(tval);
983 p[p_val].type = CKA_SENSITIVE;
984 p[p_val].value = (void *) &fval;
985 p[p_val].value_len = sizeof(fval);
989 rv = pkcs11_generate_key_pair(sinfo.module, sinfo.pks, &mech, a,
990 a_val, p, p_val, &pub, &priv);
993 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
994 ret = pkcs11_rv_to_err(rv);
998 /* extract the public key */
1001 ret = gnutls_pubkey_init(&pkey);
1007 ret = gnutls_pkcs11_obj_init(&obj);
1013 obj->pk_algorithm = pk;
1014 obj->type = GNUTLS_PKCS11_OBJ_PUBKEY;
1016 pkcs11_read_pubkey(sinfo.module, sinfo.pks, pub,
1023 ret = gnutls_pubkey_import_pkcs11(pkey, obj, 0);
1029 ret = gnutls_pubkey_export2(pkey, fmt, pubkey);
1038 gnutls_pkcs11_obj_deinit(obj);
1040 gnutls_pubkey_deinit(pkey);
1043 pkcs11_close_session(&sinfo);
1044 gnutls_free(der.data);
1049 /* loads a the corresponding to the private key public key either from
1050 * a public key object or from a certificate.
1052 static int load_pubkey_obj(gnutls_pkcs11_privkey_t pkey, gnutls_pubkey_t pub)
1055 gnutls_x509_crt_t crt;
1057 ret = gnutls_pubkey_import_url(pub, pkey->url, pkey->flags);
1063 /* else try certificate */
1064 ret = gnutls_x509_crt_init(&crt);
1070 gnutls_x509_crt_set_pin_function(crt, pkey->pin.cb, pkey->pin.data);
1072 ret = gnutls_x509_crt_import_url(crt, pkey->url, pkey->flags);
1078 ret = gnutls_pubkey_import_x509(pub, crt, 0);
1081 gnutls_x509_crt_deinit(crt);
1086 _pkcs11_privkey_get_pubkey (gnutls_pkcs11_privkey_t pkey, gnutls_pubkey_t *pub, unsigned flags)
1088 gnutls_pubkey_t pubkey = NULL;
1089 gnutls_pkcs11_obj_t obj = NULL;
1090 ck_key_type_t key_type;
1093 PKCS11_CHECK_INIT_PRIVKEY(pkey);
1097 return GNUTLS_E_INVALID_REQUEST;
1100 ret = gnutls_pubkey_init(&pubkey);
1106 ret = gnutls_pkcs11_obj_init(&obj);
1112 obj->pk_algorithm = gnutls_pkcs11_privkey_get_pk_algorithm(pkey, 0);
1113 obj->type = GNUTLS_PKCS11_OBJ_PUBKEY;
1114 pk_to_genmech(obj->pk_algorithm, &key_type);
1116 gnutls_pubkey_set_pin_function(pubkey, pkey->pin.cb, pkey->pin.data);
1118 /* we can only read the public key from RSA keys */
1119 if (key_type != CKK_RSA) {
1120 /* try opening the public key object if it exists */
1121 ret = load_pubkey_obj(pkey, pubkey);
1127 ret = pkcs11_read_pubkey(pkey->sinfo.module, pkey->sinfo.pks, pkey->ref, key_type, obj);
1133 ret = gnutls_pubkey_import_pkcs11(pubkey, obj, 0);
1147 gnutls_pkcs11_obj_deinit(obj);
1149 gnutls_pubkey_deinit(pubkey);
1155 * gnutls_pkcs11_privkey_export_pubkey
1156 * @pkey: The private key
1157 * @fmt: the format of output params. PEM or DER.
1158 * @data: will hold the public key
1159 * @flags: should be zero
1161 * This function will extract the public key (modulus and public
1162 * exponent) from the private key specified by the @url private key.
1163 * This public key will be stored in @pubkey in the format specified
1164 * by @fmt. @pubkey should be deinitialized using gnutls_free().
1166 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1167 * negative error value.
1172 gnutls_pkcs11_privkey_export_pubkey(gnutls_pkcs11_privkey_t pkey,
1173 gnutls_x509_crt_fmt_t fmt,
1174 gnutls_datum_t * data,
1178 gnutls_pubkey_t pubkey = NULL;
1180 ret = _pkcs11_privkey_get_pubkey(pkey, &pubkey, flags);
1182 return gnutls_assert_val(ret);
1184 ret = gnutls_pubkey_export2(pubkey, fmt, data);
1194 gnutls_pubkey_deinit(pubkey);
1200 * gnutls_pkcs11_privkey_set_pin_function:
1201 * @key: The private key
1203 * @userdata: data associated with the callback
1205 * This function will set a callback function to be used when
1206 * required to access the object. This function overrides the global
1207 * set using gnutls_pkcs11_set_pin_function().
1213 gnutls_pkcs11_privkey_set_pin_function(gnutls_pkcs11_privkey_t key,
1214 gnutls_pin_callback_t fn,
1218 key->pin.data = userdata;