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