pubkey: Move sexp parsing of remaining fucntions 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 the passed MPIs are either unchanged or set to NULL.
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                 {
279                   gcry_mpi_release (*array[idx]);
280                   *array[idx] = NULL;
281                 }
282               return GPG_ERR_NO_OBJ;  /* List element not found.  */
283             }
284           else
285             {
286               if (mpifmt == GCRYMPI_FMT_HEX)
287                 *array[idx] = _gcry_sexp_nth_opaque_mpi (l1, 1);
288               else
289                 *array[idx] = gcry_sexp_nth_mpi (l1, 1, mpifmt);
290               gcry_sexp_release (l1);
291               if (!*array[idx])
292                 {
293                   while (idx--)
294                     {
295                       gcry_mpi_release (*array[idx]);
296                       *array[idx] = NULL;
297                     }
298                   return GPG_ERR_INV_OBJ;  /* Conversion failed.  */
299                 }
300             }
301           idx++;
302         }
303     }
304
305   return 0;
306 }
307
308
309 /* Parse a "sig-val" s-expression and store the inner parameter list at
310    R_PARMS.  ALGO_NAMES is used to verify that the algorithm in
311    "sig-val" is valid.  Returns 0 on success and stores a new list at
312    R_PARMS which must be freed by the caller.  On error R_PARMS is set
313    to NULL and an error code returned.  If R_ECCFLAGS is not NULL flag
314    values are set into it; as of now they are only used with ecc
315    algorithms.  */
316 gpg_err_code_t
317 _gcry_pk_util_preparse_sigval (gcry_sexp_t s_sig, const char **algo_names,
318                                gcry_sexp_t *r_parms, int *r_eccflags)
319 {
320   gpg_err_code_t rc;
321   gcry_sexp_t l1 = NULL;
322   gcry_sexp_t l2 = NULL;
323   char *name = NULL;
324   int i;
325
326   *r_parms = NULL;
327   if (r_eccflags)
328     *r_eccflags = 0;
329
330   /* Extract the signature value.  */
331   l1 = gcry_sexp_find_token (s_sig, "sig-val", 0);
332   if (!l1)
333     {
334       rc = GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
335       goto leave;
336     }
337
338   l2 = gcry_sexp_nth (l1, 1);
339   if (!l2)
340     {
341       rc = GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
342       goto leave;
343     }
344   name = _gcry_sexp_nth_string (l2, 0);
345   if (!name)
346     {
347       rc = GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
348       goto leave;
349     }
350   else if (!strcmp (name, "flags"))
351     {
352       /* Skip a "flags" parameter and look again for the algorithm
353          name.  This is not used but here just for the sake of
354          consistent S-expressions we need to handle it. */
355       gcry_sexp_release (l2);
356       l2 = gcry_sexp_nth (l1, 2);
357       if (!l2)
358         {
359           rc = GPG_ERR_INV_OBJ;
360           goto leave;
361         }
362       gcry_free (name);
363       name = _gcry_sexp_nth_string (l2, 0);
364       if (!name)
365         {
366           rc = GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
367           goto leave;
368         }
369     }
370
371   for (i=0; algo_names[i]; i++)
372     if (!stricmp (name, algo_names[i]))
373       break;
374   if (!algo_names[i])
375     {
376       rc = GPG_ERR_CONFLICT; /* "sig-val" uses an unexpected algo. */
377       goto leave;
378     }
379   if (r_eccflags)
380     {
381       if (!strcmp (name, "eddsa"))
382         *r_eccflags = PUBKEY_FLAG_EDDSA;
383     }
384
385   *r_parms = l2;
386   l2 = NULL;
387   rc = 0;
388
389  leave:
390   gcry_free (name);
391   gcry_sexp_release (l2);
392   gcry_sexp_release (l1);
393   return rc;
394 }
395
396
397 /* Parse a "enc-val" s-expression and store the inner parameter list
398    at R_PARMS.  ALGO_NAMES is used to verify that the algorithm in
399    "enc-val" is valid.  Returns 0 on success and stores a new list at
400    R_PARMS which must be freed by the caller.  On error R_PARMS is set
401    to NULL and an error code returned.  If R_ECCFLAGS is not NULL flag
402    values are set into it; as of now they are only used with ecc
403    algorithms.
404
405      (enc-val
406        [(flags [raw, pkcs1, oaep, no-blinding])]
407        [(hash-algo <algo>)]
408        [(label <label>)]
409         (<algo>
410           (<param_name1> <mpi>)
411           ...
412           (<param_namen> <mpi>)))
413
414    HASH-ALGO and LABEL are specific to OAEP.  CTX will be updated with
415    encoding information.  */
416 gpg_err_code_t
417 _gcry_pk_util_preparse_encval (gcry_sexp_t sexp, const char **algo_names,
418                                gcry_sexp_t *r_parms,
419                                struct pk_encoding_ctx *ctx)
420 {
421   gcry_err_code_t rc = 0;
422   gcry_sexp_t l1 = NULL;
423   gcry_sexp_t l2 = NULL;
424   char *name = NULL;
425   size_t n;
426   int parsed_flags = 0;
427   int i;
428
429   *r_parms = NULL;
430
431   /* Check that the first element is valid.  */
432   l1 = gcry_sexp_find_token (sexp, "enc-val" , 0);
433   if (!l1)
434     {
435       rc = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
436       goto leave;
437     }
438
439   l2 = gcry_sexp_nth (l1, 1);
440   if (!l2)
441     {
442       rc = GPG_ERR_NO_OBJ;  /* No cadr for the data object.  */
443       goto leave;
444     }
445
446   /* Extract identifier of sublist.  */
447   name = _gcry_sexp_nth_string (l2, 0);
448   if (!name)
449     {
450       rc = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
451       goto leave;
452     }
453
454   if (!strcmp (name, "flags"))
455     {
456       /* There is a flags element - process it.  */
457       const char *s;
458
459       for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
460         {
461           s = gcry_sexp_nth_data (l2, i, &n);
462           if (! s)
463             ; /* Not a data element - ignore.  */
464           else if (n == 3 && !memcmp (s, "raw", 3)
465                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
466             ctx->encoding = PUBKEY_ENC_RAW;
467           else if (n == 5 && !memcmp (s, "pkcs1", 5)
468                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
469             ctx->encoding = PUBKEY_ENC_PKCS1;
470           else if (n == 4 && !memcmp (s, "oaep", 4)
471                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
472             ctx->encoding = PUBKEY_ENC_OAEP;
473           else if (n == 3 && !memcmp (s, "pss", 3)
474                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
475             {
476               rc = GPG_ERR_CONFLICT;
477               goto leave;
478             }
479           else if (n == 11 && !memcmp (s, "no-blinding", 11))
480             parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
481           else
482             {
483               rc = GPG_ERR_INV_FLAG;
484               goto leave;
485             }
486         }
487
488       /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
489       if (ctx->encoding == PUBKEY_ENC_OAEP)
490         {
491           /* Get HASH-ALGO. */
492           gcry_sexp_release (l2);
493           l2 = gcry_sexp_find_token (l1, "hash-algo", 0);
494           if (l2)
495             {
496               s = gcry_sexp_nth_data (l2, 1, &n);
497               if (!s)
498                 rc = GPG_ERR_NO_OBJ;
499               else
500                 {
501                   ctx->hash_algo = get_hash_algo (s, n);
502                   if (!ctx->hash_algo)
503                     rc = GPG_ERR_DIGEST_ALGO;
504                 }
505               if (rc)
506                 goto leave;
507             }
508
509           /* Get LABEL. */
510           gcry_sexp_release (l2);
511           l2 = gcry_sexp_find_token (l1, "label", 0);
512           if (l2)
513             {
514               s = gcry_sexp_nth_data (l2, 1, &n);
515               if (!s)
516                 rc = GPG_ERR_NO_OBJ;
517               else if (n > 0)
518                 {
519                   ctx->label = gcry_malloc (n);
520                   if (!ctx->label)
521                     rc = gpg_err_code_from_syserror ();
522                   else
523                     {
524                       memcpy (ctx->label, s, n);
525                       ctx->labellen = n;
526                     }
527                 }
528               if (rc)
529                 goto leave;
530             }
531         }
532
533       /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
534       for (i = 2; (gcry_sexp_release (l2), l2 = gcry_sexp_nth (l1, i)); i++)
535         {
536           s = gcry_sexp_nth_data (l2, 0, &n);
537           if (!(n == 9 && !memcmp (s, "hash-algo", 9))
538               && !(n == 5 && !memcmp (s, "label", 5))
539               && !(n == 15 && !memcmp (s, "random-override", 15)))
540             break;
541         }
542       if (!l2)
543         {
544           rc = GPG_ERR_NO_OBJ; /* No cadr for the data object. */
545           goto leave;
546         }
547
548       /* Extract sublist identifier.  */
549       gcry_free (name);
550       name = _gcry_sexp_nth_string (l2, 0);
551       if (!name)
552         {
553           rc = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
554           goto leave;
555         }
556     }
557   else /* No flags - flag as legacy structure.  */
558     parsed_flags |= PUBKEY_FLAG_LEGACYRESULT;
559
560   for (i=0; algo_names[i]; i++)
561     if (!stricmp (name, algo_names[i]))
562       break;
563   if (!algo_names[i])
564     {
565       rc = GPG_ERR_CONFLICT; /* "enc-val" uses an unexpected algo. */
566       goto leave;
567     }
568
569   *r_parms = l2;
570   l2 = NULL;
571   ctx->flags |= parsed_flags;
572   rc = 0;
573
574  leave:
575   gcry_free (name);
576   gcry_sexp_release (l2);
577   gcry_sexp_release (l1);
578   return rc;
579 }
580
581
582 /* Initialize an encoding context.  */
583 void
584 _gcry_pk_util_init_encoding_ctx (struct pk_encoding_ctx *ctx,
585                                  enum pk_operation op,
586                                  unsigned int nbits)
587 {
588   ctx->op = op;
589   ctx->nbits = nbits;
590   ctx->encoding = PUBKEY_ENC_UNKNOWN;
591   ctx->flags = 0;
592   ctx->hash_algo = GCRY_MD_SHA1;
593   ctx->label = NULL;
594   ctx->labellen = 0;
595   ctx->saltlen = 20;
596   ctx->verify_cmp = NULL;
597   ctx->verify_arg = NULL;
598 }
599
600 /* Free a context initialzied by _gcry_pk_util_init_encoding_ctx.  */
601 void
602 _gcry_pk_util_free_encoding_ctx (struct pk_encoding_ctx *ctx)
603 {
604   gcry_free (ctx->label);
605 }
606
607
608 /* Take the hash value and convert into an MPI, suitable for
609    passing to the low level functions.  We currently support the
610    old style way of passing just a MPI and the modern interface which
611    allows to pass flags so that we can choose between raw and pkcs1
612    padding - may be more padding options later.
613
614    (<mpi>)
615    or
616    (data
617     [(flags [raw, direct, pkcs1, oaep, pss, no-blinding, rfc6979, eddsa])]
618     [(hash <algo> <value>)]
619     [(value <text>)]
620     [(hash-algo <algo>)]
621     [(label <label>)]
622     [(salt-length <length>)]
623     [(random-override <data>)]
624    )
625
626    Either the VALUE or the HASH element must be present for use
627    with signatures.  VALUE is used for encryption.
628
629    HASH-ALGO is specific to OAEP and EDDSA.
630
631    LABEL is specific to OAEP.
632
633    SALT-LENGTH is for PSS.
634
635    RANDOM-OVERRIDE is used to replace random nonces for regression
636    testing.  */
637 gcry_err_code_t
638 _gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
639                            struct pk_encoding_ctx *ctx)
640 {
641   gcry_err_code_t rc = 0;
642   gcry_sexp_t ldata, lhash, lvalue;
643   int i;
644   size_t n;
645   const char *s;
646   int unknown_flag = 0;
647   int parsed_flags = 0;
648   int explicit_raw = 0;
649
650   *ret_mpi = NULL;
651   ldata = gcry_sexp_find_token (input, "data", 0);
652   if (!ldata)
653     { /* assume old style */
654       *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
655       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
656     }
657
658   /* see whether there is a flags object */
659   {
660     gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
661     if (lflags)
662       { /* parse the flags list. */
663         for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
664           {
665             s = gcry_sexp_nth_data (lflags, i, &n);
666             if (!s)
667               ; /* not a data element*/
668             else if (n == 7 && !memcmp (s, "rfc6979", 7))
669               parsed_flags |= PUBKEY_FLAG_RFC6979;
670             else if (n == 5 && !memcmp (s, "eddsa", 5))
671               {
672                 ctx->encoding = PUBKEY_ENC_RAW;
673                 parsed_flags |= PUBKEY_FLAG_EDDSA;
674               }
675             else if ( n == 3 && !memcmp (s, "raw", 3)
676                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
677               {
678                 ctx->encoding = PUBKEY_ENC_RAW;
679                 explicit_raw = 1;
680               }
681             else if ( n == 5 && !memcmp (s, "pkcs1", 5)
682                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
683               {
684                 ctx->encoding = PUBKEY_ENC_PKCS1;
685                 parsed_flags |= PUBKEY_FLAG_FIXEDLEN;
686               }
687             else if ( n == 4 && !memcmp (s, "oaep", 4)
688                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
689               {
690                 ctx->encoding = PUBKEY_ENC_OAEP;
691                 parsed_flags |= PUBKEY_FLAG_FIXEDLEN;
692               }
693             else if ( n == 3 && !memcmp (s, "pss", 3)
694                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
695               {
696                 ctx->encoding = PUBKEY_ENC_PSS;
697                 parsed_flags |= PUBKEY_FLAG_FIXEDLEN;
698               }
699             else if (n == 11 && ! memcmp (s, "no-blinding", 11))
700               parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
701             else
702               unknown_flag = 1;
703           }
704         gcry_sexp_release (lflags);
705       }
706   }
707
708   if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
709     ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
710
711   /* Get HASH or MPI */
712   lhash = gcry_sexp_find_token (ldata, "hash", 0);
713   lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
714
715   if (!(!lhash ^ !lvalue))
716     rc = GPG_ERR_INV_OBJ; /* none or both given */
717   else if (unknown_flag)
718     rc = GPG_ERR_INV_FLAG;
719   else if (ctx->encoding == PUBKEY_ENC_RAW
720            && (parsed_flags & PUBKEY_FLAG_EDDSA))
721     {
722       /* Prepare for EdDSA.  */
723       gcry_sexp_t list;
724       void *value;
725       size_t valuelen;
726
727       if (!lvalue)
728         {
729           rc = GPG_ERR_INV_OBJ;
730           goto leave;
731         }
732       /* Get HASH-ALGO. */
733       list = gcry_sexp_find_token (ldata, "hash-algo", 0);
734       if (list)
735         {
736           s = gcry_sexp_nth_data (list, 1, &n);
737           if (!s)
738             rc = GPG_ERR_NO_OBJ;
739           else
740             {
741               ctx->hash_algo = get_hash_algo (s, n);
742               if (!ctx->hash_algo)
743                 rc = GPG_ERR_DIGEST_ALGO;
744             }
745           gcry_sexp_release (list);
746         }
747       else
748         rc = GPG_ERR_INV_OBJ;
749       if (rc)
750         goto leave;
751
752       /* Get VALUE.  */
753       value = gcry_sexp_nth_buffer (lvalue, 1, &valuelen);
754       if (!value)
755         {
756           /* We assume that a zero length message is meant by
757              "(value)".  This is commonly used by test vectors.  Note
758              that S-expression do not allow zero length items. */
759           valuelen = 0;
760           value = gcry_malloc (1);
761           if (!value)
762             rc = gpg_err_code_from_syserror ();
763         }
764       else if ((valuelen * 8) < valuelen)
765         {
766           gcry_free (value);
767           rc = GPG_ERR_TOO_LARGE;
768         }
769       if (rc)
770         goto leave;
771
772       /* Note that mpi_set_opaque takes ownership of VALUE.  */
773       *ret_mpi = gcry_mpi_set_opaque (NULL, value, valuelen*8);
774     }
775   else if (ctx->encoding == PUBKEY_ENC_RAW && lhash
776            && (explicit_raw || (parsed_flags & PUBKEY_FLAG_RFC6979)))
777     {
778       /* Raw encoding along with a hash element.  This is commonly
779          used for DSA.  For better backward error compatibility we
780          allow this only if either the rfc6979 flag has been given or
781          the raw flags was explicitly given.  */
782       if (gcry_sexp_length (lhash) != 3)
783         rc = GPG_ERR_INV_OBJ;
784       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
785         rc = GPG_ERR_INV_OBJ;
786       else
787         {
788           void *value;
789           size_t valuelen;
790
791           ctx->hash_algo = get_hash_algo (s, n);
792           if (!ctx->hash_algo)
793             rc = GPG_ERR_DIGEST_ALGO;
794           else if (!(value=gcry_sexp_nth_buffer (lhash, 2, &valuelen)))
795             rc = GPG_ERR_INV_OBJ;
796           else if ((valuelen * 8) < valuelen)
797             {
798               gcry_free (value);
799               rc = GPG_ERR_TOO_LARGE;
800             }
801           else
802             *ret_mpi = gcry_mpi_set_opaque (NULL, value, valuelen*8);
803         }
804     }
805   else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
806     {
807       /* RFC6969 may only be used with the a hash value and not the
808          MPI based value.  */
809       if (parsed_flags & PUBKEY_FLAG_RFC6979)
810         {
811           rc = GPG_ERR_CONFLICT;
812           goto leave;
813         }
814
815       /* Get the value */
816       *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
817       if (!*ret_mpi)
818         rc = GPG_ERR_INV_OBJ;
819     }
820   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
821            && ctx->op == PUBKEY_OP_ENCRYPT)
822     {
823       const void * value;
824       size_t valuelen;
825       gcry_sexp_t list;
826       void *random_override = NULL;
827       size_t random_override_len = 0;
828
829       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
830         rc = GPG_ERR_INV_OBJ;
831       else
832         {
833           /* Get optional RANDOM-OVERRIDE.  */
834           list = gcry_sexp_find_token (ldata, "random-override", 0);
835           if (list)
836             {
837               s = gcry_sexp_nth_data (list, 1, &n);
838               if (!s)
839                 rc = GPG_ERR_NO_OBJ;
840               else if (n > 0)
841                 {
842                   random_override = gcry_malloc (n);
843                   if (!random_override)
844                     rc = gpg_err_code_from_syserror ();
845                   else
846                     {
847                       memcpy (random_override, s, n);
848                       random_override_len = n;
849                     }
850                 }
851               gcry_sexp_release (list);
852               if (rc)
853                 goto leave;
854             }
855
856           rc = _gcry_rsa_pkcs1_encode_for_enc (ret_mpi, ctx->nbits,
857                                                value, valuelen,
858                                                random_override,
859                                                random_override_len);
860           gcry_free (random_override);
861         }
862     }
863   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
864            && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
865     {
866       if (gcry_sexp_length (lhash) != 3)
867         rc = GPG_ERR_INV_OBJ;
868       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
869         rc = GPG_ERR_INV_OBJ;
870       else
871         {
872           const void * value;
873           size_t valuelen;
874
875           ctx->hash_algo = get_hash_algo (s, n);
876
877           if (!ctx->hash_algo)
878             rc = GPG_ERR_DIGEST_ALGO;
879           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
880                     || !valuelen )
881             rc = GPG_ERR_INV_OBJ;
882           else
883             rc = _gcry_rsa_pkcs1_encode_for_sig (ret_mpi, ctx->nbits,
884                                                  value, valuelen,
885                                                  ctx->hash_algo);
886         }
887     }
888   else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
889            && ctx->op == PUBKEY_OP_ENCRYPT)
890     {
891       const void * value;
892       size_t valuelen;
893
894       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
895         rc = GPG_ERR_INV_OBJ;
896       else
897         {
898           gcry_sexp_t list;
899           void *random_override = NULL;
900           size_t random_override_len = 0;
901
902           /* Get HASH-ALGO. */
903           list = gcry_sexp_find_token (ldata, "hash-algo", 0);
904           if (list)
905             {
906               s = gcry_sexp_nth_data (list, 1, &n);
907               if (!s)
908                 rc = GPG_ERR_NO_OBJ;
909               else
910                 {
911                   ctx->hash_algo = get_hash_algo (s, n);
912                   if (!ctx->hash_algo)
913                     rc = GPG_ERR_DIGEST_ALGO;
914                 }
915               gcry_sexp_release (list);
916               if (rc)
917                 goto leave;
918             }
919
920           /* Get LABEL. */
921           list = gcry_sexp_find_token (ldata, "label", 0);
922           if (list)
923             {
924               s = gcry_sexp_nth_data (list, 1, &n);
925               if (!s)
926                 rc = GPG_ERR_NO_OBJ;
927               else if (n > 0)
928                 {
929                   ctx->label = gcry_malloc (n);
930                   if (!ctx->label)
931                     rc = gpg_err_code_from_syserror ();
932                   else
933                     {
934                       memcpy (ctx->label, s, n);
935                       ctx->labellen = n;
936                     }
937                 }
938               gcry_sexp_release (list);
939               if (rc)
940                 goto leave;
941             }
942           /* Get optional RANDOM-OVERRIDE.  */
943           list = gcry_sexp_find_token (ldata, "random-override", 0);
944           if (list)
945             {
946               s = gcry_sexp_nth_data (list, 1, &n);
947               if (!s)
948                 rc = GPG_ERR_NO_OBJ;
949               else if (n > 0)
950                 {
951                   random_override = gcry_malloc (n);
952                   if (!random_override)
953                     rc = gpg_err_code_from_syserror ();
954                   else
955                     {
956                       memcpy (random_override, s, n);
957                       random_override_len = n;
958                     }
959                 }
960               gcry_sexp_release (list);
961               if (rc)
962                 goto leave;
963             }
964
965           rc = _gcry_rsa_oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
966                                       value, valuelen,
967                                       ctx->label, ctx->labellen,
968                                       random_override, random_override_len);
969
970           gcry_free (random_override);
971         }
972     }
973   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
974            && ctx->op == PUBKEY_OP_SIGN)
975     {
976       if (gcry_sexp_length (lhash) != 3)
977         rc = GPG_ERR_INV_OBJ;
978       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
979         rc = GPG_ERR_INV_OBJ;
980       else
981         {
982           const void * value;
983           size_t valuelen;
984           void *random_override = NULL;
985           size_t random_override_len = 0;
986
987           ctx->hash_algo = get_hash_algo (s, n);
988
989           if (!ctx->hash_algo)
990             rc = GPG_ERR_DIGEST_ALGO;
991           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
992                     || !valuelen )
993             rc = GPG_ERR_INV_OBJ;
994           else
995             {
996               gcry_sexp_t list;
997
998               /* Get SALT-LENGTH. */
999               list = gcry_sexp_find_token (ldata, "salt-length", 0);
1000               if (list)
1001                 {
1002                   s = gcry_sexp_nth_data (list, 1, &n);
1003                   if (!s)
1004                     {
1005                       rc = GPG_ERR_NO_OBJ;
1006                       goto leave;
1007                     }
1008                   ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
1009                   gcry_sexp_release (list);
1010                 }
1011
1012               /* Get optional RANDOM-OVERRIDE.  */
1013               list = gcry_sexp_find_token (ldata, "random-override", 0);
1014               if (list)
1015                 {
1016                   s = gcry_sexp_nth_data (list, 1, &n);
1017                   if (!s)
1018                     rc = GPG_ERR_NO_OBJ;
1019                   else if (n > 0)
1020                     {
1021                       random_override = gcry_malloc (n);
1022                       if (!random_override)
1023                         rc = gpg_err_code_from_syserror ();
1024                       else
1025                         {
1026                           memcpy (random_override, s, n);
1027                           random_override_len = n;
1028                         }
1029                     }
1030                   gcry_sexp_release (list);
1031                   if (rc)
1032                     goto leave;
1033                 }
1034
1035               /* Encode the data.  (NBITS-1 is due to 8.1.1, step 1.) */
1036               rc = _gcry_rsa_pss_encode (ret_mpi, ctx->nbits - 1,
1037                                          ctx->hash_algo,
1038                                          value, valuelen, ctx->saltlen,
1039                                          random_override, random_override_len);
1040
1041               gcry_free (random_override);
1042             }
1043         }
1044     }
1045   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
1046            && ctx->op == PUBKEY_OP_VERIFY)
1047     {
1048       if (gcry_sexp_length (lhash) != 3)
1049         rc = GPG_ERR_INV_OBJ;
1050       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1051         rc = GPG_ERR_INV_OBJ;
1052       else
1053         {
1054           ctx->hash_algo = get_hash_algo (s, n);
1055
1056           if (!ctx->hash_algo)
1057             rc = GPG_ERR_DIGEST_ALGO;
1058           else
1059             {
1060               *ret_mpi = gcry_sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
1061               if (!*ret_mpi)
1062                 rc = GPG_ERR_INV_OBJ;
1063               ctx->verify_cmp = pss_verify_cmp;
1064               ctx->verify_arg = *ret_mpi;
1065             }
1066         }
1067     }
1068   else
1069     rc = GPG_ERR_CONFLICT;
1070
1071  leave:
1072   gcry_sexp_release (ldata);
1073   gcry_sexp_release (lhash);
1074   gcry_sexp_release (lvalue);
1075
1076   if (!rc)
1077     ctx->flags = parsed_flags;
1078   else
1079     {
1080       gcry_free (ctx->label);
1081       ctx->label = NULL;
1082     }
1083
1084   return rc;
1085 }