pubkey: Support flags list in gcry_pk_genkey.
[libgcrypt.git] / cipher / pubkey-util.c
1 /* pubkey-util.c - Supporting functions for all pubkey modules.
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
27 #include "g10lib.h"
28 #include "mpi.h"
29 #include "cipher.h"
30 #include "pubkey-internal.h"
31
32
33 /* Callback for the pubkey algorithm code to verify PSS signatures.
34    OPAQUE is the data provided by the actual caller.  The meaning of
35    TMP depends on the actual algorithm (but there is only RSA); now
36    for RSA it is the output of running the public key function on the
37    input.  */
38 static int
39 pss_verify_cmp (void *opaque, gcry_mpi_t tmp)
40 {
41   struct pk_encoding_ctx *ctx = opaque;
42   gcry_mpi_t hash = ctx->verify_arg;
43
44   return _gcry_rsa_pss_verify (hash, tmp, ctx->nbits - 1,
45                                ctx->hash_algo, ctx->saltlen);
46 }
47
48
49 /* Parser for a flag list.  On return the encoding is stored at
50    R_ENCODING and the flags are stored at R_FLAGS.  if any of them is
51    not needed, NULL may be passed.  The function returns 0 on success
52    or an error code. */
53 gpg_err_code_t
54 _gcry_pk_util_parse_flaglist (gcry_sexp_t list,
55                               int *r_flags, enum pk_encoding *r_encoding)
56 {
57   gpg_err_code_t rc = 0;
58   const char *s;
59   size_t n;
60   int i;
61   int encoding = PUBKEY_ENC_UNKNOWN;
62   int flags = 0;
63
64   for (i=list?gcry_sexp_length (list)-1:0; i > 0; i--)
65     {
66       s = gcry_sexp_nth_data (list, i, &n);
67       if (!s)
68         ; /* not a data element*/
69       else if (n == 7 && !memcmp (s, "rfc6979", 7))
70         {
71           flags |= PUBKEY_FLAG_RFC6979;
72         }
73       else if (n == 5 && !memcmp (s, "eddsa", 5))
74         {
75           encoding = PUBKEY_ENC_RAW;
76           flags |= PUBKEY_FLAG_EDDSA;
77         }
78       else if (n == 3 && !memcmp (s, "raw", 3)
79                && encoding == PUBKEY_ENC_UNKNOWN)
80         {
81           encoding = PUBKEY_ENC_RAW;
82           flags |= PUBKEY_FLAG_RAW_FLAG; /* Explicitly given.  */
83         }
84       else if (n == 5 && !memcmp (s, "pkcs1", 5)
85                && encoding == PUBKEY_ENC_UNKNOWN)
86         {
87           encoding = PUBKEY_ENC_PKCS1;
88           flags |= PUBKEY_FLAG_FIXEDLEN;
89         }
90       else if (n == 4 && !memcmp (s, "oaep", 4)
91                && encoding == PUBKEY_ENC_UNKNOWN)
92         {
93           encoding = PUBKEY_ENC_OAEP;
94           flags |= PUBKEY_FLAG_FIXEDLEN;
95         }
96       else if (n == 3 && !memcmp (s, "pss", 3)
97                && encoding == PUBKEY_ENC_UNKNOWN)
98         {
99           encoding = PUBKEY_ENC_PSS;
100           flags |= PUBKEY_FLAG_FIXEDLEN;
101         }
102       else if (n == 11 && ! memcmp (s, "no-blinding", 11))
103         flags |= PUBKEY_FLAG_NO_BLINDING;
104       else if (n == 13 && ! memcmp (s, "transient-key", 13))
105         flags |= PUBKEY_FLAG_TRANSIENT_KEY;
106       else if (n == 8 && ! memcmp (s, "use-x931", 8))
107         flags |= PUBKEY_FLAG_USE_X931;
108       else if (n == 11 && ! memcmp (s, "use-fips186", 11))
109         flags |= PUBKEY_FLAG_USE_FIPS186;
110       else if (n == 13 && ! memcmp (s, "use-fips186-2", 13))
111         flags |= PUBKEY_FLAG_USE_FIPS186_2;
112       else
113         rc = GPG_ERR_INV_FLAG;
114     }
115
116   if (r_flags)
117     *r_flags = flags;
118   if (r_encoding)
119     *r_encoding = encoding;
120
121   return rc;
122 }
123
124
125 static int
126 get_hash_algo (const char *s, size_t n)
127 {
128   static const struct { const char *name; int algo; } hashnames[] = {
129     { "sha1",   GCRY_MD_SHA1 },
130     { "md5",    GCRY_MD_MD5 },
131     { "sha256", GCRY_MD_SHA256 },
132     { "ripemd160", GCRY_MD_RMD160 },
133     { "rmd160", GCRY_MD_RMD160 },
134     { "sha384", GCRY_MD_SHA384 },
135     { "sha512", GCRY_MD_SHA512 },
136     { "sha224", GCRY_MD_SHA224 },
137     { "md2",    GCRY_MD_MD2 },
138     { "md4",    GCRY_MD_MD4 },
139     { "tiger",  GCRY_MD_TIGER },
140     { "haval",  GCRY_MD_HAVAL },
141     { NULL, 0 }
142   };
143   int algo;
144   int i;
145
146   for (i=0; hashnames[i].name; i++)
147     {
148       if ( strlen (hashnames[i].name) == n
149            && !memcmp (hashnames[i].name, s, n))
150         break;
151     }
152   if (hashnames[i].name)
153     algo = hashnames[i].algo;
154   else
155     {
156       /* In case of not listed or dynamically allocated hash
157          algorithm we fall back to this somewhat slower
158          method.  Further, it also allows to use OIDs as
159          algorithm names. */
160       char *tmpname;
161
162       tmpname = gcry_malloc (n+1);
163       if (!tmpname)
164         algo = 0;  /* Out of core - silently give up.  */
165       else
166         {
167           memcpy (tmpname, s, n);
168           tmpname[n] = 0;
169           algo = gcry_md_map_name (tmpname);
170           gcry_free (tmpname);
171         }
172     }
173   return algo;
174 }
175
176
177 /* Get the "nbits" parameter from an s-expression of the format:
178  *
179  *   (algo
180  *     (parameter_name_1 ....)
181  *      ....
182  *     (parameter_name_n ....))
183  *
184  * Example:
185  *
186  *   (rsa
187  *     (nbits 4:2048))
188  *
189  * On success the value for nbits is stored at R_NBITS.  If no nbits
190  * parameter is found, the function returns success and stores 0 at
191  * R_NBITS.  For parsing errors the function returns an error code and
192  * stores 0 at R_NBITS.
193  */
194 gpg_err_code_t
195 _gcry_pk_util_get_nbits (gcry_sexp_t list, unsigned int *r_nbits)
196 {
197   char buf[50];
198   const char *s;
199   size_t n;
200
201   *r_nbits = 0;
202
203   list = gcry_sexp_find_token (list, "nbits", 0);
204   if (!list)
205     return 0; /* No NBITS found.  */
206
207   s = gcry_sexp_nth_data (list, 1, &n);
208   if (!s || n >= DIM (buf) - 1 )
209     {
210       /* NBITS given without a cdr.  */
211       gcry_sexp_release (list);
212       return GPG_ERR_INV_OBJ;
213     }
214   memcpy (buf, s, n);
215   buf[n] = 0;
216   *r_nbits = (unsigned int)strtoul (buf, NULL, 0);
217   gcry_sexp_release (list);
218   return 0;
219 }
220
221
222 /* Get the optional "rsa-use-e" parameter from an s-expression of the
223  * format:
224  *
225  *   (algo
226  *     (parameter_name_1 ....)
227  *      ....
228  *     (parameter_name_n ....))
229  *
230  * Example:
231  *
232  *   (rsa
233  *     (nbits 4:2048)
234  *     (rsa-use-e 2:41))
235  *
236  * On success the value for nbits is stored at R_E.  If no rsa-use-e
237  * parameter is found, the function returns success and stores 65537 at
238  * R_E.  For parsing errors the function returns an error code and
239  * stores 0 at R_E.
240  */
241 gpg_err_code_t
242 _gcry_pk_util_get_rsa_use_e (gcry_sexp_t list, unsigned long *r_e)
243 {
244   char buf[50];
245   const char *s;
246   size_t n;
247
248   *r_e = 0;
249
250   list = gcry_sexp_find_token (list, "rsa-use-e", 0);
251   if (!list)
252     {
253       *r_e = 65537; /* Not given, use the value generated by old versions. */
254       return 0;
255     }
256
257   s = gcry_sexp_nth_data (list, 1, &n);
258   if (!s || n >= DIM (buf) - 1 )
259     {
260       /* No value or value too large.  */
261       gcry_sexp_release (list);
262       return GPG_ERR_INV_OBJ;
263     }
264   memcpy (buf, s, n);
265   buf[n] = 0;
266   *r_e = strtoul (buf, NULL, 0);
267   gcry_sexp_release (list);
268   return 0;
269 }
270
271
272 /* Extract MPIs from an s-expression using a list of one letter
273  * parameters.  The names of these parameters are given by the string
274  * LIST.  Some special characters may be given to control the
275  * conversion:
276  *
277  *    + :: Switch to unsigned integer format (default).
278  *    - :: Switch to standard signed format.
279  *    / :: Switch to opaque format.
280  *    ? :: The previous parameter is optional.
281  *
282  * For each parameter name a pointer to an MPI variable is expected
283  * and finally a NULL is expected.  Example:
284  *
285  *   _gcry_pk_util_extract_mpis (key, "n/x+ed", &mpi_n, &mpi_x, &mpi_e, NULL)
286  *
287  * This stores the parameter "N" from KEY as an unsigned MPI into
288  * MPI_N, the parameter "X" as an opaque MPI into MPI_X, and the
289  * parameter "E" again as an unsigned MPI into MPI_E.
290  *
291  * The function returns NULL on success.  On error an error code is
292  * returned and the passed MPIs are either unchanged or set to NULL.
293  */
294 gpg_err_code_t
295 _gcry_pk_util_extract_mpis (gcry_sexp_t sexp, const char *list, ...)
296 {
297   va_list arg_ptr;
298   const char *s;
299   gcry_mpi_t *array[10];
300   int idx;
301   gcry_sexp_t l1;
302   enum gcry_mpi_format mpifmt = GCRYMPI_FMT_USG;
303
304   /* First copy all the args into an array.  This is required so that
305      we are able to release already allocated MPIs if later an error
306      was found.  */
307   va_start (arg_ptr, list) ;
308   for (s=list, idx=0; *s && idx < DIM (array); s++)
309     {
310       if (*s == '+' || *s == '-' || *s == '/' || *s == '?')
311         ;
312       else
313         {
314           array[idx] = va_arg (arg_ptr, gcry_mpi_t *);
315           if (!array[idx])
316             {
317               va_end (arg_ptr);
318               return GPG_ERR_INTERNAL; /* NULL pointer given.  */
319             }
320           idx++;
321         }
322     }
323   if (*s)
324     {
325       va_end (arg_ptr);
326       return GPG_ERR_INTERNAL;  /* Too many list elements.  */
327     }
328   if (va_arg (arg_ptr, gcry_mpi_t *))
329     {
330       va_end (arg_ptr);
331       return GPG_ERR_INTERNAL;  /* Not enough list elemends.  */
332     }
333   va_end (arg_ptr);
334
335   /* Now extract all parameters.  */
336   for (s=list, idx=0; *s; s++)
337     {
338       if (*s == '+')
339         mpifmt = GCRYMPI_FMT_USG;
340       else if (*s == '-')
341         mpifmt = GCRYMPI_FMT_STD;
342       else if (*s == '/')
343         mpifmt = GCRYMPI_FMT_HEX; /* Used to indicate opaque.  */
344       else if (*s == '?')
345         ; /* Only used via lookahead.  */
346       else
347         {
348           l1 = gcry_sexp_find_token (sexp, s, 1);
349           if (!l1 && s[1] == '?')
350             *array[idx] = NULL;       /* Optional element not found.  */
351           else if (!l1)
352             {
353               while (idx--)
354                 {
355                   gcry_mpi_release (*array[idx]);
356                   *array[idx] = NULL;
357                 }
358               return GPG_ERR_NO_OBJ;  /* List element not found.  */
359             }
360           else
361             {
362               if (mpifmt == GCRYMPI_FMT_HEX)
363                 *array[idx] = _gcry_sexp_nth_opaque_mpi (l1, 1);
364               else
365                 *array[idx] = gcry_sexp_nth_mpi (l1, 1, mpifmt);
366               gcry_sexp_release (l1);
367               if (!*array[idx])
368                 {
369                   while (idx--)
370                     {
371                       gcry_mpi_release (*array[idx]);
372                       *array[idx] = NULL;
373                     }
374                   return GPG_ERR_INV_OBJ;  /* Conversion failed.  */
375                 }
376             }
377           idx++;
378         }
379     }
380
381   return 0;
382 }
383
384
385 /* Parse a "sig-val" s-expression and store the inner parameter list at
386    R_PARMS.  ALGO_NAMES is used to verify that the algorithm in
387    "sig-val" is valid.  Returns 0 on success and stores a new list at
388    R_PARMS which must be freed by the caller.  On error R_PARMS is set
389    to NULL and an error code returned.  If R_ECCFLAGS is not NULL flag
390    values are set into it; as of now they are only used with ecc
391    algorithms.  */
392 gpg_err_code_t
393 _gcry_pk_util_preparse_sigval (gcry_sexp_t s_sig, const char **algo_names,
394                                gcry_sexp_t *r_parms, int *r_eccflags)
395 {
396   gpg_err_code_t rc;
397   gcry_sexp_t l1 = NULL;
398   gcry_sexp_t l2 = NULL;
399   char *name = NULL;
400   int i;
401
402   *r_parms = NULL;
403   if (r_eccflags)
404     *r_eccflags = 0;
405
406   /* Extract the signature value.  */
407   l1 = gcry_sexp_find_token (s_sig, "sig-val", 0);
408   if (!l1)
409     {
410       rc = GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
411       goto leave;
412     }
413
414   l2 = gcry_sexp_nth (l1, 1);
415   if (!l2)
416     {
417       rc = GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
418       goto leave;
419     }
420   name = _gcry_sexp_nth_string (l2, 0);
421   if (!name)
422     {
423       rc = GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
424       goto leave;
425     }
426   else if (!strcmp (name, "flags"))
427     {
428       /* Skip a "flags" parameter and look again for the algorithm
429          name.  This is not used but here just for the sake of
430          consistent S-expressions we need to handle it. */
431       gcry_sexp_release (l2);
432       l2 = gcry_sexp_nth (l1, 2);
433       if (!l2)
434         {
435           rc = GPG_ERR_INV_OBJ;
436           goto leave;
437         }
438       gcry_free (name);
439       name = _gcry_sexp_nth_string (l2, 0);
440       if (!name)
441         {
442           rc = GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
443           goto leave;
444         }
445     }
446
447   for (i=0; algo_names[i]; i++)
448     if (!stricmp (name, algo_names[i]))
449       break;
450   if (!algo_names[i])
451     {
452       rc = GPG_ERR_CONFLICT; /* "sig-val" uses an unexpected algo. */
453       goto leave;
454     }
455   if (r_eccflags)
456     {
457       if (!strcmp (name, "eddsa"))
458         *r_eccflags = PUBKEY_FLAG_EDDSA;
459     }
460
461   *r_parms = l2;
462   l2 = NULL;
463   rc = 0;
464
465  leave:
466   gcry_free (name);
467   gcry_sexp_release (l2);
468   gcry_sexp_release (l1);
469   return rc;
470 }
471
472
473 /* Parse a "enc-val" s-expression and store the inner parameter list
474    at R_PARMS.  ALGO_NAMES is used to verify that the algorithm in
475    "enc-val" is valid.  Returns 0 on success and stores a new list at
476    R_PARMS which must be freed by the caller.  On error R_PARMS is set
477    to NULL and an error code returned.  If R_ECCFLAGS is not NULL flag
478    values are set into it; as of now they are only used with ecc
479    algorithms.
480
481      (enc-val
482        [(flags [raw, pkcs1, oaep, no-blinding])]
483        [(hash-algo <algo>)]
484        [(label <label>)]
485         (<algo>
486           (<param_name1> <mpi>)
487           ...
488           (<param_namen> <mpi>)))
489
490    HASH-ALGO and LABEL are specific to OAEP.  CTX will be updated with
491    encoding information.  */
492 gpg_err_code_t
493 _gcry_pk_util_preparse_encval (gcry_sexp_t sexp, const char **algo_names,
494                                gcry_sexp_t *r_parms,
495                                struct pk_encoding_ctx *ctx)
496 {
497   gcry_err_code_t rc = 0;
498   gcry_sexp_t l1 = NULL;
499   gcry_sexp_t l2 = NULL;
500   char *name = NULL;
501   size_t n;
502   int parsed_flags = 0;
503   int i;
504
505   *r_parms = NULL;
506
507   /* Check that the first element is valid.  */
508   l1 = gcry_sexp_find_token (sexp, "enc-val" , 0);
509   if (!l1)
510     {
511       rc = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
512       goto leave;
513     }
514
515   l2 = gcry_sexp_nth (l1, 1);
516   if (!l2)
517     {
518       rc = GPG_ERR_NO_OBJ;  /* No cadr for the data object.  */
519       goto leave;
520     }
521
522   /* Extract identifier of sublist.  */
523   name = _gcry_sexp_nth_string (l2, 0);
524   if (!name)
525     {
526       rc = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
527       goto leave;
528     }
529
530   if (!strcmp (name, "flags"))
531     {
532       const char *s;
533
534       /* There is a flags element - process it.  */
535       rc = _gcry_pk_util_parse_flaglist (l2, &parsed_flags, &ctx->encoding);
536       if (rc)
537         goto leave;
538       if (ctx->encoding == PUBKEY_ENC_PSS)
539         {
540           rc = GPG_ERR_CONFLICT;
541           goto leave;
542         }
543
544       /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
545       if (ctx->encoding == PUBKEY_ENC_OAEP)
546         {
547           /* Get HASH-ALGO. */
548           gcry_sexp_release (l2);
549           l2 = gcry_sexp_find_token (l1, "hash-algo", 0);
550           if (l2)
551             {
552               s = gcry_sexp_nth_data (l2, 1, &n);
553               if (!s)
554                 rc = GPG_ERR_NO_OBJ;
555               else
556                 {
557                   ctx->hash_algo = get_hash_algo (s, n);
558                   if (!ctx->hash_algo)
559                     rc = GPG_ERR_DIGEST_ALGO;
560                 }
561               if (rc)
562                 goto leave;
563             }
564
565           /* Get LABEL. */
566           gcry_sexp_release (l2);
567           l2 = gcry_sexp_find_token (l1, "label", 0);
568           if (l2)
569             {
570               s = gcry_sexp_nth_data (l2, 1, &n);
571               if (!s)
572                 rc = GPG_ERR_NO_OBJ;
573               else if (n > 0)
574                 {
575                   ctx->label = gcry_malloc (n);
576                   if (!ctx->label)
577                     rc = gpg_err_code_from_syserror ();
578                   else
579                     {
580                       memcpy (ctx->label, s, n);
581                       ctx->labellen = n;
582                     }
583                 }
584               if (rc)
585                 goto leave;
586             }
587         }
588
589       /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
590       for (i = 2; (gcry_sexp_release (l2), l2 = gcry_sexp_nth (l1, i)); i++)
591         {
592           s = gcry_sexp_nth_data (l2, 0, &n);
593           if (!(n == 9 && !memcmp (s, "hash-algo", 9))
594               && !(n == 5 && !memcmp (s, "label", 5))
595               && !(n == 15 && !memcmp (s, "random-override", 15)))
596             break;
597         }
598       if (!l2)
599         {
600           rc = GPG_ERR_NO_OBJ; /* No cadr for the data object. */
601           goto leave;
602         }
603
604       /* Extract sublist identifier.  */
605       gcry_free (name);
606       name = _gcry_sexp_nth_string (l2, 0);
607       if (!name)
608         {
609           rc = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
610           goto leave;
611         }
612     }
613   else /* No flags - flag as legacy structure.  */
614     parsed_flags |= PUBKEY_FLAG_LEGACYRESULT;
615
616   for (i=0; algo_names[i]; i++)
617     if (!stricmp (name, algo_names[i]))
618       break;
619   if (!algo_names[i])
620     {
621       rc = GPG_ERR_CONFLICT; /* "enc-val" uses an unexpected algo. */
622       goto leave;
623     }
624
625   *r_parms = l2;
626   l2 = NULL;
627   ctx->flags |= parsed_flags;
628   rc = 0;
629
630  leave:
631   gcry_free (name);
632   gcry_sexp_release (l2);
633   gcry_sexp_release (l1);
634   return rc;
635 }
636
637
638 /* Initialize an encoding context.  */
639 void
640 _gcry_pk_util_init_encoding_ctx (struct pk_encoding_ctx *ctx,
641                                  enum pk_operation op,
642                                  unsigned int nbits)
643 {
644   ctx->op = op;
645   ctx->nbits = nbits;
646   ctx->encoding = PUBKEY_ENC_UNKNOWN;
647   ctx->flags = 0;
648   ctx->hash_algo = GCRY_MD_SHA1;
649   ctx->label = NULL;
650   ctx->labellen = 0;
651   ctx->saltlen = 20;
652   ctx->verify_cmp = NULL;
653   ctx->verify_arg = NULL;
654 }
655
656 /* Free a context initialzied by _gcry_pk_util_init_encoding_ctx.  */
657 void
658 _gcry_pk_util_free_encoding_ctx (struct pk_encoding_ctx *ctx)
659 {
660   gcry_free (ctx->label);
661 }
662
663
664 /* Take the hash value and convert into an MPI, suitable for
665    passing to the low level functions.  We currently support the
666    old style way of passing just a MPI and the modern interface which
667    allows to pass flags so that we can choose between raw and pkcs1
668    padding - may be more padding options later.
669
670    (<mpi>)
671    or
672    (data
673     [(flags [raw, direct, pkcs1, oaep, pss, no-blinding, rfc6979, eddsa])]
674     [(hash <algo> <value>)]
675     [(value <text>)]
676     [(hash-algo <algo>)]
677     [(label <label>)]
678     [(salt-length <length>)]
679     [(random-override <data>)]
680    )
681
682    Either the VALUE or the HASH element must be present for use
683    with signatures.  VALUE is used for encryption.
684
685    HASH-ALGO is specific to OAEP and EDDSA.
686
687    LABEL is specific to OAEP.
688
689    SALT-LENGTH is for PSS.
690
691    RANDOM-OVERRIDE is used to replace random nonces for regression
692    testing.  */
693 gcry_err_code_t
694 _gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
695                            struct pk_encoding_ctx *ctx)
696 {
697   gcry_err_code_t rc = 0;
698   gcry_sexp_t ldata, lhash, lvalue;
699   size_t n;
700   const char *s;
701   int unknown_flag = 0;
702   int parsed_flags = 0;
703
704   *ret_mpi = NULL;
705   ldata = gcry_sexp_find_token (input, "data", 0);
706   if (!ldata)
707     { /* assume old style */
708       *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
709       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
710     }
711
712   /* See whether there is a flags list.  */
713   {
714     gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
715     if (lflags)
716       {
717         if (_gcry_pk_util_parse_flaglist (lflags,
718                                           &parsed_flags, &ctx->encoding))
719           unknown_flag = 1;
720         gcry_sexp_release (lflags);
721       }
722   }
723
724   if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
725     ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
726
727   /* Get HASH or MPI */
728   lhash = gcry_sexp_find_token (ldata, "hash", 0);
729   lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
730
731   if (!(!lhash ^ !lvalue))
732     rc = GPG_ERR_INV_OBJ; /* none or both given */
733   else if (unknown_flag)
734     rc = GPG_ERR_INV_FLAG;
735   else if (ctx->encoding == PUBKEY_ENC_RAW
736            && (parsed_flags & PUBKEY_FLAG_EDDSA))
737     {
738       /* Prepare for EdDSA.  */
739       gcry_sexp_t list;
740       void *value;
741       size_t valuelen;
742
743       if (!lvalue)
744         {
745           rc = GPG_ERR_INV_OBJ;
746           goto leave;
747         }
748       /* Get HASH-ALGO. */
749       list = gcry_sexp_find_token (ldata, "hash-algo", 0);
750       if (list)
751         {
752           s = gcry_sexp_nth_data (list, 1, &n);
753           if (!s)
754             rc = GPG_ERR_NO_OBJ;
755           else
756             {
757               ctx->hash_algo = get_hash_algo (s, n);
758               if (!ctx->hash_algo)
759                 rc = GPG_ERR_DIGEST_ALGO;
760             }
761           gcry_sexp_release (list);
762         }
763       else
764         rc = GPG_ERR_INV_OBJ;
765       if (rc)
766         goto leave;
767
768       /* Get VALUE.  */
769       value = gcry_sexp_nth_buffer (lvalue, 1, &valuelen);
770       if (!value)
771         {
772           /* We assume that a zero length message is meant by
773              "(value)".  This is commonly used by test vectors.  Note
774              that S-expression do not allow zero length items. */
775           valuelen = 0;
776           value = gcry_malloc (1);
777           if (!value)
778             rc = gpg_err_code_from_syserror ();
779         }
780       else if ((valuelen * 8) < valuelen)
781         {
782           gcry_free (value);
783           rc = GPG_ERR_TOO_LARGE;
784         }
785       if (rc)
786         goto leave;
787
788       /* Note that mpi_set_opaque takes ownership of VALUE.  */
789       *ret_mpi = gcry_mpi_set_opaque (NULL, value, valuelen*8);
790     }
791   else if (ctx->encoding == PUBKEY_ENC_RAW && lhash
792            && ((parsed_flags & PUBKEY_FLAG_RAW_FLAG)
793                || (parsed_flags & PUBKEY_FLAG_RFC6979)))
794     {
795       /* Raw encoding along with a hash element.  This is commonly
796          used for DSA.  For better backward error compatibility we
797          allow this only if either the rfc6979 flag has been given or
798          the raw flags was explicitly given.  */
799       if (gcry_sexp_length (lhash) != 3)
800         rc = GPG_ERR_INV_OBJ;
801       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
802         rc = GPG_ERR_INV_OBJ;
803       else
804         {
805           void *value;
806           size_t valuelen;
807
808           ctx->hash_algo = get_hash_algo (s, n);
809           if (!ctx->hash_algo)
810             rc = GPG_ERR_DIGEST_ALGO;
811           else if (!(value=gcry_sexp_nth_buffer (lhash, 2, &valuelen)))
812             rc = GPG_ERR_INV_OBJ;
813           else if ((valuelen * 8) < valuelen)
814             {
815               gcry_free (value);
816               rc = GPG_ERR_TOO_LARGE;
817             }
818           else
819             *ret_mpi = gcry_mpi_set_opaque (NULL, value, valuelen*8);
820         }
821     }
822   else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
823     {
824       /* RFC6969 may only be used with the a hash value and not the
825          MPI based value.  */
826       if (parsed_flags & PUBKEY_FLAG_RFC6979)
827         {
828           rc = GPG_ERR_CONFLICT;
829           goto leave;
830         }
831
832       /* Get the value */
833       *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
834       if (!*ret_mpi)
835         rc = GPG_ERR_INV_OBJ;
836     }
837   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
838            && ctx->op == PUBKEY_OP_ENCRYPT)
839     {
840       const void * value;
841       size_t valuelen;
842       gcry_sexp_t list;
843       void *random_override = NULL;
844       size_t random_override_len = 0;
845
846       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
847         rc = GPG_ERR_INV_OBJ;
848       else
849         {
850           /* Get optional RANDOM-OVERRIDE.  */
851           list = gcry_sexp_find_token (ldata, "random-override", 0);
852           if (list)
853             {
854               s = gcry_sexp_nth_data (list, 1, &n);
855               if (!s)
856                 rc = GPG_ERR_NO_OBJ;
857               else if (n > 0)
858                 {
859                   random_override = gcry_malloc (n);
860                   if (!random_override)
861                     rc = gpg_err_code_from_syserror ();
862                   else
863                     {
864                       memcpy (random_override, s, n);
865                       random_override_len = n;
866                     }
867                 }
868               gcry_sexp_release (list);
869               if (rc)
870                 goto leave;
871             }
872
873           rc = _gcry_rsa_pkcs1_encode_for_enc (ret_mpi, ctx->nbits,
874                                                value, valuelen,
875                                                random_override,
876                                                random_override_len);
877           gcry_free (random_override);
878         }
879     }
880   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
881            && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
882     {
883       if (gcry_sexp_length (lhash) != 3)
884         rc = GPG_ERR_INV_OBJ;
885       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
886         rc = GPG_ERR_INV_OBJ;
887       else
888         {
889           const void * value;
890           size_t valuelen;
891
892           ctx->hash_algo = get_hash_algo (s, n);
893
894           if (!ctx->hash_algo)
895             rc = GPG_ERR_DIGEST_ALGO;
896           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
897                     || !valuelen )
898             rc = GPG_ERR_INV_OBJ;
899           else
900             rc = _gcry_rsa_pkcs1_encode_for_sig (ret_mpi, ctx->nbits,
901                                                  value, valuelen,
902                                                  ctx->hash_algo);
903         }
904     }
905   else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
906            && ctx->op == PUBKEY_OP_ENCRYPT)
907     {
908       const void * value;
909       size_t valuelen;
910
911       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
912         rc = GPG_ERR_INV_OBJ;
913       else
914         {
915           gcry_sexp_t list;
916           void *random_override = NULL;
917           size_t random_override_len = 0;
918
919           /* Get HASH-ALGO. */
920           list = gcry_sexp_find_token (ldata, "hash-algo", 0);
921           if (list)
922             {
923               s = gcry_sexp_nth_data (list, 1, &n);
924               if (!s)
925                 rc = GPG_ERR_NO_OBJ;
926               else
927                 {
928                   ctx->hash_algo = get_hash_algo (s, n);
929                   if (!ctx->hash_algo)
930                     rc = GPG_ERR_DIGEST_ALGO;
931                 }
932               gcry_sexp_release (list);
933               if (rc)
934                 goto leave;
935             }
936
937           /* Get LABEL. */
938           list = gcry_sexp_find_token (ldata, "label", 0);
939           if (list)
940             {
941               s = gcry_sexp_nth_data (list, 1, &n);
942               if (!s)
943                 rc = GPG_ERR_NO_OBJ;
944               else if (n > 0)
945                 {
946                   ctx->label = gcry_malloc (n);
947                   if (!ctx->label)
948                     rc = gpg_err_code_from_syserror ();
949                   else
950                     {
951                       memcpy (ctx->label, s, n);
952                       ctx->labellen = n;
953                     }
954                 }
955               gcry_sexp_release (list);
956               if (rc)
957                 goto leave;
958             }
959           /* Get optional RANDOM-OVERRIDE.  */
960           list = gcry_sexp_find_token (ldata, "random-override", 0);
961           if (list)
962             {
963               s = gcry_sexp_nth_data (list, 1, &n);
964               if (!s)
965                 rc = GPG_ERR_NO_OBJ;
966               else if (n > 0)
967                 {
968                   random_override = gcry_malloc (n);
969                   if (!random_override)
970                     rc = gpg_err_code_from_syserror ();
971                   else
972                     {
973                       memcpy (random_override, s, n);
974                       random_override_len = n;
975                     }
976                 }
977               gcry_sexp_release (list);
978               if (rc)
979                 goto leave;
980             }
981
982           rc = _gcry_rsa_oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
983                                       value, valuelen,
984                                       ctx->label, ctx->labellen,
985                                       random_override, random_override_len);
986
987           gcry_free (random_override);
988         }
989     }
990   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
991            && ctx->op == PUBKEY_OP_SIGN)
992     {
993       if (gcry_sexp_length (lhash) != 3)
994         rc = GPG_ERR_INV_OBJ;
995       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
996         rc = GPG_ERR_INV_OBJ;
997       else
998         {
999           const void * value;
1000           size_t valuelen;
1001           void *random_override = NULL;
1002           size_t random_override_len = 0;
1003
1004           ctx->hash_algo = get_hash_algo (s, n);
1005
1006           if (!ctx->hash_algo)
1007             rc = GPG_ERR_DIGEST_ALGO;
1008           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
1009                     || !valuelen )
1010             rc = GPG_ERR_INV_OBJ;
1011           else
1012             {
1013               gcry_sexp_t list;
1014
1015               /* Get SALT-LENGTH. */
1016               list = gcry_sexp_find_token (ldata, "salt-length", 0);
1017               if (list)
1018                 {
1019                   s = gcry_sexp_nth_data (list, 1, &n);
1020                   if (!s)
1021                     {
1022                       rc = GPG_ERR_NO_OBJ;
1023                       goto leave;
1024                     }
1025                   ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
1026                   gcry_sexp_release (list);
1027                 }
1028
1029               /* Get optional RANDOM-OVERRIDE.  */
1030               list = gcry_sexp_find_token (ldata, "random-override", 0);
1031               if (list)
1032                 {
1033                   s = gcry_sexp_nth_data (list, 1, &n);
1034                   if (!s)
1035                     rc = GPG_ERR_NO_OBJ;
1036                   else if (n > 0)
1037                     {
1038                       random_override = gcry_malloc (n);
1039                       if (!random_override)
1040                         rc = gpg_err_code_from_syserror ();
1041                       else
1042                         {
1043                           memcpy (random_override, s, n);
1044                           random_override_len = n;
1045                         }
1046                     }
1047                   gcry_sexp_release (list);
1048                   if (rc)
1049                     goto leave;
1050                 }
1051
1052               /* Encode the data.  (NBITS-1 is due to 8.1.1, step 1.) */
1053               rc = _gcry_rsa_pss_encode (ret_mpi, ctx->nbits - 1,
1054                                          ctx->hash_algo,
1055                                          value, valuelen, ctx->saltlen,
1056                                          random_override, random_override_len);
1057
1058               gcry_free (random_override);
1059             }
1060         }
1061     }
1062   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
1063            && ctx->op == PUBKEY_OP_VERIFY)
1064     {
1065       if (gcry_sexp_length (lhash) != 3)
1066         rc = GPG_ERR_INV_OBJ;
1067       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1068         rc = GPG_ERR_INV_OBJ;
1069       else
1070         {
1071           ctx->hash_algo = get_hash_algo (s, n);
1072
1073           if (!ctx->hash_algo)
1074             rc = GPG_ERR_DIGEST_ALGO;
1075           else
1076             {
1077               *ret_mpi = gcry_sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
1078               if (!*ret_mpi)
1079                 rc = GPG_ERR_INV_OBJ;
1080               ctx->verify_cmp = pss_verify_cmp;
1081               ctx->verify_arg = *ret_mpi;
1082             }
1083         }
1084     }
1085   else
1086     rc = GPG_ERR_CONFLICT;
1087
1088  leave:
1089   gcry_sexp_release (ldata);
1090   gcry_sexp_release (lhash);
1091   gcry_sexp_release (lvalue);
1092
1093   if (!rc)
1094     ctx->flags = parsed_flags;
1095   else
1096     {
1097       gcry_free (ctx->label);
1098       ctx->label = NULL;
1099     }
1100
1101   return rc;
1102 }