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
6 * This file is part of Libgcrypt.
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.
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.
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/>.
30 #include "pubkey-internal.h"
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
39 pss_verify_cmp (void *opaque, gcry_mpi_t tmp)
41 struct pk_encoding_ctx *ctx = opaque;
42 gcry_mpi_t hash = ctx->verify_arg;
44 return _gcry_rsa_pss_verify (hash, tmp, ctx->nbits - 1,
45 ctx->hash_algo, ctx->saltlen);
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
54 _gcry_pk_util_parse_flaglist (gcry_sexp_t list,
55 int *r_flags, enum pk_encoding *r_encoding)
57 gpg_err_code_t rc = 0;
61 int encoding = PUBKEY_ENC_UNKNOWN;
65 for (i = list ? sexp_length (list)-1 : 0; i > 0; i--)
67 s = sexp_nth_data (list, i, &n);
69 continue; /* Not a data element. */
74 if (!memcmp (s, "pss", 3) && encoding == PUBKEY_ENC_UNKNOWN)
76 encoding = PUBKEY_ENC_PSS;
77 flags |= PUBKEY_FLAG_FIXEDLEN;
79 else if (!memcmp (s, "raw", 3) && encoding == PUBKEY_ENC_UNKNOWN)
81 encoding = PUBKEY_ENC_RAW;
82 flags |= PUBKEY_FLAG_RAW_FLAG; /* Explicitly given. */
85 rc = GPG_ERR_INV_FLAG;
89 if (!memcmp (s, "comp", 4))
90 flags |= PUBKEY_FLAG_COMP;
91 else if (!memcmp (s, "oaep", 4) && encoding == PUBKEY_ENC_UNKNOWN)
93 encoding = PUBKEY_ENC_OAEP;
94 flags |= PUBKEY_FLAG_FIXEDLEN;
96 else if (!memcmp (s, "gost", 4))
98 encoding = PUBKEY_ENC_RAW;
99 flags |= PUBKEY_FLAG_GOST;
101 else if (!igninvflag)
102 rc = GPG_ERR_INV_FLAG;
106 if (!memcmp (s, "eddsa", 5))
108 encoding = PUBKEY_ENC_RAW;
109 flags |= PUBKEY_FLAG_EDDSA;
111 else if (!memcmp (s, "pkcs1", 5) && encoding == PUBKEY_ENC_UNKNOWN)
113 encoding = PUBKEY_ENC_PKCS1;
114 flags |= PUBKEY_FLAG_FIXEDLEN;
116 else if (!memcmp (s, "param", 5))
117 flags |= PUBKEY_FLAG_PARAM;
118 else if (!igninvflag)
119 rc = GPG_ERR_INV_FLAG;
123 if (!memcmp (s, "nocomp", 6))
124 flags |= PUBKEY_FLAG_NOCOMP;
125 else if (!igninvflag)
126 rc = GPG_ERR_INV_FLAG;
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;
139 if (!memcmp (s, "use-x931", 8))
140 flags |= PUBKEY_FLAG_USE_X931;
141 else if (!igninvflag)
142 rc = GPG_ERR_INV_FLAG;
146 if (!memcmp (s, "igninvflag", 10))
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;
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;
170 rc = GPG_ERR_INV_FLAG;
178 *r_encoding = encoding;
185 get_hash_algo (const char *s, size_t n)
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 },
205 for (i=0; hashnames[i].name; i++)
207 if ( strlen (hashnames[i].name) == n
208 && !memcmp (hashnames[i].name, s, n))
211 if (hashnames[i].name)
212 algo = hashnames[i].algo;
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
221 tmpname = xtrymalloc (n+1);
223 algo = 0; /* Out of core - silently give up. */
226 memcpy (tmpname, s, n);
228 algo = _gcry_md_map_name (tmpname);
236 /* Get the "nbits" parameter from an s-expression of the format:
239 * (parameter_name_1 ....)
241 * (parameter_name_n ....))
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.
254 _gcry_pk_util_get_nbits (gcry_sexp_t list, unsigned int *r_nbits)
262 list = sexp_find_token (list, "nbits", 0);
264 return 0; /* No NBITS found. */
266 s = sexp_nth_data (list, 1, &n);
267 if (!s || n >= DIM (buf) - 1 )
269 /* NBITS given without a cdr. */
271 return GPG_ERR_INV_OBJ;
275 *r_nbits = (unsigned int)strtoul (buf, NULL, 0);
281 /* Get the optional "rsa-use-e" parameter from an s-expression of the
285 * (parameter_name_1 ....)
287 * (parameter_name_n ....))
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
301 _gcry_pk_util_get_rsa_use_e (gcry_sexp_t list, unsigned long *r_e)
309 list = sexp_find_token (list, "rsa-use-e", 0);
312 *r_e = 65537; /* Not given, use the value generated by old versions. */
316 s = sexp_nth_data (list, 1, &n);
317 if (!s || n >= DIM (buf) - 1 )
319 /* No value or value too large. */
321 return GPG_ERR_INV_OBJ;
325 *r_e = strtoul (buf, NULL, 0);
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
339 _gcry_pk_util_preparse_sigval (gcry_sexp_t s_sig, const char **algo_names,
340 gcry_sexp_t *r_parms, int *r_eccflags)
343 gcry_sexp_t l1 = NULL;
344 gcry_sexp_t l2 = NULL;
352 /* Extract the signature value. */
353 l1 = sexp_find_token (s_sig, "sig-val", 0);
356 rc = GPG_ERR_INV_OBJ; /* Does not contain a signature value object. */
360 l2 = sexp_nth (l1, 1);
363 rc = GPG_ERR_NO_OBJ; /* No cadr for the sig object. */
366 name = sexp_nth_string (l2, 0);
369 rc = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
372 else if (!strcmp (name, "flags"))
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. */
378 l2 = sexp_nth (l1, 2);
381 rc = GPG_ERR_INV_OBJ;
385 name = sexp_nth_string (l2, 0);
388 rc = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
393 for (i=0; algo_names[i]; i++)
394 if (!stricmp (name, algo_names[i]))
398 rc = GPG_ERR_CONFLICT; /* "sig-val" uses an unexpected algo. */
403 if (!strcmp (name, "eddsa"))
404 *r_eccflags = PUBKEY_FLAG_EDDSA;
405 if (!strcmp (name, "gost"))
406 *r_eccflags = PUBKEY_FLAG_GOST;
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
430 [(flags [raw, pkcs1, oaep, no-blinding])]
434 (<param_name1> <mpi>)
436 (<param_namen> <mpi>)))
438 HASH-ALGO and LABEL are specific to OAEP. CTX will be updated with
439 encoding information. */
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)
445 gcry_err_code_t rc = 0;
446 gcry_sexp_t l1 = NULL;
447 gcry_sexp_t l2 = NULL;
450 int parsed_flags = 0;
455 /* Check that the first element is valid. */
456 l1 = sexp_find_token (sexp, "enc-val" , 0);
459 rc = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object. */
463 l2 = sexp_nth (l1, 1);
466 rc = GPG_ERR_NO_OBJ; /* No cadr for the data object. */
470 /* Extract identifier of sublist. */
471 name = sexp_nth_string (l2, 0);
474 rc = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
478 if (!strcmp (name, "flags"))
482 /* There is a flags element - process it. */
483 rc = _gcry_pk_util_parse_flaglist (l2, &parsed_flags, &ctx->encoding);
486 if (ctx->encoding == PUBKEY_ENC_PSS)
488 rc = GPG_ERR_CONFLICT;
492 /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
493 if (ctx->encoding == PUBKEY_ENC_OAEP)
497 l2 = sexp_find_token (l1, "hash-algo", 0);
500 s = sexp_nth_data (l2, 1, &n);
505 ctx->hash_algo = get_hash_algo (s, n);
507 rc = GPG_ERR_DIGEST_ALGO;
515 l2 = sexp_find_token (l1, "label", 0);
518 s = sexp_nth_data (l2, 1, &n);
523 ctx->label = xtrymalloc (n);
525 rc = gpg_err_code_from_syserror ();
528 memcpy (ctx->label, s, n);
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++)
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)))
548 rc = GPG_ERR_NO_OBJ; /* No cadr for the data object. */
552 /* Extract sublist identifier. */
554 name = sexp_nth_string (l2, 0);
557 rc = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
561 else /* No flags - flag as legacy structure. */
562 parsed_flags |= PUBKEY_FLAG_LEGACYRESULT;
564 for (i=0; algo_names[i]; i++)
565 if (!stricmp (name, algo_names[i]))
569 rc = GPG_ERR_CONFLICT; /* "enc-val" uses an unexpected algo. */
575 ctx->flags |= parsed_flags;
586 /* Initialize an encoding context. */
588 _gcry_pk_util_init_encoding_ctx (struct pk_encoding_ctx *ctx,
589 enum pk_operation op,
594 ctx->encoding = PUBKEY_ENC_UNKNOWN;
596 ctx->hash_algo = GCRY_MD_SHA1;
600 ctx->verify_cmp = NULL;
601 ctx->verify_arg = NULL;
604 /* Free a context initialzied by _gcry_pk_util_init_encoding_ctx. */
606 _gcry_pk_util_free_encoding_ctx (struct pk_encoding_ctx *ctx)
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.
621 [(flags [raw, direct, pkcs1, oaep, pss, no-blinding, rfc6979, eddsa])]
622 [(hash <algo> <value>)]
626 [(salt-length <length>)]
627 [(random-override <data>)]
630 Either the VALUE or the HASH element must be present for use
631 with signatures. VALUE is used for encryption.
633 HASH-ALGO is specific to OAEP and EDDSA.
635 LABEL is specific to OAEP.
637 SALT-LENGTH is for PSS.
639 RANDOM-OVERRIDE is used to replace random nonces for regression
642 _gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
643 struct pk_encoding_ctx *ctx)
645 gcry_err_code_t rc = 0;
646 gcry_sexp_t ldata, lhash, lvalue;
649 int unknown_flag = 0;
650 int parsed_flags = 0;
653 ldata = sexp_find_token (input, "data", 0);
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;
660 /* See whether there is a flags list. */
662 gcry_sexp_t lflags = sexp_find_token (ldata, "flags", 0);
665 if (_gcry_pk_util_parse_flaglist (lflags,
666 &parsed_flags, &ctx->encoding))
668 sexp_release (lflags);
672 if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
673 ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
675 /* Get HASH or MPI */
676 lhash = sexp_find_token (ldata, "hash", 0);
677 lvalue = lhash? NULL : sexp_find_token (ldata, "value", 0);
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))
686 /* Prepare for EdDSA. */
693 rc = GPG_ERR_INV_OBJ;
697 list = sexp_find_token (ldata, "hash-algo", 0);
700 s = sexp_nth_data (list, 1, &n);
705 ctx->hash_algo = get_hash_algo (s, n);
707 rc = GPG_ERR_DIGEST_ALGO;
712 rc = GPG_ERR_INV_OBJ;
717 value = sexp_nth_buffer (lvalue, 1, &valuelen);
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. */
724 value = xtrymalloc (1);
726 rc = gpg_err_code_from_syserror ();
728 else if ((valuelen * 8) < valuelen)
731 rc = GPG_ERR_TOO_LARGE;
736 /* Note that mpi_set_opaque takes ownership of VALUE. */
737 *ret_mpi = mpi_set_opaque (NULL, value, valuelen*8);
739 else if (ctx->encoding == PUBKEY_ENC_RAW && lhash
740 && ((parsed_flags & PUBKEY_FLAG_RAW_FLAG)
741 || (parsed_flags & PUBKEY_FLAG_RFC6979)))
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;
756 ctx->hash_algo = get_hash_algo (s, n);
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)
764 rc = GPG_ERR_TOO_LARGE;
767 *ret_mpi = mpi_set_opaque (NULL, value, valuelen*8);
770 else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
772 /* RFC6969 may only be used with the a hash value and not the
774 if (parsed_flags & PUBKEY_FLAG_RFC6979)
776 rc = GPG_ERR_CONFLICT;
781 *ret_mpi = sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
783 rc = GPG_ERR_INV_OBJ;
785 else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
786 && ctx->op == PUBKEY_OP_ENCRYPT)
791 void *random_override = NULL;
792 size_t random_override_len = 0;
794 if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
795 rc = GPG_ERR_INV_OBJ;
798 /* Get optional RANDOM-OVERRIDE. */
799 list = sexp_find_token (ldata, "random-override", 0);
802 s = sexp_nth_data (list, 1, &n);
807 random_override = xtrymalloc (n);
808 if (!random_override)
809 rc = gpg_err_code_from_syserror ();
812 memcpy (random_override, s, n);
813 random_override_len = n;
821 rc = _gcry_rsa_pkcs1_encode_for_enc (ret_mpi, ctx->nbits,
824 random_override_len);
825 xfree (random_override);
828 else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
829 && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
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;
840 ctx->hash_algo = get_hash_algo (s, n);
843 rc = GPG_ERR_DIGEST_ALGO;
844 else if ( !(value=sexp_nth_data (lhash, 2, &valuelen))
846 rc = GPG_ERR_INV_OBJ;
848 rc = _gcry_rsa_pkcs1_encode_for_sig (ret_mpi, ctx->nbits,
853 else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
854 && ctx->op == PUBKEY_OP_ENCRYPT)
859 if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
860 rc = GPG_ERR_INV_OBJ;
864 void *random_override = NULL;
865 size_t random_override_len = 0;
868 list = sexp_find_token (ldata, "hash-algo", 0);
871 s = sexp_nth_data (list, 1, &n);
876 ctx->hash_algo = get_hash_algo (s, n);
878 rc = GPG_ERR_DIGEST_ALGO;
886 list = sexp_find_token (ldata, "label", 0);
889 s = sexp_nth_data (list, 1, &n);
894 ctx->label = xtrymalloc (n);
896 rc = gpg_err_code_from_syserror ();
899 memcpy (ctx->label, s, n);
907 /* Get optional RANDOM-OVERRIDE. */
908 list = sexp_find_token (ldata, "random-override", 0);
911 s = sexp_nth_data (list, 1, &n);
916 random_override = xtrymalloc (n);
917 if (!random_override)
918 rc = gpg_err_code_from_syserror ();
921 memcpy (random_override, s, n);
922 random_override_len = n;
930 rc = _gcry_rsa_oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
932 ctx->label, ctx->labellen,
933 random_override, random_override_len);
935 xfree (random_override);
938 else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
939 && ctx->op == PUBKEY_OP_SIGN)
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;
949 void *random_override = NULL;
950 size_t random_override_len = 0;
952 ctx->hash_algo = get_hash_algo (s, n);
955 rc = GPG_ERR_DIGEST_ALGO;
956 else if ( !(value=sexp_nth_data (lhash, 2, &valuelen))
958 rc = GPG_ERR_INV_OBJ;
963 /* Get SALT-LENGTH. */
964 list = sexp_find_token (ldata, "salt-length", 0);
967 s = sexp_nth_data (list, 1, &n);
973 ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
977 /* Get optional RANDOM-OVERRIDE. */
978 list = sexp_find_token (ldata, "random-override", 0);
981 s = sexp_nth_data (list, 1, &n);
986 random_override = xtrymalloc (n);
987 if (!random_override)
988 rc = gpg_err_code_from_syserror ();
991 memcpy (random_override, s, n);
992 random_override_len = n;
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,
1003 value, valuelen, ctx->saltlen,
1004 random_override, random_override_len);
1006 xfree (random_override);
1010 else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
1011 && ctx->op == PUBKEY_OP_VERIFY)
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;
1019 ctx->hash_algo = get_hash_algo (s, n);
1021 if (!ctx->hash_algo)
1022 rc = GPG_ERR_DIGEST_ALGO;
1025 *ret_mpi = sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
1027 rc = GPG_ERR_INV_OBJ;
1028 ctx->verify_cmp = pss_verify_cmp;
1029 ctx->verify_arg = *ret_mpi;
1034 rc = GPG_ERR_CONFLICT;
1037 sexp_release (ldata);
1038 sexp_release (lhash);
1039 sexp_release (lvalue);
1042 ctx->flags = parsed_flags;