* random.c (gcry_random_add_bytes): Return if buflen is zero to
[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, 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 (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         int i;
1625         void **arg_list = malloc (sizeof (void *) * nelem);
1626         if (arg_list)
1627           {
1628             for (i = 0; i < nelem; i++)
1629               arg_list[i] = &result[i];
1630
1631             rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
1632
1633             free (arg_list);
1634           }
1635         else
1636           rc = gpg_err_code_from_errno (errno);
1637       }
1638
1639       if (rc)
1640         BUG ();
1641       gcry_free (string);
1642     }
1643
1644   if (skey)
1645     {
1646       release_mpi_array (skey);
1647       gcry_free (skey);
1648     }
1649
1650   if (hash)
1651     mpi_free (hash);
1652
1653   if (result)
1654     gcry_free (result);
1655
1656   return gcry_error (rc);
1657 }
1658
1659
1660 /****************
1661  * Verify a signature.  Caller has to supply the public key pkey, the
1662  * signature sig and his hashvalue data.  Public key has to be a
1663  * standard public key given as an S-Exp, sig is a S-Exp as returned
1664  * from gcry_pk_sign and data must be an S-Exp like the one in sign
1665  * too.
1666  */
1667 gcry_error_t
1668 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
1669 {
1670   gcry_module_t module_key = NULL, module_sig = NULL;
1671   gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
1672   gcry_err_code_t rc;
1673
1674   REGISTER_DEFAULT_PUBKEYS;
1675  
1676   rc = sexp_to_key (s_pkey, 0, &pkey, &module_key);
1677   if (! rc)
1678     rc = sexp_to_sig (s_sig, &sig, &module_sig);
1679
1680   if ((! rc)
1681       && (module_key->mod_id != module_sig->mod_id))
1682     rc = GPG_ERR_CONFLICT;
1683
1684   if (! rc)
1685     rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0);
1686
1687   if (! rc)
1688     rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
1689
1690   if (pkey)
1691     {
1692       release_mpi_array (pkey);
1693       gcry_free (pkey);
1694     }
1695   if (sig)
1696     {
1697       release_mpi_array (sig);
1698       gcry_free (sig);
1699     }
1700   if (hash)
1701     mpi_free (hash);
1702
1703   if (module_key || module_sig)
1704     {
1705       ath_mutex_lock (&pubkeys_registered_lock);
1706       if (module_key)
1707         _gcry_module_release (module_key);
1708       if (module_sig)
1709         _gcry_module_release (module_sig);
1710       ath_mutex_unlock (&pubkeys_registered_lock);
1711     }
1712
1713   return gcry_error (rc);
1714 }
1715
1716
1717 /****************
1718  * Test a key.  This may be used either for a public or a secret key
1719  * to see whether internal structre is valid.
1720  *
1721  * Returns: 0 or an errorcode.
1722  *
1723  * s_key = <key-as-defined-in-sexp_to_key>
1724  */
1725 gcry_error_t
1726 gcry_pk_testkey (gcry_sexp_t s_key)
1727 {
1728   gcry_module_t module = NULL;
1729   gcry_mpi_t *key = NULL;
1730   gcry_err_code_t rc;
1731   
1732   REGISTER_DEFAULT_PUBKEYS;
1733
1734   /* Note we currently support only secret key checking */
1735   rc = sexp_to_key (s_key, 1, &key, &module);
1736   if (! rc)
1737     {
1738       rc = pubkey_check_secret_key (module->mod_id, key);
1739       release_mpi_array (key);
1740       gcry_free (key);
1741     }
1742   return gcry_error (rc);
1743 }
1744
1745
1746 /****************
1747  * Create a public key pair and return it in r_key.
1748  * How the key is created depends on s_parms:
1749  * (genkey
1750  *  (algo
1751  *    (parameter_name_1 ....)
1752  *     ....
1753  *    (parameter_name_n ....)
1754  * ))
1755  * The key is returned in a format depending on the
1756  * algorithm. Both, private and secret keys are returned
1757  * and optionally some additional informatin.
1758  * For elgamal we return this structure:
1759  * (key-data
1760  *  (public-key
1761  *    (elg
1762  *      (p <mpi>)
1763  *      (g <mpi>)
1764  *      (y <mpi>)
1765  *    )
1766  *  )
1767  *  (private-key
1768  *    (elg
1769  *      (p <mpi>)
1770  *      (g <mpi>)
1771  *      (y <mpi>)
1772  *      (x <mpi>)
1773  *    )
1774  *  )
1775  *  (misc-key-info
1776  *     (pm1-factors n1 n2 ... nn)
1777  *  )
1778  * )
1779  */
1780 gcry_error_t
1781 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
1782 {
1783   gcry_pk_spec_t *pubkey = NULL;
1784   gcry_module_t module = NULL;
1785   gcry_sexp_t list = NULL, l2 = NULL;
1786   const char *name;
1787   size_t n;
1788   gcry_err_code_t rc = GPG_ERR_NO_ERROR;
1789   int i;
1790   const char *algo_name = NULL;
1791   int algo;
1792   const char *sec_elems = NULL, *pub_elems = NULL;
1793   gcry_mpi_t skey[10] = { NULL }, *factors = NULL;
1794   unsigned int nbits = 0;
1795   unsigned long use_e = 0;
1796
1797   REGISTER_DEFAULT_PUBKEYS;
1798
1799   *r_key = NULL;
1800   list = gcry_sexp_find_token (s_parms, "genkey", 0);
1801   if (! list)
1802     rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data */
1803
1804   if (! rc)
1805     {
1806       l2 = gcry_sexp_cadr (list);
1807       gcry_sexp_release (list);
1808       list = l2;
1809       l2 = NULL;
1810       if (! list)
1811         rc = GPG_ERR_NO_OBJ; /* no cdr for the genkey */
1812     }
1813
1814   if (! rc)
1815     {
1816       name = gcry_sexp_nth_data (list, 0, &n);
1817       if (! name)
1818         rc = GPG_ERR_INV_OBJ; /* algo string missing */
1819     }
1820
1821   if (! rc)
1822     {
1823       char *name_terminated = gcry_xmalloc (n + 1);
1824       strncpy (name_terminated, name, n);
1825       name_terminated[n] = 0;
1826
1827       ath_mutex_lock (&pubkeys_registered_lock);
1828       module = gcry_pk_lookup_name (name_terminated);
1829       ath_mutex_unlock (&pubkeys_registered_lock);
1830
1831       free (name_terminated);
1832
1833       if (! module)
1834         rc = GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
1835       else
1836         {
1837           pubkey = (gcry_pk_spec_t *) module->spec;
1838           algo = module->mod_id;
1839           algo_name = pubkey->aliases? *pubkey->aliases : NULL;
1840           if (!algo_name || !*algo_name)
1841             algo_name = pubkey->name;
1842           pub_elems = pubkey->elements_pkey;
1843           sec_elems = pubkey->elements_skey;
1844         }
1845     }
1846
1847   if (! rc)
1848     {
1849       l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
1850       if (l2)
1851         {
1852           char buf[50];
1853
1854           name = gcry_sexp_nth_data (l2, 1, &n);
1855           if ((! name) || (n >= DIM (buf) - 1))
1856             rc = GPG_ERR_INV_OBJ; /* no value or value too large */
1857           else
1858             {
1859               memcpy (buf, name, n);
1860               buf[n] = 0;
1861               use_e = strtoul (buf, NULL, 0);
1862             }
1863           gcry_sexp_release (l2);
1864           l2 = NULL;
1865         }
1866       else
1867         use_e = 65537; /* not given, use the value generated by old versions. */
1868     }
1869
1870   if (! rc)
1871     {
1872       l2 = gcry_sexp_find_token (list, "nbits", 0);
1873       gcry_sexp_release (list);
1874       list = l2;
1875       l2 = NULL;
1876       if (! list)
1877         rc = GPG_ERR_NO_OBJ; /* no nbits parameter */
1878       else
1879         {
1880           name = gcry_sexp_nth_data (list, 1, &n);
1881           if (! name)
1882             rc = GPG_ERR_INV_OBJ; /* nbits without a cdr */
1883           else
1884             {
1885               char *p = gcry_xmalloc (n + 1);
1886               memcpy (p, name, n);
1887               p[n] = 0;
1888               nbits = (unsigned int) strtol (p, NULL, 0);
1889               gcry_free (p);
1890             }
1891         }
1892     }
1893
1894   if (! rc)
1895     rc = pubkey_generate (module->mod_id, nbits, use_e, skey, &factors);
1896
1897   if (! rc)
1898     {
1899       char *string, *p;
1900       size_t nelem=0, nelem_cp = 0, needed=0;
1901       gcry_mpi_t mpis[30];
1902
1903       nelem = strlen (pub_elems) + strlen (sec_elems);
1904       for (i = 0; factors[i]; i++)
1905         nelem++;
1906       nelem_cp = nelem;
1907
1908       needed += nelem * 10;
1909       needed += 2 * strlen (algo_name) + 300;
1910       if (nelem > DIM (mpis))
1911         BUG ();
1912
1913       /* build the string */
1914       nelem = 0;
1915       string = p = gcry_xmalloc (needed);
1916       p = stpcpy (p, "(key-data");
1917       p = stpcpy (p, "(public-key(");
1918       p = stpcpy (p, algo_name);
1919       for(i = 0; pub_elems[i]; i++)
1920         {
1921           *p++ = '(';
1922           *p++ = pub_elems[i];
1923           p = stpcpy (p, "%m)");
1924           mpis[nelem++] = skey[i];
1925         }
1926       p = stpcpy (p, "))");
1927       p = stpcpy (p, "(private-key(");
1928       p = stpcpy (p, algo_name);
1929       for (i = 0; sec_elems[i]; i++)
1930         {
1931           *p++ = '(';
1932           *p++ = sec_elems[i];
1933           p = stpcpy (p, "%m)");
1934           mpis[nelem++] = skey[i];
1935         }
1936       p = stpcpy (p, "))");
1937
1938       /* Very ugly hack to make release_mpi_array() work FIXME */
1939       skey[i] = NULL;
1940
1941       p = stpcpy (p, "(misc-key-info(pm1-factors");
1942       for(i = 0; factors[i]; i++)
1943         {
1944           p = stpcpy (p, "%m");
1945           mpis[nelem++] = factors[i];
1946         }
1947       strcpy (p, ")))");
1948
1949       while (nelem < DIM (mpis))
1950         mpis[nelem++] = NULL;
1951
1952       {
1953         int elem_n = strlen (pub_elems) + strlen (sec_elems), i;
1954         void **arg_list = malloc (sizeof (void *) * nelem_cp);
1955         if (arg_list)
1956           {
1957             for (i = 0; i < elem_n; i++)
1958               arg_list[i] = &mpis[i];
1959             for (; i < nelem_cp; i++)
1960               arg_list[i] = &factors[i - elem_n];
1961
1962             rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
1963
1964             free (arg_list);
1965           }
1966         else
1967           rc = gpg_err_code_from_errno (errno);
1968       }
1969
1970       if (rc)
1971         BUG ();
1972       assert (DIM (mpis) == 30);        /* ? */
1973       gcry_free (string);
1974     }
1975
1976   release_mpi_array (skey);
1977   /* no free:  skey is a static array */
1978
1979   if (factors)
1980     {
1981       release_mpi_array ( factors );
1982       gcry_free (factors);
1983     }
1984
1985   if (l2)
1986     gcry_sexp_release (l2);
1987   if (list)
1988     gcry_sexp_release (list);
1989
1990   if (module)
1991     {
1992       ath_mutex_lock (&pubkeys_registered_lock);
1993       _gcry_module_release (module);
1994       ath_mutex_unlock (&pubkeys_registered_lock);
1995     }
1996
1997   return gcry_error (rc);
1998 }
1999
2000 /****************
2001  * Get the number of nbits from the public key
2002  * Hmmm: Should we have really this function or is it
2003  * better to have a more general function to retrieve
2004  * different propoerties of the key?
2005  */
2006 unsigned int
2007 gcry_pk_get_nbits (gcry_sexp_t key)
2008 {
2009   gcry_module_t module = NULL;
2010   gcry_pk_spec_t *pubkey;
2011   gcry_mpi_t *keyarr = NULL;
2012   unsigned int nbits = 0;
2013   gcry_err_code_t rc;
2014
2015   REGISTER_DEFAULT_PUBKEYS;
2016
2017   rc = sexp_to_key (key, 0, &keyarr, &module);
2018   if (rc == GPG_ERR_INV_OBJ)
2019     rc = sexp_to_key (key, 1, &keyarr, &module);
2020   if (rc)
2021     return 0;
2022   else
2023     {
2024       pubkey = (gcry_pk_spec_t *) module->spec;
2025       nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
2026
2027       ath_mutex_lock (&pubkeys_registered_lock);
2028       _gcry_module_release (module);
2029       ath_mutex_unlock (&pubkeys_registered_lock);
2030     }
2031
2032   release_mpi_array (keyarr);
2033   gcry_free (keyarr);
2034
2035   return nbits;
2036 }
2037
2038
2039 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
2040    key parameters expressed in a way depended on the algorithm.
2041
2042    ARRAY must either be 20 bytes long or NULL; in the latter case a
2043    newly allocated array of that size is returned, otherwise ARRAY or
2044    NULL is returned to indicate an error which is most likely an
2045    unknown algorithm.  The function accepts public or secret keys. */
2046 unsigned char *
2047 gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
2048 {
2049   gcry_sexp_t list = NULL, l2 = NULL;
2050   gcry_pk_spec_t *pubkey = NULL;
2051   gcry_module_t module = NULL;
2052   const char *s, *name;
2053   size_t n;
2054   int idx;
2055   int is_rsa;
2056   const char *elems;
2057   gcry_md_hd_t md = NULL;
2058
2059   REGISTER_DEFAULT_PUBKEYS;
2060
2061   /* check that the first element is valid */
2062   list = gcry_sexp_find_token (key, "public-key", 0);
2063   if (! list)
2064     list = gcry_sexp_find_token (key, "private-key", 0);
2065   if (! list)
2066     list = gcry_sexp_find_token (key, "protected-private-key", 0);
2067   if (! list)
2068     return NULL; /* no public- or private-key object */
2069
2070   l2 = gcry_sexp_cadr (list);
2071   gcry_sexp_release (list);
2072   list = l2;
2073   l2 = NULL;
2074
2075   name = gcry_sexp_nth_data (list, 0, &n);
2076   if (! name)
2077     goto fail; /* invalid structure of object */
2078
2079   
2080   {
2081     char *name_terminated = gcry_xmalloc (n + 1);
2082     strncpy (name_terminated, name, n);
2083     name_terminated[n] = 0;
2084
2085     ath_mutex_lock (&pubkeys_registered_lock);
2086     module = gcry_pk_lookup_name (name_terminated);
2087     ath_mutex_unlock (&pubkeys_registered_lock);
2088
2089     free (name_terminated);
2090   }
2091
2092   if (! module)
2093     goto fail; /* unknown algorithm */
2094   else
2095     pubkey = (gcry_pk_spec_t *) module->spec;
2096
2097   /* FIXME, special handling should be implemented by the algorithms,
2098      not by the libgcrypt core.  */
2099   is_rsa = module->mod_id == GCRY_PK_RSA;
2100   elems = pubkey->elements_grip;
2101   if (! elems)
2102     goto fail; /* no grip parameter */
2103     
2104   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
2105     goto fail;
2106
2107   for (idx = 0, s = elems; *s; s++, idx++)
2108     {
2109       const char *data;
2110       size_t datalen;
2111
2112       l2 = gcry_sexp_find_token (list, s, 1);
2113       if (! l2)
2114         goto fail;
2115       data = gcry_sexp_nth_data (l2, 1, &datalen);
2116       if (! data)
2117         goto fail;
2118       if (!is_rsa)
2119         {
2120           char buf[30];
2121
2122           sprintf (buf, "(1:%c%u:", *s, (unsigned int)datalen);
2123           gcry_md_write (md, buf, strlen (buf));
2124         }
2125       /* pkcs-15 says that for RSA only the modulus should be hashed -
2126          however, it is not clear wether this is meant to has the raw
2127          bytes assuming this is an unsigned integer or whether the DER
2128          required 0 should be prefixed. We hash th raw bytes.  For
2129          non-RSA we hash S-expressions. */
2130       gcry_md_write (md, data, datalen);
2131       gcry_sexp_release (l2);
2132       if (!is_rsa)
2133         gcry_md_write (md, ")", 1);
2134     }
2135
2136   if (!array)
2137     {
2138       array = gcry_malloc (20);
2139       if (! array)
2140         goto fail;
2141     }
2142   memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
2143   gcry_md_close (md);
2144   gcry_sexp_release (list);
2145    return array;
2146
2147  fail:
2148   if (l2)
2149     gcry_sexp_release (l2);
2150   if (md)
2151     gcry_md_close (md);
2152   gcry_sexp_release (list);
2153   return NULL;
2154 }
2155
2156
2157 gcry_error_t
2158 gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
2159 {
2160   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2161
2162   REGISTER_DEFAULT_PUBKEYS;
2163
2164   switch (cmd)
2165     {
2166     case GCRYCTL_DISABLE_ALGO:
2167       /* this one expects a buffer pointing to an integer with the
2168        * algo number.
2169        */
2170       if ((! buffer) || (buflen != sizeof (int)))
2171         err = GPG_ERR_CIPHER_ALGO;  /* FIXME?  */
2172       else
2173         disable_pubkey_algo (*((int *) buffer));
2174       break;
2175
2176     default:
2177       err = GPG_ERR_INV_OP;
2178     }
2179
2180   return gcry_error (err);
2181 }
2182
2183
2184 /****************
2185  * Return information about the given algorithm
2186  * WHAT select the kind of information returned:
2187  *  GCRYCTL_TEST_ALGO:
2188  *      Returns 0 when the specified algorithm is available for use.
2189  *      Buffer must be NULL, nbytes  may have the address of a variable
2190  *      with the required usage of the algorithm. It may be 0 for don't
2191  *      care or a combination of the GCRY_PK_USAGE_xxx flags;
2192  *  GCRYCTL_GET_ALGO_USAGE:
2193  *      Return the usage glafs for the give algo.  An invalid alog
2194  *      does return 0.  Disabled algos are ignored here becuase we
2195  *      only want to know whether the algo is at all capable of
2196  *      the usage.
2197  *
2198  * Note:  Because this function is in most cases used to return an
2199  * integer value, we can make it easier for the caller to just look at
2200  * the return value.  The caller will in all cases consult the value
2201  * and thereby detecting whether a error occured or not (i.e. while checking
2202  * the block size)
2203  */
2204 gcry_error_t
2205 gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
2206 {
2207   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2208
2209   switch (what)
2210     {
2211     case GCRYCTL_TEST_ALGO:
2212       {
2213         int use = nbytes ? *nbytes : 0;
2214         if (buffer)
2215           err = GPG_ERR_INV_ARG;
2216         else if (check_pubkey_algo (algorithm, use))
2217           err = GPG_ERR_PUBKEY_ALGO;
2218         break;
2219       }
2220
2221     case GCRYCTL_GET_ALGO_USAGE:
2222       {
2223         gcry_module_t pubkey;
2224         int use = 0;
2225
2226         REGISTER_DEFAULT_PUBKEYS;
2227
2228         ath_mutex_lock (&pubkeys_registered_lock);
2229         pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
2230         if (pubkey)
2231           {
2232             use = ((gcry_pk_spec_t *) pubkey->spec)->use;
2233             _gcry_module_release (pubkey);
2234           }
2235         ath_mutex_unlock (&pubkeys_registered_lock);
2236
2237         /* FIXME? */
2238         *nbytes = use;
2239       }
2240
2241     case GCRYCTL_GET_ALGO_NPKEY:
2242       {
2243         /* FIXME?  */
2244         int npkey = pubkey_get_npkey (algorithm);
2245         *nbytes = npkey;
2246         break;
2247       }
2248     case GCRYCTL_GET_ALGO_NSKEY:
2249       {
2250         /* FIXME?  */
2251         int nskey = pubkey_get_nskey (algorithm);
2252         *nbytes = nskey;
2253         break;
2254       }
2255     case GCRYCTL_GET_ALGO_NSIGN:
2256       {
2257         /* FIXME?  */
2258         int nsign = pubkey_get_nsig (algorithm);
2259         *nbytes = nsign;
2260         break;
2261       }
2262     case GCRYCTL_GET_ALGO_NENCR:
2263       {
2264         /* FIXME?  */
2265         int nencr = pubkey_get_nenc (algorithm);
2266         *nbytes = nencr;
2267         break;
2268       }
2269
2270     default:
2271       err = GPG_ERR_INV_OP;
2272     }
2273
2274   return gcry_error (err);
2275 }
2276
2277 gcry_err_code_t
2278 _gcry_pk_init (void)
2279 {
2280   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2281
2282   REGISTER_DEFAULT_PUBKEYS;
2283
2284   return err;
2285 }
2286
2287 gcry_err_code_t
2288 _gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
2289 {
2290   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2291   gcry_module_t pubkey;
2292
2293   REGISTER_DEFAULT_PUBKEYS;
2294
2295   ath_mutex_lock (&pubkeys_registered_lock);
2296   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
2297   if (pubkey)
2298     *module = pubkey;
2299   else
2300     err = GPG_ERR_PUBKEY_ALGO;
2301   ath_mutex_unlock (&pubkeys_registered_lock);
2302
2303   return err;
2304 }
2305
2306 void
2307 _gcry_pk_module_release (gcry_module_t module)
2308 {
2309   ath_mutex_lock (&pubkeys_registered_lock);
2310   _gcry_module_release (module);
2311   ath_mutex_unlock (&pubkeys_registered_lock);
2312 }
2313
2314 /* Get a list consisting of the IDs of the loaded pubkey modules.  If
2315    LIST is zero, write the number of loaded pubkey modules to
2316    LIST_LENGTH and return.  If LIST is non-zero, the first
2317    *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
2318    according size.  In case there are less pubkey modules than
2319    *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
2320 gcry_error_t
2321 gcry_pk_list (int *list, int *list_length)
2322 {
2323   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2324
2325   ath_mutex_lock (&pubkeys_registered_lock);
2326   err = _gcry_module_list (pubkeys_registered, list, list_length);
2327   ath_mutex_unlock (&pubkeys_registered_lock);
2328
2329   return err;
2330 }