diff --git a/doc/gpg.texi b/doc/gpg.texi index 475de1853..2b5467eed 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -3361,6 +3361,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 a30ef0155..abab14426 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -347,6 +347,7 @@ enum cmd_and_opt_values oShowSessionKey, oOverrideSessionKey, oOverrideSessionKeyFD, + oOverrideComplianceCheck, oNoRandomSeedFile, oAutoKeyRetrieve, oNoAutoKeyRetrieve, @@ -684,6 +685,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (oSigNotation, "sig-notation", "@"), ARGPARSE_s_s (oCertNotation, "cert-notation", "@"), ARGPARSE_s_s (oKnownNotation, "known-notation", "@"), + ARGPARSE_s_n (oOverrideComplianceCheck, "override-compliance-check", "@"), ARGPARSE_group (302, N_( "@\n(See the man page for a complete listing of all commands and options)\n" @@ -3547,6 +3549,10 @@ main (int argc, char **argv) opt.flags.allow_weak_key_signatures = 1; break; + case oOverrideComplianceCheck: + opt.flags.override_compliance_check = 1; + break; + case oFakedSystemTime: { size_t len = strlen (pargs.r.ret_str); @@ -3735,6 +3741,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 237e5ba74..f91dbd5e7 100644 --- a/g10/options.h +++ b/g10/options.h @@ -235,6 +235,7 @@ struct unsigned int allow_multiple_messages: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 a1dfe3817..eeaf6f0df 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -64,6 +64,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 @@ -163,17 +192,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. */