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