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