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.
This commit is contained in:
Werner Koch 2022-03-08 10:13:44 +01:00
parent c11292fe73
commit 17890d4318
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
5 changed files with 67 additions and 6 deletions

View File

@ -2889,6 +2889,17 @@ This option adjusts the compliance mode "de-vs" for stricter key size
requirements. For example, a value of 3000 turns rsa2048 and dsa2048
keys into non-VS-NfD compliant keys.
@item --require-compliance
@opindex require-compliance
To check that data has been encrypted according to the rules of the
current compliance mode, a gpg user needs to evaluate the status
lines. This is allows frontends to handle compliance check in a more
flexible way. However, for scripted use the required evaluation of
the status-line requires quite some effort; this option can be used
instead to make sure that the gpg process exits with a failure if the
compliance rules are not fulfilled. Note that this option has
currently an effect only in "de-vs" mode.
@end table

View File

@ -655,6 +655,18 @@ 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_mdc = use_mdc (pk_list,cfx.dek->algo);
/* Only do the is-file-already-compressed check if we are using a

View File

@ -430,6 +430,7 @@ enum cmd_and_opt_values
oNoIncludeKeyBlock,
oForceSignKey,
oForbidGenKey,
oRequireCompliance,
oNoop
};
@ -890,6 +891,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oXauthority, "xauthority", "@"),
ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"),
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", "@"),
@ -3596,6 +3598,10 @@ main (int argc, char **argv)
mopt.forbid_gen_key = 1;
break;
case oRequireCompliance:
opt.flags.require_compliance = 1;
break;
case oNoop: break;
default:

View File

@ -638,6 +638,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;
@ -761,10 +762,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;
}
}
@ -820,9 +823,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"));
}
@ -864,6 +873,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;
}
}
@ -2538,6 +2558,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;

View File

@ -253,6 +253,9 @@ struct
/* The next flag is set internally iff IMPORT_SELF_SIGS_ONLY has
* been set by the user and is not the default value. */
unsigned int expl_import_self_sigs_only: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