diff --git a/doc/gpg.texi b/doc/gpg.texi index ec54216f3..370eb32db 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -3471,6 +3471,15 @@ To avoid a minor risk of collision attacks on third-party key signatures made using SHA-1, those key signatures are considered invalid. This options allows to override this restriction. +@item --override-compliance-check +@opindex --override-compliance-check +The signature verification only allows the use of keys suitable in the +current compliance mode. If the compliance mode has been forced by a +global option, there might be no way to check certain signature. This +option allows to override this and prints an extra warning in such a +case. This option is ignored in --batch mode so that no accidental +unattended verification may happen. + @item --no-default-keyring @opindex no-default-keyring Do not add the default keyring to the list of keyrings. Note that diff --git a/g10/gpg.c b/g10/gpg.c index 411b6c097..84e24052a 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -357,6 +357,7 @@ enum cmd_and_opt_values oShowSessionKey, oOverrideSessionKey, oOverrideSessionKeyFD, + oOverrideComplianceCheck, oNoRandomSeedFile, oAutoKeyRetrieve, oNoAutoKeyRetrieve, @@ -840,7 +841,6 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oOverrideSessionKey, "override-session-key", "@"), ARGPARSE_s_i (oOverrideSessionKeyFD, "override-session-key-fd", "@"), - ARGPARSE_header ("Security", N_("Options controlling the security")), ARGPARSE_s_i (oS2KMode, "s2k-mode", "@"), @@ -871,6 +871,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oAEADAlgo, "aead-algo", "@"), ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"), ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"), + ARGPARSE_s_n (oOverrideComplianceCheck, "override-compliance-check", "@"), ARGPARSE_header (NULL, N_("Options for unattended use")), @@ -3660,6 +3661,10 @@ main (int argc, char **argv) opt.flags.allow_old_cipher_algos = 1; break; + case oOverrideComplianceCheck: + opt.flags.override_compliance_check = 1; + break; + case oFakedSystemTime: { size_t len = strlen (pargs.r.ret_str); @@ -3869,6 +3874,15 @@ main (int argc, char **argv) g10_exit(2); } + /* We allow overriding the compliance check only in non-batch mode + * so that the user has a chance to see the message. */ + if (opt.flags.override_compliance_check && opt.batch) + { + opt.flags.override_compliance_check = 0; + log_info ("Note: '%s' ignored due to batch mode\n", + "--override-compliance-check"); + } + set_debug (debug_level); if (DBG_CLOCK) log_clock ("start"); diff --git a/g10/options.h b/g10/options.h index 761d95830..2ad86ae42 100644 --- a/g10/options.h +++ b/g10/options.h @@ -245,6 +245,7 @@ struct unsigned int allow_old_cipher_algos:1; unsigned int allow_weak_digest_algos:1; unsigned int allow_weak_key_signatures:1; + unsigned int override_compliance_check:1; unsigned int large_rsa:1; unsigned int disable_signer_uid:1; unsigned int include_key_block:1; diff --git a/g10/sig-check.c b/g10/sig-check.c index 8dd18b2e2..eb6c9669d 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -67,6 +67,35 @@ sig_check_dump_stats (void) } +static gpg_error_t +check_key_verify_compliance (PKT_public_key *pk) +{ + gpg_error_t err = 0; + + if (!gnupg_pk_is_allowed (opt.compliance, PK_USE_VERIFICATION, + pk->pubkey_algo, 0, pk->pkey, + nbits_from_pk (pk), + NULL)) + { + /* Compliance failure. */ + log_info (_("key %s may not be used for signing in %s mode\n"), + keystr_from_pk (pk), + gnupg_compliance_option_string (opt.compliance)); + if (opt.flags.override_compliance_check) + log_info (_("continuing verification anyway due to option %s\n"), + "--override-compliance-failure"); + else + { + log_inc_errorcount (); /* We used log info above. */ + err = gpg_error (GPG_ERR_PUBKEY_ALGO); + } + } + + return err; +} + + + /* Check a signature. This is shorthand for check_signature2 with the unnamed arguments passed as NULL. */ int @@ -172,17 +201,8 @@ check_signature2 (ctrl_t ctrl, } else if (get_pubkey_for_sig (ctrl, pk, sig, forced_pk)) rc = gpg_error (GPG_ERR_NO_PUBKEY); - else if (!gnupg_pk_is_allowed (opt.compliance, PK_USE_VERIFICATION, - pk->pubkey_algo, 0, pk->pkey, - nbits_from_pk (pk), - NULL)) - { - /* Compliance failure. */ - log_error (_("key %s may not be used for signing in %s mode\n"), - keystr_from_pk (pk), - gnupg_compliance_option_string (opt.compliance)); - rc = gpg_error (GPG_ERR_PUBKEY_ALGO); - } + else if ((rc = check_key_verify_compliance (pk))) + ;/* Compliance failure. */ else if (!pk->flags.valid) { /* You cannot have a good sig from an invalid key. */