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