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