minor fixes in TPM code
[gnutls.git] / lib / gnutls_privkey.c
blobcb0aa006219b52952396a70e9994d6179e58b1b2
1 /*
2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010-2012 Free Software Foundation, Inc.
4 *
5 * Author: Nikos Mavrogiannopoulos
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 3 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>
23 #include <stdio.h>
24 #include <string.h>
25 #include <gnutls_errors.h>
26 #include <gnutls_datum.h>
27 #include <pkcs11_int.h>
28 #include <gnutls/abstract.h>
29 #include <gnutls_pk.h>
30 #include <x509_int.h>
31 #include <openpgp/openpgp_int.h>
32 #include <openpgp/gnutls_openpgp.h>
33 #include <gnutls_sig.h>
34 #include <abstract_int.h>
36 struct gnutls_privkey_st
38 gnutls_privkey_type_t type;
39 gnutls_pk_algorithm_t pk_algorithm;
41 union
43 gnutls_x509_privkey_t x509;
44 #ifdef ENABLE_PKCS11
45 gnutls_pkcs11_privkey_t pkcs11;
46 #endif
47 #ifdef ENABLE_OPENPGP
48 gnutls_openpgp_privkey_t openpgp;
49 #endif
50 struct {
51 gnutls_privkey_sign_func sign_func;
52 gnutls_privkey_decrypt_func decrypt_func;
53 gnutls_privkey_deinit_func deinit_func;
54 void* userdata;
55 } ext;
56 } key;
58 unsigned int flags;
61 /**
62 * gnutls_privkey_get_type:
63 * @key: should contain a #gnutls_privkey_t structure
65 * This function will return the type of the private key. This is
66 * actually the type of the subsystem used to set this private key.
68 * Returns: a member of the #gnutls_privkey_type_t enumeration on
69 * success, or a negative error code on error.
71 * Since: 2.12.0
72 **/
73 gnutls_privkey_type_t
74 gnutls_privkey_get_type (gnutls_privkey_t key)
76 return key->type;
79 /**
80 * gnutls_privkey_get_pk_algorithm:
81 * @key: should contain a #gnutls_privkey_t structure
82 * @bits: If set will return the number of bits of the parameters (may be NULL)
84 * This function will return the public key algorithm of a private
85 * key and if possible will return a number of bits that indicates
86 * the security parameter of the key.
88 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
89 * success, or a negative error code on error.
91 * Since: 2.12.0
92 **/
93 int
94 gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key, unsigned int *bits)
96 switch (key->type)
98 #ifdef ENABLE_OPENPGP
99 case GNUTLS_PRIVKEY_OPENPGP:
100 return gnutls_openpgp_privkey_get_pk_algorithm (key->key.openpgp, bits);
101 #endif
102 #ifdef ENABLE_PKCS11
103 case GNUTLS_PRIVKEY_PKCS11:
104 return gnutls_pkcs11_privkey_get_pk_algorithm (key->key.pkcs11, bits);
105 #endif
106 case GNUTLS_PRIVKEY_X509:
107 if (bits)
108 *bits = _gnutls_mpi_get_nbits (key->key.x509->params.params[0]);
109 return gnutls_x509_privkey_get_pk_algorithm (key->key.x509);
110 case GNUTLS_PRIVKEY_EXT:
111 if (bits)
112 *bits = 0;
113 return key->pk_algorithm;
114 default:
115 gnutls_assert ();
116 return GNUTLS_E_INVALID_REQUEST;
121 static int
122 privkey_to_pubkey (gnutls_pk_algorithm_t pk,
123 const gnutls_pk_params_st* priv,
124 gnutls_pk_params_st* pub)
126 int ret;
128 switch (pk)
130 case GNUTLS_PK_RSA:
131 pub->params[0] = _gnutls_mpi_copy (priv->params[0]);
132 pub->params[1] = _gnutls_mpi_copy (priv->params[1]);
134 pub->params_nr = RSA_PUBLIC_PARAMS;
136 if (pub->params[0] == NULL || pub->params[1] == NULL)
138 gnutls_assert ();
139 ret = GNUTLS_E_MEMORY_ERROR;
140 goto cleanup;
143 break;
144 case GNUTLS_PK_DSA:
145 pub->params[0] = _gnutls_mpi_copy (priv->params[0]);
146 pub->params[1] = _gnutls_mpi_copy (priv->params[1]);
147 pub->params[2] = _gnutls_mpi_copy (priv->params[2]);
148 pub->params[3] = _gnutls_mpi_copy (priv->params[3]);
150 pub->params_nr = DSA_PUBLIC_PARAMS;
152 if (pub->params[0] == NULL || pub->params[1] == NULL ||
153 pub->params[2] == NULL || pub->params[3] == NULL)
155 gnutls_assert ();
156 ret = GNUTLS_E_MEMORY_ERROR;
157 goto cleanup;
160 break;
161 case GNUTLS_PK_EC:
162 pub->params[0] = _gnutls_mpi_copy (priv->params[0]);
163 pub->params[1] = _gnutls_mpi_copy (priv->params[1]);
164 pub->params[2] = _gnutls_mpi_copy (priv->params[2]);
165 pub->params[3] = _gnutls_mpi_copy (priv->params[3]);
166 pub->params[4] = _gnutls_mpi_copy (priv->params[4]);
167 pub->params[5] = _gnutls_mpi_copy (priv->params[5]);
168 pub->params[6] = _gnutls_mpi_copy (priv->params[6]);
169 pub->params[7] = _gnutls_mpi_copy (priv->params[7]);
171 pub->params_nr = ECC_PUBLIC_PARAMS;
172 pub->flags = priv->flags;
174 if (pub->params[0] == NULL || pub->params[1] == NULL ||
175 pub->params[2] == NULL || pub->params[3] == NULL ||
176 pub->params[4] == NULL || pub->params[5] == NULL ||
177 pub->params[6] == NULL || pub->params[7] == NULL)
179 gnutls_assert ();
180 ret = GNUTLS_E_MEMORY_ERROR;
181 goto cleanup;
184 break;
185 default:
186 gnutls_assert ();
187 return GNUTLS_E_INVALID_REQUEST;
190 return 0;
191 cleanup:
192 gnutls_pk_params_release(pub);
193 return ret;
197 /* Returns the public key of the private key (if possible)
200 _gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
201 gnutls_pk_params_st * params)
203 int ret;
204 gnutls_pk_algorithm_t pk = gnutls_privkey_get_pk_algorithm (key, NULL);
206 switch (key->type)
208 #ifdef ENABLE_OPENPGP
209 case GNUTLS_PRIVKEY_OPENPGP:
211 gnutls_pk_params_st tmp_params;
212 uint32_t kid[2];
213 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
215 ret =
216 gnutls_openpgp_privkey_get_preferred_key_id (key->key.openpgp,
217 keyid);
218 if (ret == 0)
220 KEYID_IMPORT (kid, keyid);
221 ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, kid,
222 &tmp_params);
224 else
225 ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, NULL,
226 &tmp_params);
228 if (ret < 0)
230 gnutls_assert ();
231 return ret;
234 ret = privkey_to_pubkey (pk,
235 &tmp_params,
236 params);
238 gnutls_pk_params_release(&tmp_params);
241 break;
242 #endif
243 case GNUTLS_PRIVKEY_X509:
244 ret = privkey_to_pubkey (pk,
245 &key->key.x509->params,
246 params);
247 break;
248 default:
249 gnutls_assert ();
250 return GNUTLS_E_INVALID_REQUEST;
253 return ret;
257 * gnutls_privkey_init:
258 * @key: The structure to be initialized
260 * This function will initialize an private key structure.
262 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
263 * negative error value.
265 * Since: 2.12.0
268 gnutls_privkey_init (gnutls_privkey_t * key)
270 *key = gnutls_calloc (1, sizeof (struct gnutls_privkey_st));
271 if (*key == NULL)
273 gnutls_assert ();
274 return GNUTLS_E_MEMORY_ERROR;
277 return 0;
281 * gnutls_privkey_deinit:
282 * @key: The structure to be deinitialized
284 * This function will deinitialize a private key structure.
286 * Since: 2.12.0
288 void
289 gnutls_privkey_deinit (gnutls_privkey_t key)
291 if (key == NULL) return;
293 if (key->flags & GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE || key->flags & GNUTLS_PRIVKEY_IMPORT_COPY)
294 switch (key->type)
296 #ifdef ENABLE_OPENPGP
297 case GNUTLS_PRIVKEY_OPENPGP:
298 gnutls_openpgp_privkey_deinit (key->key.openpgp);
299 break;
300 #endif
301 #ifdef ENABLE_PKCS11
302 case GNUTLS_PRIVKEY_PKCS11:
303 gnutls_pkcs11_privkey_deinit (key->key.pkcs11);
304 break;
305 #endif
306 case GNUTLS_PRIVKEY_X509:
307 gnutls_x509_privkey_deinit (key->key.x509);
308 break;
309 case GNUTLS_PRIVKEY_EXT:
310 if (key->key.ext.deinit_func != NULL)
311 key->key.ext.deinit_func(key, key->key.ext.userdata);
312 break;
313 default:
314 break;
316 gnutls_free (key);
319 /* will fail if the private key contains an actual key.
321 static int check_if_clean(gnutls_privkey_t key)
323 if (key->type != 0)
324 return GNUTLS_E_INVALID_REQUEST;
326 return 0;
329 #ifdef ENABLE_PKCS11
332 * gnutls_privkey_import_pkcs11:
333 * @pkey: The private key
334 * @key: The private key to be imported
335 * @flags: Flags for the import
337 * This function will import the given private key to the abstract
338 * #gnutls_privkey_t structure.
340 * The #gnutls_pkcs11_privkey_t object must not be deallocated
341 * during the lifetime of this structure.
343 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
344 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
346 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
347 * negative error value.
349 * Since: 2.12.0
352 gnutls_privkey_import_pkcs11 (gnutls_privkey_t pkey,
353 gnutls_pkcs11_privkey_t key, unsigned int flags)
355 int ret;
357 ret = check_if_clean(pkey);
358 if (ret < 0)
360 gnutls_assert();
361 return ret;
364 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
365 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
367 pkey->key.pkcs11 = key;
368 pkey->type = GNUTLS_PRIVKEY_PKCS11;
369 pkey->pk_algorithm = gnutls_pkcs11_privkey_get_pk_algorithm (key, NULL);
370 pkey->flags = flags;
372 return 0;
376 * gnutls_privkey_import_pkcs11_url:
377 * @key: A key of type #gnutls_pubkey_t
378 * @url: A PKCS 11 url
380 * This function will import a PKCS 11 private key to a #gnutls_private_key_t
381 * structure.
383 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
384 * negative error value.
386 * Since: 3.1.0
389 gnutls_privkey_import_pkcs11_url (gnutls_privkey_t key, const char *url)
391 gnutls_pkcs11_privkey_t pkey;
392 int ret;
394 ret = gnutls_pkcs11_privkey_init (&pkey);
395 if (ret < 0)
397 gnutls_assert ();
398 return ret;
401 ret = gnutls_pkcs11_privkey_import_url (pkey, url, 0);
402 if (ret < 0)
404 gnutls_assert ();
405 goto cleanup;
408 ret = gnutls_privkey_import_pkcs11 (key, pkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
409 if (ret < 0)
411 gnutls_assert ();
412 goto cleanup;
415 return 0;
417 cleanup:
418 gnutls_pkcs11_privkey_deinit (pkey);
420 return ret;
423 #endif /* ENABLE_PKCS11 */
426 * gnutls_privkey_import_ext:
427 * @pkey: The private key
428 * @pk: The public key algorithm
429 * @userdata: private data to be provided to the callbacks
430 * @sign_func: callback for signature operations
431 * @decrypt_func: callback for decryption operations
432 * @flags: Flags for the import
434 * This function will associate the given callbacks with the
435 * #gnutls_privkey_t structure. At least one of the two callbacks
436 * must be non-null.
438 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
439 * negative error value.
441 * Since: 3.0
444 gnutls_privkey_import_ext (gnutls_privkey_t pkey,
445 gnutls_pk_algorithm_t pk,
446 void* userdata,
447 gnutls_privkey_sign_func sign_func,
448 gnutls_privkey_decrypt_func decrypt_func,
449 unsigned int flags)
451 return gnutls_privkey_import_ext2( pkey, pk, userdata, sign_func, decrypt_func,
452 NULL, flags);
456 * gnutls_privkey_import_ext2:
457 * @pkey: The private key
458 * @pk: The public key algorithm
459 * @userdata: private data to be provided to the callbacks
460 * @sign_func: callback for signature operations
461 * @decrypt_func: callback for decryption operations
462 * @deinit_func: a deinitialization function
463 * @flags: Flags for the import
465 * This function will associate the given callbacks with the
466 * #gnutls_privkey_t structure. At least one of the two callbacks
467 * must be non-null. If a deinitialization function is provided
468 * then flags is assumed to contain %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE.
470 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
471 * negative error value.
473 * Since: 3.1
476 gnutls_privkey_import_ext2 (gnutls_privkey_t pkey,
477 gnutls_pk_algorithm_t pk,
478 void* userdata,
479 gnutls_privkey_sign_func sign_func,
480 gnutls_privkey_decrypt_func decrypt_func,
481 gnutls_privkey_deinit_func deinit_func,
482 unsigned int flags)
484 int ret;
486 ret = check_if_clean(pkey);
487 if (ret < 0)
489 gnutls_assert();
490 return ret;
493 if (sign_func == NULL && decrypt_func == NULL)
494 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
496 pkey->key.ext.sign_func = sign_func;
497 pkey->key.ext.decrypt_func = decrypt_func;
498 pkey->key.ext.deinit_func = deinit_func;
499 pkey->key.ext.userdata = userdata;
500 pkey->type = GNUTLS_PRIVKEY_EXT;
501 pkey->pk_algorithm = pk;
502 pkey->flags = flags;
504 /* Ensure gnutls_privkey_deinit() calls the deinit_func */
505 if (deinit_func)
506 pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
508 return 0;
512 * gnutls_privkey_import_x509:
513 * @pkey: The private key
514 * @key: The private key to be imported
515 * @flags: Flags for the import
517 * This function will import the given private key to the abstract
518 * #gnutls_privkey_t structure.
520 * The #gnutls_x509_privkey_t object must not be deallocated
521 * during the lifetime of this structure.
523 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
524 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
526 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
527 * negative error value.
529 * Since: 2.12.0
532 gnutls_privkey_import_x509 (gnutls_privkey_t pkey,
533 gnutls_x509_privkey_t key, unsigned int flags)
535 int ret;
537 ret = check_if_clean(pkey);
538 if (ret < 0)
540 gnutls_assert();
541 return ret;
544 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
546 ret = gnutls_x509_privkey_init(&pkey->key.x509);
547 if (ret < 0)
548 return gnutls_assert_val(ret);
550 ret = gnutls_x509_privkey_cpy(pkey->key.x509, key);
551 if (ret < 0)
553 gnutls_x509_privkey_deinit(pkey->key.x509);
554 return gnutls_assert_val(ret);
557 else
558 pkey->key.x509 = key;
560 pkey->type = GNUTLS_PRIVKEY_X509;
561 pkey->pk_algorithm = gnutls_x509_privkey_get_pk_algorithm (key);
562 pkey->flags = flags;
564 return 0;
567 #ifdef ENABLE_OPENPGP
569 * gnutls_privkey_import_openpgp:
570 * @pkey: The private key
571 * @key: The private key to be imported
572 * @flags: Flags for the import
574 * This function will import the given private key to the abstract
575 * #gnutls_privkey_t structure.
577 * The #gnutls_openpgp_privkey_t object must not be deallocated
578 * during the lifetime of this structure. The subkey set as
579 * preferred will be used, or the master key otherwise.
581 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
582 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
584 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
585 * negative error value.
587 * Since: 2.12.0
590 gnutls_privkey_import_openpgp (gnutls_privkey_t pkey,
591 gnutls_openpgp_privkey_t key,
592 unsigned int flags)
594 int ret, idx;
595 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
597 ret = check_if_clean(pkey);
598 if (ret < 0)
600 gnutls_assert();
601 return ret;
604 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
606 ret = gnutls_openpgp_privkey_init(&pkey->key.openpgp);
607 if (ret < 0)
608 return gnutls_assert_val(ret);
610 ret = _gnutls_openpgp_privkey_cpy(pkey->key.openpgp, key);
611 if (ret < 0)
613 gnutls_openpgp_privkey_deinit(pkey->key.openpgp);
614 return gnutls_assert_val(ret);
617 else
618 pkey->key.openpgp = key;
620 pkey->type = GNUTLS_PRIVKEY_OPENPGP;
622 ret = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid);
623 if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR)
625 pkey->pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm(key, NULL);
627 else
629 if (ret < 0)
630 return gnutls_assert_val(ret);
632 idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);
634 pkey->pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL);
637 pkey->flags = flags;
639 return 0;
641 #endif
644 * gnutls_privkey_sign_data:
645 * @signer: Holds the key
646 * @hash: should be a digest algorithm
647 * @flags: should be 0 for now
648 * @data: holds the data to be signed
649 * @signature: will contain the signature allocate with gnutls_malloc()
651 * This function will sign the given data using a signature algorithm
652 * supported by the private key. Signature algorithms are always used
653 * together with a hash functions. Different hash functions may be
654 * used for the RSA algorithm, but only the SHA family for the DSA keys.
656 * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
657 * the hash algorithm.
659 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
660 * negative error value.
662 * Since: 2.12.0
665 gnutls_privkey_sign_data (gnutls_privkey_t signer,
666 gnutls_digest_algorithm_t hash,
667 unsigned int flags,
668 const gnutls_datum_t * data,
669 gnutls_datum_t * signature)
671 int ret;
672 gnutls_datum_t digest;
674 ret = pk_hash_data (signer->pk_algorithm, hash, NULL, data, &digest);
675 if (ret < 0)
677 gnutls_assert ();
678 return ret;
681 ret = pk_prepare_hash (signer->pk_algorithm, hash, &digest);
682 if (ret < 0)
684 gnutls_assert ();
685 goto cleanup;
688 ret = _gnutls_privkey_sign_hash (signer, &digest, signature);
689 _gnutls_free_datum (&digest);
691 if (ret < 0)
693 gnutls_assert ();
694 return ret;
697 return 0;
699 cleanup:
700 _gnutls_free_datum (&digest);
701 return ret;
705 * gnutls_privkey_sign_hash:
706 * @signer: Holds the signer's key
707 * @hash_algo: The hash algorithm used
708 * @flags: zero for now
709 * @hash_data: holds the data to be signed
710 * @signature: will contain newly allocated signature
712 * This function will sign the given hashed data using a signature algorithm
713 * supported by the private key. Signature algorithms are always used
714 * together with a hash functions. Different hash functions may be
715 * used for the RSA algorithm, but only SHA-XXX for the DSA keys.
717 * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
718 * the hash algorithm.
720 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
721 * negative error value.
723 * Since: 2.12.0
726 gnutls_privkey_sign_hash (gnutls_privkey_t signer,
727 gnutls_digest_algorithm_t hash_algo,
728 unsigned int flags,
729 const gnutls_datum_t * hash_data,
730 gnutls_datum_t * signature)
732 int ret;
733 gnutls_datum_t digest;
735 digest.data = gnutls_malloc (hash_data->size);
736 if (digest.data == NULL)
738 gnutls_assert ();
739 return GNUTLS_E_MEMORY_ERROR;
741 digest.size = hash_data->size;
742 memcpy (digest.data, hash_data->data, digest.size);
744 ret = pk_prepare_hash (signer->pk_algorithm, hash_algo, &digest);
745 if (ret < 0)
747 gnutls_assert ();
748 goto cleanup;
751 ret = _gnutls_privkey_sign_hash (signer, &digest, signature);
752 if (ret < 0)
754 gnutls_assert ();
755 goto cleanup;
758 ret = 0;
760 cleanup:
761 _gnutls_free_datum (&digest);
762 return ret;
766 * _gnutls_privkey_sign_hash:
767 * @key: Holds the key
768 * @data: holds the data to be signed
769 * @signature: will contain the signature allocate with gnutls_malloc()
771 * This function will sign the given data using a signature algorithm
772 * supported by the private key.
774 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
775 * negative error value.
778 _gnutls_privkey_sign_hash (gnutls_privkey_t key,
779 const gnutls_datum_t * hash,
780 gnutls_datum_t * signature)
782 switch (key->type)
784 #ifdef ENABLE_OPENPGP
785 case GNUTLS_PRIVKEY_OPENPGP:
786 return gnutls_openpgp_privkey_sign_hash (key->key.openpgp,
787 hash, signature);
788 #endif
789 #ifdef ENABLE_PKCS11
790 case GNUTLS_PRIVKEY_PKCS11:
791 return _gnutls_pkcs11_privkey_sign_hash (key->key.pkcs11,
792 hash, signature);
793 #endif
794 case GNUTLS_PRIVKEY_X509:
795 return _gnutls_pk_sign (key->key.x509->pk_algorithm,
796 signature, hash, &key->key.x509->params);
797 case GNUTLS_PRIVKEY_EXT:
798 if (key->key.ext.sign_func == NULL)
799 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
800 return key->key.ext.sign_func(key, key->key.ext.userdata, hash, signature);
801 default:
802 gnutls_assert ();
803 return GNUTLS_E_INVALID_REQUEST;
808 * gnutls_privkey_decrypt_data:
809 * @key: Holds the key
810 * @flags: zero for now
811 * @ciphertext: holds the data to be decrypted
812 * @plaintext: will contain the decrypted data, allocated with gnutls_malloc()
814 * This function will decrypt the given data using the algorithm
815 * supported by the private key.
817 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
818 * negative error value.
820 * Since: 2.12.0
823 gnutls_privkey_decrypt_data (gnutls_privkey_t key,
824 unsigned int flags,
825 const gnutls_datum_t * ciphertext,
826 gnutls_datum_t * plaintext)
828 switch (key->type)
830 #ifdef ENABLE_OPENPGP
831 case GNUTLS_PRIVKEY_OPENPGP:
832 return _gnutls_openpgp_privkey_decrypt_data (key->key.openpgp, flags,
833 ciphertext, plaintext);
834 #endif
835 case GNUTLS_PRIVKEY_X509:
836 return _gnutls_pk_decrypt (key->pk_algorithm, plaintext, ciphertext,
837 &key->key.x509->params);
838 #ifdef ENABLE_PKCS11
839 case GNUTLS_PRIVKEY_PKCS11:
840 return _gnutls_pkcs11_privkey_decrypt_data (key->key.pkcs11,
841 flags,
842 ciphertext, plaintext);
843 #endif
844 case GNUTLS_PRIVKEY_EXT:
845 if (key->key.ext.decrypt_func == NULL)
846 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
848 return key->key.ext.decrypt_func(key, key->key.ext.userdata, ciphertext, plaintext);
849 default:
850 gnutls_assert ();
851 return GNUTLS_E_INVALID_REQUEST;
856 * gnutls_privkey_import_x509_raw:
857 * @pkey: The private key
858 * @data: The private key data to be imported
859 * @format: The format of the private key
860 * @password: A password (optional)
862 * This function will import the given private key to the abstract
863 * #gnutls_privkey_t structure.
865 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
866 * negative error value.
868 * Since: 3.1.0
870 int gnutls_privkey_import_x509_raw (gnutls_privkey_t pkey,
871 const gnutls_datum_t * data,
872 gnutls_x509_crt_fmt_t format,
873 const char* password)
875 gnutls_x509_privkey_t xpriv;
876 int ret;
878 ret = gnutls_x509_privkey_init(&xpriv);
879 if (ret < 0)
880 return gnutls_assert_val(ret);
882 ret = gnutls_x509_privkey_import2(xpriv, data, format, password);
883 if (ret < 0)
885 gnutls_assert();
886 goto cleanup;
889 ret = gnutls_privkey_import_x509(pkey, xpriv, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
890 if (ret < 0)
892 gnutls_assert();
893 goto cleanup;
896 return 0;
898 cleanup:
899 gnutls_x509_privkey_deinit(xpriv);
901 return ret;
905 * gnutls_privkey_import_openpgp_raw:
906 * @pkey: The private key
907 * @data: The private key data to be imported
908 * @format: The format of the private key
909 * @keyid: The key id to use (optional)
910 * @password: A password (optional)
912 * This function will import the given private key to the abstract
913 * #gnutls_privkey_t structure.
915 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
916 * negative error value.
918 * Since: 3.1.0
920 int gnutls_privkey_import_openpgp_raw (gnutls_privkey_t pkey,
921 const gnutls_datum_t * data,
922 gnutls_openpgp_crt_fmt_t format,
923 const gnutls_openpgp_keyid_t keyid,
924 const char* password)
926 gnutls_openpgp_privkey_t xpriv;
927 int ret;
929 ret = gnutls_openpgp_privkey_init(&xpriv);
930 if (ret < 0)
931 return gnutls_assert_val(ret);
933 ret = gnutls_openpgp_privkey_import(xpriv, data, format, password, 0);
934 if (ret < 0)
936 gnutls_assert();
937 goto cleanup;
940 if(keyid)
942 ret = gnutls_openpgp_privkey_set_preferred_key_id(xpriv, keyid);
943 if (ret < 0)
945 gnutls_assert();
946 goto cleanup;
950 ret = gnutls_privkey_import_openpgp(pkey, xpriv, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
951 if (ret < 0)
953 gnutls_assert();
954 goto cleanup;
957 ret = 0;
959 cleanup:
960 gnutls_openpgp_privkey_deinit(xpriv);
962 return ret;
967 * gnutls_privkey_import_url:
968 * @key: A key of type #gnutls_pubkey_t
969 * @url: A PKCS 11 url
970 * @flags: should be zero
972 * This function will import a PKCS11 or TPM URL as a
973 * private key.
975 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
976 * negative error value.
978 * Since: 3.1.0
981 gnutls_privkey_import_url (gnutls_privkey_t key, const char *url, unsigned int flags)
983 #ifdef ENABLE_PKCS11
984 if (strstr(url, "pkcs11:") != NULL)
985 return gnutls_privkey_import_pkcs11_url(key, url);
986 #endif
987 #ifdef HAVE_TROUSERS
988 if (strstr(url, "tpmkey:") != NULL)
989 return gnutls_privkey_import_tpm_url(key, url, NULL, NULL, 0);
990 #endif
991 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);