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