2005-04-12 Moritz Schulte <moritz@g10code.com>
[libgcrypt.git] / cipher / ac.c
1 /* ac.c - Alternative interface for asymmetric cryptography.
2    Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3  
4    This file is part of Libgcrypt.
5   
6    Libgcrypt is free software; you can redistribute it and/or modify
7    it under the terms of the GNU Lesser general Public License as
8    published by the Free Software Foundation; either version 2.1 of
9    the License, or (at your option) any later version.
10   
11    Libgcrypt is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU Lesser General Public License for more details.
15   
16    You should have received a copy of the GNU Lesser General Public
17    License along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA.  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include <stddef.h>
27 #include <assert.h>
28
29 #include "g10lib.h"
30 #include "cipher.h"
31 #include "mpi.h"
32
33 \f
34
35 /* At the moment the ac interface is a wrapper around the pk
36    interface, but this might change somewhen in the future, depending
37    on how many people prefer the ac interface.  */
38
39 /* Mapping of flag numbers to the according strings as it is expected
40    for S-expressions.  */
41 static struct number_string
42 {
43   int number;
44   const char *string;
45 } ac_flags[] =
46   {
47     { GCRY_AC_FLAG_NO_BLINDING, "no-blinding" },
48   };
49
50 /* The positions in this list correspond to the values contained in
51    the gcry_ac_key_type_t enumeration list.  */
52 static const char *ac_key_identifiers[] =
53   {
54     "private-key",
55     "public-key"
56   };
57
58 /* These specifications are needed for key-pair generation; the caller
59    is allowed to pass additional, algorithm-specific `specs' to
60    gcry_ac_key_pair_generate.  This list is used for decoding the
61    provided values according to the selected algorithm.  */
62 struct gcry_ac_key_generate_spec
63 {
64   int algorithm;                /* Algorithm for which this flag is
65                                    relevant.  */
66   const char *name;             /* Name of this flag.  */
67   size_t offset;                /* Offset in the cipher-specific spec
68                                    structure at which the MPI value
69                                    associated with this flag is to be
70                                    found.  */
71 } ac_key_generate_specs[] =
72   {
73     { GCRY_AC_RSA, "rsa-use-e", offsetof (gcry_ac_key_spec_rsa_t, e) },
74     { 0 },
75   };
76
77 /* Handle structure.  */
78 struct gcry_ac_handle
79 {
80   int algorithm;                /* Algorithm ID associated with this
81                                    handle.  */
82   const char *algorithm_name;   /* Name of the algorithm.  */
83   unsigned int flags;           /* Flags, not used yet.  */
84   gcry_module_t module;         /* Reference to the algorithm
85                                    module.  */
86 };
87
88 /* A named MPI value.  */
89 typedef struct gcry_ac_mpi
90 {
91   const char *name_provided;    /* Provided name of MPI value. */
92   char *name;                   /* Self-maintained copy of name.  */
93   gcry_mpi_t mpi;               /* MPI value.         */
94   unsigned int flags;           /* Flags.             */
95 } gcry_ac_mpi_t;
96
97 /* A data set, that is simply a list of named MPI values.  */
98 struct gcry_ac_data
99 {
100   gcry_ac_mpi_t *data;          /* List of named values.      */
101   unsigned int data_n;          /* Number of values in DATA.  */
102 };
103
104 /* A single key.  */
105 struct gcry_ac_key
106 {
107   gcry_ac_data_t data;          /* Data in native ac structure.  */
108   gcry_ac_key_type_t type;      /* Type of the key.              */
109 };
110
111 /* A key pair.  */
112 struct gcry_ac_key_pair
113 {
114   gcry_ac_key_t public;
115   gcry_ac_key_t secret;
116 };
117
118 \f
119
120 /* 
121  * Functions for working with data sets.
122  */
123
124 /* Creates a new, empty data set and store it in DATA.  */
125 gcry_error_t
126 _gcry_ac_data_new (gcry_ac_data_t *data)
127 {
128   gcry_ac_data_t data_new;
129   gcry_error_t err;
130
131   data_new = gcry_malloc (sizeof (*data_new));
132   if (! data_new)
133     {
134       err = gcry_error_from_errno (errno);
135       goto out;
136     }
137
138   data_new->data = NULL;
139   data_new->data_n = 0;
140   *data = data_new;
141   err = 0;
142
143  out:
144
145   return err;
146 }
147
148 gcry_error_t
149 gcry_ac_data_new (gcry_ac_data_t *data)
150 {
151   gcry_error_t err;
152
153   err = _gcry_ac_data_new (data);
154
155   return gcry_error (err);
156 }
157
158 /* Destroys all the entries in DATA, but not DATA itself.  */
159 static void
160 ac_data_values_destroy (gcry_ac_data_t data)
161 {
162   unsigned int i;
163   
164   for (i = 0; i < data->data_n; i++)
165     if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
166       {
167         gcry_mpi_release (data->data[i].mpi);
168         gcry_free (data->data[i].name);
169       }
170 }
171
172 /* Destroys the data set DATA.  */
173 void
174 _gcry_ac_data_destroy (gcry_ac_data_t data)
175 {
176   if (data)
177     {
178       ac_data_values_destroy (data);
179       gcry_free (data->data);
180       gcry_free (data);
181     }
182 }
183
184 void
185 gcry_ac_data_destroy (gcry_ac_data_t data)
186 {
187   return _gcry_ac_data_destroy (data);
188 }
189
190 /* This function creates a copy of the array of named MPIs DATA_MPIS,
191    which is of length DATA_MPIS_N; the copy is stored in
192    DATA_MPIS_CP.  */
193 static gcry_error_t
194 ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n,
195                   gcry_ac_mpi_t **data_mpis_cp)
196 {
197   gcry_ac_mpi_t *data_mpis_new;
198   gcry_error_t err;
199   unsigned int i;
200   gcry_mpi_t mpi;
201   char *label;
202
203   data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n);
204   if (! data_mpis_new)
205     {
206       err = gcry_error_from_errno (errno);
207       goto out;
208     }
209   memset (data_mpis_new, 0, sizeof (*data_mpis_new) * data_mpis_n);
210
211   err = 0;
212   for (i = 0; i < data_mpis_n; i++)
213     {
214       /* Copy values.  */
215
216       if (data_mpis[i].name)
217         label = gcry_strdup (data_mpis[i].name);
218       else
219         label = gcry_strdup (data_mpis[i].name_provided);
220       mpi = gcry_mpi_copy (data_mpis[i].mpi);
221       if (! (label && mpi))
222         {
223           err = gcry_error_from_errno (errno);
224           gcry_mpi_release (mpi);
225           gcry_free (label);
226           break;
227         }
228
229       data_mpis_new[i].flags = GCRY_AC_FLAG_DEALLOC;
230       data_mpis_new[i].name = label;
231       data_mpis_new[i].mpi = mpi;
232     }
233   if (err)
234     goto out;
235
236   *data_mpis_cp = data_mpis_new;
237   err = 0;
238
239  out:
240
241   if (err)
242     if (data_mpis_new)
243       {
244         for (i = 0; i < data_mpis_n; i++)
245           {
246             gcry_mpi_release (data_mpis_new[i].mpi);
247             gcry_free (data_mpis_new[i].name);
248           }
249         gcry_free (data_mpis_new);
250       }
251
252   return err;
253 }
254
255 /* Create a copy of the data set DATA and store it in DATA_CP.  */
256 gcry_error_t
257 _gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data)
258 {
259   gcry_ac_mpi_t *data_mpis;
260   gcry_ac_data_t data_new;
261   gcry_error_t err;
262
263   /* Allocate data set.  */
264   data_new = gcry_malloc (sizeof (*data_new));
265   if (! data_new)
266     {
267       err = gcry_error_from_errno (errno);
268       goto out;
269     }
270
271   err = ac_data_mpi_copy (data->data, data->data_n, &data_mpis);
272   if (err)
273     goto out;
274   
275   data_new->data_n = data->data_n;
276   data_new->data = data_mpis;
277   *data_cp = data_new;
278
279  out:
280
281   if (err)
282     gcry_free (data_new);
283
284   return err;
285 }
286
287 gcry_error_t
288 gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data)
289 {
290   return gcry_error (_gcry_ac_data_copy (data_cp, data));
291 }
292
293 /* Returns the number of named MPI values inside of the data set
294    DATA.  */
295 unsigned int
296 _gcry_ac_data_length (gcry_ac_data_t data)
297 {
298   return data->data_n;
299 }
300
301 unsigned int
302 gcry_ac_data_length (gcry_ac_data_t data)
303 {
304   return _gcry_ac_data_length (data);
305 }
306
307 /* Add the value MPI to DATA with the label NAME.  If FLAGS contains
308    GCRY_AC_FLAG_COPY, the data set will contain copies of NAME
309    and MPI.  If FLAGS contains GCRY_AC_FLAG_DEALLOC or
310    GCRY_AC_FLAG_COPY, the values contained in the data set will
311    be deallocated when they are to be removed from the data set.  */
312 gcry_error_t
313 _gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
314                    const char *name, gcry_mpi_t mpi)
315 {
316   gcry_error_t err;
317   gcry_mpi_t mpi_cp;
318   char *name_cp;
319   unsigned int i;
320
321   name_cp = NULL;
322   mpi_cp = NULL;
323
324   if (flags & ~(GCRY_AC_FLAG_DEALLOC | GCRY_AC_FLAG_COPY))
325     {
326       err = gcry_error (GPG_ERR_INV_ARG);
327       goto out;
328     }
329
330   if (flags & GCRY_AC_FLAG_COPY)
331     {
332       /* Create copies.  */
333
334       name_cp = gcry_strdup (name);
335       mpi_cp = gcry_mpi_copy (mpi);
336       if (! (name_cp && mpi_cp))
337         {
338           err = gcry_error_from_errno (errno);
339           goto out;
340         }
341     }
342
343   /* Search for existing entry.  */
344   for (i = 0; i < data->data_n; i++)
345     if (! strcmp (name,
346                   data->data[i].name
347                   ? data->data[i].name : data->data[i].name_provided))
348       break;
349   if (i < data->data_n)
350     {
351       /* An entry for NAME does already exist.  */
352       if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
353         {
354           gcry_mpi_release (data->data[i].mpi);
355           gcry_free (data->data[i].name);
356         }
357     }
358   else
359     {
360       /* Create a new entry.  */
361
362       gcry_ac_mpi_t *ac_mpis;
363
364       ac_mpis = gcry_realloc (data->data,
365                               sizeof (*data->data) * (data->data_n + 1));
366       if (! ac_mpis)
367         {
368           err = gcry_error_from_errno (errno);
369           goto out;
370         }
371
372       if (data->data != ac_mpis)
373         data->data = ac_mpis;
374       data->data_n++;
375     }
376
377   data->data[i].name_provided = name_cp ? NULL : name;
378   data->data[i].name = name_cp;
379   data->data[i].mpi = mpi_cp ? mpi_cp : mpi;
380   data->data[i].flags = flags;
381   err = 0;
382
383  out:
384
385   if (err)
386     {
387       gcry_mpi_release (mpi_cp);
388       gcry_free (name_cp);
389     }
390
391   return err;
392 }
393
394 gcry_error_t
395 gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
396                   const char *name, gcry_mpi_t mpi)
397 {
398   return gcry_error (_gcry_ac_data_set (data, flags, name, mpi));
399 }
400
401 /* Stores the value labelled with NAME found in the data set DATA in
402    MPI.  The returned MPI value will be released in case
403    gcry_ac_data_set is used to associate the label NAME with a
404    different MPI value.  */
405 gcry_error_t
406 _gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
407                         const char *name, gcry_mpi_t *mpi)
408 {
409   gcry_mpi_t mpi_return;
410   gcry_error_t err;
411   unsigned int i;
412
413   if (flags & ~(GCRY_AC_FLAG_COPY))
414     {
415       err = gcry_error (GPG_ERR_INV_ARG);
416       goto out;
417     }
418
419   for (i = 0; i < data->data_n; i++)
420     if (! strcmp (name,
421                   data->data[i].name ?
422                   data->data[i].name : data->data[i].name_provided))
423       break;
424   if (i == data->data_n)
425     {
426       err = gcry_error (GPG_ERR_NOT_FOUND);
427       goto out;
428     }
429
430   if (flags & GCRY_AC_FLAG_COPY)
431     {
432       mpi_return = gcry_mpi_copy (data->data[i].mpi);
433       if (! mpi_return)
434         {
435           err = gcry_error_from_errno (errno); /* FIXME? */
436           goto out;
437         }
438     }
439   else
440     mpi_return = data->data[i].mpi;
441
442   *mpi = mpi_return;
443   err = 0;
444
445  out:
446
447   return err;
448 }
449
450 gcry_error_t
451 gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
452                        const char *name, gcry_mpi_t *mpi)
453 {
454   return gcry_error (_gcry_ac_data_get_name (data, flags, name, mpi));
455 }
456
457 /* Stores in NAME and MPI the named MPI value contained in the data
458    set DATA with the index IDX.  NAME or MPI may be NULL.  The
459    returned MPI value will be released in case gcry_ac_data_set is
460    used to associate the label NAME with a different MPI value.  */
461 gcry_error_t
462 _gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
463                          unsigned int idx,
464                          const char **name, gcry_mpi_t *mpi)
465 {
466   gcry_error_t err;
467   gcry_mpi_t mpi_cp;
468   char *name_cp;
469
470   name_cp = NULL;
471   mpi_cp = NULL;
472
473   if (flags & ~(GCRY_AC_FLAG_COPY))
474     {
475       err = gcry_error (GPG_ERR_INV_ARG);
476       goto out;
477     }
478
479   if (idx >= data->data_n)
480     {
481       err = gcry_error (GPG_ERR_INV_ARG);
482       goto out;
483     }
484
485   if (flags & GCRY_AC_FLAG_COPY)
486     {
487       /* Return copies to the user.  */
488       if (name)
489         {
490           if (data->data[idx].name_provided)
491             name_cp = gcry_strdup (data->data[idx].name_provided);
492           else
493             name_cp = gcry_strdup (data->data[idx].name);
494           if (! name_cp)
495             {
496               err = gcry_error_from_errno (errno);
497               goto out;
498             }
499         }
500       if (mpi)
501         {
502           mpi_cp = gcry_mpi_copy (data->data[idx].mpi);
503           if (! mpi_cp)
504             {
505               err = gcry_error_from_errno (errno);
506               goto out;
507             }
508         }
509     }
510
511   if (name)
512     *name = name_cp ? name_cp : (data->data[idx].name
513                                  ? data->data[idx].name
514                                  : data->data[idx].name_provided);
515   if (mpi)
516     *mpi = mpi_cp ? mpi_cp : data->data[idx].mpi;
517   err = 0;
518
519  out:
520
521   if (err)
522     {
523       gcry_mpi_release (mpi_cp);
524       gcry_free (name_cp);
525     }
526
527   return err;
528 }
529
530 gcry_error_t
531 gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
532                         unsigned int idx, const char **name, gcry_mpi_t *mpi)
533 {
534   return gcry_error (_gcry_ac_data_get_index (data, flags, idx, name, mpi));
535 }
536
537 /* Convert the data set DATA into a new S-Expression, which is to be
538    stored in SEXP, according to the identifiers contained in
539    IDENTIFIERS.  */
540 gcry_error_t
541 _gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
542                        const char **identifiers)
543 {
544   gcry_sexp_t sexp_new;
545   gcry_error_t err;
546   char *sexp_buffer;
547   size_t sexp_buffer_n;
548   size_t identifiers_n;
549   const char *label;
550   gcry_mpi_t mpi;
551   void **arg_list;
552   size_t data_n;
553   unsigned int i;
554
555   /* The shortest S-Expression here is the empty one "()" (including
556      NUL).  */
557   sexp_buffer_n = 3;
558   sexp_buffer = NULL;
559   arg_list = NULL;
560   err = 0;
561
562   /* Calculate size of S-expression representation.  */
563
564   i = 0;
565   if (identifiers)
566     while (identifiers[i])
567       {
568         /* For each identifier, we add "(<IDENTIFIER>)".  */
569         sexp_buffer_n += 1 + strlen (identifiers[i]) + 1;
570         i++;
571       }
572   identifiers_n = i;
573   
574   data_n = _gcry_ac_data_length (data);
575   for (i = 0; i < data_n; i++)
576     {
577       err = gcry_ac_data_get_index (data, 0, i, &label, NULL);
578       if (err)
579         break;
580       /* For each MPI we add "(<LABEL> %m)".  */
581       sexp_buffer_n += 1 + strlen (label) + 4;
582     }
583   if (err)
584     goto out;
585
586   /* Allocate buffer.  */
587
588   sexp_buffer = gcry_malloc (sexp_buffer_n);
589   if (! sexp_buffer)
590     {
591       err = gcry_error_from_errno (errno);
592       goto out;
593     }
594
595   /* Fill buffer.  */
596
597   *sexp_buffer = 0;
598   sexp_buffer_n = 0;
599
600   /* Add identifiers: (<IDENTIFIER0>(<IDENTIFIER1>...)).  */
601   for (i = 0; i < identifiers_n; i++)
602     sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(%s",
603                               identifiers[i]);
604
605   /* Add MPI list.  */
606   sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(");
607   arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1));
608   if (! arg_list)
609     {
610       err = gcry_error_from_errno (errno);
611       goto out;
612     }
613   for (i = 0; i < data_n; i++)
614     {
615       err = gcry_ac_data_get_index (data, 0, i, &label, &mpi);
616       if (err)
617         break;
618       sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n,
619                                 "(%s %%m)", label);
620       arg_list[i] = &data->data[i].mpi;
621     }
622   if (err)
623     goto out;
624   sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
625
626   /* Add closing braces for identifier list.  */
627   for (i = 0; i < identifiers_n; i++)
628     sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
629
630   /* Construct.  */
631   err = gcry_sexp_build_array (&sexp_new, NULL, sexp_buffer, arg_list);
632   if (err)
633     goto out;
634
635   *sexp = sexp_new;
636
637  out:
638
639   gcry_free (sexp_buffer);
640   gcry_free (arg_list);
641
642   return err;
643 }
644
645 gcry_error_t
646 gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
647                       const char **identifiers)
648 {
649   gcry_error_t err;
650
651   err = _gcry_ac_data_to_sexp (data, sexp, identifiers);
652
653   return gcry_error (err);
654 }
655
656 /* Create a new data set, which is to be stored in DATA_SET, from the
657    S-Expression SEXP, according to the identifiers contained in
658    IDENTIFIERS.  */
659 gcry_error_t
660 _gcry_ac_data_from_sexp (gcry_ac_data_t *data_set, gcry_sexp_t sexp,
661                          const char **identifiers)
662 {
663   gcry_ac_data_t data_set_new;
664   gcry_error_t err;
665   gcry_sexp_t sexp_cur;
666   gcry_sexp_t sexp_tmp;
667   gcry_mpi_t mpi;
668   char *string;
669   const char *data;
670   size_t data_n;
671   size_t sexp_n;
672   unsigned int i;
673
674   data_set_new = NULL;
675   sexp_cur = sexp;
676   sexp_tmp = NULL;
677   string = NULL;
678   mpi = NULL;
679   err = 0;
680
681   /* Process S-expression/identifiers.  */
682
683   if (identifiers)
684     {
685       for (i = 0; identifiers[i]; i++)
686         {
687           data = gcry_sexp_nth_data (sexp_cur, 0, &data_n);
688           if (! ((data_n == strlen (identifiers[i]))
689                  && (! strncmp (data, identifiers[i], data_n))))
690             {
691               /* Identifier mismatch.  */
692               err = gcry_error (GPG_ERR_INV_SEXP);
693               break;
694             }
695           sexp_tmp = gcry_sexp_nth (sexp_cur, 1);
696           if (! sexp_tmp)
697             {
698               /* gcry_sexp_nth() does also return NULL in case the
699                  requested element is simple an empty list.  That's
700                  why we have to add this special case.  */
701
702               if ((gcry_sexp_length (sexp_cur) == 1) || identifiers[i + 1])
703                 {
704                   err = gcry_error (GPG_ERR_INV_SEXP);
705                   break;
706                 }
707             }
708           if (sexp_cur != sexp)
709             gcry_sexp_release (sexp_cur);
710           sexp_cur = sexp_tmp;
711         }
712       if (err)
713         goto out;
714     }
715
716   /* Create data set from S-expression data.  */
717   
718   err = gcry_ac_data_new (&data_set_new);
719   if (err)
720     goto out;
721
722   if (sexp_cur)
723     sexp_n = gcry_sexp_length (sexp_cur);
724   else
725     sexp_n = 0;
726
727   for (i = 0; i < sexp_n; i++)
728     {
729       sexp_tmp = gcry_sexp_nth (sexp_cur, i);
730       if (! sexp_tmp)
731         {
732           err = gcry_error (GPG_ERR_INV_SEXP);
733           break;
734         }
735
736       data = gcry_sexp_nth_data (sexp_tmp, 0, &data_n);
737       string = gcry_malloc (data_n + 1);
738       if (! string)
739         {
740           err = gcry_error_from_errno (errno);
741           break;
742         }
743       memcpy (string, data, data_n);
744       string[data_n] = 0;
745
746       mpi = gcry_sexp_nth_mpi (sexp_tmp, 1, 0);
747       if (! mpi)
748         {
749           err = gcry_error (GPG_ERR_INV_SEXP); /* FIXME? */
750           break;
751         }
752
753       err = gcry_ac_data_set (data_set_new, GCRY_AC_FLAG_DEALLOC, string, mpi);
754       if (err)
755         break;
756
757       string = NULL;
758       mpi = NULL;
759
760       gcry_sexp_release (sexp_tmp);
761       sexp_tmp = NULL;
762     }
763   if (err)
764     goto out;
765
766   *data_set = data_set_new;
767
768  out:
769
770   gcry_sexp_release (sexp_tmp);
771   gcry_mpi_release (mpi);
772   gcry_free (string);
773   
774   if (err)
775     gcry_ac_data_destroy (data_set_new);
776
777   return err;
778 }
779
780 gcry_error_t
781 gcry_ac_data_from_sexp (gcry_ac_data_t *data_set, gcry_sexp_t sexp,
782                         const char **identifiers)
783 {
784   gcry_error_t err;
785
786   err = _gcry_ac_data_from_sexp (data_set, sexp, identifiers);
787
788   return gcry_error (err);
789 }
790
791 /* Destroys any values contained in the data set DATA.  */
792 void
793 _gcry_ac_data_clear (gcry_ac_data_t data)
794 {
795   ac_data_values_destroy (data);
796   gcry_free (data->data);
797   data->data = NULL;
798   data->data_n = 0;
799 }
800
801 void
802 gcry_ac_data_clear (gcry_ac_data_t data)
803 {
804   return _gcry_ac_data_clear (data);
805 }
806
807 \f
808
809 /*
810  * Implementation of `ac io' objects.
811  */
812
813 /* Initialize AC_IO according to MODE, TYPE and the variable list of
814    arguments AP.  The list of variable arguments to specify depends on
815    the given TYPE.  */
816 static void
817 _gcry_ac_io_init_va (gcry_ac_io_t *ac_io,
818                      gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, va_list ap)
819 {
820   memset (ac_io, 0, sizeof (*ac_io));
821
822   assert ((mode == GCRY_AC_IO_READABLE) || (mode == GCRY_AC_IO_WRITABLE));
823   assert ((type == GCRY_AC_IO_STRING) || (type == GCRY_AC_IO_STRING));
824
825   ac_io->mode = mode;
826   ac_io->type = type;
827
828   switch (mode)
829     {
830     case GCRY_AC_IO_READABLE:
831       switch (type)
832         {
833         case GCRY_AC_IO_STRING:
834           ac_io->readable.string.data = va_arg (ap, unsigned char *);
835           ac_io->readable.string.data_n = va_arg (ap, size_t);
836           break;
837
838         case GCRY_AC_IO_CALLBACK:
839           ac_io->readable.callback.cb = va_arg (ap, gcry_ac_data_read_cb_t);
840           ac_io->readable.callback.opaque = va_arg (ap, void *);
841           break;
842         }
843       break;
844     case GCRY_AC_IO_WRITABLE:
845       switch (type)
846         {
847         case GCRY_AC_IO_STRING:
848           ac_io->writable.string.data = va_arg (ap, unsigned char **);
849           ac_io->writable.string.data_n = va_arg (ap, size_t *);
850           break;
851
852         case GCRY_AC_IO_CALLBACK:
853           ac_io->writable.callback.cb = va_arg (ap, gcry_ac_data_write_cb_t);
854           ac_io->writable.callback.opaque = va_arg (ap, void *);
855           break;
856         }
857       break;
858     }
859 }
860
861 void
862 gcry_ac_io_init_va (gcry_ac_io_t *ac_io,
863                     gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, va_list ap)
864 {
865   _gcry_ac_io_init_va (ac_io, mode, type, ap);
866 }
867
868 /* Initialize AC_IO according to MODE, TYPE and the variable list of
869    arguments.  The list of variable arguments to specify depends on
870    the given TYPE. */
871 static void
872 _gcry_ac_io_init (gcry_ac_io_t *ac_io,
873                   gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, ...)
874 {
875   va_list ap;
876
877   va_start (ap, type);
878   _gcry_ac_io_init_va (ac_io, mode, type, ap);
879   va_end (ap);
880 }
881
882
883 void
884 gcry_ac_io_init (gcry_ac_io_t *ac_io,
885                  gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, ...)
886 {
887   va_list ap;
888
889   va_start (ap, type);
890   _gcry_ac_io_init_va (ac_io, mode, type, ap);
891   va_end (ap);
892 }
893
894 /* Write to the IO object AC_IO BUFFER_N bytes from BUFFER.  Return
895    zero on success or error code.  */
896 static gcry_error_t
897 _gcry_ac_io_write (gcry_ac_io_t *ac_io, unsigned char *buffer, size_t buffer_n)
898 {
899   gcry_error_t err;
900
901   assert (ac_io->mode == GCRY_AC_IO_WRITABLE);
902   err = 0;
903
904   switch (ac_io->type)
905     {
906     case GCRY_AC_IO_STRING:
907       {
908         unsigned char *p;
909
910         if (*ac_io->writable.string.data)
911           {
912             p = gcry_realloc (*ac_io->writable.string.data,
913                               *ac_io->writable.string.data_n + buffer_n);
914             if (! p)
915               err = gcry_error_from_errno (errno);
916             else
917               {
918                 if (*ac_io->writable.string.data != p)
919                   *ac_io->writable.string.data = p;
920                 memcpy (p + *ac_io->writable.string.data_n, buffer, buffer_n);
921                 *ac_io->writable.string.data_n += buffer_n;
922               }
923           }
924         else
925           {
926             if (gcry_is_secure (buffer))
927               p = gcry_malloc_secure (buffer_n);
928             else
929               p = gcry_malloc (buffer_n);
930             if (! p)
931               err = gcry_error_from_errno (errno);
932             else
933               {
934                 memcpy (p, buffer, buffer_n);
935                 *ac_io->writable.string.data = p;
936                 *ac_io->writable.string.data_n = buffer_n;
937               }
938           }
939       }
940       break;
941
942     case GCRY_AC_IO_CALLBACK:
943       err = (*ac_io->writable.callback.cb) (ac_io->writable.callback.opaque,
944                                             buffer, buffer_n);
945       break;
946     }
947
948   return err;
949 }
950
951 /* Read *BUFFER_N bytes from the IO object AC_IO into BUFFER; NREAD
952    bytes have already been read from the object; on success, store the
953    amount of bytes read in *BUFFER_N; zero bytes read means EOF.
954    Return zero on success or error code.  */
955 static gcry_error_t
956 _gcry_ac_io_read (gcry_ac_io_t *ac_io,
957                   unsigned int nread, unsigned char *buffer, size_t *buffer_n)
958 {
959   gcry_error_t err;
960   
961   assert (ac_io->mode == GCRY_AC_IO_READABLE);
962   err = 0;
963
964   switch (ac_io->type)
965     {
966     case GCRY_AC_IO_STRING:
967       {
968         size_t bytes_available;
969         size_t bytes_to_read;
970         size_t bytes_wanted;
971
972         bytes_available = ac_io->readable.string.data_n - nread;
973         bytes_wanted = *buffer_n;
974
975         if (bytes_wanted > bytes_available)
976           bytes_to_read = bytes_available;
977         else
978           bytes_to_read = bytes_wanted;
979
980         memcpy (buffer, ac_io->readable.string.data + nread, bytes_to_read);
981         *buffer_n = bytes_to_read;
982         err = 0;
983         break;
984       }
985
986     case GCRY_AC_IO_CALLBACK:
987       err = (*ac_io->readable.callback.cb) (ac_io->readable.callback.opaque,
988                                             buffer, buffer_n);
989       break;
990     }
991
992   return err;
993 }
994
995 /* Read all data available from the IO object AC_IO into newly
996    allocated memory, storing an appropriate pointer in *BUFFER and the
997    amount of bytes read in *BUFFER_N.  Return zero on success or error
998    code.  */
999 static gcry_error_t
1000 _gcry_ac_io_read_all (gcry_ac_io_t *ac_io, unsigned char **buffer, size_t *buffer_n)
1001 {
1002   unsigned char *buffer_new;
1003   size_t buffer_new_n;
1004   unsigned char buf[BUFSIZ];
1005   size_t buf_n;
1006   unsigned char *p;
1007   gcry_error_t err;
1008
1009   buffer_new = NULL;
1010   buffer_new_n = 0;
1011
1012   while (1)
1013     {
1014       buf_n = sizeof (buf);
1015       err = _gcry_ac_io_read (ac_io, buffer_new_n, buf, &buf_n);
1016       if (err)
1017         break;
1018
1019       if (buf_n)
1020         {
1021           p = gcry_realloc (buffer_new, buffer_new_n + buf_n);
1022           if (! p)
1023             {
1024               err = gcry_error_from_errno (errno);
1025               break;
1026             }
1027           
1028           if (buffer_new != p)
1029             buffer_new = p;
1030
1031           memcpy (buffer_new + buffer_new_n, buf, buf_n);
1032           buffer_new_n += buf_n;
1033         }
1034       else
1035         break;
1036     }
1037   if (err)
1038     goto out;
1039
1040   *buffer_n = buffer_new_n;
1041   *buffer = buffer_new;
1042
1043  out:
1044
1045   if (err)
1046     gcry_free (buffer_new);
1047
1048   return err;
1049 }
1050
1051 /* Read data chunks from the IO object AC_IO until EOF, feeding them
1052    to the callback function CB.  Return zero on success or error
1053    code.  */
1054 static gcry_error_t
1055 _gcry_ac_io_process (gcry_ac_io_t *ac_io,
1056                      gcry_ac_data_write_cb_t cb, void *opaque)
1057 {
1058   unsigned char buffer[BUFSIZ];
1059   unsigned int nread;
1060   size_t buffer_n;
1061   gcry_error_t err;
1062
1063   nread = 0;
1064
1065   while (1)
1066     {
1067       buffer_n = sizeof (buffer);
1068       err = _gcry_ac_io_read (ac_io, nread, buffer, &buffer_n);
1069       if (err)
1070         break;
1071       if (buffer_n)
1072         {
1073           err = (*cb) (opaque, buffer, buffer_n);
1074           if (err)
1075             break;
1076           nread += buffer_n;
1077         }
1078       else
1079         break;
1080     }
1081
1082   return err;
1083 }
1084
1085 \f
1086
1087 /* 
1088  * Functions for converting data between the native ac and the
1089  * S-expression structure used by the pk interface.
1090  */
1091
1092 /* Extract the S-Expression DATA_SEXP into DATA under the control of
1093    TYPE and NAME.  This function assumes that S-Expressions are of the
1094    following structure:
1095
1096    (IDENTIFIER [...]
1097    (ALGORITHM <list of named MPI values>)) */
1098 gcry_error_t
1099 ac_data_extract (const char *identifier, const char *algorithm,
1100                  gcry_sexp_t sexp, gcry_ac_data_t *data)
1101 {
1102   gcry_error_t err;
1103   gcry_sexp_t value_sexp;
1104   gcry_sexp_t data_sexp;
1105   size_t data_sexp_n;
1106   gcry_mpi_t value_mpi;
1107   char *value_name;
1108   const char *data_raw;
1109   size_t data_raw_n;
1110   gcry_ac_data_t data_new;
1111   unsigned int i;
1112
1113   value_sexp = NULL;
1114   data_sexp = NULL;
1115   value_name = NULL;
1116   value_mpi = NULL;
1117   data_new = NULL;
1118
1119   /* Verify that the S-expression contains the correct identifier.  */
1120   data_raw = gcry_sexp_nth_data (sexp, 0, &data_raw_n);
1121   if ((! data_raw) || strncmp (identifier, data_raw, data_raw_n))
1122     {
1123       err = gcry_error (GPG_ERR_INV_SEXP);
1124       goto out;
1125     }
1126
1127   /* Extract inner S-expression.  */
1128   data_sexp = gcry_sexp_find_token (sexp, algorithm, 0);
1129   if (! data_sexp)
1130     {
1131       err = gcry_error (GPG_ERR_INV_SEXP);
1132       goto out;
1133     }
1134
1135   /* Count data elements.  */
1136   data_sexp_n = gcry_sexp_length (data_sexp);
1137   data_sexp_n--;
1138
1139   /* Allocate new data set.  */
1140   err = _gcry_ac_data_new (&data_new);
1141   if (err)
1142     goto out;
1143
1144   /* Iterate through list of data elements and add them to the data
1145      set.  */
1146   for (i = 0; i < data_sexp_n; i++)
1147     {
1148       /* Get the S-expression of the named MPI, that contains the name
1149          and the MPI value.  */
1150       value_sexp = gcry_sexp_nth (data_sexp, i + 1);
1151       if (! value_sexp)
1152         {
1153           err = gcry_error (GPG_ERR_INV_SEXP);
1154           break;
1155         }
1156
1157       /* Extract the name.  */
1158       data_raw = gcry_sexp_nth_data (value_sexp, 0, &data_raw_n);
1159       if (! data_raw)
1160         {
1161           err = gcry_error (GPG_ERR_INV_SEXP);
1162           break;
1163         }
1164
1165       /* Extract the MPI value.  */
1166       value_mpi = gcry_sexp_nth_mpi (value_sexp, 1, GCRYMPI_FMT_USG);
1167       if (! value_mpi)
1168         {
1169           err = gcry_error (GPG_ERR_INTERNAL); /* FIXME? */
1170           break;
1171         }
1172
1173       /* Duplicate the name.  */
1174       value_name = gcry_malloc (data_raw_n + 1);
1175       if (! value_name)
1176         {
1177           err = gcry_error_from_errno (errno);
1178           break;
1179         }
1180       strncpy (value_name, data_raw, data_raw_n);
1181       value_name[data_raw_n] = 0;
1182
1183       err = _gcry_ac_data_set (data_new, GCRY_AC_FLAG_DEALLOC, value_name, value_mpi);
1184       if (err)
1185         break;
1186
1187       gcry_sexp_release (value_sexp);
1188       value_sexp = NULL;
1189       value_name = NULL;
1190       value_mpi = NULL;
1191     }
1192   if (err)
1193     goto out;
1194
1195   /* Copy out.  */
1196   *data = data_new;
1197
1198  out:
1199
1200   /* Deallocate resources.  */
1201   if (err)
1202     {
1203       _gcry_ac_data_destroy (data_new);
1204       gcry_mpi_release (value_mpi);
1205       gcry_free (value_name);
1206       gcry_sexp_release (value_sexp);
1207     }
1208   gcry_sexp_release (data_sexp);
1209
1210   return err;
1211 }
1212
1213 /* Construct an S-expression from the DATA and store it in
1214    DATA_SEXP. The S-expression will be of the following structure:
1215
1216    (IDENTIFIER [(flags [...])]
1217    (ALGORITHM <list of named MPI values>))  */
1218 static gcry_error_t
1219 ac_data_construct (const char *identifier, int include_flags,
1220                    unsigned int flags, const char *algorithm,
1221                    gcry_ac_data_t data, gcry_sexp_t *sexp)
1222 {
1223   unsigned int data_length;
1224   gcry_sexp_t sexp_new;
1225   gcry_error_t err;
1226   size_t sexp_format_n;
1227   char *sexp_format;
1228   void **arg_list;
1229   unsigned int i;
1230
1231   arg_list = NULL;
1232   sexp_new = NULL;
1233   sexp_format = NULL;
1234
1235   /* We build a list of arguments to pass to
1236      gcry_sexp_build_array().  */
1237   data_length = _gcry_ac_data_length (data);
1238   arg_list = gcry_malloc (sizeof (*arg_list) * (data_length * 2));
1239   if (! arg_list)
1240     {
1241       err = gcry_error_from_errno (errno);
1242       goto out;
1243     }
1244
1245   /* Fill list with MPIs.  */
1246   for (i = 0; i < data_length; i++)
1247     {
1248       /* FIXME!! */
1249       arg_list[(i * 2) + 0] = (data->data[i].name
1250                                ? (void **) &data->data[i].name
1251                                : (void **) &data->data[i].name_provided);
1252       arg_list[(i * 2) + 1] = &data->data[i].mpi;
1253     }
1254
1255   /* Calculate size of format string.  */
1256   sexp_format_n = (3
1257                    + (include_flags ? 7 : 0)
1258                    + (algorithm ? (2 + strlen (algorithm)) : 0)
1259                    + strlen (identifier));
1260
1261   for (i = 0; i < data_length; i++)
1262     /* Per-element sizes.  */
1263     sexp_format_n += 6;
1264
1265   if (include_flags)
1266     /* Add flags.  */
1267     for (i = 0; i < DIM (ac_flags); i++)
1268       if (flags & ac_flags[i].number)
1269         sexp_format_n += strlen (ac_flags[i].string) + 1;
1270
1271   /* Done.  */
1272   sexp_format = gcry_malloc (sexp_format_n);
1273   if (! sexp_format)
1274     {
1275       err = gcry_error_from_errno (errno);
1276       goto out;
1277     }
1278
1279   /* Construct the format string.  */
1280
1281   *sexp_format = 0;
1282   strcat (sexp_format, "(");
1283   strcat (sexp_format, identifier);
1284   if (include_flags)
1285     {
1286       strcat (sexp_format, "(flags");
1287       for (i = 0; i < DIM (ac_flags); i++)
1288         if (flags & ac_flags[i].number)
1289           {
1290             strcat (sexp_format, " ");
1291             strcat (sexp_format, ac_flags[i].string);
1292           }
1293       strcat (sexp_format, ")");
1294     }
1295   if (algorithm)
1296     {
1297       strcat (sexp_format, "(");
1298       strcat (sexp_format, algorithm);
1299     }
1300   for (i = 0; i < data_length; i++)
1301     strcat (sexp_format, "(%s%m)");
1302   if (algorithm)
1303     strcat (sexp_format, ")");
1304   strcat (sexp_format, ")");
1305
1306   /* Create final S-expression.  */
1307   err = gcry_sexp_build_array (&sexp_new, NULL, sexp_format, arg_list);
1308   if (err)
1309     goto out;
1310
1311   *sexp = sexp_new;
1312
1313  out:
1314
1315   /* Deallocate resources.  */
1316   gcry_free (sexp_format);
1317   gcry_free (arg_list);
1318   if (err)
1319     gcry_sexp_release (sexp_new);
1320
1321   return err;
1322 }
1323
1324 \f
1325
1326 /* 
1327  * Wrapper macros.
1328  */
1329
1330
1331 \f
1332
1333 /*
1334  * Handle management.
1335  */
1336
1337 /* Creates a new handle for the algorithm ALGORITHM and stores it in
1338    HANDLE.  FLAGS is not used yet.  */
1339 gcry_error_t
1340 _gcry_ac_open (gcry_ac_handle_t *handle,
1341                gcry_ac_id_t algorithm, unsigned int flags)
1342 {
1343   gcry_ac_handle_t handle_new;
1344   const char *algorithm_name;
1345   gcry_module_t module;
1346   gcry_error_t err;
1347
1348   *handle = NULL;
1349   module = NULL;
1350
1351   /* Get name.  */
1352   algorithm_name = _gcry_pk_aliased_algo_name (algorithm);
1353   if (! algorithm_name)
1354     {
1355       err = gcry_error (GPG_ERR_PUBKEY_ALGO);
1356       goto out;
1357     }
1358
1359   /* Acquire reference to the pubkey module.  */
1360   err = _gcry_pk_module_lookup (algorithm, &module);
1361   if (err)
1362     goto out;
1363   
1364   /* Allocate.  */
1365   handle_new = gcry_malloc (sizeof (*handle_new));
1366   if (! handle_new)
1367     {
1368       err = gcry_error_from_errno (errno);
1369       goto out;
1370     }
1371
1372   /* Done.  */
1373   handle_new->algorithm = algorithm;
1374   handle_new->algorithm_name = algorithm_name;
1375   handle_new->flags = flags;
1376   handle_new->module = module;
1377   *handle = handle_new;
1378
1379  out:
1380   
1381   /* Deallocate resources.  */
1382   if (err)
1383     _gcry_pk_module_release (module);
1384
1385   return err;
1386 }
1387
1388 gcry_error_t
1389 gcry_ac_open (gcry_ac_handle_t *handle,
1390               gcry_ac_id_t algorithm, unsigned int flags)
1391 {
1392   gcry_error_t err;
1393
1394   err = _gcry_ac_open (handle, algorithm, flags);
1395
1396   return gcry_error (err);
1397 }
1398
1399 /* Destroys the handle HANDLE.  */
1400 void
1401 _gcry_ac_close (gcry_ac_handle_t handle)
1402 {
1403   /* Release reference to pubkey module.  */
1404   if (handle)
1405     {
1406       _gcry_pk_module_release (handle->module);
1407       gcry_free (handle);
1408     }
1409 }
1410
1411 void
1412 gcry_ac_close (gcry_ac_handle_t handle)
1413 {
1414   _gcry_ac_close (handle);
1415 }
1416
1417 \f
1418
1419 /* 
1420  * Key management.
1421  */
1422
1423 /* Initialize a key from a given data set.  */
1424 /* FIXME/Damn: the argument HANDLE is not only unnecessary, it is
1425    completely WRONG here.  */
1426 gcry_error_t
1427 _gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
1428                    gcry_ac_key_type_t type, gcry_ac_data_t data)
1429 {
1430   gcry_ac_data_t data_new;
1431   gcry_ac_key_t key_new;
1432   gcry_error_t err;
1433
1434   /* Allocate.  */
1435   key_new = gcry_malloc (sizeof (*key_new));
1436   if (! key_new)
1437     {
1438       err = gcry_error_from_errno (errno);
1439       goto out;
1440     }
1441
1442   /* Copy data set.  */
1443   err = _gcry_ac_data_copy (&data_new, data);
1444   if (err)
1445     goto out;
1446
1447   /* Done.  */
1448   key_new->data = data_new;
1449   key_new->type = type;
1450   *key = key_new;
1451
1452  out:
1453
1454   if (err)
1455     /* Deallocate resources.  */
1456     gcry_free (key_new);
1457
1458   return err;
1459 }
1460
1461 gcry_error_t
1462 gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
1463                   gcry_ac_key_type_t type, gcry_ac_data_t data)
1464 {
1465   gcry_error_t err;
1466
1467   err = _gcry_ac_key_init (key, handle, type, data);
1468
1469   return gcry_error (err);
1470 }
1471
1472 /* Generates a new key pair via the handle HANDLE of NBITS bits and
1473    stores it in KEY_PAIR.  In case non-standard settings are wanted, a
1474    pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
1475    matching the selected algorithm, can be given as KEY_SPEC.
1476    MISC_DATA is not used yet.  */
1477 gcry_error_t
1478 _gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits,
1479                             void *key_spec,
1480                             gcry_ac_key_pair_t *key_pair,
1481                             gcry_mpi_t **misc_data)
1482 {
1483   gcry_sexp_t genkey_sexp_request;
1484   gcry_sexp_t genkey_sexp_reply;
1485   gcry_ac_data_t key_data_secret;
1486   gcry_ac_data_t key_data_public;
1487   gcry_ac_key_pair_t key_pair_new;
1488   gcry_ac_key_t key_secret;
1489   gcry_ac_key_t key_public;
1490   gcry_sexp_t key_sexp;
1491   gcry_error_t err;
1492   char *genkey_format;
1493   size_t genkey_format_n;
1494   void **arg_list;
1495   size_t arg_list_n;
1496   unsigned int i;
1497   unsigned int j;
1498
1499   key_data_secret = NULL;
1500   key_data_public = NULL;
1501   key_secret = NULL;
1502   key_public = NULL;
1503   genkey_format = NULL;
1504   arg_list = NULL;
1505   genkey_sexp_request = NULL;
1506   genkey_sexp_reply = NULL;
1507
1508   /* Allocate key pair.  */
1509   key_pair_new = gcry_malloc (sizeof (struct gcry_ac_key_pair));
1510   if (! key_pair_new)
1511     {
1512       err = gcry_error_from_errno (errno);
1513       goto out;
1514     }
1515
1516   /* Allocate keys.  */
1517   key_secret = gcry_malloc (sizeof (*key_secret));
1518   if (! key_secret)
1519     {
1520       err = gcry_error_from_errno (errno);
1521       goto out;
1522     }
1523   key_public = gcry_malloc (sizeof (*key_public));
1524   if (! key_public)
1525     {
1526       err = gcry_error_from_errno (errno);
1527       goto out;
1528     }
1529
1530   /* Calculate size of the format string, that is used for creating
1531      the request S-expression.  */
1532   genkey_format_n = 22;
1533
1534   /* Respect any relevant algorithm specific commands.  */
1535   if (key_spec)
1536     for (i = 0; i < DIM (ac_key_generate_specs); i++)
1537       if (handle->algorithm == ac_key_generate_specs[i].algorithm)
1538         genkey_format_n += 6;
1539
1540   /* Create format string.  */
1541   genkey_format = gcry_malloc (genkey_format_n);
1542   if (! genkey_format)
1543     {
1544       err = gcry_error_from_errno (errno);
1545       goto out;
1546     }
1547
1548   /* Fill format string.  */
1549   *genkey_format = 0;
1550   strcat (genkey_format, "(genkey(%s(nbits%d)");
1551   if (key_spec)
1552     for (i = 0; i < DIM (ac_key_generate_specs); i++)
1553       if (handle->algorithm == ac_key_generate_specs[i].algorithm)
1554         strcat (genkey_format, "(%s%m)");
1555   strcat (genkey_format, "))");
1556
1557   /* Build list of argument pointers, the algorithm name and the nbits
1558      are always needed.  */
1559   arg_list_n = 2;
1560
1561   /* Now the algorithm specific arguments.  */
1562   if (key_spec)
1563     for (i = 0; i < DIM (ac_key_generate_specs); i++)
1564       if (handle->algorithm == ac_key_generate_specs[i].algorithm)
1565         arg_list_n += 2;
1566
1567   /* Allocate list.  */
1568   arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n);
1569   if (! arg_list)
1570     {
1571       err = gcry_error_from_errno (errno);
1572       goto out;
1573     }
1574
1575   arg_list[0] = (void *) &handle->algorithm_name;
1576   arg_list[1] = (void *) &nbits;
1577   if (key_spec)
1578     for (j = 2, i = 0; i < DIM (ac_key_generate_specs); i++)
1579       if (handle->algorithm == ac_key_generate_specs[i].algorithm)
1580         {
1581           /* Add name of this specification flag and the
1582              according member of the spec strucuture.  */
1583           arg_list[j++] = (void *)(&ac_key_generate_specs[i].name);
1584           arg_list[j++] = (void *)
1585             (((char *) key_spec)
1586              + ac_key_generate_specs[i].offset);
1587           /* FIXME: above seems to suck.  */
1588         }
1589
1590   /* Construct final request S-expression.  */
1591   err = gcry_sexp_build_array (&genkey_sexp_request,
1592                                NULL, genkey_format, arg_list);
1593   if (err)
1594     goto out;
1595
1596   /* Perform genkey operation.  */
1597   err = gcry_pk_genkey (&genkey_sexp_reply, genkey_sexp_request);
1598   if (err)
1599     goto out;
1600
1601   key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "private-key", 0);
1602   if (! key_sexp)
1603     {
1604       err = gcry_error (GPG_ERR_INTERNAL);
1605       goto out;
1606     }
1607   err = ac_data_extract ("private-key", handle->algorithm_name,
1608                          key_sexp, &key_data_secret);
1609   if (err)
1610     goto out;
1611
1612   gcry_sexp_release (key_sexp);
1613   key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "public-key", 0);
1614   if (! key_sexp)
1615     {
1616       err = gcry_error (GPG_ERR_INTERNAL);
1617       goto out;
1618     }
1619   err = ac_data_extract ("public-key", handle->algorithm_name,
1620                          key_sexp, &key_data_public);
1621   if (err)
1622     goto out;
1623
1624   /* Done.  */
1625
1626   key_secret->type = GCRY_AC_KEY_SECRET;
1627   key_secret->data = key_data_secret;
1628   key_public->type = GCRY_AC_KEY_PUBLIC;
1629   key_public->data = key_data_public;
1630   key_pair_new->secret = key_secret;
1631   key_pair_new->public = key_public;
1632   *key_pair = key_pair_new;
1633
1634  out:
1635
1636   /* Deallocate resources.  */
1637   
1638   gcry_free (genkey_format);
1639   gcry_free (arg_list);
1640   gcry_sexp_release (genkey_sexp_request);
1641   gcry_sexp_release (genkey_sexp_reply);
1642   if (err)
1643     {
1644       _gcry_ac_data_destroy (key_data_secret);
1645       _gcry_ac_data_destroy (key_data_public);
1646       gcry_free (key_secret);
1647       gcry_free (key_public);
1648       gcry_free (key_pair_new);
1649     }
1650
1651   return err;
1652 }
1653
1654 gcry_error_t
1655 gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits, void *key_spec,
1656                            gcry_ac_key_pair_t *key_pair, gcry_mpi_t **misc_data)
1657 {
1658   gcry_error_t err;
1659
1660   err = _gcry_ac_key_pair_generate (handle, nbits, key_spec, key_pair, misc_data);
1661
1662   return gcry_error (err);
1663 }
1664
1665 /* Returns the key of type WHICH out of the key pair KEY_PAIR.  */
1666 gcry_ac_key_t
1667 _gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair, gcry_ac_key_type_t which)
1668 {
1669   gcry_ac_key_t key;
1670
1671   switch (which)
1672     {
1673     case GCRY_AC_KEY_SECRET:
1674       key = key_pair->secret;
1675       break;
1676
1677     case GCRY_AC_KEY_PUBLIC:
1678       key = key_pair->public;
1679       break;
1680
1681     default:
1682       key = NULL;
1683       break;
1684     }
1685
1686   return key;
1687 }
1688
1689 gcry_ac_key_t
1690 gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair, gcry_ac_key_type_t which)
1691 {
1692   gcry_ac_key_t key;
1693
1694   key = _gcry_ac_key_pair_extract (key_pair, which);
1695
1696   return key;
1697 }
1698
1699 /* Destroys the key KEY.  */
1700 void
1701 _gcry_ac_key_destroy (gcry_ac_key_t key)
1702 {
1703   unsigned int i;
1704
1705   if (key)
1706     {
1707       if (key->data)
1708         {
1709           for (i = 0; i < key->data->data_n; i++)
1710             if (key->data->data[i].mpi != NULL)
1711               gcry_mpi_release (key->data->data[i].mpi);
1712           gcry_free (key->data);
1713         }
1714       gcry_free (key);
1715     }
1716 }
1717
1718 void
1719 gcry_ac_key_destroy (gcry_ac_key_t key)
1720 {
1721   _gcry_ac_key_destroy (key);
1722 }
1723
1724 /* Destroys the key pair KEY_PAIR.  */
1725 void
1726 _gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
1727 {
1728   if (key_pair)
1729     {
1730       gcry_ac_key_destroy (key_pair->secret);
1731       gcry_ac_key_destroy (key_pair->public);
1732       gcry_free (key_pair);
1733     }
1734 }
1735
1736 void
1737 gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
1738 {
1739   _gcry_ac_key_pair_destroy (key_pair);
1740 }
1741
1742 /* Returns the data set contained in the key KEY.  */
1743 gcry_ac_data_t
1744 _gcry_ac_key_data_get (gcry_ac_key_t key)
1745 {
1746   return key->data;
1747 }
1748
1749 gcry_ac_data_t
1750 gcry_ac_key_data_get (gcry_ac_key_t key)
1751 {
1752   gcry_ac_data_t data;
1753
1754   data = _gcry_ac_key_data_get (key);
1755
1756   return data;
1757 }
1758
1759 /* Verifies that the key KEY is sane via HANDLE.  */
1760 gcry_error_t
1761 _gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
1762 {
1763   gcry_sexp_t key_sexp;
1764   gcry_error_t err;
1765
1766   key_sexp = NULL;
1767   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
1768                            handle->algorithm_name, key->data, &key_sexp);
1769   if (err)
1770     goto out;
1771
1772   err = gcry_pk_testkey (key_sexp);
1773
1774  out:
1775
1776   gcry_sexp_release (key_sexp);
1777
1778   return gcry_error (err);
1779 }
1780
1781 gcry_error_t
1782 gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
1783 {
1784   gcry_error_t err;
1785
1786   err = _gcry_ac_key_test (handle, key);
1787
1788   return gcry_error (err);
1789 }
1790
1791 /* Stores the number of bits of the key KEY in NBITS via HANDLE.  */
1792 gcry_error_t
1793 _gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
1794                         gcry_ac_key_t key, unsigned int *nbits)
1795 {
1796   gcry_sexp_t key_sexp;
1797   gcry_error_t err;
1798   unsigned int n;
1799
1800   key_sexp = NULL;
1801
1802   err = ac_data_construct (ac_key_identifiers[key->type],
1803                            0, 0, handle->algorithm_name, key->data, &key_sexp);
1804   if (err)
1805     goto out;
1806
1807   n = gcry_pk_get_nbits (key_sexp);
1808   if (! n)
1809     {
1810       err = gcry_error (GPG_ERR_PUBKEY_ALGO);
1811       goto out;
1812     }
1813
1814   *nbits = n;
1815
1816  out:
1817
1818   gcry_sexp_release (key_sexp);
1819
1820   return err;
1821 }
1822
1823 gcry_error_t
1824 gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
1825                        gcry_ac_key_t key, unsigned int *nbits)
1826 {
1827   gcry_error_t err;
1828
1829   err = _gcry_ac_key_get_nbits (handle, key, nbits);
1830
1831   return gcry_error (err);
1832 }
1833
1834 /* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
1835    HANDLE.  */
1836 gcry_error_t
1837 _gcry_ac_key_get_grip (gcry_ac_handle_t handle,
1838                        gcry_ac_key_t key, unsigned char *key_grip)
1839 {
1840   gcry_sexp_t key_sexp;
1841   gcry_error_t err;
1842   unsigned char *ret;
1843
1844   key_sexp = NULL;
1845   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
1846                            handle->algorithm_name, key->data, &key_sexp);
1847   if (err)
1848     goto out;
1849
1850   ret = gcry_pk_get_keygrip (key_sexp, key_grip);
1851   if (! ret)
1852     {
1853       err = gcry_error (GPG_ERR_INV_OBJ);
1854       goto out;
1855     }
1856
1857   err = 0;
1858
1859  out:
1860
1861   gcry_sexp_release (key_sexp);
1862
1863   return err;
1864 }
1865
1866 gcry_error_t
1867 gcry_ac_key_get_grip (gcry_ac_handle_t handle,
1868                       gcry_ac_key_t key, unsigned char *key_grip)
1869 {
1870   gcry_error_t err;
1871
1872   err = _gcry_ac_key_get_grip (handle, key, key_grip);
1873
1874   return gcry_error (err);
1875 }
1876
1877
1878 \f
1879
1880 /* 
1881  * Functions performing cryptographic operations.
1882  */
1883
1884 /* Encrypts the plain text MPI value DATA_PLAIN with the key public
1885    KEY under the control of the flags FLAGS and stores the resulting
1886    data set into DATA_ENCRYPTED.  */
1887 gcry_error_t
1888 _gcry_ac_data_encrypt (gcry_ac_handle_t handle,
1889                        unsigned int flags,
1890                        gcry_ac_key_t key,
1891                        gcry_mpi_t data_plain,
1892                        gcry_ac_data_t *data_encrypted)
1893 {
1894   gcry_ac_data_t data_encrypted_new;
1895   gcry_ac_data_t data_value;
1896   gcry_sexp_t sexp_request;
1897   gcry_sexp_t sexp_reply;
1898   gcry_sexp_t sexp_key;
1899   gcry_error_t err;
1900
1901   data_encrypted_new = NULL;
1902   sexp_request = NULL;
1903   sexp_reply = NULL;
1904   data_value = NULL;
1905   sexp_key = NULL;
1906
1907   if (key->type != GCRY_AC_KEY_PUBLIC)
1908     {
1909       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
1910       goto out;
1911     }
1912
1913   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
1914                            handle->algorithm_name, key->data, &sexp_key);
1915   if (err)
1916     goto out;
1917
1918   err = _gcry_ac_data_new (&data_value);
1919   if (err)
1920     goto out;
1921
1922   err = _gcry_ac_data_set (data_value, 0, "value", data_plain);
1923   if (err)
1924     goto out;
1925
1926   err = ac_data_construct ("data", 1, flags, handle->algorithm_name,
1927                            data_value, &sexp_request);
1928   if (err)
1929     goto out;
1930
1931   /* FIXME: error vs. errcode? */
1932
1933   err = gcry_pk_encrypt (&sexp_reply, sexp_request, sexp_key);
1934   if (err)
1935     goto out;
1936
1937   /* Extract data.  */
1938   err = ac_data_extract ("enc-val", handle->algorithm_name,
1939                          sexp_reply, &data_encrypted_new);
1940   if (err)
1941     goto out;
1942
1943   *data_encrypted = data_encrypted_new;
1944
1945  out:
1946
1947   /* Deallocate resources.  */
1948
1949   gcry_sexp_release (sexp_request);
1950   gcry_sexp_release (sexp_reply);
1951   gcry_sexp_release (sexp_key);
1952   _gcry_ac_data_destroy (data_value);
1953
1954   return err;
1955 }
1956
1957 gcry_error_t
1958 gcry_ac_data_encrypt (gcry_ac_handle_t handle,
1959                       unsigned int flags,
1960                       gcry_ac_key_t key,
1961                       gcry_mpi_t data_plain,
1962                       gcry_ac_data_t *data_encrypted)
1963 {
1964   gcry_error_t err;
1965
1966   err = _gcry_ac_data_encrypt (handle, flags, key, data_plain, data_encrypted);
1967
1968   return gcry_error (err);
1969 }
1970
1971 /* Decrypts the encrypted data contained in the data set
1972    DATA_ENCRYPTED with the secret key KEY under the control of the
1973    flags FLAGS and stores the resulting plain text MPI value in
1974    DATA_PLAIN.  */
1975 gcry_error_t
1976 _gcry_ac_data_decrypt (gcry_ac_handle_t handle,
1977                        unsigned int flags,
1978                        gcry_ac_key_t key,
1979                        gcry_mpi_t *data_plain,
1980                        gcry_ac_data_t data_encrypted)
1981 {
1982   gcry_mpi_t data_decrypted;
1983   gcry_sexp_t sexp_request;
1984   gcry_sexp_t sexp_reply;
1985   gcry_sexp_t sexp_value;
1986   gcry_sexp_t sexp_key;
1987   gcry_error_t err;
1988
1989   sexp_request = NULL;
1990   sexp_reply = NULL;
1991   sexp_value = NULL;
1992   sexp_key = NULL;
1993
1994   if (key->type != GCRY_AC_KEY_SECRET)
1995     {
1996       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
1997       goto out;
1998     }
1999
2000   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
2001                            handle->algorithm_name, key->data, &sexp_key);
2002   if (err)
2003     goto out;
2004
2005   /* Create S-expression from data.  */
2006   err = ac_data_construct ("enc-val", 1, flags, handle->algorithm_name,
2007                            data_encrypted, &sexp_request);
2008   if (err)
2009     goto out;
2010
2011   /* Decrypt.  */
2012   err = gcry_pk_decrypt (&sexp_reply, sexp_request, sexp_key);
2013   if (err)
2014     goto out;
2015
2016   /* Extract plain text. */
2017   sexp_value = gcry_sexp_find_token (sexp_reply, "value", 0);
2018   if (! sexp_value)
2019     {
2020       /* FIXME?  */
2021       err = gcry_error (GPG_ERR_GENERAL);
2022       goto out;
2023     }
2024
2025   data_decrypted = gcry_sexp_nth_mpi (sexp_value, 1, GCRYMPI_FMT_USG);
2026   if (! data_decrypted)
2027     {
2028       err = gcry_error (GPG_ERR_GENERAL);
2029       goto out;
2030     }
2031
2032   *data_plain = data_decrypted;
2033
2034  out:
2035
2036   /* Deallocate resources.  */
2037   gcry_sexp_release (sexp_request);
2038   gcry_sexp_release (sexp_reply);
2039   gcry_sexp_release (sexp_value);
2040   gcry_sexp_release (sexp_key);
2041
2042   return gcry_error (err);
2043
2044 }
2045
2046 gcry_error_t
2047 gcry_ac_data_decrypt (gcry_ac_handle_t handle,
2048                       unsigned int flags,
2049                       gcry_ac_key_t key,
2050                       gcry_mpi_t *data_plain,
2051                       gcry_ac_data_t data_encrypted)
2052 {
2053   gcry_error_t err;
2054
2055   err = _gcry_ac_data_decrypt (handle, flags, key, data_plain, data_encrypted);
2056
2057   return gcry_error (err);
2058 }
2059
2060 /* Signs the data contained in DATA with the secret key KEY and stores
2061    the resulting signature data set in DATA_SIGNATURE.  */
2062 gcry_error_t
2063 _gcry_ac_data_sign (gcry_ac_handle_t handle,
2064                     gcry_ac_key_t key,
2065                     gcry_mpi_t data,
2066                     gcry_ac_data_t *data_signature)
2067 {
2068   gcry_ac_data_t data_signed;
2069   gcry_ac_data_t data_value;
2070   gcry_sexp_t sexp_request;
2071   gcry_sexp_t sexp_reply;
2072   gcry_sexp_t sexp_key;
2073   gcry_error_t err;
2074
2075   data_signed = NULL;
2076   data_value = NULL;
2077   sexp_request = NULL;
2078   sexp_reply = NULL;
2079   sexp_key = NULL;
2080
2081   if (key->type != GCRY_AC_KEY_SECRET)
2082     {
2083       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
2084       goto out;
2085     }
2086
2087   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
2088                            handle->algorithm_name, key->data, &sexp_key);
2089   if (err)
2090     goto out;
2091
2092   err = _gcry_ac_data_new (&data_value);
2093   if (err)
2094     goto out;
2095
2096   err = _gcry_ac_data_set (data_value, 0, "value", data);
2097   if (err)
2098     goto out;
2099
2100   /* Create S-expression holding the data.  */
2101   err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_request);
2102   if (err)
2103     goto out;
2104
2105   /* Sign.  */
2106   err = gcry_pk_sign (&sexp_reply, sexp_request, sexp_key);
2107   if (err)
2108     goto out;
2109
2110   /* Extract data.  */
2111   err = ac_data_extract ("sig-val", handle->algorithm_name,
2112                          sexp_reply, &data_signed);
2113   if (err)
2114     goto out;
2115
2116   /* Done.  */
2117   *data_signature = data_signed;
2118
2119  out:
2120
2121   gcry_sexp_release (sexp_request);
2122   gcry_sexp_release (sexp_reply);
2123   gcry_sexp_release (sexp_key);
2124   _gcry_ac_data_destroy (data_value);
2125
2126   return gcry_error (err);
2127 }
2128
2129 gcry_error_t
2130 gcry_ac_data_sign (gcry_ac_handle_t handle,
2131                    gcry_ac_key_t key,
2132                    gcry_mpi_t data,
2133                    gcry_ac_data_t *data_signature)
2134 {
2135   gcry_error_t err;
2136
2137   err = _gcry_ac_data_sign (handle, key, data, data_signature);
2138
2139   return gcry_error (err);
2140 }
2141
2142
2143 /* Verifies that the signature contained in the data set
2144    DATA_SIGNATURE is indeed the result of signing the data contained
2145    in DATA with the secret key belonging to the public key KEY.  */
2146 gcry_error_t
2147 _gcry_ac_data_verify (gcry_ac_handle_t handle,
2148                       gcry_ac_key_t key,
2149                       gcry_mpi_t data,
2150                       gcry_ac_data_t data_signature)
2151 {
2152   gcry_sexp_t sexp_signature;
2153   gcry_ac_data_t data_value;
2154   gcry_sexp_t sexp_data;
2155   gcry_sexp_t sexp_key;
2156   gcry_error_t err;
2157
2158   sexp_signature = NULL;
2159   data_value = NULL;
2160   sexp_data = NULL;
2161   sexp_key = NULL;
2162
2163   err = ac_data_construct ("public-key", 0, 0,
2164                            handle->algorithm_name, key->data, &sexp_key);
2165   if (err)
2166     goto out;
2167
2168   if (key->type != GCRY_AC_KEY_PUBLIC)
2169     {
2170       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
2171       goto out;
2172     }
2173
2174   /* Construct S-expression holding the signature data.  */
2175   err = ac_data_construct ("sig-val", 1, 0, handle->algorithm_name,
2176                            data_signature, &sexp_signature);
2177   if (err)
2178     goto out;
2179
2180   err = _gcry_ac_data_new (&data_value);
2181   if (err)
2182     goto out;
2183
2184   err = _gcry_ac_data_set (data_value, 0, "value", data);
2185   if (err)
2186     goto out;
2187
2188   /* Construct S-expression holding the data.  */
2189   err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_data);
2190   if (err)
2191     goto out;
2192
2193   /* Verify signature.  */
2194   err = gcry_pk_verify (sexp_signature, sexp_data, sexp_key);
2195
2196  out:
2197
2198   gcry_sexp_release (sexp_signature);
2199   gcry_sexp_release (sexp_data);
2200   gcry_sexp_release (sexp_key);
2201   _gcry_ac_data_destroy (data_value);
2202
2203   return gcry_error (err);
2204 }
2205
2206 gcry_error_t
2207 gcry_ac_data_verify (gcry_ac_handle_t handle,
2208                      gcry_ac_key_t key,
2209                      gcry_mpi_t data,
2210                      gcry_ac_data_t data_signature)
2211 {
2212   gcry_error_t err;
2213
2214   err = _gcry_ac_data_verify (handle, key, data, data_signature);
2215
2216   return gcry_error (err);
2217 }
2218
2219 \f
2220
2221
2222 /*
2223  * Implementation of encoding methods (em).
2224  */
2225
2226 /* Type for functions that encode or decode (hence the name) a
2227    message.  */
2228 typedef gcry_error_t (*gcry_ac_em_dencode_t) (unsigned int flags,
2229                                                  void *options,
2230                                                  gcry_ac_io_t *ac_io_read,
2231                                                  gcry_ac_io_t *ac_io_write);
2232
2233 /* Fill the buffer BUFFER which is BUFFER_N bytes long with non-zero
2234    random bytes of random level LEVEL.  */
2235 static void
2236 em_randomize_nonzero (unsigned char *buffer, size_t buffer_n,
2237                       gcry_random_level_t level)
2238 {
2239   unsigned char *buffer_rand;
2240   unsigned int buffer_rand_n;
2241   unsigned int zeros;
2242   unsigned int i;
2243   unsigned int j;
2244
2245   for (i = 0; i < buffer_n; i++)
2246     buffer[i] = 0;
2247   
2248   do
2249     {
2250       /* Count zeros.  */
2251       for (i = zeros = 0; i < buffer_n; i++)
2252         if (! buffer[i])
2253           zeros++;
2254
2255       if (zeros)
2256         {
2257           /* Get random bytes.  */
2258           buffer_rand_n = zeros + (zeros / 128);
2259           buffer_rand = gcry_random_bytes_secure (buffer_rand_n, level);
2260
2261           /* Substitute zeros with non-zero random bytes.  */
2262           for (i = j = 0; zeros && (i < buffer_n) && (j < buffer_rand_n); i++)
2263             if (! buffer[i])
2264               {
2265                 while ((j < buffer_rand_n) && (! buffer_rand[j]))
2266                   j++;
2267                 if (j < buffer_rand_n)
2268                   {
2269                     buffer[i] = buffer_rand[j++];
2270                     zeros--;
2271                   }
2272                 else
2273                   break;
2274               }
2275           gcry_free (buffer_rand);
2276         }
2277     }
2278   while (zeros);
2279 }
2280
2281 /* Encode a message according to the Encoding Method for Encryption
2282    `PKCS-V1_5' (EME-PKCS-V1_5).  */
2283 static gcry_error_t
2284 eme_pkcs_v1_5_encode (unsigned int flags, void *opts,
2285                       gcry_ac_io_t *ac_io_read,
2286                       gcry_ac_io_t *ac_io_write)
2287 {
2288   gcry_ac_eme_pkcs_v1_5_t *options;
2289   gcry_error_t err;
2290   unsigned char *buffer;
2291   unsigned char *ps;
2292   unsigned char *m;
2293   size_t m_n;
2294   unsigned int ps_n;
2295   unsigned int k;
2296
2297   options = opts;
2298   buffer = NULL;
2299   m = NULL;
2300
2301   err = _gcry_ac_io_read_all (ac_io_read, &m, &m_n);
2302   if (err)
2303     goto out;
2304
2305   /* Figure out key length in bytes.  */
2306   err = _gcry_ac_key_get_nbits (options->handle, options->key, &k);
2307   if (err)
2308     goto out;
2309
2310   k /= 8;
2311   if (m_n > k - 11)
2312     {
2313       /* Key is too short for message.  */
2314       err = gcry_error (GPG_ERR_TOO_SHORT);
2315       goto out;
2316     }
2317
2318   /* According to this encoding method, the first byte of the encoded
2319      message is zero.  This byte will be lost anyway, when the encoded
2320      message is to be converted into an MPI, that's why we skip
2321      it.  */
2322
2323   /* Allocate buffer.  */
2324   buffer = gcry_malloc (k - 1);
2325   if (! buffer)
2326     {
2327       err = gcry_error_from_errno (errno);
2328       goto out;
2329     }
2330
2331   /* Generate an octet string PS of length k - mLen - 3 consisting
2332      of pseudorandomly generated nonzero octets.  The length of PS
2333      will be at least eight octets.  */
2334   ps_n = k - m_n - 3;
2335   ps = buffer + 1;
2336   em_randomize_nonzero (ps, ps_n, GCRY_STRONG_RANDOM);
2337
2338   /* Concatenate PS, the message M, and other padding to form an
2339      encoded message EM of length k octets as:
2340
2341      EM = 0x00 || 0x02 || PS || 0x00 || M.  */
2342
2343   buffer[0] = 0x02;
2344   buffer[ps_n + 1] = 0x00;
2345   memcpy (buffer + ps_n + 2, m, m_n);
2346
2347   err = _gcry_ac_io_write (ac_io_write, buffer, k - 1);
2348
2349  out:
2350
2351   gcry_free (buffer);
2352   gcry_free (m);
2353
2354   return err;
2355 }
2356
2357 /* Decode a message according to the Encoding Method for Encryption
2358    `PKCS-V1_5' (EME-PKCS-V1_5).  */
2359 static gcry_error_t
2360 eme_pkcs_v1_5_decode (unsigned int flags, void *opts,
2361                       gcry_ac_io_t *ac_io_read,
2362                       gcry_ac_io_t *ac_io_write)
2363 {
2364   gcry_ac_eme_pkcs_v1_5_t *options;
2365   unsigned char *buffer;
2366   unsigned char *em;
2367   size_t em_n;
2368   gcry_error_t err;
2369   unsigned int i;
2370   unsigned int k;
2371
2372   options = opts;
2373   buffer = NULL;
2374   em = NULL;
2375
2376   err = _gcry_ac_io_read_all (ac_io_read, &em, &em_n);
2377   if (err)
2378     goto out;
2379
2380   err = _gcry_ac_key_get_nbits (options->handle, options->key, &k);
2381   if (err)
2382     goto out;
2383   k /= 8;
2384
2385   /* Search for zero byte.  */
2386   for (i = 0; (i < em_n) && em[i]; i++);
2387
2388   /* According to this encoding method, the first byte of the encoded
2389      message should be zero.  This byte is lost.  */
2390
2391   if (! ((em_n >= 10)
2392          && (em_n == (k - 1))
2393          && (em[0] == 0x02)
2394          && (i < em_n)
2395          && ((i - 1) >= 8)))
2396     {
2397       err = gcry_error (GPG_ERR_DECRYPT_FAILED);
2398       goto out;
2399     }
2400
2401   i++;
2402   buffer = gcry_malloc (em_n - i);
2403   if (! buffer)
2404     {
2405       err = gcry_error_from_errno (errno);
2406       goto out;
2407     }
2408
2409   memcpy (buffer, em + i, em_n - i);
2410   err = _gcry_ac_io_write (ac_io_write, buffer, em_n - i);
2411
2412  out:
2413
2414   gcry_free (buffer);
2415   gcry_free (em);
2416
2417   return err;
2418 }
2419
2420 static gcry_error_t
2421 emsa_pkcs_v1_5_encode_data_cb (void *opaque,
2422                                unsigned char *buffer, size_t buffer_n)
2423 {
2424   gcry_md_hd_t md_handle;
2425
2426   md_handle = opaque;
2427   gcry_md_write (md_handle, buffer, buffer_n);
2428
2429   return 0;
2430 }
2431
2432
2433 /* Encode a message according to the Encoding Method for Signatures
2434    with Appendix `PKCS-V1_5' (EMSA-PKCS-V1_5).  */
2435 static gcry_error_t
2436 emsa_pkcs_v1_5_encode (unsigned int flags, void *opts,
2437                        gcry_ac_io_t *ac_io_read,
2438                        gcry_ac_io_t *ac_io_write)
2439 {
2440   gcry_ac_emsa_pkcs_v1_5_t *options;
2441   gcry_error_t err;
2442   gcry_md_hd_t md;
2443   unsigned char *t;
2444   size_t t_n;
2445   unsigned char *h;
2446   size_t h_n;
2447   unsigned char *ps;
2448   size_t ps_n;
2449   unsigned char *buffer;
2450   size_t buffer_n;
2451   unsigned char asn[100];       /* FIXME, always enough?  */
2452   size_t asn_n;
2453   unsigned int i;
2454   
2455   options = opts;
2456   buffer = NULL;
2457   md = NULL;
2458   ps = NULL;
2459   t = NULL;
2460
2461   /* Create hashing handle and get the necessary information.  */
2462   err = gcry_md_open (&md, options->md, 0);
2463   if (err)
2464     goto out;
2465
2466   asn_n = DIM (asn);
2467   err = gcry_md_algo_info (options->md, GCRYCTL_GET_ASNOID, asn, &asn_n);
2468   if (err)
2469     goto out;
2470
2471   h_n = gcry_md_get_algo_dlen (options->md);
2472
2473   err = _gcry_ac_io_process (ac_io_read, emsa_pkcs_v1_5_encode_data_cb, md);
2474   if (err)
2475     goto out;
2476
2477   h = gcry_md_read (md, 0);
2478
2479   /* Encode the algorithm ID for the hash function and the hash value
2480      into an ASN.1 value of type DigestInfo with the Distinguished
2481      Encoding Rules (DER), where the type DigestInfo has the syntax:
2482
2483      DigestInfo ::== SEQUENCE {
2484      digestAlgorithm AlgorithmIdentifier,
2485      digest OCTET STRING
2486      }
2487
2488      The first field identifies the hash function and the second
2489      contains the hash value.  Let T be the DER encoding of the
2490      DigestInfo value and let tLen be the length in octets of T.  */
2491
2492   t_n = asn_n + h_n;
2493   t = gcry_malloc (t_n);
2494   if (! t)
2495     {
2496       err = gcry_error_from_errno (errno);
2497       goto out;
2498     }
2499
2500   for (i = 0; i < asn_n; i++)
2501     t[i] = asn[i];
2502   for (i = 0; i < h_n; i++)
2503     t[asn_n + i] = h[i];
2504
2505   /* If emLen < tLen + 11, output "intended encoded message length
2506      too short" and stop.  */
2507   if (options->em_n < t_n + 11)
2508     {
2509       err = gcry_error (GPG_ERR_TOO_SHORT);
2510       goto out;
2511     }
2512
2513   /* Generate an octet string PS consisting of emLen - tLen - 3 octets
2514      with hexadecimal value 0xFF.  The length of PS will be at least 8
2515      octets.  */
2516   ps_n = options->em_n - t_n - 3;
2517   ps = gcry_malloc (ps_n);
2518   if (! ps)
2519     {
2520       err = gcry_error_from_errno (errno);
2521       goto out;
2522     }
2523   for (i = 0; i < ps_n; i++)
2524     ps[i] = 0xFF;
2525
2526   /* Concatenate PS, the DER encoding T, and other padding to form the
2527      encoded message EM as:
2528
2529      EM = 0x00 || 0x01 || PS || 0x00 || T.  */
2530
2531   buffer_n = ps_n + t_n + 3;
2532   buffer = gcry_malloc (buffer_n);
2533   if (! buffer)
2534     {
2535       err = gcry_error_from_errno (errno);
2536       goto out;
2537     }
2538
2539   buffer[0] = 0x00;
2540   buffer[1] = 0x01;
2541   for (i = 0; i < ps_n; i++)
2542     buffer[2 + i] = ps[i];
2543   buffer[2 + ps_n] = 0x00;
2544   for (i = 0; i < t_n; i++)
2545     buffer[3 + ps_n + i] = t[i];
2546
2547   err = _gcry_ac_io_write (ac_io_write, buffer, buffer_n);
2548
2549  out:
2550
2551   gcry_md_close (md);
2552
2553   gcry_free (buffer);
2554   gcry_free (ps);
2555   gcry_free (t);
2556
2557   return err;
2558 }
2559
2560 /* `Actions' for data_dencode().  */
2561 typedef enum dencode_action
2562   {
2563     DATA_ENCODE,
2564     DATA_DECODE,
2565   }
2566 dencode_action_t;
2567
2568 /* Encode or decode a message according to the the encoding method
2569    METHOD; ACTION specifies wether the message that is contained in
2570    BUFFER_IN and of length BUFFER_IN_N should be encoded or decoded.
2571    The resulting message will be stored in a newly allocated buffer in
2572    BUFFER_OUT and BUFFER_OUT_N.  */
2573 static gcry_error_t
2574 ac_data_dencode (gcry_ac_em_t method, dencode_action_t action,
2575                  unsigned int flags, void *options,
2576                  gcry_ac_io_t *ac_io_read,
2577                  gcry_ac_io_t *ac_io_write)
2578 {
2579   struct
2580   {
2581     gcry_ac_em_t method;
2582     gcry_ac_em_dencode_t encode;
2583     gcry_ac_em_dencode_t decode;
2584   } methods[] =
2585     {
2586       { GCRY_AC_EME_PKCS_V1_5,
2587         eme_pkcs_v1_5_encode, eme_pkcs_v1_5_decode },
2588       { GCRY_AC_EMSA_PKCS_V1_5,
2589         emsa_pkcs_v1_5_encode, NULL },
2590     };
2591   size_t methods_n;
2592   gcry_error_t err;
2593   unsigned int i;
2594
2595   methods_n = sizeof (methods) / sizeof (*methods);
2596
2597   for (i = 0; i < methods_n; i++)
2598     if (methods[i].method == method)
2599       break;
2600   if (i == methods_n)
2601     {
2602       err = gcry_error (GPG_ERR_NOT_FOUND);     /* FIXME? */
2603       goto out;
2604     }
2605
2606   err = 0;
2607   switch (action)
2608     {
2609     case DATA_ENCODE:
2610       if (methods[i].encode)
2611         /* FIXME? */
2612         err = (*methods[i].encode) (flags, options, ac_io_read, ac_io_write);
2613       break;
2614
2615     case DATA_DECODE:
2616       if (methods[i].decode)
2617         /* FIXME? */
2618         err = (*methods[i].decode) (flags, options, ac_io_read, ac_io_write);
2619       break;
2620
2621     default:
2622       err = gcry_error (GPG_ERR_INV_ARG);
2623       break;
2624     }
2625
2626  out:
2627
2628   return err;
2629 }
2630
2631 /* Encode a message according to the encoding method METHOD.  OPTIONS
2632    must be a pointer to a method-specific structure
2633    (gcry_ac_em*_t).  */
2634 gcry_error_t
2635 _gcry_ac_data_encode (gcry_ac_em_t method,
2636                       unsigned int flags, void *options,
2637                       gcry_ac_io_t *ac_io_read,
2638                       gcry_ac_io_t *ac_io_write)
2639 {
2640   return ac_data_dencode (method, DATA_ENCODE, flags, options,
2641                           ac_io_read, ac_io_write);
2642 }
2643
2644 /* Dencode a message according to the encoding method METHOD.  OPTIONS
2645    must be a pointer to a method-specific structure
2646    (gcry_ac_em*_t).  */
2647 gcry_error_t
2648 _gcry_ac_data_decode (gcry_ac_em_t method,
2649                       unsigned int flags, void *options,
2650                       gcry_ac_io_t *ac_io_read,
2651                       gcry_ac_io_t *ac_io_write)
2652 {
2653   return ac_data_dencode (method, DATA_DECODE, flags, options,
2654                           ac_io_read, ac_io_write);
2655 }
2656
2657 gcry_error_t
2658 gcry_ac_data_encode (gcry_ac_em_t method,
2659                      unsigned int flags, void *options,
2660                      gcry_ac_io_t *ac_io_read,
2661                      gcry_ac_io_t *ac_io_write)
2662 {
2663   gcry_error_t err;
2664
2665   err = _gcry_ac_data_encode (method, flags, options,
2666                               ac_io_read, ac_io_write);
2667
2668   return gcry_error (err);
2669 }
2670
2671 gcry_error_t
2672 gcry_ac_data_decode (gcry_ac_em_t method,
2673                      unsigned int flags, void *options,
2674                      gcry_ac_io_t *ac_io_read,
2675                      gcry_ac_io_t *ac_io_write)
2676 {
2677   gcry_error_t err;
2678
2679   err = _gcry_ac_data_decode (method, flags, options,
2680                               ac_io_read, ac_io_write);
2681   
2682   return gcry_error (err);
2683 }
2684
2685 /* Convert an MPI into an octet string.  */
2686 void
2687 _gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
2688 {
2689   unsigned long digit;
2690   gcry_mpi_t base;
2691   unsigned int i;
2692   unsigned int n;
2693   gcry_mpi_t m;
2694   gcry_mpi_t d;
2695
2696   base = gcry_mpi_new (0);
2697   gcry_mpi_set_ui (base, 256);
2698
2699   n = 0;
2700   m = gcry_mpi_copy (mpi);
2701   while (gcry_mpi_cmp_ui (m, 0))
2702     {
2703       n++;
2704       gcry_mpi_div (m, NULL, m, base, 0);
2705     }
2706
2707   gcry_mpi_set (m, mpi);
2708   d = gcry_mpi_new (0);
2709   for (i = 0; (i < n) && (i < os_n); i++)
2710     {
2711       gcry_mpi_mod (d, m, base);
2712       _gcry_mpi_get_ui (d, &digit);
2713       gcry_mpi_div (m, NULL, m, base, 0);
2714       os[os_n - i - 1] = (digit & 0xFF);
2715     }
2716
2717   for (; i < os_n; i++)
2718     os[os_n - i - 1] = 0;
2719
2720   gcry_mpi_release (base);
2721   gcry_mpi_release (d);
2722   gcry_mpi_release (m);
2723 }
2724
2725 /* Convert an MPI into an octet string (I2OSP). */
2726 void
2727 gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
2728 {
2729   _gcry_ac_mpi_to_os (mpi, os, os_n);
2730 }
2731
2732 /* Convert an MPI into an newly allocated octet string.  */
2733 gcry_error_t
2734 _gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, size_t *os_n)
2735 {
2736   unsigned char *buffer;
2737   size_t buffer_n;
2738   gcry_error_t err;
2739   unsigned int nbits;
2740
2741   nbits = gcry_mpi_get_nbits (mpi);
2742   buffer_n = (nbits + 7) / 8;
2743   buffer = gcry_malloc (buffer_n);
2744   if (! buffer)
2745     {
2746       err = gcry_error_from_errno (errno);
2747       goto out;
2748     }
2749       
2750   _gcry_ac_mpi_to_os (mpi, buffer, buffer_n);
2751   *os = buffer;
2752   *os_n = buffer_n;
2753   err = 0;
2754
2755  out:
2756
2757   return err;
2758 }
2759
2760 gcry_error_t
2761 gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, size_t *os_n)
2762 {
2763   gcry_error_t err;
2764
2765   err = _gcry_ac_mpi_to_os_alloc (mpi, os, os_n);
2766
2767   return gcry_error (err);
2768 }
2769
2770 /* Convert an octet string into an MPI.  */
2771 void
2772 _gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
2773 {
2774   unsigned int i;
2775   gcry_mpi_t xi;
2776   gcry_mpi_t x;
2777   gcry_mpi_t a;
2778   
2779   a = gcry_mpi_new (0);
2780   gcry_mpi_set_ui (a, 1);
2781   x = gcry_mpi_new (0);
2782   gcry_mpi_set_ui (x, 0);
2783   xi = gcry_mpi_new (0);
2784
2785   for (i = 0; i < os_n; i++)
2786     {
2787       gcry_mpi_mul_ui (xi, a, os[os_n - i - 1]);
2788       gcry_mpi_add (x, x, xi);
2789       gcry_mpi_mul_ui (a, a, 256);
2790     }
2791       
2792   gcry_mpi_release (xi);
2793   gcry_mpi_release (a);
2794
2795   gcry_mpi_set (mpi, x);
2796   gcry_mpi_release (x);         /* FIXME: correct? */
2797 }
2798
2799 void
2800 gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
2801 {
2802   _gcry_ac_os_to_mpi (mpi, os, os_n);
2803 }
2804
2805 \f
2806
2807 /* 
2808  * Implementation of Encryption Schemes (ES) and Signature Schemes
2809  * with Appendix (SSA).
2810  */
2811
2812 /* Schemes consist of two things: encoding methods and cryptographic
2813    primitives.
2814
2815    Since encoding methods are accessible through a common API with
2816    method-specific options passed as an anonymous struct, schemes have
2817    to provide functions that construct this method-specific structure;
2818    this is what the functions of type `gcry_ac_dencode_prepare_t' are
2819    there for.  */
2820
2821 typedef gcry_error_t (*gcry_ac_dencode_prepare_t) (gcry_ac_handle_t handle,
2822                                                       gcry_ac_key_t key,
2823                                                       void *opts,
2824                                                       void *opts_em);
2825
2826 /* The `dencode_prepare' function for ES-PKCS-V1_5.  */
2827 static gcry_error_t
2828 ac_es_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
2829                                  void *opts, void *opts_em)
2830 {
2831   gcry_ac_eme_pkcs_v1_5_t *options_em;
2832
2833   options_em = opts_em;
2834
2835   options_em->handle = handle;
2836   options_em->key = key;
2837
2838   return 0;
2839 }
2840
2841 /* The `dencode_prepare' function for SSA-PKCS-V1_5.  */
2842 static gcry_error_t
2843 ac_ssa_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
2844                                   void *opts, void *opts_em)
2845 {
2846   gcry_ac_emsa_pkcs_v1_5_t *options_em;
2847   gcry_ac_ssa_pkcs_v1_5_t *options;
2848   gcry_error_t err;
2849   unsigned int k;
2850
2851   options_em = opts_em;
2852   options = opts;
2853
2854   err = _gcry_ac_key_get_nbits (handle, key, &k);
2855   if (err)
2856     goto out;
2857
2858   k = (k + 7) / 8;
2859   options_em->md = options->md;
2860   options_em->em_n = k;
2861
2862  out:
2863
2864   return err;
2865 }
2866
2867 /* Type holding the information about each supported
2868    Encryption/Signature Scheme.  */
2869 typedef struct ac_scheme
2870 {
2871   gcry_ac_scheme_t scheme;
2872   gcry_ac_em_t scheme_encoding;
2873   gcry_ac_dencode_prepare_t dencode_prepare;
2874   size_t options_em_n;
2875 } ac_scheme_t;
2876
2877 /* List of supported Schemes.  */
2878 static ac_scheme_t ac_schemes[] =
2879   {
2880     { GCRY_AC_ES_PKCS_V1_5, GCRY_AC_EME_PKCS_V1_5,
2881       ac_es_dencode_prepare_pkcs_v1_5,
2882       sizeof (gcry_ac_eme_pkcs_v1_5_t) },
2883     { GCRY_AC_SSA_PKCS_V1_5, GCRY_AC_EMSA_PKCS_V1_5,
2884       ac_ssa_dencode_prepare_pkcs_v1_5,
2885       sizeof (gcry_ac_emsa_pkcs_v1_5_t) }
2886   };
2887
2888 /* Lookup a scheme by it's ID.  */
2889 static ac_scheme_t *
2890 ac_scheme_get (gcry_ac_scheme_t scheme)
2891 {
2892   ac_scheme_t *ac_scheme;
2893   unsigned int i;
2894
2895   for (i = 0; i < DIM (ac_schemes); i++)
2896     if (scheme == ac_schemes[i].scheme)
2897       break;
2898   if (i == DIM (ac_schemes))
2899     ac_scheme = NULL;
2900   else
2901     ac_scheme = ac_schemes + i;
2902
2903   return ac_scheme;
2904 }
2905
2906 /* Prepares the encoding/decoding by creating an according option
2907    structure.  */
2908 static gcry_error_t
2909 ac_dencode_prepare (gcry_ac_handle_t handle, gcry_ac_key_t key, void *opts,
2910                     ac_scheme_t scheme, void **opts_em)
2911 {
2912   gcry_error_t err;
2913   void *options_em;
2914
2915   options_em = gcry_malloc (scheme.options_em_n);
2916   if (! options_em)
2917     {
2918       err = gcry_error_from_errno (errno);
2919       goto out;
2920     }
2921   
2922   err = (*scheme.dencode_prepare) (handle, key, opts, options_em);
2923   if (err)
2924     goto out;
2925
2926   *opts_em = options_em;
2927
2928  out:
2929
2930   if (err)
2931     free (options_em);
2932
2933   return err;
2934 }
2935
2936 /* Convert a data set into a single MPI; currently, this is only
2937    supported for data sets containing a single MPI.  */
2938 static gcry_error_t
2939 ac_data_set_to_mpi (gcry_ac_data_t data, gcry_mpi_t *mpi)
2940 {
2941   gcry_error_t err;
2942   gcry_mpi_t mpi_new;
2943   unsigned int elems;
2944
2945   elems = _gcry_ac_data_length (data);
2946
2947   if (elems != 1)
2948     {
2949       /* FIXME: I guess, we should be more flexible in this respect by
2950          allowing the actual encryption/signature schemes to implement
2951          this conversion mechanism.  */
2952       err = gcry_error (GPG_ERR_CONFLICT);
2953       goto out;
2954     }
2955
2956   err = _gcry_ac_data_get_index (data, GCRY_AC_FLAG_COPY, 0, NULL, &mpi_new);
2957   if (err)
2958     goto out;
2959
2960   *mpi = mpi_new;
2961
2962  out:
2963
2964   return err;
2965 }
2966
2967 /* Encrypts the plain text message contained in M, which is of size
2968    M_N, with the public key KEY_PUBLIC according to the Encryption
2969    Scheme SCHEME_ID.  HANDLE is used for accessing the low-level
2970    cryptographic primitives.  If OPTS is not NULL, it has to be an
2971    anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
2972    The encrypted message will be stored in C and C_N.  */
2973 gcry_error_t
2974 _gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
2975                               gcry_ac_scheme_t scheme_id,
2976                               unsigned int flags, void *opts,
2977                               gcry_ac_key_t key,
2978                               gcry_ac_io_t *io_message,
2979                               gcry_ac_io_t *io_cipher)
2980 {
2981   gcry_error_t err;
2982   gcry_ac_io_t io_em;
2983   unsigned char *em;
2984   size_t em_n;
2985   gcry_mpi_t mpi_plain;
2986   gcry_ac_data_t data_encrypted;
2987   gcry_mpi_t mpi_encrypted;
2988   unsigned char *buffer;
2989   size_t buffer_n;
2990   void *opts_em;
2991   ac_scheme_t *scheme;
2992
2993   data_encrypted = NULL;
2994   mpi_encrypted = NULL;
2995   mpi_plain = NULL;
2996   opts_em = NULL;
2997   buffer = NULL;
2998   em = NULL;
2999
3000   scheme = ac_scheme_get (scheme_id);
3001   if (! scheme)
3002     {
3003       err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
3004       goto out;
3005     }
3006
3007   if (key->type != GCRY_AC_KEY_PUBLIC)
3008     {
3009       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
3010       goto out;
3011     }
3012
3013   err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
3014   if (err)
3015     goto out;
3016
3017   _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
3018                     GCRY_AC_IO_STRING, &em, &em_n);
3019
3020   err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
3021                               io_message, &io_em);
3022   if (err)
3023     goto out;
3024
3025   mpi_plain = gcry_mpi_snew (0);
3026   gcry_ac_os_to_mpi (mpi_plain, em, em_n);
3027
3028   err = _gcry_ac_data_encrypt (handle, 0, key, mpi_plain, &data_encrypted);
3029   if (err)
3030     goto out;
3031
3032   err = ac_data_set_to_mpi (data_encrypted, &mpi_encrypted);
3033   if (err)
3034     goto out;
3035
3036   err = _gcry_ac_mpi_to_os_alloc (mpi_encrypted, &buffer, &buffer_n);
3037   if (err)
3038     goto out;
3039
3040   err = _gcry_ac_io_write (io_cipher, buffer, buffer_n);
3041
3042  out:
3043
3044   gcry_ac_data_destroy (data_encrypted);
3045   gcry_mpi_release (mpi_encrypted);
3046   gcry_mpi_release (mpi_plain);
3047   gcry_free (opts_em);
3048   gcry_free (buffer);
3049   gcry_free (em);
3050
3051   return err;
3052 }
3053
3054 gcry_error_t
3055 gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
3056                              gcry_ac_scheme_t scheme_id,
3057                              unsigned int flags, void *opts,
3058                              gcry_ac_key_t key,
3059                              gcry_ac_io_t *io_message,
3060                              gcry_ac_io_t *io_cipher)
3061 {
3062   gcry_error_t err;
3063
3064   err = _gcry_ac_data_encrypt_scheme (handle, scheme_id, flags, opts, key,
3065                                       io_message, io_cipher);
3066
3067   return gcry_error (err);
3068 }
3069
3070 /* Decryptes the cipher message contained in C, which is of size C_N,
3071    with the secret key KEY_SECRET according to the Encryption Scheme
3072    SCHEME_ID.  Handle is used for accessing the low-level
3073    cryptographic primitives.  If OPTS is not NULL, it has to be an
3074    anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
3075    The decrypted message will be stored in M and M_N.  */
3076 gcry_error_t
3077 _gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
3078                               gcry_ac_scheme_t scheme_id,
3079                               unsigned int flags, void *opts,
3080                               gcry_ac_key_t key,
3081                               gcry_ac_io_t *io_cipher,
3082                               gcry_ac_io_t *io_message)
3083 {
3084   gcry_ac_io_t io_em;
3085   gcry_error_t err;
3086   gcry_ac_data_t data_encrypted;
3087   unsigned char *em;
3088   size_t em_n;
3089   gcry_mpi_t mpi_encrypted;
3090   gcry_mpi_t mpi_decrypted;
3091   void *opts_em;
3092   ac_scheme_t *scheme;
3093   char *elements_enc;
3094   size_t elements_enc_n;
3095   unsigned char *c;
3096   size_t c_n;
3097
3098   data_encrypted = NULL;
3099   mpi_encrypted = NULL;
3100   mpi_decrypted = NULL;
3101   elements_enc = NULL;
3102   opts_em = NULL;
3103   em = NULL;
3104   c = NULL;
3105
3106   scheme = ac_scheme_get (scheme_id);
3107   if (! scheme)
3108     {
3109       err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
3110       goto out;
3111     }
3112
3113   if (key->type != GCRY_AC_KEY_SECRET)
3114     {
3115       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
3116       goto out;
3117     }
3118
3119   err = _gcry_ac_io_read_all (io_cipher, &c, &c_n);
3120   if (err)
3121     goto out;
3122
3123   mpi_encrypted = gcry_mpi_snew (0);
3124   gcry_ac_os_to_mpi (mpi_encrypted, c, c_n);
3125
3126   err = _gcry_pk_get_elements (handle->algorithm, &elements_enc, NULL);
3127   if (err)
3128     goto out;
3129
3130   elements_enc_n = strlen (elements_enc);
3131   if (elements_enc_n != 1)
3132     {
3133       /* FIXME? */
3134       err = gcry_error (GPG_ERR_CONFLICT);
3135       goto out;
3136     }
3137
3138   err = _gcry_ac_data_new (&data_encrypted);
3139   if (err)
3140     goto out;
3141
3142   err = _gcry_ac_data_set (data_encrypted, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
3143                            elements_enc, mpi_encrypted);
3144   if (err)
3145     goto out;
3146
3147   err = _gcry_ac_data_decrypt (handle, 0, key, &mpi_decrypted, data_encrypted);
3148   if (err)
3149     goto out;
3150
3151   err = _gcry_ac_mpi_to_os_alloc (mpi_decrypted, &em, &em_n);
3152   if (err)
3153     goto out;
3154
3155   err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
3156   if (err)
3157     goto out;
3158
3159   _gcry_ac_io_init (&io_em, GCRY_AC_IO_READABLE,
3160                     GCRY_AC_IO_STRING, em, em_n);
3161
3162   err = _gcry_ac_data_decode (scheme->scheme_encoding, 0, opts_em,
3163                               &io_em, io_message);
3164   if (err)
3165     goto out;
3166
3167  out:
3168   
3169   _gcry_ac_data_destroy (data_encrypted);
3170   gcry_mpi_release (mpi_encrypted);
3171   gcry_mpi_release (mpi_decrypted);
3172   free (elements_enc);
3173   gcry_free (opts_em);
3174   gcry_free (em);
3175   gcry_free (c);
3176
3177   return err;
3178 }
3179
3180 gcry_error_t
3181 gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
3182                              gcry_ac_scheme_t scheme_id,
3183                              unsigned int flags, void *opts,
3184                              gcry_ac_key_t key,
3185                              gcry_ac_io_t *io_cipher,
3186                              gcry_ac_io_t *io_message)
3187 {
3188   gcry_error_t err;
3189
3190   err = _gcry_ac_data_decrypt_scheme (handle, scheme_id, flags, opts, key,
3191                                       io_cipher, io_message);
3192
3193   return gcry_error (err);
3194 }  
3195
3196 /* Signs the message contained in M, which is of size M_N, with the
3197    secret key KEY according to the Signature Scheme SCHEME_ID.  Handle
3198    is used for accessing the low-level cryptographic primitives.  If
3199    OPTS is not NULL, it has to be an anonymous structure specific to
3200    the chosen scheme (gcry_ac_ssa_*_t).  The signed message will be
3201    stored in S and S_N.  */
3202 gcry_error_t
3203 _gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
3204                            gcry_ac_scheme_t scheme_id,
3205                            unsigned int flags, void *opts,
3206                            gcry_ac_key_t key,
3207                            gcry_ac_io_t *io_message,
3208                            gcry_ac_io_t *io_signature)
3209 {
3210   gcry_ac_io_t io_em;
3211   gcry_error_t err;
3212   gcry_ac_data_t data_signed;
3213   unsigned char *em;
3214   size_t em_n;
3215   gcry_mpi_t mpi;
3216   void *opts_em;
3217   unsigned char *buffer;
3218   size_t buffer_n;
3219   gcry_mpi_t mpi_signed;
3220   ac_scheme_t *scheme;
3221
3222   data_signed = NULL;
3223   mpi_signed = NULL;
3224   opts_em = NULL;
3225   buffer = NULL;
3226   mpi = NULL;
3227   em = NULL;
3228
3229   if (key->type != GCRY_AC_KEY_SECRET)
3230     {
3231       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
3232       goto out;
3233     }
3234
3235   scheme = ac_scheme_get (scheme_id);
3236   if (! scheme)
3237     {
3238       /* FIXME: adjust api of scheme_get in respect to err codes.  */
3239       err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
3240       goto out;
3241     }
3242
3243   err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
3244   if (err)
3245     goto out;
3246
3247   _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
3248                     GCRY_AC_IO_STRING, &em, &em_n);
3249
3250   err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
3251                               io_message, &io_em);
3252   if (err)
3253     goto out;
3254
3255   mpi = gcry_mpi_new (0);
3256   _gcry_ac_os_to_mpi (mpi, em, em_n);
3257
3258   err = _gcry_ac_data_sign (handle, key, mpi, &data_signed);
3259   if (err)
3260     goto out;
3261
3262   err = ac_data_set_to_mpi (data_signed, &mpi_signed);
3263   if (err)
3264     goto out;
3265
3266   err = _gcry_ac_mpi_to_os_alloc (mpi_signed, &buffer, &buffer_n);
3267   if (err)
3268     goto out;
3269
3270   err = _gcry_ac_io_write (io_signature, buffer, buffer_n);
3271
3272  out:
3273
3274   _gcry_ac_data_destroy (data_signed);
3275   gcry_mpi_release (mpi_signed);
3276   gcry_mpi_release (mpi);
3277   gcry_free (opts_em);
3278   gcry_free (buffer);
3279   gcry_free (em);
3280
3281   return err;
3282 }
3283
3284 gcry_error_t
3285 gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
3286                           gcry_ac_scheme_t scheme_id,
3287                           unsigned int flags,
3288                           void *opts,
3289                           gcry_ac_key_t key,
3290                           gcry_ac_io_t *io_message,
3291                           gcry_ac_io_t *io_signature)
3292 {
3293   gcry_error_t err;
3294
3295   err = _gcry_ac_data_sign_scheme (handle, scheme_id, flags, opts, key,
3296                                    io_message, io_signature);
3297
3298   return gcry_error (err);
3299 }
3300
3301 /* Verifies that the signature contained in S, which is of length S_N,
3302    is indeed the result of signing the message contained in M, which
3303    is of size M_N, with the secret key belonging to the public key
3304    KEY_PUBLIC.  If OPTS is not NULL, it has to be an anonymous
3305    structure (gcry_ac_ssa_*_t) specific to the Signature Scheme, whose
3306    ID is contained in SCHEME_ID.  */
3307 gcry_error_t
3308 _gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
3309                              gcry_ac_scheme_t scheme_id,
3310                              unsigned int flags, void *opts,
3311                              gcry_ac_key_t key,
3312                              gcry_ac_io_t *io_message,
3313                              gcry_ac_io_t *io_signature)
3314 {
3315   gcry_ac_io_t io_em;
3316   gcry_error_t err;
3317   gcry_ac_data_t data_signed;
3318   unsigned char *em;
3319   size_t em_n;
3320   void *opts_em;
3321   gcry_mpi_t mpi_signature;
3322   gcry_mpi_t mpi_data;
3323   ac_scheme_t *scheme;
3324   char *elements_sig;
3325   size_t elements_sig_n;
3326   unsigned char *s;
3327   size_t s_n;
3328
3329   mpi_signature = NULL;
3330   elements_sig = NULL;
3331   data_signed = NULL;
3332   mpi_data = NULL;
3333   opts_em = NULL;
3334   em = NULL;
3335   s = NULL;
3336
3337   if (key->type != GCRY_AC_KEY_PUBLIC)
3338     {
3339       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
3340       goto out;
3341     }
3342
3343   scheme = ac_scheme_get (scheme_id);
3344   if (! scheme)
3345     {
3346       err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
3347       goto out;
3348     }
3349
3350   err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
3351   if (err)
3352     goto out;
3353
3354   _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
3355                     GCRY_AC_IO_STRING, &em, &em_n);
3356
3357   err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
3358                               io_message, &io_em);
3359   if (err)
3360     goto out;
3361
3362   mpi_data = gcry_mpi_new (0);
3363   _gcry_ac_os_to_mpi (mpi_data, em, em_n);
3364
3365   err = _gcry_ac_io_read_all (io_signature, &s, &s_n);
3366   if (err)
3367     goto out;
3368
3369   mpi_signature = gcry_mpi_new (0);
3370   _gcry_ac_os_to_mpi (mpi_signature, s, s_n);
3371
3372   err = _gcry_pk_get_elements (handle->algorithm, NULL, &elements_sig);
3373   if (err)
3374     goto out;
3375
3376   elements_sig_n = strlen (elements_sig);
3377   if (elements_sig_n != 1)
3378     {
3379       /* FIXME? */
3380       err = gcry_error (GPG_ERR_CONFLICT);
3381       goto out;
3382     }
3383
3384   err = _gcry_ac_data_new (&data_signed);
3385   if (err)
3386     goto out;
3387
3388   err = _gcry_ac_data_set (data_signed, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
3389                            elements_sig, mpi_signature);
3390   if (err)
3391     goto out;
3392
3393   gcry_mpi_release (mpi_signature);
3394   mpi_signature = NULL;
3395   
3396   err = _gcry_ac_data_verify (handle, key, mpi_data, data_signed);
3397
3398  out:
3399
3400   _gcry_ac_data_destroy (data_signed);
3401   gcry_mpi_release (mpi_signature);
3402   gcry_mpi_release (mpi_data);
3403   free (elements_sig);
3404   gcry_free (opts_em);
3405   gcry_free (em);
3406   gcry_free (s);
3407
3408   return err;
3409 }
3410
3411 gcry_error_t
3412 gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
3413                             gcry_ac_scheme_t scheme_id,
3414                             unsigned int flags, void *opts,
3415                             gcry_ac_key_t key,
3416                             gcry_ac_io_t *io_message,
3417                             gcry_ac_io_t *io_signature)
3418 {
3419   gcry_error_t err;
3420
3421   err = _gcry_ac_data_verify_scheme (handle, scheme_id, flags, opts, key,
3422                                      io_message, io_signature);
3423
3424   return gcry_error (err);
3425 }
3426
3427
3428
3429 /* 
3430  * General functions.
3431  */
3432
3433 /* Stores the textual representation of the algorithm whose id is
3434    given in ALGORITHM in NAME.  */
3435 gcry_error_t
3436 gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name)
3437 {
3438   gcry_error_t err;
3439   const char *n;
3440
3441   n = gcry_pk_algo_name (algorithm);
3442   if (! *n)
3443     {
3444       err = gcry_error (GPG_ERR_PUBKEY_ALGO);
3445       goto out;
3446     }
3447
3448   *name = n;
3449   err = 0;
3450
3451  out:
3452
3453   return gcry_error (err);
3454 }
3455
3456 /* Stores the numeric ID of the algorithm whose textual representation
3457    is contained in NAME in ALGORITHM.  */
3458 gcry_error_t
3459 gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm)
3460 {
3461   gcry_error_t err;
3462   int algo;
3463
3464   algo = gcry_pk_map_name (name);
3465   if (! algo)
3466     {
3467       err = gcry_error (GPG_ERR_PUBKEY_ALGO);
3468       goto out;
3469     }
3470
3471   *algorithm = algo;
3472   err = 0;
3473
3474  out:
3475
3476   return gcry_error (err);
3477 }