diff options
-rw-r--r-- | g10/decrypt-data.c | 21 | ||||
-rw-r--r-- | g10/gpgv.c | 4 | ||||
-rw-r--r-- | g10/mainproc.c | 31 | ||||
-rw-r--r-- | g10/packet.h | 5 | ||||
-rw-r--r-- | g10/test-stubs.c | 4 |
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; } |