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