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