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