Tizen 2.0 Release
[external/libgnutls26.git] / lib / x509 / privkey.c
1 /*
2  * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software
3  * Foundation, Inc.
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
9  * The GnuTLS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA
23  *
24  */
25
26 #include <gnutls_int.h>
27 #include <gnutls_datum.h>
28 #include <gnutls_global.h>
29 #include <gnutls_errors.h>
30 #include <gnutls_rsa_export.h>
31 #include <gnutls_sig.h>
32 #include <common.h>
33 #include <gnutls_x509.h>
34 #include <x509_b64.h>
35 #include <x509_int.h>
36 #include <gnutls_pk.h>
37 #include <gnutls_mpi.h>
38
39 static int _gnutls_asn1_encode_rsa (ASN1_TYPE * c2, bigint_t * params);
40
41 /**
42  * gnutls_x509_privkey_init:
43  * @key: The structure to be initialized
44  *
45  * This function will initialize an private key structure.
46  *
47  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
48  *   negative error value.
49  **/
50 int
51 gnutls_x509_privkey_init (gnutls_x509_privkey_t * key)
52 {
53   *key = gnutls_calloc (1, sizeof (gnutls_x509_privkey_int));
54
55   if (*key)
56     {
57       (*key)->key = ASN1_TYPE_EMPTY;
58       (*key)->pk_algorithm = GNUTLS_PK_UNKNOWN;
59       return 0;                 /* success */
60     }
61
62   return GNUTLS_E_MEMORY_ERROR;
63 }
64
65 /**
66  * gnutls_x509_privkey_deinit:
67  * @key: The structure to be deinitialized
68  *
69  * This function will deinitialize a private key structure.
70  **/
71 void
72 gnutls_x509_privkey_deinit (gnutls_x509_privkey_t key)
73 {
74   int i;
75
76   if (!key)
77     return;
78
79   for (i = 0; i < key->params_size; i++)
80     {
81       _gnutls_mpi_release (&key->params[i]);
82     }
83
84   asn1_delete_structure (&key->key);
85   gnutls_free (key);
86 }
87
88 /**
89  * gnutls_x509_privkey_cpy:
90  * @dst: The destination key, which should be initialized.
91  * @src: The source key
92  *
93  * This function will copy a private key from source to destination
94  * key. Destination has to be initialized.
95  *
96  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
97  *   negative error value.
98  **/
99 int
100 gnutls_x509_privkey_cpy (gnutls_x509_privkey_t dst, gnutls_x509_privkey_t src)
101 {
102   int i, ret;
103
104   if (!src || !dst)
105     return GNUTLS_E_INVALID_REQUEST;
106
107   for (i = 0; i < src->params_size; i++)
108     {
109       dst->params[i] = _gnutls_mpi_copy (src->params[i]);
110       if (dst->params[i] == NULL)
111         return GNUTLS_E_MEMORY_ERROR;
112     }
113
114   dst->params_size = src->params_size;
115   dst->pk_algorithm = src->pk_algorithm;
116
117   switch (dst->pk_algorithm)
118     {
119         case GNUTLS_PK_DSA:
120           ret = _gnutls_asn1_encode_dsa (&dst->key, dst->params);
121           if (ret < 0)
122             {
123               gnutls_assert ();
124               return ret;
125             }
126           break;
127         case GNUTLS_PK_RSA:
128           ret = _gnutls_asn1_encode_rsa (&dst->key, dst->params);
129           if (ret < 0)
130             {
131               gnutls_assert ();
132               return ret;
133             }
134           break;
135         default:
136           gnutls_assert ();
137           return GNUTLS_E_INVALID_REQUEST;
138     }
139
140   return 0;
141 }
142
143 /* Converts an RSA PKCS#1 key to
144  * an internal structure (gnutls_private_key)
145  */
146 ASN1_TYPE
147 _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key,
148                                       gnutls_x509_privkey_t pkey)
149 {
150   int result;
151   ASN1_TYPE pkey_asn;
152   gnutls_pk_params_st pk_params;
153
154   memset (&pk_params, 0, sizeof (pk_params));
155   pk_params.params_nr = RSA_PRIVATE_PARAMS;
156
157   if ((result =
158        asn1_create_element (_gnutls_get_gnutls_asn (),
159                             "GNUTLS.RSAPrivateKey",
160                             &pkey_asn)) != ASN1_SUCCESS)
161     {
162       gnutls_assert ();
163       return NULL;
164     }
165
166   result = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL);
167   if (result != ASN1_SUCCESS)
168     {
169       gnutls_assert ();
170       goto error;
171     }
172
173   if ((result = _gnutls_x509_read_int (pkey_asn, "modulus",
174                                        &pk_params.params[0])) < 0)
175     {
176       gnutls_assert ();
177       goto error;
178     }
179
180   if ((result =
181        _gnutls_x509_read_int (pkey_asn, "publicExponent",
182                               &pk_params.params[1])) < 0)
183     {
184       gnutls_assert ();
185       goto error;
186     }
187
188   if ((result =
189        _gnutls_x509_read_int (pkey_asn, "privateExponent",
190                               &pk_params.params[2])) < 0)
191     {
192       gnutls_assert ();
193       goto error;
194     }
195
196   if ((result = _gnutls_x509_read_int (pkey_asn, "prime1",
197                                        &pk_params.params[3])) < 0)
198     {
199       gnutls_assert ();
200       goto error;
201     }
202
203   if ((result = _gnutls_x509_read_int (pkey_asn, "prime2",
204                                        &pk_params.params[4])) < 0)
205     {
206       gnutls_assert ();
207       goto error;
208     }
209
210   if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient",
211                                        &pk_params.params[5])) < 0)
212     {
213       gnutls_assert ();
214       goto error;
215     }
216
217   if ((result = _gnutls_x509_read_int (pkey_asn, "exponent1",
218                                        &pk_params.params[6])) < 0)
219     {
220       gnutls_assert ();
221       goto error;
222     }
223
224   if ((result = _gnutls_x509_read_int (pkey_asn, "exponent2",
225                                        &pk_params.params[7])) < 0)
226     {
227       gnutls_assert ();
228       goto error;
229     }
230
231
232   result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pk_params);
233   if (result < 0)
234     {
235       gnutls_assert ();
236       goto error;
237     }
238
239   pkey->params[0] = pk_params.params[0];
240   pkey->params[1] = pk_params.params[1];
241   pkey->params[2] = pk_params.params[2];
242   pkey->params[3] = pk_params.params[3];
243   pkey->params[4] = pk_params.params[4];
244   pkey->params[5] = pk_params.params[5];
245   pkey->params[6] = pk_params.params[6];
246   pkey->params[7] = pk_params.params[7];
247   pkey->params_size = pk_params.params_nr;
248
249   return pkey_asn;
250
251 error:
252   asn1_delete_structure (&pkey_asn);
253   gnutls_pk_params_release (&pk_params);
254   return NULL;
255
256 }
257
258 static ASN1_TYPE
259 decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey)
260 {
261   int result;
262   ASN1_TYPE dsa_asn;
263
264   if ((result =
265        asn1_create_element (_gnutls_get_gnutls_asn (),
266                             "GNUTLS.DSAPrivateKey",
267                             &dsa_asn)) != ASN1_SUCCESS)
268     {
269       gnutls_assert ();
270       return NULL;
271     }
272
273   result = asn1_der_decoding (&dsa_asn, raw_key->data, raw_key->size, NULL);
274   if (result != ASN1_SUCCESS)
275     {
276       gnutls_assert ();
277       goto error;
278     }
279
280   if ((result = _gnutls_x509_read_int (dsa_asn, "p", &pkey->params[0])) < 0)
281     {
282       gnutls_assert ();
283       goto error;
284     }
285
286   if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params[1])) < 0)
287     {
288       gnutls_assert ();
289       goto error;
290     }
291
292   if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params[2])) < 0)
293     {
294       gnutls_assert ();
295       goto error;
296     }
297
298   if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params[3])) < 0)
299     {
300       gnutls_assert ();
301       goto error;
302     }
303
304   if ((result = _gnutls_x509_read_int (dsa_asn, "priv",
305                                        &pkey->params[4])) < 0)
306     {
307       gnutls_assert ();
308       goto error;
309     }
310   pkey->params_size = 5;
311
312   return dsa_asn;
313
314 error:
315   asn1_delete_structure (&dsa_asn);
316   _gnutls_mpi_release (&pkey->params[0]);
317   _gnutls_mpi_release (&pkey->params[1]);
318   _gnutls_mpi_release (&pkey->params[2]);
319   _gnutls_mpi_release (&pkey->params[3]);
320   _gnutls_mpi_release (&pkey->params[4]);
321   return NULL;
322
323 }
324
325
326 #define PEM_KEY_DSA "DSA PRIVATE KEY"
327 #define PEM_KEY_RSA "RSA PRIVATE KEY"
328
329 /**
330  * gnutls_x509_privkey_import:
331  * @key: The structure to store the parsed key
332  * @data: The DER or PEM encoded certificate.
333  * @format: One of DER or PEM
334  *
335  * This function will convert the given DER or PEM encoded key to the
336  * native #gnutls_x509_privkey_t format. The output will be stored in
337  * @key .
338  *
339  * If the key is PEM encoded it should have a header of "RSA PRIVATE
340  * KEY", or "DSA PRIVATE KEY".
341  *
342  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
343  *   negative error value.
344  **/
345 int
346 gnutls_x509_privkey_import (gnutls_x509_privkey_t key,
347                             const gnutls_datum_t * data,
348                             gnutls_x509_crt_fmt_t format)
349 {
350   int result = 0, need_free = 0;
351   gnutls_datum_t _data;
352
353   if (key == NULL)
354     {
355       gnutls_assert ();
356       return GNUTLS_E_INVALID_REQUEST;
357     }
358
359   _data.data = data->data;
360   _data.size = data->size;
361
362   key->pk_algorithm = GNUTLS_PK_UNKNOWN;
363
364   /* If the Certificate is in PEM format then decode it
365    */
366   if (format == GNUTLS_X509_FMT_PEM)
367     {
368       opaque *out;
369
370       /* Try the first header */
371       result =
372         _gnutls_fbase64_decode (PEM_KEY_RSA, data->data, data->size, &out);
373
374       if (result >= 0)
375         key->pk_algorithm = GNUTLS_PK_RSA;
376
377       if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
378         {
379           /* try for the second header */
380           result =
381             _gnutls_fbase64_decode (PEM_KEY_DSA, data->data, data->size,
382                                     &out);
383           if (result <= 0)
384             {
385               if (result == 0)
386                 result = GNUTLS_E_INTERNAL_ERROR;
387               gnutls_assert ();
388
389               goto failover;
390             }
391
392           key->pk_algorithm = GNUTLS_PK_DSA;
393         }
394
395       _data.data = out;
396       _data.size = result;
397
398       need_free = 1;
399     }
400
401   if (key->pk_algorithm == GNUTLS_PK_RSA)
402     {
403       key->key = _gnutls_privkey_decode_pkcs1_rsa_key (&_data, key);
404       if (key->key == NULL)
405         gnutls_assert ();
406     }
407   else if (key->pk_algorithm == GNUTLS_PK_DSA)
408     {
409       key->key = decode_dsa_key (&_data, key);
410       if (key->key == NULL)
411         gnutls_assert ();
412     }
413   else
414     {
415       /* Try decoding with both, and accept the one that
416        * succeeds.
417        */
418       key->pk_algorithm = GNUTLS_PK_RSA;
419       key->key = _gnutls_privkey_decode_pkcs1_rsa_key (&_data, key);
420
421       if (key->key == NULL)
422         {
423           key->pk_algorithm = GNUTLS_PK_DSA;
424           key->key = decode_dsa_key (&_data, key);
425           if (key->key == NULL)
426             gnutls_assert ();
427         }
428     }
429
430   if (key->key == NULL)
431     {
432       gnutls_assert ();
433       result = GNUTLS_E_ASN1_DER_ERROR;
434       goto failover;
435     }
436
437   if (need_free)
438     _gnutls_free_datum (&_data);
439
440   /* The key has now been decoded.
441    */
442
443   return 0;
444
445 failover:
446   /* Try PKCS #8 */
447 #ifdef ENABLE_PKI
448   if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
449     {
450       _gnutls_debug_log ("Falling back to PKCS #8 key decoding\n");
451       result = gnutls_x509_privkey_import_pkcs8 (key, data, format,
452                                                  NULL, GNUTLS_PKCS_PLAIN);
453     }
454 #endif
455
456   if (need_free)
457     _gnutls_free_datum (&_data);
458
459   return result;
460 }
461
462 #define FREE_RSA_PRIVATE_PARAMS for (i=0;i<RSA_PRIVATE_PARAMS;i++) \
463                 _gnutls_mpi_release(&key->params[i])
464 #define FREE_DSA_PRIVATE_PARAMS for (i=0;i<DSA_PRIVATE_PARAMS;i++) \
465                 _gnutls_mpi_release(&key->params[i])
466
467 /**
468  * gnutls_x509_privkey_import_rsa_raw:
469  * @key: The structure to store the parsed key
470  * @m: holds the modulus
471  * @e: holds the public exponent
472  * @d: holds the private exponent
473  * @p: holds the first prime (p)
474  * @q: holds the second prime (q)
475  * @u: holds the coefficient
476  *
477  * This function will convert the given RSA raw parameters to the
478  * native #gnutls_x509_privkey_t format.  The output will be stored in
479  * @key.
480  *
481  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
482  *   negative error value.
483  **/
484 int
485 gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key,
486                                     const gnutls_datum_t * m,
487                                     const gnutls_datum_t * e,
488                                     const gnutls_datum_t * d,
489                                     const gnutls_datum_t * p,
490                                     const gnutls_datum_t * q,
491                                     const gnutls_datum_t * u)
492 {
493   return gnutls_x509_privkey_import_rsa_raw2 (key, m, e, d, p, q, u, NULL,
494                                               NULL);
495 }
496
497 /**
498  * gnutls_x509_privkey_import_rsa_raw2:
499  * @key: The structure to store the parsed key
500  * @m: holds the modulus
501  * @e: holds the public exponent
502  * @d: holds the private exponent
503  * @p: holds the first prime (p)
504  * @q: holds the second prime (q)
505  * @u: holds the coefficient
506  * @e1: holds e1 = d mod (p-1)
507  * @e2: holds e2 = d mod (q-1)
508  *
509  * This function will convert the given RSA raw parameters to the
510  * native #gnutls_x509_privkey_t format.  The output will be stored in
511  * @key.
512  *
513  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
514  *   negative error value.
515  **/
516 int
517 gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key,
518                                      const gnutls_datum_t * m,
519                                      const gnutls_datum_t * e,
520                                      const gnutls_datum_t * d,
521                                      const gnutls_datum_t * p,
522                                      const gnutls_datum_t * q,
523                                      const gnutls_datum_t * u,
524                                      const gnutls_datum_t * e1,
525                                      const gnutls_datum_t * e2)
526 {
527   int i = 0, ret;
528   size_t siz = 0;
529   gnutls_pk_params_st pk_params;
530
531   memset (&pk_params, 0, sizeof (pk_params));
532
533   if (key == NULL)
534     {
535       gnutls_assert ();
536       return GNUTLS_E_INVALID_REQUEST;
537     }
538
539   key->params_size = 0;
540
541   siz = m->size;
542   if (_gnutls_mpi_scan_nz (&key->params[0], m->data, siz))
543     {
544       gnutls_assert ();
545       FREE_RSA_PRIVATE_PARAMS;
546       return GNUTLS_E_MPI_SCAN_FAILED;
547     }
548   key->params_size++;
549
550   siz = e->size;
551   if (_gnutls_mpi_scan_nz (&key->params[1], e->data, siz))
552     {
553       gnutls_assert ();
554       FREE_RSA_PRIVATE_PARAMS;
555       return GNUTLS_E_MPI_SCAN_FAILED;
556     }
557   key->params_size++;
558
559   siz = d->size;
560   if (_gnutls_mpi_scan_nz (&key->params[2], d->data, siz))
561     {
562       gnutls_assert ();
563       FREE_RSA_PRIVATE_PARAMS;
564       return GNUTLS_E_MPI_SCAN_FAILED;
565     }
566   key->params_size++;
567
568   siz = p->size;
569   if (_gnutls_mpi_scan_nz (&key->params[3], p->data, siz))
570     {
571       gnutls_assert ();
572       FREE_RSA_PRIVATE_PARAMS;
573       return GNUTLS_E_MPI_SCAN_FAILED;
574     }
575   key->params_size++;
576
577   siz = q->size;
578   if (_gnutls_mpi_scan_nz (&key->params[4], q->data, siz))
579     {
580       gnutls_assert ();
581       FREE_RSA_PRIVATE_PARAMS;
582       return GNUTLS_E_MPI_SCAN_FAILED;
583     }
584   key->params_size++;
585
586   siz = u->size;
587   if (_gnutls_mpi_scan_nz (&key->params[5], u->data, siz))
588     {
589       gnutls_assert ();
590       FREE_RSA_PRIVATE_PARAMS;
591       return GNUTLS_E_MPI_SCAN_FAILED;
592     }
593   key->params_size++;
594
595   if (e1 && e2)
596     {
597       siz = e1->size;
598       if (_gnutls_mpi_scan_nz (&key->params[6], e1->data, siz))
599         {
600           gnutls_assert ();
601           FREE_RSA_PRIVATE_PARAMS;
602           return GNUTLS_E_MPI_SCAN_FAILED;
603         }
604       key->params_size++;
605
606       siz = e2->size;
607       if (_gnutls_mpi_scan_nz (&key->params[7], e2->data, siz))
608         {
609           gnutls_assert ();
610           FREE_RSA_PRIVATE_PARAMS;
611           return GNUTLS_E_MPI_SCAN_FAILED;
612         }
613       key->params_size++;
614     }
615
616   for (i = 0; i < key->params_size; i++)
617     {
618       pk_params.params[i] = key->params[i];
619     }
620
621   pk_params.params_nr = key->params_size;
622
623   ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pk_params);
624   if (ret < 0)
625     {
626       gnutls_assert ();
627       FREE_RSA_PRIVATE_PARAMS;
628       return ret;
629     }
630
631   for (i = 0; i < pk_params.params_nr; i++)
632     {
633       key->params[i] = pk_params.params[i];
634     }
635   key->params_size = pk_params.params_nr;
636
637   ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
638   if (ret < 0)
639     {
640       gnutls_assert ();
641       FREE_RSA_PRIVATE_PARAMS;
642       return ret;
643     }
644
645   key->params_size = RSA_PRIVATE_PARAMS;
646   key->pk_algorithm = GNUTLS_PK_RSA;
647
648   return 0;
649
650 }
651
652 /**
653  * gnutls_x509_privkey_import_dsa_raw:
654  * @key: The structure to store the parsed key
655  * @p: holds the p
656  * @q: holds the q
657  * @g: holds the g
658  * @y: holds the y
659  * @x: holds the x
660  *
661  * This function will convert the given DSA raw parameters to the
662  * native #gnutls_x509_privkey_t format.  The output will be stored
663  * in @key.
664  *
665  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
666  *   negative error value.
667  **/
668 int
669 gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key,
670                                     const gnutls_datum_t * p,
671                                     const gnutls_datum_t * q,
672                                     const gnutls_datum_t * g,
673                                     const gnutls_datum_t * y,
674                                     const gnutls_datum_t * x)
675 {
676   int i = 0, ret;
677   size_t siz = 0;
678
679   if (key == NULL)
680     {
681       gnutls_assert ();
682       return GNUTLS_E_INVALID_REQUEST;
683     }
684
685   siz = p->size;
686   if (_gnutls_mpi_scan_nz (&key->params[0], p->data, siz))
687     {
688       gnutls_assert ();
689       FREE_DSA_PRIVATE_PARAMS;
690       return GNUTLS_E_MPI_SCAN_FAILED;
691     }
692
693   siz = q->size;
694   if (_gnutls_mpi_scan_nz (&key->params[1], q->data, siz))
695     {
696       gnutls_assert ();
697       FREE_DSA_PRIVATE_PARAMS;
698       return GNUTLS_E_MPI_SCAN_FAILED;
699     }
700
701   siz = g->size;
702   if (_gnutls_mpi_scan_nz (&key->params[2], g->data, siz))
703     {
704       gnutls_assert ();
705       FREE_DSA_PRIVATE_PARAMS;
706       return GNUTLS_E_MPI_SCAN_FAILED;
707     }
708
709   siz = y->size;
710   if (_gnutls_mpi_scan_nz (&key->params[3], y->data, siz))
711     {
712       gnutls_assert ();
713       FREE_DSA_PRIVATE_PARAMS;
714       return GNUTLS_E_MPI_SCAN_FAILED;
715     }
716
717   siz = x->size;
718   if (_gnutls_mpi_scan_nz (&key->params[4], x->data, siz))
719     {
720       gnutls_assert ();
721       FREE_DSA_PRIVATE_PARAMS;
722       return GNUTLS_E_MPI_SCAN_FAILED;
723     }
724
725   ret = _gnutls_asn1_encode_dsa (&key->key, key->params);
726   if (ret < 0)
727     {
728       gnutls_assert ();
729       FREE_DSA_PRIVATE_PARAMS;
730       return ret;
731     }
732
733   key->params_size = DSA_PRIVATE_PARAMS;
734   key->pk_algorithm = GNUTLS_PK_DSA;
735
736   return 0;
737
738 }
739
740
741 /**
742  * gnutls_x509_privkey_get_pk_algorithm:
743  * @key: should contain a #gnutls_x509_privkey_t structure
744  *
745  * This function will return the public key algorithm of a private
746  * key.
747  *
748  * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
749  *   success, or a negative value on error.
750  **/
751 int
752 gnutls_x509_privkey_get_pk_algorithm (gnutls_x509_privkey_t key)
753 {
754   if (key == NULL)
755     {
756       gnutls_assert ();
757       return GNUTLS_E_INVALID_REQUEST;
758     }
759
760   return key->pk_algorithm;
761 }
762
763 /**
764  * gnutls_x509_privkey_export:
765  * @key: Holds the key
766  * @format: the format of output params. One of PEM or DER.
767  * @output_data: will contain a private key PEM or DER encoded
768  * @output_data_size: holds the size of output_data (and will be
769  *   replaced by the actual size of parameters)
770  *
771  * This function will export the private key to a PKCS1 structure for
772  * RSA keys, or an integer sequence for DSA keys.  The DSA keys are in
773  * the same format with the parameters used by openssl.
774  *
775  * If the buffer provided is not long enough to hold the output, then
776  * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER
777  * will be returned.
778  *
779  * If the structure is PEM encoded, it will have a header
780  * of "BEGIN RSA PRIVATE KEY".
781  *
782  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
783  *   negative error value.
784  **/
785 int
786 gnutls_x509_privkey_export (gnutls_x509_privkey_t key,
787                             gnutls_x509_crt_fmt_t format, void *output_data,
788                             size_t * output_data_size)
789 {
790   const char *msg;
791
792   if (key == NULL)
793     {
794       gnutls_assert ();
795       return GNUTLS_E_INVALID_REQUEST;
796     }
797
798   if (key->pk_algorithm == GNUTLS_PK_RSA)
799     msg = PEM_KEY_RSA;
800   else if (key->pk_algorithm == GNUTLS_PK_DSA)
801     msg = PEM_KEY_DSA;
802   else
803     msg = NULL;
804
805   return _gnutls_x509_export_int (key->key, format, msg,
806                                   output_data, output_data_size);
807 }
808
809 /**
810  * gnutls_x509_privkey_sec_param:
811  * @key: a key structure
812  *
813  * This function will return the security parameter appropriate with
814  * this private key.
815  *
816  * Returns: On success, a valid security parameter is returned otherwise
817  * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
818  **/
819 gnutls_sec_param_t
820 gnutls_x509_privkey_sec_param (gnutls_x509_privkey_t key)
821 {
822   int ret;
823
824   switch (key->pk_algorithm)
825     {
826     case GNUTLS_PK_RSA:
827       ret = gnutls_pk_bits_to_sec_param (GNUTLS_PK_RSA, _gnutls_mpi_get_nbits (key->params[0]   /*m */
828                                          ));
829       break;
830     case GNUTLS_PK_DSA:
831       ret = gnutls_pk_bits_to_sec_param (GNUTLS_PK_DSA, _gnutls_mpi_get_nbits (key->params[0]   /*p */
832                                          ));
833       break;
834     default:
835       ret = GNUTLS_SEC_PARAM_UNKNOWN;
836     }
837
838   return ret;
839 }
840
841 /**
842  * gnutls_x509_privkey_export_rsa_raw:
843  * @key: a structure that holds the rsa parameters
844  * @m: will hold the modulus
845  * @e: will hold the public exponent
846  * @d: will hold the private exponent
847  * @p: will hold the first prime (p)
848  * @q: will hold the second prime (q)
849  * @u: will hold the coefficient
850  *
851  * This function will export the RSA private key's parameters found
852  * in the given structure. The new parameters will be allocated using
853  * gnutls_malloc() and will be stored in the appropriate datum.
854  *
855  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
856  *   negative error value.
857  **/
858 int
859 gnutls_x509_privkey_export_rsa_raw (gnutls_x509_privkey_t key,
860                                     gnutls_datum_t * m, gnutls_datum_t * e,
861                                     gnutls_datum_t * d, gnutls_datum_t * p,
862                                     gnutls_datum_t * q, gnutls_datum_t * u)
863 {
864
865   return gnutls_x509_privkey_export_rsa_raw2 (key, m, e, d, p, q, u, NULL,
866                                               NULL);
867 }
868
869 /**
870  * gnutls_x509_privkey_export_rsa_raw2:
871  * @key: a structure that holds the rsa parameters
872  * @m: will hold the modulus
873  * @e: will hold the public exponent
874  * @d: will hold the private exponent
875  * @p: will hold the first prime (p)
876  * @q: will hold the second prime (q)
877  * @u: will hold the coefficient
878  * @e1: will hold e1 = d mod (p-1)
879  * @e2: will hold e2 = d mod (q-1)
880  *
881  * This function will export the RSA private key's parameters found
882  * in the given structure. The new parameters will be allocated using
883  * gnutls_malloc() and will be stored in the appropriate datum.
884  *
885  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
886  *   negative error value.
887  **/
888 int
889 gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key,
890                                      gnutls_datum_t * m, gnutls_datum_t * e,
891                                      gnutls_datum_t * d, gnutls_datum_t * p,
892                                      gnutls_datum_t * q, gnutls_datum_t * u,
893                                      gnutls_datum_t * e1, gnutls_datum_t * e2)
894 {
895   int ret;
896   gnutls_pk_params_st pk_params;
897
898   memset (&pk_params, 0, sizeof (pk_params));
899
900   if (key == NULL)
901     {
902       gnutls_assert ();
903       return GNUTLS_E_INVALID_REQUEST;
904     }
905
906   m->data = e->data = d->data = p->data = q->data = u->data = NULL;
907   m->size = e->size = d->size = p->size = q->size = u->size = 0;
908
909   ret = _gnutls_pk_params_copy (&pk_params, key->params, RSA_PRIVATE_PARAMS);
910   if (ret < 0)
911     {
912       gnutls_assert ();
913       return ret;
914     }
915
916   ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
917   if (ret < 0)
918     {
919       gnutls_assert ();
920       goto error;
921     }
922
923   ret = _gnutls_mpi_dprint_lz (pk_params.params[0], m);
924   if (ret < 0)
925     {
926       gnutls_assert ();
927       goto error;
928     }
929
930   /* E */
931   ret = _gnutls_mpi_dprint_lz (pk_params.params[1], e);
932   if (ret < 0)
933     {
934       gnutls_assert ();
935       goto error;
936     }
937
938   /* D */
939   ret = _gnutls_mpi_dprint_lz (pk_params.params[2], d);
940   if (ret < 0)
941     {
942       gnutls_assert ();
943       goto error;
944     }
945
946   /* P */
947   ret = _gnutls_mpi_dprint_lz (pk_params.params[3], p);
948   if (ret < 0)
949     {
950       gnutls_assert ();
951       goto error;
952     }
953
954   /* Q */
955   ret = _gnutls_mpi_dprint_lz (pk_params.params[4], q);
956   if (ret < 0)
957     {
958       gnutls_assert ();
959       goto error;
960     }
961
962   /* U */
963   ret = _gnutls_mpi_dprint_lz (key->params[5], u);
964   if (ret < 0)
965     {
966       gnutls_assert ();
967       goto error;
968     }
969
970   /* E1 */
971   if (e1)
972     {
973       ret = _gnutls_mpi_dprint_lz (key->params[6], e1);
974       if (ret < 0)
975         {
976           gnutls_assert ();
977           goto error;
978         }
979     }
980
981   /* E2 */
982   if (e2)
983     {
984       ret = _gnutls_mpi_dprint_lz (key->params[7], e2);
985       if (ret < 0)
986         {
987           gnutls_assert ();
988           goto error;
989         }
990     }
991
992   gnutls_pk_params_release (&pk_params);
993
994   return 0;
995
996 error:
997   _gnutls_free_datum (m);
998   _gnutls_free_datum (d);
999   _gnutls_free_datum (e);
1000   _gnutls_free_datum (p);
1001   _gnutls_free_datum (q);
1002   gnutls_pk_params_release (&pk_params);
1003
1004   return ret;
1005 }
1006
1007 /**
1008  * gnutls_x509_privkey_export_dsa_raw:
1009  * @key: a structure that holds the DSA parameters
1010  * @p: will hold the p
1011  * @q: will hold the q
1012  * @g: will hold the g
1013  * @y: will hold the y
1014  * @x: will hold the x
1015  *
1016  * This function will export the DSA private key's parameters found
1017  * in the given structure. The new parameters will be allocated using
1018  * gnutls_malloc() and will be stored in the appropriate datum.
1019  *
1020  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1021  *   negative error value.
1022  **/
1023 int
1024 gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key,
1025                                     gnutls_datum_t * p, gnutls_datum_t * q,
1026                                     gnutls_datum_t * g, gnutls_datum_t * y,
1027                                     gnutls_datum_t * x)
1028 {
1029   int ret;
1030
1031   if (key == NULL)
1032     {
1033       gnutls_assert ();
1034       return GNUTLS_E_INVALID_REQUEST;
1035     }
1036
1037   /* P */
1038   ret = _gnutls_mpi_dprint_lz (key->params[0], p);
1039   if (ret < 0)
1040     {
1041       gnutls_assert ();
1042       return ret;
1043     }
1044
1045   /* Q */
1046   ret = _gnutls_mpi_dprint_lz (key->params[1], q);
1047   if (ret < 0)
1048     {
1049       gnutls_assert ();
1050       _gnutls_free_datum (p);
1051       return ret;
1052     }
1053
1054
1055   /* G */
1056   ret = _gnutls_mpi_dprint_lz (key->params[2], g);
1057   if (ret < 0)
1058     {
1059       gnutls_assert ();
1060       _gnutls_free_datum (p);
1061       _gnutls_free_datum (q);
1062       return ret;
1063     }
1064
1065
1066   /* Y */
1067   ret = _gnutls_mpi_dprint_lz (key->params[3], y);
1068   if (ret < 0)
1069     {
1070       gnutls_assert ();
1071       _gnutls_free_datum (p);
1072       _gnutls_free_datum (g);
1073       _gnutls_free_datum (q);
1074       return ret;
1075     }
1076
1077   /* X */
1078   ret = _gnutls_mpi_dprint_lz (key->params[4], x);
1079   if (ret < 0)
1080     {
1081       gnutls_assert ();
1082       _gnutls_free_datum (y);
1083       _gnutls_free_datum (p);
1084       _gnutls_free_datum (g);
1085       _gnutls_free_datum (q);
1086       return ret;
1087     }
1088
1089   return 0;
1090 }
1091
1092
1093 /* Encodes the RSA parameters into an ASN.1 RSA private key structure.
1094  */
1095 static int
1096 _gnutls_asn1_encode_rsa (ASN1_TYPE * c2, bigint_t * params)
1097 {
1098   int result;
1099   opaque null = '\0';
1100   gnutls_pk_params_st pk_params;
1101   gnutls_datum_t m, e, d, p, q, u, exp1, exp2;
1102
1103   memset (&pk_params, 0, sizeof (pk_params));
1104
1105   memset (&m, 0, sizeof (m));
1106   memset (&p, 0, sizeof (p));
1107   memset (&q, 0, sizeof (q));
1108   memset (&p, 0, sizeof (p));
1109   memset (&u, 0, sizeof (u));
1110   memset (&e, 0, sizeof (e));
1111   memset (&d, 0, sizeof (d));
1112   memset (&exp1, 0, sizeof (exp1));
1113   memset (&exp2, 0, sizeof (exp2));
1114
1115   result = _gnutls_pk_params_copy (&pk_params, params, RSA_PRIVATE_PARAMS);
1116   if (result < 0)
1117     {
1118       gnutls_assert ();
1119       return result;
1120     }
1121
1122   result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
1123   if (result < 0)
1124     {
1125       gnutls_assert ();
1126       goto cleanup;
1127     }
1128
1129   /* retrieve as data */
1130
1131   result = _gnutls_mpi_dprint_lz (pk_params.params[0], &m);
1132   if (result < 0)
1133     {
1134       gnutls_assert ();
1135       goto cleanup;
1136     }
1137
1138   result = _gnutls_mpi_dprint_lz (pk_params.params[1], &e);
1139   if (result < 0)
1140     {
1141       gnutls_assert ();
1142       goto cleanup;
1143     }
1144
1145   result = _gnutls_mpi_dprint_lz (pk_params.params[2], &d);
1146   if (result < 0)
1147     {
1148       gnutls_assert ();
1149       goto cleanup;
1150     }
1151
1152   result = _gnutls_mpi_dprint_lz (pk_params.params[3], &p);
1153   if (result < 0)
1154     {
1155       gnutls_assert ();
1156       goto cleanup;
1157     }
1158
1159   result = _gnutls_mpi_dprint_lz (pk_params.params[4], &q);
1160   if (result < 0)
1161     {
1162       gnutls_assert ();
1163       goto cleanup;
1164     }
1165
1166   result = _gnutls_mpi_dprint_lz (pk_params.params[5], &u);
1167   if (result < 0)
1168     {
1169       gnutls_assert ();
1170       goto cleanup;
1171     }
1172
1173   result = _gnutls_mpi_dprint_lz (pk_params.params[6], &exp1);
1174   if (result < 0)
1175     {
1176       gnutls_assert ();
1177       goto cleanup;
1178     }
1179
1180   result = _gnutls_mpi_dprint_lz (pk_params.params[7], &exp2);
1181   if (result < 0)
1182     {
1183       gnutls_assert ();
1184       goto cleanup;
1185     }
1186
1187   /* Ok. Now we have the data. Create the asn1 structures
1188    */
1189
1190   /* first make sure that no previously allocated data are leaked */
1191   if (*c2 != ASN1_TYPE_EMPTY)
1192     {
1193       asn1_delete_structure (c2);
1194       *c2 = ASN1_TYPE_EMPTY;
1195     }
1196
1197   if ((result = asn1_create_element
1198        (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPrivateKey", c2))
1199       != ASN1_SUCCESS)
1200     {
1201       gnutls_assert ();
1202       result = _gnutls_asn2err (result);
1203       goto cleanup;
1204     }
1205
1206   /* Write PRIME 
1207    */
1208   if ((result = asn1_write_value (*c2, "modulus",
1209                                   m.data, m.size)) != ASN1_SUCCESS)
1210     {
1211       gnutls_assert ();
1212       result = _gnutls_asn2err (result);
1213       goto cleanup;
1214     }
1215
1216   if ((result = asn1_write_value (*c2, "publicExponent",
1217                                   e.data, e.size)) != ASN1_SUCCESS)
1218     {
1219       gnutls_assert ();
1220       result = _gnutls_asn2err (result);
1221       goto cleanup;
1222     }
1223
1224   if ((result = asn1_write_value (*c2, "privateExponent",
1225                                   d.data, d.size)) != ASN1_SUCCESS)
1226     {
1227       gnutls_assert ();
1228       result = _gnutls_asn2err (result);
1229       goto cleanup;
1230     }
1231
1232   if ((result = asn1_write_value (*c2, "prime1",
1233                                   p.data, p.size)) != ASN1_SUCCESS)
1234     {
1235       gnutls_assert ();
1236       result = _gnutls_asn2err (result);
1237       goto cleanup;
1238     }
1239
1240   if ((result = asn1_write_value (*c2, "prime2",
1241                                   q.data, q.size)) != ASN1_SUCCESS)
1242     {
1243       gnutls_assert ();
1244       result = _gnutls_asn2err (result);
1245       goto cleanup;
1246     }
1247
1248   if ((result = asn1_write_value (*c2, "coefficient",
1249                                   u.data, u.size)) != ASN1_SUCCESS)
1250     {
1251       gnutls_assert ();
1252       result = _gnutls_asn2err (result);
1253
1254       goto cleanup;
1255     }
1256
1257   if ((result = asn1_write_value (*c2, "exponent1",
1258                                   exp1.data, exp1.size)) != ASN1_SUCCESS)
1259     {
1260       gnutls_assert ();
1261       result = _gnutls_asn2err (result);
1262       goto cleanup;
1263     }
1264
1265   if ((result = asn1_write_value (*c2, "exponent2",
1266                                   exp2.data, exp2.size)) != ASN1_SUCCESS)
1267     {
1268       gnutls_assert ();
1269       result = _gnutls_asn2err (result);
1270       goto cleanup;
1271     }
1272
1273   if ((result = asn1_write_value (*c2, "otherPrimeInfos",
1274                                   NULL, 0)) != ASN1_SUCCESS)
1275     {
1276       gnutls_assert ();
1277       result = _gnutls_asn2err (result);
1278       goto cleanup;
1279     }
1280
1281   if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
1282     {
1283       gnutls_assert ();
1284       result = _gnutls_asn2err (result);
1285       goto cleanup;
1286     }
1287
1288   result = 0;
1289
1290 cleanup:
1291   if (result != 0)
1292     asn1_delete_structure (c2);
1293
1294   gnutls_pk_params_release (&pk_params);
1295
1296   _gnutls_free_datum (&m);
1297   _gnutls_free_datum (&d);
1298   _gnutls_free_datum (&e);
1299   _gnutls_free_datum (&p);
1300   _gnutls_free_datum (&q);
1301   _gnutls_free_datum (&u);
1302   _gnutls_free_datum (&exp1);
1303   _gnutls_free_datum (&exp2);
1304
1305   return result;
1306 }
1307
1308 /* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
1309  */
1310 int
1311 _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, bigint_t * params)
1312 {
1313   int result, i;
1314   size_t size[DSA_PRIVATE_PARAMS], total;
1315   opaque *p_data, *q_data, *g_data, *x_data, *y_data;
1316   opaque *all_data = NULL, *p;
1317   opaque null = '\0';
1318
1319   /* Read all the sizes */
1320   total = 0;
1321   for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
1322     {
1323       _gnutls_mpi_print_lz (params[i], NULL, &size[i]);
1324       total += size[i];
1325     }
1326
1327   /* Encoding phase.
1328    * allocate data enough to hold everything
1329    */
1330   all_data = gnutls_secure_malloc (total);
1331   if (all_data == NULL)
1332     {
1333       gnutls_assert ();
1334       result = GNUTLS_E_MEMORY_ERROR;
1335       goto cleanup;
1336     }
1337
1338   p = all_data;
1339   p_data = p;
1340   p += size[0];
1341   q_data = p;
1342   p += size[1];
1343   g_data = p;
1344   p += size[2];
1345   y_data = p;
1346   p += size[3];
1347   x_data = p;
1348
1349   _gnutls_mpi_print_lz (params[0], p_data, &size[0]);
1350   _gnutls_mpi_print_lz (params[1], q_data, &size[1]);
1351   _gnutls_mpi_print_lz (params[2], g_data, &size[2]);
1352   _gnutls_mpi_print_lz (params[3], y_data, &size[3]);
1353   _gnutls_mpi_print_lz (params[4], x_data, &size[4]);
1354
1355   /* Ok. Now we have the data. Create the asn1 structures
1356    */
1357
1358   /* first make sure that no previously allocated data are leaked */
1359   if (*c2 != ASN1_TYPE_EMPTY)
1360     {
1361       asn1_delete_structure (c2);
1362       *c2 = ASN1_TYPE_EMPTY;
1363     }
1364
1365   if ((result = asn1_create_element
1366        (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPrivateKey", c2))
1367       != ASN1_SUCCESS)
1368     {
1369       gnutls_assert ();
1370       result = _gnutls_asn2err (result);
1371       goto cleanup;
1372     }
1373
1374   /* Write PRIME 
1375    */
1376   if ((result = asn1_write_value (*c2, "p", p_data, size[0])) != ASN1_SUCCESS)
1377     {
1378       gnutls_assert ();
1379       result = _gnutls_asn2err (result);
1380       goto cleanup;
1381     }
1382
1383   if ((result = asn1_write_value (*c2, "q", q_data, size[1])) != ASN1_SUCCESS)
1384     {
1385       gnutls_assert ();
1386       result = _gnutls_asn2err (result);
1387       goto cleanup;
1388     }
1389
1390   if ((result = asn1_write_value (*c2, "g", g_data, size[2])) != ASN1_SUCCESS)
1391     {
1392       gnutls_assert ();
1393       result = _gnutls_asn2err (result);
1394       goto cleanup;
1395     }
1396
1397   if ((result = asn1_write_value (*c2, "Y", y_data, size[3])) != ASN1_SUCCESS)
1398     {
1399       gnutls_assert ();
1400       result = _gnutls_asn2err (result);
1401       goto cleanup;
1402     }
1403
1404   if ((result = asn1_write_value (*c2, "priv",
1405                                   x_data, size[4])) != ASN1_SUCCESS)
1406     {
1407       gnutls_assert ();
1408       result = _gnutls_asn2err (result);
1409       goto cleanup;
1410     }
1411
1412   gnutls_free (all_data);
1413
1414   if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
1415     {
1416       gnutls_assert ();
1417       result = _gnutls_asn2err (result);
1418       goto cleanup;
1419     }
1420
1421   return 0;
1422
1423 cleanup:
1424   asn1_delete_structure (c2);
1425   gnutls_free (all_data);
1426
1427   return result;
1428 }
1429
1430
1431 /**
1432  * gnutls_x509_privkey_generate:
1433  * @key: should contain a #gnutls_x509_privkey_t structure
1434  * @algo: is one of RSA or DSA.
1435  * @bits: the size of the modulus
1436  * @flags: unused for now.  Must be 0.
1437  *
1438  * This function will generate a random private key. Note that this
1439  * function must be called on an empty private key.
1440  *
1441  * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits().
1442  *
1443  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1444  *   negative error value.
1445  **/
1446 int
1447 gnutls_x509_privkey_generate (gnutls_x509_privkey_t key,
1448                               gnutls_pk_algorithm_t algo, unsigned int bits,
1449                               unsigned int flags)
1450 {
1451   int ret;
1452   unsigned int params_len = MAX_PRIV_PARAMS_SIZE;
1453   unsigned int i;
1454
1455   if (key == NULL)
1456     {
1457       gnutls_assert ();
1458       return GNUTLS_E_INVALID_REQUEST;
1459     }
1460
1461   switch (algo)
1462     {
1463     case GNUTLS_PK_DSA:
1464       ret = _gnutls_dsa_generate_params (key->params, &params_len, bits);
1465       if (ret < 0)
1466         {
1467           gnutls_assert ();
1468           return ret;
1469         }
1470
1471       if (params_len != DSA_PRIVATE_PARAMS)
1472         {
1473           gnutls_assert ();
1474           ret = GNUTLS_E_INTERNAL_ERROR;
1475           goto cleanup;
1476         }
1477
1478       ret = _gnutls_asn1_encode_dsa (&key->key, key->params);
1479       if (ret < 0)
1480         {
1481           gnutls_assert ();
1482           goto cleanup;
1483         }
1484       key->params_size = params_len;
1485       key->pk_algorithm = GNUTLS_PK_DSA;
1486
1487       break;
1488     case GNUTLS_PK_RSA:
1489       ret = _gnutls_rsa_generate_params (key->params, &params_len, bits);
1490       if (ret < 0)
1491         {
1492           gnutls_assert ();
1493           return ret;
1494         }
1495
1496       if (params_len != RSA_PRIVATE_PARAMS)
1497         {
1498           gnutls_assert ();
1499           ret = GNUTLS_E_INTERNAL_ERROR;
1500           goto cleanup;
1501         }
1502
1503       ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
1504       if (ret < 0)
1505         {
1506           gnutls_assert ();
1507           goto cleanup;
1508         }
1509
1510       key->params_size = params_len;
1511       key->pk_algorithm = GNUTLS_PK_RSA;
1512
1513       break;
1514     default:
1515       gnutls_assert ();
1516       return GNUTLS_E_INVALID_REQUEST;
1517     }
1518
1519   return 0;
1520
1521 cleanup:
1522   key->pk_algorithm = GNUTLS_PK_UNKNOWN;
1523   key->params_size = 0;
1524   for (i = 0; i < params_len; i++)
1525     _gnutls_mpi_release (&key->params[i]);
1526
1527   return ret;
1528 }
1529
1530 /**
1531  * gnutls_x509_privkey_get_key_id:
1532  * @key: Holds the key
1533  * @flags: should be 0 for now
1534  * @output_data: will contain the key ID
1535  * @output_data_size: holds the size of output_data (and will be
1536  *   replaced by the actual size of parameters)
1537  *
1538  * This function will return a unique ID the depends on the public key
1539  * parameters. This ID can be used in checking whether a certificate
1540  * corresponds to the given key.
1541  *
1542  * If the buffer provided is not long enough to hold the output, then
1543  * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
1544  * be returned.  The output will normally be a SHA-1 hash output,
1545  * which is 20 bytes.
1546  *
1547  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1548  *   negative error value.
1549  **/
1550 int
1551 gnutls_x509_privkey_get_key_id (gnutls_x509_privkey_t key,
1552                                 unsigned int flags,
1553                                 unsigned char *output_data,
1554                                 size_t * output_data_size)
1555 {
1556   int result;
1557   digest_hd_st hd;
1558   gnutls_datum_t der = { NULL, 0 };
1559
1560   if (key == NULL)
1561     {
1562       gnutls_assert ();
1563       return GNUTLS_E_INVALID_REQUEST;
1564     }
1565
1566   if (*output_data_size < 20)
1567     {
1568       gnutls_assert ();
1569       *output_data_size = 20;
1570       return GNUTLS_E_SHORT_MEMORY_BUFFER;
1571     }
1572
1573   if (key->pk_algorithm == GNUTLS_PK_RSA)
1574     {
1575       result =
1576         _gnutls_x509_write_rsa_params (key->params, key->params_size, &der);
1577       if (result < 0)
1578         {
1579           gnutls_assert ();
1580           goto cleanup;
1581         }
1582     }
1583   else if (key->pk_algorithm == GNUTLS_PK_DSA)
1584     {
1585       result =
1586         _gnutls_x509_write_dsa_public_key (key->params,
1587                                            key->params_size, &der);
1588       if (result < 0)
1589         {
1590           gnutls_assert ();
1591           goto cleanup;
1592         }
1593     }
1594   else
1595     return GNUTLS_E_INTERNAL_ERROR;
1596
1597   result = _gnutls_hash_init (&hd, GNUTLS_MAC_SHA1);
1598   if (result < 0)
1599     {
1600       gnutls_assert ();
1601       goto cleanup;
1602     }
1603
1604   _gnutls_hash (&hd, der.data, der.size);
1605
1606   _gnutls_hash_deinit (&hd, output_data);
1607   *output_data_size = 20;
1608
1609   result = 0;
1610
1611 cleanup:
1612
1613   _gnutls_free_datum (&der);
1614   return result;
1615 }
1616
1617
1618 #ifdef ENABLE_PKI
1619 /*-
1620  * _gnutls_x509_privkey_sign_hash2:
1621  * @signer: Holds the signer's key
1622  * @hash_algo: The hash algorithm used
1623  * @hash_data: holds the data to be signed
1624  * @signature: will contain newly allocated signature
1625  * @flags: zero for now
1626  *
1627  * This function will sign the given hashed data using a signature algorithm
1628  * supported by the private key. Signature algorithms are always used
1629  * together with a hash functions.  Different hash functions may be
1630  * used for the RSA algorithm, but only SHA-1,SHA-224 and SHA-256 
1631  * for the DSA keys, depending on their bit size.
1632  *
1633  * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
1634  * the hash algorithm.
1635  *
1636  * The RSA algorithm is used in PKCS #1 v1.5 mode.
1637  *
1638  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1639  *   negative error value.
1640  -*/
1641 static int
1642 _gnutls_x509_privkey_sign_hash2 (gnutls_x509_privkey_t signer,
1643                                 gnutls_digest_algorithm_t hash_algo,
1644                                 unsigned int flags,
1645                                 const gnutls_datum_t * hash_data,
1646                                 gnutls_datum_t * signature)
1647 {
1648   int ret;
1649   gnutls_datum_t digest;
1650
1651   digest.data = gnutls_malloc (hash_data->size);
1652   if (digest.data == NULL)
1653     {
1654       gnutls_assert ();
1655       return GNUTLS_E_MEMORY_ERROR;
1656     }
1657   digest.size = hash_data->size;
1658   memcpy (digest.data, hash_data->data, digest.size);
1659
1660   ret = pk_prepare_hash (signer->pk_algorithm, hash_algo, &digest);
1661   if (ret < 0)
1662     {
1663       gnutls_assert ();
1664       goto cleanup;
1665     }
1666
1667   ret = _gnutls_soft_sign (signer->pk_algorithm, signer->params,
1668                            signer->params_size, &digest, signature);
1669
1670   if (ret < 0)
1671     {
1672       gnutls_assert ();
1673       goto cleanup;
1674     }
1675
1676   ret = 0;
1677
1678 cleanup:
1679   _gnutls_free_datum (&digest);
1680   return ret;
1681 }
1682
1683 /**
1684  * gnutls_x509_privkey_sign_hash:
1685  * @key: Holds the key
1686  * @hash: holds the data to be signed
1687  * @signature: will contain newly allocated signature
1688  *
1689  * This function will sign the given hash using the private key. Do not
1690  * use this function directly unless you know what it is. Typical signing
1691  * requires the data to be hashed and stored in special formats 
1692  * (e.g. BER Digest-Info for RSA).
1693  *
1694  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1695  *   negative error value.
1696  *
1697  * Deprecated in: 2.12.0
1698  */
1699 int
1700 gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key,
1701                                const gnutls_datum_t * hash,
1702                                gnutls_datum_t * signature)
1703 {
1704   int result;
1705
1706   if (key == NULL)
1707     {
1708       gnutls_assert ();
1709       return GNUTLS_E_INVALID_REQUEST;
1710     }
1711
1712   result = _gnutls_soft_sign (key->pk_algorithm, key->params,
1713                               key->params_size, hash, signature);
1714   if (result < 0)
1715     {
1716       gnutls_assert ();
1717       return result;
1718     }
1719
1720   return 0;
1721 }
1722
1723 /**
1724  * gnutls_x509_privkey_sign_data:
1725  * @key: Holds the key
1726  * @digest: should be MD5 or SHA1
1727  * @flags: should be 0 for now
1728  * @data: holds the data to be signed
1729  * @signature: will contain the signature
1730  * @signature_size: holds the size of signature (and will be replaced
1731  *   by the new size)
1732  *
1733  * This function will sign the given data using a signature algorithm
1734  * supported by the private key. Signature algorithms are always used
1735  * together with a hash functions.  Different hash functions may be
1736  * used for the RSA algorithm, but only SHA-1 for the DSA keys.
1737  *
1738  * If the buffer provided is not long enough to hold the output, then
1739  * *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
1740  * be returned.
1741  *
1742  * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
1743  * the hash algorithm.
1744  *
1745  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1746  *   negative error value.
1747  *
1748  * Deprecated: Use gnutls_privkey_sign_data().
1749  */
1750 int
1751 gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key,
1752                                gnutls_digest_algorithm_t digest,
1753                                unsigned int flags,
1754                                const gnutls_datum_t * data,
1755                                void *signature, size_t * signature_size)
1756 {
1757   int result;
1758   gnutls_datum_t sig = { NULL, 0 };
1759   gnutls_datum_t hash;
1760
1761   if (key == NULL)
1762     {
1763       gnutls_assert ();
1764       return GNUTLS_E_INVALID_REQUEST;
1765     }
1766
1767   result =
1768     pk_hash_data (key->pk_algorithm, digest, key->params, data, &hash);
1769   if (result < 0)
1770     {
1771       gnutls_assert ();
1772       return result;
1773     }
1774
1775   result =
1776     _gnutls_x509_privkey_sign_hash2 (key, digest, flags, &hash, signature);
1777
1778   _gnutls_free_datum(&hash);
1779
1780   if (result < 0)
1781     {
1782       gnutls_assert ();
1783       return result;
1784     }
1785     
1786   if (*signature_size < sig.size)
1787     {
1788       *signature_size = sig.size;
1789       _gnutls_free_datum (&sig);
1790       return GNUTLS_E_SHORT_MEMORY_BUFFER;
1791     }
1792
1793   *signature_size = sig.size;
1794   memcpy (signature, sig.data, sig.size);
1795
1796   _gnutls_free_datum (&sig);
1797
1798   return 0;
1799 }
1800
1801
1802 /**
1803  * gnutls_x509_privkey_verify_data:
1804  * @key: Holds the key
1805  * @flags: should be 0 for now
1806  * @data: holds the data to be signed
1807  * @signature: contains the signature
1808  *
1809  * This function will verify the given signed data, using the
1810  * parameters in the private key.
1811  *
1812  * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED 
1813  * is returned, and a positive code on success.
1814  *
1815  * Deprecated: Use gnutls_pubkey_verify_data().
1816  */
1817 int
1818 gnutls_x509_privkey_verify_data (gnutls_x509_privkey_t key,
1819                                  unsigned int flags,
1820                                  const gnutls_datum_t * data,
1821                                  const gnutls_datum_t * signature)
1822 {
1823   int result;
1824
1825   if (key == NULL)
1826     {
1827       gnutls_assert ();
1828       return GNUTLS_E_INVALID_REQUEST;
1829     }
1830
1831   result = _gnutls_x509_privkey_verify_signature (data, signature, key);
1832   if (result < 0)
1833     {
1834       gnutls_assert ();
1835       return result;
1836     }
1837
1838   return result;
1839 }
1840
1841 /**
1842  * gnutls_x509_privkey_fix:
1843  * @key: Holds the key
1844  *
1845  * This function will recalculate the secondary parameters in a key.
1846  * In RSA keys, this can be the coefficient and exponent1,2.
1847  *
1848  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1849  *   negative error value.
1850  **/
1851 int
1852 gnutls_x509_privkey_fix (gnutls_x509_privkey_t key)
1853 {
1854   int ret;
1855
1856   if (key == NULL)
1857     {
1858       gnutls_assert ();
1859       return GNUTLS_E_INVALID_REQUEST;
1860     }
1861
1862   asn1_delete_structure (&key->key);
1863
1864   switch (key->pk_algorithm)
1865     {
1866     case GNUTLS_PK_DSA:
1867       ret = _gnutls_asn1_encode_dsa (&key->key, key->params);
1868       if (ret < 0)
1869         {
1870           gnutls_assert ();
1871           return ret;
1872         }
1873       break;
1874     case GNUTLS_PK_RSA:
1875       ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
1876       if (ret < 0)
1877         {
1878           gnutls_assert ();
1879           return ret;
1880         }
1881       break;
1882     default:
1883       gnutls_assert ();
1884       return GNUTLS_E_INVALID_REQUEST;
1885     }
1886
1887   return 0;
1888 }
1889
1890 #endif