summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2018-06-01 01:29:20 +0200
committerWerner Koch <wk@gnupg.org>2018-06-01 01:29:34 +0200
commit662604c5bcb4e03d3c9ecc670d4f320a2418ebb3 (patch)
tree4495b29c8d7ab2c323f58d8fb772411789d7c565
parentdd19cabe81b7bf4177ea2ca741f6eb6cd1cab25e (diff)
downloadgpgme-662604c5bcb4e03d3c9ecc670d4f320a2418ebb3.tar.gz
core: New context flag "ignore-mdc-error".
* src/context.h (gpgme_context): Add field ignore_mdc_error. * src/gpgme.c (gpgme_set_ctx_flag, gpgme_get_ctx_flag): Set/get it. * src/engine-gpg.c (engine_gpg): Add flags.ignore_mdc_error. (gpg_set_engine_flags): Set it. (build_argv): Pass option to gpg. * src/decrypt.c (_gpgme_decrypt_status_handler): Take care of flag. (gpgme_op_decrypt_result): Clear flag. (gpgme_op_decrypt): Clear flag. * src/decrypt-verify.c (gpgme_op_decrypt_verify): Clear flag (gpgme_op_decrypt_ext): Clear flag. * tests/run-decrypt.c (show_usage): Add option --ignore-mdc-error. Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r--NEWS1
-rw-r--r--doc/gpgme.texi11
-rw-r--r--src/context.h4
-rw-r--r--src/decrypt-verify.c2
-rw-r--r--src/decrypt.c6
-rw-r--r--src/engine-gpg.c17
-rw-r--r--src/gpgme.c8
-rw-r--r--tests/run-decrypt.c20
8 files changed, 65 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index bc1330ad..4eb3dbeb 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ Noteworthy changes in version 1.11.2 (unreleased)
* Interface changes relative to the 1.11.1 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_decrypt_result_t EXTENDED: New field legacy_cipher_nomdc.
+ gpgme_set_ctx_flag EXTENDED: New flag 'ignore-mdc-error'.
cpp: DecryptionResult::sessionKey NEW.
cpp: DecryptionResult::symkeyAlgo NEW.
cpp: Data::rewind NEW.
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index d8771167..e3445a0e 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -3078,7 +3078,7 @@ the time when you verified the signature.
The string given in @var{value} is passed to the GnuPG engines to
request restrictions based on the origin of the request. Valid values
are documented in the GnuPG manual and the gpg man page under the
-option ``--request-origin''. Requires at least GnuPG 2.2.6 to have an
+option @option{--request-origin}. Requires at least GnuPG 2.2.6 to have an
effect.
@item "no-symkey-cache"
@@ -3086,6 +3086,15 @@ For OpenPGP disable the passphrase cache used for symmetrical en- and
decryption. This cache is based on the message specific salt value.
Requires at least GnuPG 2.2.7 to have an effect.
+@item "ignore-mdc-error"
+This flag passes the option @option{--ignore-mdc-error} to gpg. This
+can be used to force decryption of a message which failed due to a
+missing integrity check. This flag must be used with great caution
+and only if it is a known non-corrupted old message and the decryption
+result of the former try had the decryption result flag
+@code{legacy_cipher_nomdc} set. For failsafe reasons this flag is
+reset after each operation.
+
@end table
This function returns @code{0} on success.
diff --git a/src/context.h b/src/context.h
index c8e75ba0..bdab6878 100644
--- a/src/context.h
+++ b/src/context.h
@@ -124,6 +124,10 @@ struct gpgme_context
/* Do not use the symmtric encryption passphrase cache. */
unsigned int no_symkey_cache : 1;
+ /* Pass --ignore-mdc-error to gpg. Note that this flag is reset
+ * after the operation. */
+ unsigned int ignore_mdc_error : 1;
+
/* Flags for keylist mode. */
gpgme_keylist_mode_t keylist_mode;
diff --git a/src/decrypt-verify.c b/src/decrypt-verify.c
index ce4a7a9b..1bd81c31 100644
--- a/src/decrypt-verify.c
+++ b/src/decrypt-verify.c
@@ -127,6 +127,7 @@ gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher,
err = decrypt_verify_start (ctx, 1, GPGME_DECRYPT_VERIFY, cipher, plain);
if (!err)
err = _gpgme_wait_one (ctx);
+ ctx->ignore_mdc_error = 0; /* Always reset. */
return TRACE_ERR (err);
}
@@ -177,5 +178,6 @@ gpgme_op_decrypt_ext (gpgme_ctx_t ctx,
err = _gpgme_decrypt_start (ctx, 1, flags, cipher, plain);
if (!err)
err = _gpgme_wait_one (ctx);
+ ctx->ignore_mdc_error = 0; /* Always reset. */
return TRACE_ERR (err);
}
diff --git a/src/decrypt.c b/src/decrypt.c
index f2278d8d..8c95ebed 100644
--- a/src/decrypt.c
+++ b/src/decrypt.c
@@ -97,6 +97,8 @@ gpgme_op_decrypt_result (gpgme_ctx_t ctx)
TRACE_BEG (DEBUG_CTX, "gpgme_op_decrypt_result", ctx);
+ ctx->ignore_mdc_error = 0; /* Always reset this flag. */
+
err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
opd = hook;
if (err || !opd)
@@ -362,7 +364,8 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
return opd->pkdecrypt_failed;
else if (opd->failed && opd->any_no_seckey)
return gpg_error (GPG_ERR_NO_SECKEY);
- else if (opd->failed || opd->not_integrity_protected)
+ else if (opd->failed || (opd->not_integrity_protected
+ && !ctx->ignore_mdc_error))
return gpg_error (GPG_ERR_DECRYPT_FAILED);
else if (!opd->okay)
return gpg_error (GPG_ERR_NO_DATA);
@@ -564,5 +567,6 @@ gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain)
err = _gpgme_decrypt_start (ctx, 1, 0, cipher, plain);
if (!err)
err = _gpgme_wait_one (ctx);
+ ctx->ignore_mdc_error = 0; /* Always reset. */
return TRACE_ERR (err);
}
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 43d49fe6..802af08d 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -144,6 +144,7 @@ struct engine_gpg
struct {
unsigned int no_symkey_cache : 1;
unsigned int offline : 1;
+ unsigned int ignore_mdc_error : 1;
} flags;
/* NULL or the data object fed to --override_session_key-fd. */
@@ -646,9 +647,10 @@ gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
gpg->flags.no_symkey_cache = (ctx->no_symkey_cache
&& have_gpg_version (gpg, "2.2.7"));
-
gpg->flags.offline = (ctx->offline && have_gpg_version (gpg, "2.1.23"));
+ gpg->flags.ignore_mdc_error = !!ctx->ignore_mdc_error;
+
}
@@ -955,6 +957,19 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
argc++;
}
+ if (gpg->flags.ignore_mdc_error)
+ {
+ argv[argc] = strdup ("--ignore-mdc-error");
+ if (!argv[argc])
+ {
+ int saved_err = gpg_error_from_syserror ();
+ free (fd_data_map);
+ free_argv (argv);
+ return saved_err;
+ }
+ argc++;
+ }
+
if (gpg->flags.offline)
{
argv[argc] = strdup ("--disable-dirmngr");
diff --git a/src/gpgme.c b/src/gpgme.c
index 82d67478..b03c7b87 100644
--- a/src/gpgme.c
+++ b/src/gpgme.c
@@ -542,6 +542,10 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
{
ctx->no_symkey_cache = abool;
}
+ else if (!strcmp (name, "ignore-mdc-error"))
+ {
+ ctx->ignore_mdc_error = abool;
+ }
else
err = gpg_error (GPG_ERR_UNKNOWN_NAME);
@@ -591,6 +595,10 @@ gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
{
return ctx->no_symkey_cache? "1":"";
}
+ else if (!strcmp (name, "ignore-mdc-error"))
+ {
+ return ctx->ignore_mdc_error? "1":"";
+ }
else
return NULL;
}
diff --git a/tests/run-decrypt.c b/tests/run-decrypt.c
index 8ec0cb4f..99a15c7e 100644
--- a/tests/run-decrypt.c
+++ b/tests/run-decrypt.c
@@ -86,6 +86,7 @@ show_usage (int ex)
" --override-session-key STRING use STRING as session key\n"
" --request-origin STRING use STRING as request origin\n"
" --no-symkey-cache disable the use of that cache\n"
+ " --ignore-mdc-error allow decryption of legacy data\n"
" --unwrap remove only the encryption layer\n"
, stderr);
exit (ex);
@@ -109,6 +110,7 @@ main (int argc, char **argv)
const char *override_session_key = NULL;
const char *request_origin = NULL;
int no_symkey_cache = 0;
+ int ignore_mdc_error = 0;
int raw_output = 0;
if (argc)
@@ -170,6 +172,11 @@ main (int argc, char **argv)
no_symkey_cache = 1;
argc--; argv++;
}
+ else if (!strcmp (*argv, "--ignore-mdc-error"))
+ {
+ ignore_mdc_error = 1;
+ argc--; argv++;
+ }
else if (!strcmp (*argv, "--unwrap"))
{
flags |= GPGME_DECRYPT_UNWRAP;
@@ -241,7 +248,18 @@ main (int argc, char **argv)
err = gpgme_set_ctx_flag (ctx, "no-symkey-cache", "1");
if (err)
{
- fprintf (stderr, PGM ": error setting no-symkey-cache: %s\n",
+ fprintf (stderr, PGM ": error setting no-symkey-cache: %s\n",
+ gpgme_strerror (err));
+ exit (1);
+ }
+ }
+
+ if (ignore_mdc_error)
+ {
+ err = gpgme_set_ctx_flag (ctx, "ignore-mdc-error", "1");
+ if (err)
+ {
+ fprintf (stderr, PGM ": error setting ignore-mdc-error: %s\n",
gpgme_strerror (err));
exit (1);
}