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