Add a few comments to the pkcs#1 code.
[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
787 /* Encode {VALUE,VALUELEN} for an NBITS keys using the pkcs#1 block
788    type 2 padding.  On sucess the result is stored as a new MPI at
789    R_RESULT.  On error the value at R_RESULT is undefined.  */
790 static gcry_err_code_t
791 pkcs1_encode_for_encryption (gcry_mpi_t *r_result, unsigned int nbits,
792                              const unsigned char *value, size_t valuelen)
793 {
794   gcry_err_code_t rc = 0;
795   gcry_error_t err;
796   unsigned char *frame = NULL;
797   size_t nframe = (nbits+7) / 8;
798   int i;
799   size_t n;
800   unsigned char *p;
801
802   if (valuelen + 7 > nframe || !nframe)
803     {
804       /* Can't encode a VALUELEN value in a NFRAME bytes frame.  */
805       return GPG_ERR_TOO_SHORT; /* The key is too short.  */
806     }
807
808   if ( !(frame = gcry_malloc_secure (nframe)))
809     return gpg_err_code_from_syserror ();
810
811   n = 0;
812   frame[n++] = 0;
813   frame[n++] = 2; /* block type */
814   i = nframe - 3 - valuelen;
815   gcry_assert (i > 0);
816   p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
817   /* Replace zero bytes by new values. */
818   for (;;)
819     {
820       int j, k;
821       unsigned char *pp;
822
823       /* Count the zero bytes. */
824       for (j=k=0; j < i; j++)
825         {
826           if (!p[j])
827             k++;
828         }
829       if (!k)
830         break; /* Okay: no (more) zero bytes. */
831
832       k += k/128 + 3; /* Better get some more. */
833       pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
834       for (j=0; j < i && k; )
835         {
836           if (!p[j])
837             p[j] = pp[--k];
838           if (p[j])
839             j++;
840         }
841       gcry_free (pp);
842     }
843   memcpy (frame+n, p, i);
844   n += i;
845   gcry_free (p);
846
847   frame[n++] = 0;
848   memcpy (frame+n, value, valuelen);
849   n += valuelen;
850   gcry_assert (n == nframe);
851
852   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
853   if (err)
854     rc = gcry_err_code (err);
855   else if (DBG_CIPHER)
856     log_mpidump ("PKCS#1 block type 2 encoded data", *r_result);
857   gcry_free (frame);
858
859   return rc;
860 }
861
862
863 /* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding.
864    NBITS is the size of the secret key.  On sucess the result is
865    stored as a new MPI at R_RESULT.  On error the value at R_RESULT is
866    undefined.  */
867 static gcry_err_code_t
868 pkcs1_decode_for_encryption (gcry_mpi_t *r_result, unsigned int nbits,
869                              gcry_mpi_t value)
870 {
871   gcry_err_code_t rc = 0;
872   gcry_error_t err;
873   unsigned char *frame = NULL;
874   size_t nframe = (nbits+7) / 8;
875   size_t n;
876
877   if ( !(frame = gcry_malloc_secure (nframe)))
878     return gpg_err_code_from_syserror ();
879
880   err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
881   if (err)
882     {
883       gcry_free (frame);
884       return gcry_err_code (err);
885     }
886
887   if (n < nframe)
888     {
889       memmove (frame + (nframe - n), frame, n);
890       memset (frame, 0, (nframe - n));
891     }
892
893   /* FRAME = 0x00 || 0x02 || PS || 0x00 || M */
894   n = 0;
895   if (frame[n++] != 0x00 || frame[n++] != 0x02)
896     {
897       gcry_free (frame);
898       return GPG_ERR_ENCODING_PROBLEM;
899     }
900
901   for (; frame[n] != 0x00 && n < nframe; n++)
902     ;
903   if (n == nframe)
904     {
905       gcry_free (frame);
906       return GPG_ERR_ENCODING_PROBLEM;
907     }
908
909   n++;
910   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, &frame[n], nframe - n, NULL);
911   if (err)
912     rc = gcry_err_code (err);
913   else if (DBG_CIPHER)
914     log_mpidump ("value extracted from PKCS#1 block type 2 encoded data",
915                  *r_result);
916   gcry_free (frame);
917
918   return rc;
919 }
920
921
922 /* Encode {VALUE,VALUELEN} for an NBITS keys and hash algorith ALGO
923    using the pkcs#1 block type 1 padding.  On sucess the result is
924    stored as a new MPI at R_RESULT.  On error the value at R_RESULT is
925    undefined.  */
926 static gcry_err_code_t
927 pkcs1_encode_for_signature (gcry_mpi_t *r_result, unsigned int nbits,
928                             const unsigned char *value, size_t valuelen,
929                             int algo)
930 {
931   gcry_err_code_t rc = 0;
932   gcry_error_t err;
933   byte asn[100];
934   byte *frame = NULL;
935   size_t nframe = (nbits+7) / 8;
936   int i;
937   size_t n;
938   size_t asnlen, dlen;
939
940   asnlen = DIM(asn);
941   dlen = gcry_md_get_algo_dlen (algo);
942
943   if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
944     {
945       /* We don't have yet all of the above algorithms.  */
946       return GPG_ERR_NOT_IMPLEMENTED;
947     }
948
949   if ( valuelen != dlen )
950     {
951       /* Hash value does not match the length of digest for
952          the given algorithm.  */
953       return GPG_ERR_CONFLICT;
954     }
955
956   if ( !dlen || dlen + asnlen + 4 > nframe)
957     {
958       /* Can't encode an DLEN byte digest MD into an NFRAME byte
959          frame.  */
960       return GPG_ERR_TOO_SHORT;
961     }
962
963   if ( !(frame = gcry_malloc (nframe)) )
964     return gpg_err_code_from_syserror ();
965
966   /* Assemble the pkcs#1 block type 1. */
967   n = 0;
968   frame[n++] = 0;
969   frame[n++] = 1; /* block type */
970   i = nframe - valuelen - asnlen - 3 ;
971   gcry_assert (i > 1);
972   memset (frame+n, 0xff, i );
973   n += i;
974   frame[n++] = 0;
975   memcpy (frame+n, asn, asnlen);
976   n += asnlen;
977   memcpy (frame+n, value, valuelen );
978   n += valuelen;
979   gcry_assert (n == nframe);
980
981   /* Convert it into an MPI. */
982   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
983   if (err)
984     rc = gcry_err_code (err);
985   else if (DBG_CIPHER)
986     log_mpidump ("PKCS#1 block type 1 encoded data", *r_result);
987   gcry_free (frame);
988
989   return rc;
990 }
991
992
993 static gcry_err_code_t
994 mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen,
995       int algo)
996 {
997   size_t dlen;
998   int idx;
999   gcry_md_hd_t hd;
1000   gcry_error_t err;
1001   unsigned char *p;
1002
1003   err = gcry_md_test_algo (algo);
1004   if (err)
1005     return gpg_err_code (err);
1006
1007   memset (output, 0, outlen);
1008   dlen = gcry_md_get_algo_dlen (algo);
1009   for (idx = 0, p = output; idx < (outlen + dlen - 1) / dlen; idx++, p += dlen)
1010     {
1011       unsigned char c[4], *digest;
1012
1013       c[0] = (idx >> 24) & 0xFF;
1014       c[1] = (idx >> 16) & 0xFF;
1015       c[2] = (idx >> 8) & 0xFF;
1016       c[3] = idx & 0xFF;
1017
1018       err = gcry_md_open (&hd, algo, 0);
1019       if (err)
1020         return gpg_err_code (err);
1021
1022       gcry_md_write (hd, seed, seedlen);
1023       gcry_md_write (hd, c, 4);
1024       digest = gcry_md_read (hd, 0);
1025       if (outlen - (p - output) >= dlen)
1026         memcpy (p, digest, dlen);
1027       else
1028         memcpy (p, digest, outlen - (p - output));
1029       gcry_md_close (hd);
1030     }
1031   return GPG_ERR_NO_ERROR;
1032 }
1033
1034 static gcry_err_code_t
1035 oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
1036              const unsigned char *value, size_t valuelen,
1037              const unsigned char *label, size_t labellen)
1038 {
1039   gcry_err_code_t rc = 0;
1040   gcry_error_t err;
1041   unsigned char *frame = NULL;
1042   size_t nframe = (nbits+7) / 8;
1043   unsigned char *dmask, *smask, *p;
1044   size_t dlen;
1045   gcry_md_hd_t hd;
1046   size_t n;
1047
1048   dlen = gcry_md_get_algo_dlen (algo);
1049   if (valuelen > nframe - 2 * dlen - 1 || !nframe)
1050     /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
1051     return GPG_ERR_TOO_SHORT; /* the key is too short */
1052   if ( !(frame = gcry_malloc_secure (nframe)))
1053     return gpg_err_code_from_syserror ();
1054
1055   /* FRAME = 00 || SEED || DB */
1056   memset (frame, 0, nframe);
1057   n = 0;
1058   frame[n++] = 0;
1059   gcry_randomize (&frame[n], dlen, GCRY_STRONG_RANDOM);
1060
1061   n += dlen;
1062   gcry_md_open (&hd, algo, 0);
1063   gcry_md_write (hd, label, labellen);
1064   memcpy (&frame[n], gcry_md_read (hd, 0), dlen);
1065   gcry_md_close (hd);
1066   n = nframe - valuelen - 1;
1067   frame[n++] = 1;
1068   memcpy (&frame[n], value, valuelen);
1069
1070   if ( !(dmask = gcry_malloc_secure (nframe - dlen - 1)))
1071     {
1072       rc = gpg_err_code_from_syserror ();
1073       gcry_free (frame);
1074       return rc;
1075     }
1076   mgf1 (dmask, nframe - dlen - 1, &frame[1], dlen, algo);
1077   for (n = 1 + dlen, p = dmask; n < nframe; n++)
1078     frame[n] ^= *p++;
1079   gcry_free (dmask);
1080   n += valuelen;
1081
1082   if ( !(smask = gcry_malloc_secure (dlen)))
1083     {
1084       rc = gpg_err_code_from_syserror ();
1085       gcry_free (frame);
1086       return rc;
1087     }
1088   mgf1 (smask, dlen, &frame[1 + dlen], nframe - dlen - 1, algo);
1089   for (n = 1, p = smask; n < 1 + dlen; n++)
1090     frame[n] ^= *p++;
1091   gcry_free (smask);
1092   n = nframe;
1093
1094   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
1095   if (err)
1096     rc = gcry_err_code (err);
1097   else if (DBG_CIPHER)
1098     log_mpidump ("OAEP encoded data", *r_result);
1099   gcry_free (frame);
1100
1101   return rc;
1102 }
1103
1104 static gcry_err_code_t
1105 oaep_decode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
1106              gcry_mpi_t value, const unsigned char *label, size_t labellen)
1107 {
1108   gcry_err_code_t rc = 0;
1109   gcry_error_t err;
1110   unsigned char *frame = NULL, *dmask, *smask, *p;
1111   size_t nframe = (nbits+7) / 8;
1112   size_t dlen;
1113   gcry_md_hd_t hd;
1114   size_t n;
1115
1116   if ( !(frame = gcry_malloc_secure (nframe)))
1117     return gpg_err_code_from_syserror ();
1118
1119   err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
1120   if (err)
1121     return gcry_err_code (err);
1122   if (n < nframe)
1123     {
1124       memmove (frame + (nframe - n), frame, n);
1125       memset (frame, 0, (nframe - n));
1126     }
1127
1128   /* FRAME = 00 || MASKED_SEED || MASKED_DB */
1129   if (frame[0])
1130     {
1131       gcry_free (frame);
1132       return GPG_ERR_ENCODING_PROBLEM;
1133     }
1134
1135   dlen = gcry_md_get_algo_dlen (algo);
1136   if (nframe < 1 + 2 * dlen + 1)
1137     {
1138       gcry_free (frame);
1139       return GPG_ERR_TOO_SHORT;
1140     }
1141   if ( !(smask = gcry_malloc_secure (dlen)))
1142     {
1143       rc = gpg_err_code_from_syserror ();
1144       gcry_free (frame);
1145       return rc;
1146     }
1147   mgf1 (smask, dlen, &frame[1 + dlen], nframe - dlen - 1, algo);
1148   for (n = 1, p = smask; n < 1 + dlen; n++)
1149     frame[n] ^= *p++;
1150   gcry_free (smask);
1151
1152   if ( !(dmask = gcry_malloc_secure (nframe - dlen - 1)))
1153     {
1154       rc = gpg_err_code_from_syserror ();
1155       gcry_free (frame);
1156       return rc;
1157     }
1158   mgf1 (dmask, nframe - dlen - 1, &frame[1], dlen, algo);
1159   for (n = 1 + dlen, p = dmask; n < nframe; n++)
1160     frame[n] ^= *p++;
1161   gcry_free (dmask);
1162
1163   gcry_md_open (&hd, algo, 0);
1164   gcry_md_write (hd, label, labellen);
1165   memcpy (&frame[1], gcry_md_read (hd, 0), dlen);
1166   gcry_md_close (hd);
1167
1168   if (memcmp (&frame[1], &frame[1 + dlen], dlen))
1169     {
1170       gcry_free (frame);
1171       return GPG_ERR_ENCODING_PROBLEM;
1172     }
1173
1174   for (n = 1 + dlen * 2; n < nframe && !frame[n]; n++)
1175     ;
1176   if (n < nframe && frame[n] != 1)
1177     {
1178       gcry_free (frame);
1179       return GPG_ERR_ENCODING_PROBLEM;
1180     }
1181
1182   n++;
1183   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, &frame[n], nframe - n, NULL);
1184   if (err)
1185     rc = gcry_err_code (err);
1186   else if (DBG_CIPHER)
1187     log_mpidump ("value extracted from OAEP encoded data", *r_result);
1188   gcry_free (frame);
1189
1190   return rc;
1191 }
1192
1193 /* Internal function.   */
1194 static gcry_err_code_t
1195 sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
1196                        gcry_mpi_t *elements, const char *algo_name)
1197 {
1198   gcry_err_code_t err = 0;
1199   int i, idx;
1200   const char *name;
1201   gcry_sexp_t list;
1202
1203   for (name = element_names, idx = 0; *name && !err; name++, idx++)
1204     {
1205       list = gcry_sexp_find_token (key_sexp, name, 1);
1206       if (!list)
1207         elements[idx] = NULL;
1208       else
1209         {
1210           elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
1211           gcry_sexp_release (list);
1212           if (!elements[idx])
1213             err = GPG_ERR_INV_OBJ;
1214         }
1215     }
1216
1217   if (!err)
1218     {
1219       /* Check that all elements are available.  */
1220       for (name = element_names, idx = 0; *name; name++, idx++)
1221         if (!elements[idx])
1222           break;
1223       if (*name)
1224         {
1225           err = GPG_ERR_NO_OBJ;
1226           /* Some are missing.  Before bailing out we test for
1227              optional parameters.  */
1228           if (algo_name && !strcmp (algo_name, "RSA")
1229               && !strcmp (element_names, "nedpqu") )
1230             {
1231               /* This is RSA.  Test whether we got N, E and D and that
1232                  the optional P, Q and U are all missing.  */
1233               if (elements[0] && elements[1] && elements[2]
1234                   && !elements[3] && !elements[4] && !elements[5])
1235                 err = 0;
1236             }
1237         }
1238     }
1239
1240
1241   if (err)
1242     {
1243       for (i = 0; i < idx; i++)
1244         if (elements[i])
1245           gcry_free (elements[i]);
1246     }
1247   return err;
1248 }
1249
1250
1251 /* Internal function used for ecc.  Note, that this function makes use
1252    of its intimate knowledge about the ECC parameters from ecc.c. */
1253 static gcry_err_code_t
1254 sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
1255                            gcry_mpi_t *elements, pk_extra_spec_t *extraspec)
1256
1257 {
1258   gcry_err_code_t err = 0;
1259   int idx;
1260   const char *name;
1261   gcry_sexp_t list;
1262
1263   /* Clear the array for easier error cleanup. */
1264   for (name = element_names, idx = 0; *name; name++, idx++)
1265     elements[idx] = NULL;
1266   gcry_assert (idx >= 5); /* We know that ECC has at least 5 elements
1267                              (params only) or 6 (full public key).  */
1268   if (idx == 5)
1269     elements[5] = NULL;   /* Extra clear for the params only case.  */
1270
1271
1272   /* Init the array with the available curve parameters. */
1273   for (name = element_names, idx = 0; *name && !err; name++, idx++)
1274     {
1275       list = gcry_sexp_find_token (key_sexp, name, 1);
1276       if (!list)
1277         elements[idx] = NULL;
1278       else
1279         {
1280           elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
1281           gcry_sexp_release (list);
1282           if (!elements[idx])
1283             {
1284               err = GPG_ERR_INV_OBJ;
1285               goto leave;
1286             }
1287         }
1288     }
1289
1290   /* Check whether a curve parameter has been given and then fill any
1291      missing elements.  */
1292   list = gcry_sexp_find_token (key_sexp, "curve", 5);
1293   if (list)
1294     {
1295       if (extraspec->get_param)
1296         {
1297           char *curve;
1298           gcry_mpi_t params[6];
1299
1300           for (idx = 0; idx < DIM(params); idx++)
1301             params[idx] = NULL;
1302
1303           curve = _gcry_sexp_nth_string (list, 1);
1304           gcry_sexp_release (list);
1305           if (!curve)
1306             {
1307               /* No curve name given (or out of core). */
1308               err = GPG_ERR_INV_OBJ;
1309               goto leave;
1310             }
1311           err = extraspec->get_param (curve, params);
1312           gcry_free (curve);
1313           if (err)
1314             goto leave;
1315
1316           for (idx = 0; idx < DIM(params); idx++)
1317             {
1318               if (!elements[idx])
1319                 elements[idx] = params[idx];
1320               else
1321                 mpi_free (params[idx]);
1322             }
1323         }
1324       else
1325         {
1326           gcry_sexp_release (list);
1327           err = GPG_ERR_INV_OBJ; /* "curve" given but ECC not supported. */
1328           goto leave;
1329         }
1330     }
1331
1332   /* Check that all parameters are known.  */
1333   for (name = element_names, idx = 0; *name; name++, idx++)
1334     if (!elements[idx])
1335       {
1336         err = GPG_ERR_NO_OBJ;
1337         goto leave;
1338       }
1339
1340  leave:
1341   if (err)
1342     {
1343       for (name = element_names, idx = 0; *name; name++, idx++)
1344         if (elements[idx])
1345           gcry_free (elements[idx]);
1346     }
1347   return err;
1348 }
1349
1350
1351
1352 /****************
1353  * Convert a S-Exp with either a private or a public key to our
1354  * internal format. Currently we do only support the following
1355  * algorithms:
1356  *    dsa
1357  *    rsa
1358  *    openpgp-dsa
1359  *    openpgp-rsa
1360  *    openpgp-elg
1361  *    openpgp-elg-sig
1362  *    ecdsa
1363  *    ecdh
1364  * Provide a SE with the first element be either "private-key" or
1365  * or "public-key". It is followed by a list with its first element
1366  * be one of the above algorithm identifiers and the remaning
1367  * elements are pairs with parameter-id and value.
1368  * NOTE: we look through the list to find a list beginning with
1369  * "private-key" or "public-key" - the first one found is used.
1370  *
1371  * If OVERRIDE_ELEMS is not NULL those elems override the parameter
1372  * specification taken from the module.  This ise used by
1373  * gcry_pk_get_curve.
1374  *
1375  * Returns: A pointer to an allocated array of MPIs if the return value is
1376  *          zero; the caller has to release this array.
1377  *
1378  * Example of a DSA public key:
1379  *  (private-key
1380  *    (dsa
1381  *      (p <mpi>)
1382  *      (g <mpi>)
1383  *      (y <mpi>)
1384  *      (x <mpi>)
1385  *    )
1386  *  )
1387  * The <mpi> are expected to be in GCRYMPI_FMT_USG
1388  */
1389 static gcry_err_code_t
1390 sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems,
1391              gcry_mpi_t **retarray, gcry_module_t *retalgo)
1392 {
1393   gcry_err_code_t err = 0;
1394   gcry_sexp_t list, l2;
1395   char *name;
1396   const char *elems;
1397   gcry_mpi_t *array;
1398   gcry_module_t module;
1399   gcry_pk_spec_t *pubkey;
1400   pk_extra_spec_t *extraspec;
1401   int is_ecc;
1402
1403   /* Check that the first element is valid.  */
1404   list = gcry_sexp_find_token (sexp,
1405                                want_private? "private-key":"public-key", 0);
1406   if (!list)
1407     return GPG_ERR_INV_OBJ; /* Does not contain a key object.  */
1408
1409   l2 = gcry_sexp_cadr( list );
1410   gcry_sexp_release ( list );
1411   list = l2;
1412   name = _gcry_sexp_nth_string (list, 0);
1413   if (!name)
1414     {
1415       gcry_sexp_release ( list );
1416       return GPG_ERR_INV_OBJ;      /* Invalid structure of object. */
1417     }
1418
1419   ath_mutex_lock (&pubkeys_registered_lock);
1420   module = gcry_pk_lookup_name (name);
1421   ath_mutex_unlock (&pubkeys_registered_lock);
1422
1423   /* Fixme: We should make sure that an ECC key is always named "ecc"
1424      and not "ecdsa".  "ecdsa" should be used for the signature
1425      itself.  We need a function to test whether an algorithm given
1426      with a key is compatible with an application of the key (signing,
1427      encryption).  For RSA this is easy, but ECC is the first
1428      algorithm which has many flavours.  */
1429   is_ecc = ( !strcmp (name, "ecdsa")
1430              || !strcmp (name, "ecdh")
1431              || !strcmp (name, "ecc") );
1432   gcry_free (name);
1433
1434   if (!module)
1435     {
1436       gcry_sexp_release (list);
1437       return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
1438     }
1439   else
1440     {
1441       pubkey = (gcry_pk_spec_t *) module->spec;
1442       extraspec = module->extraspec;
1443     }
1444
1445   if (override_elems)
1446     elems = override_elems;
1447   else if (want_private)
1448     elems = pubkey->elements_skey;
1449   else
1450     elems = pubkey->elements_pkey;
1451   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
1452   if (!array)
1453     err = gpg_err_code_from_syserror ();
1454   if (!err)
1455     {
1456       if (is_ecc)
1457         err = sexp_elements_extract_ecc (list, elems, array, extraspec);
1458       else
1459         err = sexp_elements_extract (list, elems, array, pubkey->name);
1460     }
1461
1462   gcry_sexp_release (list);
1463
1464   if (err)
1465     {
1466       gcry_free (array);
1467
1468       ath_mutex_lock (&pubkeys_registered_lock);
1469       _gcry_module_release (module);
1470       ath_mutex_unlock (&pubkeys_registered_lock);
1471     }
1472   else
1473     {
1474       *retarray = array;
1475       *retalgo = module;
1476     }
1477
1478   return err;
1479 }
1480
1481
1482 static gcry_err_code_t
1483 sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
1484              gcry_module_t *retalgo)
1485 {
1486   gcry_err_code_t err = 0;
1487   gcry_sexp_t list, l2;
1488   char *name;
1489   const char *elems;
1490   gcry_mpi_t *array;
1491   gcry_module_t module;
1492   gcry_pk_spec_t *pubkey;
1493
1494   /* Check that the first element is valid.  */
1495   list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
1496   if (!list)
1497     return GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
1498
1499   l2 = gcry_sexp_nth (list, 1);
1500   if (!l2)
1501     {
1502       gcry_sexp_release (list);
1503       return GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
1504     }
1505   name = _gcry_sexp_nth_string (l2, 0);
1506   if (!name)
1507     {
1508       gcry_sexp_release (list);
1509       gcry_sexp_release (l2);
1510       return GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
1511     }
1512   else if (!strcmp (name, "flags"))
1513     {
1514       /* Skip flags, since they are not used but here just for the
1515          sake of consistent S-expressions.  */
1516       gcry_free (name);
1517       gcry_sexp_release (l2);
1518       l2 = gcry_sexp_nth (list, 2);
1519       if (!l2)
1520         {
1521           gcry_sexp_release (list);
1522           return GPG_ERR_INV_OBJ;
1523         }
1524       name = _gcry_sexp_nth_string (l2, 0);
1525     }
1526
1527   ath_mutex_lock (&pubkeys_registered_lock);
1528   module = gcry_pk_lookup_name (name);
1529   ath_mutex_unlock (&pubkeys_registered_lock);
1530   gcry_free (name);
1531   name = NULL;
1532
1533   if (!module)
1534     {
1535       gcry_sexp_release (l2);
1536       gcry_sexp_release (list);
1537       return GPG_ERR_PUBKEY_ALGO;  /* Unknown algorithm. */
1538     }
1539   else
1540     pubkey = (gcry_pk_spec_t *) module->spec;
1541
1542   elems = pubkey->elements_sig;
1543   array = gcry_calloc (strlen (elems) + 1 , sizeof *array );
1544   if (!array)
1545     err = gpg_err_code_from_syserror ();
1546
1547   if (!err)
1548     err = sexp_elements_extract (list, elems, array, NULL);
1549
1550   gcry_sexp_release (l2);
1551   gcry_sexp_release (list);
1552
1553   if (err)
1554     {
1555       ath_mutex_lock (&pubkeys_registered_lock);
1556       _gcry_module_release (module);
1557       ath_mutex_unlock (&pubkeys_registered_lock);
1558
1559       gcry_free (array);
1560     }
1561   else
1562     {
1563       *retarray = array;
1564       *retalgo = module;
1565     }
1566
1567   return err;
1568 }
1569
1570 static inline int
1571 get_hash_algo (const char *s, size_t n)
1572 {
1573   static const struct { const char *name; int algo; } hashnames[] = {
1574     { "sha1",   GCRY_MD_SHA1 },
1575     { "md5",    GCRY_MD_MD5 },
1576     { "sha256", GCRY_MD_SHA256 },
1577     { "ripemd160", GCRY_MD_RMD160 },
1578     { "rmd160", GCRY_MD_RMD160 },
1579     { "sha384", GCRY_MD_SHA384 },
1580     { "sha512", GCRY_MD_SHA512 },
1581     { "sha224", GCRY_MD_SHA224 },
1582     { "md2",    GCRY_MD_MD2 },
1583     { "md4",    GCRY_MD_MD4 },
1584     { "tiger",  GCRY_MD_TIGER },
1585     { "haval",  GCRY_MD_HAVAL },
1586     { NULL, 0 }
1587   };
1588   int algo;
1589   int i;
1590
1591   for (i=0; hashnames[i].name; i++)
1592     {
1593       if ( strlen (hashnames[i].name) == n
1594            && !memcmp (hashnames[i].name, s, n))
1595         break;
1596     }
1597   if (hashnames[i].name)
1598     algo = hashnames[i].algo;
1599   else
1600     {
1601       /* In case of not listed or dynamically allocated hash
1602          algorithm we fall back to this somewhat slower
1603          method.  Further, it also allows to use OIDs as
1604          algorithm names. */
1605       char *tmpname;
1606
1607       tmpname = gcry_malloc (n+1);
1608       if (!tmpname)
1609         algo = 0;  /* Out of core - silently give up.  */
1610       else
1611         {
1612           memcpy (tmpname, s, n);
1613           tmpname[n] = 0;
1614           algo = gcry_md_map_name (tmpname);
1615           gcry_free (tmpname);
1616         }
1617     }
1618   return algo;
1619 }
1620
1621
1622 /****************
1623  * Take sexp and return an array of MPI as used for our internal decrypt
1624  * function.
1625  * s_data = (enc-val
1626  *           [(flags [raw, pkcs1, oaep, no-blinding])]
1627  *           [(hash-algo <algo>)]
1628  *           [(label <label>)]
1629  *            (<algo>
1630  *              (<param_name1> <mpi>)
1631  *              ...
1632  *              (<param_namen> <mpi>)
1633  *            ))
1634  * HASH-ALGO and LABEL are specific to OAEP.
1635  * RET_MODERN is set to true when at least an empty flags list has been found.
1636  * CTX is used to return encoding information; it may be NULL in which
1637  * case raw encoding is used.
1638  */
1639 static gcry_err_code_t
1640 sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
1641              int *ret_modern, int *flags, struct pk_encoding_ctx *ctx)
1642 {
1643   gcry_err_code_t err = 0;
1644   gcry_sexp_t list = NULL, l2 = NULL;
1645   gcry_pk_spec_t *pubkey = NULL;
1646   gcry_module_t module = NULL;
1647   char *name = NULL;
1648   size_t n;
1649   int parsed_flags = 0;
1650   const char *elems;
1651   gcry_mpi_t *array = NULL;
1652   struct pk_encoding_ctx dummy_ctx;
1653
1654   *ret_modern = 0;
1655
1656   if (!ctx)
1657     ctx = &dummy_ctx;
1658   ctx->encoding = PUBKEY_ENC_RAW;
1659   ctx->hash_algo = GCRY_MD_SHA1;
1660   ctx->label = NULL;
1661   ctx->labellen = 0;
1662
1663   /* Check that the first element is valid.  */
1664   list = gcry_sexp_find_token (sexp, "enc-val" , 0);
1665   if (!list)
1666     {
1667       err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
1668       goto leave;
1669     }
1670
1671   l2 = gcry_sexp_nth (list, 1);
1672   if (!l2)
1673     {
1674       err = GPG_ERR_NO_OBJ; /* No cdr for the data object.  */
1675       goto leave;
1676     }
1677
1678   /* Extract identifier of sublist.  */
1679   name = _gcry_sexp_nth_string (l2, 0);
1680   if (!name)
1681     {
1682       err = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
1683       goto leave;
1684     }
1685
1686   if (!strcmp (name, "flags"))
1687     {
1688       /* There is a flags element - process it.  */
1689       const char *s;
1690       int i;
1691
1692       *ret_modern = 1;
1693       for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
1694         {
1695           s = gcry_sexp_nth_data (l2, i, &n);
1696           if (! s)
1697             ; /* Not a data element - ignore.  */
1698           else if (n == 3 && !memcmp (s, "raw", 3)
1699                    && ctx->encoding == PUBKEY_ENC_RAW)
1700             ; /* This is just a dummy as it is the default.  */
1701           else if (n == 5 && !memcmp (s, "pkcs1", 5)
1702                    && ctx->encoding == PUBKEY_ENC_RAW)
1703             ctx->encoding = PUBKEY_ENC_PKCS1;
1704           else if (n == 4 && !memcmp (s, "oaep", 4)
1705                    && ctx->encoding == PUBKEY_ENC_RAW)
1706             ctx->encoding = PUBKEY_ENC_OAEP;
1707           else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1708             parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1709           else
1710             {
1711               err = GPG_ERR_INV_FLAG;
1712               goto leave;
1713             }
1714         }
1715       gcry_sexp_release (l2);
1716
1717       /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
1718       if (ctx->encoding == PUBKEY_ENC_OAEP)
1719         {
1720           /* Get HASH-ALGO. */
1721           l2 = gcry_sexp_find_token (list, "hash-algo", 0);
1722           if (l2)
1723             {
1724               s = gcry_sexp_nth_data (l2, 1, &n);
1725               if (!s)
1726                 err = GPG_ERR_NO_OBJ;
1727               else
1728                 {
1729                   ctx->hash_algo = get_hash_algo (s, n);
1730                   if (!ctx->hash_algo)
1731                     err = GPG_ERR_DIGEST_ALGO;
1732                 }
1733               gcry_sexp_release (l2);
1734               if (err)
1735                 goto leave;
1736             }
1737
1738           /* Get LABEL. */
1739           l2 = gcry_sexp_find_token (list, "label", 0);
1740           if (l2)
1741             {
1742               s = gcry_sexp_nth_data (l2, 1, &n);
1743               if (!s)
1744                 err = GPG_ERR_NO_OBJ;
1745               else if (n > 0)
1746                 {
1747                   ctx->label = gcry_malloc (n);
1748                   if (!ctx->label)
1749                     err = gpg_err_code_from_syserror ();
1750                   else
1751                     {
1752                       memcpy (ctx->label, s, n);
1753                       ctx->labellen = n;
1754                     }
1755                 }
1756               gcry_sexp_release (l2);
1757               if (err)
1758                 goto leave;
1759             }
1760         }
1761
1762       /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
1763       for (i = 2; (l2 = gcry_sexp_nth (list, i)) != NULL; i++)
1764         {
1765           s = gcry_sexp_nth_data (l2, 0, &n);
1766           if (!(n == 9 && !memcmp (s, "hash-algo", 9))
1767               && !(n == 5 && !memcmp (s, "label", 5)))
1768             break;
1769           gcry_sexp_release (l2);
1770         }
1771
1772       if (!l2)
1773         {
1774           err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
1775           goto leave;
1776         }
1777
1778       /* Extract sublist identifier.  */
1779       gcry_free (name);
1780       name = _gcry_sexp_nth_string (l2, 0);
1781       if (!name)
1782         {
1783           err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
1784           goto leave;
1785         }
1786
1787       gcry_sexp_release (list);
1788       list = l2;
1789       l2 = NULL;
1790     }
1791
1792   ath_mutex_lock (&pubkeys_registered_lock);
1793   module = gcry_pk_lookup_name (name);
1794   ath_mutex_unlock (&pubkeys_registered_lock);
1795
1796   if (!module)
1797     {
1798       err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
1799       goto leave;
1800     }
1801   pubkey = (gcry_pk_spec_t *) module->spec;
1802
1803   elems = pubkey->elements_enc;
1804   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
1805   if (!array)
1806     {
1807       err = gpg_err_code_from_syserror ();
1808       goto leave;
1809     }
1810
1811   err = sexp_elements_extract (list, elems, array, NULL);
1812
1813  leave:
1814   gcry_sexp_release (list);
1815   gcry_sexp_release (l2);
1816   gcry_free (name);
1817
1818   if (err)
1819     {
1820       ath_mutex_lock (&pubkeys_registered_lock);
1821       _gcry_module_release (module);
1822       ath_mutex_unlock (&pubkeys_registered_lock);
1823       gcry_free (array);
1824       gcry_free (ctx->label);
1825       ctx->label = NULL;
1826     }
1827   else
1828     {
1829       *retarray = array;
1830       *retalgo = module;
1831       *flags = parsed_flags;
1832     }
1833
1834   return err;
1835 }
1836
1837 /* Take the hash value and convert into an MPI, suitable for
1838    passing to the low level functions.  We currently support the
1839    old style way of passing just a MPI and the modern interface which
1840    allows to pass flags so that we can choose between raw and pkcs1
1841    padding - may be more padding options later.
1842
1843    (<mpi>)
1844    or
1845    (data
1846     [(flags [raw, pkcs1, oaep, no-blinding])]
1847     [(hash <algo> <value>)]
1848     [(value <text>)]
1849     [(hash-algo <algo>)]
1850     [(label <label>)]
1851    )
1852
1853    Either the VALUE or the HASH element must be present for use
1854    with signatures.  VALUE is used for encryption.
1855
1856    HASH-ALGO and LABEL are specific to OAEP.
1857
1858    NBITS is the length of the key in bits.
1859
1860 */
1861 static gcry_err_code_t
1862 sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
1863                   int for_encryption, int *flags, struct pk_encoding_ctx *ctx)
1864 {
1865   gcry_err_code_t rc = 0;
1866   gcry_sexp_t ldata, lhash, lvalue;
1867   int i;
1868   size_t n;
1869   const char *s;
1870   int unknown_flag=0;
1871   int parsed_flags = 0, dummy_flags;
1872   struct pk_encoding_ctx dummy_ctx;
1873
1874   if (! flags)
1875     flags = &dummy_flags;
1876
1877   if (! ctx)
1878     ctx = &dummy_ctx;
1879
1880   ctx->encoding = PUBKEY_ENC_UNKNOWN;
1881   ctx->hash_algo = GCRY_MD_SHA1;
1882   ctx->label = NULL;
1883   ctx->labellen = 0;
1884
1885   *ret_mpi = NULL;
1886   ldata = gcry_sexp_find_token (input, "data", 0);
1887   if (!ldata)
1888     { /* assume old style */
1889       *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
1890       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
1891     }
1892
1893   /* see whether there is a flags object */
1894   {
1895     gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
1896     if (lflags)
1897       { /* parse the flags list. */
1898         for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
1899           {
1900             s = gcry_sexp_nth_data (lflags, i, &n);
1901             if (!s)
1902               ; /* not a data element*/
1903             else if ( n == 3 && !memcmp (s, "raw", 3)
1904                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1905               ctx->encoding = PUBKEY_ENC_RAW;
1906             else if ( n == 5 && !memcmp (s, "pkcs1", 5)
1907                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1908               ctx->encoding = PUBKEY_ENC_PKCS1;
1909             else if ( n == 4 && !memcmp (s, "oaep", 4)
1910                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1911               ctx->encoding = PUBKEY_ENC_OAEP;
1912             else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1913               parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1914             else
1915               unknown_flag = 1;
1916           }
1917         gcry_sexp_release (lflags);
1918       }
1919   }
1920
1921   if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
1922     ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
1923
1924   /* Get HASH or MPI */
1925   lhash = gcry_sexp_find_token (ldata, "hash", 0);
1926   lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
1927
1928   if (!(!lhash ^ !lvalue))
1929     rc = GPG_ERR_INV_OBJ; /* none or both given */
1930   else if (unknown_flag)
1931     rc = GPG_ERR_INV_FLAG;
1932   else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
1933     {
1934       *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
1935       if (!*ret_mpi)
1936         rc = GPG_ERR_INV_OBJ;
1937     }
1938   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue && for_encryption)
1939     {
1940       const void * value;
1941       size_t valuelen;
1942
1943       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1944         rc = GPG_ERR_INV_OBJ;
1945       else
1946         rc = pkcs1_encode_for_encryption (ret_mpi, nbits, value, valuelen);
1947     }
1948   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash && !for_encryption)
1949     {
1950       if (gcry_sexp_length (lhash) != 3)
1951         rc = GPG_ERR_INV_OBJ;
1952       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1953         rc = GPG_ERR_INV_OBJ;
1954       else
1955         {
1956           int algo;
1957           const void * value;
1958           size_t valuelen;
1959
1960           algo = get_hash_algo (s, n);
1961
1962           if (!algo)
1963             rc = GPG_ERR_DIGEST_ALGO;
1964           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
1965                     || !valuelen )
1966             rc = GPG_ERR_INV_OBJ;
1967           else
1968             rc = pkcs1_encode_for_signature (ret_mpi, nbits, value, valuelen,
1969                                              algo);
1970         }
1971     }
1972   else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue && for_encryption)
1973     {
1974       const void * value;
1975       size_t valuelen;
1976
1977       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1978         rc = GPG_ERR_INV_OBJ;
1979       else
1980         {
1981           gcry_sexp_t list;
1982
1983           /* Get HASH-ALGO. */
1984           list = gcry_sexp_find_token (ldata, "hash-algo", 0);
1985           if (list)
1986             {
1987               s = gcry_sexp_nth_data (list, 1, &n);
1988               if (!s)
1989                 rc = GPG_ERR_NO_OBJ;
1990               else
1991                 {
1992                   ctx->hash_algo = get_hash_algo (s, n);
1993                   if (!ctx->hash_algo)
1994                     rc = GPG_ERR_DIGEST_ALGO;
1995                 }
1996               gcry_sexp_release (list);
1997               if (rc)
1998                 goto leave;
1999             }
2000
2001           /* Get LABEL. */
2002           list = gcry_sexp_find_token (ldata, "label", 0);
2003           if (list)
2004             {
2005               s = gcry_sexp_nth_data (list, 1, &n);
2006               if (!s)
2007                 rc = GPG_ERR_NO_OBJ;
2008               else if (n > 0)
2009                 {
2010                   ctx->label = gcry_malloc (n);
2011                   if (!ctx->label)
2012                     rc = gpg_err_code_from_syserror ();
2013                   else
2014                     {
2015                       memcpy (ctx->label, s, n);
2016                       ctx->labellen = n;
2017                     }
2018                 }
2019               gcry_sexp_release (list);
2020               if (rc)
2021                 goto leave;
2022             }
2023
2024           rc = oaep_encode (ret_mpi, nbits, ctx->hash_algo, value, valuelen,
2025                             ctx->label, ctx->labellen);
2026         }
2027     }
2028   else
2029     rc = GPG_ERR_CONFLICT;
2030
2031  leave:
2032   gcry_sexp_release (ldata);
2033   gcry_sexp_release (lhash);
2034   gcry_sexp_release (lvalue);
2035
2036   if (!rc)
2037     *flags = parsed_flags;
2038   else
2039     {
2040       gcry_free (ctx->label);
2041       ctx->label = NULL;
2042     }
2043
2044   return rc;
2045 }
2046
2047
2048 /*
2049    Do a PK encrypt operation
2050
2051    Caller has to provide a public key as the SEXP pkey and data as a
2052    SEXP with just one MPI in it. Alternatively S_DATA might be a
2053    complex S-Expression, similar to the one used for signature
2054    verification.  This provides a flag which allows to handle PKCS#1
2055    block type 2 padding.  The function returns a a sexp which may be
2056    passed to to pk_decrypt.
2057
2058    Returns: 0 or an errorcode.
2059
2060    s_data = See comment for sexp_data_to_mpi
2061    s_pkey = <key-as-defined-in-sexp_to_key>
2062    r_ciph = (enc-val
2063                (<algo>
2064                  (<param_name1> <mpi>)
2065                  ...
2066                  (<param_namen> <mpi>)
2067                ))
2068
2069 */
2070 gcry_error_t
2071 gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
2072 {
2073   gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
2074   const char *algo_name, *algo_elems;
2075   int flags;
2076   struct pk_encoding_ctx ctx;
2077   gcry_err_code_t rc;
2078   gcry_pk_spec_t *pubkey = NULL;
2079   gcry_module_t module = NULL;
2080
2081   *r_ciph = NULL;
2082
2083   REGISTER_DEFAULT_PUBKEYS;
2084
2085   memset (&ctx, 0, sizeof(struct pk_encoding_ctx));
2086   /* Get the key. */
2087   rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module);
2088   if (rc)
2089     goto leave;
2090
2091   gcry_assert (module);
2092   pubkey = (gcry_pk_spec_t *) module->spec;
2093
2094   /* If aliases for the algorithm name exists, take the first one
2095      instead of the regular name to adhere to SPKI conventions.  We
2096      assume that the first alias name is the lowercase version of the
2097      regular one.  This change is required for compatibility with
2098      1.1.12 generated S-expressions. */
2099   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2100   if (!algo_name || !*algo_name)
2101     algo_name = pubkey->name;
2102
2103   algo_elems = pubkey->elements_enc;
2104
2105   /* Get the stuff we want to encrypt. */
2106   rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
2107                          &flags, &ctx);
2108   if (rc)
2109     goto leave;
2110
2111   /* Now we can encrypt DATA to CIPH. */
2112   ciph = gcry_calloc (strlen (algo_elems) + 1, sizeof (*ciph));
2113   if (!ciph)
2114     {
2115       rc = gpg_err_code_from_syserror ();
2116       goto leave;
2117     }
2118   rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
2119   mpi_free (data);
2120   data = NULL;
2121   if (rc)
2122     goto leave;
2123
2124   /* We did it.  Now build the return list */
2125   {
2126     char *string, *p;
2127     int i;
2128     size_t nelem = strlen (algo_elems);
2129     size_t needed = 19 + strlen (algo_name) + (nelem * 5);
2130     void **arg_list;
2131
2132     /* Build the string.  */
2133     string = p = gcry_malloc (needed);
2134     if (!string)
2135       {
2136         rc = gpg_err_code_from_syserror ();
2137         goto leave;
2138       }
2139     p = stpcpy ( p, "(enc-val(" );
2140     p = stpcpy ( p, algo_name );
2141     for (i=0; algo_elems[i]; i++ )
2142       {
2143         *p++ = '(';
2144         *p++ = algo_elems[i];
2145         p = stpcpy ( p, "%m)" );
2146       }
2147     strcpy ( p, "))" );
2148
2149     /* And now the ugly part: We don't have a function to pass an
2150      * array to a format string, so we have to do it this way :-(.  */
2151     /* FIXME: There is now such a format specifier, so we can
2152        change the code to be more clear. */
2153     arg_list = malloc (nelem * sizeof *arg_list);
2154     if (!arg_list)
2155       {
2156         rc = gpg_err_code_from_syserror ();
2157         goto leave;
2158       }
2159
2160     for (i = 0; i < nelem; i++)
2161       arg_list[i] = ciph + i;
2162
2163     rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
2164     free (arg_list);
2165     if (rc)
2166       BUG ();
2167     gcry_free (string);
2168   }
2169
2170  leave:
2171   if (pkey)
2172     {
2173       release_mpi_array (pkey);
2174       gcry_free (pkey);
2175     }
2176
2177   if (ciph)
2178     {
2179       release_mpi_array (ciph);
2180       gcry_free (ciph);
2181     }
2182
2183   if (module)
2184     {
2185       ath_mutex_lock (&pubkeys_registered_lock);
2186       _gcry_module_release (module);
2187       ath_mutex_unlock (&pubkeys_registered_lock);
2188     }
2189
2190   gcry_free (ctx.label);
2191
2192   return gcry_error (rc);
2193 }
2194
2195 /*
2196    Do a PK decrypt operation
2197
2198    Caller has to provide a secret key as the SEXP skey and data in a
2199    format as created by gcry_pk_encrypt.  For historic reasons the
2200    function returns simply an MPI as an S-expression part; this is
2201    deprecated and the new method should be used which returns a real
2202    S-expressionl this is selected by adding at least an empty flags
2203    list to S_DATA.
2204
2205    Returns: 0 or an errorcode.
2206
2207    s_data = (enc-val
2208               [(flags [raw, pkcs1, oaep])]
2209               (<algo>
2210                 (<param_name1> <mpi>)
2211                 ...
2212                 (<param_namen> <mpi>)
2213               ))
2214    s_skey = <key-as-defined-in-sexp_to_key>
2215    r_plain= Either an incomplete S-expression without the parentheses
2216             or if the flags list is used (even if empty) a real S-expression:
2217             (value PLAIN).
2218  */
2219 gcry_error_t
2220 gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
2221 {
2222   gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL, unpad = NULL;
2223   int modern, flags;
2224   struct pk_encoding_ctx ctx;
2225   gcry_err_code_t rc;
2226   gcry_module_t module_enc = NULL, module_key = NULL;
2227
2228   *r_plain = NULL;
2229   ctx.label = NULL;
2230
2231   REGISTER_DEFAULT_PUBKEYS;
2232
2233   rc = sexp_to_key (s_skey, 1, NULL, &skey, &module_key);
2234   if (rc)
2235     goto leave;
2236
2237   rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &flags, &ctx);
2238   if (rc)
2239     goto leave;
2240
2241   if (module_key->mod_id != module_enc->mod_id)
2242     {
2243       rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
2244       goto leave;
2245     }
2246
2247   rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
2248   if (rc)
2249     goto leave;
2250
2251   /* Do un-padding if necessary. */
2252   switch (ctx.encoding)
2253     {
2254     case PUBKEY_ENC_PKCS1:
2255       rc = pkcs1_decode_for_encryption (&unpad, gcry_pk_get_nbits (s_skey),
2256                                         plain);
2257       mpi_free (plain);
2258       if (rc)
2259         goto leave;
2260       plain = unpad;
2261       break;
2262     case PUBKEY_ENC_OAEP:
2263       rc = oaep_decode (&unpad, gcry_pk_get_nbits (s_skey), ctx.hash_algo,
2264                         plain, ctx.label, ctx.labellen);
2265       mpi_free (plain);
2266       if (rc)
2267         goto leave;
2268       plain = unpad;
2269       break;
2270     default:
2271       break;
2272     }
2273
2274   if (gcry_sexp_build (r_plain, NULL, modern? "(value %m)" : "%m", plain))
2275     BUG ();
2276
2277  leave:
2278   if (skey)
2279     {
2280       release_mpi_array (skey);
2281       gcry_free (skey);
2282     }
2283
2284   if (plain)
2285     mpi_free (plain);
2286
2287   if (data)
2288     {
2289       release_mpi_array (data);
2290       gcry_free (data);
2291     }
2292
2293   if (module_key || module_enc)
2294     {
2295       ath_mutex_lock (&pubkeys_registered_lock);
2296       if (module_key)
2297         _gcry_module_release (module_key);
2298       if (module_enc)
2299         _gcry_module_release (module_enc);
2300       ath_mutex_unlock (&pubkeys_registered_lock);
2301     }
2302
2303   gcry_free (ctx.label);
2304
2305   return gcry_error (rc);
2306 }
2307
2308
2309
2310 /*
2311    Create a signature.
2312
2313    Caller has to provide a secret key as the SEXP skey and data
2314    expressed as a SEXP list hash with only one element which should
2315    instantly be available as a MPI. Alternatively the structure given
2316    below may be used for S_HASH, it provides the abiliy to pass flags
2317    to the operation; the only flag defined by now is "pkcs1" which
2318    does PKCS#1 block type 1 style padding.
2319
2320    Returns: 0 or an errorcode.
2321             In case of 0 the function returns a new SEXP with the
2322             signature value; the structure of this signature depends on the
2323             other arguments but is always suitable to be passed to
2324             gcry_pk_verify
2325
2326    s_hash = See comment for sexp_data_to_mpi
2327
2328    s_skey = <key-as-defined-in-sexp_to_key>
2329    r_sig  = (sig-val
2330               (<algo>
2331                 (<param_name1> <mpi>)
2332                 ...
2333                 (<param_namen> <mpi>))
2334              [(hash algo)])
2335
2336   Note that (hash algo) in R_SIG is not used.
2337 */
2338 gcry_error_t
2339 gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
2340 {
2341   gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
2342   gcry_pk_spec_t *pubkey = NULL;
2343   gcry_module_t module = NULL;
2344   const char *algo_name, *algo_elems;
2345   int i;
2346   gcry_err_code_t rc;
2347
2348   *r_sig = NULL;
2349
2350   REGISTER_DEFAULT_PUBKEYS;
2351
2352   rc = sexp_to_key (s_skey, 1, NULL, &skey, &module);
2353   if (rc)
2354     goto leave;
2355
2356   gcry_assert (module);
2357   pubkey = (gcry_pk_spec_t *) module->spec;
2358   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2359   if (!algo_name || !*algo_name)
2360     algo_name = pubkey->name;
2361
2362   algo_elems = pubkey->elements_sig;
2363
2364   /* Get the stuff we want to sign.  Note that pk_get_nbits does also
2365       work on a private key. */
2366   rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey),
2367                              &hash, 0, NULL, NULL);
2368   if (rc)
2369     goto leave;
2370
2371   result = gcry_calloc (strlen (algo_elems) + 1, sizeof (*result));
2372   if (!result)
2373     {
2374       rc = gpg_err_code_from_syserror ();
2375       goto leave;
2376     }
2377   rc = pubkey_sign (module->mod_id, result, hash, skey);
2378   if (rc)
2379     goto leave;
2380
2381   {
2382     char *string, *p;
2383     size_t nelem, needed = strlen (algo_name) + 20;
2384     void **arg_list;
2385
2386     nelem = strlen (algo_elems);
2387
2388     /* Count elements, so that we can allocate enough space. */
2389     needed += 10 * nelem;
2390
2391     /* Build the string. */
2392     string = p = gcry_malloc (needed);
2393     if (!string)
2394       {
2395         rc = gpg_err_code_from_syserror ();
2396         goto leave;
2397       }
2398     p = stpcpy (p, "(sig-val(");
2399     p = stpcpy (p, algo_name);
2400     for (i = 0; algo_elems[i]; i++)
2401       {
2402         *p++ = '(';
2403         *p++ = algo_elems[i];
2404         p = stpcpy (p, "%m)");
2405       }
2406     strcpy (p, "))");
2407
2408     arg_list = malloc (nelem * sizeof *arg_list);
2409     if (!arg_list)
2410       {
2411         rc = gpg_err_code_from_syserror ();
2412         goto leave;
2413       }
2414
2415     for (i = 0; i < nelem; i++)
2416       arg_list[i] = result + i;
2417
2418     rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
2419     free (arg_list);
2420     if (rc)
2421       BUG ();
2422     gcry_free (string);
2423   }
2424
2425  leave:
2426   if (skey)
2427     {
2428       release_mpi_array (skey);
2429       gcry_free (skey);
2430     }
2431
2432   if (hash)
2433     mpi_free (hash);
2434
2435   if (result)
2436     {
2437       release_mpi_array (result);
2438       gcry_free (result);
2439     }
2440
2441   return gcry_error (rc);
2442 }
2443
2444
2445 /*
2446    Verify a signature.
2447
2448    Caller has to supply the public key pkey, the signature sig and his
2449    hashvalue data.  Public key has to be a standard public key given
2450    as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
2451    must be an S-Exp like the one in sign too.  */
2452 gcry_error_t
2453 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
2454 {
2455   gcry_module_t module_key = NULL, module_sig = NULL;
2456   gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
2457   gcry_err_code_t rc;
2458
2459   REGISTER_DEFAULT_PUBKEYS;
2460
2461   rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module_key);
2462   if (rc)
2463     goto leave;
2464
2465   rc = sexp_to_sig (s_sig, &sig, &module_sig);
2466   if (rc)
2467     goto leave;
2468
2469   /* Fixme: Check that the algorithm of S_SIG is compatible to the one
2470      of S_PKEY.  */
2471
2472   if (module_key->mod_id != module_sig->mod_id)
2473     {
2474       rc = GPG_ERR_CONFLICT;
2475       goto leave;
2476     }
2477
2478   rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0, NULL);
2479   if (rc)
2480     goto leave;
2481
2482   rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
2483
2484  leave:
2485   if (pkey)
2486     {
2487       release_mpi_array (pkey);
2488       gcry_free (pkey);
2489     }
2490   if (sig)
2491     {
2492       release_mpi_array (sig);
2493       gcry_free (sig);
2494     }
2495   if (hash)
2496     mpi_free (hash);
2497
2498   if (module_key || module_sig)
2499     {
2500       ath_mutex_lock (&pubkeys_registered_lock);
2501       if (module_key)
2502         _gcry_module_release (module_key);
2503       if (module_sig)
2504         _gcry_module_release (module_sig);
2505       ath_mutex_unlock (&pubkeys_registered_lock);
2506     }
2507
2508   return gcry_error (rc);
2509 }
2510
2511
2512 /*
2513    Test a key.
2514
2515    This may be used either for a public or a secret key to see whether
2516    the internal structure is okay.
2517
2518    Returns: 0 or an errorcode.
2519
2520    s_key = <key-as-defined-in-sexp_to_key> */
2521 gcry_error_t
2522 gcry_pk_testkey (gcry_sexp_t s_key)
2523 {
2524   gcry_module_t module = NULL;
2525   gcry_mpi_t *key = NULL;
2526   gcry_err_code_t rc;
2527
2528   REGISTER_DEFAULT_PUBKEYS;
2529
2530   /* Note we currently support only secret key checking. */
2531   rc = sexp_to_key (s_key, 1, NULL, &key, &module);
2532   if (! rc)
2533     {
2534       rc = pubkey_check_secret_key (module->mod_id, key);
2535       release_mpi_array (key);
2536       gcry_free (key);
2537     }
2538   return gcry_error (rc);
2539 }
2540
2541
2542 /*
2543   Create a public key pair and return it in r_key.
2544   How the key is created depends on s_parms:
2545   (genkey
2546    (algo
2547      (parameter_name_1 ....)
2548       ....
2549      (parameter_name_n ....)
2550   ))
2551   The key is returned in a format depending on the
2552   algorithm. Both, private and secret keys are returned
2553   and optionally some additional informatin.
2554   For elgamal we return this structure:
2555   (key-data
2556    (public-key
2557      (elg
2558         (p <mpi>)
2559         (g <mpi>)
2560         (y <mpi>)
2561      )
2562    )
2563    (private-key
2564      (elg
2565         (p <mpi>)
2566         (g <mpi>)
2567         (y <mpi>)
2568         (x <mpi>)
2569      )
2570    )
2571    (misc-key-info
2572       (pm1-factors n1 n2 ... nn)
2573    ))
2574  */
2575 gcry_error_t
2576 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
2577 {
2578   gcry_pk_spec_t *pubkey = NULL;
2579   gcry_module_t module = NULL;
2580   gcry_sexp_t list = NULL;
2581   gcry_sexp_t l2 = NULL;
2582   gcry_sexp_t l3 = NULL;
2583   char *name = NULL;
2584   size_t n;
2585   gcry_err_code_t rc = GPG_ERR_NO_ERROR;
2586   int i, j;
2587   const char *algo_name = NULL;
2588   int algo;
2589   const char *sec_elems = NULL, *pub_elems = NULL;
2590   gcry_mpi_t skey[12];
2591   gcry_mpi_t *factors = NULL;
2592   gcry_sexp_t extrainfo = NULL;
2593   unsigned int nbits = 0;
2594   unsigned long use_e = 0;
2595
2596   skey[0] = NULL;
2597   *r_key = NULL;
2598
2599   REGISTER_DEFAULT_PUBKEYS;
2600
2601   list = gcry_sexp_find_token (s_parms, "genkey", 0);
2602   if (!list)
2603     {
2604       rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
2605       goto leave;
2606     }
2607
2608   l2 = gcry_sexp_cadr (list);
2609   gcry_sexp_release (list);
2610   list = l2;
2611   l2 = NULL;
2612   if (! list)
2613     {
2614       rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
2615       goto leave;
2616     }
2617
2618   name = _gcry_sexp_nth_string (list, 0);
2619   if (!name)
2620     {
2621       rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
2622       goto leave;
2623     }
2624
2625   ath_mutex_lock (&pubkeys_registered_lock);
2626   module = gcry_pk_lookup_name (name);
2627   ath_mutex_unlock (&pubkeys_registered_lock);
2628   gcry_free (name);
2629   name = NULL;
2630   if (!module)
2631     {
2632       rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
2633       goto leave;
2634     }
2635
2636   pubkey = (gcry_pk_spec_t *) module->spec;
2637   algo = module->mod_id;
2638   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2639   if (!algo_name || !*algo_name)
2640     algo_name = pubkey->name;
2641   pub_elems = pubkey->elements_pkey;
2642   sec_elems = pubkey->elements_skey;
2643   if (strlen (sec_elems) >= DIM(skey))
2644     BUG ();
2645
2646   /* Handle the optional rsa-use-e element.  Actually this belong into
2647      the algorithm module but we have this parameter in the public
2648      module API, so we need to parse it right here.  */
2649   l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
2650   if (l2)
2651     {
2652       char buf[50];
2653       const char *s;
2654
2655       s = gcry_sexp_nth_data (l2, 1, &n);
2656       if ( !s || n >= DIM (buf) - 1 )
2657         {
2658           rc = GPG_ERR_INV_OBJ; /* No value or value too large.  */
2659           goto leave;
2660         }
2661       memcpy (buf, s, n);
2662       buf[n] = 0;
2663       use_e = strtoul (buf, NULL, 0);
2664       gcry_sexp_release (l2);
2665       l2 = NULL;
2666     }
2667   else
2668     use_e = 65537; /* Not given, use the value generated by old versions. */
2669
2670
2671   /* Get the "nbits" parameter.  */
2672   l2 = gcry_sexp_find_token (list, "nbits", 0);
2673   if (l2)
2674     {
2675       char buf[50];
2676       const char *s;
2677
2678       s = gcry_sexp_nth_data (l2, 1, &n);
2679       if (!s || n >= DIM (buf) - 1 )
2680         {
2681           rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr.  */
2682           goto leave;
2683         }
2684       memcpy (buf, s, n);
2685       buf[n] = 0;
2686       nbits = (unsigned int)strtoul (buf, NULL, 0);
2687       gcry_sexp_release (l2); l2 = NULL;
2688     }
2689   else
2690     nbits = 0;
2691
2692   /* Pass control to the algorithm module. */
2693   rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey,
2694                         &factors, &extrainfo);
2695   gcry_sexp_release (list); list = NULL;
2696   if (rc)
2697     goto leave;
2698
2699   /* Key generation succeeded: Build an S-expression.  */
2700   {
2701     char *string, *p;
2702     size_t nelem=0, nelem_cp = 0, needed=0;
2703     gcry_mpi_t mpis[30];
2704     int percent_s_idx = -1;
2705
2706     /* Estimate size of format string.  */
2707     nelem = strlen (pub_elems) + strlen (sec_elems);
2708     if (factors)
2709       {
2710         for (i = 0; factors[i]; i++)
2711           nelem++;
2712       }
2713     nelem_cp = nelem;
2714
2715     needed += nelem * 10;
2716     /* (+5 is for EXTRAINFO ("%S")).  */
2717     needed += 2 * strlen (algo_name) + 300 + 5;
2718     if (nelem > DIM (mpis))
2719       BUG ();
2720
2721     /* Build the string. */
2722     nelem = 0;
2723     string = p = gcry_malloc (needed);
2724     if (!string)
2725       {
2726         rc = gpg_err_code_from_syserror ();
2727         goto leave;
2728       }
2729     p = stpcpy (p, "(key-data");
2730     p = stpcpy (p, "(public-key(");
2731     p = stpcpy (p, algo_name);
2732     for(i = 0; pub_elems[i]; i++)
2733       {
2734         *p++ = '(';
2735         *p++ = pub_elems[i];
2736         p = stpcpy (p, "%m)");
2737         mpis[nelem++] = skey[i];
2738       }
2739     if (extrainfo && (algo == GCRY_PK_ECDSA || algo == GCRY_PK_ECDH))
2740       {
2741         /* Very ugly hack to insert the used curve parameter into the
2742            list of public key parameters.  */
2743         percent_s_idx = nelem;
2744         p = stpcpy (p, "%S");
2745       }
2746     p = stpcpy (p, "))");
2747     p = stpcpy (p, "(private-key(");
2748     p = stpcpy (p, algo_name);
2749     for (i = 0; sec_elems[i]; i++)
2750       {
2751         *p++ = '(';
2752         *p++ = sec_elems[i];
2753         p = stpcpy (p, "%m)");
2754         mpis[nelem++] = skey[i];
2755       }
2756     p = stpcpy (p, "))");
2757
2758     /* Hack to make release_mpi_array() work.  */
2759     skey[i] = NULL;
2760
2761     if (extrainfo && percent_s_idx == -1)
2762       {
2763         /* If we have extrainfo we should not have any factors.  */
2764         p = stpcpy (p, "%S");
2765       }
2766     else if (factors && factors[0])
2767       {
2768         p = stpcpy (p, "(misc-key-info(pm1-factors");
2769         for(i = 0; factors[i]; i++)
2770           {
2771             p = stpcpy (p, "%m");
2772             mpis[nelem++] = factors[i];
2773           }
2774         p = stpcpy (p, "))");
2775       }
2776     strcpy (p, ")");
2777     gcry_assert (p - string < needed);
2778
2779     while (nelem < DIM (mpis))
2780       mpis[nelem++] = NULL;
2781
2782     {
2783       int elem_n = strlen (pub_elems) + strlen (sec_elems);
2784       void **arg_list;
2785
2786       /* Allocate one extra for EXTRAINFO ("%S").  */
2787       arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
2788       if (!arg_list)
2789         {
2790           rc = gpg_err_code_from_syserror ();
2791           goto leave;
2792         }
2793       for (i = j = 0; i < elem_n; i++)
2794         {
2795           if (i == percent_s_idx)
2796             arg_list[j++] = &extrainfo;
2797           arg_list[j++] = mpis + i;
2798         }
2799       if (extrainfo && percent_s_idx == -1)
2800         arg_list[j] = &extrainfo;
2801       else if (factors && factors[0])
2802         {
2803           for (; i < nelem_cp; i++)
2804             arg_list[j++] = factors + i - elem_n;
2805         }
2806       rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
2807       gcry_free (arg_list);
2808       if (rc)
2809         BUG ();
2810       gcry_assert (DIM (mpis) == 30); /* Reminder to make sure that
2811                                          the array gets increased if
2812                                          new parameters are added. */
2813     }
2814     gcry_free (string);
2815   }
2816
2817  leave:
2818   gcry_free (name);
2819   gcry_sexp_release (extrainfo);
2820   release_mpi_array (skey);
2821   /* Don't free SKEY itself, it is an stack allocated array. */
2822
2823   if (factors)
2824     {
2825       release_mpi_array ( factors );
2826       gcry_free (factors);
2827     }
2828
2829   gcry_sexp_release (l3);
2830   gcry_sexp_release (l2);
2831   gcry_sexp_release (list);
2832
2833   if (module)
2834     {
2835       ath_mutex_lock (&pubkeys_registered_lock);
2836       _gcry_module_release (module);
2837       ath_mutex_unlock (&pubkeys_registered_lock);
2838     }
2839
2840   return gcry_error (rc);
2841 }
2842
2843
2844 /*
2845    Get the number of nbits from the public key.
2846
2847    Hmmm: Should we have really this function or is it better to have a
2848    more general function to retrieve different properties of the key?  */
2849 unsigned int
2850 gcry_pk_get_nbits (gcry_sexp_t key)
2851 {
2852   gcry_module_t module = NULL;
2853   gcry_pk_spec_t *pubkey;
2854   gcry_mpi_t *keyarr = NULL;
2855   unsigned int nbits = 0;
2856   gcry_err_code_t rc;
2857
2858   REGISTER_DEFAULT_PUBKEYS;
2859
2860   rc = sexp_to_key (key, 0, NULL, &keyarr, &module);
2861   if (rc == GPG_ERR_INV_OBJ)
2862     rc = sexp_to_key (key, 1, NULL, &keyarr, &module);
2863   if (rc)
2864     return 0; /* Error - 0 is a suitable indication for that. */
2865
2866   pubkey = (gcry_pk_spec_t *) module->spec;
2867   nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
2868
2869   ath_mutex_lock (&pubkeys_registered_lock);
2870   _gcry_module_release (module);
2871   ath_mutex_unlock (&pubkeys_registered_lock);
2872
2873   release_mpi_array (keyarr);
2874   gcry_free (keyarr);
2875
2876   return nbits;
2877 }
2878
2879
2880 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
2881    key parameters expressed in a way depending on the algorithm.
2882
2883    ARRAY must either be 20 bytes long or NULL; in the latter case a
2884    newly allocated array of that size is returned, otherwise ARRAY or
2885    NULL is returned to indicate an error which is most likely an
2886    unknown algorithm.  The function accepts public or secret keys. */
2887 unsigned char *
2888 gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
2889 {
2890   gcry_sexp_t list = NULL, l2 = NULL;
2891   gcry_pk_spec_t *pubkey = NULL;
2892   gcry_module_t module = NULL;
2893   pk_extra_spec_t *extraspec;
2894   const char *s;
2895   char *name = NULL;
2896   int idx;
2897   const char *elems;
2898   gcry_md_hd_t md = NULL;
2899   int okay = 0;
2900
2901   REGISTER_DEFAULT_PUBKEYS;
2902
2903   /* Check that the first element is valid. */
2904   list = gcry_sexp_find_token (key, "public-key", 0);
2905   if (! list)
2906     list = gcry_sexp_find_token (key, "private-key", 0);
2907   if (! list)
2908     list = gcry_sexp_find_token (key, "protected-private-key", 0);
2909   if (! list)
2910     list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
2911   if (! list)
2912     return NULL; /* No public- or private-key object. */
2913
2914   l2 = gcry_sexp_cadr (list);
2915   gcry_sexp_release (list);
2916   list = l2;
2917   l2 = NULL;
2918
2919   name = _gcry_sexp_nth_string (list, 0);
2920   if (!name)
2921     goto fail; /* Invalid structure of object. */
2922
2923   ath_mutex_lock (&pubkeys_registered_lock);
2924   module = gcry_pk_lookup_name (name);
2925   ath_mutex_unlock (&pubkeys_registered_lock);
2926
2927   if (!module)
2928     goto fail; /* Unknown algorithm.  */
2929
2930   pubkey = (gcry_pk_spec_t *) module->spec;
2931   extraspec = module->extraspec;
2932
2933   elems = pubkey->elements_grip;
2934   if (!elems)
2935     goto fail; /* No grip parameter.  */
2936
2937   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
2938     goto fail;
2939
2940   if (extraspec && extraspec->comp_keygrip)
2941     {
2942       /* Module specific method to compute a keygrip.  */
2943       if (extraspec->comp_keygrip (md, list))
2944         goto fail;
2945     }
2946   else
2947     {
2948       /* Generic method to compute a keygrip.  */
2949       for (idx = 0, s = elems; *s; s++, idx++)
2950         {
2951           const char *data;
2952           size_t datalen;
2953           char buf[30];
2954
2955           l2 = gcry_sexp_find_token (list, s, 1);
2956           if (! l2)
2957             goto fail;
2958           data = gcry_sexp_nth_data (l2, 1, &datalen);
2959           if (! data)
2960             goto fail;
2961
2962           snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
2963           gcry_md_write (md, buf, strlen (buf));
2964           gcry_md_write (md, data, datalen);
2965           gcry_sexp_release (l2);
2966           l2 = NULL;
2967           gcry_md_write (md, ")", 1);
2968         }
2969     }
2970
2971   if (!array)
2972     {
2973       array = gcry_malloc (20);
2974       if (! array)
2975         goto fail;
2976     }
2977
2978   memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
2979   okay = 1;
2980
2981  fail:
2982   gcry_free (name);
2983   gcry_sexp_release (l2);
2984   gcry_md_close (md);
2985   gcry_sexp_release (list);
2986   return okay? array : NULL;
2987 }
2988
2989
2990 \f
2991 const char *
2992 gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
2993 {
2994   gcry_mpi_t *pkey = NULL;
2995   gcry_sexp_t list = NULL;
2996   gcry_sexp_t l2;
2997   gcry_module_t module = NULL;
2998   pk_extra_spec_t *extraspec;
2999   char *name = NULL;
3000   const char *result = NULL;
3001   int want_private = 1;
3002
3003   if (r_nbits)
3004     *r_nbits = 0;
3005
3006   REGISTER_DEFAULT_PUBKEYS;
3007
3008   if (key)
3009     {
3010       iterator = 0;
3011
3012       /* Check that the first element is valid. */
3013       list = gcry_sexp_find_token (key, "public-key", 0);
3014       if (list)
3015         want_private = 0;
3016       if (!list)
3017         list = gcry_sexp_find_token (key, "private-key", 0);
3018       if (!list)
3019         return NULL; /* No public- or private-key object. */
3020
3021       l2 = gcry_sexp_cadr (list);
3022       gcry_sexp_release (list);
3023       list = l2;
3024       l2 = NULL;
3025
3026       name = _gcry_sexp_nth_string (list, 0);
3027       if (!name)
3028         goto leave; /* Invalid structure of object. */
3029
3030       /* Get the key.  We pass the names of the parameters for
3031          override_elems; this allows to call this function without the
3032          actual public key parameter.  */
3033       if (sexp_to_key (key, want_private, "pabgn", &pkey, &module))
3034         goto leave;
3035     }
3036   else
3037     {
3038       ath_mutex_lock (&pubkeys_registered_lock);
3039       module = gcry_pk_lookup_name ("ecc");
3040       ath_mutex_unlock (&pubkeys_registered_lock);
3041       if (!module)
3042         goto leave;
3043     }
3044
3045   extraspec = module->extraspec;
3046   if (!extraspec || !extraspec->get_curve)
3047     goto leave;
3048
3049   result = extraspec->get_curve (pkey, iterator, r_nbits);
3050
3051  leave:
3052   if (pkey)
3053     {
3054       release_mpi_array (pkey);
3055       gcry_free (pkey);
3056     }
3057   if (module)
3058     {
3059       ath_mutex_lock (&pubkeys_registered_lock);
3060       _gcry_module_release (module);
3061       ath_mutex_unlock (&pubkeys_registered_lock);
3062     }
3063   gcry_free (name);
3064   gcry_sexp_release (list);
3065   return result;
3066 }
3067
3068
3069 \f
3070 gcry_sexp_t
3071 gcry_pk_get_param (int algo, const char *name)
3072 {
3073   gcry_module_t module = NULL;
3074   pk_extra_spec_t *extraspec;
3075   gcry_sexp_t result = NULL;
3076
3077   if (algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH)
3078     return NULL;
3079
3080   REGISTER_DEFAULT_PUBKEYS;
3081
3082   ath_mutex_lock (&pubkeys_registered_lock);
3083   module = gcry_pk_lookup_name ("ecc");
3084   ath_mutex_unlock (&pubkeys_registered_lock);
3085   if (module)
3086     {
3087       extraspec = module->extraspec;
3088       if (extraspec && extraspec->get_curve_param)
3089         result = extraspec->get_curve_param (name);
3090
3091       ath_mutex_lock (&pubkeys_registered_lock);
3092       _gcry_module_release (module);
3093       ath_mutex_unlock (&pubkeys_registered_lock);
3094     }
3095   return result;
3096 }
3097
3098
3099 \f
3100 gcry_error_t
3101 gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
3102 {
3103   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3104
3105   REGISTER_DEFAULT_PUBKEYS;
3106
3107   switch (cmd)
3108     {
3109     case GCRYCTL_DISABLE_ALGO:
3110       /* This one expects a buffer pointing to an integer with the
3111          algo number.  */
3112       if ((! buffer) || (buflen != sizeof (int)))
3113         err = GPG_ERR_INV_ARG;
3114       else
3115         disable_pubkey_algo (*((int *) buffer));
3116       break;
3117
3118     default:
3119       err = GPG_ERR_INV_OP;
3120     }
3121
3122   return gcry_error (err);
3123 }
3124
3125
3126 /* Return information about the given algorithm
3127
3128    WHAT selects the kind of information returned:
3129
3130     GCRYCTL_TEST_ALGO:
3131         Returns 0 when the specified algorithm is available for use.
3132         Buffer must be NULL, nbytes  may have the address of a variable
3133         with the required usage of the algorithm. It may be 0 for don't
3134         care or a combination of the GCRY_PK_USAGE_xxx flags;
3135
3136     GCRYCTL_GET_ALGO_USAGE:
3137         Return the usage flags for the given algo.  An invalid algo
3138         returns 0.  Disabled algos are ignored here because we
3139         only want to know whether the algo is at all capable of
3140         the usage.
3141
3142    Note: Because this function is in most cases used to return an
3143    integer value, we can make it easier for the caller to just look at
3144    the return value.  The caller will in all cases consult the value
3145    and thereby detecting whether a error occurred or not (i.e. while
3146    checking the block size) */
3147 gcry_error_t
3148 gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
3149 {
3150   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3151
3152   switch (what)
3153     {
3154     case GCRYCTL_TEST_ALGO:
3155       {
3156         int use = nbytes ? *nbytes : 0;
3157         if (buffer)
3158           err = GPG_ERR_INV_ARG;
3159         else if (check_pubkey_algo (algorithm, use))
3160           err = GPG_ERR_PUBKEY_ALGO;
3161         break;
3162       }
3163
3164     case GCRYCTL_GET_ALGO_USAGE:
3165       {
3166         gcry_module_t pubkey;
3167         int use = 0;
3168
3169         REGISTER_DEFAULT_PUBKEYS;
3170
3171         ath_mutex_lock (&pubkeys_registered_lock);
3172         pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
3173         if (pubkey)
3174           {
3175             use = ((gcry_pk_spec_t *) pubkey->spec)->use;
3176             _gcry_module_release (pubkey);
3177           }
3178         ath_mutex_unlock (&pubkeys_registered_lock);
3179
3180         /* FIXME? */
3181         *nbytes = use;
3182
3183         break;
3184       }
3185
3186     case GCRYCTL_GET_ALGO_NPKEY:
3187       {
3188         /* FIXME?  */
3189         int npkey = pubkey_get_npkey (algorithm);
3190         *nbytes = npkey;
3191         break;
3192       }
3193     case GCRYCTL_GET_ALGO_NSKEY:
3194       {
3195         /* FIXME?  */
3196         int nskey = pubkey_get_nskey (algorithm);
3197         *nbytes = nskey;
3198         break;
3199       }
3200     case GCRYCTL_GET_ALGO_NSIGN:
3201       {
3202         /* FIXME?  */
3203         int nsign = pubkey_get_nsig (algorithm);
3204         *nbytes = nsign;
3205         break;
3206       }
3207     case GCRYCTL_GET_ALGO_NENCR:
3208       {
3209         /* FIXME?  */
3210         int nencr = pubkey_get_nenc (algorithm);
3211         *nbytes = nencr;
3212         break;
3213       }
3214
3215     default:
3216       err = GPG_ERR_INV_OP;
3217     }
3218
3219   return gcry_error (err);
3220 }
3221
3222
3223 /* Explicitly initialize this module.  */
3224 gcry_err_code_t
3225 _gcry_pk_init (void)
3226 {
3227   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3228
3229   REGISTER_DEFAULT_PUBKEYS;
3230
3231   return err;
3232 }
3233
3234
3235 gcry_err_code_t
3236 _gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
3237 {
3238   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3239   gcry_module_t pubkey;
3240
3241   REGISTER_DEFAULT_PUBKEYS;
3242
3243   ath_mutex_lock (&pubkeys_registered_lock);
3244   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
3245   if (pubkey)
3246     *module = pubkey;
3247   else
3248     err = GPG_ERR_PUBKEY_ALGO;
3249   ath_mutex_unlock (&pubkeys_registered_lock);
3250
3251   return err;
3252 }
3253
3254
3255 void
3256 _gcry_pk_module_release (gcry_module_t module)
3257 {
3258   ath_mutex_lock (&pubkeys_registered_lock);
3259   _gcry_module_release (module);
3260   ath_mutex_unlock (&pubkeys_registered_lock);
3261 }
3262
3263 /* Get a list consisting of the IDs of the loaded pubkey modules.  If
3264    LIST is zero, write the number of loaded pubkey modules to
3265    LIST_LENGTH and return.  If LIST is non-zero, the first
3266    *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
3267    according size.  In case there are less pubkey modules than
3268    *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
3269 gcry_error_t
3270 gcry_pk_list (int *list, int *list_length)
3271 {
3272   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3273
3274   ath_mutex_lock (&pubkeys_registered_lock);
3275   err = _gcry_module_list (pubkeys_registered, list, list_length);
3276   ath_mutex_unlock (&pubkeys_registered_lock);
3277
3278   return err;
3279 }
3280
3281
3282 /* Run the selftests for pubkey algorithm ALGO with optional reporting
3283    function REPORT.  */
3284 gpg_error_t
3285 _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
3286 {
3287   gcry_module_t module = NULL;
3288   pk_extra_spec_t *extraspec = NULL;
3289   gcry_err_code_t ec = 0;
3290
3291   REGISTER_DEFAULT_PUBKEYS;
3292
3293   ath_mutex_lock (&pubkeys_registered_lock);
3294   module = _gcry_module_lookup_id (pubkeys_registered, algo);
3295   if (module && !(module->flags & FLAG_MODULE_DISABLED))
3296     extraspec = module->extraspec;
3297   ath_mutex_unlock (&pubkeys_registered_lock);
3298   if (extraspec && extraspec->selftest)
3299     ec = extraspec->selftest (algo, extended, report);
3300   else
3301     {
3302       ec = GPG_ERR_PUBKEY_ALGO;
3303       if (report)
3304         report ("pubkey", algo, "module",
3305                 module && !(module->flags & FLAG_MODULE_DISABLED)?
3306                 "no selftest available" :
3307                 module? "algorithm disabled" : "algorithm not found");
3308     }
3309
3310   if (module)
3311     {
3312       ath_mutex_lock (&pubkeys_registered_lock);
3313       _gcry_module_release (module);
3314       ath_mutex_unlock (&pubkeys_registered_lock);
3315     }
3316   return gpg_error (ec);
3317 }
3318
3319
3320 /* This function is only used by ac.c!  */
3321 gcry_err_code_t
3322 _gcry_pk_get_elements (int algo, char **enc, char **sig)
3323 {
3324   gcry_module_t pubkey;
3325   gcry_pk_spec_t *spec;
3326   gcry_err_code_t err;
3327   char *enc_cp;
3328   char *sig_cp;
3329
3330   REGISTER_DEFAULT_PUBKEYS;
3331
3332   enc_cp = NULL;
3333   sig_cp = NULL;
3334   spec = NULL;
3335
3336   pubkey = _gcry_module_lookup_id (pubkeys_registered, algo);
3337   if (! pubkey)
3338     {
3339       err = GPG_ERR_INTERNAL;
3340       goto out;
3341     }
3342   spec = pubkey->spec;
3343
3344   if (enc)
3345     {
3346       enc_cp = strdup (spec->elements_enc);
3347       if (! enc_cp)
3348         {
3349           err = gpg_err_code_from_syserror ();
3350           goto out;
3351         }
3352     }
3353
3354   if (sig)
3355     {
3356       sig_cp = strdup (spec->elements_sig);
3357       if (! sig_cp)
3358         {
3359           err = gpg_err_code_from_syserror ();
3360           goto out;
3361         }
3362     }
3363
3364   if (enc)
3365     *enc = enc_cp;
3366   if (sig)
3367     *sig = sig_cp;
3368   err = 0;
3369
3370  out:
3371
3372   _gcry_module_release (pubkey);
3373   if (err)
3374     {
3375       free (enc_cp);
3376       free (sig_cp);
3377     }
3378
3379   return err;
3380 }