Integrating http://code.google.com/p/gnupg-ecc/source/detail?r=15 .
[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       &_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 //  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    //   if (is_ecc)
1035  //       err = sexp_elements_extract_ecc (list, elems, array, extraspec);
1036    //   else
1037         err = sexp_elements_extract (list, elems, array, pubkey->name);
1038     }
1039   
1040   gcry_sexp_release (list);
1041   
1042   if (err)
1043     {
1044       gcry_free (array);
1045
1046       ath_mutex_lock (&pubkeys_registered_lock);
1047       _gcry_module_release (module);
1048       ath_mutex_unlock (&pubkeys_registered_lock);
1049     }
1050   else
1051     {
1052       *retarray = array;
1053       *retalgo = module;
1054     }
1055   
1056   return err;
1057 }
1058
1059
1060 static gcry_err_code_t
1061 sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
1062              gcry_module_t *retalgo)
1063 {
1064   gcry_err_code_t err = 0;
1065   gcry_sexp_t list, l2;
1066   char *name;
1067   const char *elems;
1068   gcry_mpi_t *array;
1069   gcry_module_t module;
1070   gcry_pk_spec_t *pubkey;
1071   
1072   /* Check that the first element is valid.  */
1073   list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
1074   if (!list)
1075     return GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
1076
1077   l2 = gcry_sexp_nth (list, 1);
1078   if (!l2)
1079     {
1080       gcry_sexp_release (list);
1081       return GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
1082     }
1083   name = _gcry_sexp_nth_string (l2, 0);
1084   if (!name)
1085     {
1086       gcry_sexp_release (list);
1087       gcry_sexp_release (l2);
1088       return GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
1089     }
1090   else if (!strcmp (name, "flags")) 
1091     {
1092       /* Skip flags, since they are not used but here just for the
1093          sake of consistent S-expressions.  */
1094       gcry_free (name);
1095       gcry_sexp_release (l2);
1096       l2 = gcry_sexp_nth (list, 2);
1097       if (!l2)
1098         {
1099           gcry_sexp_release (list);
1100           return GPG_ERR_INV_OBJ;
1101         }
1102       name = _gcry_sexp_nth_string (l2, 0);
1103     }
1104       
1105   ath_mutex_lock (&pubkeys_registered_lock);
1106   module = gcry_pk_lookup_name (name);
1107   ath_mutex_unlock (&pubkeys_registered_lock);
1108   gcry_free (name);
1109   name = NULL;
1110
1111   if (!module)
1112     {
1113       gcry_sexp_release (l2);
1114       gcry_sexp_release (list);
1115       return GPG_ERR_PUBKEY_ALGO;  /* Unknown algorithm. */
1116     }
1117   else
1118     pubkey = (gcry_pk_spec_t *) module->spec;
1119
1120   elems = pubkey->elements_sig;
1121   array = gcry_calloc (strlen (elems) + 1 , sizeof *array );
1122   if (!array)
1123     err = gpg_err_code_from_errno (errno);
1124
1125   if (!err)
1126     err = sexp_elements_extract (list, elems, array, NULL);
1127
1128   gcry_sexp_release (l2);
1129   gcry_sexp_release (list);
1130
1131   if (err)
1132     {
1133       ath_mutex_lock (&pubkeys_registered_lock);
1134       _gcry_module_release (module);
1135       ath_mutex_unlock (&pubkeys_registered_lock);
1136       
1137       gcry_free (array);
1138     }
1139   else
1140     {
1141       *retarray = array;
1142       *retalgo = module;
1143     }
1144   
1145   return err;
1146 }
1147
1148
1149 /****************
1150  * Take sexp and return an array of MPI as used for our internal decrypt
1151  * function.
1152  * s_data = (enc-val
1153  *           [(flags [pkcs1])]
1154  *            (<algo>
1155  *              (<param_name1> <mpi>)
1156  *              ...
1157  *              (<param_namen> <mpi>)
1158  *            ))
1159  * RET_MODERN is set to true when at least an empty flags list has been found.
1160  */
1161 static gcry_err_code_t
1162 sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
1163              int *ret_modern, int *ret_want_pkcs1, int *flags)
1164 {
1165   gcry_err_code_t err = 0;
1166   gcry_sexp_t list = NULL, l2 = NULL;
1167   gcry_pk_spec_t *pubkey = NULL;
1168   gcry_module_t module = NULL;
1169   char *name = NULL;
1170   size_t n;
1171   int parsed_flags = 0;
1172   const char *elems;
1173   gcry_mpi_t *array = NULL;
1174
1175   *ret_want_pkcs1 = 0;
1176   *ret_modern = 0;
1177
1178   /* Check that the first element is valid.  */
1179   list = gcry_sexp_find_token (sexp, "enc-val" , 0);
1180   if (!list)
1181     {
1182       err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
1183       goto leave;
1184     }
1185
1186   l2 = gcry_sexp_nth (list, 1);
1187   if (!l2)
1188     {
1189       err = GPG_ERR_NO_OBJ; /* No cdr for the data object.  */
1190       goto leave;
1191     }
1192
1193   /* Extract identifier of sublist.  */
1194   name = _gcry_sexp_nth_string (l2, 0);
1195   if (!name)
1196     {
1197       err = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
1198       goto leave;
1199     }
1200   
1201   if (!strcmp (name, "flags"))
1202     {
1203       /* There is a flags element - process it.  */
1204       const char *s;
1205       int i;
1206       
1207       *ret_modern = 1;
1208       for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
1209         {
1210           s = gcry_sexp_nth_data (l2, i, &n);
1211           if (! s)
1212             ; /* Not a data element - ignore.  */
1213           else if (n == 3 && !memcmp (s, "raw", 3))
1214             ; /* This is just a dummy as it is the default.  */
1215           else if (n == 5 && !memcmp (s, "pkcs1", 5))
1216             *ret_want_pkcs1 = 1;
1217           else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1218             parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1219           else
1220             {
1221               err = GPG_ERR_INV_FLAG;
1222               goto leave;
1223             }
1224         }
1225       
1226       /* Get the next which has the actual data. */
1227       gcry_sexp_release (l2);
1228       l2 = gcry_sexp_nth (list, 2);
1229       if (!l2)
1230         {
1231           err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
1232           goto leave;
1233         }
1234
1235       /* Extract sublist identifier.  */
1236       gcry_free (name);
1237       name = _gcry_sexp_nth_string (l2, 0);
1238       if (!name)
1239         {
1240           err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
1241           goto leave;
1242         }
1243
1244       gcry_sexp_release (list);
1245       list = l2;
1246       l2 = NULL;
1247     }
1248
1249   ath_mutex_lock (&pubkeys_registered_lock);
1250   module = gcry_pk_lookup_name (name);
1251   ath_mutex_unlock (&pubkeys_registered_lock);
1252   
1253   if (!module)
1254     {
1255       err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
1256       goto leave;
1257     }
1258   pubkey = (gcry_pk_spec_t *) module->spec;
1259
1260   elems = pubkey->elements_enc;
1261   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
1262   if (!array)
1263     {
1264       err = gpg_err_code_from_errno (errno);
1265       goto leave;
1266     }
1267
1268   err = sexp_elements_extract (list, elems, array, NULL);
1269
1270  leave:
1271   gcry_sexp_release (list);
1272   gcry_sexp_release (l2);
1273   gcry_free (name);
1274
1275   if (err)
1276     {
1277       ath_mutex_lock (&pubkeys_registered_lock);
1278       _gcry_module_release (module);
1279       ath_mutex_unlock (&pubkeys_registered_lock);
1280       gcry_free (array);
1281     }
1282   else
1283     {
1284       *retarray = array;
1285       *retalgo = module;
1286       *flags = parsed_flags;
1287     }
1288
1289   return err;
1290 }
1291
1292 /* Take the hash value and convert into an MPI, suitable for
1293    passing to the low level functions.  We currently support the
1294    old style way of passing just a MPI and the modern interface which
1295    allows to pass flags so that we can choose between raw and pkcs1
1296    padding - may be more padding options later. 
1297
1298    (<mpi>)
1299    or
1300    (data
1301     [(flags [pkcs1])]
1302     [(hash <algo> <value>)]
1303     [(value <text>)]
1304    )
1305    
1306    Either the VALUE or the HASH element must be present for use
1307    with signatures.  VALUE is used for encryption.
1308
1309    NBITS is the length of the key in bits. 
1310
1311 */
1312 static gcry_err_code_t
1313 sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
1314                   int for_encryption, int *flags)
1315 {
1316   gcry_err_code_t rc = 0;
1317   gcry_sexp_t ldata, lhash, lvalue;
1318   int i;
1319   size_t n;
1320   const char *s;
1321   int is_raw = 0, is_pkcs1 = 0, unknown_flag=0; 
1322   int parsed_flags = 0, dummy_flags;
1323
1324   if (! flags)
1325     flags = &dummy_flags;
1326   
1327   *ret_mpi = NULL;
1328   ldata = gcry_sexp_find_token (input, "data", 0);
1329   if (!ldata)
1330     { /* assume old style */
1331       *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
1332       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
1333     }
1334
1335   /* see whether there is a flags object */
1336   {
1337     gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
1338     if (lflags)
1339       { /* parse the flags list. */
1340         for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
1341           {
1342             s = gcry_sexp_nth_data (lflags, i, &n);
1343             if (!s)
1344               ; /* not a data element*/
1345             else if ( n == 3 && !memcmp (s, "raw", 3))
1346               is_raw = 1;
1347             else if ( n == 5 && !memcmp (s, "pkcs1", 5))
1348               is_pkcs1 = 1;
1349             else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1350               parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1351             else
1352               unknown_flag = 1;
1353           }
1354         gcry_sexp_release (lflags);
1355       }
1356   }
1357
1358   if (!is_pkcs1 && !is_raw)
1359     is_raw = 1; /* default to raw */
1360
1361   /* Get HASH or MPI */
1362   lhash = gcry_sexp_find_token (ldata, "hash", 0);
1363   lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
1364
1365   if (!(!lhash ^ !lvalue))
1366     rc = GPG_ERR_INV_OBJ; /* none or both given */
1367   else if (unknown_flag)
1368     rc = GPG_ERR_INV_FLAG;
1369   else if (is_raw && is_pkcs1 && !for_encryption)
1370     rc = GPG_ERR_CONFLICT;
1371   else if (is_raw && lvalue)
1372     {
1373       *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
1374       if (!*ret_mpi)
1375         rc = GPG_ERR_INV_OBJ;
1376     }
1377   else if (is_pkcs1 && lvalue && for_encryption)
1378     { 
1379       /* Create pkcs#1 block type 2 padding. */
1380       unsigned char *frame = NULL;
1381       size_t nframe = (nbits+7) / 8;
1382       const void * value;
1383       size_t valuelen;
1384       unsigned char *p;
1385
1386       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1387         rc = GPG_ERR_INV_OBJ;
1388       else if (valuelen + 7 > nframe || !nframe)
1389         {
1390           /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
1391           rc = GPG_ERR_TOO_SHORT; /* the key is too short */
1392         }
1393       else if ( !(frame = gcry_malloc_secure (nframe)))
1394         rc = gpg_err_code_from_errno (errno);
1395       else
1396         {
1397           n = 0;
1398           frame[n++] = 0;
1399           frame[n++] = 2; /* block type */
1400           i = nframe - 3 - valuelen;
1401           gcry_assert (i > 0);
1402           p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
1403           /* Replace zero bytes by new values. */
1404           for (;;)
1405             {
1406               int j, k;
1407               unsigned char *pp;
1408               
1409               /* Count the zero bytes. */
1410               for (j=k=0; j < i; j++)
1411                 {
1412                   if (!p[j])
1413                     k++;
1414                 }
1415               if (!k)
1416                 break; /* Okay: no (more) zero bytes. */
1417               
1418               k += k/128 + 3; /* Better get some more. */
1419               pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
1420               for (j=0; j < i && k; )
1421                 {
1422                   if (!p[j])
1423                     p[j] = pp[--k];
1424                   if (p[j])
1425                     j++;
1426                 }
1427               gcry_free (pp);
1428             }
1429           memcpy (frame+n, p, i);
1430           n += i;
1431           gcry_free (p);
1432           
1433           frame[n++] = 0;
1434           memcpy (frame+n, value, valuelen);
1435           n += valuelen;
1436           gcry_assert (n == nframe);
1437
1438           /* FIXME, error checking?  */
1439           gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
1440         }
1441
1442       gcry_free(frame);
1443     }
1444   else if (is_pkcs1 && lhash && !for_encryption)
1445     { 
1446       /* Create pkcs#1 block type 1 padding. */
1447       if (gcry_sexp_length (lhash) != 3)
1448         rc = GPG_ERR_INV_OBJ;
1449       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1450         rc = GPG_ERR_INV_OBJ;
1451       else
1452         {
1453           static struct { const char *name; int algo; } hashnames[] = 
1454           { { "sha1",   GCRY_MD_SHA1 },
1455             { "md5",    GCRY_MD_MD5 },
1456             { "sha256", GCRY_MD_SHA256 },
1457             { "ripemd160", GCRY_MD_RMD160 },
1458             { "rmd160", GCRY_MD_RMD160 },
1459             { "sha384", GCRY_MD_SHA384 },
1460             { "sha512", GCRY_MD_SHA512 },
1461             { "sha224", GCRY_MD_SHA224 },
1462             { "md2",    GCRY_MD_MD2 },
1463             { "md4",    GCRY_MD_MD4 },
1464             { "tiger",  GCRY_MD_TIGER },
1465             { "haval",  GCRY_MD_HAVAL },
1466             { NULL, 0 }
1467           };
1468           int algo;
1469           byte asn[100];
1470           byte *frame = NULL;
1471           size_t nframe = (nbits+7) / 8;
1472           const void * value;
1473           size_t valuelen;
1474           size_t asnlen, dlen;
1475             
1476           for (i=0; hashnames[i].name; i++)
1477             {
1478               if ( strlen (hashnames[i].name) == n
1479                    && !memcmp (hashnames[i].name, s, n))
1480                 break;
1481             }
1482           if (hashnames[i].name)
1483             algo = hashnames[i].algo;
1484           else
1485             {
1486               /* In case of not listed or dynamically allocated hash
1487                  algorithm we fall back to this somewhat slower
1488                  method.  Further, it also allows to use OIDs as
1489                  algorithm names. */
1490               char *tmpname;
1491
1492               tmpname = gcry_malloc (n+1);
1493               if (!tmpname)
1494                 algo = 0;  /* Out of core - silently give up.  */
1495               else
1496                 {
1497                   memcpy (tmpname, s, n);
1498                   tmpname[n] = 0;
1499                   algo = gcry_md_map_name (tmpname);
1500                   gcry_free (tmpname);
1501                 }
1502             }
1503
1504           asnlen = DIM(asn);
1505           dlen = gcry_md_get_algo_dlen (algo);
1506
1507           if (!algo)
1508             rc = GPG_ERR_DIGEST_ALGO;
1509           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
1510                     || !valuelen )
1511             rc = GPG_ERR_INV_OBJ;
1512           else if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
1513             {
1514               /* We don't have yet all of the above algorithms.  */
1515               rc = GPG_ERR_NOT_IMPLEMENTED;
1516             }
1517           else if ( valuelen != dlen )
1518             {
1519               /* Hash value does not match the length of digest for
1520                  the given algorithm. */
1521               rc = GPG_ERR_CONFLICT;
1522             }
1523           else if( !dlen || dlen + asnlen + 4 > nframe)
1524             {
1525               /* Can't encode an DLEN byte digest MD into a NFRAME
1526                  byte frame. */
1527               rc = GPG_ERR_TOO_SHORT;
1528             }
1529           else if ( !(frame = gcry_malloc (nframe)) )
1530             rc = gpg_err_code_from_errno (errno);
1531           else
1532             { /* Assemble the pkcs#1 block type 1. */
1533               n = 0;
1534               frame[n++] = 0;
1535               frame[n++] = 1; /* block type */
1536               i = nframe - valuelen - asnlen - 3 ;
1537               gcry_assert (i > 1);
1538               memset (frame+n, 0xff, i );
1539               n += i;
1540               frame[n++] = 0;
1541               memcpy (frame+n, asn, asnlen);
1542               n += asnlen;
1543               memcpy (frame+n, value, valuelen );
1544               n += valuelen;
1545               gcry_assert (n == nframe);
1546       
1547               /* Convert it into an MPI.  FIXME: error checking?  */
1548               gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
1549             }
1550           
1551           gcry_free (frame);
1552         }
1553     }
1554   else
1555     rc = GPG_ERR_CONFLICT;
1556    
1557   gcry_sexp_release (ldata);
1558   gcry_sexp_release (lhash);
1559   gcry_sexp_release (lvalue);
1560
1561   if (!rc)
1562     *flags = parsed_flags;
1563
1564   return rc;
1565 }
1566
1567
1568 /*
1569    Do a PK encrypt operation
1570   
1571    Caller has to provide a public key as the SEXP pkey and data as a
1572    SEXP with just one MPI in it. Alternatively S_DATA might be a
1573    complex S-Expression, similar to the one used for signature
1574    verification.  This provides a flag which allows to handle PKCS#1
1575    block type 2 padding.  The function returns a a sexp which may be
1576    passed to to pk_decrypt.
1577   
1578    Returns: 0 or an errorcode.
1579   
1580    s_data = See comment for sexp_data_to_mpi
1581    s_pkey = <key-as-defined-in-sexp_to_key>
1582    r_ciph = (enc-val
1583                (<algo>
1584                  (<param_name1> <mpi>)
1585                  ...
1586                  (<param_namen> <mpi>)
1587                ))
1588
1589 */
1590 gcry_error_t
1591 gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
1592 {
1593   gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
1594   const char *algo_name, *algo_elems;
1595   int flags;
1596   gcry_err_code_t rc;
1597   gcry_pk_spec_t *pubkey = NULL;
1598   gcry_module_t module = NULL;
1599
1600   *r_ciph = NULL;
1601
1602   REGISTER_DEFAULT_PUBKEYS;
1603
1604   /* Get the key. */
1605   rc = sexp_to_key (s_pkey, 0, &pkey, &module);
1606   if (rc)
1607     goto leave;
1608
1609   gcry_assert (module);
1610   pubkey = (gcry_pk_spec_t *) module->spec;
1611
1612   /* If aliases for the algorithm name exists, take the first one
1613      instead of the regular name to adhere to SPKI conventions.  We
1614      assume that the first alias name is the lowercase version of the
1615      regular one.  This change is required for compatibility with
1616      1.1.12 generated S-expressions. */
1617   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
1618   if (!algo_name || !*algo_name)
1619     algo_name = pubkey->name;
1620   
1621   algo_elems = pubkey->elements_enc;
1622   
1623   /* Get the stuff we want to encrypt. */
1624   rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
1625                          &flags);
1626   if (rc)
1627     goto leave;
1628
1629   /* Now we can encrypt DATA to CIPH. */
1630   ciph = gcry_calloc (strlen (algo_elems) + 1, sizeof (*ciph));
1631   if (!ciph)
1632     {
1633       rc = gpg_err_code_from_errno (errno);
1634       goto leave;
1635     }
1636   rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
1637   mpi_free (data);
1638   data = NULL;
1639   if (rc)
1640     goto leave;
1641
1642   /* We did it.  Now build the return list */
1643   {
1644     char *string, *p;
1645     int i;
1646     size_t nelem = strlen (algo_elems);
1647     size_t needed = 19 + strlen (algo_name) + (nelem * 5);
1648     void **arg_list;
1649     
1650     /* Build the string.  */
1651     string = p = gcry_malloc (needed);
1652     if (!string)
1653       {
1654         rc = gpg_err_code_from_errno (errno);
1655         goto leave;
1656       }
1657     p = stpcpy ( p, "(enc-val(" );
1658     p = stpcpy ( p, algo_name );
1659     for (i=0; algo_elems[i]; i++ )
1660       {
1661         *p++ = '(';
1662         *p++ = algo_elems[i];
1663         p = stpcpy ( p, "%m)" );
1664       }
1665     strcpy ( p, "))" );
1666     
1667     /* And now the ugly part: We don't have a function to pass an
1668      * array to a format string, so we have to do it this way :-(.  */
1669     /* FIXME: There is now such a format specifier, so we can
1670        change the code to be more clear. */
1671     arg_list = malloc (nelem * sizeof *arg_list);
1672     if (!arg_list)
1673       {
1674         rc = gpg_err_code_from_errno (errno);
1675         goto leave;
1676       }
1677
1678     for (i = 0; i < nelem; i++)
1679       arg_list[i] = ciph + i;
1680     
1681     rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
1682     free (arg_list);
1683     if (rc)
1684       BUG ();
1685     gcry_free (string);
1686   }
1687
1688  leave:
1689   if (pkey)
1690     {
1691       release_mpi_array (pkey);
1692       gcry_free (pkey);
1693     }
1694
1695   if (ciph)
1696     {
1697       release_mpi_array (ciph);
1698       gcry_free (ciph);
1699     }
1700
1701   if (module)
1702     {
1703       ath_mutex_lock (&pubkeys_registered_lock);
1704       _gcry_module_release (module);
1705       ath_mutex_unlock (&pubkeys_registered_lock);
1706     }
1707
1708   return gcry_error (rc);
1709 }
1710
1711 /* 
1712    Do a PK decrypt operation
1713   
1714    Caller has to provide a secret key as the SEXP skey and data in a
1715    format as created by gcry_pk_encrypt.  For historic reasons the
1716    function returns simply an MPI as an S-expression part; this is
1717    deprecated and the new method should be used which returns a real
1718    S-expressionl this is selected by adding at least an empty flags
1719    list to S_DATA.
1720    
1721    Returns: 0 or an errorcode.
1722   
1723    s_data = (enc-val
1724               [(flags)]
1725               (<algo>
1726                 (<param_name1> <mpi>)
1727                 ...
1728                 (<param_namen> <mpi>)
1729               ))
1730    s_skey = <key-as-defined-in-sexp_to_key>
1731    r_plain= Either an incomplete S-expression without the parentheses
1732             or if the flags list is used (even if empty) a real S-expression:
1733             (value PLAIN). 
1734  */
1735 gcry_error_t
1736 gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
1737 {
1738   gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL;
1739   int modern, want_pkcs1, flags;
1740   gcry_err_code_t rc;
1741   gcry_module_t module_enc = NULL, module_key = NULL;
1742   gcry_pk_spec_t *pubkey = NULL;
1743
1744   *r_plain = NULL;
1745
1746   REGISTER_DEFAULT_PUBKEYS;
1747
1748   rc = sexp_to_key (s_skey, 1, &skey, &module_key);
1749   if (rc)
1750     goto leave;
1751
1752   rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &want_pkcs1, &flags);
1753   if (rc)
1754     goto leave;
1755   
1756   if (module_key->mod_id != module_enc->mod_id)
1757     {
1758       rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
1759       goto leave;
1760     }
1761
1762   pubkey = (gcry_pk_spec_t *) module_key->spec;
1763
1764   rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
1765   if (rc)
1766     goto leave;
1767
1768   if (gcry_sexp_build (r_plain, NULL, modern? "(value %m)" : "%m", plain))
1769     BUG ();
1770   
1771  leave:
1772   if (skey)
1773     {
1774       release_mpi_array (skey);
1775       gcry_free (skey);
1776     }
1777
1778   if (plain)
1779     mpi_free (plain);
1780
1781   if (data)
1782     {
1783       release_mpi_array (data);
1784       gcry_free (data);
1785     }
1786
1787   if (module_key || module_enc)
1788     {
1789       ath_mutex_lock (&pubkeys_registered_lock);
1790       if (module_key)
1791         _gcry_module_release (module_key);
1792       if (module_enc)
1793         _gcry_module_release (module_enc);
1794       ath_mutex_unlock (&pubkeys_registered_lock);
1795     }
1796
1797   return gcry_error (rc);
1798 }
1799
1800
1801
1802 /*
1803    Create a signature.
1804   
1805    Caller has to provide a secret key as the SEXP skey and data
1806    expressed as a SEXP list hash with only one element which should
1807    instantly be available as a MPI. Alternatively the structure given
1808    below may be used for S_HASH, it provides the abiliy to pass flags
1809    to the operation; the only flag defined by now is "pkcs1" which
1810    does PKCS#1 block type 1 style padding.
1811   
1812    Returns: 0 or an errorcode.
1813             In case of 0 the function returns a new SEXP with the
1814             signature value; the structure of this signature depends on the
1815             other arguments but is always suitable to be passed to
1816             gcry_pk_verify
1817   
1818    s_hash = See comment for sexp_data_to_mpi
1819                
1820    s_skey = <key-as-defined-in-sexp_to_key>
1821    r_sig  = (sig-val
1822               (<algo>
1823                 (<param_name1> <mpi>)
1824                 ...
1825                 (<param_namen> <mpi>))
1826              [(hash algo)]) 
1827
1828   Note that (hash algo) in R_SIG is not used.
1829 */
1830 gcry_error_t
1831 gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
1832 {
1833   gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
1834   gcry_pk_spec_t *pubkey = NULL;
1835   gcry_module_t module = NULL;
1836   const char *algo_name, *algo_elems;
1837   int i;
1838   gcry_err_code_t rc;
1839
1840   *r_sig = NULL;
1841
1842   REGISTER_DEFAULT_PUBKEYS;
1843
1844   rc = sexp_to_key (s_skey, 1, &skey, &module);
1845   if (rc)
1846     goto leave;
1847
1848   gcry_assert (module);
1849   pubkey = (gcry_pk_spec_t *) module->spec;
1850   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
1851   if (!algo_name || !*algo_name)
1852     algo_name = pubkey->name;
1853   
1854   algo_elems = pubkey->elements_sig;
1855
1856   /* Get the stuff we want to sign.  Note that pk_get_nbits does also
1857       work on a private key. */
1858   rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey),
1859                              &hash, 0, NULL);
1860   if (rc)
1861     goto leave;
1862
1863   result = gcry_calloc (strlen (algo_elems) + 1, sizeof (*result));
1864   if (!result)
1865     {
1866       rc = gpg_err_code_from_errno (errno);
1867       goto leave;
1868     }
1869   rc = pubkey_sign (module->mod_id, result, hash, skey);
1870   if (rc)
1871     goto leave;
1872
1873   {
1874     char *string, *p;
1875     size_t nelem, needed = strlen (algo_name) + 20;
1876     void **arg_list;
1877
1878     nelem = strlen (algo_elems);
1879     
1880     /* Count elements, so that we can allocate enough space. */
1881     needed += 10 * nelem;
1882
1883     /* Build the string. */
1884     string = p = gcry_malloc (needed);
1885     if (!string)
1886       {
1887         rc = gpg_err_code_from_errno (errno);
1888         goto leave;
1889       }
1890     p = stpcpy (p, "(sig-val(");
1891     p = stpcpy (p, algo_name);
1892     for (i = 0; algo_elems[i]; i++)
1893       {
1894         *p++ = '(';
1895         *p++ = algo_elems[i];
1896         p = stpcpy (p, "%m)");
1897       }
1898     strcpy (p, "))");
1899
1900     arg_list = malloc (nelem * sizeof *arg_list);
1901     if (!arg_list)
1902       {
1903         rc = gpg_err_code_from_errno (errno);
1904         goto leave;
1905       }
1906
1907     for (i = 0; i < nelem; i++)
1908       arg_list[i] = result + i;
1909
1910     rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
1911     free (arg_list);
1912     if (rc)
1913       BUG ();
1914     gcry_free (string);
1915   }
1916
1917  leave:
1918   if (skey)
1919     {
1920       release_mpi_array (skey);
1921       gcry_free (skey);
1922     }
1923
1924   if (hash)
1925     mpi_free (hash);
1926
1927   if (result)
1928     {
1929       release_mpi_array (result);
1930       gcry_free (result);
1931     }
1932
1933   return gcry_error (rc);
1934 }
1935
1936
1937 /*
1938    Verify a signature.
1939
1940    Caller has to supply the public key pkey, the signature sig and his
1941    hashvalue data.  Public key has to be a standard public key given
1942    as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
1943    must be an S-Exp like the one in sign too.  */
1944 gcry_error_t
1945 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
1946 {
1947   gcry_module_t module_key = NULL, module_sig = NULL;
1948   gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
1949   gcry_err_code_t rc;
1950
1951   REGISTER_DEFAULT_PUBKEYS;
1952  
1953   rc = sexp_to_key (s_pkey, 0, &pkey, &module_key);
1954   if (rc)
1955     goto leave;
1956
1957   rc = sexp_to_sig (s_sig, &sig, &module_sig);
1958   if (rc)
1959     goto leave;
1960
1961   /* Fixme: Check that the algorithm of S_SIG is compatible to the one
1962      of S_PKEY.  */
1963
1964   if (module_key->mod_id != module_sig->mod_id)
1965     {
1966       rc = GPG_ERR_CONFLICT;
1967       goto leave;
1968     }
1969
1970   rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0);
1971   if (rc)
1972     goto leave;
1973
1974   rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
1975
1976  leave:
1977   if (pkey)
1978     {
1979       release_mpi_array (pkey);
1980       gcry_free (pkey);
1981     }
1982   if (sig)
1983     {
1984       release_mpi_array (sig);
1985       gcry_free (sig);
1986     }
1987   if (hash)
1988     mpi_free (hash);
1989
1990   if (module_key || module_sig)
1991     {
1992       ath_mutex_lock (&pubkeys_registered_lock);
1993       if (module_key)
1994         _gcry_module_release (module_key);
1995       if (module_sig)
1996         _gcry_module_release (module_sig);
1997       ath_mutex_unlock (&pubkeys_registered_lock);
1998     }
1999
2000   return gcry_error (rc);
2001 }
2002
2003
2004 /*
2005    Test a key.
2006
2007    This may be used either for a public or a secret key to see whether
2008    the internal structure is okay.
2009   
2010    Returns: 0 or an errorcode.
2011   
2012    s_key = <key-as-defined-in-sexp_to_key> */
2013 gcry_error_t
2014 gcry_pk_testkey (gcry_sexp_t s_key)
2015 {
2016   gcry_module_t module = NULL;
2017   gcry_mpi_t *key = NULL;
2018   gcry_err_code_t rc;
2019   
2020   REGISTER_DEFAULT_PUBKEYS;
2021
2022   /* Note we currently support only secret key checking. */
2023   rc = sexp_to_key (s_key, 1, &key, &module);
2024   if (! rc)
2025     {
2026       rc = pubkey_check_secret_key (module->mod_id, key);
2027       release_mpi_array (key);
2028       gcry_free (key);
2029     }
2030   return gcry_error (rc);
2031 }
2032
2033
2034 /*
2035   Create a public key pair and return it in r_key.
2036   How the key is created depends on s_parms:
2037   (genkey
2038    (algo
2039      (parameter_name_1 ....)
2040       ....
2041      (parameter_name_n ....)
2042   ))
2043   The key is returned in a format depending on the
2044   algorithm. Both, private and secret keys are returned
2045   and optionally some additional informatin.
2046   For elgamal we return this structure:
2047   (key-data
2048    (public-key
2049      (elg
2050         (p <mpi>)
2051         (g <mpi>)
2052         (y <mpi>)
2053      )
2054    )
2055    (private-key
2056      (elg
2057         (p <mpi>)
2058         (g <mpi>)
2059         (y <mpi>)
2060         (x <mpi>)
2061      )
2062    )
2063    (misc-key-info
2064       (pm1-factors n1 n2 ... nn)
2065    ))
2066  */
2067 gcry_error_t
2068 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
2069 {
2070   gcry_pk_spec_t *pubkey = NULL;
2071   gcry_module_t module = NULL;
2072   gcry_sexp_t list = NULL;
2073   gcry_sexp_t l2 = NULL;
2074   gcry_sexp_t l3 = NULL;
2075   char *name = NULL;
2076   size_t n;
2077   gcry_err_code_t rc = GPG_ERR_NO_ERROR;
2078   int i;
2079   const char *algo_name = NULL;
2080   int algo;
2081   const char *sec_elems = NULL, *pub_elems = NULL;
2082   gcry_mpi_t skey[12];
2083   gcry_mpi_t *factors = NULL;
2084   gcry_sexp_t extrainfo = NULL;
2085   unsigned int nbits = 0;
2086   unsigned long use_e = 0;
2087
2088   skey[0] = NULL;
2089   *r_key = NULL;
2090
2091   REGISTER_DEFAULT_PUBKEYS;
2092
2093   list = gcry_sexp_find_token (s_parms, "genkey", 0);
2094   if (!list)
2095     {
2096       rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
2097       goto leave;
2098     }
2099
2100   l2 = gcry_sexp_cadr (list);
2101   gcry_sexp_release (list);
2102   list = l2;
2103   l2 = NULL;
2104   if (! list)
2105     {
2106       rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
2107       goto leave;
2108     }
2109
2110   name = _gcry_sexp_nth_string (list, 0);
2111   if (!name)
2112     {
2113       rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
2114       goto leave;
2115     }
2116   
2117   ath_mutex_lock (&pubkeys_registered_lock);
2118   module = gcry_pk_lookup_name (name);
2119   ath_mutex_unlock (&pubkeys_registered_lock);
2120   gcry_free (name);
2121   name = NULL;
2122   if (!module)
2123     {
2124       rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
2125       goto leave;
2126     }
2127   
2128   pubkey = (gcry_pk_spec_t *) module->spec;
2129   algo = module->mod_id;
2130   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2131   if (!algo_name || !*algo_name)
2132     algo_name = pubkey->name;
2133   pub_elems = pubkey->elements_pkey;
2134   sec_elems = pubkey->elements_skey;
2135   if (strlen (sec_elems) >= DIM(skey))
2136     BUG ();
2137
2138   /* Handle the optional rsa-use-e element.  Actually this belong into
2139      the algorithm module but we have this parameter in the public
2140      module API, so we need to parse it right here.  */
2141   l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
2142   if (l2)
2143     {
2144       char buf[50];
2145       const char *s;
2146
2147       s = gcry_sexp_nth_data (l2, 1, &n);
2148       if ( !s || n >= DIM (buf) - 1 )
2149         {
2150           rc = GPG_ERR_INV_OBJ; /* No value or value too large.  */
2151           goto leave;
2152         }
2153       memcpy (buf, s, n);
2154       buf[n] = 0;
2155       use_e = strtoul (buf, NULL, 0);
2156       gcry_sexp_release (l2);
2157       l2 = NULL;
2158     }
2159   else
2160     use_e = 65537; /* Not given, use the value generated by old versions. */
2161
2162
2163   /* Get the "nbits" parameter.  */
2164   l2 = gcry_sexp_find_token (list, "nbits", 0);
2165   if (l2)
2166     {
2167       char buf[50];
2168       const char *s;
2169
2170       s = gcry_sexp_nth_data (l2, 1, &n);
2171       if (!s || n >= DIM (buf) - 1 )
2172         {
2173           rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr.  */
2174           goto leave;
2175         }
2176       memcpy (buf, s, n);
2177       buf[n] = 0;
2178       nbits = (unsigned int)strtoul (buf, NULL, 0);
2179       gcry_sexp_release (l2); l2 = NULL;
2180     }
2181   else 
2182     nbits = 0;
2183
2184   /* Pass control to the algorithm module. */
2185   rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey, 
2186                         &factors, &extrainfo);
2187   gcry_sexp_release (list); list = NULL;
2188   if (rc)
2189     goto leave;
2190
2191   /* Key generation succeeded: Build an S-expression.  */
2192   {
2193     char *string, *p;
2194     size_t nelem=0, nelem_cp = 0, needed=0;
2195     gcry_mpi_t mpis[30];
2196     
2197     /* Estimate size of format string.  */
2198     nelem = strlen (pub_elems) + strlen (sec_elems);
2199     if (factors)
2200       {
2201         for (i = 0; factors[i]; i++)
2202           nelem++;
2203       }
2204     nelem_cp = nelem;
2205
2206     needed += nelem * 10;
2207     /* (+5 is for EXTRAINFO ("%S")).  */
2208     needed += 2 * strlen (algo_name) + 300 + 5;
2209     if (nelem > DIM (mpis))
2210       BUG ();
2211
2212     /* Build the string. */
2213     nelem = 0;
2214     string = p = gcry_malloc (needed);
2215     if (!string)
2216       {
2217         rc = gpg_err_code_from_errno (errno);
2218         goto leave;
2219       }
2220     p = stpcpy (p, "(key-data");
2221     p = stpcpy (p, "(public-key(");
2222     p = stpcpy (p, algo_name);
2223     for(i = 0; pub_elems[i]; i++)
2224       {
2225         *p++ = '(';
2226         *p++ = pub_elems[i];
2227         p = stpcpy (p, "%m)");
2228         mpis[nelem++] = skey[i];
2229       }
2230     p = stpcpy (p, "))");
2231     p = stpcpy (p, "(private-key(");
2232     p = stpcpy (p, algo_name);
2233     for (i = 0; sec_elems[i]; i++)
2234       {
2235         *p++ = '(';
2236         *p++ = sec_elems[i];
2237         p = stpcpy (p, "%m)");
2238         mpis[nelem++] = skey[i];
2239       }
2240     p = stpcpy (p, "))");
2241
2242     /* Hack to make release_mpi_array() work.  */
2243     skey[i] = NULL;
2244
2245     if (extrainfo)
2246       {
2247         /* If we have extrainfo we should not have any factors.  */
2248         p = stpcpy (p, "%S");
2249       }
2250     else if (factors && factors[0])
2251       {
2252         p = stpcpy (p, "(misc-key-info(pm1-factors");
2253         for(i = 0; factors[i]; i++)
2254           {
2255             p = stpcpy (p, "%m");
2256             mpis[nelem++] = factors[i];
2257           }
2258         p = stpcpy (p, "))");
2259       }
2260     strcpy (p, ")");
2261     gcry_assert (p - string < needed);
2262
2263     while (nelem < DIM (mpis))
2264       mpis[nelem++] = NULL;
2265
2266     {
2267       int elem_n = strlen (pub_elems) + strlen (sec_elems);
2268       void **arg_list;
2269
2270       /* Allocate one extra for EXTRAINFO ("%S").  */
2271       arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
2272       if (!arg_list)
2273         {
2274           rc = gpg_err_code_from_errno (errno);
2275           goto leave;
2276         }
2277       for (i = 0; i < elem_n; i++)
2278         arg_list[i] = mpis + i;
2279       if (extrainfo)
2280         arg_list[i] = &extrainfo;
2281       else if (factors && factors[0])
2282         {
2283           for (; i < nelem_cp; i++)
2284             arg_list[i] = factors + i - elem_n;
2285         }
2286       
2287       rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
2288       gcry_free (arg_list);
2289       if (rc)
2290         BUG ();
2291       gcry_assert (DIM (mpis) == 30); /* Reminder to make sure that
2292                                          the array gets increased if
2293                                          new parameters are added. */
2294     }
2295     gcry_free (string);
2296   }
2297
2298  leave:
2299   gcry_free (name);
2300   gcry_sexp_release (extrainfo);
2301   release_mpi_array (skey);
2302   /* Don't free SKEY itself, it is an stack allocated array. */
2303
2304   if (factors)
2305     {
2306       release_mpi_array ( factors );
2307       gcry_free (factors);
2308     }
2309   
2310   gcry_sexp_release (l3);
2311   gcry_sexp_release (l2);
2312   gcry_sexp_release (list);
2313
2314   if (module)
2315     {
2316       ath_mutex_lock (&pubkeys_registered_lock);
2317       _gcry_module_release (module);
2318       ath_mutex_unlock (&pubkeys_registered_lock);
2319     }
2320
2321   return gcry_error (rc);
2322 }
2323
2324
2325 /* 
2326    Get the number of nbits from the public key.
2327
2328    Hmmm: Should we have really this function or is it better to have a
2329    more general function to retrieve different properties of the key?  */
2330 unsigned int
2331 gcry_pk_get_nbits (gcry_sexp_t key)
2332 {
2333   gcry_module_t module = NULL;
2334   gcry_pk_spec_t *pubkey;
2335   gcry_mpi_t *keyarr = NULL;
2336   unsigned int nbits = 0;
2337   gcry_err_code_t rc;
2338
2339   REGISTER_DEFAULT_PUBKEYS;
2340
2341   rc = sexp_to_key (key, 0, &keyarr, &module);
2342   if (rc == GPG_ERR_INV_OBJ)
2343     rc = sexp_to_key (key, 1, &keyarr, &module);
2344   if (rc)
2345     return 0; /* Error - 0 is a suitable indication for that. */
2346
2347   pubkey = (gcry_pk_spec_t *) module->spec;
2348   nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
2349   
2350   ath_mutex_lock (&pubkeys_registered_lock);
2351   _gcry_module_release (module);
2352   ath_mutex_unlock (&pubkeys_registered_lock);
2353
2354   release_mpi_array (keyarr);
2355   gcry_free (keyarr);
2356
2357   return nbits;
2358 }
2359
2360
2361 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
2362    key parameters expressed in a way depending on the algorithm.
2363
2364    ARRAY must either be 20 bytes long or NULL; in the latter case a
2365    newly allocated array of that size is returned, otherwise ARRAY or
2366    NULL is returned to indicate an error which is most likely an
2367    unknown algorithm.  The function accepts public or secret keys. */
2368 unsigned char *
2369 gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
2370 {
2371   gcry_sexp_t list = NULL, l2 = NULL;
2372   gcry_pk_spec_t *pubkey = NULL;
2373   gcry_module_t module = NULL;
2374   pk_extra_spec_t *extraspec;
2375   const char *s;
2376   char *name = NULL;
2377   int idx;
2378   const char *elems;
2379   gcry_md_hd_t md = NULL;
2380
2381   REGISTER_DEFAULT_PUBKEYS;
2382
2383   /* Check that the first element is valid. */
2384   list = gcry_sexp_find_token (key, "public-key", 0);
2385   if (! list)
2386     list = gcry_sexp_find_token (key, "private-key", 0);
2387   if (! list)
2388     list = gcry_sexp_find_token (key, "protected-private-key", 0);
2389   if (! list)
2390     list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
2391   if (! list)
2392     return NULL; /* No public- or private-key object. */
2393
2394   l2 = gcry_sexp_cadr (list);
2395   gcry_sexp_release (list);
2396   list = l2;
2397   l2 = NULL;
2398
2399   name = _gcry_sexp_nth_string (list, 0);
2400   if (!name)
2401     goto fail; /* Invalid structure of object. */
2402
2403   ath_mutex_lock (&pubkeys_registered_lock);
2404   module = gcry_pk_lookup_name (name);
2405   ath_mutex_unlock (&pubkeys_registered_lock);
2406
2407   if (!module)
2408     goto fail; /* Unknown algorithm.  */
2409
2410   pubkey = (gcry_pk_spec_t *) module->spec;
2411   extraspec = module->extraspec;
2412
2413   elems = pubkey->elements_grip;
2414   if (!elems)
2415     goto fail; /* No grip parameter.  */
2416     
2417   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
2418     goto fail;
2419
2420   if (extraspec && extraspec->comp_keygrip)
2421     {
2422       /* Module specific method to compute a keygrip.  */
2423       if (extraspec->comp_keygrip (md, list))
2424         goto fail;
2425     }
2426   else
2427     {
2428       /* Generic method to compute a keygrip.  */
2429       for (idx = 0, s = elems; *s; s++, idx++)
2430         {
2431           const char *data;
2432           size_t datalen;
2433           char buf[30];
2434           
2435           l2 = gcry_sexp_find_token (list, s, 1);
2436           if (! l2)
2437             goto fail;
2438           data = gcry_sexp_nth_data (l2, 1, &datalen);
2439           if (! data)
2440             goto fail;
2441           
2442           snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
2443           gcry_md_write (md, buf, strlen (buf));
2444           gcry_md_write (md, data, datalen);
2445           gcry_sexp_release (l2);
2446           gcry_md_write (md, ")", 1);
2447         }
2448     }
2449   
2450   if (!array)
2451     {
2452       array = gcry_malloc (20);
2453       if (! array)
2454         goto fail;
2455     }
2456
2457   memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
2458   gcry_md_close (md);
2459   gcry_sexp_release (list);
2460   return array;
2461
2462  fail:
2463   gcry_free (name);
2464   gcry_sexp_release (l2);
2465   gcry_md_close (md);
2466   gcry_sexp_release (list);
2467   return NULL;
2468 }
2469
2470
2471 gcry_error_t
2472 gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
2473 {
2474   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2475
2476   REGISTER_DEFAULT_PUBKEYS;
2477
2478   switch (cmd)
2479     {
2480     case GCRYCTL_DISABLE_ALGO:
2481       /* This one expects a buffer pointing to an integer with the
2482          algo number.  */
2483       if ((! buffer) || (buflen != sizeof (int)))
2484         err = GPG_ERR_INV_ARG;
2485       else
2486         disable_pubkey_algo (*((int *) buffer));
2487       break;
2488
2489     default:
2490       err = GPG_ERR_INV_OP;
2491     }
2492
2493   return gcry_error (err);
2494 }
2495
2496
2497 /* Return information about the given algorithm
2498
2499    WHAT selects the kind of information returned:
2500
2501     GCRYCTL_TEST_ALGO:
2502         Returns 0 when the specified algorithm is available for use.
2503         Buffer must be NULL, nbytes  may have the address of a variable
2504         with the required usage of the algorithm. It may be 0 for don't
2505         care or a combination of the GCRY_PK_USAGE_xxx flags;
2506
2507     GCRYCTL_GET_ALGO_USAGE:
2508         Return the usage flags for the given algo.  An invalid algo
2509         returns 0.  Disabled algos are ignored here because we
2510         only want to know whether the algo is at all capable of
2511         the usage.
2512   
2513    Note: Because this function is in most cases used to return an
2514    integer value, we can make it easier for the caller to just look at
2515    the return value.  The caller will in all cases consult the value
2516    and thereby detecting whether a error occurred or not (i.e. while
2517    checking the block size) */
2518 gcry_error_t
2519 gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
2520 {
2521   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2522
2523   switch (what)
2524     {
2525     case GCRYCTL_TEST_ALGO:
2526       {
2527         int use = nbytes ? *nbytes : 0;
2528         if (buffer)
2529           err = GPG_ERR_INV_ARG;
2530         else if (check_pubkey_algo (algorithm, use))
2531           err = GPG_ERR_PUBKEY_ALGO;
2532         break;
2533       }
2534
2535     case GCRYCTL_GET_ALGO_USAGE:
2536       {
2537         gcry_module_t pubkey;
2538         int use = 0;
2539
2540         REGISTER_DEFAULT_PUBKEYS;
2541
2542         ath_mutex_lock (&pubkeys_registered_lock);
2543         pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
2544         if (pubkey)
2545           {
2546             use = ((gcry_pk_spec_t *) pubkey->spec)->use;
2547             _gcry_module_release (pubkey);
2548           }
2549         ath_mutex_unlock (&pubkeys_registered_lock);
2550
2551         /* FIXME? */
2552         *nbytes = use;
2553
2554         break;
2555       }
2556
2557     case GCRYCTL_GET_ALGO_NPKEY:
2558       {
2559         /* FIXME?  */
2560         int npkey = pubkey_get_npkey (algorithm);
2561         *nbytes = npkey;
2562         break;
2563       }
2564     case GCRYCTL_GET_ALGO_NSKEY:
2565       {
2566         /* FIXME?  */
2567         int nskey = pubkey_get_nskey (algorithm);
2568         *nbytes = nskey;
2569         break;
2570       }
2571     case GCRYCTL_GET_ALGO_NSIGN:
2572       {
2573         /* FIXME?  */
2574         int nsign = pubkey_get_nsig (algorithm);
2575         *nbytes = nsign;
2576         break;
2577       }
2578     case GCRYCTL_GET_ALGO_NENCR:
2579       {
2580         /* FIXME?  */
2581         int nencr = pubkey_get_nenc (algorithm);
2582         *nbytes = nencr;
2583         break;
2584       }
2585
2586     default:
2587       err = GPG_ERR_INV_OP;
2588     }
2589
2590   return gcry_error (err);
2591 }
2592
2593
2594 /* Explicitly initialize this module.  */
2595 gcry_err_code_t
2596 _gcry_pk_init (void)
2597 {
2598   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2599
2600   REGISTER_DEFAULT_PUBKEYS;
2601
2602   return err;
2603 }
2604
2605
2606 gcry_err_code_t
2607 _gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
2608 {
2609   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2610   gcry_module_t pubkey;
2611
2612   REGISTER_DEFAULT_PUBKEYS;
2613
2614   ath_mutex_lock (&pubkeys_registered_lock);
2615   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
2616   if (pubkey)
2617     *module = pubkey;
2618   else
2619     err = GPG_ERR_PUBKEY_ALGO;
2620   ath_mutex_unlock (&pubkeys_registered_lock);
2621
2622   return err;
2623 }
2624
2625
2626 void
2627 _gcry_pk_module_release (gcry_module_t module)
2628 {
2629   ath_mutex_lock (&pubkeys_registered_lock);
2630   _gcry_module_release (module);
2631   ath_mutex_unlock (&pubkeys_registered_lock);
2632 }
2633
2634 /* Get a list consisting of the IDs of the loaded pubkey modules.  If
2635    LIST is zero, write the number of loaded pubkey modules to
2636    LIST_LENGTH and return.  If LIST is non-zero, the first
2637    *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
2638    according size.  In case there are less pubkey modules than
2639    *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
2640 gcry_error_t
2641 gcry_pk_list (int *list, int *list_length)
2642 {
2643   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2644
2645   ath_mutex_lock (&pubkeys_registered_lock);
2646   err = _gcry_module_list (pubkeys_registered, list, list_length);
2647   ath_mutex_unlock (&pubkeys_registered_lock);
2648
2649   return err;
2650 }
2651
2652
2653 /* Run the selftests for pubkey algorithm ALGO with optional reporting
2654    function REPORT.  */
2655 gpg_error_t
2656 _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
2657 {
2658   gcry_module_t module = NULL;
2659   pk_extra_spec_t *extraspec = NULL;
2660   gcry_err_code_t ec = 0;
2661
2662   REGISTER_DEFAULT_PUBKEYS;
2663
2664   ath_mutex_lock (&pubkeys_registered_lock);
2665   module = _gcry_module_lookup_id (pubkeys_registered, algo);
2666   if (module && !(module->flags & FLAG_MODULE_DISABLED))
2667     extraspec = module->extraspec;
2668   ath_mutex_unlock (&pubkeys_registered_lock);
2669   if (extraspec && extraspec->selftest)
2670     ec = extraspec->selftest (algo, extended, report);
2671   else
2672     {
2673       ec = GPG_ERR_PUBKEY_ALGO;
2674       if (report)
2675         report ("pubkey", algo, "module", 
2676                 module && !(module->flags & FLAG_MODULE_DISABLED)?
2677                 "no selftest available" :
2678                 module? "algorithm disabled" : "algorithm not found");
2679     }
2680
2681   if (module)
2682     {
2683       ath_mutex_lock (&pubkeys_registered_lock);
2684       _gcry_module_release (module);
2685       ath_mutex_unlock (&pubkeys_registered_lock);
2686     }
2687   return gpg_error (ec);
2688 }
2689
2690
2691 /* This function is only used by ac.c!  */
2692 gcry_err_code_t
2693 _gcry_pk_get_elements (int algo, char **enc, char **sig)
2694 {
2695   gcry_module_t pubkey;
2696   gcry_pk_spec_t *spec;
2697   gcry_err_code_t err;
2698   char *enc_cp;
2699   char *sig_cp;
2700
2701   REGISTER_DEFAULT_PUBKEYS;
2702
2703   enc_cp = NULL;
2704   sig_cp = NULL;
2705   spec = NULL;
2706
2707   pubkey = _gcry_module_lookup_id (pubkeys_registered, algo);
2708   if (! pubkey)
2709     {
2710       err = GPG_ERR_INTERNAL;
2711       goto out;
2712     }
2713   spec = pubkey->spec;
2714
2715   if (enc)
2716     {
2717       enc_cp = strdup (spec->elements_enc);
2718       if (! enc_cp)
2719         {
2720           err = gpg_err_code_from_errno (errno);
2721           goto out;
2722         }
2723     }
2724   
2725   if (sig)
2726     {
2727       sig_cp = strdup (spec->elements_sig);
2728       if (! sig_cp)
2729         {
2730           err = gpg_err_code_from_errno (errno);
2731           goto out;
2732         }
2733     }
2734
2735   if (enc)
2736     *enc = enc_cp;
2737   if (sig)
2738     *sig = sig_cp;
2739   err = 0;
2740
2741  out:
2742
2743   _gcry_module_release (pubkey);
2744   if (err)
2745     {
2746       free (enc_cp);
2747       free (sig_cp);
2748     }
2749
2750   return err;
2751 }