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