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