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