summaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2022-03-08 10:13:44 +0100
committerWerner Koch <wk@gnupg.org>2022-03-08 19:26:01 +0100
commitee013c5350ce6a5b3d4089753cb99a44802fdfa8 (patch)
treed81bc0fc1d8a47e2230f35df87e6f4ca84cdb116 /g10
parentgpg: fix --enarmor with zero length source file (diff)
downloadgnupg2-ee013c5350ce6a5b3d4089753cb99a44802fdfa8.tar.xz
gnupg2-ee013c5350ce6a5b3d4089753cb99a44802fdfa8.zip
gpg: New option --require-compliance.
* g10/options.h (opt): Add field flags.require_compliance. * g10/gpg.c (oRequireCompliance): New. (opts): Add --require-compliance. (main): Set option. * g10/mainproc.c (proc_encrypted): Emit error if non de-vs compliant. (check_sig_and_print): Ditto. * g10/encrypt.c (encrypt_crypt): Ditto. -- Note that in the --encrypt and --verify cased other checks may kick in earlier than this new --require-compliance controlled one.
Diffstat (limited to 'g10')
-rw-r--r--g10/encrypt.c11
-rw-r--r--g10/gpg.c6
-rw-r--r--g10/mainproc.c41
-rw-r--r--g10/options.h3
4 files changed, 55 insertions, 6 deletions
diff --git a/g10/encrypt.c b/g10/encrypt.c
index bca7344f4..28a761747 100644
--- a/g10/encrypt.c
+++ b/g10/encrypt.c
@@ -847,6 +847,17 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
gnupg_status_compliance_flag (CO_DE_VS),
NULL);
+ if (opt.flags.require_compliance
+ && opt.compliance == CO_DE_VS
+ && !compliant)
+ {
+ log_error (_("operation forced to fail due to"
+ " unfulfilled compliance rules\n"));
+ rc = gpg_error (GPG_ERR_FORBIDDEN);
+ g10_errors_seen = 1;
+ goto leave;
+ }
+
cfx.dek->use_aead = use_aead (pk_list, cfx.dek->algo);
if (!cfx.dek->use_aead)
cfx.dek->use_mdc = !!use_mdc (pk_list, cfx.dek->algo);
diff --git a/g10/gpg.c b/g10/gpg.c
index 1155f501c..4883493db 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -442,6 +442,7 @@ enum cmd_and_opt_values
oChUid,
oForceSignKey,
oForbidGenKey,
+ oRequireCompliance,
oNoop
};
@@ -911,6 +912,7 @@ static gpgrt_opt_t opts[] = {
ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"),
ARGPARSE_s_n (oUseKeyboxd, "use-keyboxd", "@"),
ARGPARSE_s_n (oForbidGenKey, "forbid-gen-key", "@"),
+ ARGPARSE_s_n (oRequireCompliance, "require-compliance", "@"),
/* Options which can be used in special circumstances. They are not
* published and we hope they are never required. */
ARGPARSE_s_n (oUseOnlyOpenPGPCard, "use-only-openpgp-card", "@"),
@@ -3731,6 +3733,10 @@ main (int argc, char **argv)
mopt.forbid_gen_key = 1;
break;
+ case oRequireCompliance:
+ opt.flags.require_compliance = 1;
+ break;
+
case oNoop: break;
default:
diff --git a/g10/mainproc.c b/g10/mainproc.c
index f44e68453..70685fab9 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -546,6 +546,7 @@ proc_encrypted (CTX c, PACKET *pkt)
{
int result = 0;
int early_plaintext = literals_seen;
+ unsigned int compliance_de_vs = 0;
if (pkt->pkttype == PKT_ENCRYPTED_AEAD)
c->seen_pkt_encrypted_aead = 1;
@@ -721,10 +722,12 @@ 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);
-
+ {
+ write_status_strings (STATUS_DECRYPTION_COMPLIANCE_MODE,
+ gnupg_status_compliance_flag (CO_DE_VS),
+ NULL);
+ compliance_de_vs |= 1;
+ }
}
if (!result)
@@ -779,9 +782,15 @@ proc_encrypted (CTX c, PACKET *pkt)
log_info(_("decryption okay\n"));
if (pkt->pkt.encrypted->aead_algo)
- write_status (STATUS_GOODMDC);
+ {
+ write_status (STATUS_GOODMDC);
+ compliance_de_vs |= 2;
+ }
else if (pkt->pkt.encrypted->mdc_method && !result)
- write_status (STATUS_GOODMDC);
+ {
+ write_status (STATUS_GOODMDC);
+ compliance_de_vs |= 2;
+ }
else
log_info (_("WARNING: message was not integrity protected\n"));
}
@@ -823,6 +832,17 @@ proc_encrypted (CTX c, PACKET *pkt)
* a misplace extra literal data packets follows after this
* encrypted packet. */
literals_seen++;
+
+ /* The --require-compliance option allows to simplify decryption in
+ * 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))
+ {
+ log_error (_("operation forced to fail due to"
+ " unfulfilled compliance rules\n"));
+ g10_errors_seen = 1;
+ }
}
@@ -2439,6 +2459,15 @@ check_sig_and_print (CTX c, kbnode_t node)
write_status_strings (STATUS_VERIFICATION_COMPLIANCE_MODE,
gnupg_status_compliance_flag (CO_DE_VS),
NULL);
+ else if (opt.flags.require_compliance
+ && opt.compliance == CO_DE_VS)
+ {
+ log_error (_("operation forced to fail due to"
+ " unfulfilled compliance rules\n"));
+ if (!rc)
+ rc = gpg_error (GPG_ERR_FORBIDDEN);
+ }
+
free_public_key (pk);
pk = NULL;
diff --git a/g10/options.h b/g10/options.h
index 8df463ed4..10e61ea4c 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -269,6 +269,9 @@ struct
/* The next flag is set internally iff IMPORT_CLEAN has
* been set by the user and is not the default value. */
unsigned int expl_import_clean:1;
+ /* Fail if an operation can't be done in the requested compliance
+ * mode. */
+ unsigned int require_compliance:1;
} flags;
/* Linked list of ways to find a key if the key isn't on the local