* acinclude.m4 (AC_CHECK_PTH): Added.
[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     { &_gcry_pubkey_spec_rsa, GCRY_PK_RSA },
48 #endif
49 #if USE_ELGAMAL
50     { &_gcry_pubkey_spec_elg, GCRY_PK_ELG },
51 #endif
52 #if USE_DSA
53     { &_gcry_pubkey_spec_dsa, GCRY_PK_DSA },
54 #endif
55     { NULL, 0 },
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, idx;
688   const char *name;
689   gcry_sexp_t list;
690
691   for (name = element_names, idx = 0; *name && (! err); name++, idx++)
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[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
699           gcry_sexp_release (list);
700           if (! elements[idx])
701             err = GPG_ERR_INV_OBJ;
702         }
703     }
704
705   if (err)
706     {
707       for (i = 0; i < idx; i++)
708         if (elements[i])
709           gcry_free (elements[i]);
710     }
711   return err;
712 }
713
714 /****************
715  * Convert a S-Exp with either a private or a public key to our
716  * internal format. Currently we do only support the following
717  * algorithms:
718  *    dsa
719  *    rsa
720  *    openpgp-dsa
721  *    openpgp-rsa
722  *    openpgp-elg
723  *    openpgp-elg-sig
724  * Provide a SE with the first element be either "private-key" or
725  * or "public-key". the followed by a list with its first element
726  * be one of the above algorithm identifiers and the following
727  * elements are pairs with parameter-id and value.
728  * NOTE: we look through the list to find a list beginning with
729  * "private-key" or "public-key" - the first one found is used.
730  *
731  * FIXME: Allow for encrypted secret keys here.
732  *
733  * Returns: A pointer to an allocated array of MPIs if the return value is
734  *          zero; the caller has to release this array.
735  *
736  * Example of a DSA public key:
737  *  (private-key
738  *    (dsa
739  *      (p <mpi>)
740  *      (g <mpi>)
741  *      (y <mpi>)
742  *      (x <mpi>)
743  *    )
744  *  )
745  * The <mpi> are expected to be in GCRYMPI_FMT_USG
746  */
747 static gcry_err_code_t
748 sexp_to_key (gcry_sexp_t sexp, int want_private, gcry_mpi_t **retarray,
749              gcry_module_t *retalgo)
750 {
751     gcry_sexp_t list, l2;
752     const char *name;
753     size_t n;
754     const char *elems;
755     gcry_mpi_t *array;
756     gcry_err_code_t err = GPG_ERR_NO_ERROR;
757     gcry_module_t module;
758     gcry_pk_spec_t *pubkey;
759
760     /* check that the first element is valid */
761     list = gcry_sexp_find_token( sexp, want_private? "private-key"
762                                                     :"public-key", 0 );
763     if( !list )
764         return GPG_ERR_INV_OBJ; /* Does not contain a public- or private-key object */
765     l2 = gcry_sexp_cadr( list );
766     gcry_sexp_release ( list );
767     list = l2;
768     name = gcry_sexp_nth_data( list, 0, &n );
769     if( !name ) {
770         gcry_sexp_release ( list );
771         return GPG_ERR_INV_OBJ; /* invalid structure of object */
772     }
773
774     {
775       char *name_terminated = gcry_xmalloc (n + 1);
776       strncpy (name_terminated, name, n);
777       name_terminated[n] = 0;
778
779       ath_mutex_lock (&pubkeys_registered_lock);
780       module = gcry_pk_lookup_name (name_terminated);
781       ath_mutex_unlock (&pubkeys_registered_lock);
782
783       free (name_terminated);
784     }
785
786     if (! module)
787       {
788         gcry_sexp_release (list);
789         return GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
790       }
791     else
792       pubkey = (gcry_pk_spec_t *) module->spec;
793
794     elems = want_private ? pubkey->elements_skey : pubkey->elements_pkey;
795     array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
796     if (! array)
797       err = gpg_err_code_from_errno (errno);
798     if (! err)
799       err = sexp_elements_extract (list, elems, array);
800
801     if (list)
802       gcry_sexp_release (list);
803
804     if (err)
805       {
806         if (array)
807           gcry_free (array);
808
809         ath_mutex_lock (&pubkeys_registered_lock);
810         _gcry_module_release (module);
811         ath_mutex_unlock (&pubkeys_registered_lock);
812       }
813     else
814       {
815         *retarray = array;
816         *retalgo = module;
817       }
818
819     return err;
820 }
821
822 static gcry_err_code_t
823 sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
824              gcry_module_t *retalgo)
825 {
826     gcry_sexp_t list, l2;
827     const char *name;
828     size_t n;
829     const char *elems;
830     gcry_mpi_t *array;
831     gcry_err_code_t err = GPG_ERR_NO_ERROR;
832     gcry_module_t module;
833     gcry_pk_spec_t *pubkey;
834
835     /* check that the first element is valid */
836     list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
837     if( !list )
838         return GPG_ERR_INV_OBJ; /* Does not contain a signature value object */
839     l2 = gcry_sexp_nth (list, 1);
840     if(! l2)
841       {
842         gcry_sexp_release (list);
843         return GPG_ERR_NO_OBJ; /* no cadr for the sig object */
844       }
845     name = gcry_sexp_nth_data( l2, 0, &n );
846     if( !name ) {
847         gcry_sexp_release ( list );
848         gcry_sexp_release ( l2 );
849         return GPG_ERR_INV_OBJ; /* invalid structure of object */
850     }
851     else if (n == 5 && (! memcmp (name, "flags", 5))) {
852       /* Skip flags, since they are not used but just here for the
853          sake of consisten S-expressions.  */
854       gcry_sexp_release (l2);
855       l2 = gcry_sexp_nth (list, 2);
856       if (! l2)
857         {
858           gcry_sexp_release (list);
859           return GPG_ERR_INV_OBJ;
860         }
861       name = gcry_sexp_nth_data (l2, 0, &n);
862     }
863       
864     {
865       char *name_terminated = gcry_xmalloc (n + 1);
866       strncpy (name_terminated, name, n);
867       name_terminated[n] = 0;
868       
869       ath_mutex_lock (&pubkeys_registered_lock);
870       module = gcry_pk_lookup_name (name_terminated);
871       ath_mutex_unlock (&pubkeys_registered_lock);
872
873       free (name_terminated);
874     }
875
876     if (! module)
877       {
878         gcry_sexp_release (l2);
879         gcry_sexp_release (list);
880         return GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
881       }
882     else
883       pubkey = (gcry_pk_spec_t *) module->spec;
884
885     elems = pubkey->elements_sig;
886     array = gcry_calloc (strlen (elems) + 1 , sizeof (*array));
887     if (! array)
888       err = gpg_err_code_from_errno (errno);
889
890     if (! err)
891       err = sexp_elements_extract (list, elems, array);
892
893     gcry_sexp_release (l2);
894     gcry_sexp_release (list);
895
896     if (err)
897       {
898         ath_mutex_lock (&pubkeys_registered_lock);
899         _gcry_module_release (module);
900         ath_mutex_unlock (&pubkeys_registered_lock);
901
902         if (array)
903           gcry_free (array);
904       }
905     else
906       {
907         *retarray = array;
908         *retalgo = module;
909       }
910
911     return err;
912 }
913
914
915 /****************
916  * Take sexp and return an array of MPI as used for our internal decrypt
917  * function.
918  * s_data = (enc-val
919  *           [(flags [pkcs1])
920  *            (<algo>
921  *              (<param_name1> <mpi>)
922  *              ...
923  *              (<param_namen> <mpi>)
924  *            ))
925  * RET_MODERN is set to true when at least an empty flags list has been found.
926  */
927 static gcry_err_code_t
928 sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
929              int *ret_modern, int *ret_want_pkcs1, int *flags)
930 {
931   gcry_sexp_t list = NULL, l2 = NULL;
932   gcry_pk_spec_t *pubkey = NULL;
933   gcry_module_t module = NULL;
934   const char *name;
935   size_t n;
936   int parsed_flags = 0;
937   const char *elems;
938   gcry_mpi_t *array = NULL;
939   gcry_err_code_t err = GPG_ERR_NO_ERROR;
940
941   *ret_want_pkcs1 = 0;
942   *ret_modern = 0;
943
944   /* check that the first element is valid */
945   list = gcry_sexp_find_token (sexp, "enc-val" , 0);
946   if (! list)
947     err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object */
948
949   if (! err)
950     {
951       l2 = gcry_sexp_nth (list, 1);
952       if (! l2)
953         err = GPG_ERR_NO_OBJ; /* no cdr for the data object */
954     }
955
956   if (! err)
957     {
958       /* Extract identifier of sublist.  */
959       name = gcry_sexp_nth_data (l2, 0, &n);
960       if (! name)
961         err = GPG_ERR_INV_OBJ; /* invalid structure of object */
962     }
963
964   if (! err)
965     {
966       if ((n == 5) && (! memcmp (name, "flags", 5)))
967         {
968           /* There is a flags element - process it */
969           const char *s;
970           int i;
971
972           *ret_modern = 1;
973           for (i = gcry_sexp_length (l2) - 1; i > 0 && (! err); i--)
974             {
975               s = gcry_sexp_nth_data (l2, i, &n);
976               if (! s)
977                 ; /* not a data element - ignore */
978               else if (n == 3 && ! memcmp (s, "raw", 3))
979                 ; /* just a dummy because it is the default */
980               else if (n == 5 && ! memcmp (s, "pkcs1", 5))
981                 *ret_want_pkcs1 = 1;
982               else if (n == 11 && ! memcmp (s, "no-blinding", 11))
983                 parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
984               else
985                 err = GPG_ERR_INV_FLAG;
986             }
987       
988           if (! err)
989             {
990               /* Get the next which has the actual data */
991               gcry_sexp_release (l2);
992               l2 = gcry_sexp_nth (list, 2);
993               if (! l2)
994                 err = GPG_ERR_NO_OBJ; /* no cdr for the data object */
995             }
996       
997           if (! err)
998             {
999               /* Extract sublist identifier.  */
1000               name = gcry_sexp_nth_data (l2, 0, &n);
1001               if (! name)
1002                 err = GPG_ERR_INV_OBJ; /* invalid structure of object */
1003             }
1004         }
1005
1006       if (! err)
1007         {
1008           gcry_sexp_release (list);
1009           list = l2;
1010           l2 = NULL;
1011         }
1012     }
1013
1014   if (! err)
1015     {
1016       char *name_terminated = gcry_xmalloc (n + 1);
1017       strncpy (name_terminated, name, n);
1018       name_terminated[n] = 0;
1019
1020       ath_mutex_lock (&pubkeys_registered_lock);
1021       module = gcry_pk_lookup_name (name_terminated);
1022       ath_mutex_unlock (&pubkeys_registered_lock);
1023
1024       free (name_terminated);
1025
1026       if (! module)
1027         err = GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
1028       else
1029         pubkey = (gcry_pk_spec_t *) module->spec;
1030     }
1031
1032   if (! err)
1033     {
1034       elems = pubkey->elements_enc;
1035       array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
1036       if (! array)
1037         err = gpg_err_code_from_errno (errno);
1038     }
1039
1040   if (! err)
1041     err = sexp_elements_extract (list, elems, array);
1042
1043   if (list)
1044     gcry_sexp_release (list);
1045   if (l2)
1046     gcry_sexp_release (l2);
1047
1048   if (err)
1049     {
1050       ath_mutex_lock (&pubkeys_registered_lock);
1051       _gcry_module_release (module);
1052       ath_mutex_unlock (&pubkeys_registered_lock);
1053       if (array)
1054         gcry_free (array);
1055     }
1056   else
1057     {
1058       *retarray = array;
1059       *retalgo = module;
1060       *flags = parsed_flags;
1061     }
1062
1063   return err;
1064 }
1065
1066 /* Take the hash value and convert into an MPI, suitable for for
1067    passing to the low level functions.  We currently support the
1068    old style way of passing just a MPI and the modern interface which
1069    allows to pass flags so that we can choose between raw and pkcs1
1070    padding - may be more padding options later. 
1071
1072    (<mpi>)
1073    or
1074    (data
1075     [(flags [pkcs1])]
1076     [(hash <algo> <value>)]
1077     [(value <text>)]
1078    )
1079    
1080    Either the VALUE or the HASH element must be present for use
1081    with signatures.  VALUE is used for encryption.
1082
1083    NBITS is the length of the key in bits. 
1084
1085 */
1086 static gcry_err_code_t
1087 sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
1088                   int for_encryption, int *flags)
1089 {
1090   gcry_err_code_t rc = 0;
1091   gcry_sexp_t ldata, lhash, lvalue;
1092   int i;
1093   size_t n;
1094   const char *s;
1095   int is_raw = 0, is_pkcs1 = 0, unknown_flag=0; 
1096   int parsed_flags = 0, dummy_flags;
1097
1098   if (! flags)
1099     flags = &dummy_flags;
1100   
1101   *ret_mpi = NULL;
1102   ldata = gcry_sexp_find_token (input, "data", 0);
1103   if (!ldata)
1104     { /* assume old style */
1105       *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
1106       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
1107     }
1108
1109   /* see whether there is a flags object */
1110   {
1111     gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
1112     if (lflags)
1113       { /* parse the flags list. */
1114         for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
1115           {
1116             s = gcry_sexp_nth_data (lflags, i, &n);
1117             if (!s)
1118               ; /* not a data element*/
1119             else if ( n == 3 && !memcmp (s, "raw", 3))
1120               is_raw = 1;
1121             else if ( n == 5 && !memcmp (s, "pkcs1", 5))
1122               is_pkcs1 = 1;
1123             else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1124               parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1125             else
1126               unknown_flag = 1;
1127           }
1128         gcry_sexp_release (lflags);
1129       }
1130   }
1131
1132   if (!is_pkcs1 && !is_raw)
1133     is_raw = 1; /* default to raw */
1134
1135   /* Get HASH or MPI */
1136   lhash = gcry_sexp_find_token (ldata, "hash", 0);
1137   lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
1138
1139   if (!(!lhash ^ !lvalue))
1140     rc = GPG_ERR_INV_OBJ; /* none or both given */
1141   else if (unknown_flag)
1142     rc = GPG_ERR_INV_FLAG;
1143   else if (is_raw && is_pkcs1 && !for_encryption)
1144     rc = GPG_ERR_CONFLICT;
1145   else if (is_raw && lvalue)
1146     {
1147       *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
1148       if (!*ret_mpi)
1149         rc = GPG_ERR_INV_OBJ;
1150     }
1151   else if (is_pkcs1 && lvalue && for_encryption)
1152     { /* create pkcs#1 block type 2 padding */
1153       unsigned char *frame = NULL;
1154       size_t nframe = (nbits+7) / 8;
1155       const void * value;
1156       size_t valuelen;
1157       unsigned char *p;
1158
1159       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1160         rc = GPG_ERR_INV_OBJ;
1161       else if (valuelen + 7 > nframe || !nframe)
1162         {
1163           /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
1164           rc = GPG_ERR_TOO_SHORT; /* the key is too short */
1165         }
1166       else if ( !(frame = gcry_malloc_secure (nframe)))
1167         rc = gpg_err_code_from_errno (errno);
1168       else
1169         {
1170           n = 0;
1171           frame[n++] = 0;
1172           frame[n++] = 2; /* block type */
1173           i = nframe - 3 - valuelen;
1174           assert (i > 0);
1175           p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
1176           /* replace zero bytes by new values*/
1177           for (;;)
1178             {
1179               int j, k;
1180               unsigned char *pp;
1181               
1182               /* count the zero bytes */
1183               for (j=k=0; j < i; j++)
1184                 {
1185                   if (!p[j])
1186                     k++;
1187                 }
1188               if (!k)
1189                 break; /* okay: no (more) zero bytes */
1190               
1191               k += k/128; /* better get some more */
1192               pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
1193               for (j=0; j < i && k; j++)
1194                 {
1195                   if (!p[j])
1196                     p[j] = pp[--k];
1197                 }
1198               gcry_free (pp);
1199             }
1200           memcpy (frame+n, p, i);
1201           n += i;
1202           gcry_free (p);
1203           
1204           frame[n++] = 0;
1205           memcpy (frame+n, value, valuelen);
1206           n += valuelen;
1207           assert (n == nframe);
1208
1209           /* FIXME, error checking?  */
1210           gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
1211         }
1212
1213       gcry_free(frame);
1214     }
1215   else if (is_pkcs1 && lhash && !for_encryption)
1216     { /* create pkcs#1 block type 1 padding */
1217       if (gcry_sexp_length (lhash) != 3)
1218         rc = GPG_ERR_INV_OBJ;
1219       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1220         rc = GPG_ERR_INV_OBJ;
1221       else
1222         {
1223           static struct { const char *name; int algo; } hashnames[] = 
1224           { { "sha1",   GCRY_MD_SHA1 },
1225             { "md5",    GCRY_MD_MD5 },
1226             { "rmd160", GCRY_MD_RMD160 },
1227             { "sha256", GCRY_MD_SHA256 },
1228             { "sha384", GCRY_MD_SHA384 },
1229             { "sha512", GCRY_MD_SHA512 },
1230             { "md2",    GCRY_MD_MD2 },
1231             { "md4",    GCRY_MD_MD4 },
1232             { "tiger",  GCRY_MD_TIGER },
1233             { "haval",  GCRY_MD_HAVAL },
1234             { NULL }
1235           };
1236           int algo;
1237           byte asn[100];
1238           byte *frame = NULL;
1239           size_t nframe = (nbits+7) / 8;
1240           const void * value;
1241           size_t valuelen;
1242           size_t asnlen, dlen;
1243             
1244           for (i=0; hashnames[i].name; i++)
1245             {
1246               if ( strlen (hashnames[i].name) == n
1247                    && !memcmp (hashnames[i].name, s, n))
1248                 break;
1249             }
1250
1251           algo = hashnames[i].algo;
1252           asnlen = DIM(asn);
1253           dlen = gcry_md_get_algo_dlen (algo);
1254
1255           if (!hashnames[i].name)
1256             rc = GPG_ERR_DIGEST_ALGO;
1257           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
1258                     || !valuelen )
1259             rc = GPG_ERR_INV_OBJ;
1260           else if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
1261             rc = GPG_ERR_NOT_IMPLEMENTED; /* we don't have all of the above algos */
1262           else if ( valuelen != dlen )
1263             {
1264               /* hash value does not match the length of digest for
1265                  the given algo */
1266               rc = GPG_ERR_CONFLICT;
1267             }
1268           else if( !dlen || dlen + asnlen + 4 > nframe)
1269             {
1270               /* can't encode an DLEN byte digest MD into a NFRAME byte frame */
1271               rc = GPG_ERR_TOO_SHORT;
1272             }
1273           else if ( !(frame = gcry_malloc (nframe)) )
1274             rc = gpg_err_code_from_errno (errno);
1275           else
1276             { /* assemble the pkcs#1 block type 1 */
1277               n = 0;
1278               frame[n++] = 0;
1279               frame[n++] = 1; /* block type */
1280               i = nframe - valuelen - asnlen - 3 ;
1281               assert (i > 1);
1282               memset (frame+n, 0xff, i );
1283               n += i;
1284               frame[n++] = 0;
1285               memcpy (frame+n, asn, asnlen);
1286               n += asnlen;
1287               memcpy (frame+n, value, valuelen );
1288               n += valuelen;
1289               assert (n == nframe);
1290       
1291               /* convert it into an MPI, FIXME: error checking?  */
1292               gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
1293             }
1294           
1295           gcry_free (frame);
1296         }
1297     }
1298   else
1299     rc = GPG_ERR_CONFLICT;
1300    
1301   gcry_sexp_release (ldata);
1302   gcry_sexp_release (lhash);
1303   gcry_sexp_release (lvalue);
1304
1305   if (! rc)
1306     *flags = parsed_flags;
1307
1308   return rc;
1309 }
1310
1311
1312 /*
1313    Do a PK encrypt operation
1314   
1315    Caller has to provide a public key as the SEXP pkey and data as a
1316    SEXP with just one MPI in it. Alternativly S_DATA might be a
1317    complex S-Expression, similar to the one used for signature
1318    verification.  This provides a flag which allows to handle PKCS#1
1319    block type 2 padding.  The function returns a a sexp which may be
1320    passed to to pk_decrypt.
1321   
1322    Returns: 0 or an errorcode.
1323   
1324    s_data = See comment for sexp_data_to_mpi
1325    s_pkey = <key-as-defined-in-sexp_to_key>
1326    r_ciph = (enc-val
1327                (<algo>
1328                  (<param_name1> <mpi>)
1329                  ...
1330                  (<param_namen> <mpi>)
1331                ))
1332
1333 */
1334 gcry_error_t
1335 gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
1336 {
1337   gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
1338   const char *algo_name, *algo_elems;
1339   int flags;
1340   gcry_err_code_t rc;
1341   gcry_pk_spec_t *pubkey = NULL;
1342   gcry_module_t module = NULL;
1343
1344   REGISTER_DEFAULT_PUBKEYS;
1345
1346   *r_ciph = NULL;
1347   /* get the key */
1348   rc = sexp_to_key (s_pkey, 0, &pkey, &module);
1349   if (! rc)
1350     {
1351       assert (module);
1352       pubkey = (gcry_pk_spec_t *) module->spec;
1353
1354       /* If aliases for the algorithm name exists, take the first one
1355          instead of the regular name to adhere to SPKI conventions.
1356          We assume that the first alias name is the lowercase version
1357          of the regular one.  This change is required for
1358          compatibility with 1.1.12 generated S-expressions. */
1359       algo_name = pubkey->aliases? *pubkey->aliases : NULL;
1360       if (!algo_name || !*algo_name)
1361         algo_name = pubkey->name;
1362
1363       algo_elems = pubkey->elements_enc;
1364       
1365       /* get the stuff we want to encrypt */
1366       rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
1367                              &flags);
1368     }
1369
1370   if (! rc)
1371     {
1372       /* Now we can encrypt data to ciph */
1373       ciph = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*ciph));
1374       rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
1375       mpi_free (data);
1376     }
1377
1378   /* We did it.  Now build the return list */
1379   if (! rc)
1380     {
1381       char *string, *p;
1382       int i;
1383       size_t nelem = strlen (algo_elems);
1384       size_t needed = 19 + strlen (algo_name) + (nelem * 5);
1385
1386       /* Build the string.  */
1387       string = p = gcry_xmalloc (needed);
1388       p = stpcpy ( p, "(enc-val(" );
1389       p = stpcpy ( p, algo_name );
1390       for(i=0; algo_elems[i]; i++ ) {
1391         *p++ = '(';
1392         *p++ = algo_elems[i];
1393         p = stpcpy ( p, "%m)" );
1394       }
1395       strcpy ( p, "))" );
1396
1397       /* and now the ugly part:  we don't have a function to
1398        * pass an array to a format string, so we have to do it this way :-(
1399        */
1400
1401       {
1402         void **arg_list = malloc (nelem * sizeof *arg_list);
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 (pkey)
1422     {
1423       release_mpi_array (pkey);
1424       gcry_free (pkey);
1425     }
1426
1427   if (ciph)
1428     {
1429       release_mpi_array (ciph);
1430       gcry_free (ciph);
1431     }
1432
1433   if (module)
1434     {
1435       ath_mutex_lock (&pubkeys_registered_lock);
1436       _gcry_module_release (module);
1437       ath_mutex_unlock (&pubkeys_registered_lock);
1438     }
1439
1440   return gcry_error (rc);
1441 }
1442
1443 /****************
1444  * Do a PK decrypt operation
1445  *
1446  * Caller has to provide a secret key as the SEXP skey and data in a
1447  * format as created by gcry_pk_encrypt.  For historic reasons the
1448  * function returns simply an MPI as an S-expression part; this is
1449  * deprecated and the new method should be used which returns a real
1450  * S-expressionl this is selected by adding at least an empty flags
1451  * list to S_DATA.
1452  * 
1453  * Returns: 0 or an errorcode.
1454  *
1455  * s_data = (enc-val
1456  *            [(flags)]
1457  *            (<algo>
1458  *              (<param_name1> <mpi>)
1459  *              ...
1460  *              (<param_namen> <mpi>)
1461  *            ))
1462  * s_skey = <key-as-defined-in-sexp_to_key>
1463  * r_plain= Either an incomplete S-expression without the parentheses
1464  *          or if the flags list is used (even if empty) a real S-expression:
1465  *          (value PLAIN).  */
1466 gcry_error_t
1467 gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
1468 {
1469   gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL;
1470   int modern, want_pkcs1, flags;
1471   gcry_err_code_t rc;
1472   gcry_module_t module_enc = NULL, module_key = NULL;
1473   gcry_pk_spec_t *pubkey = NULL;
1474
1475   REGISTER_DEFAULT_PUBKEYS;
1476
1477   *r_plain = NULL;
1478   rc = sexp_to_key (s_skey, 1, &skey, &module_key);
1479
1480   if (! rc)
1481     rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &want_pkcs1, &flags);
1482
1483   if (! rc)
1484     {
1485       if (module_key->mod_id != module_enc->mod_id)
1486         rc = GPG_ERR_CONFLICT; /* key algo does not match data algo */
1487       else
1488         pubkey = (gcry_pk_spec_t *) module_key->spec;
1489     }
1490
1491   if (! rc)
1492     rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
1493
1494   if (! rc)
1495     {
1496       if (! modern)
1497         {
1498           if (gcry_sexp_build (r_plain, NULL, "%m", plain))
1499             BUG ();
1500         }
1501       else
1502         {
1503           if (gcry_sexp_build (r_plain, NULL, "(value %m)", plain))
1504             BUG ();
1505         }
1506     }
1507
1508   if (skey)
1509     {
1510       release_mpi_array (skey);
1511       gcry_free (skey);
1512     }
1513
1514   if (plain)
1515     mpi_free (plain);
1516
1517   if (data)
1518     {
1519       release_mpi_array (data);
1520       gcry_free (data);
1521     }
1522
1523   if (module_key || module_enc)
1524     {
1525       ath_mutex_lock (&pubkeys_registered_lock);
1526       if (module_key)
1527         _gcry_module_release (module_key);
1528       if (module_enc)
1529         _gcry_module_release (module_enc);
1530       ath_mutex_unlock (&pubkeys_registered_lock);
1531     }
1532
1533   return gcry_error (rc);
1534 }
1535
1536
1537
1538 /****************
1539  * Create a signature.
1540  *
1541  * Caller has to provide a secret key as the SEXP skey and data
1542  * expressed as a SEXP list hash with only one element which should
1543  * instantly be available as a MPI. Alternatively the structure given
1544  * below may be used for S_HASH, it provides the abiliy to pass flags
1545  * to the operation; the only flag defined by now is "pkcs1" which
1546  * does PKCS#1 block type 1 style padding.
1547  *
1548  * Returns: 0 or an errorcode.
1549  *          In case of 0 the function returns a new SEXP with the
1550  *          signature value; the structure of this signature depends on the
1551  *          other arguments but is always suitable to be passed to
1552  *          gcry_pk_verify
1553  *
1554  * s_hash = See comment for sexp_data_to_mpi
1555  *             
1556  * s_skey = <key-as-defined-in-sexp_to_key>
1557  * r_sig  = (sig-val
1558  *            (<algo>
1559  *              (<param_name1> <mpi>)
1560  *              ...
1561  *              (<param_namen> <mpi>)
1562  * )) */
1563 gcry_error_t
1564 gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
1565 {
1566   gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
1567   gcry_pk_spec_t *pubkey = NULL;
1568   gcry_module_t module = NULL;
1569   const char *algo_name, *algo_elems;
1570   int i;
1571   gcry_err_code_t rc;
1572
1573
1574   REGISTER_DEFAULT_PUBKEYS;
1575
1576   *r_sig = NULL;
1577   rc = sexp_to_key (s_skey, 1, &skey, &module);
1578
1579   if (! rc)
1580     {
1581       assert (module);
1582       pubkey = (gcry_pk_spec_t *) module->spec;
1583       algo_name = pubkey->aliases? *pubkey->aliases : NULL;
1584       if (!algo_name || !*algo_name)
1585         algo_name = pubkey->name;
1586
1587       algo_elems = pubkey->elements_sig;
1588
1589       /* get the stuff we want to sign */
1590       /* Note that pk_get_nbits does also work on a private key */
1591       rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey),
1592                              &hash, 0, NULL);
1593     }
1594
1595   if (! rc)
1596     {
1597       result = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*result));
1598       rc = pubkey_sign (module->mod_id, result, hash, skey);
1599     }
1600
1601   if (! rc)
1602     {
1603       char *string, *p;
1604       size_t nelem, needed = strlen (algo_name) + 20;
1605
1606       nelem = strlen (algo_elems);
1607
1608       /* count elements, so that we can allocate enough space */
1609       needed += 10 * nelem;
1610
1611       /* build the string */
1612       string = p = gcry_xmalloc (needed);
1613       p = stpcpy (p, "(sig-val(");
1614       p = stpcpy (p, algo_name);
1615       for(i = 0; algo_elems[i]; i++)
1616         {
1617           *p++ = '(';
1618           *p++ = algo_elems[i];
1619           p = stpcpy (p, "%m)");
1620         }
1621       strcpy (p, "))");
1622
1623       {
1624         void **arg_list = malloc (nelem * sizeof *arg_list);
1625         if (arg_list)
1626           {
1627             for (i = 0; i < nelem; i++)
1628               arg_list[i] = &result[i];
1629
1630             rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
1631
1632             free (arg_list);
1633           }
1634         else
1635           rc = gpg_err_code_from_errno (errno);
1636       }
1637
1638       if (rc)
1639         BUG ();
1640       gcry_free (string);
1641     }
1642
1643   if (skey)
1644     {
1645       release_mpi_array (skey);
1646       gcry_free (skey);
1647     }
1648
1649   if (hash)
1650     mpi_free (hash);
1651
1652   if (result)
1653     gcry_free (result);
1654
1655   return gcry_error (rc);
1656 }
1657
1658
1659 /****************
1660  * Verify a signature.  Caller has to supply the public key pkey, the
1661  * signature sig and his hashvalue data.  Public key has to be a
1662  * standard public key given as an S-Exp, sig is a S-Exp as returned
1663  * from gcry_pk_sign and data must be an S-Exp like the one in sign
1664  * too.
1665  */
1666 gcry_error_t
1667 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
1668 {
1669   gcry_module_t module_key = NULL, module_sig = NULL;
1670   gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
1671   gcry_err_code_t rc;
1672
1673   REGISTER_DEFAULT_PUBKEYS;
1674  
1675   rc = sexp_to_key (s_pkey, 0, &pkey, &module_key);
1676   if (! rc)
1677     rc = sexp_to_sig (s_sig, &sig, &module_sig);
1678
1679   if ((! rc)
1680       && (module_key->mod_id != module_sig->mod_id))
1681     rc = GPG_ERR_CONFLICT;
1682
1683   if (! rc)
1684     rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0);
1685
1686   if (! rc)
1687     rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
1688
1689   if (pkey)
1690     {
1691       release_mpi_array (pkey);
1692       gcry_free (pkey);
1693     }
1694   if (sig)
1695     {
1696       release_mpi_array (sig);
1697       gcry_free (sig);
1698     }
1699   if (hash)
1700     mpi_free (hash);
1701
1702   if (module_key || module_sig)
1703     {
1704       ath_mutex_lock (&pubkeys_registered_lock);
1705       if (module_key)
1706         _gcry_module_release (module_key);
1707       if (module_sig)
1708         _gcry_module_release (module_sig);
1709       ath_mutex_unlock (&pubkeys_registered_lock);
1710     }
1711
1712   return gcry_error (rc);
1713 }
1714
1715
1716 /****************
1717  * Test a key.  This may be used either for a public or a secret key
1718  * to see whether internal structre is valid.
1719  *
1720  * Returns: 0 or an errorcode.
1721  *
1722  * s_key = <key-as-defined-in-sexp_to_key>
1723  */
1724 gcry_error_t
1725 gcry_pk_testkey (gcry_sexp_t s_key)
1726 {
1727   gcry_module_t module = NULL;
1728   gcry_mpi_t *key = NULL;
1729   gcry_err_code_t rc;
1730   
1731   REGISTER_DEFAULT_PUBKEYS;
1732
1733   /* Note we currently support only secret key checking */
1734   rc = sexp_to_key (s_key, 1, &key, &module);
1735   if (! rc)
1736     {
1737       rc = pubkey_check_secret_key (module->mod_id, key);
1738       release_mpi_array (key);
1739       gcry_free (key);
1740     }
1741   return gcry_error (rc);
1742 }
1743
1744
1745 /****************
1746  * Create a public key pair and return it in r_key.
1747  * How the key is created depends on s_parms:
1748  * (genkey
1749  *  (algo
1750  *    (parameter_name_1 ....)
1751  *     ....
1752  *    (parameter_name_n ....)
1753  * ))
1754  * The key is returned in a format depending on the
1755  * algorithm. Both, private and secret keys are returned
1756  * and optionally some additional informatin.
1757  * For elgamal we return this structure:
1758  * (key-data
1759  *  (public-key
1760  *    (elg
1761  *      (p <mpi>)
1762  *      (g <mpi>)
1763  *      (y <mpi>)
1764  *    )
1765  *  )
1766  *  (private-key
1767  *    (elg
1768  *      (p <mpi>)
1769  *      (g <mpi>)
1770  *      (y <mpi>)
1771  *      (x <mpi>)
1772  *    )
1773  *  )
1774  *  (misc-key-info
1775  *     (pm1-factors n1 n2 ... nn)
1776  *  )
1777  * )
1778  */
1779 gcry_error_t
1780 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
1781 {
1782   gcry_pk_spec_t *pubkey = NULL;
1783   gcry_module_t module = NULL;
1784   gcry_sexp_t list = NULL, l2 = NULL;
1785   const char *name;
1786   size_t n;
1787   gcry_err_code_t rc = GPG_ERR_NO_ERROR;
1788   int i;
1789   const char *algo_name = NULL;
1790   int algo;
1791   const char *sec_elems = NULL, *pub_elems = NULL;
1792   gcry_mpi_t skey[10] = { NULL }, *factors = NULL;
1793   unsigned int nbits = 0;
1794   unsigned long use_e = 0;
1795
1796   REGISTER_DEFAULT_PUBKEYS;
1797
1798   *r_key = NULL;
1799   list = gcry_sexp_find_token (s_parms, "genkey", 0);
1800   if (! list)
1801     rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data */
1802
1803   if (! rc)
1804     {
1805       l2 = gcry_sexp_cadr (list);
1806       gcry_sexp_release (list);
1807       list = l2;
1808       l2 = NULL;
1809       if (! list)
1810         rc = GPG_ERR_NO_OBJ; /* no cdr for the genkey */
1811     }
1812
1813   if (! rc)
1814     {
1815       name = gcry_sexp_nth_data (list, 0, &n);
1816       if (! name)
1817         rc = GPG_ERR_INV_OBJ; /* algo string missing */
1818     }
1819
1820   if (! rc)
1821     {
1822       char *name_terminated = gcry_xmalloc (n + 1);
1823       strncpy (name_terminated, name, n);
1824       name_terminated[n] = 0;
1825
1826       ath_mutex_lock (&pubkeys_registered_lock);
1827       module = gcry_pk_lookup_name (name_terminated);
1828       ath_mutex_unlock (&pubkeys_registered_lock);
1829
1830       free (name_terminated);
1831
1832       if (! module)
1833         rc = GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
1834       else
1835         {
1836           pubkey = (gcry_pk_spec_t *) module->spec;
1837           algo = module->mod_id;
1838           algo_name = pubkey->aliases? *pubkey->aliases : NULL;
1839           if (!algo_name || !*algo_name)
1840             algo_name = pubkey->name;
1841           pub_elems = pubkey->elements_pkey;
1842           sec_elems = pubkey->elements_skey;
1843         }
1844     }
1845
1846   if (! rc)
1847     {
1848       l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
1849       if (l2)
1850         {
1851           char buf[50];
1852
1853           name = gcry_sexp_nth_data (l2, 1, &n);
1854           if ((! name) || (n >= DIM (buf) - 1))
1855             rc = GPG_ERR_INV_OBJ; /* no value or value too large */
1856           else
1857             {
1858               memcpy (buf, name, n);
1859               buf[n] = 0;
1860               use_e = strtoul (buf, NULL, 0);
1861             }
1862           gcry_sexp_release (l2);
1863           l2 = NULL;
1864         }
1865       else
1866         use_e = 65537; /* not given, use the value generated by old versions. */
1867     }
1868
1869   if (! rc)
1870     {
1871       l2 = gcry_sexp_find_token (list, "nbits", 0);
1872       gcry_sexp_release (list);
1873       list = l2;
1874       l2 = NULL;
1875       if (! list)
1876         rc = GPG_ERR_NO_OBJ; /* no nbits parameter */
1877       else
1878         {
1879           name = gcry_sexp_nth_data (list, 1, &n);
1880           if (! name)
1881             rc = GPG_ERR_INV_OBJ; /* nbits without a cdr */
1882           else
1883             {
1884               char *p = gcry_xmalloc (n + 1);
1885               memcpy (p, name, n);
1886               p[n] = 0;
1887               nbits = (unsigned int) strtol (p, NULL, 0);
1888               gcry_free (p);
1889             }
1890         }
1891     }
1892
1893   if (! rc)
1894     rc = pubkey_generate (module->mod_id, nbits, use_e, skey, &factors);
1895
1896   if (! rc)
1897     {
1898       char *string, *p;
1899       size_t nelem=0, nelem_cp = 0, needed=0;
1900       gcry_mpi_t mpis[30];
1901
1902       nelem = strlen (pub_elems) + strlen (sec_elems);
1903       for (i = 0; factors[i]; i++)
1904         nelem++;
1905       nelem_cp = nelem;
1906
1907       needed += nelem * 10;
1908       needed += 2 * strlen (algo_name) + 300;
1909       if (nelem > DIM (mpis))
1910         BUG ();
1911
1912       /* build the string */
1913       nelem = 0;
1914       string = p = gcry_xmalloc (needed);
1915       p = stpcpy (p, "(key-data");
1916       p = stpcpy (p, "(public-key(");
1917       p = stpcpy (p, algo_name);
1918       for(i = 0; pub_elems[i]; i++)
1919         {
1920           *p++ = '(';
1921           *p++ = pub_elems[i];
1922           p = stpcpy (p, "%m)");
1923           mpis[nelem++] = skey[i];
1924         }
1925       p = stpcpy (p, "))");
1926       p = stpcpy (p, "(private-key(");
1927       p = stpcpy (p, algo_name);
1928       for (i = 0; sec_elems[i]; i++)
1929         {
1930           *p++ = '(';
1931           *p++ = sec_elems[i];
1932           p = stpcpy (p, "%m)");
1933           mpis[nelem++] = skey[i];
1934         }
1935       p = stpcpy (p, "))");
1936
1937       /* Very ugly hack to make release_mpi_array() work FIXME */
1938       skey[i] = NULL;
1939
1940       p = stpcpy (p, "(misc-key-info(pm1-factors");
1941       for(i = 0; factors[i]; i++)
1942         {
1943           p = stpcpy (p, "%m");
1944           mpis[nelem++] = factors[i];
1945         }
1946       strcpy (p, ")))");
1947
1948       while (nelem < DIM (mpis))
1949         mpis[nelem++] = NULL;
1950
1951       {
1952         int elem_n = strlen (pub_elems) + strlen (sec_elems);
1953         void **arg_list = malloc (nelem_cp * sizeof *arg_list);
1954         if (arg_list)
1955           {
1956             for (i = 0; i < elem_n; i++)
1957               arg_list[i] = &mpis[i];
1958             for (; i < nelem_cp; i++)
1959               arg_list[i] = &factors[i - elem_n];
1960
1961             rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
1962
1963             free (arg_list);
1964           }
1965         else
1966           rc = gpg_err_code_from_errno (errno);
1967       }
1968
1969       if (rc)
1970         BUG ();
1971       assert (DIM (mpis) == 30);        /* ? */
1972       gcry_free (string);
1973     }
1974
1975   release_mpi_array (skey);
1976   /* no free:  skey is a static array */
1977
1978   if (factors)
1979     {
1980       release_mpi_array ( factors );
1981       gcry_free (factors);
1982     }
1983
1984   if (l2)
1985     gcry_sexp_release (l2);
1986   if (list)
1987     gcry_sexp_release (list);
1988
1989   if (module)
1990     {
1991       ath_mutex_lock (&pubkeys_registered_lock);
1992       _gcry_module_release (module);
1993       ath_mutex_unlock (&pubkeys_registered_lock);
1994     }
1995
1996   return gcry_error (rc);
1997 }
1998
1999 /****************
2000  * Get the number of nbits from the public key
2001  * Hmmm: Should we have really this function or is it
2002  * better to have a more general function to retrieve
2003  * different propoerties of the key?
2004  */
2005 unsigned int
2006 gcry_pk_get_nbits (gcry_sexp_t key)
2007 {
2008   gcry_module_t module = NULL;
2009   gcry_pk_spec_t *pubkey;
2010   gcry_mpi_t *keyarr = NULL;
2011   unsigned int nbits = 0;
2012   gcry_err_code_t rc;
2013
2014   REGISTER_DEFAULT_PUBKEYS;
2015
2016   rc = sexp_to_key (key, 0, &keyarr, &module);
2017   if (rc == GPG_ERR_INV_OBJ)
2018     rc = sexp_to_key (key, 1, &keyarr, &module);
2019   if (rc)
2020     return 0;
2021   else
2022     {
2023       pubkey = (gcry_pk_spec_t *) module->spec;
2024       nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
2025
2026       ath_mutex_lock (&pubkeys_registered_lock);
2027       _gcry_module_release (module);
2028       ath_mutex_unlock (&pubkeys_registered_lock);
2029     }
2030
2031   release_mpi_array (keyarr);
2032   gcry_free (keyarr);
2033
2034   return nbits;
2035 }
2036
2037
2038 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
2039    key parameters expressed in a way depended on the algorithm.
2040
2041    ARRAY must either be 20 bytes long or NULL; in the latter case a
2042    newly allocated array of that size is returned, otherwise ARRAY or
2043    NULL is returned to indicate an error which is most likely an
2044    unknown algorithm.  The function accepts public or secret keys. */
2045 unsigned char *
2046 gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
2047 {
2048   gcry_sexp_t list = NULL, l2 = NULL;
2049   gcry_pk_spec_t *pubkey = NULL;
2050   gcry_module_t module = NULL;
2051   const char *s, *name;
2052   size_t n;
2053   int idx;
2054   int is_rsa;
2055   const char *elems;
2056   gcry_md_hd_t md = NULL;
2057
2058   REGISTER_DEFAULT_PUBKEYS;
2059
2060   /* check that the first element is valid */
2061   list = gcry_sexp_find_token (key, "public-key", 0);
2062   if (! list)
2063     list = gcry_sexp_find_token (key, "private-key", 0);
2064   if (! list)
2065     list = gcry_sexp_find_token (key, "protected-private-key", 0);
2066   if (! list)
2067     return NULL; /* no public- or private-key object */
2068
2069   l2 = gcry_sexp_cadr (list);
2070   gcry_sexp_release (list);
2071   list = l2;
2072   l2 = NULL;
2073
2074   name = gcry_sexp_nth_data (list, 0, &n);
2075   if (! name)
2076     goto fail; /* invalid structure of object */
2077
2078   
2079   {
2080     char *name_terminated = gcry_xmalloc (n + 1);
2081     strncpy (name_terminated, name, n);
2082     name_terminated[n] = 0;
2083
2084     ath_mutex_lock (&pubkeys_registered_lock);
2085     module = gcry_pk_lookup_name (name_terminated);
2086     ath_mutex_unlock (&pubkeys_registered_lock);
2087
2088     free (name_terminated);
2089   }
2090
2091   if (! module)
2092     goto fail; /* unknown algorithm */
2093   else
2094     pubkey = (gcry_pk_spec_t *) module->spec;
2095
2096   /* FIXME, special handling should be implemented by the algorithms,
2097      not by the libgcrypt core.  */
2098   is_rsa = module->mod_id == GCRY_PK_RSA;
2099   elems = pubkey->elements_grip;
2100   if (! elems)
2101     goto fail; /* no grip parameter */
2102     
2103   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
2104     goto fail;
2105
2106   for (idx = 0, s = elems; *s; s++, idx++)
2107     {
2108       const char *data;
2109       size_t datalen;
2110
2111       l2 = gcry_sexp_find_token (list, s, 1);
2112       if (! l2)
2113         goto fail;
2114       data = gcry_sexp_nth_data (l2, 1, &datalen);
2115       if (! data)
2116         goto fail;
2117       if (!is_rsa)
2118         {
2119           char buf[30];
2120
2121           sprintf (buf, "(1:%c%u:", *s, (unsigned int)datalen);
2122           gcry_md_write (md, buf, strlen (buf));
2123         }
2124       /* pkcs-15 says that for RSA only the modulus should be hashed -
2125          however, it is not clear wether this is meant to has the raw
2126          bytes assuming this is an unsigned integer or whether the DER
2127          required 0 should be prefixed. We hash th raw bytes.  For
2128          non-RSA we hash S-expressions. */
2129       gcry_md_write (md, data, datalen);
2130       gcry_sexp_release (l2);
2131       if (!is_rsa)
2132         gcry_md_write (md, ")", 1);
2133     }
2134
2135   if (!array)
2136     {
2137       array = gcry_malloc (20);
2138       if (! array)
2139         goto fail;
2140     }
2141   memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
2142   gcry_md_close (md);
2143   gcry_sexp_release (list);
2144    return array;
2145
2146  fail:
2147   if (l2)
2148     gcry_sexp_release (l2);
2149   if (md)
2150     gcry_md_close (md);
2151   gcry_sexp_release (list);
2152   return NULL;
2153 }
2154
2155
2156 gcry_error_t
2157 gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
2158 {
2159   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2160
2161   REGISTER_DEFAULT_PUBKEYS;
2162
2163   switch (cmd)
2164     {
2165     case GCRYCTL_DISABLE_ALGO:
2166       /* this one expects a buffer pointing to an integer with the
2167        * algo number.
2168        */
2169       if ((! buffer) || (buflen != sizeof (int)))
2170         err = GPG_ERR_CIPHER_ALGO;  /* FIXME?  */
2171       else
2172         disable_pubkey_algo (*((int *) buffer));
2173       break;
2174
2175     default:
2176       err = GPG_ERR_INV_OP;
2177     }
2178
2179   return gcry_error (err);
2180 }
2181
2182
2183 /****************
2184  * Return information about the given algorithm
2185  * WHAT select the kind of information returned:
2186  *  GCRYCTL_TEST_ALGO:
2187  *      Returns 0 when the specified algorithm is available for use.
2188  *      Buffer must be NULL, nbytes  may have the address of a variable
2189  *      with the required usage of the algorithm. It may be 0 for don't
2190  *      care or a combination of the GCRY_PK_USAGE_xxx flags;
2191  *  GCRYCTL_GET_ALGO_USAGE:
2192  *      Return the usage glafs for the give algo.  An invalid alog
2193  *      does return 0.  Disabled algos are ignored here becuase we
2194  *      only want to know whether the algo is at all capable of
2195  *      the usage.
2196  *
2197  * Note:  Because this function is in most cases used to return an
2198  * integer value, we can make it easier for the caller to just look at
2199  * the return value.  The caller will in all cases consult the value
2200  * and thereby detecting whether a error occured or not (i.e. while checking
2201  * the block size)
2202  */
2203 gcry_error_t
2204 gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
2205 {
2206   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2207
2208   switch (what)
2209     {
2210     case GCRYCTL_TEST_ALGO:
2211       {
2212         int use = nbytes ? *nbytes : 0;
2213         if (buffer)
2214           err = GPG_ERR_INV_ARG;
2215         else if (check_pubkey_algo (algorithm, use))
2216           err = GPG_ERR_PUBKEY_ALGO;
2217         break;
2218       }
2219
2220     case GCRYCTL_GET_ALGO_USAGE:
2221       {
2222         gcry_module_t pubkey;
2223         int use = 0;
2224
2225         REGISTER_DEFAULT_PUBKEYS;
2226
2227         ath_mutex_lock (&pubkeys_registered_lock);
2228         pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
2229         if (pubkey)
2230           {
2231             use = ((gcry_pk_spec_t *) pubkey->spec)->use;
2232             _gcry_module_release (pubkey);
2233           }
2234         ath_mutex_unlock (&pubkeys_registered_lock);
2235
2236         /* FIXME? */
2237         *nbytes = use;
2238       }
2239
2240     case GCRYCTL_GET_ALGO_NPKEY:
2241       {
2242         /* FIXME?  */
2243         int npkey = pubkey_get_npkey (algorithm);
2244         *nbytes = npkey;
2245         break;
2246       }
2247     case GCRYCTL_GET_ALGO_NSKEY:
2248       {
2249         /* FIXME?  */
2250         int nskey = pubkey_get_nskey (algorithm);
2251         *nbytes = nskey;
2252         break;
2253       }
2254     case GCRYCTL_GET_ALGO_NSIGN:
2255       {
2256         /* FIXME?  */
2257         int nsign = pubkey_get_nsig (algorithm);
2258         *nbytes = nsign;
2259         break;
2260       }
2261     case GCRYCTL_GET_ALGO_NENCR:
2262       {
2263         /* FIXME?  */
2264         int nencr = pubkey_get_nenc (algorithm);
2265         *nbytes = nencr;
2266         break;
2267       }
2268
2269     default:
2270       err = GPG_ERR_INV_OP;
2271     }
2272
2273   return gcry_error (err);
2274 }
2275
2276 gcry_err_code_t
2277 _gcry_pk_init (void)
2278 {
2279   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2280
2281   REGISTER_DEFAULT_PUBKEYS;
2282
2283   return err;
2284 }
2285
2286 gcry_err_code_t
2287 _gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
2288 {
2289   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2290   gcry_module_t pubkey;
2291
2292   REGISTER_DEFAULT_PUBKEYS;
2293
2294   ath_mutex_lock (&pubkeys_registered_lock);
2295   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
2296   if (pubkey)
2297     *module = pubkey;
2298   else
2299     err = GPG_ERR_PUBKEY_ALGO;
2300   ath_mutex_unlock (&pubkeys_registered_lock);
2301
2302   return err;
2303 }
2304
2305 void
2306 _gcry_pk_module_release (gcry_module_t module)
2307 {
2308   ath_mutex_lock (&pubkeys_registered_lock);
2309   _gcry_module_release (module);
2310   ath_mutex_unlock (&pubkeys_registered_lock);
2311 }
2312
2313 /* Get a list consisting of the IDs of the loaded pubkey modules.  If
2314    LIST is zero, write the number of loaded pubkey modules to
2315    LIST_LENGTH and return.  If LIST is non-zero, the first
2316    *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
2317    according size.  In case there are less pubkey modules than
2318    *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
2319 gcry_error_t
2320 gcry_pk_list (int *list, int *list_length)
2321 {
2322   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2323
2324   ath_mutex_lock (&pubkeys_registered_lock);
2325   err = _gcry_module_list (pubkeys_registered, list, list_length);
2326   ath_mutex_unlock (&pubkeys_registered_lock);
2327
2328   return err;
2329 }