Tizen 2.0 Release
[external/libgnutls26.git] / lib / gnutls_privkey.c
1 /*
2  * GnuTLS PKCS#11 support
3  * Copyright (C) 2010 Free Software Foundation
4  * 
5  * Author: Nikos Mavrogiannopoulos
6  *
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.
11  *
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.
16  *
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
21 */
22
23 #include <gnutls_int.h>
24 #include <gnutls/pkcs11.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <gnutls_errors.h>
28 #include <gnutls_datum.h>
29 #include <pkcs11_int.h>
30 #include <gnutls/abstract.h>
31 #include <gnutls_pk.h>
32 #include <x509_int.h>
33 #include <openpgp/openpgp_int.h>
34 #include <openpgp/gnutls_openpgp.h>
35 #include <gnutls_sig.h>
36 #include <abstract_int.h>
37
38 struct gnutls_privkey_st
39 {
40   gnutls_privkey_type_t type;
41   gnutls_pk_algorithm_t pk_algorithm;
42
43   union
44   {
45     gnutls_x509_privkey_t x509;
46 #ifdef ENABLE_PKCS11
47     gnutls_pkcs11_privkey_t pkcs11;
48 #endif
49 #ifdef ENABLE_OPENPGP
50     gnutls_openpgp_privkey_t openpgp;
51 #endif
52   } key;
53
54   unsigned int flags;
55 };
56
57 /**
58  * gnutls_privkey_get_type:
59  * @key: should contain a #gnutls_privkey_t structure
60  *
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.
63  *
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)
69 {
70   return key->type;
71 }
72
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)
77  *
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.
81  *
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)
87 {
88   switch (key->type)
89     {
90 #ifdef ENABLE_OPENPGP
91     case GNUTLS_PRIVKEY_OPENPGP:
92       return gnutls_openpgp_privkey_get_pk_algorithm (key->key.openpgp, bits);
93 #endif
94 #ifdef ENABLE_PKCS11
95     case GNUTLS_PRIVKEY_PKCS11:
96       return gnutls_pkcs11_privkey_get_pk_algorithm (key->key.pkcs11, bits);
97 #endif
98     case GNUTLS_PRIVKEY_X509:
99       if (bits)
100         *bits = _gnutls_mpi_get_nbits (key->key.x509->params[0]);
101       return gnutls_x509_privkey_get_pk_algorithm (key->key.x509);
102     default:
103       gnutls_assert ();
104       return GNUTLS_E_INVALID_REQUEST;
105     }
106
107 }
108
109 static int
110 privkey_to_pubkey (gnutls_pk_algorithm_t pk,
111                    const bigint_t * params, int params_size,
112                    bigint_t * new_params, int *new_params_size)
113 {
114   int ret, i;
115
116   switch (pk)
117     {
118     case GNUTLS_PK_RSA:
119       if (*new_params_size < RSA_PUBLIC_PARAMS
120           || params_size < RSA_PRIVATE_PARAMS)
121         {
122           gnutls_assert ();
123           return GNUTLS_E_INVALID_REQUEST;
124         }
125
126       new_params[0] = _gnutls_mpi_copy (params[0]);
127       new_params[1] = _gnutls_mpi_copy (params[1]);
128
129       *new_params_size = RSA_PUBLIC_PARAMS;
130
131       if (new_params[0] == NULL || new_params[1] == NULL)
132         {
133           gnutls_assert ();
134           ret = GNUTLS_E_MEMORY_ERROR;
135           goto cleanup;
136         }
137
138       break;
139     case GNUTLS_PK_DSA:
140       if (*new_params_size < DSA_PUBLIC_PARAMS
141           || params_size < DSA_PRIVATE_PARAMS)
142         {
143           gnutls_assert ();
144           return GNUTLS_E_INVALID_REQUEST;
145         }
146
147       new_params[0] = _gnutls_mpi_copy (params[0]);
148       new_params[1] = _gnutls_mpi_copy (params[1]);
149       new_params[2] = _gnutls_mpi_copy (params[2]);
150       new_params[3] = _gnutls_mpi_copy (params[3]);
151
152       *new_params_size = DSA_PUBLIC_PARAMS;
153
154       if (new_params[0] == NULL || new_params[1] == NULL ||
155           new_params[2] == NULL || new_params[3] == NULL)
156         {
157           gnutls_assert ();
158           ret = GNUTLS_E_MEMORY_ERROR;
159           goto cleanup;
160         }
161
162       break;
163     default:
164       gnutls_assert ();
165       return GNUTLS_E_INVALID_REQUEST;
166     }
167
168   return 0;
169 cleanup:
170   for (i = 0; i < *new_params_size; i++)
171     _gnutls_mpi_release (new_params[i]);
172   return ret;
173 }
174
175
176 /* Returns the public key of the private key (if possible)
177  */
178 int
179 _gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
180                                  bigint_t * params, int *params_size)
181 {
182   int ret;
183   gnutls_pk_algorithm_t pk = gnutls_privkey_get_pk_algorithm (key, NULL);
184
185   switch (key->type)
186     {
187 #ifdef ENABLE_OPENPGP
188     case GNUTLS_PRIVKEY_OPENPGP:
189       {
190         bigint_t tmp_params[MAX_PRIV_PARAMS_SIZE];
191         int tmp_params_size = MAX_PRIV_PARAMS_SIZE;
192         uint32_t kid[2], i;
193         uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
194
195         ret =
196           gnutls_openpgp_privkey_get_preferred_key_id (key->key.openpgp,
197                                                        keyid);
198         if (ret == 0)
199           {
200             KEYID_IMPORT (kid, keyid);
201             ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, kid,
202                                                     tmp_params,
203                                                     &tmp_params_size);
204           }
205         else
206           ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, NULL,
207                                                   tmp_params,
208                                                   &tmp_params_size);
209
210         if (ret < 0)
211           {
212             gnutls_assert ();
213             return ret;
214           }
215
216         ret = privkey_to_pubkey (pk,
217                                  tmp_params, tmp_params_size,
218                                  params, params_size);
219
220         for (i = 0; i < tmp_params_size; i++)
221           _gnutls_mpi_release (&tmp_params[i]);
222
223       }
224
225       break;
226 #endif
227     case GNUTLS_PRIVKEY_X509:
228       ret = privkey_to_pubkey (pk,
229                                key->key.x509->params,
230                                key->key.x509->params_size, params,
231                                params_size);
232       break;
233     default:
234       gnutls_assert ();
235       return GNUTLS_E_INVALID_REQUEST;
236     }
237
238   return ret;
239 }
240
241 /**
242  * gnutls_privkey_init:
243  * @key: The structure to be initialized
244  *
245  * This function will initialize an private key structure.
246  *
247  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
248  *   negative error value.
249  **/
250 int
251 gnutls_privkey_init (gnutls_privkey_t * key)
252 {
253   *key = gnutls_calloc (1, sizeof (struct gnutls_privkey_st));
254   if (*key == NULL)
255     {
256       gnutls_assert ();
257       return GNUTLS_E_MEMORY_ERROR;
258     }
259
260   return 0;
261 }
262
263 /**
264  * gnutls_privkey_deinit:
265  * @key: The structure to be deinitialized
266  *
267  * This function will deinitialize a private key structure.
268  **/
269 void
270 gnutls_privkey_deinit (gnutls_privkey_t key)
271 {
272   if (key == NULL) return;
273
274   if (key->flags & GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE || key->flags & GNUTLS_PRIVKEY_IMPORT_COPY)
275     switch (key->type)
276       {
277 #ifdef ENABLE_OPENPGP
278       case GNUTLS_PRIVKEY_OPENPGP:
279         gnutls_openpgp_privkey_deinit (key->key.openpgp);
280         break;
281 #endif
282 #ifdef ENABLE_PKCS11
283       case GNUTLS_PRIVKEY_PKCS11:
284         gnutls_pkcs11_privkey_deinit (key->key.pkcs11);
285         break;
286 #endif
287       case GNUTLS_PRIVKEY_X509:
288         gnutls_x509_privkey_deinit (key->key.x509);
289         break;
290       }
291   gnutls_free (key);
292 }
293
294 /* will fail if the private key contains an actual key.
295  */
296 static int check_if_clean(gnutls_privkey_t key)
297 {
298   if (key->type != 0)
299     return GNUTLS_E_INVALID_REQUEST;
300
301   return 0;
302 }
303
304 #ifdef ENABLE_PKCS11
305
306 /**
307  * gnutls_privkey_import_pkcs11:
308  * @pkey: The private key
309  * @key: The private key to be imported
310  * @flags: should be zero
311  *
312  * This function will import the given private key to the abstract
313  * #gnutls_privkey_t structure.
314  *
315  * The #gnutls_pkcs11_privkey_t object must not be deallocated
316  * during the lifetime of this structure.
317  *
318  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
319  *   negative error value.
320  **/
321 int
322 gnutls_privkey_import_pkcs11 (gnutls_privkey_t pkey,
323                               gnutls_pkcs11_privkey_t key, unsigned int flags)
324 {
325 int ret;
326
327   ret = check_if_clean(pkey);
328   if (ret < 0)
329     {
330       gnutls_assert();
331       return ret;
332     }
333
334   if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
335     return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
336
337   pkey->key.pkcs11 = key;
338   pkey->type = GNUTLS_PRIVKEY_PKCS11;
339   pkey->pk_algorithm = gnutls_pkcs11_privkey_get_pk_algorithm (key, NULL);
340   pkey->flags = flags;
341
342   return 0;
343 }
344
345 #endif /* ENABLE_PKCS11 */
346
347 /**
348  * gnutls_privkey_import_x509:
349  * @pkey: The private key
350  * @key: The private key to be imported
351  * @flags: should be zero
352  *
353  * This function will import the given private key to the abstract
354  * #gnutls_privkey_t structure.
355  *
356  * The #gnutls_x509_privkey_t object must not be deallocated
357  * during the lifetime of this structure.
358  *
359  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
360  *   negative error value.
361  **/
362 int
363 gnutls_privkey_import_x509 (gnutls_privkey_t pkey,
364                             gnutls_x509_privkey_t key, unsigned int flags)
365 {
366 int ret;
367
368   ret = check_if_clean(pkey);
369   if (ret < 0)
370     {
371       gnutls_assert();
372       return ret;
373     }
374
375   if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
376     {
377       ret = gnutls_x509_privkey_init(&pkey->key.x509);
378       if (ret < 0)
379         return gnutls_assert_val(ret);
380       
381       ret = gnutls_x509_privkey_cpy(pkey->key.x509, key);
382       if (ret < 0)
383         {
384           gnutls_x509_privkey_deinit(pkey->key.x509);
385           return gnutls_assert_val(ret);
386         }
387     }
388   else
389     pkey->key.x509 = key;
390
391   pkey->type = GNUTLS_PRIVKEY_X509;
392   pkey->pk_algorithm = gnutls_x509_privkey_get_pk_algorithm (key);
393   pkey->flags = flags;
394
395   return 0;
396 }
397
398 #ifdef ENABLE_OPENPGP
399 /**
400  * gnutls_privkey_import_openpgp:
401  * @pkey: The private key
402  * @key: The private key to be imported
403  * @flags: should be zero
404  *
405  * This function will import the given private key to the abstract
406  * #gnutls_privkey_t structure.
407  *
408  * The #gnutls_openpgp_privkey_t object must not be deallocated
409  * during the lifetime of this structure. The subkey set as
410  * preferred will be used, or the master key otherwise.
411  *
412  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
413  *   negative error value.
414  **/
415 int
416 gnutls_privkey_import_openpgp (gnutls_privkey_t pkey,
417                                gnutls_openpgp_privkey_t key,
418                                unsigned int flags)
419 {
420 int ret, idx;
421 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
422
423   ret = check_if_clean(pkey);
424   if (ret < 0)
425     {
426       gnutls_assert();
427       return ret;
428     }
429
430   if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
431     {
432       ret = gnutls_openpgp_privkey_init(&pkey->key.openpgp);
433       if (ret < 0)
434         return gnutls_assert_val(ret);
435       
436       ret = _gnutls_openpgp_privkey_cpy(pkey->key.openpgp, key);
437       if (ret < 0)
438         {
439           gnutls_openpgp_privkey_deinit(pkey->key.openpgp);
440           return gnutls_assert_val(ret);
441         }
442     }
443   else
444     pkey->key.openpgp = key;
445
446   pkey->type = GNUTLS_PRIVKEY_OPENPGP;
447   
448   ret = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid);
449   if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR)
450     {
451       pkey->pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm(key, NULL);
452     }
453   else
454     {
455       if (ret < 0)
456         return gnutls_assert_val(ret);
457
458       idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);
459   
460       pkey->pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL);
461     }
462
463   pkey->flags = flags;
464
465   return 0;
466 }
467 #endif
468
469 /**
470  * gnutls_privkey_sign_data:
471  * @signer: Holds the key
472  * @hash: should be a digest algorithm
473  * @flags: should be 0 for now
474  * @data: holds the data to be signed
475  * @signature: will contain the signature allocate with gnutls_malloc()
476  *
477  * This function will sign the given data using a signature algorithm
478  * supported by the private key. Signature algorithms are always used
479  * together with a hash functions.  Different hash functions may be
480  * used for the RSA algorithm, but only SHA-1 for the DSA keys.
481  *
482  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
483  * negative error value.
484  *
485  * Since: 2.12.0
486  **/
487 int
488 gnutls_privkey_sign_data (gnutls_privkey_t signer,
489                           gnutls_digest_algorithm_t hash,
490                           unsigned int flags,
491                           const gnutls_datum_t * data,
492                           gnutls_datum_t * signature)
493 {
494   int ret;
495   gnutls_datum_t digest;
496
497   ret = pk_hash_data (signer->pk_algorithm, hash, NULL, data, &digest);
498   if (ret < 0)
499     {
500       gnutls_assert ();
501       return ret;
502     }
503
504   ret = pk_prepare_hash (signer->pk_algorithm, hash, &digest);
505   if (ret < 0)
506     {
507       gnutls_assert ();
508       goto cleanup;
509     }
510
511   ret = _gnutls_privkey_sign_hash (signer, &digest, signature);
512   _gnutls_free_datum (&digest);
513
514   if (ret < 0)
515     {
516       gnutls_assert ();
517       return ret;
518     }
519
520   return 0;
521
522 cleanup:
523   _gnutls_free_datum (&digest);
524   return ret;
525 }
526
527 /**
528  * gnutls_privkey_sign_hash:
529  * @signer: Holds the signer's key
530  * @hash_algo: The hash algorithm used
531  * @flags: zero for now
532  * @hash_data: holds the data to be signed
533  * @signature: will contain newly allocated signature
534  *
535  * This function will sign the given hashed data using a signature algorithm
536  * supported by the private key. Signature algorithms are always used
537  * together with a hash functions.  Different hash functions may be
538  * used for the RSA algorithm, but only SHA-XXX for the DSA keys.
539  *
540  * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
541  * the hash algorithm.
542  *
543  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
544  *   negative error value.
545  *
546  * Since: 2.12.0
547  **/
548 int
549 gnutls_privkey_sign_hash (gnutls_privkey_t signer,
550                           gnutls_digest_algorithm_t hash_algo,
551                           unsigned int flags,
552                           const gnutls_datum_t * hash_data,
553                           gnutls_datum_t * signature)
554 {
555   int ret;
556   gnutls_datum_t digest;
557
558   digest.data = gnutls_malloc (hash_data->size);
559   if (digest.data == NULL)
560     {
561       gnutls_assert ();
562       return GNUTLS_E_MEMORY_ERROR;
563     }
564   digest.size = hash_data->size;
565   memcpy (digest.data, hash_data->data, digest.size);
566
567   ret = pk_prepare_hash (signer->pk_algorithm, hash_algo, &digest);
568   if (ret < 0)
569     {
570       gnutls_assert ();
571       goto cleanup;
572     }
573
574   ret = _gnutls_privkey_sign_hash (signer, &digest, signature);
575   if (ret < 0)
576     {
577       gnutls_assert ();
578       goto cleanup;
579     }
580
581   ret = 0;
582
583 cleanup:
584   _gnutls_free_datum (&digest);
585   return ret;
586 }
587
588 /*-
589  * _gnutls_privkey_sign_hash:
590  * @key: Holds the key
591  * @data: holds the data to be signed
592  * @signature: will contain the signature allocate with gnutls_malloc()
593  *
594  * This function will sign the given data using a signature algorithm
595  * supported by the private key.
596  *
597  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
598  * negative error value.
599  -*/
600 int
601 _gnutls_privkey_sign_hash (gnutls_privkey_t key,
602                            const gnutls_datum_t * hash,
603                            gnutls_datum_t * signature)
604 {
605   switch (key->type)
606     {
607 #ifdef ENABLE_OPENPGP
608     case GNUTLS_PRIVKEY_OPENPGP:
609       return gnutls_openpgp_privkey_sign_hash (key->key.openpgp,
610                                                 hash, signature);
611 #endif
612 #ifdef ENABLE_PKCS11
613     case GNUTLS_PRIVKEY_PKCS11:
614       return _gnutls_pkcs11_privkey_sign_hash (key->key.pkcs11,
615                                                hash, signature);
616 #endif
617     case GNUTLS_PRIVKEY_X509:
618       return _gnutls_soft_sign (key->key.x509->pk_algorithm,
619                                 key->key.x509->params,
620                                 key->key.x509->params_size, hash, signature);
621     default:
622       gnutls_assert ();
623       return GNUTLS_E_INVALID_REQUEST;
624     }
625 }
626
627 /**
628  * gnutls_privkey_decrypt_data:
629  * @key: Holds the key
630  * @flags: zero for now
631  * @ciphertext: holds the data to be decrypted
632  * @plaintext: will contain the decrypted data, allocated with gnutls_malloc()
633  *
634  * This function will decrypt the given data using the algorithm
635  * supported by the private key.
636  *
637  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
638  * negative error value.
639  **/
640 int
641 gnutls_privkey_decrypt_data (gnutls_privkey_t key,
642                              unsigned int flags,
643                              const gnutls_datum_t * ciphertext,
644                              gnutls_datum_t * plaintext)
645 {
646   if (key->pk_algorithm != GNUTLS_PK_RSA)
647     {
648       gnutls_assert ();
649       return GNUTLS_E_INVALID_REQUEST;
650     }
651
652   switch (key->type)
653     {
654 #ifdef ENABLE_OPENPGP
655     case GNUTLS_PRIVKEY_OPENPGP:
656       return _gnutls_openpgp_privkey_decrypt_data (key->key.openpgp, flags,
657                                                   ciphertext, plaintext);
658 #endif
659     case GNUTLS_PRIVKEY_X509:
660       return _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext,
661                                         key->key.x509->params,
662                                         key->key.x509->params_size, 2);
663 #ifdef ENABLE_PKCS11
664     case GNUTLS_PRIVKEY_PKCS11:
665       return _gnutls_pkcs11_privkey_decrypt_data (key->key.pkcs11,
666                                                  flags,
667                                                  ciphertext, plaintext);
668 #endif
669     default:
670       gnutls_assert ();
671       return GNUTLS_E_INVALID_REQUEST;
672     }
673 }