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