updated licenses
[gnutls.git] / lib / gnutls_privkey.c
blob9cb820ed565cd3c4041781709a099008427f0882
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 void* userdata;
54 } ext;
55 } key;
57 unsigned int flags;
60 /**
61 * gnutls_privkey_get_type:
62 * @key: should contain a #gnutls_privkey_t structure
64 * This function will return the type of the private key. This is
65 * actually the type of the subsystem used to set this private key.
67 * Returns: a member of the #gnutls_privkey_type_t enumeration on
68 * success, or a negative error code on error.
70 * Since: 2.12.0
71 **/
72 gnutls_privkey_type_t
73 gnutls_privkey_get_type (gnutls_privkey_t key)
75 return key->type;
78 /**
79 * gnutls_privkey_get_pk_algorithm:
80 * @key: should contain a #gnutls_privkey_t structure
81 * @bits: If set will return the number of bits of the parameters (may be NULL)
83 * This function will return the public key algorithm of a private
84 * key and if possible will return a number of bits that indicates
85 * the security parameter of the key.
87 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
88 * success, or a negative error code on error.
90 * Since: 2.12.0
91 **/
92 int
93 gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key, unsigned int *bits)
95 switch (key->type)
97 #ifdef ENABLE_OPENPGP
98 case GNUTLS_PRIVKEY_OPENPGP:
99 return gnutls_openpgp_privkey_get_pk_algorithm (key->key.openpgp, bits);
100 #endif
101 #ifdef ENABLE_PKCS11
102 case GNUTLS_PRIVKEY_PKCS11:
103 return gnutls_pkcs11_privkey_get_pk_algorithm (key->key.pkcs11, bits);
104 #endif
105 case GNUTLS_PRIVKEY_X509:
106 if (bits)
107 *bits = _gnutls_mpi_get_nbits (key->key.x509->params.params[0]);
108 return gnutls_x509_privkey_get_pk_algorithm (key->key.x509);
109 case GNUTLS_PRIVKEY_EXT:
110 if (bits)
111 *bits = 0;
112 return key->pk_algorithm;
113 default:
114 gnutls_assert ();
115 return GNUTLS_E_INVALID_REQUEST;
120 static int
121 privkey_to_pubkey (gnutls_pk_algorithm_t pk,
122 const gnutls_pk_params_st* priv,
123 gnutls_pk_params_st* pub)
125 int ret;
127 switch (pk)
129 case GNUTLS_PK_RSA:
130 pub->params[0] = _gnutls_mpi_copy (priv->params[0]);
131 pub->params[1] = _gnutls_mpi_copy (priv->params[1]);
133 pub->params_nr = RSA_PUBLIC_PARAMS;
135 if (pub->params[0] == NULL || pub->params[1] == NULL)
137 gnutls_assert ();
138 ret = GNUTLS_E_MEMORY_ERROR;
139 goto cleanup;
142 break;
143 case GNUTLS_PK_DSA:
144 pub->params[0] = _gnutls_mpi_copy (priv->params[0]);
145 pub->params[1] = _gnutls_mpi_copy (priv->params[1]);
146 pub->params[2] = _gnutls_mpi_copy (priv->params[2]);
147 pub->params[3] = _gnutls_mpi_copy (priv->params[3]);
149 pub->params_nr = DSA_PUBLIC_PARAMS;
151 if (pub->params[0] == NULL || pub->params[1] == NULL ||
152 pub->params[2] == NULL || pub->params[3] == NULL)
154 gnutls_assert ();
155 ret = GNUTLS_E_MEMORY_ERROR;
156 goto cleanup;
159 break;
160 case GNUTLS_PK_EC:
161 pub->params[0] = _gnutls_mpi_copy (priv->params[0]);
162 pub->params[1] = _gnutls_mpi_copy (priv->params[1]);
163 pub->params[2] = _gnutls_mpi_copy (priv->params[2]);
164 pub->params[3] = _gnutls_mpi_copy (priv->params[3]);
165 pub->params[4] = _gnutls_mpi_copy (priv->params[4]);
166 pub->params[5] = _gnutls_mpi_copy (priv->params[5]);
167 pub->params[6] = _gnutls_mpi_copy (priv->params[6]);
168 pub->params[7] = _gnutls_mpi_copy (priv->params[7]);
170 pub->params_nr = ECC_PUBLIC_PARAMS;
171 pub->flags = priv->flags;
173 if (pub->params[0] == NULL || pub->params[1] == NULL ||
174 pub->params[2] == NULL || pub->params[3] == NULL ||
175 pub->params[4] == NULL || pub->params[5] == NULL ||
176 pub->params[6] == NULL || pub->params[7] == NULL)
178 gnutls_assert ();
179 ret = GNUTLS_E_MEMORY_ERROR;
180 goto cleanup;
183 break;
184 default:
185 gnutls_assert ();
186 return GNUTLS_E_INVALID_REQUEST;
189 return 0;
190 cleanup:
191 gnutls_pk_params_release(pub);
192 return ret;
196 /* Returns the public key of the private key (if possible)
199 _gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
200 gnutls_pk_params_st * params)
202 int ret;
203 gnutls_pk_algorithm_t pk = gnutls_privkey_get_pk_algorithm (key, NULL);
205 switch (key->type)
207 #ifdef ENABLE_OPENPGP
208 case GNUTLS_PRIVKEY_OPENPGP:
210 gnutls_pk_params_st tmp_params;
211 uint32_t kid[2];
212 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
214 ret =
215 gnutls_openpgp_privkey_get_preferred_key_id (key->key.openpgp,
216 keyid);
217 if (ret == 0)
219 KEYID_IMPORT (kid, keyid);
220 ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, kid,
221 &tmp_params);
223 else
224 ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, NULL,
225 &tmp_params);
227 if (ret < 0)
229 gnutls_assert ();
230 return ret;
233 ret = privkey_to_pubkey (pk,
234 &tmp_params,
235 params);
237 gnutls_pk_params_release(&tmp_params);
240 break;
241 #endif
242 case GNUTLS_PRIVKEY_X509:
243 ret = privkey_to_pubkey (pk,
244 &key->key.x509->params,
245 params);
246 break;
247 default:
248 gnutls_assert ();
249 return GNUTLS_E_INVALID_REQUEST;
252 return ret;
256 * gnutls_privkey_init:
257 * @key: The structure to be initialized
259 * This function will initialize an private key structure.
261 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
262 * negative error value.
264 * Since: 2.12.0
267 gnutls_privkey_init (gnutls_privkey_t * key)
269 *key = gnutls_calloc (1, sizeof (struct gnutls_privkey_st));
270 if (*key == NULL)
272 gnutls_assert ();
273 return GNUTLS_E_MEMORY_ERROR;
276 return 0;
280 * gnutls_privkey_deinit:
281 * @key: The structure to be deinitialized
283 * This function will deinitialize a private key structure.
285 * Since: 2.12.0
287 void
288 gnutls_privkey_deinit (gnutls_privkey_t key)
290 if (key == NULL) return;
292 if (key->flags & GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE || key->flags & GNUTLS_PRIVKEY_IMPORT_COPY)
293 switch (key->type)
295 #ifdef ENABLE_OPENPGP
296 case GNUTLS_PRIVKEY_OPENPGP:
297 gnutls_openpgp_privkey_deinit (key->key.openpgp);
298 break;
299 #endif
300 #ifdef ENABLE_PKCS11
301 case GNUTLS_PRIVKEY_PKCS11:
302 gnutls_pkcs11_privkey_deinit (key->key.pkcs11);
303 break;
304 #endif
305 case GNUTLS_PRIVKEY_X509:
306 gnutls_x509_privkey_deinit (key->key.x509);
307 break;
308 default:
309 break;
311 gnutls_free (key);
314 /* will fail if the private key contains an actual key.
316 static int check_if_clean(gnutls_privkey_t key)
318 if (key->type != 0)
319 return GNUTLS_E_INVALID_REQUEST;
321 return 0;
324 #ifdef ENABLE_PKCS11
327 * gnutls_privkey_import_pkcs11:
328 * @pkey: The private key
329 * @key: The private key to be imported
330 * @flags: Flags for the import
332 * This function will import the given private key to the abstract
333 * #gnutls_privkey_t structure.
335 * The #gnutls_pkcs11_privkey_t object must not be deallocated
336 * during the lifetime of this structure.
338 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
339 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
341 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
342 * negative error value.
344 * Since: 2.12.0
347 gnutls_privkey_import_pkcs11 (gnutls_privkey_t pkey,
348 gnutls_pkcs11_privkey_t key, unsigned int flags)
350 int ret;
352 ret = check_if_clean(pkey);
353 if (ret < 0)
355 gnutls_assert();
356 return ret;
359 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
360 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
362 pkey->key.pkcs11 = key;
363 pkey->type = GNUTLS_PRIVKEY_PKCS11;
364 pkey->pk_algorithm = gnutls_pkcs11_privkey_get_pk_algorithm (key, NULL);
365 pkey->flags = flags;
367 return 0;
370 #endif /* ENABLE_PKCS11 */
373 * gnutls_privkey_import_ext:
374 * @pkey: The private key
375 * @pk: The public key algorithm
376 * @userdata: private data to be provided to the callbacks
377 * @sign_func: callback for signature operations
378 * @decrypt_func: callback for decryption operations
379 * @flags: Flags for the import
381 * This function will associate the given callbacks with the
382 * #gnutls_privkey_t structure. At least one of the two callbacks
383 * must be non-null.
385 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
386 * negative error value.
388 * Since: 3.0
391 gnutls_privkey_import_ext (gnutls_privkey_t pkey,
392 gnutls_pk_algorithm_t pk,
393 void* userdata,
394 gnutls_privkey_sign_func sign_func,
395 gnutls_privkey_decrypt_func decrypt_func,
396 unsigned int flags)
398 int ret;
400 ret = check_if_clean(pkey);
401 if (ret < 0)
403 gnutls_assert();
404 return ret;
407 if (sign_func == NULL && decrypt_func == NULL)
408 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
410 pkey->key.ext.sign_func = sign_func;
411 pkey->key.ext.decrypt_func = decrypt_func;
412 pkey->key.ext.userdata = userdata;
413 pkey->type = GNUTLS_PRIVKEY_EXT;
414 pkey->pk_algorithm = pk;
415 pkey->flags = flags;
417 return 0;
421 * gnutls_privkey_import_x509:
422 * @pkey: The private key
423 * @key: The private key to be imported
424 * @flags: Flags for the import
426 * This function will import the given private key to the abstract
427 * #gnutls_privkey_t structure.
429 * The #gnutls_x509_privkey_t object must not be deallocated
430 * during the lifetime of this structure.
432 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
433 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
435 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
436 * negative error value.
438 * Since: 2.12.0
441 gnutls_privkey_import_x509 (gnutls_privkey_t pkey,
442 gnutls_x509_privkey_t key, unsigned int flags)
444 int ret;
446 ret = check_if_clean(pkey);
447 if (ret < 0)
449 gnutls_assert();
450 return ret;
453 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
455 ret = gnutls_x509_privkey_init(&pkey->key.x509);
456 if (ret < 0)
457 return gnutls_assert_val(ret);
459 ret = gnutls_x509_privkey_cpy(pkey->key.x509, key);
460 if (ret < 0)
462 gnutls_x509_privkey_deinit(pkey->key.x509);
463 return gnutls_assert_val(ret);
466 else
467 pkey->key.x509 = key;
469 pkey->type = GNUTLS_PRIVKEY_X509;
470 pkey->pk_algorithm = gnutls_x509_privkey_get_pk_algorithm (key);
471 pkey->flags = flags;
473 return 0;
476 #ifdef ENABLE_OPENPGP
478 * gnutls_privkey_import_openpgp:
479 * @pkey: The private key
480 * @key: The private key to be imported
481 * @flags: Flags for the import
483 * This function will import the given private key to the abstract
484 * #gnutls_privkey_t structure.
486 * The #gnutls_openpgp_privkey_t object must not be deallocated
487 * during the lifetime of this structure. The subkey set as
488 * preferred will be used, or the master key otherwise.
490 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
491 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
493 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
494 * negative error value.
496 * Since: 2.12.0
499 gnutls_privkey_import_openpgp (gnutls_privkey_t pkey,
500 gnutls_openpgp_privkey_t key,
501 unsigned int flags)
503 int ret, idx;
504 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
506 ret = check_if_clean(pkey);
507 if (ret < 0)
509 gnutls_assert();
510 return ret;
513 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
515 ret = gnutls_openpgp_privkey_init(&pkey->key.openpgp);
516 if (ret < 0)
517 return gnutls_assert_val(ret);
519 ret = _gnutls_openpgp_privkey_cpy(pkey->key.openpgp, key);
520 if (ret < 0)
522 gnutls_openpgp_privkey_deinit(pkey->key.openpgp);
523 return gnutls_assert_val(ret);
526 else
527 pkey->key.openpgp = key;
529 pkey->type = GNUTLS_PRIVKEY_OPENPGP;
531 ret = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid);
532 if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR)
534 pkey->pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm(key, NULL);
536 else
538 if (ret < 0)
539 return gnutls_assert_val(ret);
541 idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);
543 pkey->pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL);
546 pkey->flags = flags;
548 return 0;
550 #endif
553 * gnutls_privkey_sign_data:
554 * @signer: Holds the key
555 * @hash: should be a digest algorithm
556 * @flags: should be 0 for now
557 * @data: holds the data to be signed
558 * @signature: will contain the signature allocate with gnutls_malloc()
560 * This function will sign the given data using a signature algorithm
561 * supported by the private key. Signature algorithms are always used
562 * together with a hash functions. Different hash functions may be
563 * used for the RSA algorithm, but only the SHA family for the DSA keys.
565 * Use gnutls_pubkey_get_preferred_hash_algorithm() to determine
566 * the hash algorithm.
568 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
569 * negative error value.
571 * Since: 2.12.0
574 gnutls_privkey_sign_data (gnutls_privkey_t signer,
575 gnutls_digest_algorithm_t hash,
576 unsigned int flags,
577 const gnutls_datum_t * data,
578 gnutls_datum_t * signature)
580 int ret;
581 gnutls_datum_t digest;
583 ret = pk_hash_data (signer->pk_algorithm, hash, NULL, data, &digest);
584 if (ret < 0)
586 gnutls_assert ();
587 return ret;
590 ret = pk_prepare_hash (signer->pk_algorithm, hash, &digest);
591 if (ret < 0)
593 gnutls_assert ();
594 goto cleanup;
597 ret = _gnutls_privkey_sign_hash (signer, &digest, signature);
598 _gnutls_free_datum (&digest);
600 if (ret < 0)
602 gnutls_assert ();
603 return ret;
606 return 0;
608 cleanup:
609 _gnutls_free_datum (&digest);
610 return ret;
614 * gnutls_privkey_sign_hash:
615 * @signer: Holds the signer's key
616 * @hash_algo: The hash algorithm used
617 * @flags: zero for now
618 * @hash_data: holds the data to be signed
619 * @signature: will contain newly allocated signature
621 * This function will sign the given hashed data using a signature algorithm
622 * supported by the private key. Signature algorithms are always used
623 * together with a hash functions. Different hash functions may be
624 * used for the RSA algorithm, but only SHA-XXX for the DSA keys.
626 * Use gnutls_pubkey_get_preferred_hash_algorithm() to determine
627 * the hash algorithm.
629 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
630 * negative error value.
632 * Since: 2.12.0
635 gnutls_privkey_sign_hash (gnutls_privkey_t signer,
636 gnutls_digest_algorithm_t hash_algo,
637 unsigned int flags,
638 const gnutls_datum_t * hash_data,
639 gnutls_datum_t * signature)
641 int ret;
642 gnutls_datum_t digest;
644 digest.data = gnutls_malloc (hash_data->size);
645 if (digest.data == NULL)
647 gnutls_assert ();
648 return GNUTLS_E_MEMORY_ERROR;
650 digest.size = hash_data->size;
651 memcpy (digest.data, hash_data->data, digest.size);
653 ret = pk_prepare_hash (signer->pk_algorithm, hash_algo, &digest);
654 if (ret < 0)
656 gnutls_assert ();
657 goto cleanup;
660 ret = _gnutls_privkey_sign_hash (signer, &digest, signature);
661 if (ret < 0)
663 gnutls_assert ();
664 goto cleanup;
667 ret = 0;
669 cleanup:
670 _gnutls_free_datum (&digest);
671 return ret;
675 * _gnutls_privkey_sign_hash:
676 * @key: Holds the key
677 * @data: holds the data to be signed
678 * @signature: will contain the signature allocate with gnutls_malloc()
680 * This function will sign the given data using a signature algorithm
681 * supported by the private key.
683 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
684 * negative error value.
687 _gnutls_privkey_sign_hash (gnutls_privkey_t key,
688 const gnutls_datum_t * hash,
689 gnutls_datum_t * signature)
691 switch (key->type)
693 #ifdef ENABLE_OPENPGP
694 case GNUTLS_PRIVKEY_OPENPGP:
695 return gnutls_openpgp_privkey_sign_hash (key->key.openpgp,
696 hash, signature);
697 #endif
698 #ifdef ENABLE_PKCS11
699 case GNUTLS_PRIVKEY_PKCS11:
700 return _gnutls_pkcs11_privkey_sign_hash (key->key.pkcs11,
701 hash, signature);
702 #endif
703 case GNUTLS_PRIVKEY_X509:
704 return _gnutls_soft_sign (key->key.x509->pk_algorithm,
705 &key->key.x509->params,
706 hash, signature);
707 case GNUTLS_PRIVKEY_EXT:
708 if (key->key.ext.sign_func == NULL)
709 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
710 return key->key.ext.sign_func(key, key->key.ext.userdata, hash, signature);
711 default:
712 gnutls_assert ();
713 return GNUTLS_E_INVALID_REQUEST;
718 * gnutls_privkey_decrypt_data:
719 * @key: Holds the key
720 * @flags: zero for now
721 * @ciphertext: holds the data to be decrypted
722 * @plaintext: will contain the decrypted data, allocated with gnutls_malloc()
724 * This function will decrypt the given data using the algorithm
725 * supported by the private key.
727 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
728 * negative error value.
730 * Since: 2.12.0
733 gnutls_privkey_decrypt_data (gnutls_privkey_t key,
734 unsigned int flags,
735 const gnutls_datum_t * ciphertext,
736 gnutls_datum_t * plaintext)
738 if (key->pk_algorithm != GNUTLS_PK_RSA)
740 gnutls_assert ();
741 return GNUTLS_E_INVALID_REQUEST;
744 switch (key->type)
746 #ifdef ENABLE_OPENPGP
747 case GNUTLS_PRIVKEY_OPENPGP:
748 return _gnutls_openpgp_privkey_decrypt_data (key->key.openpgp, flags,
749 ciphertext, plaintext);
750 #endif
751 case GNUTLS_PRIVKEY_X509:
752 return _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext,
753 &key->key.x509->params,
755 #ifdef ENABLE_PKCS11
756 case GNUTLS_PRIVKEY_PKCS11:
757 return _gnutls_pkcs11_privkey_decrypt_data (key->key.pkcs11,
758 flags,
759 ciphertext, plaintext);
760 #endif
761 case GNUTLS_PRIVKEY_EXT:
762 if (key->key.ext.decrypt_func == NULL)
763 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
765 return key->key.ext.decrypt_func(key, key->key.ext.userdata, ciphertext, plaintext);
766 default:
767 gnutls_assert ();
768 return GNUTLS_E_INVALID_REQUEST;