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