2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010-2014 Free Software Foundation, Inc.
4 * Copyright (C) 2012-2014 Nikos Mavrogiannopoulos
6 * Author: Nikos Mavrogiannopoulos
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
22 #include <gnutls_int.h>
23 #include <gnutls/pkcs11.h>
26 #include <gnutls_errors.h>
27 #include <gnutls_datum.h>
28 #include <pkcs11_int.h>
29 #include <gnutls/abstract.h>
30 #include <gnutls_pk.h>
32 #include <openpgp/openpgp_int.h>
33 #include <openpgp/gnutls_openpgp.h>
34 #include <gnutls_sig.h>
35 #include <algorithms.h>
37 #include <system-keys.h>
39 #include <abstract_int.h>
42 _gnutls_privkey_sign_raw_data(gnutls_privkey_t key,
44 const gnutls_datum_t * data,
45 gnutls_datum_t * signature);
48 * gnutls_privkey_get_type:
49 * @key: should contain a #gnutls_privkey_t type
51 * This function will return the type of the private key. This is
52 * actually the type of the subsystem used to set this private key.
54 * Returns: a member of the #gnutls_privkey_type_t enumeration on
55 * success, or a negative error code on error.
59 gnutls_privkey_type_t gnutls_privkey_get_type(gnutls_privkey_t key)
65 * gnutls_privkey_get_pk_algorithm:
66 * @key: should contain a #gnutls_privkey_t type
67 * @bits: If set will return the number of bits of the parameters (may be NULL)
69 * This function will return the public key algorithm of a private
70 * key and if possible will return a number of bits that indicates
71 * the security parameter of the key.
73 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
74 * success, or a negative error code on error.
78 int gnutls_privkey_get_pk_algorithm(gnutls_privkey_t key, unsigned int *bits)
82 case GNUTLS_PRIVKEY_OPENPGP:
83 return gnutls_openpgp_privkey_get_pk_algorithm(key->key.openpgp,
87 case GNUTLS_PRIVKEY_PKCS11:
88 return gnutls_pkcs11_privkey_get_pk_algorithm(key->key.pkcs11,
91 case GNUTLS_PRIVKEY_X509:
94 _gnutls_mpi_get_nbits(key->key.x509->
96 return gnutls_x509_privkey_get_pk_algorithm(key->key.x509);
97 case GNUTLS_PRIVKEY_EXT:
100 return key->pk_algorithm;
103 return GNUTLS_E_INVALID_REQUEST;
109 privkey_to_pubkey(gnutls_pk_algorithm_t pk,
110 const gnutls_pk_params_st * priv, gnutls_pk_params_st * pub)
114 pub->algo = priv->algo;
115 pub->flags = priv->flags;
119 pub->params[0] = _gnutls_mpi_copy(priv->params[0]);
120 pub->params[1] = _gnutls_mpi_copy(priv->params[1]);
122 pub->params_nr = RSA_PUBLIC_PARAMS;
124 if (pub->params[0] == NULL || pub->params[1] == NULL) {
126 ret = GNUTLS_E_MEMORY_ERROR;
132 pub->params[0] = _gnutls_mpi_copy(priv->params[0]);
133 pub->params[1] = _gnutls_mpi_copy(priv->params[1]);
134 pub->params[2] = _gnutls_mpi_copy(priv->params[2]);
135 pub->params[3] = _gnutls_mpi_copy(priv->params[3]);
137 pub->params_nr = DSA_PUBLIC_PARAMS;
139 if (pub->params[0] == NULL || pub->params[1] == NULL ||
140 pub->params[2] == NULL || pub->params[3] == NULL) {
142 ret = GNUTLS_E_MEMORY_ERROR;
148 pub->params[ECC_X] = _gnutls_mpi_copy(priv->params[ECC_X]);
149 pub->params[ECC_Y] = _gnutls_mpi_copy(priv->params[ECC_Y]);
151 pub->params_nr = ECC_PUBLIC_PARAMS;
153 if (pub->params[ECC_X] == NULL || pub->params[ECC_Y] == NULL) {
155 ret = GNUTLS_E_MEMORY_ERROR;
162 return GNUTLS_E_INVALID_REQUEST;
167 gnutls_pk_params_release(pub);
171 /* Returns the public key of the private key (if possible)
174 _gnutls_privkey_get_mpis(gnutls_privkey_t key, gnutls_pk_params_st * params)
179 #ifdef ENABLE_OPENPGP
180 case GNUTLS_PRIVKEY_OPENPGP:
183 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
186 gnutls_openpgp_privkey_get_preferred_key_id
187 (key->key.openpgp, keyid);
189 KEYID_IMPORT(kid, keyid);
191 _gnutls_openpgp_privkey_get_mpis
192 (key->key.openpgp, kid, params);
195 _gnutls_openpgp_privkey_get_mpis
196 (key->key.openpgp, NULL, params);
206 case GNUTLS_PRIVKEY_X509:
207 ret = _gnutls_pk_params_copy(params, &key->key.x509->params);
210 case GNUTLS_PRIVKEY_PKCS11: {
211 gnutls_pubkey_t pubkey;
213 ret = _pkcs11_privkey_get_pubkey(key->key.pkcs11, &pubkey, 0);
215 return gnutls_assert_val(ret);
217 ret = _gnutls_pubkey_get_mpis(pubkey, params);
218 gnutls_pubkey_deinit(pubkey);
225 return GNUTLS_E_INVALID_REQUEST;
232 _gnutls_privkey_get_public_mpis(gnutls_privkey_t key,
233 gnutls_pk_params_st * params)
236 gnutls_pk_params_st tmp1;
238 gnutls_pk_params_init(&tmp1);
240 ret = _gnutls_privkey_get_mpis(key, &tmp1);
242 return gnutls_assert_val(ret);
244 ret = privkey_to_pubkey(key->pk_algorithm, &tmp1, params);
246 gnutls_pk_params_release(&tmp1);
255 * gnutls_privkey_init:
256 * @key: A pointer to the type to be initialized
258 * This function will initialize a private key.
260 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
261 * negative error value.
265 int gnutls_privkey_init(gnutls_privkey_t * key)
269 *key = gnutls_calloc(1, sizeof(struct gnutls_privkey_st));
272 return GNUTLS_E_MEMORY_ERROR;
279 * gnutls_privkey_deinit:
280 * @key: The key to be deinitialized
282 * This function will deinitialize a private key structure.
286 void gnutls_privkey_deinit(gnutls_privkey_t key)
291 if (key->flags & GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
292 || key->flags & GNUTLS_PRIVKEY_IMPORT_COPY)
294 #ifdef ENABLE_OPENPGP
295 case GNUTLS_PRIVKEY_OPENPGP:
296 gnutls_openpgp_privkey_deinit(key->key.openpgp);
300 case GNUTLS_PRIVKEY_PKCS11:
301 gnutls_pkcs11_privkey_deinit(key->key.pkcs11);
304 case GNUTLS_PRIVKEY_X509:
305 gnutls_x509_privkey_deinit(key->key.x509);
307 case GNUTLS_PRIVKEY_EXT:
308 if (key->key.ext.deinit_func != NULL)
309 key->key.ext.deinit_func(key,
310 key->key.ext.userdata);
318 /* will fail if the private key contains an actual key.
320 static int check_if_clean(gnutls_privkey_t key)
323 return GNUTLS_E_INVALID_REQUEST;
331 * gnutls_privkey_import_pkcs11:
332 * @pkey: The private key
333 * @key: The private key to be imported
334 * @flags: Flags for the import
336 * This function will import the given private key to the abstract
337 * #gnutls_privkey_t type.
339 * The #gnutls_pkcs11_privkey_t object must not be deallocated
340 * during the lifetime of this structure.
342 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
343 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
345 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
346 * negative error value.
351 gnutls_privkey_import_pkcs11(gnutls_privkey_t pkey,
352 gnutls_pkcs11_privkey_t key, unsigned int flags)
356 ret = check_if_clean(pkey);
362 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
363 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
365 pkey->key.pkcs11 = key;
366 pkey->type = GNUTLS_PRIVKEY_PKCS11;
367 pkey->pk_algorithm = gnutls_pkcs11_privkey_get_pk_algorithm(key, NULL);
371 gnutls_pkcs11_privkey_set_pin_function(key, pkey->pin.cb,
379 * gnutls_privkey_import_pkcs11_url:
380 * @key: A key of type #gnutls_pubkey_t
381 * @url: A PKCS 11 url
383 * This function will import a PKCS 11 private key to a #gnutls_private_key_t
386 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
387 * negative error value.
392 int gnutls_privkey_import_pkcs11_url(gnutls_privkey_t key, const char *url)
399 int _gnutls_privkey_import_pkcs11_url(gnutls_privkey_t key, const char *url, unsigned flags)
401 gnutls_pkcs11_privkey_t pkey;
404 ret = gnutls_pkcs11_privkey_init(&pkey);
411 gnutls_pkcs11_privkey_set_pin_function(pkey, key->pin.cb,
414 ret = gnutls_pkcs11_privkey_import_url(pkey, url, flags);
421 gnutls_privkey_import_pkcs11(key, pkey,
422 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
431 gnutls_pkcs11_privkey_deinit(pkey);
437 * gnutls_privkey_export_pkcs11:
438 * @pkey: The private key
439 * @key: Location for the key to be exported.
441 * Converts the given abstract private key to a #gnutls_pkcs11_privkey_t
442 * type. The key must be of type %GNUTLS_PRIVKEY_PKCS11. The key
443 * returned in @key must be deinitialized with
444 * gnutls_pkcs11_privkey_deinit().
446 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
447 * negative error value.
452 gnutls_privkey_export_pkcs11(gnutls_privkey_t pkey,
453 gnutls_pkcs11_privkey_t *key)
457 if (pkey->type != GNUTLS_PRIVKEY_PKCS11) {
459 return GNUTLS_E_INVALID_REQUEST;
462 ret = gnutls_pkcs11_privkey_init(key);
464 return gnutls_assert_val(ret);
466 ret = gnutls_pkcs11_privkey_cpy(*key, pkey->key.pkcs11);
468 gnutls_pkcs11_privkey_deinit(*key);
471 return gnutls_assert_val(ret);
476 #endif /* ENABLE_PKCS11 */
479 * gnutls_privkey_import_ext:
480 * @pkey: The private key
481 * @pk: The public key algorithm
482 * @userdata: private data to be provided to the callbacks
483 * @sign_func: callback for signature operations
484 * @decrypt_func: callback for decryption operations
485 * @flags: Flags for the import
487 * This function will associate the given callbacks with the
488 * #gnutls_privkey_t type. At least one of the two callbacks
491 * See also gnutls_privkey_import_ext3().
493 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
494 * negative error value.
499 gnutls_privkey_import_ext(gnutls_privkey_t pkey,
500 gnutls_pk_algorithm_t pk,
502 gnutls_privkey_sign_func sign_func,
503 gnutls_privkey_decrypt_func decrypt_func,
506 return gnutls_privkey_import_ext2(pkey, pk, userdata, sign_func,
507 decrypt_func, NULL, flags);
511 * gnutls_privkey_import_ext2:
512 * @pkey: The private key
513 * @pk: The public key algorithm
514 * @userdata: private data to be provided to the callbacks
515 * @sign_fn: callback for signature operations
516 * @decrypt_fn: callback for decryption operations
517 * @deinit_fn: a deinitialization function
518 * @flags: Flags for the import
520 * This function will associate the given callbacks with the
521 * #gnutls_privkey_t type. At least one of the two callbacks
522 * must be non-null. If a deinitialization function is provided
523 * then flags is assumed to contain %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE.
525 * Note that the signing function is supposed to "raw" sign data, i.e.,
526 * without any hashing or preprocessing. In case of RSA the DigestInfo
527 * will be provided, and the signing function is expected to do the PKCS #1
528 * 1.5 padding and the exponentiation.
530 * See also gnutls_privkey_import_ext3().
532 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
533 * negative error value.
538 gnutls_privkey_import_ext2(gnutls_privkey_t pkey,
539 gnutls_pk_algorithm_t pk,
541 gnutls_privkey_sign_func sign_fn,
542 gnutls_privkey_decrypt_func decrypt_fn,
543 gnutls_privkey_deinit_func deinit_fn,
548 ret = check_if_clean(pkey);
554 if (sign_fn == NULL && decrypt_fn == NULL)
555 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
557 pkey->key.ext.sign_func = sign_fn;
558 pkey->key.ext.decrypt_func = decrypt_fn;
559 pkey->key.ext.deinit_func = deinit_fn;
560 pkey->key.ext.userdata = userdata;
561 pkey->type = GNUTLS_PRIVKEY_EXT;
562 pkey->pk_algorithm = pk;
565 /* Ensure gnutls_privkey_deinit() calls the deinit_func */
567 pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
573 * gnutls_privkey_import_ext3:
574 * @pkey: The private key
575 * @userdata: private data to be provided to the callbacks
576 * @sign_fn: callback for signature operations
577 * @decrypt_fn: callback for decryption operations
578 * @deinit_fn: a deinitialization function
579 * @info_fn: returns info about the public key algorithm (should not be %NULL)
580 * @flags: Flags for the import
582 * This function will associate the given callbacks with the
583 * #gnutls_privkey_t type. At least one of the two callbacks
584 * must be non-null. If a deinitialization function is provided
585 * then flags is assumed to contain %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE.
587 * Note that the signing function is supposed to "raw" sign data, i.e.,
588 * without any hashing or preprocessing. In case of RSA the DigestInfo
589 * will be provided, and the signing function is expected to do the PKCS #1
590 * 1.5 padding and the exponentiation.
592 * The @info_fn must provide information on the algorithms supported by
593 * this private key, and should support the flags %GNUTLS_PRIVKEY_INFO_PK_ALGO and
594 * %GNUTLS_PRIVKEY_INFO_SIGN_ALGO. It must return -1 on unknown flags.
596 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
597 * negative error value.
602 gnutls_privkey_import_ext3(gnutls_privkey_t pkey,
604 gnutls_privkey_sign_func sign_fn,
605 gnutls_privkey_decrypt_func decrypt_fn,
606 gnutls_privkey_deinit_func deinit_fn,
607 gnutls_privkey_info_func info_fn,
612 ret = check_if_clean(pkey);
618 if (sign_fn == NULL && decrypt_fn == NULL)
619 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
622 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
624 pkey->key.ext.sign_func = sign_fn;
625 pkey->key.ext.decrypt_func = decrypt_fn;
626 pkey->key.ext.deinit_func = deinit_fn;
627 pkey->key.ext.info_func = info_fn;
628 pkey->key.ext.userdata = userdata;
629 pkey->type = GNUTLS_PRIVKEY_EXT;
632 pkey->pk_algorithm = pkey->key.ext.info_func(pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO, pkey->key.ext.userdata);
634 /* Ensure gnutls_privkey_deinit() calls the deinit_func */
636 pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
642 * gnutls_privkey_import_x509:
643 * @pkey: The private key
644 * @key: The private key to be imported
645 * @flags: Flags for the import
647 * This function will import the given private key to the abstract
648 * #gnutls_privkey_t type.
650 * The #gnutls_x509_privkey_t object must not be deallocated
651 * during the lifetime of this structure.
653 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
654 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
656 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
657 * negative error value.
662 gnutls_privkey_import_x509(gnutls_privkey_t pkey,
663 gnutls_x509_privkey_t key, unsigned int flags)
667 ret = check_if_clean(pkey);
673 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY) {
674 ret = gnutls_x509_privkey_init(&pkey->key.x509);
676 return gnutls_assert_val(ret);
678 ret = gnutls_x509_privkey_cpy(pkey->key.x509, key);
680 gnutls_x509_privkey_deinit(pkey->key.x509);
681 return gnutls_assert_val(ret);
684 pkey->key.x509 = key;
686 pkey->type = GNUTLS_PRIVKEY_X509;
687 pkey->pk_algorithm = gnutls_x509_privkey_get_pk_algorithm(key);
694 * gnutls_privkey_export_x509:
695 * @pkey: The private key
696 * @key: Location for the key to be exported.
698 * Converts the given abstract private key to a #gnutls_x509_privkey_t
699 * type. The key must be of type %GNUTLS_PRIVKEY_X509. The key returned
700 * in @key must be deinitialized with gnutls_x509_privkey_deinit().
702 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
703 * negative error value.
708 gnutls_privkey_export_x509(gnutls_privkey_t pkey,
709 gnutls_x509_privkey_t *key)
713 if (pkey->type != GNUTLS_PRIVKEY_X509) {
715 return GNUTLS_E_INVALID_REQUEST;
718 ret = gnutls_x509_privkey_init(key);
720 return gnutls_assert_val(ret);
722 ret = gnutls_x509_privkey_cpy(*key, pkey->key.x509);
724 gnutls_x509_privkey_deinit(*key);
727 return gnutls_assert_val(ret);
734 * gnutls_privkey_generate:
735 * @pkey: The private key
736 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
737 * @bits: the size of the modulus
738 * @flags: unused for now. Must be 0.
740 * This function will generate a random private key. Note that this
741 * function must be called on an empty private key.
743 * Note that when generating an elliptic curve key, the curve
744 * can be substituted in the place of the bits parameter using the
745 * GNUTLS_CURVE_TO_BITS() macro.
747 * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits().
749 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
750 * negative error value.
755 gnutls_privkey_generate(gnutls_privkey_t pkey,
756 gnutls_pk_algorithm_t algo, unsigned int bits,
761 ret = gnutls_x509_privkey_init(&pkey->key.x509);
763 return gnutls_assert_val(ret);
765 ret = gnutls_x509_privkey_generate(pkey->key.x509, algo, bits, flags);
767 gnutls_x509_privkey_deinit(pkey->key.x509);
768 pkey->key.x509 = NULL;
769 return gnutls_assert_val(ret);
772 pkey->type = GNUTLS_PRIVKEY_X509;
773 pkey->pk_algorithm = algo;
774 pkey->flags = flags | GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
779 #ifdef ENABLE_OPENPGP
781 * gnutls_privkey_import_openpgp:
782 * @pkey: The private key
783 * @key: The private key to be imported
784 * @flags: Flags for the import
786 * This function will import the given private key to the abstract
787 * #gnutls_privkey_t type.
789 * The #gnutls_openpgp_privkey_t object must not be deallocated
790 * during the lifetime of this structure. The subkey set as
791 * preferred will be used, or the master key otherwise.
793 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
794 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
796 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
797 * negative error value.
802 gnutls_privkey_import_openpgp(gnutls_privkey_t pkey,
803 gnutls_openpgp_privkey_t key, unsigned int flags)
806 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
808 ret = check_if_clean(pkey);
814 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY) {
815 ret = gnutls_openpgp_privkey_init(&pkey->key.openpgp);
817 return gnutls_assert_val(ret);
819 ret = _gnutls_openpgp_privkey_cpy(pkey->key.openpgp, key);
821 gnutls_openpgp_privkey_deinit(pkey->key.openpgp);
822 return gnutls_assert_val(ret);
825 pkey->key.openpgp = key;
827 pkey->type = GNUTLS_PRIVKEY_OPENPGP;
829 ret = gnutls_openpgp_privkey_get_preferred_key_id(key, keyid);
830 if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR) {
832 gnutls_openpgp_privkey_get_pk_algorithm(key, NULL);
835 return gnutls_assert_val(ret);
837 idx = gnutls_openpgp_privkey_get_subkey_idx(key, keyid);
840 gnutls_openpgp_privkey_get_subkey_pk_algorithm(key,
850 * gnutls_privkey_import_openpgp_raw:
851 * @pkey: The private key
852 * @data: The private key data to be imported
853 * @format: The format of the private key
854 * @keyid: The key id to use (optional)
855 * @password: A password (optional)
857 * This function will import the given private key to the abstract
858 * #gnutls_privkey_t type.
860 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
861 * negative error value.
865 int gnutls_privkey_import_openpgp_raw(gnutls_privkey_t pkey,
866 const gnutls_datum_t * data,
867 gnutls_openpgp_crt_fmt_t format,
868 const gnutls_openpgp_keyid_t keyid,
869 const char *password)
871 gnutls_openpgp_privkey_t xpriv;
874 ret = gnutls_openpgp_privkey_init(&xpriv);
876 return gnutls_assert_val(ret);
878 ret = gnutls_openpgp_privkey_import(xpriv, data, format, password, 0);
885 ret = gnutls_openpgp_privkey_set_preferred_key_id(xpriv, keyid);
893 gnutls_privkey_import_openpgp(pkey, xpriv,
894 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
903 gnutls_openpgp_privkey_deinit(xpriv);
909 * gnutls_privkey_export_openpgp:
910 * @pkey: The private key
911 * @key: Location for the key to be exported.
913 * Converts the given abstract private key to a #gnutls_openpgp_privkey_t
914 * type. The key must be of type %GNUTLS_PRIVKEY_OPENPGP. The key
915 * returned in @key must be deinitialized with
916 * gnutls_openpgp_privkey_deinit().
918 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
919 * negative error value.
924 gnutls_privkey_export_openpgp(gnutls_privkey_t pkey,
925 gnutls_openpgp_privkey_t *key)
929 if (pkey->type != GNUTLS_PRIVKEY_OPENPGP) {
931 return GNUTLS_E_INVALID_REQUEST;
934 ret = gnutls_openpgp_privkey_init(key);
936 return gnutls_assert_val(ret);
938 ret = _gnutls_openpgp_privkey_cpy(*key, pkey->key.openpgp);
940 gnutls_openpgp_privkey_deinit(*key);
943 return gnutls_assert_val(ret);
951 * gnutls_privkey_sign_data:
952 * @signer: Holds the key
953 * @hash: should be a digest algorithm
954 * @flags: Zero or one of %gnutls_privkey_flags_t
955 * @data: holds the data to be signed
956 * @signature: will contain the signature allocated with gnutls_malloc()
958 * This function will sign the given data using a signature algorithm
959 * supported by the private key. Signature algorithms are always used
960 * together with a hash functions. Different hash functions may be
961 * used for the RSA algorithm, but only the SHA family for the DSA keys.
963 * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
964 * the hash algorithm.
966 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
967 * negative error value.
972 gnutls_privkey_sign_data(gnutls_privkey_t signer,
973 gnutls_digest_algorithm_t hash,
975 const gnutls_datum_t * data,
976 gnutls_datum_t * signature)
979 gnutls_datum_t digest;
980 const mac_entry_st *me = hash_to_entry(hash);
982 if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
983 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
985 ret = pk_hash_data(signer->pk_algorithm, me, NULL, data, &digest);
991 ret = pk_prepare_hash(signer->pk_algorithm, me, &digest);
997 ret = _gnutls_privkey_sign_raw_data(signer, flags, &digest, signature);
998 _gnutls_free_datum(&digest);
1008 _gnutls_free_datum(&digest);
1013 * gnutls_privkey_sign_hash:
1014 * @signer: Holds the signer's key
1015 * @hash_algo: The hash algorithm used
1016 * @flags: Zero or one of %gnutls_privkey_flags_t
1017 * @hash_data: holds the data to be signed
1018 * @signature: will contain newly allocated signature
1020 * This function will sign the given hashed data using a signature algorithm
1021 * supported by the private key. Signature algorithms are always used
1022 * together with a hash functions. Different hash functions may be
1023 * used for the RSA algorithm, but only SHA-XXX for the DSA keys.
1025 * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
1026 * the hash algorithm.
1028 * Note that if %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA flag is specified this function
1029 * will ignore @hash_algo and perform a raw PKCS1 signature.
1031 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1032 * negative error value.
1037 gnutls_privkey_sign_hash(gnutls_privkey_t signer,
1038 gnutls_digest_algorithm_t hash_algo,
1040 const gnutls_datum_t * hash_data,
1041 gnutls_datum_t * signature)
1044 gnutls_datum_t digest;
1046 if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
1047 return _gnutls_privkey_sign_raw_data(signer, flags,
1048 hash_data, signature);
1050 digest.data = gnutls_malloc(hash_data->size);
1051 if (digest.data == NULL) {
1053 return GNUTLS_E_MEMORY_ERROR;
1055 digest.size = hash_data->size;
1056 memcpy(digest.data, hash_data->data, digest.size);
1059 pk_prepare_hash(signer->pk_algorithm, hash_to_entry(hash_algo),
1066 ret = _gnutls_privkey_sign_raw_data(signer, flags, &digest, signature);
1075 _gnutls_free_datum(&digest);
1080 * gnutls_privkey_sign_raw_data:
1081 * @key: Holds the key
1082 * @flags: should be zero
1083 * @data: holds the data to be signed
1084 * @signature: will contain the signature allocated with gnutls_malloc()
1086 * This function will sign the given data using a signature algorithm
1087 * supported by the private key. Note that this is a low-level function
1088 * and does not apply any preprocessing or hash on the signed data.
1089 * For example on an RSA key the input @data should be of the DigestInfo
1090 * PKCS #1 1.5 format. Use it only if you know what are you doing.
1092 * Note this function is equivalent to using the %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA
1093 * flag with gnutls_privkey_sign_hash().
1095 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1096 * negative error value.
1101 _gnutls_privkey_sign_raw_data(gnutls_privkey_t key,
1103 const gnutls_datum_t * data,
1104 gnutls_datum_t * signature)
1106 switch (key->type) {
1107 #ifdef ENABLE_OPENPGP
1108 case GNUTLS_PRIVKEY_OPENPGP:
1109 return gnutls_openpgp_privkey_sign_hash(key->key.openpgp,
1112 #ifdef ENABLE_PKCS11
1113 case GNUTLS_PRIVKEY_PKCS11:
1114 return _gnutls_pkcs11_privkey_sign_hash(key->key.pkcs11,
1117 case GNUTLS_PRIVKEY_X509:
1118 return _gnutls_pk_sign(key->key.x509->pk_algorithm,
1119 signature, data, &key->key.x509->params);
1120 case GNUTLS_PRIVKEY_EXT:
1121 if (key->key.ext.sign_func == NULL)
1122 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1123 return key->key.ext.sign_func(key, key->key.ext.userdata,
1127 return GNUTLS_E_INVALID_REQUEST;
1132 * gnutls_privkey_decrypt_data:
1133 * @key: Holds the key
1134 * @flags: zero for now
1135 * @ciphertext: holds the data to be decrypted
1136 * @plaintext: will contain the decrypted data, allocated with gnutls_malloc()
1138 * This function will decrypt the given data using the algorithm
1139 * supported by the private key.
1141 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1142 * negative error value.
1147 gnutls_privkey_decrypt_data(gnutls_privkey_t key,
1149 const gnutls_datum_t * ciphertext,
1150 gnutls_datum_t * plaintext)
1152 switch (key->type) {
1153 #ifdef ENABLE_OPENPGP
1154 case GNUTLS_PRIVKEY_OPENPGP:
1155 return _gnutls_openpgp_privkey_decrypt_data(key->key.openpgp,
1159 case GNUTLS_PRIVKEY_X509:
1160 return _gnutls_pk_decrypt(key->pk_algorithm, plaintext,
1161 ciphertext, &key->key.x509->params);
1162 #ifdef ENABLE_PKCS11
1163 case GNUTLS_PRIVKEY_PKCS11:
1164 return _gnutls_pkcs11_privkey_decrypt_data(key->key.pkcs11,
1169 case GNUTLS_PRIVKEY_EXT:
1170 if (key->key.ext.decrypt_func == NULL)
1171 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1173 return key->key.ext.decrypt_func(key,
1174 key->key.ext.userdata,
1175 ciphertext, plaintext);
1178 return GNUTLS_E_INVALID_REQUEST;
1183 * gnutls_privkey_import_x509_raw:
1184 * @pkey: The private key
1185 * @data: The private key data to be imported
1186 * @format: The format of the private key
1187 * @password: A password (optional)
1188 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
1190 * This function will import the given private key to the abstract
1191 * #gnutls_privkey_t type.
1193 * The supported formats are basic unencrypted key, PKCS8, PKCS12,
1194 * and the openssl format.
1196 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1197 * negative error value.
1201 int gnutls_privkey_import_x509_raw(gnutls_privkey_t pkey,
1202 const gnutls_datum_t * data,
1203 gnutls_x509_crt_fmt_t format,
1204 const char *password, unsigned int flags)
1206 gnutls_x509_privkey_t xpriv;
1209 ret = gnutls_x509_privkey_init(&xpriv);
1211 return gnutls_assert_val(ret);
1214 gnutls_x509_privkey_set_pin_function(xpriv, pkey->pin.cb,
1218 ret = gnutls_x509_privkey_import2(xpriv, data, format, password, flags);
1225 gnutls_privkey_import_x509(pkey, xpriv,
1226 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
1235 gnutls_x509_privkey_deinit(xpriv);
1241 * gnutls_privkey_import_url:
1242 * @key: A key of type #gnutls_privkey_t
1243 * @url: A PKCS 11 url
1244 * @flags: should be zero
1246 * This function will import a PKCS11 or TPM URL as a
1247 * private key. The supported URL types can be checked
1248 * using gnutls_url_is_supported().
1250 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1251 * negative error value.
1256 gnutls_privkey_import_url(gnutls_privkey_t key, const char *url,
1262 if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0) {
1263 #ifdef ENABLE_PKCS11
1264 ret = _gnutls_privkey_import_pkcs11_url(key, url, flags);
1266 ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1271 if (strncmp(url, TPMKEY_URL, TPMKEY_URL_SIZE) == 0) {
1272 #ifdef HAVE_TROUSERS
1273 ret = gnutls_privkey_import_tpm_url(key, url, NULL, NULL, 0);
1275 ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1280 if (strncmp(url, SYSTEM_URL, SYSTEM_URL_SIZE) == 0) {
1281 ret = _gnutls_privkey_import_system_url(key, url);
1285 for (i=0;i<_gnutls_custom_urls_size;i++) {
1286 if (strncmp(url, _gnutls_custom_urls[i].name, _gnutls_custom_urls[i].name_size) == 0) {
1287 if (_gnutls_custom_urls[i].import_key) {
1288 ret = _gnutls_custom_urls[i].import_key(key, url, flags);
1295 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1301 * gnutls_privkey_set_pin_function:
1302 * @key: A key of type #gnutls_privkey_t
1304 * @userdata: data associated with the callback
1306 * This function will set a callback function to be used when
1307 * required to access the object. This function overrides any other
1308 * global PIN functions.
1310 * Note that this function must be called right after initialization
1316 void gnutls_privkey_set_pin_function(gnutls_privkey_t key,
1317 gnutls_pin_callback_t fn, void *userdata)
1320 key->pin.data = userdata;
1324 * gnutls_privkey_status:
1325 * @key: Holds the key
1327 * Checks the status of the private key token. This function
1328 * is an actual wrapper over gnutls_pkcs11_privkey_status(), and
1329 * if the private key is a PKCS #11 token it will check whether
1330 * it is inserted or not.
1332 * Returns: this function will return non-zero if the token
1333 * holding the private key is still available (inserted), and zero otherwise.
1338 int gnutls_privkey_status(gnutls_privkey_t key)
1340 switch (key->type) {
1341 #ifdef ENABLE_PKCS11
1342 case GNUTLS_PRIVKEY_PKCS11:
1343 return gnutls_pkcs11_privkey_status(key->key.pkcs11);
1351 * gnutls_privkey_verify_params:
1352 * @key: should contain a #gnutls_privkey_t type
1354 * This function will verify the private key parameters.
1356 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1357 * negative error value.
1361 int gnutls_privkey_verify_params(gnutls_privkey_t key)
1363 gnutls_pk_params_st params;
1366 gnutls_pk_params_init(¶ms);
1368 ret = _gnutls_privkey_get_mpis(key, ¶ms);
1370 return gnutls_assert_val(ret);
1372 ret = _gnutls_pk_verify_priv_params(key->pk_algorithm, ¶ms);
1374 gnutls_pk_params_release(¶ms);
1385 * _gnutls_privkey_get_preferred_sign_algo:
1386 * @key: should contain a #gnutls_privkey_t type
1388 * This function returns the preferred signature algorithm for this
1391 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1392 * negative error value.
1396 gnutls_sign_algorithm_t
1397 _gnutls_privkey_get_preferred_sign_algo(gnutls_privkey_t key)
1399 if (key->type == GNUTLS_PRIVKEY_EXT) {
1400 if (key->key.ext.info_func)
1401 return key->key.ext.info_func(key, GNUTLS_PRIVKEY_INFO_SIGN_ALGO, key->key.ext.userdata);
1403 return key->preferred_sign_algo;