diff options
author | Werner Koch <[email protected]> | 2018-07-19 15:38:50 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2018-07-19 15:39:09 +0000 |
commit | 085cdeddef637cc057362fcbde13b0261b8699ec (patch) | |
tree | d70d2be38d9015f5bc04c6a69b87b529d8940b21 /src/decrypt.c | |
parent | cpp: Print origin and last update for key/uid (diff) | |
download | gpgme-085cdeddef637cc057362fcbde13b0261b8699ec.tar.gz gpgme-085cdeddef637cc057362fcbde13b0261b8699ec.zip |
core: Blank out the plaintext after decryption failure.
* src/data.h (data_prop_t): New enum.
(struct gpgme_data): Add field propidx.
* src/data.c (property_t): New.
(property_table, property_table_size, property_table_lock): New.
(insert_into_property_table): New.
(remove_from_property_table): New.
(_gpgme_data_get_dserial): New.
(_gpgme_data_set_prop): New.
(_gpgme_data_get_prop): New.
(_gpgme_data_new): Connect new object to property_table.
(_gpgme_data_release): Remove from property_table.
(gpgme_data_read): With DATA_PROP_BLANKOUT set don't fill the buffer.
* src/data-mem.c (gpgme_data_release_and_get_mem): Likewise.
* src/decrypt.c (struct op_data): Add field plaintext_dserial.
(_gpgme_op_decrypt_init_result): Add arg plaintext and init new field.
(_gpgme_decrypt_status_handler): Set DATA_PROP_BLANKOUT on decryption
failure.
(_gpgme_decrypt_start): Pass PLAIN to the init function.
* src/decrypt-verify.c (decrypt_verify_start): Ditto.
* configure.ac: Check for stdint.h and bail out if uint64_t is not
available.
--
This is a best effort feature to not output plaintext after a
decryption failure (e.g. due to no or broken authenticated
encryption). It always work when using a memory object and reading it
after the decryption but it can't work reliable when the user is
reading from the data object while the decryption process is still
running.
This is quite a large change because the data objects and the context
objects are allowed to be owned by different threads. Thus a
synchronization is needed and we do this with a global table of all
data objects to which the context objects can do soft-linking via a
unique data object serial number.
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'src/decrypt.c')
-rw-r--r-- | src/decrypt.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/decrypt.c b/src/decrypt.c index f5b93d7c..b51603a3 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -32,7 +32,7 @@ #include "util.h" #include "context.h" #include "ops.h" - +#include "data.h" typedef struct @@ -69,6 +69,9 @@ typedef struct This makes appending new invalid signers painless while preserving the order. */ gpgme_recipient_t *last_recipient_p; + + /* The data object serial number of the plaintext. */ + uint64_t plaintext_dserial; } *op_data_t; @@ -419,6 +422,14 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code, case GPGME_STATUS_DECRYPTION_FAILED: opd->failed = 1; + /* Tell the data object that it shall not return any data. We + * use the serial number because the data object may be owned by + * another thread. We also don't check for an error because it + * is possible that the data object has already been destroyed + * and we are then not interested in returning an error. */ + if (!ctx->ignore_mdc_error) + _gpgme_data_set_prop (NULL, opd->plaintext_dserial, + DATA_PROP_BLANKOUT, 1); break; case GPGME_STATUS_ERROR: @@ -508,7 +519,7 @@ decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args) gpgme_error_t -_gpgme_op_decrypt_init_result (gpgme_ctx_t ctx) +_gpgme_op_decrypt_init_result (gpgme_ctx_t ctx, gpgme_data_t plaintext) { gpgme_error_t err; void *hook; @@ -521,6 +532,7 @@ _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx) return err; opd->last_recipient_p = &opd->result.recipients; + opd->plaintext_dserial = _gpgme_data_get_dserial (plaintext); return 0; } @@ -538,7 +550,7 @@ _gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous, if (err) return err; - err = _gpgme_op_decrypt_init_result (ctx); + err = _gpgme_op_decrypt_init_result (ctx, plain); if (err) return err; |