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