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