guile: Change tests to use priority strings.
[gnutls.git] / lib / gnutls_privkey.c
blob0ee2d9478abde6442bf3833f3a9f98a0882be994
1 /*
2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010 Free Software Foundation
4 *
5 * Author: Nikos Mavrogiannopoulos
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 * MA 02111-1307, USA
23 #include <gnutls_int.h>
24 #include <pakchois/pakchois.h>
25 #include <gnutls/pkcs11.h>
26 #include <stdio.h>
27 #include <stdbool.h>
28 #include <string.h>
29 #include <gnutls_errors.h>
30 #include <gnutls_datum.h>
31 #include <pkcs11_int.h>
32 #include <gnutls/abstract.h>
33 #include <gnutls_pk.h>
34 #include <x509_int.h>
35 #include <openpgp/openpgp_int.h>
36 #include <openpgp/gnutls_openpgp.h>
37 #include <gnutls_sig.h>
38 #include <abstract_int.h>
40 struct gnutls_privkey_st
42 gnutls_privkey_type_t type;
43 gnutls_pk_algorithm_t pk_algorithm;
45 union
47 gnutls_x509_privkey_t x509;
48 gnutls_pkcs11_privkey_t pkcs11;
49 #ifdef ENABLE_OPENPGP
50 gnutls_openpgp_privkey_t openpgp;
51 #endif
52 } key;
54 unsigned int flags;
57 /**
58 * gnutls_privkey_get_type:
59 * @key: should contain a #gnutls_privkey_t structure
61 * This function will return the type of the private key. This is
62 * actually the type of the subsystem used to set this private key.
64 * Returns: a member of the #gnutls_privkey_type_t enumeration on
65 * success, or a negative value on error.
66 **/
67 gnutls_privkey_type_t
68 gnutls_privkey_get_type (gnutls_privkey_t key)
70 return key->type;
73 /**
74 * gnutls_privkey_get_pk_algorithm:
75 * @key: should contain a #gnutls_privkey_t structure
76 * @bits: If set will return the number of bits of the parameters (may be NULL)
78 * This function will return the public key algorithm of a private
79 * key and if possible will return a number of bits that indicates
80 * the security parameter of the key.
82 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
83 * success, or a negative value on error.
84 **/
85 int
86 gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key, unsigned int *bits)
88 switch (key->type)
90 #ifdef ENABLE_OPENPGP
91 case GNUTLS_PRIVKEY_OPENPGP:
92 return gnutls_openpgp_privkey_get_pk_algorithm (key->key.openpgp, bits);
93 #endif
94 case GNUTLS_PRIVKEY_PKCS11:
95 return gnutls_pkcs11_privkey_get_pk_algorithm (key->key.pkcs11, bits);
96 case GNUTLS_PRIVKEY_X509:
97 if (bits)
98 *bits = _gnutls_mpi_get_nbits (key->key.x509->params[0]);
99 return gnutls_x509_privkey_get_pk_algorithm (key->key.x509);
100 default:
101 gnutls_assert ();
102 return GNUTLS_E_INVALID_REQUEST;
107 static int
108 privkey_to_pubkey (gnutls_pk_algorithm_t pk,
109 const bigint_t * params, int params_size,
110 bigint_t * new_params, int *new_params_size)
112 int ret, i;
114 switch (pk)
116 case GNUTLS_PK_RSA:
117 if (*new_params_size < RSA_PUBLIC_PARAMS
118 || params_size < RSA_PRIVATE_PARAMS)
120 gnutls_assert ();
121 return GNUTLS_E_INVALID_REQUEST;
124 new_params[0] = _gnutls_mpi_copy (params[0]);
125 new_params[1] = _gnutls_mpi_copy (params[1]);
127 *new_params_size = RSA_PUBLIC_PARAMS;
129 if (new_params[0] == NULL || new_params[1] == NULL)
131 gnutls_assert ();
132 ret = GNUTLS_E_MEMORY_ERROR;
133 goto cleanup;
136 break;
137 case GNUTLS_PK_DSA:
138 if (*new_params_size < DSA_PUBLIC_PARAMS
139 || params_size < DSA_PRIVATE_PARAMS)
141 gnutls_assert ();
142 return GNUTLS_E_INVALID_REQUEST;
145 new_params[0] = _gnutls_mpi_copy (params[0]);
146 new_params[1] = _gnutls_mpi_copy (params[1]);
147 new_params[2] = _gnutls_mpi_copy (params[2]);
148 new_params[3] = _gnutls_mpi_copy (params[3]);
150 *new_params_size = DSA_PUBLIC_PARAMS;
152 if (new_params[0] == NULL || new_params[1] == NULL ||
153 new_params[2] == NULL || new_params[3] == NULL)
155 gnutls_assert ();
156 ret = GNUTLS_E_MEMORY_ERROR;
157 goto cleanup;
160 break;
161 default:
162 gnutls_assert ();
163 return GNUTLS_E_INVALID_REQUEST;
166 return 0;
167 cleanup:
168 for (i = 0; i < *new_params_size; i++)
169 _gnutls_mpi_release (new_params[i]);
170 return ret;
174 /* Returns the public key of the private key (if possible)
177 _gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
178 bigint_t * params, int *params_size)
180 int ret;
181 gnutls_pk_algorithm_t pk = gnutls_privkey_get_pk_algorithm (key, NULL);
183 switch (key->type)
185 #ifdef ENABLE_OPENPGP
186 case GNUTLS_PRIVKEY_OPENPGP:
188 bigint_t tmp_params[MAX_PRIV_PARAMS_SIZE];
189 int tmp_params_size = MAX_PRIV_PARAMS_SIZE;
190 uint32_t kid[2], i;
191 gnutls_openpgp_keyid_t keyid;
193 ret =
194 gnutls_openpgp_privkey_get_preferred_key_id (key->key.openpgp,
195 keyid);
196 if (ret == 0)
198 KEYID_IMPORT (kid, keyid);
199 ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, kid,
200 tmp_params,
201 &tmp_params_size);
203 else
204 ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, NULL,
205 tmp_params,
206 &tmp_params_size);
208 if (ret < 0)
210 gnutls_assert ();
211 return ret;
214 ret = privkey_to_pubkey (pk,
215 tmp_params, tmp_params_size,
216 params, params_size);
218 for (i = 0; i < tmp_params_size; i++)
219 _gnutls_mpi_release (&tmp_params[i]);
223 break;
224 #endif
225 case GNUTLS_PRIVKEY_X509:
226 ret = privkey_to_pubkey (pk,
227 key->key.x509->params,
228 key->key.x509->params_size, params,
229 params_size);
230 break;
231 default:
232 gnutls_assert ();
233 return GNUTLS_E_INVALID_REQUEST;
236 return ret;
240 * gnutls_privkey_init:
241 * @key: The structure to be initialized
243 * This function will initialize an private key structure.
245 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
246 * negative error value.
249 gnutls_privkey_init (gnutls_privkey_t * key)
251 *key = gnutls_calloc (1, sizeof (struct gnutls_privkey_st));
252 if (*key == NULL)
254 gnutls_assert ();
255 return GNUTLS_E_MEMORY_ERROR;
258 return 0;
262 * gnutls_privkey_deinit:
263 * @key: The structure to be deinitialized
265 * This function will deinitialize a private key structure.
267 void
268 gnutls_privkey_deinit (gnutls_privkey_t key)
270 if (key->flags & GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE)
271 switch (key->type)
273 #ifdef ENABLE_OPENPGP
274 case GNUTLS_PRIVKEY_OPENPGP:
275 return gnutls_openpgp_privkey_deinit (key->key.openpgp);
276 #endif
277 case GNUTLS_PRIVKEY_PKCS11:
278 return gnutls_pkcs11_privkey_deinit (key->key.pkcs11);
279 case GNUTLS_PRIVKEY_X509:
280 return gnutls_x509_privkey_deinit (key->key.x509);
282 gnutls_free (key);
285 /* will fail if the private key contains an actual key.
287 static int check_if_clean(gnutls_privkey_t key)
289 if (key->type != 0)
290 return GNUTLS_E_INVALID_REQUEST;
292 return 0;
296 * gnutls_privkey_import_pkcs11:
297 * @pkey: The private key
298 * @key: The private key to be imported
299 * @flags: should be zero
301 * This function will import the given private key to the abstract
302 * #gnutls_privkey_t structure.
304 * The #gnutls_pkcs11_privkey_t object must not be deallocated
305 * during the lifetime of this structure.
307 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
308 * negative error value.
311 gnutls_privkey_import_pkcs11 (gnutls_privkey_t pkey,
312 gnutls_pkcs11_privkey_t key, unsigned int flags)
314 int ret;
316 ret = check_if_clean(pkey);
317 if (ret < 0)
319 gnutls_assert();
320 return ret;
323 pkey->key.pkcs11 = key;
324 pkey->type = GNUTLS_PRIVKEY_PKCS11;
325 pkey->pk_algorithm = gnutls_pkcs11_privkey_get_pk_algorithm (key, NULL);
326 pkey->flags = flags;
328 return 0;
332 * gnutls_privkey_import_x509:
333 * @pkey: The private key
334 * @key: The private key to be imported
335 * @flags: should be zero
337 * This function will import the given private key to the abstract
338 * #gnutls_privkey_t structure.
340 * The #gnutls_x509_privkey_t object must not be deallocated
341 * during the lifetime of this structure.
343 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
344 * negative error value.
347 gnutls_privkey_import_x509 (gnutls_privkey_t pkey,
348 gnutls_x509_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 pkey->key.x509 = key;
360 pkey->type = GNUTLS_PRIVKEY_X509;
361 pkey->pk_algorithm = gnutls_x509_privkey_get_pk_algorithm (key);
362 pkey->flags = flags;
364 return 0;
367 #ifdef ENABLE_OPENPGP
369 * gnutls_privkey_import_openpgp:
370 * @pkey: The private key
371 * @key: The private key to be imported
372 * @flags: should be zero
374 * This function will import the given private key to the abstract
375 * #gnutls_privkey_t structure.
377 * The #gnutls_openpgp_privkey_t object must not be deallocated
378 * during the lifetime of this structure.
380 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
381 * negative error value.
384 gnutls_privkey_import_openpgp (gnutls_privkey_t pkey,
385 gnutls_openpgp_privkey_t key,
386 unsigned int flags)
388 int ret;
390 ret = check_if_clean(pkey);
391 if (ret < 0)
393 gnutls_assert();
394 return ret;
397 pkey->key.openpgp = key;
398 pkey->type = GNUTLS_PRIVKEY_OPENPGP;
399 pkey->pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
400 pkey->flags = flags;
402 return 0;
404 #endif
407 * gnutls_privkey_sign_data2:
408 * @signer: Holds the key
409 * @digest: should be a digest algorithm
410 * @flags: should be 0 for now
411 * @data: holds the data to be signed
412 * @signature: will contain the signature allocate with gnutls_malloc()
414 * This function will sign the given data using a signature algorithm
415 * supported by the private key. Signature algorithms are always used
416 * together with a hash functions. Different hash functions may be
417 * used for the RSA algorithm, but only SHA-1 for the DSA keys.
419 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
420 * negative error value.
422 * Since: 2.12.0
425 gnutls_privkey_sign_data (gnutls_privkey_t signer,
426 gnutls_digest_algorithm_t hash,
427 unsigned int flags,
428 const gnutls_datum_t * data,
429 gnutls_datum_t * signature)
431 int ret;
432 gnutls_datum_t digest;
434 ret = pk_hash_data (signer->pk_algorithm, hash, NULL, data, &digest);
435 if (ret < 0)
437 gnutls_assert ();
438 return ret;
441 ret = pk_prepare_hash (signer->pk_algorithm, hash, &digest);
442 if (ret < 0)
444 gnutls_assert ();
445 goto cleanup;
448 ret = _gnutls_privkey_sign_hash (signer, &digest, signature);
449 _gnutls_free_datum (&digest);
451 if (ret < 0)
453 gnutls_assert ();
454 return ret;
457 return 0;
459 cleanup:
460 _gnutls_free_datum (&digest);
461 return ret;
465 * gnutls_privkey_sign_hash:
466 * @signer: Holds the signer's key
467 * @hash_algo: The hash algorithm used
468 * @flags: zero for now
469 * @hash_data: holds the data to be signed
470 * @signature: will contain newly allocated signature
472 * This function will sign the given hashed data using a signature algorithm
473 * supported by the private key. Signature algorithms are always used
474 * together with a hash functions. Different hash functions may be
475 * used for the RSA algorithm, but only SHA-XXX for the DSA keys.
477 * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
478 * the hash algorithm.
480 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
481 * negative error value.
483 * Since: 2.12.0
486 gnutls_privkey_sign_hash (gnutls_privkey_t signer,
487 gnutls_digest_algorithm_t hash_algo,
488 unsigned int flags,
489 const gnutls_datum_t * hash_data,
490 gnutls_datum_t * signature)
492 int ret;
493 gnutls_datum_t digest;
495 digest.data = gnutls_malloc (hash_data->size);
496 if (digest.data == NULL)
498 gnutls_assert ();
499 return GNUTLS_E_MEMORY_ERROR;
501 digest.size = hash_data->size;
502 memcpy (digest.data, hash_data->data, digest.size);
504 ret = pk_prepare_hash (signer->pk_algorithm, hash_algo, &digest);
505 if (ret < 0)
507 gnutls_assert ();
508 goto cleanup;
511 ret = _gnutls_privkey_sign_hash (signer, &digest, signature);
512 if (ret < 0)
514 gnutls_assert ();
515 goto cleanup;
518 ret = 0;
520 cleanup:
521 _gnutls_free_datum (&digest);
522 return ret;
526 * _gnutls_privkey_sign_hash:
527 * @key: Holds the key
528 * @data: holds the data to be signed
529 * @signature: will contain the signature allocate with gnutls_malloc()
531 * This function will sign the given data using a signature algorithm
532 * supported by the private key.
534 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
535 * negative error value.
538 _gnutls_privkey_sign_hash (gnutls_privkey_t key,
539 const gnutls_datum_t * hash,
540 gnutls_datum_t * signature)
542 switch (key->type)
544 #ifdef ENABLE_OPENPGP
545 case GNUTLS_PRIVKEY_OPENPGP:
546 return gnutls_openpgp_privkey_sign_hash (key->key.openpgp,
547 hash, signature);
548 #endif
549 case GNUTLS_PRIVKEY_PKCS11:
550 return _gnutls_pkcs11_privkey_sign_hash (key->key.pkcs11,
551 hash, signature);
552 case GNUTLS_PRIVKEY_X509:
553 return _gnutls_soft_sign (key->key.x509->pk_algorithm,
554 key->key.x509->params,
555 key->key.x509->params_size, hash, signature);
556 default:
557 gnutls_assert ();
558 return GNUTLS_E_INVALID_REQUEST;
563 * gnutls_privkey_decrypt_data:
564 * @key: Holds the key
565 * @flags: zero for now
566 * @ciphertext: holds the data to be decrypted
567 * @plaintext: will contain the decrypted data, allocated with gnutls_malloc()
569 * This function will decrypt the given data using the algorithm
570 * supported by the private key.
572 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
573 * negative error value.
576 gnutls_privkey_decrypt_data (gnutls_privkey_t key,
577 unsigned int flags,
578 const gnutls_datum_t * ciphertext,
579 gnutls_datum_t * plaintext)
581 if (key->pk_algorithm != GNUTLS_PK_RSA)
583 gnutls_assert ();
584 return GNUTLS_E_INVALID_REQUEST;
587 switch (key->type)
589 #ifdef ENABLE_OPENPGP
590 case GNUTLS_PRIVKEY_OPENPGP:
591 return _gnutls_openpgp_privkey_decrypt_data (key->key.openpgp, flags,
592 ciphertext, plaintext);
593 #endif
594 case GNUTLS_PRIVKEY_X509:
595 return _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext,
596 key->key.x509->params,
597 key->key.x509->params_size, 2);
598 case GNUTLS_PRIVKEY_PKCS11:
599 return _gnutls_pkcs11_privkey_decrypt_data (key->key.pkcs11,
600 flags,
601 ciphertext, plaintext);
602 default:
603 gnutls_assert ();
604 return GNUTLS_E_INVALID_REQUEST;