Cleanup pk_encoding_ctx 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_open (&hd, algo, 0);
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       gcry_md_reset (hd);
1019       gcry_md_write (hd, seed, seedlen);
1020       gcry_md_write (hd, c, 4);
1021       digest = gcry_md_read (hd, 0);
1022       if (outlen - (p - output) >= dlen)
1023         memcpy (p, digest, dlen);
1024       else
1025         memcpy (p, digest, outlen - (p - output));
1026     }
1027   gcry_md_close (hd);
1028   return GPG_ERR_NO_ERROR;
1029 }
1030
1031 static gcry_err_code_t
1032 oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
1033              const unsigned char *value, size_t valuelen,
1034              const unsigned char *label, size_t labellen)
1035 {
1036   gcry_err_code_t rc = 0;
1037   gcry_error_t err;
1038   unsigned char *frame = NULL;
1039   size_t nframe = (nbits+7) / 8;
1040   unsigned char *dmask, *smask, *p;
1041   size_t dlen;
1042   gcry_md_hd_t hd;
1043   size_t n;
1044
1045   dlen = gcry_md_get_algo_dlen (algo);
1046   if (valuelen > nframe - 2 * dlen - 1 || !nframe)
1047     /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
1048     return GPG_ERR_TOO_SHORT; /* the key is too short */
1049   if ( !(frame = gcry_malloc_secure (nframe)))
1050     return gpg_err_code_from_syserror ();
1051
1052   /* FRAME = 00 || SEED || DB */
1053   memset (frame, 0, nframe);
1054   n = 0;
1055   frame[n++] = 0;
1056   gcry_randomize (&frame[n], dlen, GCRY_STRONG_RANDOM);
1057
1058   n += dlen;
1059   gcry_md_open (&hd, algo, 0);
1060   gcry_md_write (hd, label, labellen);
1061   memcpy (&frame[n], gcry_md_read (hd, 0), dlen);
1062   gcry_md_close (hd);
1063   n = nframe - valuelen - 1;
1064   frame[n++] = 1;
1065   memcpy (&frame[n], value, valuelen);
1066
1067   if ( !(dmask = gcry_malloc_secure (nframe - dlen - 1)))
1068     {
1069       rc = gpg_err_code_from_syserror ();
1070       gcry_free (frame);
1071       return rc;
1072     }
1073   mgf1 (dmask, nframe - dlen - 1, &frame[1], dlen, algo);
1074   for (n = 1 + dlen, p = dmask; n < nframe; n++)
1075     frame[n] ^= *p++;
1076   gcry_free (dmask);
1077   n += valuelen;
1078
1079   if ( !(smask = gcry_malloc_secure (dlen)))
1080     {
1081       rc = gpg_err_code_from_syserror ();
1082       gcry_free (frame);
1083       return rc;
1084     }
1085   mgf1 (smask, dlen, &frame[1 + dlen], nframe - dlen - 1, algo);
1086   for (n = 1, p = smask; n < 1 + dlen; n++)
1087     frame[n] ^= *p++;
1088   gcry_free (smask);
1089   n = nframe;
1090
1091   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
1092   if (err)
1093     rc = gcry_err_code (err);
1094   else if (DBG_CIPHER)
1095     log_mpidump ("OAEP encoded data", *r_result);
1096   gcry_free (frame);
1097
1098   return rc;
1099 }
1100
1101 static gcry_err_code_t
1102 oaep_decode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
1103              gcry_mpi_t value, const unsigned char *label, size_t labellen)
1104 {
1105   gcry_err_code_t rc = 0;
1106   gcry_error_t err;
1107   unsigned char *frame = NULL, *dmask, *smask, *p;
1108   size_t nframe = (nbits+7) / 8;
1109   size_t dlen;
1110   gcry_md_hd_t hd;
1111   size_t n;
1112
1113   if ( !(frame = gcry_malloc_secure (nframe)))
1114     return gpg_err_code_from_syserror ();
1115
1116   err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
1117   if (err)
1118     {
1119       gcry_free (frame);
1120       return gcry_err_code (err);
1121     }
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
1653   *ret_modern = 0;
1654
1655   /* Check that the first element is valid.  */
1656   list = gcry_sexp_find_token (sexp, "enc-val" , 0);
1657   if (!list)
1658     {
1659       err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
1660       goto leave;
1661     }
1662
1663   l2 = gcry_sexp_nth (list, 1);
1664   if (!l2)
1665     {
1666       err = GPG_ERR_NO_OBJ; /* No cdr for the data object.  */
1667       goto leave;
1668     }
1669
1670   /* Extract identifier of sublist.  */
1671   name = _gcry_sexp_nth_string (l2, 0);
1672   if (!name)
1673     {
1674       err = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
1675       goto leave;
1676     }
1677
1678   if (!strcmp (name, "flags"))
1679     {
1680       /* There is a flags element - process it.  */
1681       const char *s;
1682       int i;
1683
1684       *ret_modern = 1;
1685       for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
1686         {
1687           s = gcry_sexp_nth_data (l2, i, &n);
1688           if (! s)
1689             ; /* Not a data element - ignore.  */
1690           else if (n == 3 && !memcmp (s, "raw", 3)
1691                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1692             ctx->encoding = PUBKEY_ENC_RAW;
1693           else if (n == 5 && !memcmp (s, "pkcs1", 5)
1694                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1695             ctx->encoding = PUBKEY_ENC_PKCS1;
1696           else if (n == 4 && !memcmp (s, "oaep", 4)
1697                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1698             ctx->encoding = PUBKEY_ENC_OAEP;
1699           else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1700             parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1701           else
1702             {
1703               err = GPG_ERR_INV_FLAG;
1704               goto leave;
1705             }
1706         }
1707       gcry_sexp_release (l2);
1708
1709       /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
1710       if (ctx->encoding == PUBKEY_ENC_OAEP)
1711         {
1712           /* Get HASH-ALGO. */
1713           l2 = gcry_sexp_find_token (list, "hash-algo", 0);
1714           if (l2)
1715             {
1716               s = gcry_sexp_nth_data (l2, 1, &n);
1717               if (!s)
1718                 err = GPG_ERR_NO_OBJ;
1719               else
1720                 {
1721                   ctx->hash_algo = get_hash_algo (s, n);
1722                   if (!ctx->hash_algo)
1723                     err = GPG_ERR_DIGEST_ALGO;
1724                 }
1725               gcry_sexp_release (l2);
1726               if (err)
1727                 goto leave;
1728             }
1729
1730           /* Get LABEL. */
1731           l2 = gcry_sexp_find_token (list, "label", 0);
1732           if (l2)
1733             {
1734               s = gcry_sexp_nth_data (l2, 1, &n);
1735               if (!s)
1736                 err = GPG_ERR_NO_OBJ;
1737               else if (n > 0)
1738                 {
1739                   ctx->label = gcry_malloc (n);
1740                   if (!ctx->label)
1741                     err = gpg_err_code_from_syserror ();
1742                   else
1743                     {
1744                       memcpy (ctx->label, s, n);
1745                       ctx->labellen = n;
1746                     }
1747                 }
1748               gcry_sexp_release (l2);
1749               if (err)
1750                 goto leave;
1751             }
1752         }
1753
1754       /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
1755       for (i = 2; (l2 = gcry_sexp_nth (list, i)) != NULL; i++)
1756         {
1757           s = gcry_sexp_nth_data (l2, 0, &n);
1758           if (!(n == 9 && !memcmp (s, "hash-algo", 9))
1759               && !(n == 5 && !memcmp (s, "label", 5)))
1760             break;
1761           gcry_sexp_release (l2);
1762         }
1763
1764       if (!l2)
1765         {
1766           err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
1767           goto leave;
1768         }
1769
1770       /* Extract sublist identifier.  */
1771       gcry_free (name);
1772       name = _gcry_sexp_nth_string (l2, 0);
1773       if (!name)
1774         {
1775           err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
1776           goto leave;
1777         }
1778
1779       gcry_sexp_release (list);
1780       list = l2;
1781       l2 = NULL;
1782     }
1783
1784   ath_mutex_lock (&pubkeys_registered_lock);
1785   module = gcry_pk_lookup_name (name);
1786   ath_mutex_unlock (&pubkeys_registered_lock);
1787
1788   if (!module)
1789     {
1790       err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
1791       goto leave;
1792     }
1793   pubkey = (gcry_pk_spec_t *) module->spec;
1794
1795   elems = pubkey->elements_enc;
1796   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
1797   if (!array)
1798     {
1799       err = gpg_err_code_from_syserror ();
1800       goto leave;
1801     }
1802
1803   err = sexp_elements_extract (list, elems, array, NULL);
1804
1805  leave:
1806   gcry_sexp_release (list);
1807   gcry_sexp_release (l2);
1808   gcry_free (name);
1809
1810   if (err)
1811     {
1812       ath_mutex_lock (&pubkeys_registered_lock);
1813       _gcry_module_release (module);
1814       ath_mutex_unlock (&pubkeys_registered_lock);
1815       gcry_free (array);
1816       gcry_free (ctx->label);
1817       ctx->label = NULL;
1818     }
1819   else
1820     {
1821       *retarray = array;
1822       *retalgo = module;
1823       *flags = parsed_flags;
1824     }
1825
1826   return err;
1827 }
1828
1829 /* Take the hash value and convert into an MPI, suitable for
1830    passing to the low level functions.  We currently support the
1831    old style way of passing just a MPI and the modern interface which
1832    allows to pass flags so that we can choose between raw and pkcs1
1833    padding - may be more padding options later.
1834
1835    (<mpi>)
1836    or
1837    (data
1838     [(flags [raw, pkcs1, oaep, no-blinding])]
1839     [(hash <algo> <value>)]
1840     [(value <text>)]
1841     [(hash-algo <algo>)]
1842     [(label <label>)]
1843    )
1844
1845    Either the VALUE or the HASH element must be present for use
1846    with signatures.  VALUE is used for encryption.
1847
1848    HASH-ALGO and LABEL are specific to OAEP.
1849
1850    NBITS is the length of the key in bits.
1851
1852 */
1853 static gcry_err_code_t
1854 sexp_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
1855                   struct pk_encoding_ctx *ctx)
1856 {
1857   gcry_err_code_t rc = 0;
1858   gcry_sexp_t ldata, lhash, lvalue;
1859   int i;
1860   size_t n;
1861   const char *s;
1862   int unknown_flag=0;
1863   int parsed_flags = 0;
1864
1865   *ret_mpi = NULL;
1866   ldata = gcry_sexp_find_token (input, "data", 0);
1867   if (!ldata)
1868     { /* assume old style */
1869       *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
1870       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
1871     }
1872
1873   /* see whether there is a flags object */
1874   {
1875     gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
1876     if (lflags)
1877       { /* parse the flags list. */
1878         for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
1879           {
1880             s = gcry_sexp_nth_data (lflags, i, &n);
1881             if (!s)
1882               ; /* not a data element*/
1883             else if ( n == 3 && !memcmp (s, "raw", 3)
1884                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1885               ctx->encoding = PUBKEY_ENC_RAW;
1886             else if ( n == 5 && !memcmp (s, "pkcs1", 5)
1887                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1888               ctx->encoding = PUBKEY_ENC_PKCS1;
1889             else if ( n == 4 && !memcmp (s, "oaep", 4)
1890                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1891               ctx->encoding = PUBKEY_ENC_OAEP;
1892             else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1893               parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1894             else
1895               unknown_flag = 1;
1896           }
1897         gcry_sexp_release (lflags);
1898       }
1899   }
1900
1901   if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
1902     ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
1903
1904   /* Get HASH or MPI */
1905   lhash = gcry_sexp_find_token (ldata, "hash", 0);
1906   lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
1907
1908   if (!(!lhash ^ !lvalue))
1909     rc = GPG_ERR_INV_OBJ; /* none or both given */
1910   else if (unknown_flag)
1911     rc = GPG_ERR_INV_FLAG;
1912   else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
1913     {
1914       *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
1915       if (!*ret_mpi)
1916         rc = GPG_ERR_INV_OBJ;
1917     }
1918   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
1919            && ctx->op == PUBKEY_OP_ENCRYPT)
1920     {
1921       const void * value;
1922       size_t valuelen;
1923
1924       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1925         rc = GPG_ERR_INV_OBJ;
1926       else
1927         rc = pkcs1_encode_for_encryption (ret_mpi, ctx->nbits, value, valuelen);
1928     }
1929   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
1930            && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
1931     {
1932       if (gcry_sexp_length (lhash) != 3)
1933         rc = GPG_ERR_INV_OBJ;
1934       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1935         rc = GPG_ERR_INV_OBJ;
1936       else
1937         {
1938           const void * value;
1939           size_t valuelen;
1940
1941           ctx->hash_algo = get_hash_algo (s, n);
1942
1943           if (!ctx->hash_algo)
1944             rc = GPG_ERR_DIGEST_ALGO;
1945           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
1946                     || !valuelen )
1947             rc = GPG_ERR_INV_OBJ;
1948           else
1949             rc = pkcs1_encode_for_signature (ret_mpi, ctx->nbits,
1950                                              value, valuelen,
1951                                              ctx->hash_algo);
1952         }
1953     }
1954   else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
1955            && ctx->op == PUBKEY_OP_ENCRYPT)
1956     {
1957       const void * value;
1958       size_t valuelen;
1959
1960       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1961         rc = GPG_ERR_INV_OBJ;
1962       else
1963         {
1964           gcry_sexp_t list;
1965
1966           /* Get HASH-ALGO. */
1967           list = gcry_sexp_find_token (ldata, "hash-algo", 0);
1968           if (list)
1969             {
1970               s = gcry_sexp_nth_data (list, 1, &n);
1971               if (!s)
1972                 rc = GPG_ERR_NO_OBJ;
1973               else
1974                 {
1975                   ctx->hash_algo = get_hash_algo (s, n);
1976                   if (!ctx->hash_algo)
1977                     rc = GPG_ERR_DIGEST_ALGO;
1978                 }
1979               gcry_sexp_release (list);
1980               if (rc)
1981                 goto leave;
1982             }
1983
1984           /* Get LABEL. */
1985           list = gcry_sexp_find_token (ldata, "label", 0);
1986           if (list)
1987             {
1988               s = gcry_sexp_nth_data (list, 1, &n);
1989               if (!s)
1990                 rc = GPG_ERR_NO_OBJ;
1991               else if (n > 0)
1992                 {
1993                   ctx->label = gcry_malloc (n);
1994                   if (!ctx->label)
1995                     rc = gpg_err_code_from_syserror ();
1996                   else
1997                     {
1998                       memcpy (ctx->label, s, n);
1999                       ctx->labellen = n;
2000                     }
2001                 }
2002               gcry_sexp_release (list);
2003               if (rc)
2004                 goto leave;
2005             }
2006
2007           rc = oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
2008                             value, valuelen,
2009                             ctx->label, ctx->labellen);
2010         }
2011     }
2012   else
2013     rc = GPG_ERR_CONFLICT;
2014
2015  leave:
2016   gcry_sexp_release (ldata);
2017   gcry_sexp_release (lhash);
2018   gcry_sexp_release (lvalue);
2019
2020   if (!rc)
2021     ctx->flags = parsed_flags;
2022   else
2023     {
2024       gcry_free (ctx->label);
2025       ctx->label = NULL;
2026     }
2027
2028   return rc;
2029 }
2030
2031 static void
2032 init_encoding_ctx (struct pk_encoding_ctx *ctx, enum pk_operation op,
2033                    unsigned int nbits)
2034 {
2035   ctx->op = op;
2036   ctx->nbits = nbits;
2037   ctx->encoding = PUBKEY_ENC_UNKNOWN;
2038   ctx->flags = 0;
2039   ctx->hash_algo = GCRY_MD_SHA1;
2040   ctx->label = NULL;
2041   ctx->labellen = 0;
2042   ctx->verify_cmp = NULL;
2043   ctx->verify_arg = NULL;
2044 }
2045
2046
2047 /*
2048    Do a PK encrypt operation
2049
2050    Caller has to provide a public key as the SEXP pkey and data as a
2051    SEXP with just one MPI in it. Alternatively S_DATA might be a
2052    complex S-Expression, similar to the one used for signature
2053    verification.  This provides a flag which allows to handle PKCS#1
2054    block type 2 padding.  The function returns a a sexp which may be
2055    passed to to pk_decrypt.
2056
2057    Returns: 0 or an errorcode.
2058
2059    s_data = See comment for sexp_data_to_mpi
2060    s_pkey = <key-as-defined-in-sexp_to_key>
2061    r_ciph = (enc-val
2062                (<algo>
2063                  (<param_name1> <mpi>)
2064                  ...
2065                  (<param_namen> <mpi>)
2066                ))
2067
2068 */
2069 gcry_error_t
2070 gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
2071 {
2072   gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
2073   const char *algo_name, *algo_elems;
2074   struct pk_encoding_ctx ctx;
2075   gcry_err_code_t rc;
2076   gcry_pk_spec_t *pubkey = NULL;
2077   gcry_module_t module = NULL;
2078
2079   *r_ciph = NULL;
2080
2081   REGISTER_DEFAULT_PUBKEYS;
2082
2083   /* Get the key. */
2084   rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module);
2085   if (rc)
2086     goto leave;
2087
2088   gcry_assert (module);
2089   pubkey = (gcry_pk_spec_t *) module->spec;
2090
2091   /* If aliases for the algorithm name exists, take the first one
2092      instead of the regular name to adhere to SPKI conventions.  We
2093      assume that the first alias name is the lowercase version of the
2094      regular one.  This change is required for compatibility with
2095      1.1.12 generated S-expressions. */
2096   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2097   if (!algo_name || !*algo_name)
2098     algo_name = pubkey->name;
2099
2100   algo_elems = pubkey->elements_enc;
2101
2102   /* Get the stuff we want to encrypt. */
2103   init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey));
2104   rc = sexp_data_to_mpi (s_data, &data, &ctx);
2105   if (rc)
2106     goto leave;
2107
2108   /* Now we can encrypt DATA to CIPH. */
2109   ciph = gcry_calloc (strlen (algo_elems) + 1, sizeof (*ciph));
2110   if (!ciph)
2111     {
2112       rc = gpg_err_code_from_syserror ();
2113       goto leave;
2114     }
2115   rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, ctx.flags);
2116   mpi_free (data);
2117   data = NULL;
2118   if (rc)
2119     goto leave;
2120
2121   /* We did it.  Now build the return list */
2122   {
2123     char *string, *p;
2124     int i;
2125     size_t nelem = strlen (algo_elems);
2126     size_t needed = 19 + strlen (algo_name) + (nelem * 5);
2127     void **arg_list;
2128
2129     /* Build the string.  */
2130     string = p = gcry_malloc (needed);
2131     if (!string)
2132       {
2133         rc = gpg_err_code_from_syserror ();
2134         goto leave;
2135       }
2136     p = stpcpy ( p, "(enc-val(" );
2137     p = stpcpy ( p, algo_name );
2138     for (i=0; algo_elems[i]; i++ )
2139       {
2140         *p++ = '(';
2141         *p++ = algo_elems[i];
2142         p = stpcpy ( p, "%m)" );
2143       }
2144     strcpy ( p, "))" );
2145
2146     /* And now the ugly part: We don't have a function to pass an
2147      * array to a format string, so we have to do it this way :-(.  */
2148     /* FIXME: There is now such a format specifier, so we can
2149        change the code to be more clear. */
2150     arg_list = malloc (nelem * sizeof *arg_list);
2151     if (!arg_list)
2152       {
2153         rc = gpg_err_code_from_syserror ();
2154         goto leave;
2155       }
2156
2157     for (i = 0; i < nelem; i++)
2158       arg_list[i] = ciph + i;
2159
2160     rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
2161     free (arg_list);
2162     if (rc)
2163       BUG ();
2164     gcry_free (string);
2165   }
2166
2167  leave:
2168   if (pkey)
2169     {
2170       release_mpi_array (pkey);
2171       gcry_free (pkey);
2172     }
2173
2174   if (ciph)
2175     {
2176       release_mpi_array (ciph);
2177       gcry_free (ciph);
2178     }
2179
2180   if (module)
2181     {
2182       ath_mutex_lock (&pubkeys_registered_lock);
2183       _gcry_module_release (module);
2184       ath_mutex_unlock (&pubkeys_registered_lock);
2185     }
2186
2187   gcry_free (ctx.label);
2188
2189   return gcry_error (rc);
2190 }
2191
2192 /*
2193    Do a PK decrypt operation
2194
2195    Caller has to provide a secret key as the SEXP skey and data in a
2196    format as created by gcry_pk_encrypt.  For historic reasons the
2197    function returns simply an MPI as an S-expression part; this is
2198    deprecated and the new method should be used which returns a real
2199    S-expressionl this is selected by adding at least an empty flags
2200    list to S_DATA.
2201
2202    Returns: 0 or an errorcode.
2203
2204    s_data = (enc-val
2205               [(flags [raw, pkcs1, oaep])]
2206               (<algo>
2207                 (<param_name1> <mpi>)
2208                 ...
2209                 (<param_namen> <mpi>)
2210               ))
2211    s_skey = <key-as-defined-in-sexp_to_key>
2212    r_plain= Either an incomplete S-expression without the parentheses
2213             or if the flags list is used (even if empty) a real S-expression:
2214             (value PLAIN).
2215  */
2216 gcry_error_t
2217 gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
2218 {
2219   gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL, unpad = NULL;
2220   int modern, flags;
2221   struct pk_encoding_ctx ctx;
2222   gcry_err_code_t rc;
2223   gcry_module_t module_enc = NULL, module_key = NULL;
2224
2225   *r_plain = NULL;
2226   ctx.label = NULL;
2227
2228   REGISTER_DEFAULT_PUBKEYS;
2229
2230   rc = sexp_to_key (s_skey, 1, NULL, &skey, &module_key);
2231   if (rc)
2232     goto leave;
2233
2234   init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT, gcry_pk_get_nbits (s_skey));
2235   rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &flags, &ctx);
2236   if (rc)
2237     goto leave;
2238
2239   if (module_key->mod_id != module_enc->mod_id)
2240     {
2241       rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
2242       goto leave;
2243     }
2244
2245   rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
2246   if (rc)
2247     goto leave;
2248
2249   /* Do un-padding if necessary. */
2250   switch (ctx.encoding)
2251     {
2252     case PUBKEY_ENC_PKCS1:
2253       rc = pkcs1_decode_for_encryption (&unpad, gcry_pk_get_nbits (s_skey),
2254                                         plain);
2255       mpi_free (plain);
2256       if (rc)
2257         goto leave;
2258       plain = unpad;
2259       break;
2260     case PUBKEY_ENC_OAEP:
2261       rc = oaep_decode (&unpad, gcry_pk_get_nbits (s_skey), ctx.hash_algo,
2262                         plain, ctx.label, ctx.labellen);
2263       mpi_free (plain);
2264       if (rc)
2265         goto leave;
2266       plain = unpad;
2267       break;
2268     default:
2269       break;
2270     }
2271
2272   if (gcry_sexp_build (r_plain, NULL, modern? "(value %m)" : "%m", plain))
2273     BUG ();
2274
2275  leave:
2276   if (skey)
2277     {
2278       release_mpi_array (skey);
2279       gcry_free (skey);
2280     }
2281
2282   if (plain)
2283     mpi_free (plain);
2284
2285   if (data)
2286     {
2287       release_mpi_array (data);
2288       gcry_free (data);
2289     }
2290
2291   if (module_key || module_enc)
2292     {
2293       ath_mutex_lock (&pubkeys_registered_lock);
2294       if (module_key)
2295         _gcry_module_release (module_key);
2296       if (module_enc)
2297         _gcry_module_release (module_enc);
2298       ath_mutex_unlock (&pubkeys_registered_lock);
2299     }
2300
2301   gcry_free (ctx.label);
2302
2303   return gcry_error (rc);
2304 }
2305
2306
2307
2308 /*
2309    Create a signature.
2310
2311    Caller has to provide a secret key as the SEXP skey and data
2312    expressed as a SEXP list hash with only one element which should
2313    instantly be available as a MPI. Alternatively the structure given
2314    below may be used for S_HASH, it provides the abiliy to pass flags
2315    to the operation; the only flag defined by now is "pkcs1" which
2316    does PKCS#1 block type 1 style padding.
2317
2318    Returns: 0 or an errorcode.
2319             In case of 0 the function returns a new SEXP with the
2320             signature value; the structure of this signature depends on the
2321             other arguments but is always suitable to be passed to
2322             gcry_pk_verify
2323
2324    s_hash = See comment for sexp_data_to_mpi
2325
2326    s_skey = <key-as-defined-in-sexp_to_key>
2327    r_sig  = (sig-val
2328               (<algo>
2329                 (<param_name1> <mpi>)
2330                 ...
2331                 (<param_namen> <mpi>))
2332              [(hash algo)])
2333
2334   Note that (hash algo) in R_SIG is not used.
2335 */
2336 gcry_error_t
2337 gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
2338 {
2339   gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
2340   gcry_pk_spec_t *pubkey = NULL;
2341   gcry_module_t module = NULL;
2342   const char *algo_name, *algo_elems;
2343   struct pk_encoding_ctx ctx;
2344   int i;
2345   gcry_err_code_t rc;
2346
2347   *r_sig = NULL;
2348
2349   REGISTER_DEFAULT_PUBKEYS;
2350
2351   rc = sexp_to_key (s_skey, 1, NULL, &skey, &module);
2352   if (rc)
2353     goto leave;
2354
2355   gcry_assert (module);
2356   pubkey = (gcry_pk_spec_t *) module->spec;
2357   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2358   if (!algo_name || !*algo_name)
2359     algo_name = pubkey->name;
2360
2361   algo_elems = pubkey->elements_sig;
2362
2363   /* Get the stuff we want to sign.  Note that pk_get_nbits does also
2364       work on a private key. */
2365   init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, gcry_pk_get_nbits (s_skey));
2366   rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
2367   if (rc)
2368     goto leave;
2369
2370   result = gcry_calloc (strlen (algo_elems) + 1, sizeof (*result));
2371   if (!result)
2372     {
2373       rc = gpg_err_code_from_syserror ();
2374       goto leave;
2375     }
2376   rc = pubkey_sign (module->mod_id, result, hash, skey);
2377   if (rc)
2378     goto leave;
2379
2380   {
2381     char *string, *p;
2382     size_t nelem, needed = strlen (algo_name) + 20;
2383     void **arg_list;
2384
2385     nelem = strlen (algo_elems);
2386
2387     /* Count elements, so that we can allocate enough space. */
2388     needed += 10 * nelem;
2389
2390     /* Build the string. */
2391     string = p = gcry_malloc (needed);
2392     if (!string)
2393       {
2394         rc = gpg_err_code_from_syserror ();
2395         goto leave;
2396       }
2397     p = stpcpy (p, "(sig-val(");
2398     p = stpcpy (p, algo_name);
2399     for (i = 0; algo_elems[i]; i++)
2400       {
2401         *p++ = '(';
2402         *p++ = algo_elems[i];
2403         p = stpcpy (p, "%m)");
2404       }
2405     strcpy (p, "))");
2406
2407     arg_list = malloc (nelem * sizeof *arg_list);
2408     if (!arg_list)
2409       {
2410         rc = gpg_err_code_from_syserror ();
2411         goto leave;
2412       }
2413
2414     for (i = 0; i < nelem; i++)
2415       arg_list[i] = result + i;
2416
2417     rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
2418     free (arg_list);
2419     if (rc)
2420       BUG ();
2421     gcry_free (string);
2422   }
2423
2424  leave:
2425   if (skey)
2426     {
2427       release_mpi_array (skey);
2428       gcry_free (skey);
2429     }
2430
2431   if (hash)
2432     mpi_free (hash);
2433
2434   if (result)
2435     {
2436       release_mpi_array (result);
2437       gcry_free (result);
2438     }
2439
2440   return gcry_error (rc);
2441 }
2442
2443
2444 /*
2445    Verify a signature.
2446
2447    Caller has to supply the public key pkey, the signature sig and his
2448    hashvalue data.  Public key has to be a standard public key given
2449    as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
2450    must be an S-Exp like the one in sign too.  */
2451 gcry_error_t
2452 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
2453 {
2454   gcry_module_t module_key = NULL, module_sig = NULL;
2455   gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
2456   struct pk_encoding_ctx ctx;
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   /* Get the stuff we want to verify. */
2479   init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY, gcry_pk_get_nbits (s_pkey));
2480   rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
2481   if (rc)
2482     goto leave;
2483
2484   rc = pubkey_verify (module_key->mod_id, hash, sig, pkey,
2485                       ctx.verify_cmp, &ctx);
2486
2487  leave:
2488   if (pkey)
2489     {
2490       release_mpi_array (pkey);
2491       gcry_free (pkey);
2492     }
2493   if (sig)
2494     {
2495       release_mpi_array (sig);
2496       gcry_free (sig);
2497     }
2498   if (hash)
2499     mpi_free (hash);
2500
2501   if (module_key || module_sig)
2502     {
2503       ath_mutex_lock (&pubkeys_registered_lock);
2504       if (module_key)
2505         _gcry_module_release (module_key);
2506       if (module_sig)
2507         _gcry_module_release (module_sig);
2508       ath_mutex_unlock (&pubkeys_registered_lock);
2509     }
2510
2511   return gcry_error (rc);
2512 }
2513
2514
2515 /*
2516    Test a key.
2517
2518    This may be used either for a public or a secret key to see whether
2519    the internal structure is okay.
2520
2521    Returns: 0 or an errorcode.
2522
2523    s_key = <key-as-defined-in-sexp_to_key> */
2524 gcry_error_t
2525 gcry_pk_testkey (gcry_sexp_t s_key)
2526 {
2527   gcry_module_t module = NULL;
2528   gcry_mpi_t *key = NULL;
2529   gcry_err_code_t rc;
2530
2531   REGISTER_DEFAULT_PUBKEYS;
2532
2533   /* Note we currently support only secret key checking. */
2534   rc = sexp_to_key (s_key, 1, NULL, &key, &module);
2535   if (! rc)
2536     {
2537       rc = pubkey_check_secret_key (module->mod_id, key);
2538       release_mpi_array (key);
2539       gcry_free (key);
2540     }
2541   return gcry_error (rc);
2542 }
2543
2544
2545 /*
2546   Create a public key pair and return it in r_key.
2547   How the key is created depends on s_parms:
2548   (genkey
2549    (algo
2550      (parameter_name_1 ....)
2551       ....
2552      (parameter_name_n ....)
2553   ))
2554   The key is returned in a format depending on the
2555   algorithm. Both, private and secret keys are returned
2556   and optionally some additional informatin.
2557   For elgamal we return this structure:
2558   (key-data
2559    (public-key
2560      (elg
2561         (p <mpi>)
2562         (g <mpi>)
2563         (y <mpi>)
2564      )
2565    )
2566    (private-key
2567      (elg
2568         (p <mpi>)
2569         (g <mpi>)
2570         (y <mpi>)
2571         (x <mpi>)
2572      )
2573    )
2574    (misc-key-info
2575       (pm1-factors n1 n2 ... nn)
2576    ))
2577  */
2578 gcry_error_t
2579 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
2580 {
2581   gcry_pk_spec_t *pubkey = NULL;
2582   gcry_module_t module = NULL;
2583   gcry_sexp_t list = NULL;
2584   gcry_sexp_t l2 = NULL;
2585   gcry_sexp_t l3 = NULL;
2586   char *name = NULL;
2587   size_t n;
2588   gcry_err_code_t rc = GPG_ERR_NO_ERROR;
2589   int i, j;
2590   const char *algo_name = NULL;
2591   int algo;
2592   const char *sec_elems = NULL, *pub_elems = NULL;
2593   gcry_mpi_t skey[12];
2594   gcry_mpi_t *factors = NULL;
2595   gcry_sexp_t extrainfo = NULL;
2596   unsigned int nbits = 0;
2597   unsigned long use_e = 0;
2598
2599   skey[0] = NULL;
2600   *r_key = NULL;
2601
2602   REGISTER_DEFAULT_PUBKEYS;
2603
2604   list = gcry_sexp_find_token (s_parms, "genkey", 0);
2605   if (!list)
2606     {
2607       rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
2608       goto leave;
2609     }
2610
2611   l2 = gcry_sexp_cadr (list);
2612   gcry_sexp_release (list);
2613   list = l2;
2614   l2 = NULL;
2615   if (! list)
2616     {
2617       rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
2618       goto leave;
2619     }
2620
2621   name = _gcry_sexp_nth_string (list, 0);
2622   if (!name)
2623     {
2624       rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
2625       goto leave;
2626     }
2627
2628   ath_mutex_lock (&pubkeys_registered_lock);
2629   module = gcry_pk_lookup_name (name);
2630   ath_mutex_unlock (&pubkeys_registered_lock);
2631   gcry_free (name);
2632   name = NULL;
2633   if (!module)
2634     {
2635       rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
2636       goto leave;
2637     }
2638
2639   pubkey = (gcry_pk_spec_t *) module->spec;
2640   algo = module->mod_id;
2641   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2642   if (!algo_name || !*algo_name)
2643     algo_name = pubkey->name;
2644   pub_elems = pubkey->elements_pkey;
2645   sec_elems = pubkey->elements_skey;
2646   if (strlen (sec_elems) >= DIM(skey))
2647     BUG ();
2648
2649   /* Handle the optional rsa-use-e element.  Actually this belong into
2650      the algorithm module but we have this parameter in the public
2651      module API, so we need to parse it right here.  */
2652   l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
2653   if (l2)
2654     {
2655       char buf[50];
2656       const char *s;
2657
2658       s = gcry_sexp_nth_data (l2, 1, &n);
2659       if ( !s || n >= DIM (buf) - 1 )
2660         {
2661           rc = GPG_ERR_INV_OBJ; /* No value or value too large.  */
2662           goto leave;
2663         }
2664       memcpy (buf, s, n);
2665       buf[n] = 0;
2666       use_e = strtoul (buf, NULL, 0);
2667       gcry_sexp_release (l2);
2668       l2 = NULL;
2669     }
2670   else
2671     use_e = 65537; /* Not given, use the value generated by old versions. */
2672
2673
2674   /* Get the "nbits" parameter.  */
2675   l2 = gcry_sexp_find_token (list, "nbits", 0);
2676   if (l2)
2677     {
2678       char buf[50];
2679       const char *s;
2680
2681       s = gcry_sexp_nth_data (l2, 1, &n);
2682       if (!s || n >= DIM (buf) - 1 )
2683         {
2684           rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr.  */
2685           goto leave;
2686         }
2687       memcpy (buf, s, n);
2688       buf[n] = 0;
2689       nbits = (unsigned int)strtoul (buf, NULL, 0);
2690       gcry_sexp_release (l2); l2 = NULL;
2691     }
2692   else
2693     nbits = 0;
2694
2695   /* Pass control to the algorithm module. */
2696   rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey,
2697                         &factors, &extrainfo);
2698   gcry_sexp_release (list); list = NULL;
2699   if (rc)
2700     goto leave;
2701
2702   /* Key generation succeeded: Build an S-expression.  */
2703   {
2704     char *string, *p;
2705     size_t nelem=0, nelem_cp = 0, needed=0;
2706     gcry_mpi_t mpis[30];
2707     int percent_s_idx = -1;
2708
2709     /* Estimate size of format string.  */
2710     nelem = strlen (pub_elems) + strlen (sec_elems);
2711     if (factors)
2712       {
2713         for (i = 0; factors[i]; i++)
2714           nelem++;
2715       }
2716     nelem_cp = nelem;
2717
2718     needed += nelem * 10;
2719     /* (+5 is for EXTRAINFO ("%S")).  */
2720     needed += 2 * strlen (algo_name) + 300 + 5;
2721     if (nelem > DIM (mpis))
2722       BUG ();
2723
2724     /* Build the string. */
2725     nelem = 0;
2726     string = p = gcry_malloc (needed);
2727     if (!string)
2728       {
2729         rc = gpg_err_code_from_syserror ();
2730         goto leave;
2731       }
2732     p = stpcpy (p, "(key-data");
2733     p = stpcpy (p, "(public-key(");
2734     p = stpcpy (p, algo_name);
2735     for(i = 0; pub_elems[i]; i++)
2736       {
2737         *p++ = '(';
2738         *p++ = pub_elems[i];
2739         p = stpcpy (p, "%m)");
2740         mpis[nelem++] = skey[i];
2741       }
2742     if (extrainfo && (algo == GCRY_PK_ECDSA || algo == GCRY_PK_ECDH))
2743       {
2744         /* Very ugly hack to insert the used curve parameter into the
2745            list of public key parameters.  */
2746         percent_s_idx = nelem;
2747         p = stpcpy (p, "%S");
2748       }
2749     p = stpcpy (p, "))");
2750     p = stpcpy (p, "(private-key(");
2751     p = stpcpy (p, algo_name);
2752     for (i = 0; sec_elems[i]; i++)
2753       {
2754         *p++ = '(';
2755         *p++ = sec_elems[i];
2756         p = stpcpy (p, "%m)");
2757         mpis[nelem++] = skey[i];
2758       }
2759     p = stpcpy (p, "))");
2760
2761     /* Hack to make release_mpi_array() work.  */
2762     skey[i] = NULL;
2763
2764     if (extrainfo && percent_s_idx == -1)
2765       {
2766         /* If we have extrainfo we should not have any factors.  */
2767         p = stpcpy (p, "%S");
2768       }
2769     else if (factors && factors[0])
2770       {
2771         p = stpcpy (p, "(misc-key-info(pm1-factors");
2772         for(i = 0; factors[i]; i++)
2773           {
2774             p = stpcpy (p, "%m");
2775             mpis[nelem++] = factors[i];
2776           }
2777         p = stpcpy (p, "))");
2778       }
2779     strcpy (p, ")");
2780     gcry_assert (p - string < needed);
2781
2782     while (nelem < DIM (mpis))
2783       mpis[nelem++] = NULL;
2784
2785     {
2786       int elem_n = strlen (pub_elems) + strlen (sec_elems);
2787       void **arg_list;
2788
2789       /* Allocate one extra for EXTRAINFO ("%S").  */
2790       arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
2791       if (!arg_list)
2792         {
2793           rc = gpg_err_code_from_syserror ();
2794           goto leave;
2795         }
2796       for (i = j = 0; i < elem_n; i++)
2797         {
2798           if (i == percent_s_idx)
2799             arg_list[j++] = &extrainfo;
2800           arg_list[j++] = mpis + i;
2801         }
2802       if (extrainfo && percent_s_idx == -1)
2803         arg_list[j] = &extrainfo;
2804       else if (factors && factors[0])
2805         {
2806           for (; i < nelem_cp; i++)
2807             arg_list[j++] = factors + i - elem_n;
2808         }
2809       rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
2810       gcry_free (arg_list);
2811       if (rc)
2812         BUG ();
2813       gcry_assert (DIM (mpis) == 30); /* Reminder to make sure that
2814                                          the array gets increased if
2815                                          new parameters are added. */
2816     }
2817     gcry_free (string);
2818   }
2819
2820  leave:
2821   gcry_free (name);
2822   gcry_sexp_release (extrainfo);
2823   release_mpi_array (skey);
2824   /* Don't free SKEY itself, it is an stack allocated array. */
2825
2826   if (factors)
2827     {
2828       release_mpi_array ( factors );
2829       gcry_free (factors);
2830     }
2831
2832   gcry_sexp_release (l3);
2833   gcry_sexp_release (l2);
2834   gcry_sexp_release (list);
2835
2836   if (module)
2837     {
2838       ath_mutex_lock (&pubkeys_registered_lock);
2839       _gcry_module_release (module);
2840       ath_mutex_unlock (&pubkeys_registered_lock);
2841     }
2842
2843   return gcry_error (rc);
2844 }
2845
2846
2847 /*
2848    Get the number of nbits from the public key.
2849
2850    Hmmm: Should we have really this function or is it better to have a
2851    more general function to retrieve different properties of the key?  */
2852 unsigned int
2853 gcry_pk_get_nbits (gcry_sexp_t key)
2854 {
2855   gcry_module_t module = NULL;
2856   gcry_pk_spec_t *pubkey;
2857   gcry_mpi_t *keyarr = NULL;
2858   unsigned int nbits = 0;
2859   gcry_err_code_t rc;
2860
2861   REGISTER_DEFAULT_PUBKEYS;
2862
2863   rc = sexp_to_key (key, 0, NULL, &keyarr, &module);
2864   if (rc == GPG_ERR_INV_OBJ)
2865     rc = sexp_to_key (key, 1, NULL, &keyarr, &module);
2866   if (rc)
2867     return 0; /* Error - 0 is a suitable indication for that. */
2868
2869   pubkey = (gcry_pk_spec_t *) module->spec;
2870   nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
2871
2872   ath_mutex_lock (&pubkeys_registered_lock);
2873   _gcry_module_release (module);
2874   ath_mutex_unlock (&pubkeys_registered_lock);
2875
2876   release_mpi_array (keyarr);
2877   gcry_free (keyarr);
2878
2879   return nbits;
2880 }
2881
2882
2883 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
2884    key parameters expressed in a way depending on the algorithm.
2885
2886    ARRAY must either be 20 bytes long or NULL; in the latter case a
2887    newly allocated array of that size is returned, otherwise ARRAY or
2888    NULL is returned to indicate an error which is most likely an
2889    unknown algorithm.  The function accepts public or secret keys. */
2890 unsigned char *
2891 gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
2892 {
2893   gcry_sexp_t list = NULL, l2 = NULL;
2894   gcry_pk_spec_t *pubkey = NULL;
2895   gcry_module_t module = NULL;
2896   pk_extra_spec_t *extraspec;
2897   const char *s;
2898   char *name = NULL;
2899   int idx;
2900   const char *elems;
2901   gcry_md_hd_t md = NULL;
2902   int okay = 0;
2903
2904   REGISTER_DEFAULT_PUBKEYS;
2905
2906   /* Check that the first element is valid. */
2907   list = gcry_sexp_find_token (key, "public-key", 0);
2908   if (! list)
2909     list = gcry_sexp_find_token (key, "private-key", 0);
2910   if (! list)
2911     list = gcry_sexp_find_token (key, "protected-private-key", 0);
2912   if (! list)
2913     list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
2914   if (! list)
2915     return NULL; /* No public- or private-key object. */
2916
2917   l2 = gcry_sexp_cadr (list);
2918   gcry_sexp_release (list);
2919   list = l2;
2920   l2 = NULL;
2921
2922   name = _gcry_sexp_nth_string (list, 0);
2923   if (!name)
2924     goto fail; /* Invalid structure of object. */
2925
2926   ath_mutex_lock (&pubkeys_registered_lock);
2927   module = gcry_pk_lookup_name (name);
2928   ath_mutex_unlock (&pubkeys_registered_lock);
2929
2930   if (!module)
2931     goto fail; /* Unknown algorithm.  */
2932
2933   pubkey = (gcry_pk_spec_t *) module->spec;
2934   extraspec = module->extraspec;
2935
2936   elems = pubkey->elements_grip;
2937   if (!elems)
2938     goto fail; /* No grip parameter.  */
2939
2940   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
2941     goto fail;
2942
2943   if (extraspec && extraspec->comp_keygrip)
2944     {
2945       /* Module specific method to compute a keygrip.  */
2946       if (extraspec->comp_keygrip (md, list))
2947         goto fail;
2948     }
2949   else
2950     {
2951       /* Generic method to compute a keygrip.  */
2952       for (idx = 0, s = elems; *s; s++, idx++)
2953         {
2954           const char *data;
2955           size_t datalen;
2956           char buf[30];
2957
2958           l2 = gcry_sexp_find_token (list, s, 1);
2959           if (! l2)
2960             goto fail;
2961           data = gcry_sexp_nth_data (l2, 1, &datalen);
2962           if (! data)
2963             goto fail;
2964
2965           snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
2966           gcry_md_write (md, buf, strlen (buf));
2967           gcry_md_write (md, data, datalen);
2968           gcry_sexp_release (l2);
2969           l2 = NULL;
2970           gcry_md_write (md, ")", 1);
2971         }
2972     }
2973
2974   if (!array)
2975     {
2976       array = gcry_malloc (20);
2977       if (! array)
2978         goto fail;
2979     }
2980
2981   memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
2982   okay = 1;
2983
2984  fail:
2985   gcry_free (name);
2986   gcry_sexp_release (l2);
2987   gcry_md_close (md);
2988   gcry_sexp_release (list);
2989   return okay? array : NULL;
2990 }
2991
2992
2993 \f
2994 const char *
2995 gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
2996 {
2997   gcry_mpi_t *pkey = NULL;
2998   gcry_sexp_t list = NULL;
2999   gcry_sexp_t l2;
3000   gcry_module_t module = NULL;
3001   pk_extra_spec_t *extraspec;
3002   char *name = NULL;
3003   const char *result = NULL;
3004   int want_private = 1;
3005
3006   if (r_nbits)
3007     *r_nbits = 0;
3008
3009   REGISTER_DEFAULT_PUBKEYS;
3010
3011   if (key)
3012     {
3013       iterator = 0;
3014
3015       /* Check that the first element is valid. */
3016       list = gcry_sexp_find_token (key, "public-key", 0);
3017       if (list)
3018         want_private = 0;
3019       if (!list)
3020         list = gcry_sexp_find_token (key, "private-key", 0);
3021       if (!list)
3022         return NULL; /* No public- or private-key object. */
3023
3024       l2 = gcry_sexp_cadr (list);
3025       gcry_sexp_release (list);
3026       list = l2;
3027       l2 = NULL;
3028
3029       name = _gcry_sexp_nth_string (list, 0);
3030       if (!name)
3031         goto leave; /* Invalid structure of object. */
3032
3033       /* Get the key.  We pass the names of the parameters for
3034          override_elems; this allows to call this function without the
3035          actual public key parameter.  */
3036       if (sexp_to_key (key, want_private, "pabgn", &pkey, &module))
3037         goto leave;
3038     }
3039   else
3040     {
3041       ath_mutex_lock (&pubkeys_registered_lock);
3042       module = gcry_pk_lookup_name ("ecc");
3043       ath_mutex_unlock (&pubkeys_registered_lock);
3044       if (!module)
3045         goto leave;
3046     }
3047
3048   extraspec = module->extraspec;
3049   if (!extraspec || !extraspec->get_curve)
3050     goto leave;
3051
3052   result = extraspec->get_curve (pkey, iterator, r_nbits);
3053
3054  leave:
3055   if (pkey)
3056     {
3057       release_mpi_array (pkey);
3058       gcry_free (pkey);
3059     }
3060   if (module)
3061     {
3062       ath_mutex_lock (&pubkeys_registered_lock);
3063       _gcry_module_release (module);
3064       ath_mutex_unlock (&pubkeys_registered_lock);
3065     }
3066   gcry_free (name);
3067   gcry_sexp_release (list);
3068   return result;
3069 }
3070
3071
3072 \f
3073 gcry_sexp_t
3074 gcry_pk_get_param (int algo, const char *name)
3075 {
3076   gcry_module_t module = NULL;
3077   pk_extra_spec_t *extraspec;
3078   gcry_sexp_t result = NULL;
3079
3080   if (algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH)
3081     return NULL;
3082
3083   REGISTER_DEFAULT_PUBKEYS;
3084
3085   ath_mutex_lock (&pubkeys_registered_lock);
3086   module = gcry_pk_lookup_name ("ecc");
3087   ath_mutex_unlock (&pubkeys_registered_lock);
3088   if (module)
3089     {
3090       extraspec = module->extraspec;
3091       if (extraspec && extraspec->get_curve_param)
3092         result = extraspec->get_curve_param (name);
3093
3094       ath_mutex_lock (&pubkeys_registered_lock);
3095       _gcry_module_release (module);
3096       ath_mutex_unlock (&pubkeys_registered_lock);
3097     }
3098   return result;
3099 }
3100
3101
3102 \f
3103 gcry_error_t
3104 gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
3105 {
3106   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3107
3108   REGISTER_DEFAULT_PUBKEYS;
3109
3110   switch (cmd)
3111     {
3112     case GCRYCTL_DISABLE_ALGO:
3113       /* This one expects a buffer pointing to an integer with the
3114          algo number.  */
3115       if ((! buffer) || (buflen != sizeof (int)))
3116         err = GPG_ERR_INV_ARG;
3117       else
3118         disable_pubkey_algo (*((int *) buffer));
3119       break;
3120
3121     default:
3122       err = GPG_ERR_INV_OP;
3123     }
3124
3125   return gcry_error (err);
3126 }
3127
3128
3129 /* Return information about the given algorithm
3130
3131    WHAT selects the kind of information returned:
3132
3133     GCRYCTL_TEST_ALGO:
3134         Returns 0 when the specified algorithm is available for use.
3135         Buffer must be NULL, nbytes  may have the address of a variable
3136         with the required usage of the algorithm. It may be 0 for don't
3137         care or a combination of the GCRY_PK_USAGE_xxx flags;
3138
3139     GCRYCTL_GET_ALGO_USAGE:
3140         Return the usage flags for the given algo.  An invalid algo
3141         returns 0.  Disabled algos are ignored here because we
3142         only want to know whether the algo is at all capable of
3143         the usage.
3144
3145    Note: Because this function is in most cases used to return an
3146    integer value, we can make it easier for the caller to just look at
3147    the return value.  The caller will in all cases consult the value
3148    and thereby detecting whether a error occurred or not (i.e. while
3149    checking the block size) */
3150 gcry_error_t
3151 gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
3152 {
3153   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3154
3155   switch (what)
3156     {
3157     case GCRYCTL_TEST_ALGO:
3158       {
3159         int use = nbytes ? *nbytes : 0;
3160         if (buffer)
3161           err = GPG_ERR_INV_ARG;
3162         else if (check_pubkey_algo (algorithm, use))
3163           err = GPG_ERR_PUBKEY_ALGO;
3164         break;
3165       }
3166
3167     case GCRYCTL_GET_ALGO_USAGE:
3168       {
3169         gcry_module_t pubkey;
3170         int use = 0;
3171
3172         REGISTER_DEFAULT_PUBKEYS;
3173
3174         ath_mutex_lock (&pubkeys_registered_lock);
3175         pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
3176         if (pubkey)
3177           {
3178             use = ((gcry_pk_spec_t *) pubkey->spec)->use;
3179             _gcry_module_release (pubkey);
3180           }
3181         ath_mutex_unlock (&pubkeys_registered_lock);
3182
3183         /* FIXME? */
3184         *nbytes = use;
3185
3186         break;
3187       }
3188
3189     case GCRYCTL_GET_ALGO_NPKEY:
3190       {
3191         /* FIXME?  */
3192         int npkey = pubkey_get_npkey (algorithm);
3193         *nbytes = npkey;
3194         break;
3195       }
3196     case GCRYCTL_GET_ALGO_NSKEY:
3197       {
3198         /* FIXME?  */
3199         int nskey = pubkey_get_nskey (algorithm);
3200         *nbytes = nskey;
3201         break;
3202       }
3203     case GCRYCTL_GET_ALGO_NSIGN:
3204       {
3205         /* FIXME?  */
3206         int nsign = pubkey_get_nsig (algorithm);
3207         *nbytes = nsign;
3208         break;
3209       }
3210     case GCRYCTL_GET_ALGO_NENCR:
3211       {
3212         /* FIXME?  */
3213         int nencr = pubkey_get_nenc (algorithm);
3214         *nbytes = nencr;
3215         break;
3216       }
3217
3218     default:
3219       err = GPG_ERR_INV_OP;
3220     }
3221
3222   return gcry_error (err);
3223 }
3224
3225
3226 /* Explicitly initialize this module.  */
3227 gcry_err_code_t
3228 _gcry_pk_init (void)
3229 {
3230   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3231
3232   REGISTER_DEFAULT_PUBKEYS;
3233
3234   return err;
3235 }
3236
3237
3238 gcry_err_code_t
3239 _gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
3240 {
3241   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3242   gcry_module_t pubkey;
3243
3244   REGISTER_DEFAULT_PUBKEYS;
3245
3246   ath_mutex_lock (&pubkeys_registered_lock);
3247   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
3248   if (pubkey)
3249     *module = pubkey;
3250   else
3251     err = GPG_ERR_PUBKEY_ALGO;
3252   ath_mutex_unlock (&pubkeys_registered_lock);
3253
3254   return err;
3255 }
3256
3257
3258 void
3259 _gcry_pk_module_release (gcry_module_t module)
3260 {
3261   ath_mutex_lock (&pubkeys_registered_lock);
3262   _gcry_module_release (module);
3263   ath_mutex_unlock (&pubkeys_registered_lock);
3264 }
3265
3266 /* Get a list consisting of the IDs of the loaded pubkey modules.  If
3267    LIST is zero, write the number of loaded pubkey modules to
3268    LIST_LENGTH and return.  If LIST is non-zero, the first
3269    *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
3270    according size.  In case there are less pubkey modules than
3271    *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
3272 gcry_error_t
3273 gcry_pk_list (int *list, int *list_length)
3274 {
3275   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3276
3277   ath_mutex_lock (&pubkeys_registered_lock);
3278   err = _gcry_module_list (pubkeys_registered, list, list_length);
3279   ath_mutex_unlock (&pubkeys_registered_lock);
3280
3281   return err;
3282 }
3283
3284
3285 /* Run the selftests for pubkey algorithm ALGO with optional reporting
3286    function REPORT.  */
3287 gpg_error_t
3288 _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
3289 {
3290   gcry_module_t module = NULL;
3291   pk_extra_spec_t *extraspec = NULL;
3292   gcry_err_code_t ec = 0;
3293
3294   REGISTER_DEFAULT_PUBKEYS;
3295
3296   ath_mutex_lock (&pubkeys_registered_lock);
3297   module = _gcry_module_lookup_id (pubkeys_registered, algo);
3298   if (module && !(module->flags & FLAG_MODULE_DISABLED))
3299     extraspec = module->extraspec;
3300   ath_mutex_unlock (&pubkeys_registered_lock);
3301   if (extraspec && extraspec->selftest)
3302     ec = extraspec->selftest (algo, extended, report);
3303   else
3304     {
3305       ec = GPG_ERR_PUBKEY_ALGO;
3306       if (report)
3307         report ("pubkey", algo, "module",
3308                 module && !(module->flags & FLAG_MODULE_DISABLED)?
3309                 "no selftest available" :
3310                 module? "algorithm disabled" : "algorithm not found");
3311     }
3312
3313   if (module)
3314     {
3315       ath_mutex_lock (&pubkeys_registered_lock);
3316       _gcry_module_release (module);
3317       ath_mutex_unlock (&pubkeys_registered_lock);
3318     }
3319   return gpg_error (ec);
3320 }
3321
3322
3323 /* This function is only used by ac.c!  */
3324 gcry_err_code_t
3325 _gcry_pk_get_elements (int algo, char **enc, char **sig)
3326 {
3327   gcry_module_t pubkey;
3328   gcry_pk_spec_t *spec;
3329   gcry_err_code_t err;
3330   char *enc_cp;
3331   char *sig_cp;
3332
3333   REGISTER_DEFAULT_PUBKEYS;
3334
3335   enc_cp = NULL;
3336   sig_cp = NULL;
3337   spec = NULL;
3338
3339   pubkey = _gcry_module_lookup_id (pubkeys_registered, algo);
3340   if (! pubkey)
3341     {
3342       err = GPG_ERR_INTERNAL;
3343       goto out;
3344     }
3345   spec = pubkey->spec;
3346
3347   if (enc)
3348     {
3349       enc_cp = strdup (spec->elements_enc);
3350       if (! enc_cp)
3351         {
3352           err = gpg_err_code_from_syserror ();
3353           goto out;
3354         }
3355     }
3356
3357   if (sig)
3358     {
3359       sig_cp = strdup (spec->elements_sig);
3360       if (! sig_cp)
3361         {
3362           err = gpg_err_code_from_syserror ();
3363           goto out;
3364         }
3365     }
3366
3367   if (enc)
3368     *enc = enc_cp;
3369   if (sig)
3370     *sig = sig_cp;
3371   err = 0;
3372
3373  out:
3374
3375   _gcry_module_release (pubkey);
3376   if (err)
3377     {
3378       free (enc_cp);
3379       free (sig_cp);
3380     }
3381
3382   return err;
3383 }