The ACE engine of VIA processors is now used for AES-128.
[libgcrypt.git] / cipher / ac.c
1 /* ac.c - Alternative interface for asymmetric cryptography.
2    Copyright (C) 2003, 2004, 2005, 2006
3                  2007  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 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
1500   /* Allocate key pair.  */
1501   key_pair_new = gcry_malloc (sizeof (struct gcry_ac_key_pair));
1502   if (! key_pair_new)
1503     {
1504       err = gcry_error_from_errno (errno);
1505       goto out;
1506     }
1507
1508   /* Allocate keys.  */
1509   key_secret = gcry_malloc (sizeof (*key_secret));
1510   if (! key_secret)
1511     {
1512       err = gcry_error_from_errno (errno);
1513       goto out;
1514     }
1515   key_public = gcry_malloc (sizeof (*key_public));
1516   if (! key_public)
1517     {
1518       err = gcry_error_from_errno (errno);
1519       goto out;
1520     }
1521
1522   /* Calculate size of the format string, that is used for creating
1523      the request S-expression.  */
1524   genkey_format_n = 22;
1525
1526   /* Respect any relevant algorithm specific commands.  */
1527   if (key_spec)
1528     for (i = 0; i < DIM (ac_key_generate_specs); i++)
1529       if (handle->algorithm == ac_key_generate_specs[i].algorithm)
1530         genkey_format_n += 6;
1531
1532   /* Create format string.  */
1533   genkey_format = gcry_malloc (genkey_format_n);
1534   if (! genkey_format)
1535     {
1536       err = gcry_error_from_errno (errno);
1537       goto out;
1538     }
1539
1540   /* Fill format string.  */
1541   *genkey_format = 0;
1542   strcat (genkey_format, "(genkey(%s(nbits%d)");
1543   if (key_spec)
1544     for (i = 0; i < DIM (ac_key_generate_specs); i++)
1545       if (handle->algorithm == ac_key_generate_specs[i].algorithm)
1546         strcat (genkey_format, "(%s%m)");
1547   strcat (genkey_format, "))");
1548
1549   /* Build list of argument pointers, the algorithm name and the nbits
1550      are always needed.  */
1551   arg_list_n = 2;
1552
1553   /* Now the algorithm specific arguments.  */
1554   if (key_spec)
1555     for (i = 0; i < DIM (ac_key_generate_specs); i++)
1556       if (handle->algorithm == ac_key_generate_specs[i].algorithm)
1557         arg_list_n += 2;
1558
1559   /* Allocate list.  */
1560   arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n);
1561   if (! arg_list)
1562     {
1563       err = gcry_error_from_errno (errno);
1564       goto out;
1565     }
1566
1567   arg_list[0] = (void *) &handle->algorithm_name;
1568   arg_list[1] = (void *) &nbits;
1569   if (key_spec)
1570     for (j = 2, i = 0; i < DIM (ac_key_generate_specs); i++)
1571       if (handle->algorithm == ac_key_generate_specs[i].algorithm)
1572         {
1573           /* Add name of this specification flag and the
1574              according member of the spec strucuture.  */
1575           arg_list[j++] = (void *)(&ac_key_generate_specs[i].name);
1576           arg_list[j++] = (void *)
1577             (((char *) key_spec)
1578              + ac_key_generate_specs[i].offset);
1579           /* FIXME: above seems to suck.  */
1580         }
1581
1582   /* Construct final request S-expression.  */
1583   err = gcry_sexp_build_array (&genkey_sexp_request,
1584                                NULL, genkey_format, arg_list);
1585   if (err)
1586     goto out;
1587
1588   /* Perform genkey operation.  */
1589   err = gcry_pk_genkey (&genkey_sexp_reply, genkey_sexp_request);
1590   if (err)
1591     goto out;
1592
1593   key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "private-key", 0);
1594   if (! key_sexp)
1595     {
1596       err = gcry_error (GPG_ERR_INTERNAL);
1597       goto out;
1598     }
1599   err = ac_data_extract ("private-key", handle->algorithm_name,
1600                          key_sexp, &key_data_secret);
1601   if (err)
1602     goto out;
1603
1604   gcry_sexp_release (key_sexp);
1605   key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "public-key", 0);
1606   if (! key_sexp)
1607     {
1608       err = gcry_error (GPG_ERR_INTERNAL);
1609       goto out;
1610     }
1611   err = ac_data_extract ("public-key", handle->algorithm_name,
1612                          key_sexp, &key_data_public);
1613   if (err)
1614     goto out;
1615
1616   /* Done.  */
1617
1618   key_secret->type = GCRY_AC_KEY_SECRET;
1619   key_secret->data = key_data_secret;
1620   key_public->type = GCRY_AC_KEY_PUBLIC;
1621   key_public->data = key_data_public;
1622   key_pair_new->secret = key_secret;
1623   key_pair_new->public = key_public;
1624   *key_pair = key_pair_new;
1625
1626  out:
1627
1628   /* Deallocate resources.  */
1629   
1630   gcry_free (genkey_format);
1631   gcry_free (arg_list);
1632   gcry_sexp_release (genkey_sexp_request);
1633   gcry_sexp_release (genkey_sexp_reply);
1634   if (err)
1635     {
1636       _gcry_ac_data_destroy (key_data_secret);
1637       _gcry_ac_data_destroy (key_data_public);
1638       gcry_free (key_secret);
1639       gcry_free (key_public);
1640       gcry_free (key_pair_new);
1641     }
1642
1643   return err;
1644 }
1645
1646 /* Returns the key of type WHICH out of the key pair KEY_PAIR.  */
1647 gcry_ac_key_t
1648 _gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair, 
1649                            gcry_ac_key_type_t which)
1650 {
1651   gcry_ac_key_t key;
1652
1653   switch (which)
1654     {
1655     case GCRY_AC_KEY_SECRET:
1656       key = key_pair->secret;
1657       break;
1658
1659     case GCRY_AC_KEY_PUBLIC:
1660       key = key_pair->public;
1661       break;
1662
1663     default:
1664       key = NULL;
1665       break;
1666     }
1667
1668   return key;
1669 }
1670
1671 /* Destroys the key KEY.  */
1672 void
1673 _gcry_ac_key_destroy (gcry_ac_key_t key)
1674 {
1675   unsigned int i;
1676
1677   if (key)
1678     {
1679       if (key->data)
1680         {
1681           for (i = 0; i < key->data->data_n; i++)
1682             if (key->data->data[i].mpi != NULL)
1683               gcry_mpi_release (key->data->data[i].mpi);
1684           gcry_free (key->data);
1685         }
1686       gcry_free (key);
1687     }
1688 }
1689
1690 /* Destroys the key pair KEY_PAIR.  */
1691 void
1692 _gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
1693 {
1694   if (key_pair)
1695     {
1696       gcry_ac_key_destroy (key_pair->secret);
1697       gcry_ac_key_destroy (key_pair->public);
1698       gcry_free (key_pair);
1699     }
1700 }
1701
1702 /* Returns the data set contained in the key KEY.  */
1703 gcry_ac_data_t
1704 _gcry_ac_key_data_get (gcry_ac_key_t key)
1705 {
1706   return key->data;
1707 }
1708
1709 /* Verifies that the key KEY is sane via HANDLE.  */
1710 gcry_error_t
1711 _gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
1712 {
1713   gcry_sexp_t key_sexp;
1714   gcry_error_t err;
1715
1716   key_sexp = NULL;
1717   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
1718                            handle->algorithm_name, key->data, &key_sexp);
1719   if (err)
1720     goto out;
1721
1722   err = gcry_pk_testkey (key_sexp);
1723
1724  out:
1725
1726   gcry_sexp_release (key_sexp);
1727
1728   return gcry_error (err);
1729 }
1730
1731 /* Stores the number of bits of the key KEY in NBITS via HANDLE.  */
1732 gcry_error_t
1733 _gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
1734                         gcry_ac_key_t key, unsigned int *nbits)
1735 {
1736   gcry_sexp_t key_sexp;
1737   gcry_error_t err;
1738   unsigned int n;
1739
1740   key_sexp = NULL;
1741
1742   err = ac_data_construct (ac_key_identifiers[key->type],
1743                            0, 0, handle->algorithm_name, key->data, &key_sexp);
1744   if (err)
1745     goto out;
1746
1747   n = gcry_pk_get_nbits (key_sexp);
1748   if (! n)
1749     {
1750       err = gcry_error (GPG_ERR_PUBKEY_ALGO);
1751       goto out;
1752     }
1753
1754   *nbits = n;
1755
1756  out:
1757
1758   gcry_sexp_release (key_sexp);
1759
1760   return err;
1761 }
1762
1763 /* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
1764    HANDLE.  */
1765 gcry_error_t
1766 _gcry_ac_key_get_grip (gcry_ac_handle_t handle,
1767                        gcry_ac_key_t key, unsigned char *key_grip)
1768 {
1769   gcry_sexp_t key_sexp;
1770   gcry_error_t err;
1771   unsigned char *ret;
1772
1773   key_sexp = NULL;
1774   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
1775                            handle->algorithm_name, key->data, &key_sexp);
1776   if (err)
1777     goto out;
1778
1779   ret = gcry_pk_get_keygrip (key_sexp, key_grip);
1780   if (! ret)
1781     {
1782       err = gcry_error (GPG_ERR_INV_OBJ);
1783       goto out;
1784     }
1785
1786   err = 0;
1787
1788  out:
1789
1790   gcry_sexp_release (key_sexp);
1791
1792   return err;
1793 }
1794
1795
1796 \f
1797
1798 /* 
1799  * Functions performing cryptographic operations.
1800  */
1801
1802 /* Encrypts the plain text MPI value DATA_PLAIN with the key public
1803    KEY under the control of the flags FLAGS and stores the resulting
1804    data set into DATA_ENCRYPTED.  */
1805 gcry_error_t
1806 _gcry_ac_data_encrypt (gcry_ac_handle_t handle,
1807                        unsigned int flags,
1808                        gcry_ac_key_t key,
1809                        gcry_mpi_t data_plain,
1810                        gcry_ac_data_t *data_encrypted)
1811 {
1812   gcry_ac_data_t data_encrypted_new;
1813   gcry_ac_data_t data_value;
1814   gcry_sexp_t sexp_request;
1815   gcry_sexp_t sexp_reply;
1816   gcry_sexp_t sexp_key;
1817   gcry_error_t err;
1818
1819   data_encrypted_new = NULL;
1820   sexp_request = NULL;
1821   sexp_reply = NULL;
1822   data_value = NULL;
1823   sexp_key = NULL;
1824
1825   if (key->type != GCRY_AC_KEY_PUBLIC)
1826     {
1827       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
1828       goto out;
1829     }
1830
1831   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
1832                            handle->algorithm_name, key->data, &sexp_key);
1833   if (err)
1834     goto out;
1835
1836   err = _gcry_ac_data_new (&data_value);
1837   if (err)
1838     goto out;
1839
1840   err = _gcry_ac_data_set (data_value, 0, "value", data_plain);
1841   if (err)
1842     goto out;
1843
1844   err = ac_data_construct ("data", 1, flags, handle->algorithm_name,
1845                            data_value, &sexp_request);
1846   if (err)
1847     goto out;
1848
1849   /* FIXME: error vs. errcode? */
1850
1851   err = gcry_pk_encrypt (&sexp_reply, sexp_request, sexp_key);
1852   if (err)
1853     goto out;
1854
1855   /* Extract data.  */
1856   err = ac_data_extract ("enc-val", handle->algorithm_name,
1857                          sexp_reply, &data_encrypted_new);
1858   if (err)
1859     goto out;
1860
1861   *data_encrypted = data_encrypted_new;
1862
1863  out:
1864
1865   /* Deallocate resources.  */
1866
1867   gcry_sexp_release (sexp_request);
1868   gcry_sexp_release (sexp_reply);
1869   gcry_sexp_release (sexp_key);
1870   _gcry_ac_data_destroy (data_value);
1871
1872   return err;
1873 }
1874
1875 /* Decrypts the encrypted data contained in the data set
1876    DATA_ENCRYPTED with the secret key KEY under the control of the
1877    flags FLAGS and stores the resulting plain text MPI value in
1878    DATA_PLAIN.  */
1879 gcry_error_t
1880 _gcry_ac_data_decrypt (gcry_ac_handle_t handle,
1881                        unsigned int flags,
1882                        gcry_ac_key_t key,
1883                        gcry_mpi_t *data_plain,
1884                        gcry_ac_data_t data_encrypted)
1885 {
1886   gcry_mpi_t data_decrypted;
1887   gcry_sexp_t sexp_request;
1888   gcry_sexp_t sexp_reply;
1889   gcry_sexp_t sexp_value;
1890   gcry_sexp_t sexp_key;
1891   gcry_error_t err;
1892
1893   sexp_request = NULL;
1894   sexp_reply = NULL;
1895   sexp_value = NULL;
1896   sexp_key = NULL;
1897
1898   if (key->type != GCRY_AC_KEY_SECRET)
1899     {
1900       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
1901       goto out;
1902     }
1903
1904   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
1905                            handle->algorithm_name, key->data, &sexp_key);
1906   if (err)
1907     goto out;
1908
1909   /* Create S-expression from data.  */
1910   err = ac_data_construct ("enc-val", 1, flags, handle->algorithm_name,
1911                            data_encrypted, &sexp_request);
1912   if (err)
1913     goto out;
1914
1915   /* Decrypt.  */
1916   err = gcry_pk_decrypt (&sexp_reply, sexp_request, sexp_key);
1917   if (err)
1918     goto out;
1919
1920   /* Extract plain text. */
1921   sexp_value = gcry_sexp_find_token (sexp_reply, "value", 0);
1922   if (! sexp_value)
1923     {
1924       /* FIXME?  */
1925       err = gcry_error (GPG_ERR_GENERAL);
1926       goto out;
1927     }
1928
1929   data_decrypted = gcry_sexp_nth_mpi (sexp_value, 1, GCRYMPI_FMT_USG);
1930   if (! data_decrypted)
1931     {
1932       err = gcry_error (GPG_ERR_GENERAL);
1933       goto out;
1934     }
1935
1936   *data_plain = data_decrypted;
1937
1938  out:
1939
1940   /* Deallocate resources.  */
1941   gcry_sexp_release (sexp_request);
1942   gcry_sexp_release (sexp_reply);
1943   gcry_sexp_release (sexp_value);
1944   gcry_sexp_release (sexp_key);
1945
1946   return gcry_error (err);
1947
1948 }
1949
1950 /* Signs the data contained in DATA with the secret key KEY and stores
1951    the resulting signature data set in DATA_SIGNATURE.  */
1952 gcry_error_t
1953 _gcry_ac_data_sign (gcry_ac_handle_t handle,
1954                     gcry_ac_key_t key,
1955                     gcry_mpi_t data,
1956                     gcry_ac_data_t *data_signature)
1957 {
1958   gcry_ac_data_t data_signed;
1959   gcry_ac_data_t data_value;
1960   gcry_sexp_t sexp_request;
1961   gcry_sexp_t sexp_reply;
1962   gcry_sexp_t sexp_key;
1963   gcry_error_t err;
1964
1965   data_signed = NULL;
1966   data_value = NULL;
1967   sexp_request = NULL;
1968   sexp_reply = NULL;
1969   sexp_key = NULL;
1970
1971   if (key->type != GCRY_AC_KEY_SECRET)
1972     {
1973       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
1974       goto out;
1975     }
1976
1977   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
1978                            handle->algorithm_name, key->data, &sexp_key);
1979   if (err)
1980     goto out;
1981
1982   err = _gcry_ac_data_new (&data_value);
1983   if (err)
1984     goto out;
1985
1986   err = _gcry_ac_data_set (data_value, 0, "value", data);
1987   if (err)
1988     goto out;
1989
1990   /* Create S-expression holding the data.  */
1991   err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_request);
1992   if (err)
1993     goto out;
1994
1995   /* Sign.  */
1996   err = gcry_pk_sign (&sexp_reply, sexp_request, sexp_key);
1997   if (err)
1998     goto out;
1999
2000   /* Extract data.  */
2001   err = ac_data_extract ("sig-val", handle->algorithm_name,
2002                          sexp_reply, &data_signed);
2003   if (err)
2004     goto out;
2005
2006   /* Done.  */
2007   *data_signature = data_signed;
2008
2009  out:
2010
2011   gcry_sexp_release (sexp_request);
2012   gcry_sexp_release (sexp_reply);
2013   gcry_sexp_release (sexp_key);
2014   _gcry_ac_data_destroy (data_value);
2015
2016   return gcry_error (err);
2017 }
2018
2019
2020 /* Verifies that the signature contained in the data set
2021    DATA_SIGNATURE is indeed the result of signing the data contained
2022    in DATA with the secret key belonging to the public key KEY.  */
2023 gcry_error_t
2024 _gcry_ac_data_verify (gcry_ac_handle_t handle,
2025                       gcry_ac_key_t key,
2026                       gcry_mpi_t data,
2027                       gcry_ac_data_t data_signature)
2028 {
2029   gcry_sexp_t sexp_signature;
2030   gcry_ac_data_t data_value;
2031   gcry_sexp_t sexp_data;
2032   gcry_sexp_t sexp_key;
2033   gcry_error_t err;
2034
2035   sexp_signature = NULL;
2036   data_value = NULL;
2037   sexp_data = NULL;
2038   sexp_key = NULL;
2039
2040   err = ac_data_construct ("public-key", 0, 0,
2041                            handle->algorithm_name, key->data, &sexp_key);
2042   if (err)
2043     goto out;
2044
2045   if (key->type != GCRY_AC_KEY_PUBLIC)
2046     {
2047       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
2048       goto out;
2049     }
2050
2051   /* Construct S-expression holding the signature data.  */
2052   err = ac_data_construct ("sig-val", 1, 0, handle->algorithm_name,
2053                            data_signature, &sexp_signature);
2054   if (err)
2055     goto out;
2056
2057   err = _gcry_ac_data_new (&data_value);
2058   if (err)
2059     goto out;
2060
2061   err = _gcry_ac_data_set (data_value, 0, "value", data);
2062   if (err)
2063     goto out;
2064
2065   /* Construct S-expression holding the data.  */
2066   err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_data);
2067   if (err)
2068     goto out;
2069
2070   /* Verify signature.  */
2071   err = gcry_pk_verify (sexp_signature, sexp_data, sexp_key);
2072
2073  out:
2074
2075   gcry_sexp_release (sexp_signature);
2076   gcry_sexp_release (sexp_data);
2077   gcry_sexp_release (sexp_key);
2078   _gcry_ac_data_destroy (data_value);
2079
2080   return gcry_error (err);
2081 }
2082
2083
2084
2085 \f
2086 /*
2087  * Implementation of encoding methods (em).
2088  */
2089
2090 /* Type for functions that encode or decode (hence the name) a
2091    message.  */
2092 typedef gcry_error_t (*gcry_ac_em_dencode_t) (unsigned int flags,
2093                                                  void *options,
2094                                                  gcry_ac_io_t *ac_io_read,
2095                                                  gcry_ac_io_t *ac_io_write);
2096
2097 /* Fill the buffer BUFFER which is BUFFER_N bytes long with non-zero
2098    random bytes of random level LEVEL.  */
2099 static void
2100 em_randomize_nonzero (unsigned char *buffer, size_t buffer_n,
2101                       gcry_random_level_t level)
2102 {
2103   unsigned char *buffer_rand;
2104   unsigned int buffer_rand_n;
2105   unsigned int zeros;
2106   unsigned int i;
2107   unsigned int j;
2108
2109   for (i = 0; i < buffer_n; i++)
2110     buffer[i] = 0;
2111   
2112   do
2113     {
2114       /* Count zeros.  */
2115       for (i = zeros = 0; i < buffer_n; i++)
2116         if (! buffer[i])
2117           zeros++;
2118
2119       if (zeros)
2120         {
2121           /* Get random bytes.  */
2122           buffer_rand_n = zeros + (zeros / 128);
2123           buffer_rand = gcry_random_bytes_secure (buffer_rand_n, level);
2124
2125           /* Substitute zeros with non-zero random bytes.  */
2126           for (i = j = 0; zeros && (i < buffer_n) && (j < buffer_rand_n); i++)
2127             if (! buffer[i])
2128               {
2129                 while ((j < buffer_rand_n) && (! buffer_rand[j]))
2130                   j++;
2131                 if (j < buffer_rand_n)
2132                   {
2133                     buffer[i] = buffer_rand[j++];
2134                     zeros--;
2135                   }
2136                 else
2137                   break;
2138               }
2139           gcry_free (buffer_rand);
2140         }
2141     }
2142   while (zeros);
2143 }
2144
2145 /* Encode a message according to the Encoding Method for Encryption
2146    `PKCS-V1_5' (EME-PKCS-V1_5).  */
2147 static gcry_error_t
2148 eme_pkcs_v1_5_encode (unsigned int flags, void *opts,
2149                       gcry_ac_io_t *ac_io_read,
2150                       gcry_ac_io_t *ac_io_write)
2151 {
2152   gcry_ac_eme_pkcs_v1_5_t *options;
2153   gcry_error_t err;
2154   unsigned char *buffer;
2155   unsigned char *ps;
2156   unsigned char *m;
2157   size_t m_n;
2158   unsigned int ps_n;
2159   unsigned int k;
2160
2161   (void)flags;
2162
2163   options = opts;
2164   buffer = NULL;
2165   m = NULL;
2166
2167   err = _gcry_ac_io_read_all (ac_io_read, &m, &m_n);
2168   if (err)
2169     goto out;
2170
2171   /* Figure out key length in bytes.  */
2172   k = options->key_size / 8;
2173
2174   if (m_n > k - 11)
2175     {
2176       /* Key is too short for message.  */
2177       err = gcry_error (GPG_ERR_TOO_SHORT);
2178       goto out;
2179     }
2180
2181   /* According to this encoding method, the first byte of the encoded
2182      message is zero.  This byte will be lost anyway, when the encoded
2183      message is to be converted into an MPI, that's why we skip
2184      it.  */
2185
2186   /* Allocate buffer.  */
2187   buffer = gcry_malloc (k - 1);
2188   if (! buffer)
2189     {
2190       err = gcry_error_from_errno (errno);
2191       goto out;
2192     }
2193
2194   /* Generate an octet string PS of length k - mLen - 3 consisting
2195      of pseudorandomly generated nonzero octets.  The length of PS
2196      will be at least eight octets.  */
2197   ps_n = k - m_n - 3;
2198   ps = buffer + 1;
2199   em_randomize_nonzero (ps, ps_n, GCRY_STRONG_RANDOM);
2200
2201   /* Concatenate PS, the message M, and other padding to form an
2202      encoded message EM of length k octets as:
2203
2204      EM = 0x00 || 0x02 || PS || 0x00 || M.  */
2205
2206   buffer[0] = 0x02;
2207   buffer[ps_n + 1] = 0x00;
2208   memcpy (buffer + ps_n + 2, m, m_n);
2209
2210   err = _gcry_ac_io_write (ac_io_write, buffer, k - 1);
2211
2212  out:
2213
2214   gcry_free (buffer);
2215   gcry_free (m);
2216
2217   return err;
2218 }
2219
2220 /* Decode a message according to the Encoding Method for Encryption
2221    `PKCS-V1_5' (EME-PKCS-V1_5).  */
2222 static gcry_error_t
2223 eme_pkcs_v1_5_decode (unsigned int flags, void *opts,
2224                       gcry_ac_io_t *ac_io_read,
2225                       gcry_ac_io_t *ac_io_write)
2226 {
2227   gcry_ac_eme_pkcs_v1_5_t *options;
2228   unsigned char *buffer;
2229   unsigned char *em;
2230   size_t em_n;
2231   gcry_error_t err;
2232   unsigned int i;
2233   unsigned int k;
2234
2235   (void)flags;
2236
2237   options = opts;
2238   buffer = NULL;
2239   em = NULL;
2240
2241   err = _gcry_ac_io_read_all (ac_io_read, &em, &em_n);
2242   if (err)
2243     goto out;
2244
2245   /* Figure out key size.  */
2246   k = options->key_size / 8;
2247
2248   /* Search for zero byte.  */
2249   for (i = 0; (i < em_n) && em[i]; i++);
2250
2251   /* According to this encoding method, the first byte of the encoded
2252      message should be zero.  This byte is lost.  */
2253
2254   if (! ((em_n >= 10)
2255          && (em_n == (k - 1))
2256          && (em[0] == 0x02)
2257          && (i < em_n)
2258          && ((i - 1) >= 8)))
2259     {
2260       err = gcry_error (GPG_ERR_DECRYPT_FAILED);
2261       goto out;
2262     }
2263
2264   i++;
2265   buffer = gcry_malloc (em_n - i);
2266   if (! buffer)
2267     {
2268       err = gcry_error_from_errno (errno);
2269       goto out;
2270     }
2271
2272   memcpy (buffer, em + i, em_n - i);
2273   err = _gcry_ac_io_write (ac_io_write, buffer, em_n - i);
2274
2275  out:
2276
2277   gcry_free (buffer);
2278   gcry_free (em);
2279
2280   return err;
2281 }
2282
2283 static gcry_error_t
2284 emsa_pkcs_v1_5_encode_data_cb (void *opaque,
2285                                unsigned char *buffer, size_t buffer_n)
2286 {
2287   gcry_md_hd_t md_handle;
2288
2289   md_handle = opaque;
2290   gcry_md_write (md_handle, buffer, buffer_n);
2291
2292   return 0;
2293 }
2294
2295
2296 /* Encode a message according to the Encoding Method for Signatures
2297    with Appendix `PKCS-V1_5' (EMSA-PKCS-V1_5).  */
2298 static gcry_error_t
2299 emsa_pkcs_v1_5_encode (unsigned int flags, void *opts,
2300                        gcry_ac_io_t *ac_io_read,
2301                        gcry_ac_io_t *ac_io_write)
2302 {
2303   gcry_ac_emsa_pkcs_v1_5_t *options;
2304   gcry_error_t err;
2305   gcry_md_hd_t md;
2306   unsigned char *t;
2307   size_t t_n;
2308   unsigned char *h;
2309   size_t h_n;
2310   unsigned char *ps;
2311   size_t ps_n;
2312   unsigned char *buffer;
2313   size_t buffer_n;
2314   unsigned char asn[100];       /* FIXME, always enough?  */
2315   size_t asn_n;
2316   unsigned int i;
2317
2318   (void)flags;
2319   
2320   options = opts;
2321   buffer = NULL;
2322   md = NULL;
2323   ps = NULL;
2324   t = NULL;
2325
2326   /* Create hashing handle and get the necessary information.  */
2327   err = gcry_md_open (&md, options->md, 0);
2328   if (err)
2329     goto out;
2330
2331   asn_n = DIM (asn);
2332   err = gcry_md_algo_info (options->md, GCRYCTL_GET_ASNOID, asn, &asn_n);
2333   if (err)
2334     goto out;
2335
2336   h_n = gcry_md_get_algo_dlen (options->md);
2337
2338   err = _gcry_ac_io_process (ac_io_read, emsa_pkcs_v1_5_encode_data_cb, md);
2339   if (err)
2340     goto out;
2341
2342   h = gcry_md_read (md, 0);
2343
2344   /* Encode the algorithm ID for the hash function and the hash value
2345      into an ASN.1 value of type DigestInfo with the Distinguished
2346      Encoding Rules (DER), where the type DigestInfo has the syntax:
2347
2348      DigestInfo ::== SEQUENCE {
2349      digestAlgorithm AlgorithmIdentifier,
2350      digest OCTET STRING
2351      }
2352
2353      The first field identifies the hash function and the second
2354      contains the hash value.  Let T be the DER encoding of the
2355      DigestInfo value and let tLen be the length in octets of T.  */
2356
2357   t_n = asn_n + h_n;
2358   t = gcry_malloc (t_n);
2359   if (! t)
2360     {
2361       err = gcry_error_from_errno (errno);
2362       goto out;
2363     }
2364
2365   for (i = 0; i < asn_n; i++)
2366     t[i] = asn[i];
2367   for (i = 0; i < h_n; i++)
2368     t[asn_n + i] = h[i];
2369
2370   /* If emLen < tLen + 11, output "intended encoded message length
2371      too short" and stop.  */
2372   if (options->em_n < t_n + 11)
2373     {
2374       err = gcry_error (GPG_ERR_TOO_SHORT);
2375       goto out;
2376     }
2377
2378   /* Generate an octet string PS consisting of emLen - tLen - 3 octets
2379      with hexadecimal value 0xFF.  The length of PS will be at least 8
2380      octets.  */
2381   ps_n = options->em_n - t_n - 3;
2382   ps = gcry_malloc (ps_n);
2383   if (! ps)
2384     {
2385       err = gcry_error_from_errno (errno);
2386       goto out;
2387     }
2388   for (i = 0; i < ps_n; i++)
2389     ps[i] = 0xFF;
2390
2391   /* Concatenate PS, the DER encoding T, and other padding to form the
2392      encoded message EM as:
2393
2394      EM = 0x00 || 0x01 || PS || 0x00 || T.  */
2395
2396   buffer_n = ps_n + t_n + 3;
2397   buffer = gcry_malloc (buffer_n);
2398   if (! buffer)
2399     {
2400       err = gcry_error_from_errno (errno);
2401       goto out;
2402     }
2403
2404   buffer[0] = 0x00;
2405   buffer[1] = 0x01;
2406   for (i = 0; i < ps_n; i++)
2407     buffer[2 + i] = ps[i];
2408   buffer[2 + ps_n] = 0x00;
2409   for (i = 0; i < t_n; i++)
2410     buffer[3 + ps_n + i] = t[i];
2411
2412   err = _gcry_ac_io_write (ac_io_write, buffer, buffer_n);
2413
2414  out:
2415
2416   gcry_md_close (md);
2417
2418   gcry_free (buffer);
2419   gcry_free (ps);
2420   gcry_free (t);
2421
2422   return err;
2423 }
2424
2425 /* `Actions' for data_dencode().  */
2426 typedef enum dencode_action
2427   {
2428     DATA_ENCODE,
2429     DATA_DECODE,
2430   }
2431 dencode_action_t;
2432
2433 /* Encode or decode a message according to the the encoding method
2434    METHOD; ACTION specifies wether the message that is contained in
2435    BUFFER_IN and of length BUFFER_IN_N should be encoded or decoded.
2436    The resulting message will be stored in a newly allocated buffer in
2437    BUFFER_OUT and BUFFER_OUT_N.  */
2438 static gcry_error_t
2439 ac_data_dencode (gcry_ac_em_t method, dencode_action_t action,
2440                  unsigned int flags, void *options,
2441                  gcry_ac_io_t *ac_io_read,
2442                  gcry_ac_io_t *ac_io_write)
2443 {
2444   struct
2445   {
2446     gcry_ac_em_t method;
2447     gcry_ac_em_dencode_t encode;
2448     gcry_ac_em_dencode_t decode;
2449   } methods[] =
2450     {
2451       { GCRY_AC_EME_PKCS_V1_5,
2452         eme_pkcs_v1_5_encode, eme_pkcs_v1_5_decode },
2453       { GCRY_AC_EMSA_PKCS_V1_5,
2454         emsa_pkcs_v1_5_encode, NULL },
2455     };
2456   size_t methods_n;
2457   gcry_error_t err;
2458   unsigned int i;
2459
2460   methods_n = sizeof (methods) / sizeof (*methods);
2461
2462   for (i = 0; i < methods_n; i++)
2463     if (methods[i].method == method)
2464       break;
2465   if (i == methods_n)
2466     {
2467       err = gcry_error (GPG_ERR_NOT_FOUND);     /* FIXME? */
2468       goto out;
2469     }
2470
2471   err = 0;
2472   switch (action)
2473     {
2474     case DATA_ENCODE:
2475       if (methods[i].encode)
2476         /* FIXME? */
2477         err = (*methods[i].encode) (flags, options, ac_io_read, ac_io_write);
2478       break;
2479
2480     case DATA_DECODE:
2481       if (methods[i].decode)
2482         /* FIXME? */
2483         err = (*methods[i].decode) (flags, options, ac_io_read, ac_io_write);
2484       break;
2485
2486     default:
2487       err = gcry_error (GPG_ERR_INV_ARG);
2488       break;
2489     }
2490
2491  out:
2492
2493   return err;
2494 }
2495
2496 /* Encode a message according to the encoding method METHOD.  OPTIONS
2497    must be a pointer to a method-specific structure
2498    (gcry_ac_em*_t).  */
2499 gcry_error_t
2500 _gcry_ac_data_encode (gcry_ac_em_t method,
2501                       unsigned int flags, void *options,
2502                       gcry_ac_io_t *ac_io_read,
2503                       gcry_ac_io_t *ac_io_write)
2504 {
2505   return ac_data_dencode (method, DATA_ENCODE, flags, options,
2506                           ac_io_read, ac_io_write);
2507 }
2508
2509 /* Dencode a message according to the encoding method METHOD.  OPTIONS
2510    must be a pointer to a method-specific structure
2511    (gcry_ac_em*_t).  */
2512 gcry_error_t
2513 _gcry_ac_data_decode (gcry_ac_em_t method,
2514                       unsigned int flags, void *options,
2515                       gcry_ac_io_t *ac_io_read,
2516                       gcry_ac_io_t *ac_io_write)
2517 {
2518   return ac_data_dencode (method, DATA_DECODE, flags, options,
2519                           ac_io_read, ac_io_write);
2520 }
2521
2522 /* Convert an MPI into an octet string.  */
2523 void
2524 _gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
2525 {
2526   unsigned long digit;
2527   gcry_mpi_t base;
2528   unsigned int i;
2529   unsigned int n;
2530   gcry_mpi_t m;
2531   gcry_mpi_t d;
2532
2533   base = gcry_mpi_new (0);
2534   gcry_mpi_set_ui (base, 256);
2535
2536   n = 0;
2537   m = gcry_mpi_copy (mpi);
2538   while (gcry_mpi_cmp_ui (m, 0))
2539     {
2540       n++;
2541       gcry_mpi_div (m, NULL, m, base, 0);
2542     }
2543
2544   gcry_mpi_set (m, mpi);
2545   d = gcry_mpi_new (0);
2546   for (i = 0; (i < n) && (i < os_n); i++)
2547     {
2548       gcry_mpi_mod (d, m, base);
2549       _gcry_mpi_get_ui (d, &digit);
2550       gcry_mpi_div (m, NULL, m, base, 0);
2551       os[os_n - i - 1] = (digit & 0xFF);
2552     }
2553
2554   for (; i < os_n; i++)
2555     os[os_n - i - 1] = 0;
2556
2557   gcry_mpi_release (base);
2558   gcry_mpi_release (d);
2559   gcry_mpi_release (m);
2560 }
2561
2562 /* Convert an MPI into an newly allocated octet string.  */
2563 gcry_error_t
2564 _gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, size_t *os_n)
2565 {
2566   unsigned char *buffer;
2567   size_t buffer_n;
2568   gcry_error_t err;
2569   unsigned int nbits;
2570
2571   nbits = gcry_mpi_get_nbits (mpi);
2572   buffer_n = (nbits + 7) / 8;
2573   buffer = gcry_malloc (buffer_n);
2574   if (! buffer)
2575     {
2576       err = gcry_error_from_errno (errno);
2577       goto out;
2578     }
2579       
2580   _gcry_ac_mpi_to_os (mpi, buffer, buffer_n);
2581   *os = buffer;
2582   *os_n = buffer_n;
2583   err = 0;
2584
2585  out:
2586
2587   return err;
2588 }
2589
2590
2591 /* Convert an octet string into an MPI.  */
2592 void
2593 _gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
2594 {
2595   unsigned int i;
2596   gcry_mpi_t xi;
2597   gcry_mpi_t x;
2598   gcry_mpi_t a;
2599   
2600   a = gcry_mpi_new (0);
2601   gcry_mpi_set_ui (a, 1);
2602   x = gcry_mpi_new (0);
2603   gcry_mpi_set_ui (x, 0);
2604   xi = gcry_mpi_new (0);
2605
2606   for (i = 0; i < os_n; i++)
2607     {
2608       gcry_mpi_mul_ui (xi, a, os[os_n - i - 1]);
2609       gcry_mpi_add (x, x, xi);
2610       gcry_mpi_mul_ui (a, a, 256);
2611     }
2612       
2613   gcry_mpi_release (xi);
2614   gcry_mpi_release (a);
2615
2616   gcry_mpi_set (mpi, x);
2617   gcry_mpi_release (x);         /* FIXME: correct? */
2618 }
2619
2620
2621 \f
2622 /* 
2623  * Implementation of Encryption Schemes (ES) and Signature Schemes
2624  * with Appendix (SSA).
2625  */
2626
2627 /* Schemes consist of two things: encoding methods and cryptographic
2628    primitives.
2629
2630    Since encoding methods are accessible through a common API with
2631    method-specific options passed as an anonymous struct, schemes have
2632    to provide functions that construct this method-specific structure;
2633    this is what the functions of type `gcry_ac_dencode_prepare_t' are
2634    there for.  */
2635
2636 typedef gcry_error_t (*gcry_ac_dencode_prepare_t) (gcry_ac_handle_t handle,
2637                                                    gcry_ac_key_t key,
2638                                                    void *opts,
2639                                                    void *opts_em);
2640
2641 /* The `dencode_prepare' function for ES-PKCS-V1_5.  */
2642 static gcry_error_t
2643 ac_es_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
2644                                  void *opts, void *opts_em)
2645 {
2646   gcry_ac_eme_pkcs_v1_5_t *options_em;
2647   unsigned int nbits;
2648   gcry_error_t err;
2649
2650   (void)opts;
2651
2652   err = _gcry_ac_key_get_nbits (handle, key, &nbits);
2653   if (err)
2654     goto out;
2655
2656   options_em = opts_em;
2657   options_em->key_size = nbits;
2658
2659  out:
2660
2661   return err;
2662 }
2663
2664 /* The `dencode_prepare' function for SSA-PKCS-V1_5.  */
2665 static gcry_error_t
2666 ac_ssa_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
2667                                   void *opts, void *opts_em)
2668 {
2669   gcry_ac_emsa_pkcs_v1_5_t *options_em;
2670   gcry_ac_ssa_pkcs_v1_5_t *options;
2671   gcry_error_t err;
2672   unsigned int k;
2673
2674   options_em = opts_em;
2675   options = opts;
2676
2677   err = _gcry_ac_key_get_nbits (handle, key, &k);
2678   if (err)
2679     goto out;
2680
2681   k = (k + 7) / 8;
2682   options_em->md = options->md;
2683   options_em->em_n = k;
2684
2685  out:
2686
2687   return err;
2688 }
2689
2690 /* Type holding the information about each supported
2691    Encryption/Signature Scheme.  */
2692 typedef struct ac_scheme
2693 {
2694   gcry_ac_scheme_t scheme;
2695   gcry_ac_em_t scheme_encoding;
2696   gcry_ac_dencode_prepare_t dencode_prepare;
2697   size_t options_em_n;
2698 } ac_scheme_t;
2699
2700 /* List of supported Schemes.  */
2701 static ac_scheme_t ac_schemes[] =
2702   {
2703     { GCRY_AC_ES_PKCS_V1_5, GCRY_AC_EME_PKCS_V1_5,
2704       ac_es_dencode_prepare_pkcs_v1_5,
2705       sizeof (gcry_ac_eme_pkcs_v1_5_t) },
2706     { GCRY_AC_SSA_PKCS_V1_5, GCRY_AC_EMSA_PKCS_V1_5,
2707       ac_ssa_dencode_prepare_pkcs_v1_5,
2708       sizeof (gcry_ac_emsa_pkcs_v1_5_t) }
2709   };
2710
2711 /* Lookup a scheme by it's ID.  */
2712 static ac_scheme_t *
2713 ac_scheme_get (gcry_ac_scheme_t scheme)
2714 {
2715   ac_scheme_t *ac_scheme;
2716   unsigned int i;
2717
2718   for (i = 0; i < DIM (ac_schemes); i++)
2719     if (scheme == ac_schemes[i].scheme)
2720       break;
2721   if (i == DIM (ac_schemes))
2722     ac_scheme = NULL;
2723   else
2724     ac_scheme = ac_schemes + i;
2725
2726   return ac_scheme;
2727 }
2728
2729 /* Prepares the encoding/decoding by creating an according option
2730    structure.  */
2731 static gcry_error_t
2732 ac_dencode_prepare (gcry_ac_handle_t handle, gcry_ac_key_t key, void *opts,
2733                     ac_scheme_t scheme, void **opts_em)
2734 {
2735   gcry_error_t err;
2736   void *options_em;
2737
2738   options_em = gcry_malloc (scheme.options_em_n);
2739   if (! options_em)
2740     {
2741       err = gcry_error_from_errno (errno);
2742       goto out;
2743     }
2744   
2745   err = (*scheme.dencode_prepare) (handle, key, opts, options_em);
2746   if (err)
2747     goto out;
2748
2749   *opts_em = options_em;
2750
2751  out:
2752
2753   if (err)
2754     free (options_em);
2755
2756   return err;
2757 }
2758
2759 /* Convert a data set into a single MPI; currently, this is only
2760    supported for data sets containing a single MPI.  */
2761 static gcry_error_t
2762 ac_data_set_to_mpi (gcry_ac_data_t data, gcry_mpi_t *mpi)
2763 {
2764   gcry_error_t err;
2765   gcry_mpi_t mpi_new;
2766   unsigned int elems;
2767
2768   elems = _gcry_ac_data_length (data);
2769
2770   if (elems != 1)
2771     {
2772       /* FIXME: I guess, we should be more flexible in this respect by
2773          allowing the actual encryption/signature schemes to implement
2774          this conversion mechanism.  */
2775       err = gcry_error (GPG_ERR_CONFLICT);
2776       goto out;
2777     }
2778
2779   err = _gcry_ac_data_get_index (data, GCRY_AC_FLAG_COPY, 0, NULL, &mpi_new);
2780   if (err)
2781     goto out;
2782
2783   *mpi = mpi_new;
2784
2785  out:
2786
2787   return err;
2788 }
2789
2790 /* Encrypts the plain text message contained in M, which is of size
2791    M_N, with the public key KEY_PUBLIC according to the Encryption
2792    Scheme SCHEME_ID.  HANDLE is used for accessing the low-level
2793    cryptographic primitives.  If OPTS is not NULL, it has to be an
2794    anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
2795    The encrypted message will be stored in C and C_N.  */
2796 gcry_error_t
2797 _gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
2798                               gcry_ac_scheme_t scheme_id,
2799                               unsigned int flags, void *opts,
2800                               gcry_ac_key_t key,
2801                               gcry_ac_io_t *io_message,
2802                               gcry_ac_io_t *io_cipher)
2803 {
2804   gcry_error_t err;
2805   gcry_ac_io_t io_em;
2806   unsigned char *em;
2807   size_t em_n;
2808   gcry_mpi_t mpi_plain;
2809   gcry_ac_data_t data_encrypted;
2810   gcry_mpi_t mpi_encrypted;
2811   unsigned char *buffer;
2812   size_t buffer_n;
2813   void *opts_em;
2814   ac_scheme_t *scheme;
2815
2816   (void)flags;
2817
2818   data_encrypted = NULL;
2819   mpi_encrypted = NULL;
2820   mpi_plain = NULL;
2821   opts_em = NULL;
2822   buffer = NULL;
2823   em = NULL;
2824
2825   scheme = ac_scheme_get (scheme_id);
2826   if (! scheme)
2827     {
2828       err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
2829       goto out;
2830     }
2831
2832   if (key->type != GCRY_AC_KEY_PUBLIC)
2833     {
2834       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
2835       goto out;
2836     }
2837
2838   err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
2839   if (err)
2840     goto out;
2841
2842   _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
2843                     GCRY_AC_IO_STRING, &em, &em_n);
2844
2845   err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
2846                               io_message, &io_em);
2847   if (err)
2848     goto out;
2849
2850   mpi_plain = gcry_mpi_snew (0);
2851   gcry_ac_os_to_mpi (mpi_plain, em, em_n);
2852
2853   err = _gcry_ac_data_encrypt (handle, 0, key, mpi_plain, &data_encrypted);
2854   if (err)
2855     goto out;
2856
2857   err = ac_data_set_to_mpi (data_encrypted, &mpi_encrypted);
2858   if (err)
2859     goto out;
2860
2861   err = _gcry_ac_mpi_to_os_alloc (mpi_encrypted, &buffer, &buffer_n);
2862   if (err)
2863     goto out;
2864
2865   err = _gcry_ac_io_write (io_cipher, buffer, buffer_n);
2866
2867  out:
2868
2869   gcry_ac_data_destroy (data_encrypted);
2870   gcry_mpi_release (mpi_encrypted);
2871   gcry_mpi_release (mpi_plain);
2872   gcry_free (opts_em);
2873   gcry_free (buffer);
2874   gcry_free (em);
2875
2876   return err;
2877 }
2878
2879 /* Decryptes the cipher message contained in C, which is of size C_N,
2880    with the secret key KEY_SECRET according to the Encryption Scheme
2881    SCHEME_ID.  Handle is used for accessing the low-level
2882    cryptographic primitives.  If OPTS is not NULL, it has to be an
2883    anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
2884    The decrypted message will be stored in M and M_N.  */
2885 gcry_error_t
2886 _gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
2887                               gcry_ac_scheme_t scheme_id,
2888                               unsigned int flags, void *opts,
2889                               gcry_ac_key_t key,
2890                               gcry_ac_io_t *io_cipher,
2891                               gcry_ac_io_t *io_message)
2892 {
2893   gcry_ac_io_t io_em;
2894   gcry_error_t err;
2895   gcry_ac_data_t data_encrypted;
2896   unsigned char *em;
2897   size_t em_n;
2898   gcry_mpi_t mpi_encrypted;
2899   gcry_mpi_t mpi_decrypted;
2900   void *opts_em;
2901   ac_scheme_t *scheme;
2902   char *elements_enc;
2903   size_t elements_enc_n;
2904   unsigned char *c;
2905   size_t c_n;
2906
2907   (void)flags;
2908
2909   data_encrypted = NULL;
2910   mpi_encrypted = NULL;
2911   mpi_decrypted = NULL;
2912   elements_enc = NULL;
2913   opts_em = NULL;
2914   em = NULL;
2915   c = NULL;
2916
2917   scheme = ac_scheme_get (scheme_id);
2918   if (! scheme)
2919     {
2920       err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
2921       goto out;
2922     }
2923
2924   if (key->type != GCRY_AC_KEY_SECRET)
2925     {
2926       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
2927       goto out;
2928     }
2929
2930   err = _gcry_ac_io_read_all (io_cipher, &c, &c_n);
2931   if (err)
2932     goto out;
2933
2934   mpi_encrypted = gcry_mpi_snew (0);
2935   gcry_ac_os_to_mpi (mpi_encrypted, c, c_n);
2936
2937   err = _gcry_pk_get_elements (handle->algorithm, &elements_enc, NULL);
2938   if (err)
2939     goto out;
2940
2941   elements_enc_n = strlen (elements_enc);
2942   if (elements_enc_n != 1)
2943     {
2944       /* FIXME? */
2945       err = gcry_error (GPG_ERR_CONFLICT);
2946       goto out;
2947     }
2948
2949   err = _gcry_ac_data_new (&data_encrypted);
2950   if (err)
2951     goto out;
2952
2953   err = _gcry_ac_data_set (data_encrypted, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
2954                            elements_enc, mpi_encrypted);
2955   if (err)
2956     goto out;
2957
2958   err = _gcry_ac_data_decrypt (handle, 0, key, &mpi_decrypted, data_encrypted);
2959   if (err)
2960     goto out;
2961
2962   err = _gcry_ac_mpi_to_os_alloc (mpi_decrypted, &em, &em_n);
2963   if (err)
2964     goto out;
2965
2966   err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
2967   if (err)
2968     goto out;
2969
2970   _gcry_ac_io_init (&io_em, GCRY_AC_IO_READABLE,
2971                     GCRY_AC_IO_STRING, em, em_n);
2972
2973   err = _gcry_ac_data_decode (scheme->scheme_encoding, 0, opts_em,
2974                               &io_em, io_message);
2975   if (err)
2976     goto out;
2977
2978  out:
2979   
2980   _gcry_ac_data_destroy (data_encrypted);
2981   gcry_mpi_release (mpi_encrypted);
2982   gcry_mpi_release (mpi_decrypted);
2983   free (elements_enc);
2984   gcry_free (opts_em);
2985   gcry_free (em);
2986   gcry_free (c);
2987
2988   return err;
2989 }
2990
2991
2992 /* Signs the message contained in M, which is of size M_N, with the
2993    secret key KEY according to the Signature Scheme SCHEME_ID.  Handle
2994    is used for accessing the low-level cryptographic primitives.  If
2995    OPTS is not NULL, it has to be an anonymous structure specific to
2996    the chosen scheme (gcry_ac_ssa_*_t).  The signed message will be
2997    stored in S and S_N.  */
2998 gcry_error_t
2999 _gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
3000                            gcry_ac_scheme_t scheme_id,
3001                            unsigned int flags, void *opts,
3002                            gcry_ac_key_t key,
3003                            gcry_ac_io_t *io_message,
3004                            gcry_ac_io_t *io_signature)
3005 {
3006   gcry_ac_io_t io_em;
3007   gcry_error_t err;
3008   gcry_ac_data_t data_signed;
3009   unsigned char *em;
3010   size_t em_n;
3011   gcry_mpi_t mpi;
3012   void *opts_em;
3013   unsigned char *buffer;
3014   size_t buffer_n;
3015   gcry_mpi_t mpi_signed;
3016   ac_scheme_t *scheme;
3017
3018   (void)flags;
3019
3020   data_signed = NULL;
3021   mpi_signed = NULL;
3022   opts_em = NULL;
3023   buffer = NULL;
3024   mpi = NULL;
3025   em = NULL;
3026
3027   if (key->type != GCRY_AC_KEY_SECRET)
3028     {
3029       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
3030       goto out;
3031     }
3032
3033   scheme = ac_scheme_get (scheme_id);
3034   if (! scheme)
3035     {
3036       /* FIXME: adjust api of scheme_get in respect to err codes.  */
3037       err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
3038       goto out;
3039     }
3040
3041   err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
3042   if (err)
3043     goto out;
3044
3045   _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
3046                     GCRY_AC_IO_STRING, &em, &em_n);
3047
3048   err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
3049                               io_message, &io_em);
3050   if (err)
3051     goto out;
3052
3053   mpi = gcry_mpi_new (0);
3054   _gcry_ac_os_to_mpi (mpi, em, em_n);
3055
3056   err = _gcry_ac_data_sign (handle, key, mpi, &data_signed);
3057   if (err)
3058     goto out;
3059
3060   err = ac_data_set_to_mpi (data_signed, &mpi_signed);
3061   if (err)
3062     goto out;
3063
3064   err = _gcry_ac_mpi_to_os_alloc (mpi_signed, &buffer, &buffer_n);
3065   if (err)
3066     goto out;
3067
3068   err = _gcry_ac_io_write (io_signature, buffer, buffer_n);
3069
3070  out:
3071
3072   _gcry_ac_data_destroy (data_signed);
3073   gcry_mpi_release (mpi_signed);
3074   gcry_mpi_release (mpi);
3075   gcry_free (opts_em);
3076   gcry_free (buffer);
3077   gcry_free (em);
3078
3079   return err;
3080 }
3081
3082 /* Verifies that the signature contained in S, which is of length S_N,
3083    is indeed the result of signing the message contained in M, which
3084    is of size M_N, with the secret key belonging to the public key
3085    KEY_PUBLIC.  If OPTS is not NULL, it has to be an anonymous
3086    structure (gcry_ac_ssa_*_t) specific to the Signature Scheme, whose
3087    ID is contained in SCHEME_ID.  */
3088 gcry_error_t
3089 _gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
3090                              gcry_ac_scheme_t scheme_id,
3091                              unsigned int flags, void *opts,
3092                              gcry_ac_key_t key,
3093                              gcry_ac_io_t *io_message,
3094                              gcry_ac_io_t *io_signature)
3095 {
3096   gcry_ac_io_t io_em;
3097   gcry_error_t err;
3098   gcry_ac_data_t data_signed;
3099   unsigned char *em;
3100   size_t em_n;
3101   void *opts_em;
3102   gcry_mpi_t mpi_signature;
3103   gcry_mpi_t mpi_data;
3104   ac_scheme_t *scheme;
3105   char *elements_sig;
3106   size_t elements_sig_n;
3107   unsigned char *s;
3108   size_t s_n;
3109
3110   (void)flags;
3111
3112   mpi_signature = NULL;
3113   elements_sig = NULL;
3114   data_signed = NULL;
3115   mpi_data = NULL;
3116   opts_em = NULL;
3117   em = NULL;
3118   s = NULL;
3119
3120   if (key->type != GCRY_AC_KEY_PUBLIC)
3121     {
3122       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
3123       goto out;
3124     }
3125
3126   scheme = ac_scheme_get (scheme_id);
3127   if (! scheme)
3128     {
3129       err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
3130       goto out;
3131     }
3132
3133   err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
3134   if (err)
3135     goto out;
3136
3137   _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
3138                     GCRY_AC_IO_STRING, &em, &em_n);
3139
3140   err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
3141                               io_message, &io_em);
3142   if (err)
3143     goto out;
3144
3145   mpi_data = gcry_mpi_new (0);
3146   _gcry_ac_os_to_mpi (mpi_data, em, em_n);
3147
3148   err = _gcry_ac_io_read_all (io_signature, &s, &s_n);
3149   if (err)
3150     goto out;
3151
3152   mpi_signature = gcry_mpi_new (0);
3153   _gcry_ac_os_to_mpi (mpi_signature, s, s_n);
3154
3155   err = _gcry_pk_get_elements (handle->algorithm, NULL, &elements_sig);
3156   if (err)
3157     goto out;
3158
3159   elements_sig_n = strlen (elements_sig);
3160   if (elements_sig_n != 1)
3161     {
3162       /* FIXME? */
3163       err = gcry_error (GPG_ERR_CONFLICT);
3164       goto out;
3165     }
3166
3167   err = _gcry_ac_data_new (&data_signed);
3168   if (err)
3169     goto out;
3170
3171   err = _gcry_ac_data_set (data_signed, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
3172                            elements_sig, mpi_signature);
3173   if (err)
3174     goto out;
3175
3176   gcry_mpi_release (mpi_signature);
3177   mpi_signature = NULL;
3178   
3179   err = _gcry_ac_data_verify (handle, key, mpi_data, data_signed);
3180
3181  out:
3182
3183   _gcry_ac_data_destroy (data_signed);
3184   gcry_mpi_release (mpi_signature);
3185   gcry_mpi_release (mpi_data);
3186   free (elements_sig);
3187   gcry_free (opts_em);
3188   gcry_free (em);
3189   gcry_free (s);
3190
3191   return err;
3192 }
3193
3194
3195 /* 
3196  * General functions.
3197  */
3198
3199 gcry_err_code_t
3200 _gcry_ac_init (void)
3201 {
3202   return 0;
3203 }