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