Fix memleak when decoding OAEP/PKCS#1 block type 2.
[libgcrypt.git] / cipher / pubkey.c
1 /* pubkey.c  -  pubkey dispatcher
2  * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
3  *               2007, 2008, 2011 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, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26
27 #include "g10lib.h"
28 #include "mpi.h"
29 #include "cipher.h"
30 #include "ath.h"
31
32
33 static gcry_err_code_t pubkey_decrypt (int algo, gcry_mpi_t *result,
34                                        gcry_mpi_t *data, gcry_mpi_t *skey,
35                                        int flags);
36 static gcry_err_code_t pubkey_sign (int algo, gcry_mpi_t *resarr,
37                                     gcry_mpi_t hash, gcry_mpi_t *skey);
38 static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash,
39                                       gcry_mpi_t *data, gcry_mpi_t *pkey,
40                                      int (*cmp) (void *, gcry_mpi_t),
41                                       void *opaque);
42
43
44 /* A dummy extraspec so that we do not need to tests the extraspec
45    field from the module specification against NULL and instead
46    directly test the respective fields of extraspecs.  */
47 static pk_extra_spec_t dummy_extra_spec;
48
49
50 /* This is the list of the default public-key ciphers included in
51    libgcrypt.  FIPS_ALLOWED indicated whether the algorithm is used in
52    FIPS mode. */
53 static struct pubkey_table_entry
54 {
55   gcry_pk_spec_t *pubkey;
56   pk_extra_spec_t *extraspec;
57   unsigned int algorithm;
58   int fips_allowed;
59 } pubkey_table[] =
60   {
61 #if USE_RSA
62     { &_gcry_pubkey_spec_rsa,
63       &_gcry_pubkey_extraspec_rsa,   GCRY_PK_RSA, 1},
64 #endif
65 #if USE_ELGAMAL
66     { &_gcry_pubkey_spec_elg,
67       &_gcry_pubkey_extraspec_elg,    GCRY_PK_ELG   },
68     { &_gcry_pubkey_spec_elg,
69       &_gcry_pubkey_extraspec_elg,    GCRY_PK_ELG_E },
70 #endif
71 #if USE_DSA
72     { &_gcry_pubkey_spec_dsa,
73       &_gcry_pubkey_extraspec_dsa,   GCRY_PK_DSA, 1   },
74 #endif
75 #if USE_ECC
76     { &_gcry_pubkey_spec_ecdsa,
77       &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDSA, 0 },
78     { &_gcry_pubkey_spec_ecdh,
79       &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDH, 0 },
80 #endif
81     { NULL, 0 },
82   };
83
84 /* List of registered ciphers.  */
85 static gcry_module_t pubkeys_registered;
86
87 /* This is the lock protecting PUBKEYS_REGISTERED.  */
88 static ath_mutex_t pubkeys_registered_lock = ATH_MUTEX_INITIALIZER;;
89
90 /* Flag to check whether the default pubkeys have already been
91    registered.  */
92 static int default_pubkeys_registered;
93
94 /* Convenient macro for registering the default digests.  */
95 #define REGISTER_DEFAULT_PUBKEYS                   \
96   do                                               \
97     {                                              \
98       ath_mutex_lock (&pubkeys_registered_lock);   \
99       if (! default_pubkeys_registered)            \
100         {                                          \
101           pk_register_default ();                  \
102           default_pubkeys_registered = 1;          \
103         }                                          \
104       ath_mutex_unlock (&pubkeys_registered_lock); \
105     }                                              \
106   while (0)
107
108 /* These dummy functions are used in case a cipher implementation
109    refuses to provide it's own functions.  */
110
111 static gcry_err_code_t
112 dummy_generate (int algorithm, unsigned int nbits, unsigned long dummy,
113                 gcry_mpi_t *skey, gcry_mpi_t **retfactors)
114 {
115   (void)algorithm;
116   (void)nbits;
117   (void)dummy;
118   (void)skey;
119   (void)retfactors;
120   fips_signal_error ("using dummy public key function");
121   return GPG_ERR_NOT_IMPLEMENTED;
122 }
123
124 static gcry_err_code_t
125 dummy_check_secret_key (int algorithm, gcry_mpi_t *skey)
126 {
127   (void)algorithm;
128   (void)skey;
129   fips_signal_error ("using dummy public key function");
130   return GPG_ERR_NOT_IMPLEMENTED;
131 }
132
133 static gcry_err_code_t
134 dummy_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
135                gcry_mpi_t *pkey, int flags)
136 {
137   (void)algorithm;
138   (void)resarr;
139   (void)data;
140   (void)pkey;
141   (void)flags;
142   fips_signal_error ("using dummy public key function");
143   return GPG_ERR_NOT_IMPLEMENTED;
144 }
145
146 static gcry_err_code_t
147 dummy_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
148                gcry_mpi_t *skey, int flags)
149 {
150   (void)algorithm;
151   (void)result;
152   (void)data;
153   (void)skey;
154   (void)flags;
155   fips_signal_error ("using dummy public key function");
156   return GPG_ERR_NOT_IMPLEMENTED;
157 }
158
159 static gcry_err_code_t
160 dummy_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
161             gcry_mpi_t *skey)
162 {
163   (void)algorithm;
164   (void)resarr;
165   (void)data;
166   (void)skey;
167   fips_signal_error ("using dummy public key function");
168   return GPG_ERR_NOT_IMPLEMENTED;
169 }
170
171 static gcry_err_code_t
172 dummy_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
173               gcry_mpi_t *pkey,
174               int (*cmp) (void *, gcry_mpi_t), void *opaquev)
175 {
176   (void)algorithm;
177   (void)hash;
178   (void)data;
179   (void)pkey;
180   (void)cmp;
181   (void)opaquev;
182   fips_signal_error ("using dummy public key function");
183   return GPG_ERR_NOT_IMPLEMENTED;
184 }
185
186 static unsigned
187 dummy_get_nbits (int algorithm, gcry_mpi_t *pkey)
188 {
189   (void)algorithm;
190   (void)pkey;
191   fips_signal_error ("using dummy public key function");
192   return 0;
193 }
194
195 /* Internal function.  Register all the pubkeys included in
196    PUBKEY_TABLE.  Returns zero on success or an error code.  */
197 static void
198 pk_register_default (void)
199 {
200   gcry_err_code_t err = 0;
201   int i;
202
203   for (i = 0; (! err) && pubkey_table[i].pubkey; i++)
204     {
205 #define pubkey_use_dummy(func)                       \
206       if (! pubkey_table[i].pubkey->func)            \
207         pubkey_table[i].pubkey->func = dummy_##func;
208
209       pubkey_use_dummy (generate);
210       pubkey_use_dummy (check_secret_key);
211       pubkey_use_dummy (encrypt);
212       pubkey_use_dummy (decrypt);
213       pubkey_use_dummy (sign);
214       pubkey_use_dummy (verify);
215       pubkey_use_dummy (get_nbits);
216 #undef pubkey_use_dummy
217
218       err = _gcry_module_add (&pubkeys_registered,
219                               pubkey_table[i].algorithm,
220                               (void *) pubkey_table[i].pubkey,
221                               (void *) pubkey_table[i].extraspec,
222                               NULL);
223     }
224
225   if (err)
226     BUG ();
227 }
228
229 /* Internal callback function.  Used via _gcry_module_lookup.  */
230 static int
231 gcry_pk_lookup_func_name (void *spec, void *data)
232 {
233   gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) spec;
234   char *name = (char *) data;
235   const char **aliases = pubkey->aliases;
236   int ret = stricmp (name, pubkey->name);
237
238   while (ret && *aliases)
239     ret = stricmp (name, *aliases++);
240
241   return ! ret;
242 }
243
244 /* Internal function.  Lookup a pubkey entry by it's name.  */
245 static gcry_module_t
246 gcry_pk_lookup_name (const char *name)
247 {
248   gcry_module_t pubkey;
249
250   pubkey = _gcry_module_lookup (pubkeys_registered, (void *) name,
251                                 gcry_pk_lookup_func_name);
252
253   return pubkey;
254 }
255
256 /* Register a new pubkey module whose specification can be found in
257    PUBKEY.  On success, a new algorithm ID is stored in ALGORITHM_ID
258    and a pointer representhing this module is stored in MODULE.  */
259 gcry_error_t
260 _gcry_pk_register (gcry_pk_spec_t *pubkey,
261                    pk_extra_spec_t *extraspec,
262                    unsigned int *algorithm_id,
263                    gcry_module_t *module)
264 {
265   gcry_err_code_t err = GPG_ERR_NO_ERROR;
266   gcry_module_t mod;
267
268   /* We do not support module loading in fips mode.  */
269   if (fips_mode ())
270     return gpg_error (GPG_ERR_NOT_SUPPORTED);
271
272   ath_mutex_lock (&pubkeys_registered_lock);
273   err = _gcry_module_add (&pubkeys_registered, 0,
274                           (void *) pubkey,
275                           (void *)(extraspec? extraspec : &dummy_extra_spec),
276                           &mod);
277   ath_mutex_unlock (&pubkeys_registered_lock);
278
279   if (! err)
280     {
281       *module = mod;
282       *algorithm_id = mod->mod_id;
283     }
284
285   return err;
286 }
287
288 /* Unregister the pubkey identified by ID, which must have been
289    registered with gcry_pk_register.  */
290 void
291 gcry_pk_unregister (gcry_module_t module)
292 {
293   ath_mutex_lock (&pubkeys_registered_lock);
294   _gcry_module_release (module);
295   ath_mutex_unlock (&pubkeys_registered_lock);
296 }
297
298 static void
299 release_mpi_array (gcry_mpi_t *array)
300 {
301   for (; *array; array++)
302     {
303       mpi_free(*array);
304       *array = NULL;
305     }
306 }
307
308 /****************
309  * Map a string to the pubkey algo
310  */
311 int
312 gcry_pk_map_name (const char *string)
313 {
314   gcry_module_t pubkey;
315   int algorithm = 0;
316
317   if (!string)
318     return 0;
319
320   REGISTER_DEFAULT_PUBKEYS;
321
322   ath_mutex_lock (&pubkeys_registered_lock);
323   pubkey = gcry_pk_lookup_name (string);
324   if (pubkey)
325     {
326       algorithm = pubkey->mod_id;
327       _gcry_module_release (pubkey);
328     }
329   ath_mutex_unlock (&pubkeys_registered_lock);
330
331   return algorithm;
332 }
333
334
335 /* Map the public key algorithm whose ID is contained in ALGORITHM to
336    a string representation of the algorithm name.  For unknown
337    algorithm IDs this functions returns "?". */
338 const char *
339 gcry_pk_algo_name (int algorithm)
340 {
341   gcry_module_t pubkey;
342   const char *name;
343
344   REGISTER_DEFAULT_PUBKEYS;
345
346   ath_mutex_lock (&pubkeys_registered_lock);
347   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
348   if (pubkey)
349     {
350       name = ((gcry_pk_spec_t *) pubkey->spec)->name;
351       _gcry_module_release (pubkey);
352     }
353   else
354     name = "?";
355   ath_mutex_unlock (&pubkeys_registered_lock);
356
357   return name;
358 }
359
360
361 /* A special version of gcry_pk_algo name to return the first aliased
362    name of the algorithm.  This is required to adhere to the spki
363    specs where the algorithm names are lowercase. */
364 const char *
365 _gcry_pk_aliased_algo_name (int algorithm)
366 {
367   const char *name = NULL;
368   gcry_module_t module;
369
370   REGISTER_DEFAULT_PUBKEYS;
371
372   ath_mutex_lock (&pubkeys_registered_lock);
373   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
374   if (module)
375     {
376       gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) module->spec;
377
378       name = pubkey->aliases? *pubkey->aliases : NULL;
379       if (!name || !*name)
380         name = pubkey->name;
381       _gcry_module_release (module);
382     }
383   ath_mutex_unlock (&pubkeys_registered_lock);
384
385   return name;
386 }
387
388
389 static void
390 disable_pubkey_algo (int algorithm)
391 {
392   gcry_module_t pubkey;
393
394   ath_mutex_lock (&pubkeys_registered_lock);
395   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
396   if (pubkey)
397     {
398       if (! (pubkey-> flags & FLAG_MODULE_DISABLED))
399         pubkey->flags |= FLAG_MODULE_DISABLED;
400       _gcry_module_release (pubkey);
401     }
402   ath_mutex_unlock (&pubkeys_registered_lock);
403 }
404
405
406 /****************
407  * A USE of 0 means: don't care.
408  */
409 static gcry_err_code_t
410 check_pubkey_algo (int algorithm, unsigned use)
411 {
412   gcry_err_code_t err = GPG_ERR_NO_ERROR;
413   gcry_pk_spec_t *pubkey;
414   gcry_module_t module;
415
416   REGISTER_DEFAULT_PUBKEYS;
417
418   ath_mutex_lock (&pubkeys_registered_lock);
419   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
420   if (module)
421     {
422       pubkey = (gcry_pk_spec_t *) module->spec;
423
424       if (((use & GCRY_PK_USAGE_SIGN)
425            && (! (pubkey->use & GCRY_PK_USAGE_SIGN)))
426           || ((use & GCRY_PK_USAGE_ENCR)
427               && (! (pubkey->use & GCRY_PK_USAGE_ENCR))))
428         err = GPG_ERR_WRONG_PUBKEY_ALGO;
429       else if (module->flags & FLAG_MODULE_DISABLED)
430         err = GPG_ERR_PUBKEY_ALGO;
431       _gcry_module_release (module);
432     }
433   else
434     err = GPG_ERR_PUBKEY_ALGO;
435   ath_mutex_unlock (&pubkeys_registered_lock);
436
437   return err;
438 }
439
440
441 /****************
442  * Return the number of public key material numbers
443  */
444 static int
445 pubkey_get_npkey (int algorithm)
446 {
447   gcry_module_t pubkey;
448   int npkey = 0;
449
450   REGISTER_DEFAULT_PUBKEYS;
451
452   ath_mutex_lock (&pubkeys_registered_lock);
453   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
454   if (pubkey)
455     {
456       npkey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_pkey);
457       _gcry_module_release (pubkey);
458     }
459   ath_mutex_unlock (&pubkeys_registered_lock);
460
461   return npkey;
462 }
463
464 /****************
465  * Return the number of secret key material numbers
466  */
467 static int
468 pubkey_get_nskey (int algorithm)
469 {
470   gcry_module_t pubkey;
471   int nskey = 0;
472
473   REGISTER_DEFAULT_PUBKEYS;
474
475   ath_mutex_lock (&pubkeys_registered_lock);
476   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
477   if (pubkey)
478     {
479       nskey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_skey);
480       _gcry_module_release (pubkey);
481     }
482   ath_mutex_unlock (&pubkeys_registered_lock);
483
484   return nskey;
485 }
486
487 /****************
488  * Return the number of signature material numbers
489  */
490 static int
491 pubkey_get_nsig (int algorithm)
492 {
493   gcry_module_t pubkey;
494   int nsig = 0;
495
496   REGISTER_DEFAULT_PUBKEYS;
497
498   ath_mutex_lock (&pubkeys_registered_lock);
499   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
500   if (pubkey)
501     {
502       nsig = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_sig);
503       _gcry_module_release (pubkey);
504     }
505   ath_mutex_unlock (&pubkeys_registered_lock);
506
507   return nsig;
508 }
509
510 /****************
511  * Return the number of encryption material numbers
512  */
513 static int
514 pubkey_get_nenc (int algorithm)
515 {
516   gcry_module_t pubkey;
517   int nenc = 0;
518
519   REGISTER_DEFAULT_PUBKEYS;
520
521   ath_mutex_lock (&pubkeys_registered_lock);
522   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
523   if (pubkey)
524     {
525       nenc = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_enc);
526       _gcry_module_release (pubkey);
527     }
528   ath_mutex_unlock (&pubkeys_registered_lock);
529
530   return nenc;
531 }
532
533
534 /* Generate a new public key with algorithm ALGORITHM of size NBITS
535    and return it at SKEY.  USE_E depends on the ALGORITHM.  GENPARMS
536    is passed to the algorithm module if it features an extended
537    generation function.  RETFACTOR is used by some algorithms to
538    return certain additional information which are in general not
539    required.
540
541    The function returns the error code number or 0 on success. */
542 static gcry_err_code_t
543 pubkey_generate (int algorithm,
544                  unsigned int nbits,
545                  unsigned long use_e,
546                  gcry_sexp_t genparms,
547                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
548                  gcry_sexp_t *r_extrainfo)
549 {
550   gcry_err_code_t ec = GPG_ERR_PUBKEY_ALGO;
551   gcry_module_t pubkey;
552
553   REGISTER_DEFAULT_PUBKEYS;
554
555   ath_mutex_lock (&pubkeys_registered_lock);
556   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
557   if (pubkey)
558     {
559       pk_extra_spec_t *extraspec = pubkey->extraspec;
560
561       if (extraspec && extraspec->ext_generate)
562         {
563           /* Use the extended generate function.  */
564           ec = extraspec->ext_generate
565             (algorithm, nbits, use_e, genparms, skey, retfactors, r_extrainfo);
566         }
567       else
568         {
569           /* Use the standard generate function.  */
570           ec = ((gcry_pk_spec_t *) pubkey->spec)->generate
571             (algorithm, nbits, use_e, skey, retfactors);
572         }
573       _gcry_module_release (pubkey);
574     }
575   ath_mutex_unlock (&pubkeys_registered_lock);
576
577   return ec;
578 }
579
580
581 static gcry_err_code_t
582 pubkey_check_secret_key (int algorithm, gcry_mpi_t *skey)
583 {
584   gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
585   gcry_module_t pubkey;
586
587   REGISTER_DEFAULT_PUBKEYS;
588
589   ath_mutex_lock (&pubkeys_registered_lock);
590   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
591   if (pubkey)
592     {
593       err = ((gcry_pk_spec_t *) pubkey->spec)->check_secret_key
594         (algorithm, skey);
595       _gcry_module_release (pubkey);
596     }
597   ath_mutex_unlock (&pubkeys_registered_lock);
598
599   return err;
600 }
601
602
603 /****************
604  * This is the interface to the public key encryption.  Encrypt DATA
605  * with PKEY and put it into RESARR which should be an array of MPIs
606  * of size PUBKEY_MAX_NENC (or less if the algorithm allows this -
607  * check with pubkey_get_nenc() )
608  */
609 static gcry_err_code_t
610 pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
611                 gcry_mpi_t *pkey, int flags)
612 {
613   gcry_pk_spec_t *pubkey;
614   gcry_module_t module;
615   gcry_err_code_t rc;
616   int i;
617
618   /* Note: In fips mode DBG_CIPHER will enver evaluate to true but as
619      an extra failsafe protection we explicitly test for fips mode
620      here. */
621   if (DBG_CIPHER && !fips_mode ())
622     {
623       log_debug ("pubkey_encrypt: algo=%d\n", algorithm);
624       for(i = 0; i < pubkey_get_npkey (algorithm); i++)
625         log_mpidump ("  pkey:", pkey[i]);
626       log_mpidump ("  data:", data);
627     }
628
629   ath_mutex_lock (&pubkeys_registered_lock);
630   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
631   if (module)
632     {
633       pubkey = (gcry_pk_spec_t *) module->spec;
634       rc = pubkey->encrypt (algorithm, resarr, data, pkey, flags);
635       _gcry_module_release (module);
636       goto ready;
637     }
638   rc = GPG_ERR_PUBKEY_ALGO;
639
640  ready:
641   ath_mutex_unlock (&pubkeys_registered_lock);
642
643   if (!rc && DBG_CIPHER && !fips_mode ())
644     {
645       for(i = 0; i < pubkey_get_nenc (algorithm); i++)
646         log_mpidump("  encr:", resarr[i] );
647     }
648   return rc;
649 }
650
651
652 /****************
653  * This is the interface to the public key decryption.
654  * ALGO gives the algorithm to use and this implicitly determines
655  * the size of the arrays.
656  * result is a pointer to a mpi variable which will receive a
657  * newly allocated mpi or NULL in case of an error.
658  */
659 static gcry_err_code_t
660 pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
661                 gcry_mpi_t *skey, int flags)
662 {
663   gcry_pk_spec_t *pubkey;
664   gcry_module_t module;
665   gcry_err_code_t rc;
666   int i;
667
668   *result = NULL; /* so the caller can always do a mpi_free */
669   if (DBG_CIPHER && !fips_mode ())
670     {
671       log_debug ("pubkey_decrypt: algo=%d\n", algorithm);
672       for(i = 0; i < pubkey_get_nskey (algorithm); i++)
673         log_mpidump ("  skey:", skey[i]);
674       for(i = 0; i < pubkey_get_nenc (algorithm); i++)
675         log_mpidump ("  data:", data[i]);
676     }
677
678   ath_mutex_lock (&pubkeys_registered_lock);
679   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
680   if (module)
681     {
682       pubkey = (gcry_pk_spec_t *) module->spec;
683       rc = pubkey->decrypt (algorithm, result, data, skey, flags);
684       _gcry_module_release (module);
685       goto ready;
686     }
687
688   rc = GPG_ERR_PUBKEY_ALGO;
689
690  ready:
691   ath_mutex_unlock (&pubkeys_registered_lock);
692
693   if (!rc && DBG_CIPHER && !fips_mode ())
694     log_mpidump (" plain:", *result);
695
696   return rc;
697 }
698
699
700 /****************
701  * This is the interface to the public key signing.
702  * Sign data with skey and put the result into resarr which
703  * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
704  * algorithm allows this - check with pubkey_get_nsig() )
705  */
706 static gcry_err_code_t
707 pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
708              gcry_mpi_t *skey)
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 && !fips_mode ())
716     {
717       log_debug ("pubkey_sign: algo=%d\n", algorithm);
718       for(i = 0; i < pubkey_get_nskey (algorithm); i++)
719         log_mpidump ("  skey:", skey[i]);
720       log_mpidump("  data:", data );
721     }
722
723   ath_mutex_lock (&pubkeys_registered_lock);
724   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
725   if (module)
726     {
727       pubkey = (gcry_pk_spec_t *) module->spec;
728       rc = pubkey->sign (algorithm, resarr, data, skey);
729       _gcry_module_release (module);
730       goto ready;
731     }
732
733   rc = GPG_ERR_PUBKEY_ALGO;
734
735  ready:
736   ath_mutex_unlock (&pubkeys_registered_lock);
737
738   if (!rc && DBG_CIPHER && !fips_mode ())
739     for (i = 0; i < pubkey_get_nsig (algorithm); i++)
740       log_mpidump ("   sig:", resarr[i]);
741
742   return rc;
743 }
744
745 /****************
746  * Verify a public key signature.
747  * Return 0 if the signature is good
748  */
749 static gcry_err_code_t
750 pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
751                gcry_mpi_t *pkey,
752                int (*cmp)(void *, gcry_mpi_t), void *opaquev)
753 {
754   gcry_pk_spec_t *pubkey;
755   gcry_module_t module;
756   gcry_err_code_t rc;
757   int i;
758
759   if (DBG_CIPHER && !fips_mode ())
760     {
761       log_debug ("pubkey_verify: algo=%d\n", algorithm);
762       for (i = 0; i < pubkey_get_npkey (algorithm); i++)
763         log_mpidump ("  pkey", pkey[i]);
764       for (i = 0; i < pubkey_get_nsig (algorithm); i++)
765         log_mpidump ("   sig", data[i]);
766       log_mpidump ("  hash", hash);
767     }
768
769   ath_mutex_lock (&pubkeys_registered_lock);
770   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
771   if (module)
772     {
773       pubkey = (gcry_pk_spec_t *) module->spec;
774       rc = pubkey->verify (algorithm, hash, data, pkey, cmp, opaquev);
775       _gcry_module_release (module);
776       goto ready;
777     }
778
779   rc = GPG_ERR_PUBKEY_ALGO;
780
781  ready:
782   ath_mutex_unlock (&pubkeys_registered_lock);
783   return rc;
784 }
785
786 static gcry_err_code_t
787 pkcs1_encode_for_encryption (gcry_mpi_t *r_result, unsigned int nbits,
788                              const unsigned char *value, size_t valuelen)
789 {
790   /* Create pkcs#1 block type 2 padding. */
791   gcry_err_code_t rc = 0;
792   gcry_error_t err;
793   unsigned char *frame = NULL;
794   size_t nframe = (nbits+7) / 8;
795   int i;
796   size_t n;
797   unsigned char *p;
798
799   if (valuelen + 7 > nframe || !nframe)
800     /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
801     return GPG_ERR_TOO_SHORT; /* the key is too short */
802   if ( !(frame = gcry_malloc_secure (nframe)))
803     return gpg_err_code_from_syserror ();
804
805   n = 0;
806   frame[n++] = 0;
807   frame[n++] = 2; /* block type */
808   i = nframe - 3 - valuelen;
809   gcry_assert (i > 0);
810   p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
811   /* Replace zero bytes by new values. */
812   for (;;)
813     {
814       int j, k;
815       unsigned char *pp;
816
817       /* Count the zero bytes. */
818       for (j=k=0; j < i; j++)
819         {
820           if (!p[j])
821             k++;
822         }
823       if (!k)
824         break; /* Okay: no (more) zero bytes. */
825
826       k += k/128 + 3; /* Better get some more. */
827       pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
828       for (j=0; j < i && k; )
829         {
830           if (!p[j])
831             p[j] = pp[--k];
832           if (p[j])
833             j++;
834         }
835       gcry_free (pp);
836     }
837   memcpy (frame+n, p, i);
838   n += i;
839   gcry_free (p);
840
841   frame[n++] = 0;
842   memcpy (frame+n, value, valuelen);
843   n += valuelen;
844   gcry_assert (n == nframe);
845
846   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
847   if (err)
848     rc = gcry_err_code (err);
849   else if (DBG_CIPHER)
850     log_mpidump ("PKCS#1 block type 2 encoded data", *r_result);
851   gcry_free (frame);
852
853   return rc;
854 }
855
856 static gcry_err_code_t
857 pkcs1_decode_for_encryption (gcry_mpi_t *r_result, unsigned int nbits,
858                              gcry_mpi_t value)
859 {
860   gcry_err_code_t rc = 0;
861   gcry_error_t err;
862   unsigned char *frame = NULL;
863   size_t nframe = (nbits+7) / 8;
864   size_t n;
865
866   if ( !(frame = gcry_malloc_secure (nframe)))
867     return gpg_err_code_from_syserror ();
868
869   err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
870   if (err)
871     {
872       gcry_free (frame);
873       return gcry_err_code (err);
874     }
875   if (n < nframe)
876     {
877       memmove (frame + (nframe - n), frame, n);
878       memset (frame, 0, (nframe - n));
879     }
880
881   /* FRAME = 0x00 || 0x02 || PS || 0x00 || M */
882   n = 0;
883   if (frame[n++] != 0x00 || frame[n++] != 0x02)
884     {
885       gcry_free (frame);
886       return GPG_ERR_ENCODING_PROBLEM;
887     }
888
889   for (; frame[n] != 0x00 && n < nframe; n++)
890     ;
891   if (n == nframe)
892     {
893       gcry_free (frame);
894       return GPG_ERR_ENCODING_PROBLEM;
895     }
896
897   n++;
898   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, &frame[n], nframe - n, NULL);
899   if (err)
900     rc = gcry_err_code (err);
901   else if (DBG_CIPHER)
902     log_mpidump ("value extracted from PKCS#1 block type 2 encoded data",
903                  *r_result);
904   gcry_free (frame);
905
906   return rc;
907 }
908
909 static gcry_err_code_t
910 pkcs1_encode_for_signature (gcry_mpi_t *r_result, unsigned int nbits,
911                             const unsigned char *value, size_t valuelen,
912                             int algo)
913 {
914   /* Create pkcs#1 block type 1 padding. */
915   gcry_err_code_t rc = 0;
916   gcry_error_t err;
917   byte asn[100];
918   byte *frame = NULL;
919   size_t nframe = (nbits+7) / 8;
920   int i;
921   size_t n;
922   size_t asnlen, dlen;
923
924   asnlen = DIM(asn);
925   dlen = gcry_md_get_algo_dlen (algo);
926
927   if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
928     /* We don't have yet all of the above algorithms.  */
929     return GPG_ERR_NOT_IMPLEMENTED;
930
931   if ( valuelen != dlen )
932     /* Hash value does not match the length of digest for
933        the given algorithm. */
934     return GPG_ERR_CONFLICT;
935
936   if( !dlen || dlen + asnlen + 4 > nframe)
937     /* Can't encode an DLEN byte digest MD into a NFRAME
938        byte frame. */
939     return GPG_ERR_TOO_SHORT;
940
941   if ( !(frame = gcry_malloc (nframe)) )
942     return gpg_err_code_from_syserror ();
943
944   /* Assemble the pkcs#1 block type 1. */
945   n = 0;
946   frame[n++] = 0;
947   frame[n++] = 1; /* block type */
948   i = nframe - valuelen - asnlen - 3 ;
949   gcry_assert (i > 1);
950   memset (frame+n, 0xff, i );
951   n += i;
952   frame[n++] = 0;
953   memcpy (frame+n, asn, asnlen);
954   n += asnlen;
955   memcpy (frame+n, value, valuelen );
956   n += valuelen;
957   gcry_assert (n == nframe);
958
959   /* Convert it into an MPI. */
960   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
961   if (err)
962     rc = gcry_err_code (err);
963   else if (DBG_CIPHER)
964     log_mpidump ("PKCS#1 block type 1 encoded data", *r_result);
965   gcry_free (frame);
966
967   return rc;
968 }
969
970 static gcry_err_code_t
971 mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen,
972       int algo)
973 {
974   size_t dlen;
975   int idx;
976   gcry_md_hd_t hd;
977   gcry_error_t err;
978   unsigned char *p;
979
980   err = gcry_md_test_algo (algo);
981   if (err)
982     return gpg_err_code (err);
983
984   memset (output, 0, outlen);
985   dlen = gcry_md_get_algo_dlen (algo);
986   for (idx = 0, p = output; idx < (outlen + dlen - 1) / dlen; idx++, p += dlen)
987     {
988       unsigned char c[4], *digest;
989
990       c[0] = (idx >> 24) & 0xFF;
991       c[1] = (idx >> 16) & 0xFF;
992       c[2] = (idx >> 8) & 0xFF;
993       c[3] = idx & 0xFF;
994
995       err = gcry_md_open (&hd, algo, 0);
996       if (err)
997         return gpg_err_code (err);
998
999       gcry_md_write (hd, seed, seedlen);
1000       gcry_md_write (hd, c, 4);
1001       digest = gcry_md_read (hd, 0);
1002       if (outlen - (p - output) >= dlen)
1003         memcpy (p, digest, dlen);
1004       else
1005         memcpy (p, digest, outlen - (p - output));
1006       gcry_md_close (hd);
1007     }
1008   return GPG_ERR_NO_ERROR;
1009 }
1010
1011 static gcry_err_code_t
1012 oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
1013              const unsigned char *value, size_t valuelen,
1014              const unsigned char *label, size_t labellen)
1015 {
1016   gcry_err_code_t rc = 0;
1017   gcry_error_t err;
1018   unsigned char *frame = NULL;
1019   size_t nframe = (nbits+7) / 8;
1020   unsigned char *dmask, *smask, *p;
1021   size_t dlen;
1022   gcry_md_hd_t hd;
1023   size_t n;
1024
1025   dlen = gcry_md_get_algo_dlen (algo);
1026   if (valuelen > nframe - 2 * dlen - 1 || !nframe)
1027     /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
1028     return GPG_ERR_TOO_SHORT; /* the key is too short */
1029   if ( !(frame = gcry_malloc_secure (nframe)))
1030     return gpg_err_code_from_syserror ();
1031
1032   /* FRAME = 00 || SEED || DB */
1033   memset (frame, 0, nframe);
1034   n = 0;
1035   frame[n++] = 0;
1036   gcry_randomize (&frame[n], dlen, GCRY_STRONG_RANDOM);
1037
1038   n += dlen;
1039   gcry_md_open (&hd, algo, 0);
1040   gcry_md_write (hd, label, labellen);
1041   memcpy (&frame[n], gcry_md_read (hd, 0), dlen);
1042   gcry_md_close (hd);
1043   n = nframe - valuelen - 1;
1044   frame[n++] = 1;
1045   memcpy (&frame[n], value, valuelen);
1046
1047   if ( !(dmask = gcry_malloc_secure (nframe - dlen - 1)))
1048     {
1049       rc = gpg_err_code_from_syserror ();
1050       gcry_free (frame);
1051       return rc;
1052     }
1053   mgf1 (dmask, nframe - dlen - 1, &frame[1], dlen, algo);
1054   for (n = 1 + dlen, p = dmask; n < nframe; n++)
1055     frame[n] ^= *p++;
1056   gcry_free (dmask);
1057   n += valuelen;
1058
1059   if ( !(smask = gcry_malloc_secure (dlen)))
1060     {
1061       rc = gpg_err_code_from_syserror ();
1062       gcry_free (frame);
1063       return rc;
1064     }
1065   mgf1 (smask, dlen, &frame[1 + dlen], nframe - dlen - 1, algo);
1066   for (n = 1, p = smask; n < 1 + dlen; n++)
1067     frame[n] ^= *p++;
1068   gcry_free (smask);
1069   n = nframe;
1070
1071   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
1072   if (err)
1073     rc = gcry_err_code (err);
1074   else if (DBG_CIPHER)
1075     log_mpidump ("OAEP encoded data", *r_result);
1076   gcry_free (frame);
1077
1078   return rc;
1079 }
1080
1081 static gcry_err_code_t
1082 oaep_decode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
1083              gcry_mpi_t value, const unsigned char *label, size_t labellen)
1084 {
1085   gcry_err_code_t rc = 0;
1086   gcry_error_t err;
1087   unsigned char *frame = NULL, *dmask, *smask, *p;
1088   size_t nframe = (nbits+7) / 8;
1089   size_t dlen;
1090   gcry_md_hd_t hd;
1091   size_t n;
1092
1093   if ( !(frame = gcry_malloc_secure (nframe)))
1094     return gpg_err_code_from_syserror ();
1095
1096   err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
1097   if (err)
1098     {
1099       gcry_free (frame);
1100       return gcry_err_code (err);
1101     }
1102   if (n < nframe)
1103     {
1104       memmove (frame + (nframe - n), frame, n);
1105       memset (frame, 0, (nframe - n));
1106     }
1107
1108   /* FRAME = 00 || MASKED_SEED || MASKED_DB */
1109   if (frame[0])
1110     {
1111       gcry_free (frame);
1112       return GPG_ERR_ENCODING_PROBLEM;
1113     }
1114
1115   dlen = gcry_md_get_algo_dlen (algo);
1116   if (nframe < 1 + 2 * dlen + 1)
1117     {
1118       gcry_free (frame);
1119       return GPG_ERR_TOO_SHORT;
1120     }
1121   if ( !(smask = gcry_malloc_secure (dlen)))
1122     {
1123       rc = gpg_err_code_from_syserror ();
1124       gcry_free (frame);
1125       return rc;
1126     }
1127   mgf1 (smask, dlen, &frame[1 + dlen], nframe - dlen - 1, algo);
1128   for (n = 1, p = smask; n < 1 + dlen; n++)
1129     frame[n] ^= *p++;
1130   gcry_free (smask);
1131
1132   if ( !(dmask = gcry_malloc_secure (nframe - dlen - 1)))
1133     {
1134       rc = gpg_err_code_from_syserror ();
1135       gcry_free (frame);
1136       return rc;
1137     }
1138   mgf1 (dmask, nframe - dlen - 1, &frame[1], dlen, algo);
1139   for (n = 1 + dlen, p = dmask; n < nframe; n++)
1140     frame[n] ^= *p++;
1141   gcry_free (dmask);
1142
1143   gcry_md_open (&hd, algo, 0);
1144   gcry_md_write (hd, label, labellen);
1145   memcpy (&frame[1], gcry_md_read (hd, 0), dlen);
1146   gcry_md_close (hd);
1147
1148   if (memcmp (&frame[1], &frame[1 + dlen], dlen))
1149     {
1150       gcry_free (frame);
1151       return GPG_ERR_ENCODING_PROBLEM;
1152     }
1153
1154   for (n = 1 + dlen * 2; n < nframe && !frame[n]; n++)
1155     ;
1156   if (n < nframe && frame[n] != 1)
1157     {
1158       gcry_free (frame);
1159       return GPG_ERR_ENCODING_PROBLEM;
1160     }
1161
1162   n++;
1163   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, &frame[n], nframe - n, NULL);
1164   if (err)
1165     rc = gcry_err_code (err);
1166   else if (DBG_CIPHER)
1167     log_mpidump ("value extracted from OAEP encoded data", *r_result);
1168   gcry_free (frame);
1169
1170   return rc;
1171 }
1172
1173 /* Internal function.   */
1174 static gcry_err_code_t
1175 sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
1176                        gcry_mpi_t *elements, const char *algo_name)
1177 {
1178   gcry_err_code_t err = 0;
1179   int i, idx;
1180   const char *name;
1181   gcry_sexp_t list;
1182
1183   for (name = element_names, idx = 0; *name && !err; name++, idx++)
1184     {
1185       list = gcry_sexp_find_token (key_sexp, name, 1);
1186       if (!list)
1187         elements[idx] = NULL;
1188       else
1189         {
1190           elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
1191           gcry_sexp_release (list);
1192           if (!elements[idx])
1193             err = GPG_ERR_INV_OBJ;
1194         }
1195     }
1196
1197   if (!err)
1198     {
1199       /* Check that all elements are available.  */
1200       for (name = element_names, idx = 0; *name; name++, idx++)
1201         if (!elements[idx])
1202           break;
1203       if (*name)
1204         {
1205           err = GPG_ERR_NO_OBJ;
1206           /* Some are missing.  Before bailing out we test for
1207              optional parameters.  */
1208           if (algo_name && !strcmp (algo_name, "RSA")
1209               && !strcmp (element_names, "nedpqu") )
1210             {
1211               /* This is RSA.  Test whether we got N, E and D and that
1212                  the optional P, Q and U are all missing.  */
1213               if (elements[0] && elements[1] && elements[2]
1214                   && !elements[3] && !elements[4] && !elements[5])
1215                 err = 0;
1216             }
1217         }
1218     }
1219
1220
1221   if (err)
1222     {
1223       for (i = 0; i < idx; i++)
1224         if (elements[i])
1225           gcry_free (elements[i]);
1226     }
1227   return err;
1228 }
1229
1230
1231 /* Internal function used for ecc.  Note, that this function makes use
1232    of its intimate knowledge about the ECC parameters from ecc.c. */
1233 static gcry_err_code_t
1234 sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
1235                            gcry_mpi_t *elements, pk_extra_spec_t *extraspec)
1236
1237 {
1238   gcry_err_code_t err = 0;
1239   int idx;
1240   const char *name;
1241   gcry_sexp_t list;
1242
1243   /* Clear the array for easier error cleanup. */
1244   for (name = element_names, idx = 0; *name; name++, idx++)
1245     elements[idx] = NULL;
1246   gcry_assert (idx >= 5); /* We know that ECC has at least 5 elements
1247                              (params only) or 6 (full public key).  */
1248   if (idx == 5)
1249     elements[5] = NULL;   /* Extra clear for the params only case.  */
1250
1251
1252   /* Init the array with the available curve parameters. */
1253   for (name = element_names, idx = 0; *name && !err; name++, idx++)
1254     {
1255       list = gcry_sexp_find_token (key_sexp, name, 1);
1256       if (!list)
1257         elements[idx] = NULL;
1258       else
1259         {
1260           elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
1261           gcry_sexp_release (list);
1262           if (!elements[idx])
1263             {
1264               err = GPG_ERR_INV_OBJ;
1265               goto leave;
1266             }
1267         }
1268     }
1269
1270   /* Check whether a curve parameter has been given and then fill any
1271      missing elements.  */
1272   list = gcry_sexp_find_token (key_sexp, "curve", 5);
1273   if (list)
1274     {
1275       if (extraspec->get_param)
1276         {
1277           char *curve;
1278           gcry_mpi_t params[6];
1279
1280           for (idx = 0; idx < DIM(params); idx++)
1281             params[idx] = NULL;
1282
1283           curve = _gcry_sexp_nth_string (list, 1);
1284           gcry_sexp_release (list);
1285           if (!curve)
1286             {
1287               /* No curve name given (or out of core). */
1288               err = GPG_ERR_INV_OBJ;
1289               goto leave;
1290             }
1291           err = extraspec->get_param (curve, params);
1292           gcry_free (curve);
1293           if (err)
1294             goto leave;
1295
1296           for (idx = 0; idx < DIM(params); idx++)
1297             {
1298               if (!elements[idx])
1299                 elements[idx] = params[idx];
1300               else
1301                 mpi_free (params[idx]);
1302             }
1303         }
1304       else
1305         {
1306           gcry_sexp_release (list);
1307           err = GPG_ERR_INV_OBJ; /* "curve" given but ECC not supported. */
1308           goto leave;
1309         }
1310     }
1311
1312   /* Check that all parameters are known.  */
1313   for (name = element_names, idx = 0; *name; name++, idx++)
1314     if (!elements[idx])
1315       {
1316         err = GPG_ERR_NO_OBJ;
1317         goto leave;
1318       }
1319
1320  leave:
1321   if (err)
1322     {
1323       for (name = element_names, idx = 0; *name; name++, idx++)
1324         if (elements[idx])
1325           gcry_free (elements[idx]);
1326     }
1327   return err;
1328 }
1329
1330
1331
1332 /****************
1333  * Convert a S-Exp with either a private or a public key to our
1334  * internal format. Currently we do only support the following
1335  * algorithms:
1336  *    dsa
1337  *    rsa
1338  *    openpgp-dsa
1339  *    openpgp-rsa
1340  *    openpgp-elg
1341  *    openpgp-elg-sig
1342  *    ecdsa
1343  *    ecdh
1344  * Provide a SE with the first element be either "private-key" or
1345  * or "public-key". It is followed by a list with its first element
1346  * be one of the above algorithm identifiers and the remaning
1347  * elements are pairs with parameter-id and value.
1348  * NOTE: we look through the list to find a list beginning with
1349  * "private-key" or "public-key" - the first one found is used.
1350  *
1351  * If OVERRIDE_ELEMS is not NULL those elems override the parameter
1352  * specification taken from the module.  This ise used by
1353  * gcry_pk_get_curve.
1354  *
1355  * Returns: A pointer to an allocated array of MPIs if the return value is
1356  *          zero; the caller has to release this array.
1357  *
1358  * Example of a DSA public key:
1359  *  (private-key
1360  *    (dsa
1361  *      (p <mpi>)
1362  *      (g <mpi>)
1363  *      (y <mpi>)
1364  *      (x <mpi>)
1365  *    )
1366  *  )
1367  * The <mpi> are expected to be in GCRYMPI_FMT_USG
1368  */
1369 static gcry_err_code_t
1370 sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems,
1371              gcry_mpi_t **retarray, gcry_module_t *retalgo)
1372 {
1373   gcry_err_code_t err = 0;
1374   gcry_sexp_t list, l2;
1375   char *name;
1376   const char *elems;
1377   gcry_mpi_t *array;
1378   gcry_module_t module;
1379   gcry_pk_spec_t *pubkey;
1380   pk_extra_spec_t *extraspec;
1381   int is_ecc;
1382
1383   /* Check that the first element is valid.  */
1384   list = gcry_sexp_find_token (sexp,
1385                                want_private? "private-key":"public-key", 0);
1386   if (!list)
1387     return GPG_ERR_INV_OBJ; /* Does not contain a key object.  */
1388
1389   l2 = gcry_sexp_cadr( list );
1390   gcry_sexp_release ( list );
1391   list = l2;
1392   name = _gcry_sexp_nth_string (list, 0);
1393   if (!name)
1394     {
1395       gcry_sexp_release ( list );
1396       return GPG_ERR_INV_OBJ;      /* Invalid structure of object. */
1397     }
1398
1399   ath_mutex_lock (&pubkeys_registered_lock);
1400   module = gcry_pk_lookup_name (name);
1401   ath_mutex_unlock (&pubkeys_registered_lock);
1402
1403   /* Fixme: We should make sure that an ECC key is always named "ecc"
1404      and not "ecdsa".  "ecdsa" should be used for the signature
1405      itself.  We need a function to test whether an algorithm given
1406      with a key is compatible with an application of the key (signing,
1407      encryption).  For RSA this is easy, but ECC is the first
1408      algorithm which has many flavours.  */
1409   is_ecc = ( !strcmp (name, "ecdsa")
1410              || !strcmp (name, "ecdh")
1411              || !strcmp (name, "ecc") );
1412   gcry_free (name);
1413
1414   if (!module)
1415     {
1416       gcry_sexp_release (list);
1417       return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
1418     }
1419   else
1420     {
1421       pubkey = (gcry_pk_spec_t *) module->spec;
1422       extraspec = module->extraspec;
1423     }
1424
1425   if (override_elems)
1426     elems = override_elems;
1427   else if (want_private)
1428     elems = pubkey->elements_skey;
1429   else
1430     elems = pubkey->elements_pkey;
1431   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
1432   if (!array)
1433     err = gpg_err_code_from_syserror ();
1434   if (!err)
1435     {
1436       if (is_ecc)
1437         err = sexp_elements_extract_ecc (list, elems, array, extraspec);
1438       else
1439         err = sexp_elements_extract (list, elems, array, pubkey->name);
1440     }
1441
1442   gcry_sexp_release (list);
1443
1444   if (err)
1445     {
1446       gcry_free (array);
1447
1448       ath_mutex_lock (&pubkeys_registered_lock);
1449       _gcry_module_release (module);
1450       ath_mutex_unlock (&pubkeys_registered_lock);
1451     }
1452   else
1453     {
1454       *retarray = array;
1455       *retalgo = module;
1456     }
1457
1458   return err;
1459 }
1460
1461
1462 static gcry_err_code_t
1463 sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
1464              gcry_module_t *retalgo)
1465 {
1466   gcry_err_code_t err = 0;
1467   gcry_sexp_t list, l2;
1468   char *name;
1469   const char *elems;
1470   gcry_mpi_t *array;
1471   gcry_module_t module;
1472   gcry_pk_spec_t *pubkey;
1473
1474   /* Check that the first element is valid.  */
1475   list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
1476   if (!list)
1477     return GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
1478
1479   l2 = gcry_sexp_nth (list, 1);
1480   if (!l2)
1481     {
1482       gcry_sexp_release (list);
1483       return GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
1484     }
1485   name = _gcry_sexp_nth_string (l2, 0);
1486   if (!name)
1487     {
1488       gcry_sexp_release (list);
1489       gcry_sexp_release (l2);
1490       return GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
1491     }
1492   else if (!strcmp (name, "flags"))
1493     {
1494       /* Skip flags, since they are not used but here just for the
1495          sake of consistent S-expressions.  */
1496       gcry_free (name);
1497       gcry_sexp_release (l2);
1498       l2 = gcry_sexp_nth (list, 2);
1499       if (!l2)
1500         {
1501           gcry_sexp_release (list);
1502           return GPG_ERR_INV_OBJ;
1503         }
1504       name = _gcry_sexp_nth_string (l2, 0);
1505     }
1506
1507   ath_mutex_lock (&pubkeys_registered_lock);
1508   module = gcry_pk_lookup_name (name);
1509   ath_mutex_unlock (&pubkeys_registered_lock);
1510   gcry_free (name);
1511   name = NULL;
1512
1513   if (!module)
1514     {
1515       gcry_sexp_release (l2);
1516       gcry_sexp_release (list);
1517       return GPG_ERR_PUBKEY_ALGO;  /* Unknown algorithm. */
1518     }
1519   else
1520     pubkey = (gcry_pk_spec_t *) module->spec;
1521
1522   elems = pubkey->elements_sig;
1523   array = gcry_calloc (strlen (elems) + 1 , sizeof *array );
1524   if (!array)
1525     err = gpg_err_code_from_syserror ();
1526
1527   if (!err)
1528     err = sexp_elements_extract (list, elems, array, NULL);
1529
1530   gcry_sexp_release (l2);
1531   gcry_sexp_release (list);
1532
1533   if (err)
1534     {
1535       ath_mutex_lock (&pubkeys_registered_lock);
1536       _gcry_module_release (module);
1537       ath_mutex_unlock (&pubkeys_registered_lock);
1538
1539       gcry_free (array);
1540     }
1541   else
1542     {
1543       *retarray = array;
1544       *retalgo = module;
1545     }
1546
1547   return err;
1548 }
1549
1550 static inline int
1551 get_hash_algo (const char *s, size_t n)
1552 {
1553   static const struct { const char *name; int algo; } hashnames[] = {
1554     { "sha1",   GCRY_MD_SHA1 },
1555     { "md5",    GCRY_MD_MD5 },
1556     { "sha256", GCRY_MD_SHA256 },
1557     { "ripemd160", GCRY_MD_RMD160 },
1558     { "rmd160", GCRY_MD_RMD160 },
1559     { "sha384", GCRY_MD_SHA384 },
1560     { "sha512", GCRY_MD_SHA512 },
1561     { "sha224", GCRY_MD_SHA224 },
1562     { "md2",    GCRY_MD_MD2 },
1563     { "md4",    GCRY_MD_MD4 },
1564     { "tiger",  GCRY_MD_TIGER },
1565     { "haval",  GCRY_MD_HAVAL },
1566     { NULL, 0 }
1567   };
1568   int algo;
1569   int i;
1570
1571   for (i=0; hashnames[i].name; i++)
1572     {
1573       if ( strlen (hashnames[i].name) == n
1574            && !memcmp (hashnames[i].name, s, n))
1575         break;
1576     }
1577   if (hashnames[i].name)
1578     algo = hashnames[i].algo;
1579   else
1580     {
1581       /* In case of not listed or dynamically allocated hash
1582          algorithm we fall back to this somewhat slower
1583          method.  Further, it also allows to use OIDs as
1584          algorithm names. */
1585       char *tmpname;
1586
1587       tmpname = gcry_malloc (n+1);
1588       if (!tmpname)
1589         algo = 0;  /* Out of core - silently give up.  */
1590       else
1591         {
1592           memcpy (tmpname, s, n);
1593           tmpname[n] = 0;
1594           algo = gcry_md_map_name (tmpname);
1595           gcry_free (tmpname);
1596         }
1597     }
1598   return algo;
1599 }
1600
1601
1602 /****************
1603  * Take sexp and return an array of MPI as used for our internal decrypt
1604  * function.
1605  * s_data = (enc-val
1606  *           [(flags [raw, pkcs1, oaep, no-blinding])]
1607  *           [(hash-algo <algo>)]
1608  *           [(label <label>)]
1609  *            (<algo>
1610  *              (<param_name1> <mpi>)
1611  *              ...
1612  *              (<param_namen> <mpi>)
1613  *            ))
1614  * HASH-ALGO and LABEL are specific to OAEP.
1615  * RET_MODERN is set to true when at least an empty flags list has been found.
1616  * CTX is used to return encoding information; it may be NULL in which
1617  * case raw encoding is used.
1618  */
1619 static gcry_err_code_t
1620 sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
1621              int *ret_modern, int *flags, struct pk_encoding_ctx *ctx)
1622 {
1623   gcry_err_code_t err = 0;
1624   gcry_sexp_t list = NULL, l2 = NULL;
1625   gcry_pk_spec_t *pubkey = NULL;
1626   gcry_module_t module = NULL;
1627   char *name = NULL;
1628   size_t n;
1629   int parsed_flags = 0;
1630   const char *elems;
1631   gcry_mpi_t *array = NULL;
1632   struct pk_encoding_ctx dummy_ctx;
1633
1634   *ret_modern = 0;
1635
1636   if (!ctx)
1637     ctx = &dummy_ctx;
1638   ctx->encoding = PUBKEY_ENC_RAW;
1639   ctx->hash_algo = GCRY_MD_SHA1;
1640   ctx->label = NULL;
1641   ctx->labellen = 0;
1642
1643   /* Check that the first element is valid.  */
1644   list = gcry_sexp_find_token (sexp, "enc-val" , 0);
1645   if (!list)
1646     {
1647       err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
1648       goto leave;
1649     }
1650
1651   l2 = gcry_sexp_nth (list, 1);
1652   if (!l2)
1653     {
1654       err = GPG_ERR_NO_OBJ; /* No cdr for the data object.  */
1655       goto leave;
1656     }
1657
1658   /* Extract identifier of sublist.  */
1659   name = _gcry_sexp_nth_string (l2, 0);
1660   if (!name)
1661     {
1662       err = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
1663       goto leave;
1664     }
1665
1666   if (!strcmp (name, "flags"))
1667     {
1668       /* There is a flags element - process it.  */
1669       const char *s;
1670       int i;
1671
1672       *ret_modern = 1;
1673       for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
1674         {
1675           s = gcry_sexp_nth_data (l2, i, &n);
1676           if (! s)
1677             ; /* Not a data element - ignore.  */
1678           else if (n == 3 && !memcmp (s, "raw", 3)
1679                    && ctx->encoding == PUBKEY_ENC_RAW)
1680             ; /* This is just a dummy as it is the default.  */
1681           else if (n == 5 && !memcmp (s, "pkcs1", 5)
1682                    && ctx->encoding == PUBKEY_ENC_RAW)
1683             ctx->encoding = PUBKEY_ENC_PKCS1;
1684           else if (n == 4 && !memcmp (s, "oaep", 4)
1685                    && ctx->encoding == PUBKEY_ENC_RAW)
1686             ctx->encoding = PUBKEY_ENC_OAEP;
1687           else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1688             parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1689           else
1690             {
1691               err = GPG_ERR_INV_FLAG;
1692               goto leave;
1693             }
1694         }
1695       gcry_sexp_release (l2);
1696
1697       /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
1698       if (ctx->encoding == PUBKEY_ENC_OAEP)
1699         {
1700           /* Get HASH-ALGO. */
1701           l2 = gcry_sexp_find_token (list, "hash-algo", 0);
1702           if (l2)
1703             {
1704               s = gcry_sexp_nth_data (l2, 1, &n);
1705               if (!s)
1706                 err = GPG_ERR_NO_OBJ;
1707               else
1708                 {
1709                   ctx->hash_algo = get_hash_algo (s, n);
1710                   if (!ctx->hash_algo)
1711                     err = GPG_ERR_DIGEST_ALGO;
1712                 }
1713               gcry_sexp_release (l2);
1714               if (err)
1715                 goto leave;
1716             }
1717
1718           /* Get LABEL. */
1719           l2 = gcry_sexp_find_token (list, "label", 0);
1720           if (l2)
1721             {
1722               s = gcry_sexp_nth_data (l2, 1, &n);
1723               if (!s)
1724                 err = GPG_ERR_NO_OBJ;
1725               else if (n > 0)
1726                 {
1727                   ctx->label = gcry_malloc (n);
1728                   if (!ctx->label)
1729                     err = gpg_err_code_from_syserror ();
1730                   else
1731                     {
1732                       memcpy (ctx->label, s, n);
1733                       ctx->labellen = n;
1734                     }
1735                 }
1736               gcry_sexp_release (l2);
1737               if (err)
1738                 goto leave;
1739             }
1740         }
1741
1742       /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
1743       for (i = 2; (l2 = gcry_sexp_nth (list, i)) != NULL; i++)
1744         {
1745           s = gcry_sexp_nth_data (l2, 0, &n);
1746           if (!(n == 9 && !memcmp (s, "hash-algo", 9))
1747               && !(n == 5 && !memcmp (s, "label", 5)))
1748             break;
1749           gcry_sexp_release (l2);
1750         }
1751
1752       if (!l2)
1753         {
1754           err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
1755           goto leave;
1756         }
1757
1758       /* Extract sublist identifier.  */
1759       gcry_free (name);
1760       name = _gcry_sexp_nth_string (l2, 0);
1761       if (!name)
1762         {
1763           err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
1764           goto leave;
1765         }
1766
1767       gcry_sexp_release (list);
1768       list = l2;
1769       l2 = NULL;
1770     }
1771
1772   ath_mutex_lock (&pubkeys_registered_lock);
1773   module = gcry_pk_lookup_name (name);
1774   ath_mutex_unlock (&pubkeys_registered_lock);
1775
1776   if (!module)
1777     {
1778       err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
1779       goto leave;
1780     }
1781   pubkey = (gcry_pk_spec_t *) module->spec;
1782
1783   elems = pubkey->elements_enc;
1784   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
1785   if (!array)
1786     {
1787       err = gpg_err_code_from_syserror ();
1788       goto leave;
1789     }
1790
1791   err = sexp_elements_extract (list, elems, array, NULL);
1792
1793  leave:
1794   gcry_sexp_release (list);
1795   gcry_sexp_release (l2);
1796   gcry_free (name);
1797
1798   if (err)
1799     {
1800       ath_mutex_lock (&pubkeys_registered_lock);
1801       _gcry_module_release (module);
1802       ath_mutex_unlock (&pubkeys_registered_lock);
1803       gcry_free (array);
1804       gcry_free (ctx->label);
1805       ctx->label = NULL;
1806     }
1807   else
1808     {
1809       *retarray = array;
1810       *retalgo = module;
1811       *flags = parsed_flags;
1812     }
1813
1814   return err;
1815 }
1816
1817 /* Take the hash value and convert into an MPI, suitable for
1818    passing to the low level functions.  We currently support the
1819    old style way of passing just a MPI and the modern interface which
1820    allows to pass flags so that we can choose between raw and pkcs1
1821    padding - may be more padding options later.
1822
1823    (<mpi>)
1824    or
1825    (data
1826     [(flags [raw, pkcs1, oaep, no-blinding])]
1827     [(hash <algo> <value>)]
1828     [(value <text>)]
1829     [(hash-algo <algo>)]
1830     [(label <label>)]
1831    )
1832
1833    Either the VALUE or the HASH element must be present for use
1834    with signatures.  VALUE is used for encryption.
1835
1836    HASH-ALGO and LABEL are specific to OAEP.
1837
1838    NBITS is the length of the key in bits.
1839
1840 */
1841 static gcry_err_code_t
1842 sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
1843                   int for_encryption, int *flags, struct pk_encoding_ctx *ctx)
1844 {
1845   gcry_err_code_t rc = 0;
1846   gcry_sexp_t ldata, lhash, lvalue;
1847   int i;
1848   size_t n;
1849   const char *s;
1850   int unknown_flag=0;
1851   int parsed_flags = 0, dummy_flags;
1852   struct pk_encoding_ctx dummy_ctx;
1853
1854   if (! flags)
1855     flags = &dummy_flags;
1856
1857   if (! ctx)
1858     ctx = &dummy_ctx;
1859
1860   ctx->encoding = PUBKEY_ENC_UNKNOWN;
1861   ctx->hash_algo = GCRY_MD_SHA1;
1862   ctx->label = NULL;
1863   ctx->labellen = 0;
1864
1865   *ret_mpi = NULL;
1866   ldata = gcry_sexp_find_token (input, "data", 0);
1867   if (!ldata)
1868     { /* assume old style */
1869       *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
1870       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
1871     }
1872
1873   /* see whether there is a flags object */
1874   {
1875     gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
1876     if (lflags)
1877       { /* parse the flags list. */
1878         for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
1879           {
1880             s = gcry_sexp_nth_data (lflags, i, &n);
1881             if (!s)
1882               ; /* not a data element*/
1883             else if ( n == 3 && !memcmp (s, "raw", 3)
1884                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1885               ctx->encoding = PUBKEY_ENC_RAW;
1886             else if ( n == 5 && !memcmp (s, "pkcs1", 5)
1887                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1888               ctx->encoding = PUBKEY_ENC_PKCS1;
1889             else if ( n == 4 && !memcmp (s, "oaep", 4)
1890                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1891               ctx->encoding = PUBKEY_ENC_OAEP;
1892             else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1893               parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1894             else
1895               unknown_flag = 1;
1896           }
1897         gcry_sexp_release (lflags);
1898       }
1899   }
1900
1901   if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
1902     ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
1903
1904   /* Get HASH or MPI */
1905   lhash = gcry_sexp_find_token (ldata, "hash", 0);
1906   lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
1907
1908   if (!(!lhash ^ !lvalue))
1909     rc = GPG_ERR_INV_OBJ; /* none or both given */
1910   else if (unknown_flag)
1911     rc = GPG_ERR_INV_FLAG;
1912   else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
1913     {
1914       *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
1915       if (!*ret_mpi)
1916         rc = GPG_ERR_INV_OBJ;
1917     }
1918   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue && for_encryption)
1919     {
1920       const void * value;
1921       size_t valuelen;
1922
1923       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1924         rc = GPG_ERR_INV_OBJ;
1925       else
1926         rc = pkcs1_encode_for_encryption (ret_mpi, nbits, value, valuelen);
1927     }
1928   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash && !for_encryption)
1929     {
1930       if (gcry_sexp_length (lhash) != 3)
1931         rc = GPG_ERR_INV_OBJ;
1932       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1933         rc = GPG_ERR_INV_OBJ;
1934       else
1935         {
1936           int algo;
1937           const void * value;
1938           size_t valuelen;
1939
1940           algo = get_hash_algo (s, n);
1941
1942           if (!algo)
1943             rc = GPG_ERR_DIGEST_ALGO;
1944           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
1945                     || !valuelen )
1946             rc = GPG_ERR_INV_OBJ;
1947           else
1948             rc = pkcs1_encode_for_signature (ret_mpi, nbits, value, valuelen,
1949                                              algo);
1950         }
1951     }
1952   else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue && for_encryption)
1953     {
1954       const void * value;
1955       size_t valuelen;
1956
1957       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1958         rc = GPG_ERR_INV_OBJ;
1959       else
1960         {
1961           gcry_sexp_t list;
1962
1963           /* Get HASH-ALGO. */
1964           list = gcry_sexp_find_token (ldata, "hash-algo", 0);
1965           if (list)
1966             {
1967               s = gcry_sexp_nth_data (list, 1, &n);
1968               if (!s)
1969                 rc = GPG_ERR_NO_OBJ;
1970               else
1971                 {
1972                   ctx->hash_algo = get_hash_algo (s, n);
1973                   if (!ctx->hash_algo)
1974                     rc = GPG_ERR_DIGEST_ALGO;
1975                 }
1976               gcry_sexp_release (list);
1977               if (rc)
1978                 goto leave;
1979             }
1980
1981           /* Get LABEL. */
1982           list = gcry_sexp_find_token (ldata, "label", 0);
1983           if (list)
1984             {
1985               s = gcry_sexp_nth_data (list, 1, &n);
1986               if (!s)
1987                 rc = GPG_ERR_NO_OBJ;
1988               else if (n > 0)
1989                 {
1990                   ctx->label = gcry_malloc (n);
1991                   if (!ctx->label)
1992                     rc = gpg_err_code_from_syserror ();
1993                   else
1994                     {
1995                       memcpy (ctx->label, s, n);
1996                       ctx->labellen = n;
1997                     }
1998                 }
1999               gcry_sexp_release (list);
2000               if (rc)
2001                 goto leave;
2002             }
2003
2004           rc = oaep_encode (ret_mpi, nbits, ctx->hash_algo, value, valuelen,
2005                             ctx->label, ctx->labellen);
2006         }
2007     }
2008   else
2009     rc = GPG_ERR_CONFLICT;
2010
2011  leave:
2012   gcry_sexp_release (ldata);
2013   gcry_sexp_release (lhash);
2014   gcry_sexp_release (lvalue);
2015
2016   if (!rc)
2017     *flags = parsed_flags;
2018   else
2019     {
2020       gcry_free (ctx->label);
2021       ctx->label = NULL;
2022     }
2023
2024   return rc;
2025 }
2026
2027
2028 /*
2029    Do a PK encrypt operation
2030
2031    Caller has to provide a public key as the SEXP pkey and data as a
2032    SEXP with just one MPI in it. Alternatively S_DATA might be a
2033    complex S-Expression, similar to the one used for signature
2034    verification.  This provides a flag which allows to handle PKCS#1
2035    block type 2 padding.  The function returns a a sexp which may be
2036    passed to to pk_decrypt.
2037
2038    Returns: 0 or an errorcode.
2039
2040    s_data = See comment for sexp_data_to_mpi
2041    s_pkey = <key-as-defined-in-sexp_to_key>
2042    r_ciph = (enc-val
2043                (<algo>
2044                  (<param_name1> <mpi>)
2045                  ...
2046                  (<param_namen> <mpi>)
2047                ))
2048
2049 */
2050 gcry_error_t
2051 gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
2052 {
2053   gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
2054   const char *algo_name, *algo_elems;
2055   int flags;
2056   struct pk_encoding_ctx ctx;
2057   gcry_err_code_t rc;
2058   gcry_pk_spec_t *pubkey = NULL;
2059   gcry_module_t module = NULL;
2060
2061   *r_ciph = NULL;
2062
2063   REGISTER_DEFAULT_PUBKEYS;
2064
2065   memset (&ctx, 0, sizeof(struct pk_encoding_ctx));
2066   /* Get the key. */
2067   rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module);
2068   if (rc)
2069     goto leave;
2070
2071   gcry_assert (module);
2072   pubkey = (gcry_pk_spec_t *) module->spec;
2073
2074   /* If aliases for the algorithm name exists, take the first one
2075      instead of the regular name to adhere to SPKI conventions.  We
2076      assume that the first alias name is the lowercase version of the
2077      regular one.  This change is required for compatibility with
2078      1.1.12 generated S-expressions. */
2079   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2080   if (!algo_name || !*algo_name)
2081     algo_name = pubkey->name;
2082
2083   algo_elems = pubkey->elements_enc;
2084
2085   /* Get the stuff we want to encrypt. */
2086   rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
2087                          &flags, &ctx);
2088   if (rc)
2089     goto leave;
2090
2091   /* Now we can encrypt DATA to CIPH. */
2092   ciph = gcry_calloc (strlen (algo_elems) + 1, sizeof (*ciph));
2093   if (!ciph)
2094     {
2095       rc = gpg_err_code_from_syserror ();
2096       goto leave;
2097     }
2098   rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
2099   mpi_free (data);
2100   data = NULL;
2101   if (rc)
2102     goto leave;
2103
2104   /* We did it.  Now build the return list */
2105   {
2106     char *string, *p;
2107     int i;
2108     size_t nelem = strlen (algo_elems);
2109     size_t needed = 19 + strlen (algo_name) + (nelem * 5);
2110     void **arg_list;
2111
2112     /* Build the string.  */
2113     string = p = gcry_malloc (needed);
2114     if (!string)
2115       {
2116         rc = gpg_err_code_from_syserror ();
2117         goto leave;
2118       }
2119     p = stpcpy ( p, "(enc-val(" );
2120     p = stpcpy ( p, algo_name );
2121     for (i=0; algo_elems[i]; i++ )
2122       {
2123         *p++ = '(';
2124         *p++ = algo_elems[i];
2125         p = stpcpy ( p, "%m)" );
2126       }
2127     strcpy ( p, "))" );
2128
2129     /* And now the ugly part: We don't have a function to pass an
2130      * array to a format string, so we have to do it this way :-(.  */
2131     /* FIXME: There is now such a format specifier, so we can
2132        change the code to be more clear. */
2133     arg_list = malloc (nelem * sizeof *arg_list);
2134     if (!arg_list)
2135       {
2136         rc = gpg_err_code_from_syserror ();
2137         goto leave;
2138       }
2139
2140     for (i = 0; i < nelem; i++)
2141       arg_list[i] = ciph + i;
2142
2143     rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
2144     free (arg_list);
2145     if (rc)
2146       BUG ();
2147     gcry_free (string);
2148   }
2149
2150  leave:
2151   if (pkey)
2152     {
2153       release_mpi_array (pkey);
2154       gcry_free (pkey);
2155     }
2156
2157   if (ciph)
2158     {
2159       release_mpi_array (ciph);
2160       gcry_free (ciph);
2161     }
2162
2163   if (module)
2164     {
2165       ath_mutex_lock (&pubkeys_registered_lock);
2166       _gcry_module_release (module);
2167       ath_mutex_unlock (&pubkeys_registered_lock);
2168     }
2169
2170   gcry_free (ctx.label);
2171
2172   return gcry_error (rc);
2173 }
2174
2175 /*
2176    Do a PK decrypt operation
2177
2178    Caller has to provide a secret key as the SEXP skey and data in a
2179    format as created by gcry_pk_encrypt.  For historic reasons the
2180    function returns simply an MPI as an S-expression part; this is
2181    deprecated and the new method should be used which returns a real
2182    S-expressionl this is selected by adding at least an empty flags
2183    list to S_DATA.
2184
2185    Returns: 0 or an errorcode.
2186
2187    s_data = (enc-val
2188               [(flags [raw, pkcs1, oaep])]
2189               (<algo>
2190                 (<param_name1> <mpi>)
2191                 ...
2192                 (<param_namen> <mpi>)
2193               ))
2194    s_skey = <key-as-defined-in-sexp_to_key>
2195    r_plain= Either an incomplete S-expression without the parentheses
2196             or if the flags list is used (even if empty) a real S-expression:
2197             (value PLAIN).
2198  */
2199 gcry_error_t
2200 gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
2201 {
2202   gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL, unpad = NULL;
2203   int modern, flags;
2204   struct pk_encoding_ctx ctx;
2205   gcry_err_code_t rc;
2206   gcry_module_t module_enc = NULL, module_key = NULL;
2207
2208   *r_plain = NULL;
2209   ctx.label = NULL;
2210
2211   REGISTER_DEFAULT_PUBKEYS;
2212
2213   rc = sexp_to_key (s_skey, 1, NULL, &skey, &module_key);
2214   if (rc)
2215     goto leave;
2216
2217   rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &flags, &ctx);
2218   if (rc)
2219     goto leave;
2220
2221   if (module_key->mod_id != module_enc->mod_id)
2222     {
2223       rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
2224       goto leave;
2225     }
2226
2227   rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
2228   if (rc)
2229     goto leave;
2230
2231   /* Do un-padding if necessary. */
2232   switch (ctx.encoding)
2233     {
2234     case PUBKEY_ENC_PKCS1:
2235       rc = pkcs1_decode_for_encryption (&unpad, gcry_pk_get_nbits (s_skey),
2236                                         plain);
2237       mpi_free (plain);
2238       if (rc)
2239         goto leave;
2240       plain = unpad;
2241       break;
2242     case PUBKEY_ENC_OAEP:
2243       rc = oaep_decode (&unpad, gcry_pk_get_nbits (s_skey), ctx.hash_algo,
2244                         plain, ctx.label, ctx.labellen);
2245       mpi_free (plain);
2246       if (rc)
2247         goto leave;
2248       plain = unpad;
2249       break;
2250     default:
2251       break;
2252     }
2253
2254   if (gcry_sexp_build (r_plain, NULL, modern? "(value %m)" : "%m", plain))
2255     BUG ();
2256
2257  leave:
2258   if (skey)
2259     {
2260       release_mpi_array (skey);
2261       gcry_free (skey);
2262     }
2263
2264   if (plain)
2265     mpi_free (plain);
2266
2267   if (data)
2268     {
2269       release_mpi_array (data);
2270       gcry_free (data);
2271     }
2272
2273   if (module_key || module_enc)
2274     {
2275       ath_mutex_lock (&pubkeys_registered_lock);
2276       if (module_key)
2277         _gcry_module_release (module_key);
2278       if (module_enc)
2279         _gcry_module_release (module_enc);
2280       ath_mutex_unlock (&pubkeys_registered_lock);
2281     }
2282
2283   gcry_free (ctx.label);
2284
2285   return gcry_error (rc);
2286 }
2287
2288
2289
2290 /*
2291    Create a signature.
2292
2293    Caller has to provide a secret key as the SEXP skey and data
2294    expressed as a SEXP list hash with only one element which should
2295    instantly be available as a MPI. Alternatively the structure given
2296    below may be used for S_HASH, it provides the abiliy to pass flags
2297    to the operation; the only flag defined by now is "pkcs1" which
2298    does PKCS#1 block type 1 style padding.
2299
2300    Returns: 0 or an errorcode.
2301             In case of 0 the function returns a new SEXP with the
2302             signature value; the structure of this signature depends on the
2303             other arguments but is always suitable to be passed to
2304             gcry_pk_verify
2305
2306    s_hash = See comment for sexp_data_to_mpi
2307
2308    s_skey = <key-as-defined-in-sexp_to_key>
2309    r_sig  = (sig-val
2310               (<algo>
2311                 (<param_name1> <mpi>)
2312                 ...
2313                 (<param_namen> <mpi>))
2314              [(hash algo)])
2315
2316   Note that (hash algo) in R_SIG is not used.
2317 */
2318 gcry_error_t
2319 gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
2320 {
2321   gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
2322   gcry_pk_spec_t *pubkey = NULL;
2323   gcry_module_t module = NULL;
2324   const char *algo_name, *algo_elems;
2325   int i;
2326   gcry_err_code_t rc;
2327
2328   *r_sig = NULL;
2329
2330   REGISTER_DEFAULT_PUBKEYS;
2331
2332   rc = sexp_to_key (s_skey, 1, NULL, &skey, &module);
2333   if (rc)
2334     goto leave;
2335
2336   gcry_assert (module);
2337   pubkey = (gcry_pk_spec_t *) module->spec;
2338   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2339   if (!algo_name || !*algo_name)
2340     algo_name = pubkey->name;
2341
2342   algo_elems = pubkey->elements_sig;
2343
2344   /* Get the stuff we want to sign.  Note that pk_get_nbits does also
2345       work on a private key. */
2346   rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey),
2347                              &hash, 0, NULL, NULL);
2348   if (rc)
2349     goto leave;
2350
2351   result = gcry_calloc (strlen (algo_elems) + 1, sizeof (*result));
2352   if (!result)
2353     {
2354       rc = gpg_err_code_from_syserror ();
2355       goto leave;
2356     }
2357   rc = pubkey_sign (module->mod_id, result, hash, skey);
2358   if (rc)
2359     goto leave;
2360
2361   {
2362     char *string, *p;
2363     size_t nelem, needed = strlen (algo_name) + 20;
2364     void **arg_list;
2365
2366     nelem = strlen (algo_elems);
2367
2368     /* Count elements, so that we can allocate enough space. */
2369     needed += 10 * nelem;
2370
2371     /* Build the string. */
2372     string = p = gcry_malloc (needed);
2373     if (!string)
2374       {
2375         rc = gpg_err_code_from_syserror ();
2376         goto leave;
2377       }
2378     p = stpcpy (p, "(sig-val(");
2379     p = stpcpy (p, algo_name);
2380     for (i = 0; algo_elems[i]; i++)
2381       {
2382         *p++ = '(';
2383         *p++ = algo_elems[i];
2384         p = stpcpy (p, "%m)");
2385       }
2386     strcpy (p, "))");
2387
2388     arg_list = malloc (nelem * sizeof *arg_list);
2389     if (!arg_list)
2390       {
2391         rc = gpg_err_code_from_syserror ();
2392         goto leave;
2393       }
2394
2395     for (i = 0; i < nelem; i++)
2396       arg_list[i] = result + i;
2397
2398     rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
2399     free (arg_list);
2400     if (rc)
2401       BUG ();
2402     gcry_free (string);
2403   }
2404
2405  leave:
2406   if (skey)
2407     {
2408       release_mpi_array (skey);
2409       gcry_free (skey);
2410     }
2411
2412   if (hash)
2413     mpi_free (hash);
2414
2415   if (result)
2416     {
2417       release_mpi_array (result);
2418       gcry_free (result);
2419     }
2420
2421   return gcry_error (rc);
2422 }
2423
2424
2425 /*
2426    Verify a signature.
2427
2428    Caller has to supply the public key pkey, the signature sig and his
2429    hashvalue data.  Public key has to be a standard public key given
2430    as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
2431    must be an S-Exp like the one in sign too.  */
2432 gcry_error_t
2433 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
2434 {
2435   gcry_module_t module_key = NULL, module_sig = NULL;
2436   gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
2437   gcry_err_code_t rc;
2438
2439   REGISTER_DEFAULT_PUBKEYS;
2440
2441   rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module_key);
2442   if (rc)
2443     goto leave;
2444
2445   rc = sexp_to_sig (s_sig, &sig, &module_sig);
2446   if (rc)
2447     goto leave;
2448
2449   /* Fixme: Check that the algorithm of S_SIG is compatible to the one
2450      of S_PKEY.  */
2451
2452   if (module_key->mod_id != module_sig->mod_id)
2453     {
2454       rc = GPG_ERR_CONFLICT;
2455       goto leave;
2456     }
2457
2458   rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0, NULL);
2459   if (rc)
2460     goto leave;
2461
2462   rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
2463
2464  leave:
2465   if (pkey)
2466     {
2467       release_mpi_array (pkey);
2468       gcry_free (pkey);
2469     }
2470   if (sig)
2471     {
2472       release_mpi_array (sig);
2473       gcry_free (sig);
2474     }
2475   if (hash)
2476     mpi_free (hash);
2477
2478   if (module_key || module_sig)
2479     {
2480       ath_mutex_lock (&pubkeys_registered_lock);
2481       if (module_key)
2482         _gcry_module_release (module_key);
2483       if (module_sig)
2484         _gcry_module_release (module_sig);
2485       ath_mutex_unlock (&pubkeys_registered_lock);
2486     }
2487
2488   return gcry_error (rc);
2489 }
2490
2491
2492 /*
2493    Test a key.
2494
2495    This may be used either for a public or a secret key to see whether
2496    the internal structure is okay.
2497
2498    Returns: 0 or an errorcode.
2499
2500    s_key = <key-as-defined-in-sexp_to_key> */
2501 gcry_error_t
2502 gcry_pk_testkey (gcry_sexp_t s_key)
2503 {
2504   gcry_module_t module = NULL;
2505   gcry_mpi_t *key = NULL;
2506   gcry_err_code_t rc;
2507
2508   REGISTER_DEFAULT_PUBKEYS;
2509
2510   /* Note we currently support only secret key checking. */
2511   rc = sexp_to_key (s_key, 1, NULL, &key, &module);
2512   if (! rc)
2513     {
2514       rc = pubkey_check_secret_key (module->mod_id, key);
2515       release_mpi_array (key);
2516       gcry_free (key);
2517     }
2518   return gcry_error (rc);
2519 }
2520
2521
2522 /*
2523   Create a public key pair and return it in r_key.
2524   How the key is created depends on s_parms:
2525   (genkey
2526    (algo
2527      (parameter_name_1 ....)
2528       ....
2529      (parameter_name_n ....)
2530   ))
2531   The key is returned in a format depending on the
2532   algorithm. Both, private and secret keys are returned
2533   and optionally some additional informatin.
2534   For elgamal we return this structure:
2535   (key-data
2536    (public-key
2537      (elg
2538         (p <mpi>)
2539         (g <mpi>)
2540         (y <mpi>)
2541      )
2542    )
2543    (private-key
2544      (elg
2545         (p <mpi>)
2546         (g <mpi>)
2547         (y <mpi>)
2548         (x <mpi>)
2549      )
2550    )
2551    (misc-key-info
2552       (pm1-factors n1 n2 ... nn)
2553    ))
2554  */
2555 gcry_error_t
2556 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
2557 {
2558   gcry_pk_spec_t *pubkey = NULL;
2559   gcry_module_t module = NULL;
2560   gcry_sexp_t list = NULL;
2561   gcry_sexp_t l2 = NULL;
2562   gcry_sexp_t l3 = NULL;
2563   char *name = NULL;
2564   size_t n;
2565   gcry_err_code_t rc = GPG_ERR_NO_ERROR;
2566   int i, j;
2567   const char *algo_name = NULL;
2568   int algo;
2569   const char *sec_elems = NULL, *pub_elems = NULL;
2570   gcry_mpi_t skey[12];
2571   gcry_mpi_t *factors = NULL;
2572   gcry_sexp_t extrainfo = NULL;
2573   unsigned int nbits = 0;
2574   unsigned long use_e = 0;
2575
2576   skey[0] = NULL;
2577   *r_key = NULL;
2578
2579   REGISTER_DEFAULT_PUBKEYS;
2580
2581   list = gcry_sexp_find_token (s_parms, "genkey", 0);
2582   if (!list)
2583     {
2584       rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
2585       goto leave;
2586     }
2587
2588   l2 = gcry_sexp_cadr (list);
2589   gcry_sexp_release (list);
2590   list = l2;
2591   l2 = NULL;
2592   if (! list)
2593     {
2594       rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
2595       goto leave;
2596     }
2597
2598   name = _gcry_sexp_nth_string (list, 0);
2599   if (!name)
2600     {
2601       rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
2602       goto leave;
2603     }
2604
2605   ath_mutex_lock (&pubkeys_registered_lock);
2606   module = gcry_pk_lookup_name (name);
2607   ath_mutex_unlock (&pubkeys_registered_lock);
2608   gcry_free (name);
2609   name = NULL;
2610   if (!module)
2611     {
2612       rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
2613       goto leave;
2614     }
2615
2616   pubkey = (gcry_pk_spec_t *) module->spec;
2617   algo = module->mod_id;
2618   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2619   if (!algo_name || !*algo_name)
2620     algo_name = pubkey->name;
2621   pub_elems = pubkey->elements_pkey;
2622   sec_elems = pubkey->elements_skey;
2623   if (strlen (sec_elems) >= DIM(skey))
2624     BUG ();
2625
2626   /* Handle the optional rsa-use-e element.  Actually this belong into
2627      the algorithm module but we have this parameter in the public
2628      module API, so we need to parse it right here.  */
2629   l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
2630   if (l2)
2631     {
2632       char buf[50];
2633       const char *s;
2634
2635       s = gcry_sexp_nth_data (l2, 1, &n);
2636       if ( !s || n >= DIM (buf) - 1 )
2637         {
2638           rc = GPG_ERR_INV_OBJ; /* No value or value too large.  */
2639           goto leave;
2640         }
2641       memcpy (buf, s, n);
2642       buf[n] = 0;
2643       use_e = strtoul (buf, NULL, 0);
2644       gcry_sexp_release (l2);
2645       l2 = NULL;
2646     }
2647   else
2648     use_e = 65537; /* Not given, use the value generated by old versions. */
2649
2650
2651   /* Get the "nbits" parameter.  */
2652   l2 = gcry_sexp_find_token (list, "nbits", 0);
2653   if (l2)
2654     {
2655       char buf[50];
2656       const char *s;
2657
2658       s = gcry_sexp_nth_data (l2, 1, &n);
2659       if (!s || n >= DIM (buf) - 1 )
2660         {
2661           rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr.  */
2662           goto leave;
2663         }
2664       memcpy (buf, s, n);
2665       buf[n] = 0;
2666       nbits = (unsigned int)strtoul (buf, NULL, 0);
2667       gcry_sexp_release (l2); l2 = NULL;
2668     }
2669   else
2670     nbits = 0;
2671
2672   /* Pass control to the algorithm module. */
2673   rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey,
2674                         &factors, &extrainfo);
2675   gcry_sexp_release (list); list = NULL;
2676   if (rc)
2677     goto leave;
2678
2679   /* Key generation succeeded: Build an S-expression.  */
2680   {
2681     char *string, *p;
2682     size_t nelem=0, nelem_cp = 0, needed=0;
2683     gcry_mpi_t mpis[30];
2684     int percent_s_idx = -1;
2685
2686     /* Estimate size of format string.  */
2687     nelem = strlen (pub_elems) + strlen (sec_elems);
2688     if (factors)
2689       {
2690         for (i = 0; factors[i]; i++)
2691           nelem++;
2692       }
2693     nelem_cp = nelem;
2694
2695     needed += nelem * 10;
2696     /* (+5 is for EXTRAINFO ("%S")).  */
2697     needed += 2 * strlen (algo_name) + 300 + 5;
2698     if (nelem > DIM (mpis))
2699       BUG ();
2700
2701     /* Build the string. */
2702     nelem = 0;
2703     string = p = gcry_malloc (needed);
2704     if (!string)
2705       {
2706         rc = gpg_err_code_from_syserror ();
2707         goto leave;
2708       }
2709     p = stpcpy (p, "(key-data");
2710     p = stpcpy (p, "(public-key(");
2711     p = stpcpy (p, algo_name);
2712     for(i = 0; pub_elems[i]; i++)
2713       {
2714         *p++ = '(';
2715         *p++ = pub_elems[i];
2716         p = stpcpy (p, "%m)");
2717         mpis[nelem++] = skey[i];
2718       }
2719     if (extrainfo && (algo == GCRY_PK_ECDSA || algo == GCRY_PK_ECDH))
2720       {
2721         /* Very ugly hack to insert the used curve parameter into the
2722            list of public key parameters.  */
2723         percent_s_idx = nelem;
2724         p = stpcpy (p, "%S");
2725       }
2726     p = stpcpy (p, "))");
2727     p = stpcpy (p, "(private-key(");
2728     p = stpcpy (p, algo_name);
2729     for (i = 0; sec_elems[i]; i++)
2730       {
2731         *p++ = '(';
2732         *p++ = sec_elems[i];
2733         p = stpcpy (p, "%m)");
2734         mpis[nelem++] = skey[i];
2735       }
2736     p = stpcpy (p, "))");
2737
2738     /* Hack to make release_mpi_array() work.  */
2739     skey[i] = NULL;
2740
2741     if (extrainfo && percent_s_idx == -1)
2742       {
2743         /* If we have extrainfo we should not have any factors.  */
2744         p = stpcpy (p, "%S");
2745       }
2746     else if (factors && factors[0])
2747       {
2748         p = stpcpy (p, "(misc-key-info(pm1-factors");
2749         for(i = 0; factors[i]; i++)
2750           {
2751             p = stpcpy (p, "%m");
2752             mpis[nelem++] = factors[i];
2753           }
2754         p = stpcpy (p, "))");
2755       }
2756     strcpy (p, ")");
2757     gcry_assert (p - string < needed);
2758
2759     while (nelem < DIM (mpis))
2760       mpis[nelem++] = NULL;
2761
2762     {
2763       int elem_n = strlen (pub_elems) + strlen (sec_elems);
2764       void **arg_list;
2765
2766       /* Allocate one extra for EXTRAINFO ("%S").  */
2767       arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
2768       if (!arg_list)
2769         {
2770           rc = gpg_err_code_from_syserror ();
2771           goto leave;
2772         }
2773       for (i = j = 0; i < elem_n; i++)
2774         {
2775           if (i == percent_s_idx)
2776             arg_list[j++] = &extrainfo;
2777           arg_list[j++] = mpis + i;
2778         }
2779       if (extrainfo && percent_s_idx == -1)
2780         arg_list[j] = &extrainfo;
2781       else if (factors && factors[0])
2782         {
2783           for (; i < nelem_cp; i++)
2784             arg_list[j++] = factors + i - elem_n;
2785         }
2786       rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
2787       gcry_free (arg_list);
2788       if (rc)
2789         BUG ();
2790       gcry_assert (DIM (mpis) == 30); /* Reminder to make sure that
2791                                          the array gets increased if
2792                                          new parameters are added. */
2793     }
2794     gcry_free (string);
2795   }
2796
2797  leave:
2798   gcry_free (name);
2799   gcry_sexp_release (extrainfo);
2800   release_mpi_array (skey);
2801   /* Don't free SKEY itself, it is an stack allocated array. */
2802
2803   if (factors)
2804     {
2805       release_mpi_array ( factors );
2806       gcry_free (factors);
2807     }
2808
2809   gcry_sexp_release (l3);
2810   gcry_sexp_release (l2);
2811   gcry_sexp_release (list);
2812
2813   if (module)
2814     {
2815       ath_mutex_lock (&pubkeys_registered_lock);
2816       _gcry_module_release (module);
2817       ath_mutex_unlock (&pubkeys_registered_lock);
2818     }
2819
2820   return gcry_error (rc);
2821 }
2822
2823
2824 /*
2825    Get the number of nbits from the public key.
2826
2827    Hmmm: Should we have really this function or is it better to have a
2828    more general function to retrieve different properties of the key?  */
2829 unsigned int
2830 gcry_pk_get_nbits (gcry_sexp_t key)
2831 {
2832   gcry_module_t module = NULL;
2833   gcry_pk_spec_t *pubkey;
2834   gcry_mpi_t *keyarr = NULL;
2835   unsigned int nbits = 0;
2836   gcry_err_code_t rc;
2837
2838   REGISTER_DEFAULT_PUBKEYS;
2839
2840   rc = sexp_to_key (key, 0, NULL, &keyarr, &module);
2841   if (rc == GPG_ERR_INV_OBJ)
2842     rc = sexp_to_key (key, 1, NULL, &keyarr, &module);
2843   if (rc)
2844     return 0; /* Error - 0 is a suitable indication for that. */
2845
2846   pubkey = (gcry_pk_spec_t *) module->spec;
2847   nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
2848
2849   ath_mutex_lock (&pubkeys_registered_lock);
2850   _gcry_module_release (module);
2851   ath_mutex_unlock (&pubkeys_registered_lock);
2852
2853   release_mpi_array (keyarr);
2854   gcry_free (keyarr);
2855
2856   return nbits;
2857 }
2858
2859
2860 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
2861    key parameters expressed in a way depending on the algorithm.
2862
2863    ARRAY must either be 20 bytes long or NULL; in the latter case a
2864    newly allocated array of that size is returned, otherwise ARRAY or
2865    NULL is returned to indicate an error which is most likely an
2866    unknown algorithm.  The function accepts public or secret keys. */
2867 unsigned char *
2868 gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
2869 {
2870   gcry_sexp_t list = NULL, l2 = NULL;
2871   gcry_pk_spec_t *pubkey = NULL;
2872   gcry_module_t module = NULL;
2873   pk_extra_spec_t *extraspec;
2874   const char *s;
2875   char *name = NULL;
2876   int idx;
2877   const char *elems;
2878   gcry_md_hd_t md = NULL;
2879   int okay = 0;
2880
2881   REGISTER_DEFAULT_PUBKEYS;
2882
2883   /* Check that the first element is valid. */
2884   list = gcry_sexp_find_token (key, "public-key", 0);
2885   if (! list)
2886     list = gcry_sexp_find_token (key, "private-key", 0);
2887   if (! list)
2888     list = gcry_sexp_find_token (key, "protected-private-key", 0);
2889   if (! list)
2890     list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
2891   if (! list)
2892     return NULL; /* No public- or private-key object. */
2893
2894   l2 = gcry_sexp_cadr (list);
2895   gcry_sexp_release (list);
2896   list = l2;
2897   l2 = NULL;
2898
2899   name = _gcry_sexp_nth_string (list, 0);
2900   if (!name)
2901     goto fail; /* Invalid structure of object. */
2902
2903   ath_mutex_lock (&pubkeys_registered_lock);
2904   module = gcry_pk_lookup_name (name);
2905   ath_mutex_unlock (&pubkeys_registered_lock);
2906
2907   if (!module)
2908     goto fail; /* Unknown algorithm.  */
2909
2910   pubkey = (gcry_pk_spec_t *) module->spec;
2911   extraspec = module->extraspec;
2912
2913   elems = pubkey->elements_grip;
2914   if (!elems)
2915     goto fail; /* No grip parameter.  */
2916
2917   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
2918     goto fail;
2919
2920   if (extraspec && extraspec->comp_keygrip)
2921     {
2922       /* Module specific method to compute a keygrip.  */
2923       if (extraspec->comp_keygrip (md, list))
2924         goto fail;
2925     }
2926   else
2927     {
2928       /* Generic method to compute a keygrip.  */
2929       for (idx = 0, s = elems; *s; s++, idx++)
2930         {
2931           const char *data;
2932           size_t datalen;
2933           char buf[30];
2934
2935           l2 = gcry_sexp_find_token (list, s, 1);
2936           if (! l2)
2937             goto fail;
2938           data = gcry_sexp_nth_data (l2, 1, &datalen);
2939           if (! data)
2940             goto fail;
2941
2942           snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
2943           gcry_md_write (md, buf, strlen (buf));
2944           gcry_md_write (md, data, datalen);
2945           gcry_sexp_release (l2);
2946           l2 = NULL;
2947           gcry_md_write (md, ")", 1);
2948         }
2949     }
2950
2951   if (!array)
2952     {
2953       array = gcry_malloc (20);
2954       if (! array)
2955         goto fail;
2956     }
2957
2958   memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
2959   okay = 1;
2960
2961  fail:
2962   gcry_free (name);
2963   gcry_sexp_release (l2);
2964   gcry_md_close (md);
2965   gcry_sexp_release (list);
2966   return okay? array : NULL;
2967 }
2968
2969
2970 \f
2971 const char *
2972 gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
2973 {
2974   gcry_mpi_t *pkey = NULL;
2975   gcry_sexp_t list = NULL;
2976   gcry_sexp_t l2;
2977   gcry_module_t module = NULL;
2978   pk_extra_spec_t *extraspec;
2979   char *name = NULL;
2980   const char *result = NULL;
2981   int want_private = 1;
2982
2983   if (r_nbits)
2984     *r_nbits = 0;
2985
2986   REGISTER_DEFAULT_PUBKEYS;
2987
2988   if (key)
2989     {
2990       iterator = 0;
2991
2992       /* Check that the first element is valid. */
2993       list = gcry_sexp_find_token (key, "public-key", 0);
2994       if (list)
2995         want_private = 0;
2996       if (!list)
2997         list = gcry_sexp_find_token (key, "private-key", 0);
2998       if (!list)
2999         return NULL; /* No public- or private-key object. */
3000
3001       l2 = gcry_sexp_cadr (list);
3002       gcry_sexp_release (list);
3003       list = l2;
3004       l2 = NULL;
3005
3006       name = _gcry_sexp_nth_string (list, 0);
3007       if (!name)
3008         goto leave; /* Invalid structure of object. */
3009
3010       /* Get the key.  We pass the names of the parameters for
3011          override_elems; this allows to call this function without the
3012          actual public key parameter.  */
3013       if (sexp_to_key (key, want_private, "pabgn", &pkey, &module))
3014         goto leave;
3015     }
3016   else
3017     {
3018       ath_mutex_lock (&pubkeys_registered_lock);
3019       module = gcry_pk_lookup_name ("ecc");
3020       ath_mutex_unlock (&pubkeys_registered_lock);
3021       if (!module)
3022         goto leave;
3023     }
3024
3025   extraspec = module->extraspec;
3026   if (!extraspec || !extraspec->get_curve)
3027     goto leave;
3028
3029   result = extraspec->get_curve (pkey, iterator, r_nbits);
3030
3031  leave:
3032   if (pkey)
3033     {
3034       release_mpi_array (pkey);
3035       gcry_free (pkey);
3036     }
3037   if (module)
3038     {
3039       ath_mutex_lock (&pubkeys_registered_lock);
3040       _gcry_module_release (module);
3041       ath_mutex_unlock (&pubkeys_registered_lock);
3042     }
3043   gcry_free (name);
3044   gcry_sexp_release (list);
3045   return result;
3046 }
3047
3048
3049 \f
3050 gcry_sexp_t
3051 gcry_pk_get_param (int algo, const char *name)
3052 {
3053   gcry_module_t module = NULL;
3054   pk_extra_spec_t *extraspec;
3055   gcry_sexp_t result = NULL;
3056
3057   if (algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH)
3058     return NULL;
3059
3060   REGISTER_DEFAULT_PUBKEYS;
3061
3062   ath_mutex_lock (&pubkeys_registered_lock);
3063   module = gcry_pk_lookup_name ("ecc");
3064   ath_mutex_unlock (&pubkeys_registered_lock);
3065   if (module)
3066     {
3067       extraspec = module->extraspec;
3068       if (extraspec && extraspec->get_curve_param)
3069         result = extraspec->get_curve_param (name);
3070
3071       ath_mutex_lock (&pubkeys_registered_lock);
3072       _gcry_module_release (module);
3073       ath_mutex_unlock (&pubkeys_registered_lock);
3074     }
3075   return result;
3076 }
3077
3078
3079 \f
3080 gcry_error_t
3081 gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
3082 {
3083   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3084
3085   REGISTER_DEFAULT_PUBKEYS;
3086
3087   switch (cmd)
3088     {
3089     case GCRYCTL_DISABLE_ALGO:
3090       /* This one expects a buffer pointing to an integer with the
3091          algo number.  */
3092       if ((! buffer) || (buflen != sizeof (int)))
3093         err = GPG_ERR_INV_ARG;
3094       else
3095         disable_pubkey_algo (*((int *) buffer));
3096       break;
3097
3098     default:
3099       err = GPG_ERR_INV_OP;
3100     }
3101
3102   return gcry_error (err);
3103 }
3104
3105
3106 /* Return information about the given algorithm
3107
3108    WHAT selects the kind of information returned:
3109
3110     GCRYCTL_TEST_ALGO:
3111         Returns 0 when the specified algorithm is available for use.
3112         Buffer must be NULL, nbytes  may have the address of a variable
3113         with the required usage of the algorithm. It may be 0 for don't
3114         care or a combination of the GCRY_PK_USAGE_xxx flags;
3115
3116     GCRYCTL_GET_ALGO_USAGE:
3117         Return the usage flags for the given algo.  An invalid algo
3118         returns 0.  Disabled algos are ignored here because we
3119         only want to know whether the algo is at all capable of
3120         the usage.
3121
3122    Note: Because this function is in most cases used to return an
3123    integer value, we can make it easier for the caller to just look at
3124    the return value.  The caller will in all cases consult the value
3125    and thereby detecting whether a error occurred or not (i.e. while
3126    checking the block size) */
3127 gcry_error_t
3128 gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
3129 {
3130   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3131
3132   switch (what)
3133     {
3134     case GCRYCTL_TEST_ALGO:
3135       {
3136         int use = nbytes ? *nbytes : 0;
3137         if (buffer)
3138           err = GPG_ERR_INV_ARG;
3139         else if (check_pubkey_algo (algorithm, use))
3140           err = GPG_ERR_PUBKEY_ALGO;
3141         break;
3142       }
3143
3144     case GCRYCTL_GET_ALGO_USAGE:
3145       {
3146         gcry_module_t pubkey;
3147         int use = 0;
3148
3149         REGISTER_DEFAULT_PUBKEYS;
3150
3151         ath_mutex_lock (&pubkeys_registered_lock);
3152         pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
3153         if (pubkey)
3154           {
3155             use = ((gcry_pk_spec_t *) pubkey->spec)->use;
3156             _gcry_module_release (pubkey);
3157           }
3158         ath_mutex_unlock (&pubkeys_registered_lock);
3159
3160         /* FIXME? */
3161         *nbytes = use;
3162
3163         break;
3164       }
3165
3166     case GCRYCTL_GET_ALGO_NPKEY:
3167       {
3168         /* FIXME?  */
3169         int npkey = pubkey_get_npkey (algorithm);
3170         *nbytes = npkey;
3171         break;
3172       }
3173     case GCRYCTL_GET_ALGO_NSKEY:
3174       {
3175         /* FIXME?  */
3176         int nskey = pubkey_get_nskey (algorithm);
3177         *nbytes = nskey;
3178         break;
3179       }
3180     case GCRYCTL_GET_ALGO_NSIGN:
3181       {
3182         /* FIXME?  */
3183         int nsign = pubkey_get_nsig (algorithm);
3184         *nbytes = nsign;
3185         break;
3186       }
3187     case GCRYCTL_GET_ALGO_NENCR:
3188       {
3189         /* FIXME?  */
3190         int nencr = pubkey_get_nenc (algorithm);
3191         *nbytes = nencr;
3192         break;
3193       }
3194
3195     default:
3196       err = GPG_ERR_INV_OP;
3197     }
3198
3199   return gcry_error (err);
3200 }
3201
3202
3203 /* Explicitly initialize this module.  */
3204 gcry_err_code_t
3205 _gcry_pk_init (void)
3206 {
3207   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3208
3209   REGISTER_DEFAULT_PUBKEYS;
3210
3211   return err;
3212 }
3213
3214
3215 gcry_err_code_t
3216 _gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
3217 {
3218   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3219   gcry_module_t pubkey;
3220
3221   REGISTER_DEFAULT_PUBKEYS;
3222
3223   ath_mutex_lock (&pubkeys_registered_lock);
3224   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
3225   if (pubkey)
3226     *module = pubkey;
3227   else
3228     err = GPG_ERR_PUBKEY_ALGO;
3229   ath_mutex_unlock (&pubkeys_registered_lock);
3230
3231   return err;
3232 }
3233
3234
3235 void
3236 _gcry_pk_module_release (gcry_module_t module)
3237 {
3238   ath_mutex_lock (&pubkeys_registered_lock);
3239   _gcry_module_release (module);
3240   ath_mutex_unlock (&pubkeys_registered_lock);
3241 }
3242
3243 /* Get a list consisting of the IDs of the loaded pubkey modules.  If
3244    LIST is zero, write the number of loaded pubkey modules to
3245    LIST_LENGTH and return.  If LIST is non-zero, the first
3246    *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
3247    according size.  In case there are less pubkey modules than
3248    *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
3249 gcry_error_t
3250 gcry_pk_list (int *list, int *list_length)
3251 {
3252   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3253
3254   ath_mutex_lock (&pubkeys_registered_lock);
3255   err = _gcry_module_list (pubkeys_registered, list, list_length);
3256   ath_mutex_unlock (&pubkeys_registered_lock);
3257
3258   return err;
3259 }
3260
3261
3262 /* Run the selftests for pubkey algorithm ALGO with optional reporting
3263    function REPORT.  */
3264 gpg_error_t
3265 _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
3266 {
3267   gcry_module_t module = NULL;
3268   pk_extra_spec_t *extraspec = NULL;
3269   gcry_err_code_t ec = 0;
3270
3271   REGISTER_DEFAULT_PUBKEYS;
3272
3273   ath_mutex_lock (&pubkeys_registered_lock);
3274   module = _gcry_module_lookup_id (pubkeys_registered, algo);
3275   if (module && !(module->flags & FLAG_MODULE_DISABLED))
3276     extraspec = module->extraspec;
3277   ath_mutex_unlock (&pubkeys_registered_lock);
3278   if (extraspec && extraspec->selftest)
3279     ec = extraspec->selftest (algo, extended, report);
3280   else
3281     {
3282       ec = GPG_ERR_PUBKEY_ALGO;
3283       if (report)
3284         report ("pubkey", algo, "module",
3285                 module && !(module->flags & FLAG_MODULE_DISABLED)?
3286                 "no selftest available" :
3287                 module? "algorithm disabled" : "algorithm not found");
3288     }
3289
3290   if (module)
3291     {
3292       ath_mutex_lock (&pubkeys_registered_lock);
3293       _gcry_module_release (module);
3294       ath_mutex_unlock (&pubkeys_registered_lock);
3295     }
3296   return gpg_error (ec);
3297 }
3298
3299
3300 /* This function is only used by ac.c!  */
3301 gcry_err_code_t
3302 _gcry_pk_get_elements (int algo, char **enc, char **sig)
3303 {
3304   gcry_module_t pubkey;
3305   gcry_pk_spec_t *spec;
3306   gcry_err_code_t err;
3307   char *enc_cp;
3308   char *sig_cp;
3309
3310   REGISTER_DEFAULT_PUBKEYS;
3311
3312   enc_cp = NULL;
3313   sig_cp = NULL;
3314   spec = NULL;
3315
3316   pubkey = _gcry_module_lookup_id (pubkeys_registered, algo);
3317   if (! pubkey)
3318     {
3319       err = GPG_ERR_INTERNAL;
3320       goto out;
3321     }
3322   spec = pubkey->spec;
3323
3324   if (enc)
3325     {
3326       enc_cp = strdup (spec->elements_enc);
3327       if (! enc_cp)
3328         {
3329           err = gpg_err_code_from_syserror ();
3330           goto out;
3331         }
3332     }
3333
3334   if (sig)
3335     {
3336       sig_cp = strdup (spec->elements_sig);
3337       if (! sig_cp)
3338         {
3339           err = gpg_err_code_from_syserror ();
3340           goto out;
3341         }
3342     }
3343
3344   if (enc)
3345     *enc = enc_cp;
3346   if (sig)
3347     *sig = sig_cp;
3348   err = 0;
3349
3350  out:
3351
3352   _gcry_module_release (pubkey);
3353   if (err)
3354     {
3355       free (enc_cp);
3356       free (sig_cp);
3357     }
3358
3359   return err;
3360 }