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