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