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