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