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