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