2004-08-09 Moritz Schulte <moritz@g10code.com>
[libgcrypt.git] / cipher / pubkey.c
1 /* pubkey.c  -  pubkey dispatcher
2  * Copyright (C) 1998,1999,2000,2002,2003 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 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27
28 #include "g10lib.h"
29 #include "mpi.h"
30 #include "cipher.h"
31 #include "ath.h"
32
33 static gcry_err_code_t pubkey_decrypt (int algo, gcry_mpi_t *result,
34                                        gcry_mpi_t *data, gcry_mpi_t *skey,
35                                        int flags);
36 static gcry_err_code_t pubkey_sign (int algo, gcry_mpi_t *resarr,
37                                     gcry_mpi_t hash, gcry_mpi_t *skey);
38 static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash,
39                                       gcry_mpi_t *data, gcry_mpi_t *pkey,
40                                      int (*cmp) (void *, gcry_mpi_t),
41                                       void *opaque);
42
43 /* This is the list of the default public-key ciphers included in
44    libgcrypt.  */
45 static struct pubkey_table_entry
46 {
47   gcry_pk_spec_t *pubkey;
48   unsigned int algorithm;
49 } pubkey_table[] =
50   {
51 #if USE_RSA
52     { &_gcry_pubkey_spec_rsa, GCRY_PK_RSA },
53 #endif
54 #if USE_ELGAMAL
55     { &_gcry_pubkey_spec_elg, GCRY_PK_ELG },
56 #endif
57 #if USE_DSA
58     { &_gcry_pubkey_spec_dsa, GCRY_PK_DSA },
59 #endif
60     { NULL, 0 },
61   };
62
63 /* List of registered ciphers.  */
64 static gcry_module_t pubkeys_registered;
65
66 /* This is the lock protecting PUBKEYS_REGISTERED.  */
67 static ath_mutex_t pubkeys_registered_lock;
68
69 /* Flag to check wether the default pubkeys have already been
70    registered.  */
71 static int default_pubkeys_registered;
72
73 /* Convenient macro for registering the default digests.  */
74 #define REGISTER_DEFAULT_PUBKEYS                   \
75   do                                               \
76     {                                              \
77       ath_mutex_lock (&pubkeys_registered_lock);   \
78       if (! default_pubkeys_registered)            \
79         {                                          \
80           gcry_pk_register_default ();         \
81           default_pubkeys_registered = 1;          \
82         }                                          \
83       ath_mutex_unlock (&pubkeys_registered_lock); \
84     }                                              \
85   while (0)
86
87 /* These dummy functions are used in case a cipher implementation
88    refuses to provide it's own functions.  */
89
90 static gcry_err_code_t
91 dummy_generate (int algorithm, unsigned int nbits, unsigned long dummy,
92                 gcry_mpi_t *skey, gcry_mpi_t **retfactors)
93 {
94   log_bug ("no generate() for %d\n", algorithm);
95   return GPG_ERR_PUBKEY_ALGO;
96 }
97
98 static gcry_err_code_t
99 dummy_check_secret_key (int algorithm, gcry_mpi_t *skey)
100 {
101   log_bug ("no check_secret_key() for %d\n", algorithm);
102   return GPG_ERR_PUBKEY_ALGO;
103 }
104
105 static gcry_err_code_t
106 dummy_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
107                gcry_mpi_t *pkey, int flags)
108 {
109   log_bug ("no encrypt() for %d\n", algorithm);
110   return GPG_ERR_PUBKEY_ALGO;
111 }
112
113 static gcry_err_code_t
114 dummy_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
115                gcry_mpi_t *skey, int flags)
116 {
117   log_bug ("no decrypt() for %d\n", algorithm);
118   return GPG_ERR_PUBKEY_ALGO;
119 }
120
121 static gcry_err_code_t
122 dummy_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
123             gcry_mpi_t *skey)
124 {
125   log_bug ("no sign() for %d\n", algorithm);
126   return GPG_ERR_PUBKEY_ALGO;
127 }
128
129 static gcry_err_code_t
130 dummy_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
131               gcry_mpi_t *pkey,
132               int (*cmp) (void *, gcry_mpi_t), void *opaquev)
133 {
134   log_bug ("no verify() for %d\n", algorithm);
135   return GPG_ERR_PUBKEY_ALGO;
136 }
137
138 static unsigned
139 dummy_get_nbits (int algorithm, gcry_mpi_t *pkey)
140 {
141   log_bug ("no get_nbits() for %d\n", algorithm);
142   return 0;
143 }
144
145 /* Internal function.  Register all the pubkeys included in
146    PUBKEY_TABLE.  Returns zero on success or an error code.  */
147 static void
148 gcry_pk_register_default (void)
149 {
150   gcry_err_code_t err = 0;
151   int i;
152   
153   for (i = 0; (! err) && pubkey_table[i].pubkey; i++)
154     {
155 #define pubkey_use_dummy(func)                       \
156       if (! pubkey_table[i].pubkey->func)            \
157         pubkey_table[i].pubkey->func = dummy_##func;
158
159       pubkey_use_dummy (generate);
160       pubkey_use_dummy (check_secret_key);
161       pubkey_use_dummy (encrypt);
162       pubkey_use_dummy (decrypt);
163       pubkey_use_dummy (sign);
164       pubkey_use_dummy (verify);
165       pubkey_use_dummy (get_nbits);
166 #undef pubkey_use_dummy
167       err = _gcry_module_add (&pubkeys_registered,
168                               pubkey_table[i].algorithm,
169                               (void *) pubkey_table[i].pubkey, NULL);
170     }
171
172   if (err)
173     BUG ();
174 }
175
176 /* Internal callback function.  Used via _gcry_module_lookup.  */
177 static int
178 gcry_pk_lookup_func_name (void *spec, void *data)
179 {
180   gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) spec;
181   char *name = (char *) data;
182   char **aliases = pubkey->aliases;
183   int ret = stricmp (name, pubkey->name);
184
185   while (ret && *aliases)
186     ret = stricmp (name, *aliases++);
187
188   return ! ret;
189 }
190
191 /* Internal function.  Lookup a pubkey entry by it's name.  */
192 static gcry_module_t 
193 gcry_pk_lookup_name (const char *name)
194 {
195   gcry_module_t pubkey;
196
197   pubkey = _gcry_module_lookup (pubkeys_registered, (void *) name,
198                                 gcry_pk_lookup_func_name);
199
200   return pubkey;
201 }
202
203 /* Register a new pubkey module whose specification can be found in
204    PUBKEY.  On success, a new algorithm ID is stored in ALGORITHM_ID
205    and a pointer representhing this module is stored in MODULE.  */
206 gcry_error_t
207 gcry_pk_register (gcry_pk_spec_t *pubkey,
208                   unsigned int *algorithm_id,
209                   gcry_module_t *module)
210 {
211   gcry_err_code_t err = GPG_ERR_NO_ERROR;
212   gcry_module_t mod;
213
214   ath_mutex_lock (&pubkeys_registered_lock);
215   err = _gcry_module_add (&pubkeys_registered, 0,
216                           (void *) pubkey, &mod);
217   ath_mutex_unlock (&pubkeys_registered_lock);
218
219   if (! err)
220     {
221       *module = mod;
222       *algorithm_id = mod->mod_id;
223     }
224
225   return err;
226 }
227
228 /* Unregister the pubkey identified by ID, which must have been
229    registered with gcry_pk_register.  */
230 void
231 gcry_pk_unregister (gcry_module_t module)
232 {
233   ath_mutex_lock (&pubkeys_registered_lock);
234   _gcry_module_release (module);
235   ath_mutex_unlock (&pubkeys_registered_lock);
236 }
237
238 static void
239 release_mpi_array (gcry_mpi_t *array)
240 {
241   for (; *array; array++)
242     {
243       mpi_free(*array);
244       *array = NULL;
245     }
246 }
247
248 /****************
249  * Map a string to the pubkey algo
250  */
251 int
252 gcry_pk_map_name (const char *string)
253 {
254   gcry_module_t pubkey;
255   int algorithm = 0;
256
257   if (!string)
258     return 0;
259
260   REGISTER_DEFAULT_PUBKEYS;
261
262   ath_mutex_lock (&pubkeys_registered_lock);
263   pubkey = gcry_pk_lookup_name (string);
264   if (pubkey)
265     {
266       algorithm = pubkey->mod_id;
267       _gcry_module_release (pubkey);
268     }
269   ath_mutex_unlock (&pubkeys_registered_lock);
270
271   return algorithm;
272 }
273
274
275 /****************
276  * Map a pubkey algo to a string
277  */
278 const char *
279 gcry_pk_algo_name (int algorithm)
280 {
281   const char *name = NULL;
282   gcry_module_t pubkey;
283
284   REGISTER_DEFAULT_PUBKEYS;
285
286   ath_mutex_lock (&pubkeys_registered_lock);
287   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
288   if (pubkey)
289     {
290       name = ((gcry_pk_spec_t *) pubkey->spec)->name;
291       _gcry_module_release (pubkey);
292     }
293   ath_mutex_unlock (&pubkeys_registered_lock);
294
295   return name;
296 }
297
298
299 /* A special version of gcry_pk_algo name to return the first aliased
300    name of the algorithm.  This is required to adhere to the spki
301    specs where the algorithm names are lowercase. */
302 const char *
303 _gcry_pk_aliased_algo_name (int algorithm)
304 {
305   const char *name = NULL;
306   gcry_module_t module;
307
308   REGISTER_DEFAULT_PUBKEYS;
309
310   ath_mutex_lock (&pubkeys_registered_lock);
311   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
312   if (module)
313     {
314       gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) module->spec;
315
316       name = pubkey->aliases? *pubkey->aliases : NULL;
317       if (!name || !*name)
318         name = pubkey->name;
319       _gcry_module_release (module);
320     }
321   ath_mutex_unlock (&pubkeys_registered_lock);
322
323   return name;
324 }
325
326
327 static void
328 disable_pubkey_algo (int algorithm)
329 {
330   gcry_module_t pubkey;
331
332   ath_mutex_lock (&pubkeys_registered_lock);
333   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
334   if (pubkey)
335     {
336       if (! (pubkey-> flags & FLAG_MODULE_DISABLED))
337         pubkey->flags |= FLAG_MODULE_DISABLED;
338       _gcry_module_release (pubkey);
339     }
340   ath_mutex_unlock (&pubkeys_registered_lock);
341 }
342
343
344 /****************
345  * A USE of 0 means: don't care.
346  */
347 static gcry_err_code_t
348 check_pubkey_algo (int algorithm, unsigned use)
349 {
350   gcry_err_code_t err = GPG_ERR_NO_ERROR;
351   gcry_pk_spec_t *pubkey;
352   gcry_module_t module;
353
354   REGISTER_DEFAULT_PUBKEYS;
355
356   ath_mutex_lock (&pubkeys_registered_lock);
357   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
358   if (module)
359     {
360       pubkey = (gcry_pk_spec_t *) module->spec;
361
362       if (((use & GCRY_PK_USAGE_SIGN)
363            && (! (pubkey->use & GCRY_PK_USAGE_SIGN)))
364           || ((use & GCRY_PK_USAGE_ENCR)
365               && (! (pubkey->use & GCRY_PK_USAGE_ENCR))))
366         err = GPG_ERR_WRONG_PUBKEY_ALGO;
367       else if (module->flags & FLAG_MODULE_DISABLED)
368         err = GPG_ERR_PUBKEY_ALGO;
369       _gcry_module_release (module);
370     }
371   else
372     err = GPG_ERR_PUBKEY_ALGO;
373   ath_mutex_unlock (&pubkeys_registered_lock);
374
375   return err;
376 }
377
378
379 /****************
380  * Return the number of public key material numbers
381  */
382 static int
383 pubkey_get_npkey (int algorithm)
384 {
385   gcry_module_t pubkey;
386   int npkey = 0;
387
388   REGISTER_DEFAULT_PUBKEYS;
389
390   ath_mutex_lock (&pubkeys_registered_lock);
391   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
392   if (pubkey)
393     {
394       npkey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_pkey);
395       _gcry_module_release (pubkey);
396     }
397   ath_mutex_unlock (&pubkeys_registered_lock);
398
399   return npkey;
400 }
401
402 /****************
403  * Return the number of secret key material numbers
404  */
405 static int
406 pubkey_get_nskey (int algorithm)
407 {
408   gcry_module_t pubkey;
409   int nskey = 0;
410
411   REGISTER_DEFAULT_PUBKEYS;
412
413   ath_mutex_lock (&pubkeys_registered_lock);
414   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
415   if (pubkey)
416     {
417       nskey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_skey);
418       _gcry_module_release (pubkey);
419     }
420   ath_mutex_unlock (&pubkeys_registered_lock);
421
422   return nskey;
423 }
424
425 /****************
426  * Return the number of signature material numbers
427  */
428 static int
429 pubkey_get_nsig (int algorithm)
430 {
431   gcry_module_t pubkey;
432   int nsig = 0;
433
434   REGISTER_DEFAULT_PUBKEYS;
435
436   ath_mutex_lock (&pubkeys_registered_lock);
437   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
438   if (pubkey)
439     {
440       nsig = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_sig);
441       _gcry_module_release (pubkey);
442     }
443   ath_mutex_unlock (&pubkeys_registered_lock);
444
445   return nsig;
446 }
447
448 /****************
449  * Return the number of encryption material numbers
450  */
451 static int
452 pubkey_get_nenc (int algorithm)
453 {
454   gcry_module_t pubkey;
455   int nenc = 0;
456
457   REGISTER_DEFAULT_PUBKEYS;
458
459   ath_mutex_lock (&pubkeys_registered_lock);
460   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
461   if (pubkey)
462     {
463       nenc = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_enc);
464       _gcry_module_release (pubkey);
465     }
466   ath_mutex_unlock (&pubkeys_registered_lock);
467
468   return nenc;
469 }
470
471
472 static gcry_err_code_t
473 pubkey_generate (int algorithm, unsigned int nbits, unsigned long use_e,
474                  gcry_mpi_t *skey, gcry_mpi_t **retfactors)
475 {
476   gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
477   gcry_module_t pubkey;
478
479   REGISTER_DEFAULT_PUBKEYS;
480
481   ath_mutex_lock (&pubkeys_registered_lock);
482   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
483   if (pubkey)
484     {
485       err = ((gcry_pk_spec_t *) pubkey->spec)->generate 
486         (algorithm, nbits, use_e, skey, retfactors);
487       _gcry_module_release (pubkey);
488     }
489   ath_mutex_unlock (&pubkeys_registered_lock);
490
491   return err;
492 }
493
494 static gcry_err_code_t
495 pubkey_check_secret_key (int algorithm, gcry_mpi_t *skey)
496 {
497   gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
498   gcry_module_t pubkey;
499
500   REGISTER_DEFAULT_PUBKEYS;
501
502   ath_mutex_lock (&pubkeys_registered_lock);
503   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
504   if (pubkey)
505     {
506       err = ((gcry_pk_spec_t *) pubkey->spec)->check_secret_key
507         (algorithm, skey);
508       _gcry_module_release (pubkey);
509     }
510   ath_mutex_unlock (&pubkeys_registered_lock);
511
512   return err;
513 }
514
515
516 /****************
517  * This is the interface to the public key encryption.  Encrypt DATA
518  * with PKEY and put it into RESARR which should be an array of MPIs
519  * of size PUBKEY_MAX_NENC (or less if the algorithm allows this -
520  * check with pubkey_get_nenc() )
521  */
522 static gcry_err_code_t
523 pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
524                 gcry_mpi_t *pkey, int flags)
525 {
526   gcry_pk_spec_t *pubkey;
527   gcry_module_t module;
528   gcry_err_code_t rc;
529   int i;
530
531   if (DBG_CIPHER)
532     {
533       log_debug ("pubkey_encrypt: algo=%d\n", algorithm);
534       for(i = 0; i < pubkey_get_npkey (algorithm); i++)
535         log_mpidump ("  pkey:", pkey[i]);
536       log_mpidump ("  data:", data);
537     }
538
539   ath_mutex_lock (&pubkeys_registered_lock);
540   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
541   if (module)
542     {
543       pubkey = (gcry_pk_spec_t *) module->spec;
544       rc = pubkey->encrypt (algorithm, resarr, data, pkey, flags);
545       _gcry_module_release (module);
546       goto ready;
547     }
548   rc = GPG_ERR_PUBKEY_ALGO;
549
550  ready:
551   ath_mutex_unlock (&pubkeys_registered_lock);
552
553   if (!rc && DBG_CIPHER)
554     {
555       for(i = 0; i < pubkey_get_nenc (algorithm); i++)
556         log_mpidump("  encr:", resarr[i] );
557     }
558   return rc;
559 }
560
561
562 /****************
563  * This is the interface to the public key decryption.
564  * ALGO gives the algorithm to use and this implicitly determines
565  * the size of the arrays.
566  * result is a pointer to a mpi variable which will receive a
567  * newly allocated mpi or NULL in case of an error.
568  */
569 static gcry_err_code_t
570 pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
571                 gcry_mpi_t *skey, int flags)
572 {
573   gcry_pk_spec_t *pubkey;
574   gcry_module_t module;
575   gcry_err_code_t rc;
576   int i;
577
578   *result = NULL; /* so the caller can always do a mpi_free */
579   if (DBG_CIPHER)
580     {
581       log_debug ("pubkey_decrypt: algo=%d\n", algorithm);
582       for(i = 0; i < pubkey_get_nskey (algorithm); i++)
583         log_mpidump ("  skey:", skey[i]);
584       for(i = 0; i < pubkey_get_nenc (algorithm); i++)
585         log_mpidump ("  data:", data[i]);
586     }
587
588   ath_mutex_lock (&pubkeys_registered_lock);
589   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
590   if (module)
591     {
592       pubkey = (gcry_pk_spec_t *) module->spec;
593       rc = pubkey->decrypt (algorithm, result, data, skey, flags);
594       _gcry_module_release (module);
595       goto ready;
596     }
597
598   rc = GPG_ERR_PUBKEY_ALGO;
599   
600  ready:
601   ath_mutex_unlock (&pubkeys_registered_lock);
602
603   if (! rc && DBG_CIPHER)
604     log_mpidump (" plain:", *result);
605
606   return rc;
607 }
608
609
610 /****************
611  * This is the interface to the public key signing.
612  * Sign data with skey and put the result into resarr which
613  * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
614  * algorithm allows this - check with pubkey_get_nsig() )
615  */
616 static gcry_err_code_t
617 pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
618              gcry_mpi_t *skey)
619 {
620   gcry_pk_spec_t *pubkey;
621   gcry_module_t module;
622   gcry_err_code_t rc;
623   int i;
624
625   if (DBG_CIPHER)
626     {
627       log_debug ("pubkey_sign: algo=%d\n", algorithm);
628       for(i = 0; i < pubkey_get_nskey (algorithm); i++)
629         log_mpidump ("  skey:", skey[i]);
630       log_mpidump("  data:", data );
631     }
632
633   ath_mutex_lock (&pubkeys_registered_lock);
634   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
635   if (module)
636     {
637       pubkey = (gcry_pk_spec_t *) module->spec;
638       rc = pubkey->sign (algorithm, resarr, data, skey);
639       _gcry_module_release (module);
640       goto ready;
641     }
642
643   rc = GPG_ERR_PUBKEY_ALGO;
644
645  ready:
646   ath_mutex_unlock (&pubkeys_registered_lock);
647
648   if (! rc && DBG_CIPHER)
649     for (i = 0; i < pubkey_get_nsig (algorithm); i++)
650       log_mpidump ("   sig:", resarr[i]);
651
652   return rc;
653 }
654
655 /****************
656  * Verify a public key signature.
657  * Return 0 if the signature is good
658  */
659 static gcry_err_code_t
660 pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
661                gcry_mpi_t *pkey,
662                int (*cmp)(void *, gcry_mpi_t), void *opaquev)
663 {
664   gcry_pk_spec_t *pubkey;
665   gcry_module_t module;
666   gcry_err_code_t rc;
667   int i;
668
669   if (DBG_CIPHER)
670     {
671       log_debug ("pubkey_verify: algo=%d\n", algorithm);
672       for (i = 0; i < pubkey_get_npkey (algorithm); i++)
673         log_mpidump ("  pkey:", pkey[i]);
674       for (i = 0; i < pubkey_get_nsig (algorithm); i++)
675         log_mpidump ("   sig:", data[i]);
676       log_mpidump ("  hash:", hash);
677     }
678
679   ath_mutex_lock (&pubkeys_registered_lock);
680   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
681   if (module)
682     {
683       pubkey = (gcry_pk_spec_t *) module->spec;
684       rc = pubkey->verify (algorithm, hash, data, pkey, cmp, opaquev);
685       _gcry_module_release (module);
686       goto ready;
687     }
688
689   rc = GPG_ERR_PUBKEY_ALGO;
690
691  ready:
692   ath_mutex_unlock (&pubkeys_registered_lock);
693   return rc;
694 }
695
696
697 /* Internal function.   */
698 static gcry_err_code_t
699 sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
700                        gcry_mpi_t *elements)
701 {
702   gcry_err_code_t err = GPG_ERR_NO_ERROR;
703   int i, idx;
704   const char *name;
705   gcry_sexp_t list;
706
707   for (name = element_names, idx = 0; *name && !err; name++, idx++)
708     {
709       list = gcry_sexp_find_token (key_sexp, name, 1);
710       if (! list)
711         err = GPG_ERR_NO_OBJ;
712       else
713         {
714           elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
715           gcry_sexp_release (list);
716           if (! elements[idx])
717             err = GPG_ERR_INV_OBJ;
718         }
719     }
720
721   if (err)
722     {
723       for (i = 0; i < idx; i++)
724         if (elements[i])
725           gcry_free (elements[i]);
726     }
727   return err;
728 }
729
730 /****************
731  * Convert a S-Exp with either a private or a public key to our
732  * internal format. Currently we do only support the following
733  * algorithms:
734  *    dsa
735  *    rsa
736  *    openpgp-dsa
737  *    openpgp-rsa
738  *    openpgp-elg
739  *    openpgp-elg-sig
740  * Provide a SE with the first element be either "private-key" or
741  * or "public-key". It is followed by a list with its first element
742  * be one of the above algorithm identifiers and the remaning
743  * elements are pairs with parameter-id and value.
744  * NOTE: we look through the list to find a list beginning with
745  * "private-key" or "public-key" - the first one found is used.
746  *
747  * FIXME: Allow for encrypted secret keys here.
748  *
749  * Returns: A pointer to an allocated array of MPIs if the return value is
750  *          zero; the caller has to release this array.
751  *
752  * Example of a DSA public key:
753  *  (private-key
754  *    (dsa
755  *      (p <mpi>)
756  *      (g <mpi>)
757  *      (y <mpi>)
758  *      (x <mpi>)
759  *    )
760  *  )
761  * The <mpi> are expected to be in GCRYMPI_FMT_USG
762  */
763 static gcry_err_code_t
764 sexp_to_key (gcry_sexp_t sexp, int want_private, gcry_mpi_t **retarray,
765              gcry_module_t *retalgo)
766 {
767     gcry_sexp_t list, l2;
768     const char *name;
769     size_t n;
770     const char *elems;
771     gcry_mpi_t *array;
772     gcry_err_code_t err = GPG_ERR_NO_ERROR;
773     gcry_module_t module;
774     gcry_pk_spec_t *pubkey;
775
776     /* check that the first element is valid */
777     list = gcry_sexp_find_token( sexp, want_private? "private-key"
778                                                     :"public-key", 0 );
779     if( !list )
780         return GPG_ERR_INV_OBJ; /* Does not contain a public-
781                                    or private-key object */
782     l2 = gcry_sexp_cadr( list );
783     gcry_sexp_release ( list );
784     list = l2;
785     name = gcry_sexp_nth_data( list, 0, &n );
786     if( !name ) {
787         gcry_sexp_release ( list );
788         return GPG_ERR_INV_OBJ; /* invalid structure of object */
789     }
790
791     {
792       char *name_terminated = gcry_xmalloc (n + 1);
793       memcpy (name_terminated, name, n);
794       name_terminated[n] = 0;
795
796       ath_mutex_lock (&pubkeys_registered_lock);
797       module = gcry_pk_lookup_name (name_terminated);
798       ath_mutex_unlock (&pubkeys_registered_lock);
799
800       gcry_free (name_terminated);
801     }
802
803     if (! module)
804       {
805         gcry_sexp_release (list);
806         return GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
807       }
808     else
809       pubkey = (gcry_pk_spec_t *) module->spec;
810
811     elems = want_private ? pubkey->elements_skey : pubkey->elements_pkey;
812     array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
813     if (! array)
814       err = gpg_err_code_from_errno (errno);
815     if (! err)
816       err = sexp_elements_extract (list, elems, array);
817
818     if (list)
819       gcry_sexp_release (list);
820
821     if (err)
822       {
823         if (array)
824           gcry_free (array);
825
826         ath_mutex_lock (&pubkeys_registered_lock);
827         _gcry_module_release (module);
828         ath_mutex_unlock (&pubkeys_registered_lock);
829       }
830     else
831       {
832         *retarray = array;
833         *retalgo = module;
834       }
835
836     return err;
837 }
838
839 static gcry_err_code_t
840 sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
841              gcry_module_t *retalgo)
842 {
843     gcry_sexp_t list, l2;
844     const char *name;
845     size_t n;
846     const char *elems;
847     gcry_mpi_t *array;
848     gcry_err_code_t err = GPG_ERR_NO_ERROR;
849     gcry_module_t module;
850     gcry_pk_spec_t *pubkey;
851
852     /* check that the first element is valid */
853     list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
854     if( !list )
855         return GPG_ERR_INV_OBJ; /* Does not contain a signature value object */
856     l2 = gcry_sexp_nth (list, 1);
857     if(! l2)
858       {
859         gcry_sexp_release (list);
860         return GPG_ERR_NO_OBJ; /* no cadr for the sig object */
861       }
862     name = gcry_sexp_nth_data( l2, 0, &n );
863     if( !name ) {
864         gcry_sexp_release ( list );
865         gcry_sexp_release ( l2 );
866         return GPG_ERR_INV_OBJ; /* invalid structure of object */
867     }
868     else if (n == 5 && (! memcmp (name, "flags", 5))) {
869       /* Skip flags, since they are not used but just here for the
870          sake of consistent S-expressions.  */
871       gcry_sexp_release (l2);
872       l2 = gcry_sexp_nth (list, 2);
873       if (! l2)
874         {
875           gcry_sexp_release (list);
876           return GPG_ERR_INV_OBJ;
877         }
878       name = gcry_sexp_nth_data (l2, 0, &n);
879     }
880       
881     {
882       char *name_terminated = gcry_xmalloc (n + 1);
883       memcpy (name_terminated, name, n);
884       name_terminated[n] = 0;
885       
886       ath_mutex_lock (&pubkeys_registered_lock);
887       module = gcry_pk_lookup_name (name_terminated);
888       ath_mutex_unlock (&pubkeys_registered_lock);
889
890       gcry_free (name_terminated);
891     }
892
893     if (! module)
894       {
895         gcry_sexp_release (l2);
896         gcry_sexp_release (list);
897         return GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
898       }
899     else
900       pubkey = (gcry_pk_spec_t *) module->spec;
901
902     elems = pubkey->elements_sig;
903     array = gcry_calloc (strlen (elems) + 1 , sizeof (*array));
904     if (! array)
905       err = gpg_err_code_from_errno (errno);
906
907     if (! err)
908       err = sexp_elements_extract (list, elems, array);
909
910     gcry_sexp_release (l2);
911     gcry_sexp_release (list);
912
913     if (err)
914       {
915         ath_mutex_lock (&pubkeys_registered_lock);
916         _gcry_module_release (module);
917         ath_mutex_unlock (&pubkeys_registered_lock);
918
919         if (array)
920           gcry_free (array);
921       }
922     else
923       {
924         *retarray = array;
925         *retalgo = module;
926       }
927
928     return err;
929 }
930
931
932 /****************
933  * Take sexp and return an array of MPI as used for our internal decrypt
934  * function.
935  * s_data = (enc-val
936  *           [(flags [pkcs1])
937  *            (<algo>
938  *              (<param_name1> <mpi>)
939  *              ...
940  *              (<param_namen> <mpi>)
941  *            ))
942  * RET_MODERN is set to true when at least an empty flags list has been found.
943  */
944 static gcry_err_code_t
945 sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
946              int *ret_modern, int *ret_want_pkcs1, int *flags)
947 {
948   gcry_sexp_t list = NULL, l2 = NULL;
949   gcry_pk_spec_t *pubkey = NULL;
950   gcry_module_t module = NULL;
951   const char *name;
952   size_t n;
953   int parsed_flags = 0;
954   const char *elems;
955   gcry_mpi_t *array = NULL;
956   gcry_err_code_t err = GPG_ERR_NO_ERROR;
957
958   *ret_want_pkcs1 = 0;
959   *ret_modern = 0;
960
961   /* check that the first element is valid */
962   list = gcry_sexp_find_token (sexp, "enc-val" , 0);
963   if (! list)
964     {
965       err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object */
966       goto leave;
967     }
968
969   l2 = gcry_sexp_nth (list, 1);
970   if (! l2)
971     {
972       err = GPG_ERR_NO_OBJ; /* no cdr for the data object */
973       goto leave;
974     }
975
976   /* Extract identifier of sublist.  */
977   name = gcry_sexp_nth_data (l2, 0, &n);
978   if (! name)
979     {
980       err = GPG_ERR_INV_OBJ; /* invalid structure of object */
981       goto leave;
982     }
983   
984   if ((n == 5) && (! memcmp (name, "flags", 5)))
985     {
986       /* There is a flags element - process it */
987       const char *s;
988       int i;
989       
990       *ret_modern = 1;
991       for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
992         {
993           s = gcry_sexp_nth_data (l2, i, &n);
994           if (! s)
995             ; /* not a data element - ignore */
996           else if (n == 3 && ! memcmp (s, "raw", 3))
997             ; /* just a dummy because it is the default */
998           else if (n == 5 && ! memcmp (s, "pkcs1", 5))
999             *ret_want_pkcs1 = 1;
1000           else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1001             parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1002           else
1003             {
1004               err = GPG_ERR_INV_FLAG;
1005               goto leave;
1006             }
1007         }
1008       
1009       /* Get the next which has the actual data */
1010       gcry_sexp_release (l2);
1011       l2 = gcry_sexp_nth (list, 2);
1012       if (! l2)
1013         {
1014           err = GPG_ERR_NO_OBJ; /* no cdr for the data object */
1015           goto leave;
1016         }
1017
1018       /* Extract sublist identifier.  */
1019       name = gcry_sexp_nth_data (l2, 0, &n);
1020       if (! name)
1021         {
1022           err = GPG_ERR_INV_OBJ; /* invalid structure of object */
1023           goto leave;
1024         }
1025
1026       gcry_sexp_release (list);
1027       list = l2;
1028       l2 = NULL;
1029     }
1030
1031   {
1032     char *name_terminated = gcry_xmalloc (n + 1);
1033     memcpy (name_terminated, name, n);
1034     name_terminated[n] = 0;
1035     
1036     ath_mutex_lock (&pubkeys_registered_lock);
1037     module = gcry_pk_lookup_name (name_terminated);
1038     ath_mutex_unlock (&pubkeys_registered_lock);
1039     
1040     gcry_free (name_terminated);
1041     
1042     if (! module)
1043       {
1044         err = GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
1045         goto leave;
1046       }
1047     pubkey = (gcry_pk_spec_t *) module->spec;
1048   }
1049
1050   elems = pubkey->elements_enc;
1051   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
1052   if (! array)
1053     {
1054       err = gpg_err_code_from_errno (errno);
1055       goto leave;
1056     }
1057
1058   err = sexp_elements_extract (list, elems, array);
1059
1060  leave:
1061   if (list)
1062     gcry_sexp_release (list);
1063   if (l2)
1064     gcry_sexp_release (l2);
1065
1066   if (err)
1067     {
1068       ath_mutex_lock (&pubkeys_registered_lock);
1069       _gcry_module_release (module);
1070       ath_mutex_unlock (&pubkeys_registered_lock);
1071       if (array)
1072         gcry_free (array);
1073     }
1074   else
1075     {
1076       *retarray = array;
1077       *retalgo = module;
1078       *flags = parsed_flags;
1079     }
1080
1081   return err;
1082 }
1083
1084 /* Take the hash value and convert into an MPI, suitable for for
1085    passing to the low level functions.  We currently support the
1086    old style way of passing just a MPI and the modern interface which
1087    allows to pass flags so that we can choose between raw and pkcs1
1088    padding - may be more padding options later. 
1089
1090    (<mpi>)
1091    or
1092    (data
1093     [(flags [pkcs1])]
1094     [(hash <algo> <value>)]
1095     [(value <text>)]
1096    )
1097    
1098    Either the VALUE or the HASH element must be present for use
1099    with signatures.  VALUE is used for encryption.
1100
1101    NBITS is the length of the key in bits. 
1102
1103 */
1104 static gcry_err_code_t
1105 sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
1106                   int for_encryption, int *flags)
1107 {
1108   gcry_err_code_t rc = 0;
1109   gcry_sexp_t ldata, lhash, lvalue;
1110   int i;
1111   size_t n;
1112   const char *s;
1113   int is_raw = 0, is_pkcs1 = 0, unknown_flag=0; 
1114   int parsed_flags = 0, dummy_flags;
1115
1116   if (! flags)
1117     flags = &dummy_flags;
1118   
1119   *ret_mpi = NULL;
1120   ldata = gcry_sexp_find_token (input, "data", 0);
1121   if (!ldata)
1122     { /* assume old style */
1123       *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
1124       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
1125     }
1126
1127   /* see whether there is a flags object */
1128   {
1129     gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
1130     if (lflags)
1131       { /* parse the flags list. */
1132         for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
1133           {
1134             s = gcry_sexp_nth_data (lflags, i, &n);
1135             if (!s)
1136               ; /* not a data element*/
1137             else if ( n == 3 && !memcmp (s, "raw", 3))
1138               is_raw = 1;
1139             else if ( n == 5 && !memcmp (s, "pkcs1", 5))
1140               is_pkcs1 = 1;
1141             else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1142               parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1143             else
1144               unknown_flag = 1;
1145           }
1146         gcry_sexp_release (lflags);
1147       }
1148   }
1149
1150   if (!is_pkcs1 && !is_raw)
1151     is_raw = 1; /* default to raw */
1152
1153   /* Get HASH or MPI */
1154   lhash = gcry_sexp_find_token (ldata, "hash", 0);
1155   lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
1156
1157   if (!(!lhash ^ !lvalue))
1158     rc = GPG_ERR_INV_OBJ; /* none or both given */
1159   else if (unknown_flag)
1160     rc = GPG_ERR_INV_FLAG;
1161   else if (is_raw && is_pkcs1 && !for_encryption)
1162     rc = GPG_ERR_CONFLICT;
1163   else if (is_raw && lvalue)
1164     {
1165       *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
1166       if (!*ret_mpi)
1167         rc = GPG_ERR_INV_OBJ;
1168     }
1169   else if (is_pkcs1 && lvalue && for_encryption)
1170     { /* Create pkcs#1 block type 2 padding. */
1171       unsigned char *frame = NULL;
1172       size_t nframe = (nbits+7) / 8;
1173       const void * value;
1174       size_t valuelen;
1175       unsigned char *p;
1176
1177       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1178         rc = GPG_ERR_INV_OBJ;
1179       else if (valuelen + 7 > nframe || !nframe)
1180         {
1181           /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
1182           rc = GPG_ERR_TOO_SHORT; /* the key is too short */
1183         }
1184       else if ( !(frame = gcry_malloc_secure (nframe)))
1185         rc = gpg_err_code_from_errno (errno);
1186       else
1187         {
1188           n = 0;
1189           frame[n++] = 0;
1190           frame[n++] = 2; /* block type */
1191           i = nframe - 3 - valuelen;
1192           assert (i > 0);
1193           p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
1194           /* Replace zero bytes by new values. */
1195           for (;;)
1196             {
1197               int j, k;
1198               unsigned char *pp;
1199               
1200               /* Count the zero bytes. */
1201               for (j=k=0; j < i; j++)
1202                 {
1203                   if (!p[j])
1204                     k++;
1205                 }
1206               if (!k)
1207                 break; /* Okay: no (more) zero bytes. */
1208               
1209               k += k/128; /* Better get some more. */
1210               pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
1211               for (j=0; j < i && k; j++)
1212                 {
1213                   if (!p[j])
1214                     p[j] = pp[--k];
1215                 }
1216               gcry_free (pp);
1217             }
1218           memcpy (frame+n, p, i);
1219           n += i;
1220           gcry_free (p);
1221           
1222           frame[n++] = 0;
1223           memcpy (frame+n, value, valuelen);
1224           n += valuelen;
1225           assert (n == nframe);
1226
1227           /* FIXME, error checking?  */
1228           gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
1229         }
1230
1231       gcry_free(frame);
1232     }
1233   else if (is_pkcs1 && lhash && !for_encryption)
1234     { /* Create pkcs#1 block type 1 padding. */
1235       if (gcry_sexp_length (lhash) != 3)
1236         rc = GPG_ERR_INV_OBJ;
1237       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1238         rc = GPG_ERR_INV_OBJ;
1239       else
1240         {
1241           static struct { const char *name; int algo; } hashnames[] = 
1242           { { "sha1",   GCRY_MD_SHA1 },
1243             { "md5",    GCRY_MD_MD5 },
1244             { "rmd160", GCRY_MD_RMD160 },
1245             { "sha256", GCRY_MD_SHA256 },
1246             { "sha384", GCRY_MD_SHA384 },
1247             { "sha512", GCRY_MD_SHA512 },
1248             { "md2",    GCRY_MD_MD2 },
1249             { "md4",    GCRY_MD_MD4 },
1250             { "tiger",  GCRY_MD_TIGER },
1251             { "haval",  GCRY_MD_HAVAL },
1252             { NULL }
1253           };
1254           int algo;
1255           byte asn[100];
1256           byte *frame = NULL;
1257           size_t nframe = (nbits+7) / 8;
1258           const void * value;
1259           size_t valuelen;
1260           size_t asnlen, dlen;
1261             
1262           for (i=0; hashnames[i].name; i++)
1263             {
1264               if ( strlen (hashnames[i].name) == n
1265                    && !memcmp (hashnames[i].name, s, n))
1266                 break;
1267             }
1268
1269           algo = hashnames[i].algo;
1270           asnlen = DIM(asn);
1271           dlen = gcry_md_get_algo_dlen (algo);
1272
1273           if (!hashnames[i].name)
1274             rc = GPG_ERR_DIGEST_ALGO;
1275           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
1276                     || !valuelen )
1277             rc = GPG_ERR_INV_OBJ;
1278           else if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
1279             {
1280               /* We don't have yet all of the above algorithms.  */
1281               rc = GPG_ERR_NOT_IMPLEMENTED;
1282             }
1283           else if ( valuelen != dlen )
1284             {
1285               /* Hash value does not match the length of digest for
1286                  the given algorithm. */
1287               rc = GPG_ERR_CONFLICT;
1288             }
1289           else if( !dlen || dlen + asnlen + 4 > nframe)
1290             {
1291               /* Can't encode an DLEN byte digest MD into a NFRAME
1292                  byte frame. */
1293               rc = GPG_ERR_TOO_SHORT;
1294             }
1295           else if ( !(frame = gcry_malloc (nframe)) )
1296             rc = gpg_err_code_from_errno (errno);
1297           else
1298             { /* Assemble the pkcs#1 block type 1. */
1299               n = 0;
1300               frame[n++] = 0;
1301               frame[n++] = 1; /* block type */
1302               i = nframe - valuelen - asnlen - 3 ;
1303               assert (i > 1);
1304               memset (frame+n, 0xff, i );
1305               n += i;
1306               frame[n++] = 0;
1307               memcpy (frame+n, asn, asnlen);
1308               n += asnlen;
1309               memcpy (frame+n, value, valuelen );
1310               n += valuelen;
1311               assert (n == nframe);
1312       
1313               /* convert it into an MPI, FIXME: error checking?  */
1314               gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
1315             }
1316           
1317           gcry_free (frame);
1318         }
1319     }
1320   else
1321     rc = GPG_ERR_CONFLICT;
1322    
1323   gcry_sexp_release (ldata);
1324   gcry_sexp_release (lhash);
1325   gcry_sexp_release (lvalue);
1326
1327   if (!rc)
1328     *flags = parsed_flags;
1329
1330   return rc;
1331 }
1332
1333
1334 /*
1335    Do a PK encrypt operation
1336   
1337    Caller has to provide a public key as the SEXP pkey and data as a
1338    SEXP with just one MPI in it. Alternativly S_DATA might be a
1339    complex S-Expression, similar to the one used for signature
1340    verification.  This provides a flag which allows to handle PKCS#1
1341    block type 2 padding.  The function returns a a sexp which may be
1342    passed to to pk_decrypt.
1343   
1344    Returns: 0 or an errorcode.
1345   
1346    s_data = See comment for sexp_data_to_mpi
1347    s_pkey = <key-as-defined-in-sexp_to_key>
1348    r_ciph = (enc-val
1349                (<algo>
1350                  (<param_name1> <mpi>)
1351                  ...
1352                  (<param_namen> <mpi>)
1353                ))
1354
1355 */
1356 gcry_error_t
1357 gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
1358 {
1359   gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
1360   const char *algo_name, *algo_elems;
1361   int flags;
1362   gcry_err_code_t rc;
1363   gcry_pk_spec_t *pubkey = NULL;
1364   gcry_module_t module = NULL;
1365
1366   REGISTER_DEFAULT_PUBKEYS;
1367
1368   *r_ciph = NULL;
1369   /* get the key */
1370   rc = sexp_to_key (s_pkey, 0, &pkey, &module);
1371   if (rc)
1372     goto leave;
1373
1374   assert (module);
1375   pubkey = (gcry_pk_spec_t *) module->spec;
1376
1377   /* If aliases for the algorithm name exists, take the first one
1378      instead of the regular name to adhere to SPKI conventions.  We
1379      assume that the first alias name is the lowercase version of the
1380      regular one.  This change is required for compatibility with
1381      1.1.12 generated S-expressions. */
1382   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
1383   if (!algo_name || !*algo_name)
1384     algo_name = pubkey->name;
1385   
1386   algo_elems = pubkey->elements_enc;
1387   
1388   /* Get the stuff we want to encrypt. */
1389   rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
1390                          &flags);
1391   if (rc)
1392     goto leave;
1393
1394   /* Now we can encrypt DATA to CIPH. */
1395   ciph = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*ciph));
1396   rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
1397   mpi_free (data);
1398   data = NULL;
1399   if (rc)
1400     goto leave;
1401
1402   /* We did it.  Now build the return list */
1403   {
1404     char *string, *p;
1405     int i;
1406     size_t nelem = strlen (algo_elems);
1407     size_t needed = 19 + strlen (algo_name) + (nelem * 5);
1408     void **arg_list;
1409     
1410     /* Build the string.  */
1411     string = p = gcry_xmalloc (needed);
1412     p = stpcpy ( p, "(enc-val(" );
1413     p = stpcpy ( p, algo_name );
1414     for (i=0; algo_elems[i]; i++ )
1415       {
1416         *p++ = '(';
1417         *p++ = algo_elems[i];
1418         p = stpcpy ( p, "%m)" );
1419       }
1420     strcpy ( p, "))" );
1421     
1422     /* And now the ugly part: We don't have a function to pass an
1423      * array to a format string, so we have to do it this way :-(.  */
1424     /* FIXME: There is now such a format spefier, so we can could
1425        change the code to be more clear. */
1426     arg_list = malloc (nelem * sizeof *arg_list);
1427     if (!arg_list)
1428       {
1429         rc = gpg_err_code_from_errno (errno);
1430         goto leave;
1431       }
1432
1433     for (i = 0; i < nelem; i++)
1434       arg_list[i] = ciph + i;
1435     
1436     rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
1437     free (arg_list);
1438     if (rc)
1439       BUG ();
1440     gcry_free (string);
1441   }
1442
1443  leave:
1444   if (pkey)
1445     {
1446       release_mpi_array (pkey);
1447       gcry_free (pkey);
1448     }
1449
1450   if (ciph)
1451     {
1452       release_mpi_array (ciph);
1453       gcry_free (ciph);
1454     }
1455
1456   if (module)
1457     {
1458       ath_mutex_lock (&pubkeys_registered_lock);
1459       _gcry_module_release (module);
1460       ath_mutex_unlock (&pubkeys_registered_lock);
1461     }
1462
1463   return gcry_error (rc);
1464 }
1465
1466 /* 
1467    Do a PK decrypt operation
1468   
1469    Caller has to provide a secret key as the SEXP skey and data in a
1470    format as created by gcry_pk_encrypt.  For historic reasons the
1471    function returns simply an MPI as an S-expression part; this is
1472    deprecated and the new method should be used which returns a real
1473    S-expressionl this is selected by adding at least an empty flags
1474    list to S_DATA.
1475    
1476    Returns: 0 or an errorcode.
1477   
1478    s_data = (enc-val
1479               [(flags)]
1480               (<algo>
1481                 (<param_name1> <mpi>)
1482                 ...
1483                 (<param_namen> <mpi>)
1484               ))
1485    s_skey = <key-as-defined-in-sexp_to_key>
1486    r_plain= Either an incomplete S-expression without the parentheses
1487             or if the flags list is used (even if empty) a real S-expression:
1488             (value PLAIN). 
1489  */
1490 gcry_error_t
1491 gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
1492 {
1493   gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL;
1494   int modern, want_pkcs1, flags;
1495   gcry_err_code_t rc;
1496   gcry_module_t module_enc = NULL, module_key = NULL;
1497   gcry_pk_spec_t *pubkey = NULL;
1498
1499   REGISTER_DEFAULT_PUBKEYS;
1500
1501   *r_plain = NULL;
1502   rc = sexp_to_key (s_skey, 1, &skey, &module_key);
1503   if (rc)
1504     goto leave;
1505
1506   rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &want_pkcs1, &flags);
1507   if (rc)
1508     goto leave;
1509   
1510   if (module_key->mod_id != module_enc->mod_id)
1511     {
1512       rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
1513       goto leave;
1514     }
1515
1516   pubkey = (gcry_pk_spec_t *) module_key->spec;
1517
1518   rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
1519   if (rc)
1520     goto leave;
1521
1522   if (gcry_sexp_build (r_plain, NULL, modern? "(value %m)" : "%m", plain))
1523     BUG ();
1524   
1525  leave:
1526   if (skey)
1527     {
1528       release_mpi_array (skey);
1529       gcry_free (skey);
1530     }
1531
1532   if (plain)
1533     mpi_free (plain);
1534
1535   if (data)
1536     {
1537       release_mpi_array (data);
1538       gcry_free (data);
1539     }
1540
1541   if (module_key || module_enc)
1542     {
1543       ath_mutex_lock (&pubkeys_registered_lock);
1544       if (module_key)
1545         _gcry_module_release (module_key);
1546       if (module_enc)
1547         _gcry_module_release (module_enc);
1548       ath_mutex_unlock (&pubkeys_registered_lock);
1549     }
1550
1551   return gcry_error (rc);
1552 }
1553
1554
1555
1556 /*
1557    Create a signature.
1558   
1559    Caller has to provide a secret key as the SEXP skey and data
1560    expressed as a SEXP list hash with only one element which should
1561    instantly be available as a MPI. Alternatively the structure given
1562    below may be used for S_HASH, it provides the abiliy to pass flags
1563    to the operation; the only flag defined by now is "pkcs1" which
1564    does PKCS#1 block type 1 style padding.
1565   
1566    Returns: 0 or an errorcode.
1567             In case of 0 the function returns a new SEXP with the
1568             signature value; the structure of this signature depends on the
1569             other arguments but is always suitable to be passed to
1570             gcry_pk_verify
1571   
1572    s_hash = See comment for sexp_data_to_mpi
1573                
1574    s_skey = <key-as-defined-in-sexp_to_key>
1575    r_sig  = (sig-val
1576               (<algo>
1577                 (<param_name1> <mpi>)
1578                 ...
1579                 (<param_namen> <mpi>))) 
1580 */
1581 gcry_error_t
1582 gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
1583 {
1584   gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
1585   gcry_pk_spec_t *pubkey = NULL;
1586   gcry_module_t module = NULL;
1587   const char *algo_name, *algo_elems;
1588   int i;
1589   gcry_err_code_t rc;
1590
1591   REGISTER_DEFAULT_PUBKEYS;
1592
1593   *r_sig = NULL;
1594   rc = sexp_to_key (s_skey, 1, &skey, &module);
1595   if (rc)
1596     goto leave;
1597
1598   assert (module);
1599   pubkey = (gcry_pk_spec_t *) module->spec;
1600   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
1601   if (!algo_name || !*algo_name)
1602     algo_name = pubkey->name;
1603   
1604   algo_elems = pubkey->elements_sig;
1605
1606   /* Get the stuff we want to sign.  Note that pk_get_nbits does also
1607       work on a private key. */
1608   rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey),
1609                              &hash, 0, NULL);
1610   if (rc)
1611     goto leave;
1612
1613   result = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*result));
1614   rc = pubkey_sign (module->mod_id, result, hash, skey);
1615   if (rc)
1616     goto leave;
1617
1618   {
1619     char *string, *p;
1620     size_t nelem, needed = strlen (algo_name) + 20;
1621     void **arg_list;
1622
1623     nelem = strlen (algo_elems);
1624     
1625     /* Count elements, so that we can allocate enough space. */
1626     needed += 10 * nelem;
1627
1628     /* Build the string. */
1629     string = p = gcry_xmalloc (needed);
1630     p = stpcpy (p, "(sig-val(");
1631     p = stpcpy (p, algo_name);
1632     for (i = 0; algo_elems[i]; i++)
1633       {
1634         *p++ = '(';
1635         *p++ = algo_elems[i];
1636         p = stpcpy (p, "%m)");
1637       }
1638     strcpy (p, "))");
1639
1640     arg_list = malloc (nelem * sizeof *arg_list);
1641     if (!arg_list)
1642       {
1643         rc = gpg_err_code_from_errno (errno);
1644         goto leave;
1645       }
1646
1647     for (i = 0; i < nelem; i++)
1648       arg_list[i] = result + i;
1649
1650     rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
1651     free (arg_list);
1652     if (rc)
1653       BUG ();
1654     gcry_free (string);
1655   }
1656
1657  leave:
1658   if (skey)
1659     {
1660       release_mpi_array (skey);
1661       gcry_free (skey);
1662     }
1663
1664   if (hash)
1665     mpi_free (hash);
1666
1667   if (result)
1668     {
1669       release_mpi_array (result);
1670       gcry_free (result);
1671     }
1672
1673   return gcry_error (rc);
1674 }
1675
1676
1677 /*
1678    Verify a signature.
1679
1680    Caller has to supply the public key pkey, the signature sig and his
1681    hashvalue data.  Public key has to be a standard public key given
1682    as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
1683    must be an S-Exp like the one in sign too.  */
1684 gcry_error_t
1685 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
1686 {
1687   gcry_module_t module_key = NULL, module_sig = NULL;
1688   gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
1689   gcry_err_code_t rc;
1690
1691   REGISTER_DEFAULT_PUBKEYS;
1692  
1693   rc = sexp_to_key (s_pkey, 0, &pkey, &module_key);
1694   if (rc)
1695     goto leave;
1696
1697   rc = sexp_to_sig (s_sig, &sig, &module_sig);
1698   if (rc)
1699     goto leave;
1700
1701   if (module_key->mod_id != module_sig->mod_id)
1702     {
1703       rc = GPG_ERR_CONFLICT;
1704       goto leave;
1705     }
1706
1707   rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0);
1708   if (rc)
1709     goto leave;
1710
1711   rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
1712
1713  leave:
1714   if (pkey)
1715     {
1716       release_mpi_array (pkey);
1717       gcry_free (pkey);
1718     }
1719   if (sig)
1720     {
1721       release_mpi_array (sig);
1722       gcry_free (sig);
1723     }
1724   if (hash)
1725     mpi_free (hash);
1726
1727   if (module_key || module_sig)
1728     {
1729       ath_mutex_lock (&pubkeys_registered_lock);
1730       if (module_key)
1731         _gcry_module_release (module_key);
1732       if (module_sig)
1733         _gcry_module_release (module_sig);
1734       ath_mutex_unlock (&pubkeys_registered_lock);
1735     }
1736
1737   return gcry_error (rc);
1738 }
1739
1740
1741 /*
1742    Test a key.
1743
1744    This may be used either for a public or a secret key to see whether
1745    internal structre is valid.
1746   
1747    Returns: 0 or an errorcode.
1748   
1749    s_key = <key-as-defined-in-sexp_to_key> */
1750 gcry_error_t
1751 gcry_pk_testkey (gcry_sexp_t s_key)
1752 {
1753   gcry_module_t module = NULL;
1754   gcry_mpi_t *key = NULL;
1755   gcry_err_code_t rc;
1756   
1757   REGISTER_DEFAULT_PUBKEYS;
1758
1759   /* Note we currently support only secret key checking. */
1760   rc = sexp_to_key (s_key, 1, &key, &module);
1761   if (! rc)
1762     {
1763       rc = pubkey_check_secret_key (module->mod_id, key);
1764       release_mpi_array (key);
1765       gcry_free (key);
1766     }
1767   return gcry_error (rc);
1768 }
1769
1770
1771 /*
1772   Create a public key pair and return it in r_key.
1773   How the key is created depends on s_parms:
1774   (genkey
1775    (algo
1776      (parameter_name_1 ....)
1777       ....
1778      (parameter_name_n ....)
1779   ))
1780   The key is returned in a format depending on the
1781   algorithm. Both, private and secret keys are returned
1782   and optionally some additional informatin.
1783   For elgamal we return this structure:
1784   (key-data
1785    (public-key
1786      (elg
1787         (p <mpi>)
1788         (g <mpi>)
1789         (y <mpi>)
1790      )
1791    )
1792    (private-key
1793      (elg
1794         (p <mpi>)
1795         (g <mpi>)
1796         (y <mpi>)
1797         (x <mpi>)
1798      )
1799    )
1800    (misc-key-info
1801       (pm1-factors n1 n2 ... nn)
1802    ))
1803  */
1804 gcry_error_t
1805 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
1806 {
1807   gcry_pk_spec_t *pubkey = NULL;
1808   gcry_module_t module = NULL;
1809   gcry_sexp_t list = NULL, l2 = NULL;
1810   const char *name;
1811   size_t n;
1812   gcry_err_code_t rc = GPG_ERR_NO_ERROR;
1813   int i;
1814   const char *algo_name = NULL;
1815   int algo;
1816   const char *sec_elems = NULL, *pub_elems = NULL;
1817   gcry_mpi_t skey[10], *factors = NULL;
1818   unsigned int nbits = 0;
1819   unsigned long use_e = 0;
1820   char *name_terminated;
1821
1822   REGISTER_DEFAULT_PUBKEYS;
1823
1824   skey[0] = NULL;
1825   *r_key = NULL;
1826
1827   list = gcry_sexp_find_token (s_parms, "genkey", 0);
1828   if (!list)
1829     {
1830       rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
1831       goto leave;
1832     }
1833
1834   l2 = gcry_sexp_cadr (list);
1835   gcry_sexp_release (list);
1836   list = l2;
1837   l2 = NULL;
1838   if (! list)
1839     {
1840       rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
1841       goto leave;
1842     }
1843
1844   name = gcry_sexp_nth_data (list, 0, &n);
1845   if (! name)
1846     {
1847       rc = GPG_ERR_INV_OBJ; /* Algo string missing. */
1848       goto leave;
1849     }
1850
1851   name_terminated = gcry_xmalloc (n + 1);
1852   memcpy (name_terminated, name, n);
1853   name_terminated[n] = 0;
1854   ath_mutex_lock (&pubkeys_registered_lock);
1855   module = gcry_pk_lookup_name (name_terminated);
1856   ath_mutex_unlock (&pubkeys_registered_lock);
1857   gcry_free (name_terminated);
1858
1859   if (! module)
1860     {
1861       rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
1862       goto leave;
1863     }
1864   
1865   pubkey = (gcry_pk_spec_t *) module->spec;
1866   algo = module->mod_id;
1867   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
1868   if (!algo_name || !*algo_name)
1869     algo_name = pubkey->name;
1870   pub_elems = pubkey->elements_pkey;
1871   sec_elems = pubkey->elements_skey;
1872
1873   /* Handle the optional rsa-use-e element. */
1874   l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
1875   if (l2)
1876     {
1877       char buf[50];
1878
1879       name = gcry_sexp_nth_data (l2, 1, &n);
1880       if ((! name) || (n >= DIM (buf) - 1))
1881         {
1882           rc = GPG_ERR_INV_OBJ; /* No value or value too large. */
1883           goto leave;
1884         }
1885       memcpy (buf, name, n);
1886       buf[n] = 0;
1887       use_e = strtoul (buf, NULL, 0);
1888       gcry_sexp_release (l2);
1889       l2 = NULL;
1890     }
1891   else
1892     use_e = 65537; /* Not given, use the value generated by old versions. */
1893
1894   l2 = gcry_sexp_find_token (list, "nbits", 0);
1895   gcry_sexp_release (list);
1896   list = l2;
1897   l2 = NULL;
1898   
1899   if (! list)
1900     {
1901       rc = GPG_ERR_NO_OBJ; /* No nbits parameter. */
1902       goto leave;
1903     }
1904
1905   name = gcry_sexp_nth_data (list, 1, &n);
1906   if (! name)
1907     {
1908       rc = GPG_ERR_INV_OBJ; /* nbits without a cdr. */
1909       goto leave;
1910     }
1911   
1912   name_terminated = gcry_xmalloc (n + 1);
1913   memcpy (name_terminated, name, n);
1914   name_terminated[n] = 0;
1915   nbits = (unsigned int) strtoul (name_terminated, NULL, 0);
1916   gcry_free (name_terminated);
1917
1918   rc = pubkey_generate (module->mod_id, nbits, use_e, skey, &factors);
1919   if (rc)
1920     goto leave;
1921
1922   {
1923     char *string, *p;
1924     size_t nelem=0, nelem_cp = 0, needed=0;
1925     gcry_mpi_t mpis[30];
1926     
1927     nelem = strlen (pub_elems) + strlen (sec_elems);
1928     for (i = 0; factors[i]; i++)
1929       nelem++;
1930     nelem_cp = nelem;
1931
1932     needed += nelem * 10;
1933     needed += 2 * strlen (algo_name) + 300;
1934     if (nelem > DIM (mpis))
1935       BUG ();
1936
1937     /* Build the string. */
1938     nelem = 0;
1939     string = p = gcry_xmalloc (needed);
1940     p = stpcpy (p, "(key-data");
1941     p = stpcpy (p, "(public-key(");
1942     p = stpcpy (p, algo_name);
1943     for(i = 0; pub_elems[i]; i++)
1944       {
1945         *p++ = '(';
1946         *p++ = pub_elems[i];
1947         p = stpcpy (p, "%m)");
1948         mpis[nelem++] = skey[i];
1949       }
1950     p = stpcpy (p, "))");
1951     p = stpcpy (p, "(private-key(");
1952     p = stpcpy (p, algo_name);
1953     for (i = 0; sec_elems[i]; i++)
1954       {
1955         *p++ = '(';
1956         *p++ = sec_elems[i];
1957         p = stpcpy (p, "%m)");
1958         mpis[nelem++] = skey[i];
1959       }
1960     p = stpcpy (p, "))");
1961
1962     /* Very ugly hack to make release_mpi_array() work FIXME */
1963     skey[i] = NULL;
1964
1965     p = stpcpy (p, "(misc-key-info(pm1-factors");
1966     for(i = 0; factors[i]; i++)
1967       {
1968         p = stpcpy (p, "%m");
1969         mpis[nelem++] = factors[i];
1970       }
1971     strcpy (p, ")))");
1972
1973     while (nelem < DIM (mpis))
1974       mpis[nelem++] = NULL;
1975
1976     {
1977       int elem_n = strlen (pub_elems) + strlen (sec_elems);
1978       void **arg_list;
1979
1980       arg_list = malloc (nelem_cp * sizeof *arg_list);
1981       if (!arg_list)
1982         {
1983           rc = gpg_err_code_from_errno (errno);
1984           goto leave;
1985         }
1986       for (i = 0; i < elem_n; i++)
1987         arg_list[i] = mpis + i;
1988       for (; i < nelem_cp; i++)
1989         arg_list[i] = factors + i - elem_n;
1990       
1991       rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
1992       free (arg_list);
1993       if (rc)
1994         BUG ();
1995       assert (DIM (mpis) == 30); /* Reminder to make sure that the
1996                                     array gets increased if new
1997                                     parameters are added. */
1998     }
1999     gcry_free (string);
2000   }
2001
2002  leave:
2003   release_mpi_array (skey);
2004   /* Don't free SKEY itself, it is a static array. */
2005     
2006   if (factors)
2007     {
2008       release_mpi_array ( factors );
2009       gcry_free (factors);
2010     }
2011   
2012   if (l2)
2013     gcry_sexp_release (l2);
2014   if (list)
2015     gcry_sexp_release (list);
2016   
2017   if (module)
2018     {
2019       ath_mutex_lock (&pubkeys_registered_lock);
2020       _gcry_module_release (module);
2021       ath_mutex_unlock (&pubkeys_registered_lock);
2022     }
2023
2024   return gcry_error (rc);
2025 }
2026
2027
2028 /* 
2029    Get the number of nbits from the public key.
2030
2031    Hmmm: Should we have really this function or is it better to have a
2032    more general function to retrieve different propoerties of the key?  */
2033 unsigned int
2034 gcry_pk_get_nbits (gcry_sexp_t key)
2035 {
2036   gcry_module_t module = NULL;
2037   gcry_pk_spec_t *pubkey;
2038   gcry_mpi_t *keyarr = NULL;
2039   unsigned int nbits = 0;
2040   gcry_err_code_t rc;
2041
2042   REGISTER_DEFAULT_PUBKEYS;
2043
2044   rc = sexp_to_key (key, 0, &keyarr, &module);
2045   if (rc == GPG_ERR_INV_OBJ)
2046     rc = sexp_to_key (key, 1, &keyarr, &module);
2047   if (rc)
2048     return 0; /* Error - 0 is a suitable indication for that. */
2049
2050   pubkey = (gcry_pk_spec_t *) module->spec;
2051   nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
2052   
2053   ath_mutex_lock (&pubkeys_registered_lock);
2054   _gcry_module_release (module);
2055   ath_mutex_unlock (&pubkeys_registered_lock);
2056
2057   release_mpi_array (keyarr);
2058   gcry_free (keyarr);
2059
2060   return nbits;
2061 }
2062
2063
2064 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
2065    key parameters expressed in a way depended on the algorithm.
2066
2067    ARRAY must either be 20 bytes long or NULL; in the latter case a
2068    newly allocated array of that size is returned, otherwise ARRAY or
2069    NULL is returned to indicate an error which is most likely an
2070    unknown algorithm.  The function accepts public or secret keys. */
2071 unsigned char *
2072 gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
2073 {
2074   gcry_sexp_t list = NULL, l2 = NULL;
2075   gcry_pk_spec_t *pubkey = NULL;
2076   gcry_module_t module = NULL;
2077   const char *s, *name;
2078   size_t n;
2079   int idx;
2080   int is_rsa;
2081   const char *elems;
2082   gcry_md_hd_t md = NULL;
2083
2084   REGISTER_DEFAULT_PUBKEYS;
2085
2086   /* Check that the first element is valid. */
2087   list = gcry_sexp_find_token (key, "public-key", 0);
2088   if (! list)
2089     list = gcry_sexp_find_token (key, "private-key", 0);
2090   if (! list)
2091     list = gcry_sexp_find_token (key, "protected-private-key", 0);
2092   if (! list)
2093     return NULL; /* No public- or private-key object. */
2094
2095   l2 = gcry_sexp_cadr (list);
2096   gcry_sexp_release (list);
2097   list = l2;
2098   l2 = NULL;
2099
2100   name = gcry_sexp_nth_data (list, 0, &n);
2101   if (! name)
2102     goto fail; /* Invalid structure of object. */
2103
2104   {
2105     char *name_terminated = gcry_xmalloc (n + 1);
2106     memcpy (name_terminated, name, n);
2107     name_terminated[n] = 0;
2108     ath_mutex_lock (&pubkeys_registered_lock);
2109     module = gcry_pk_lookup_name (name_terminated);
2110     ath_mutex_unlock (&pubkeys_registered_lock);
2111     gcry_free (name_terminated);
2112   }
2113
2114   if (! module)
2115     goto fail; /* unknown algorithm */
2116
2117   pubkey = (gcry_pk_spec_t *) module->spec;
2118
2119   /* FIXME, special handling should be implemented by the algorithms,
2120      not by the libgcrypt core.  */
2121   is_rsa = module->mod_id == GCRY_PK_RSA;
2122   elems = pubkey->elements_grip;
2123   if (! elems)
2124     goto fail; /* no grip parameter */
2125     
2126   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
2127     goto fail;
2128
2129   for (idx = 0, s = elems; *s; s++, idx++)
2130     {
2131       const char *data;
2132       size_t datalen;
2133
2134       l2 = gcry_sexp_find_token (list, s, 1);
2135       if (! l2)
2136         goto fail;
2137       data = gcry_sexp_nth_data (l2, 1, &datalen);
2138       if (! data)
2139         goto fail;
2140       if (!is_rsa)
2141         {
2142           char buf[30];
2143
2144           sprintf (buf, "(1:%c%u:", *s, (unsigned int)datalen);
2145           gcry_md_write (md, buf, strlen (buf));
2146         }
2147   
2148       /* PKCS-15 says that for RSA only the modulus should be hashed -
2149          however, it is not clear wether this is meant to has the raw
2150          bytes assuming this is an unsigned integer or whether the DER
2151          required 0 should be prefixed. We hash the raw bytes.  For
2152          non-RSA we hash S-expressions. */
2153       gcry_md_write (md, data, datalen);
2154       gcry_sexp_release (l2);
2155       if (!is_rsa)
2156         gcry_md_write (md, ")", 1);
2157     }
2158
2159   if (!array)
2160     {
2161       array = gcry_malloc (20);
2162       if (! array)
2163         goto fail;
2164     }
2165
2166   memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
2167   gcry_md_close (md);
2168   gcry_sexp_release (list);
2169   return array;
2170
2171  fail:
2172   if (l2)
2173     gcry_sexp_release (l2);
2174   if (md)
2175     gcry_md_close (md);
2176   gcry_sexp_release (list);
2177   return NULL;
2178 }
2179
2180
2181 gcry_error_t
2182 gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
2183 {
2184   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2185
2186   REGISTER_DEFAULT_PUBKEYS;
2187
2188   switch (cmd)
2189     {
2190     case GCRYCTL_DISABLE_ALGO:
2191       /* This one expects a buffer pointing to an integer with the
2192          algo number.  */
2193       if ((! buffer) || (buflen != sizeof (int)))
2194         err = GPG_ERR_INV_ARG;
2195       else
2196         disable_pubkey_algo (*((int *) buffer));
2197       break;
2198
2199     default:
2200       err = GPG_ERR_INV_OP;
2201     }
2202
2203   return gcry_error (err);
2204 }
2205
2206
2207 /*
2208    Return information about the given algorithm
2209    WHAT select the kind of information returned:
2210     GCRYCTL_TEST_ALGO:
2211         Returns 0 when the specified algorithm is available for use.
2212         Buffer must be NULL, nbytes  may have the address of a variable
2213         with the required usage of the algorithm. It may be 0 for don't
2214         care or a combination of the GCRY_PK_USAGE_xxx flags;
2215     GCRYCTL_GET_ALGO_USAGE:
2216         Return the usage glafs for the give algo.  An invalid alog
2217         does return 0.  Disabled algos are ignored here becuase we
2218         only want to know whether the algo is at all capable of
2219         the usage.
2220   
2221    Note: Because this function is in most cases used to return an
2222    integer value, we can make it easier for the caller to just look at
2223    the return value.  The caller will in all cases consult the value
2224    and thereby detecting whether a error occured or not (i.e. while
2225    checking the block size) */
2226 gcry_error_t
2227 gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
2228 {
2229   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2230
2231   switch (what)
2232     {
2233     case GCRYCTL_TEST_ALGO:
2234       {
2235         int use = nbytes ? *nbytes : 0;
2236         if (buffer)
2237           err = GPG_ERR_INV_ARG;
2238         else if (check_pubkey_algo (algorithm, use))
2239           err = GPG_ERR_PUBKEY_ALGO;
2240         break;
2241       }
2242
2243     case GCRYCTL_GET_ALGO_USAGE:
2244       {
2245         gcry_module_t pubkey;
2246         int use = 0;
2247
2248         REGISTER_DEFAULT_PUBKEYS;
2249
2250         ath_mutex_lock (&pubkeys_registered_lock);
2251         pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
2252         if (pubkey)
2253           {
2254             use = ((gcry_pk_spec_t *) pubkey->spec)->use;
2255             _gcry_module_release (pubkey);
2256           }
2257         ath_mutex_unlock (&pubkeys_registered_lock);
2258
2259         /* FIXME? */
2260         *nbytes = use;
2261       }
2262
2263     case GCRYCTL_GET_ALGO_NPKEY:
2264       {
2265         /* FIXME?  */
2266         int npkey = pubkey_get_npkey (algorithm);
2267         *nbytes = npkey;
2268         break;
2269       }
2270     case GCRYCTL_GET_ALGO_NSKEY:
2271       {
2272         /* FIXME?  */
2273         int nskey = pubkey_get_nskey (algorithm);
2274         *nbytes = nskey;
2275         break;
2276       }
2277     case GCRYCTL_GET_ALGO_NSIGN:
2278       {
2279         /* FIXME?  */
2280         int nsign = pubkey_get_nsig (algorithm);
2281         *nbytes = nsign;
2282         break;
2283       }
2284     case GCRYCTL_GET_ALGO_NENCR:
2285       {
2286         /* FIXME?  */
2287         int nencr = pubkey_get_nenc (algorithm);
2288         *nbytes = nencr;
2289         break;
2290       }
2291
2292     default:
2293       err = GPG_ERR_INV_OP;
2294     }
2295
2296   return gcry_error (err);
2297 }
2298
2299
2300 gcry_err_code_t
2301 _gcry_pk_init (void)
2302 {
2303   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2304
2305   REGISTER_DEFAULT_PUBKEYS;
2306
2307   return err;
2308 }
2309
2310
2311 gcry_err_code_t
2312 _gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
2313 {
2314   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2315   gcry_module_t pubkey;
2316
2317   REGISTER_DEFAULT_PUBKEYS;
2318
2319   ath_mutex_lock (&pubkeys_registered_lock);
2320   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
2321   if (pubkey)
2322     *module = pubkey;
2323   else
2324     err = GPG_ERR_PUBKEY_ALGO;
2325   ath_mutex_unlock (&pubkeys_registered_lock);
2326
2327   return err;
2328 }
2329
2330
2331 void
2332 _gcry_pk_module_release (gcry_module_t module)
2333 {
2334   ath_mutex_lock (&pubkeys_registered_lock);
2335   _gcry_module_release (module);
2336   ath_mutex_unlock (&pubkeys_registered_lock);
2337 }
2338
2339 /* Get a list consisting of the IDs of the loaded pubkey modules.  If
2340    LIST is zero, write the number of loaded pubkey modules to
2341    LIST_LENGTH and return.  If LIST is non-zero, the first
2342    *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
2343    according size.  In case there are less pubkey modules than
2344    *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
2345 gcry_error_t
2346 gcry_pk_list (int *list, int *list_length)
2347 {
2348   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2349
2350   ath_mutex_lock (&pubkeys_registered_lock);
2351   err = _gcry_module_list (pubkeys_registered, list, list_length);
2352   ath_mutex_unlock (&pubkeys_registered_lock);
2353
2354   return err;
2355 }