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