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