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