aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--g10/decrypt-data.c21
-rw-r--r--g10/gpgv.c4
-rw-r--r--g10/mainproc.c31
-rw-r--r--g10/packet.h5
-rw-r--r--g10/test-stubs.c4
5 files changed, 47 insertions, 18 deletions
diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c
index 8b48d18bf..6c1d6ebcd 100644
--- a/g10/decrypt-data.c
+++ b/g10/decrypt-data.c
@@ -214,10 +214,14 @@ aead_checktag (decode_filter_ctx_t dfx, int final, const void *tagbuf)
/****************
- * Decrypt the data, specified by ED with the key DEK.
+ * Decrypt the data, specified by ED with the key DEK. On return
+ * COMPLIANCE_ERROR is set to true iff the decryption can claim that
+ * it was compliant in the current mode; otherwise this flag is set to
+ * false.
*/
int
-decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
+decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek,
+ int *compliance_error)
{
decode_filter_ctx_t dfx;
enum gcry_cipher_modes ciphermode;
@@ -228,6 +232,8 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
unsigned int blocksize;
unsigned int nprefix;
+ *compliance_error = 0;
+
dfx = xtrycalloc (1, sizeof *dfx);
if (!dfx)
return gpg_error_from_syserror ();
@@ -261,8 +267,14 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
log_error (_("cipher algorithm '%s' may not be used in %s mode\n"),
openpgp_cipher_algo_name (dek->algo),
gnupg_compliance_option_string (opt.compliance));
- rc = gpg_error (GPG_ERR_CIPHER_ALGO);
- goto leave;
+ *compliance_error = 1;
+ if (opt.flags.require_compliance)
+ {
+ /* We fail early in this case because it does not make sense
+ * to first decrypt everything. */
+ rc = gpg_error (GPG_ERR_CIPHER_ALGO);
+ goto leave;
+ }
}
write_status_printf (STATUS_DECRYPTION_INFO, "%d %d %d",
@@ -424,6 +436,7 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
if (!ed->buf)
{
log_error (_("problem handling encrypted packet\n"));
+ rc = gpg_error (GPG_ERR_INV_PACKET);
goto leave;
}
diff --git a/g10/gpgv.c b/g10/gpgv.c
index d1e6da956..3bb99dc6c 100644
--- a/g10/gpgv.c
+++ b/g10/gpgv.c
@@ -544,12 +544,14 @@ get_override_session_key (DEK *dek, const char *string)
/* Stub: */
int
-decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
+decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek,
+ int *compliance_error)
{
(void)ctrl;
(void)procctx;
(void)ed;
(void)dek;
+ (void)compliance_error;
return GPG_ERR_GENERAL;
}
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 70685fab9..cd62737a4 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -722,16 +722,17 @@ proc_encrypted (CTX c, PACKET *pkt)
xfree (pk);
if (compliant)
- {
- write_status_strings (STATUS_DECRYPTION_COMPLIANCE_MODE,
- gnupg_status_compliance_flag (CO_DE_VS),
- NULL);
- compliance_de_vs |= 1;
- }
+ compliance_de_vs |= 1;
}
if (!result)
- result = decrypt_data (c->ctrl, c, pkt->pkt.encrypted, c->dek );
+ {
+ int compl_error;
+ result = decrypt_data (c->ctrl, c, pkt->pkt.encrypted, c->dek,
+ &compl_error);
+ if (!result && !compl_error)
+ compliance_de_vs |= 2;
+ }
/* Trigger the deferred error. */
if (!result && early_plaintext)
@@ -784,12 +785,12 @@ proc_encrypted (CTX c, PACKET *pkt)
if (pkt->pkt.encrypted->aead_algo)
{
write_status (STATUS_GOODMDC);
- compliance_de_vs |= 2;
+ compliance_de_vs |= 4;
}
else if (pkt->pkt.encrypted->mdc_method && !result)
{
write_status (STATUS_GOODMDC);
- compliance_de_vs |= 2;
+ compliance_de_vs |= 4;
}
else
log_info (_("WARNING: message was not integrity protected\n"));
@@ -821,6 +822,16 @@ proc_encrypted (CTX c, PACKET *pkt)
* ways to specify the session key (symmmetric and PK). */
}
+
+ /* If we concluded that the decryption was compliant, issue a
+ * compliance status before the thed end of decryption status. */
+ if (compliance_de_vs == (4|2|1))
+ {
+ write_status_strings (STATUS_DECRYPTION_COMPLIANCE_MODE,
+ gnupg_status_compliance_flag (CO_DE_VS),
+ NULL);
+ }
+
xfree (c->dek);
c->dek = NULL;
free_packet (pkt, NULL);
@@ -837,7 +848,7 @@ proc_encrypted (CTX c, PACKET *pkt)
* de-vs compliance mode by just looking at the exit status. */
if (opt.flags.require_compliance
&& opt.compliance == CO_DE_VS
- && compliance_de_vs != (2|1))
+ && compliance_de_vs != (4|2|1))
{
log_error (_("operation forced to fail due to"
" unfulfilled compliance rules\n"));
diff --git a/g10/packet.h b/g10/packet.h
index b27beccdd..5a14015a1 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -914,8 +914,9 @@ gpg_error_t get_override_session_key (DEK *dek, const char *string);
int handle_compressed (ctrl_t ctrl, void *ctx, PKT_compressed *cd,
int (*callback)(iobuf_t, void *), void *passthru );
-/*-- encr-data.c --*/
-int decrypt_data (ctrl_t ctrl, void *ctx, PKT_encrypted *ed, DEK *dek );
+/*-- decrypt-data.c --*/
+int decrypt_data (ctrl_t ctrl, void *ctx, PKT_encrypted *ed, DEK *dek,
+ int *compliance_error);
/*-- plaintext.c --*/
gpg_error_t get_output_file (const byte *embedded_name, int embedded_namelen,
diff --git a/g10/test-stubs.c b/g10/test-stubs.c
index 1b9f12068..cfe33b1d0 100644
--- a/g10/test-stubs.c
+++ b/g10/test-stubs.c
@@ -305,12 +305,14 @@ get_override_session_key (DEK *dek, const char *string)
/* Stub: */
int
-decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
+decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek,
+ int *compliance_error)
{
(void)ctrl;
(void)procctx;
(void)ed;
(void)dek;
+ (void)compliance_error;
return GPG_ERR_GENERAL;
}