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