aboutsummaryrefslogtreecommitdiffstats
path: root/src/data-mem.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2018-07-19 15:38:50 +0000
committerWerner Koch <[email protected]>2018-07-19 15:39:09 +0000
commit085cdeddef637cc057362fcbde13b0261b8699ec (patch)
treed70d2be38d9015f5bc04c6a69b87b529d8940b21 /src/data-mem.c
parentcpp: Print origin and last update for key/uid (diff)
downloadgpgme-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/data-mem.c')
-rw-r--r--src/data-mem.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/src/data-mem.c b/src/data-mem.c
index a498b826..7569f7df 100644
--- a/src/data-mem.c
+++ b/src/data-mem.c
@@ -224,7 +224,10 @@ gpgme_data_new_from_mem (gpgme_data_t *r_dh, const char *buffer,
char *
gpgme_data_release_and_get_mem (gpgme_data_t dh, size_t *r_len)
{
+ gpg_error_t err;
char *str = NULL;
+ size_t len;
+ int blankout;
TRACE_BEG1 (DEBUG_DATA, "gpgme_data_release_and_get_mem", dh,
"r_len=%p", r_len);
@@ -236,10 +239,22 @@ gpgme_data_release_and_get_mem (gpgme_data_t dh, size_t *r_len)
return NULL;
}
+ err = _gpgme_data_get_prop (dh, 0, DATA_PROP_BLANKOUT, &blankout);
+ if (err)
+ {
+ gpgme_data_release (dh);
+ TRACE_ERR (err);
+ return NULL;
+ }
+
str = dh->data.mem.buffer;
+ len = dh->data.mem.length;
+ if (blankout && len)
+ len = 1;
+
if (!str && dh->data.mem.orig_buffer)
{
- str = malloc (dh->data.mem.length);
+ str = malloc (len);
if (!str)
{
int saved_err = gpg_error_from_syserror ();
@@ -247,15 +262,22 @@ gpgme_data_release_and_get_mem (gpgme_data_t dh, size_t *r_len)
TRACE_ERR (saved_err);
return NULL;
}
- memcpy (str, dh->data.mem.orig_buffer, dh->data.mem.length);
+ if (blankout)
+ memset (str, 0, len);
+ else
+ memcpy (str, dh->data.mem.orig_buffer, len);
}
else
- /* Prevent mem_release from releasing the buffer memory. We must
- not fail from this point. */
- dh->data.mem.buffer = NULL;
+ {
+ if (blankout && len)
+ *str = 0;
+ /* Prevent mem_release from releasing the buffer memory. We
+ * must not fail from this point. */
+ dh->data.mem.buffer = NULL;
+ }
if (r_len)
- *r_len = dh->data.mem.length;
+ *r_len = len;
gpgme_data_release (dh);