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