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