gpg: Tweak compliance checking for verification

* common/compliance.c (gnupg_pk_is_allowed): Rework to always allow
verification.
* g10/mainproc.c (check_sig_and_print): Print a con-compliant warning.
* g10/sig-check.c (check_signature2): Use log_error instead of
log_info.
--

We should be able to verify all signatures.  So we only print a
warning.  That is the same beheavour as for untrusted keys etc.

GnuPG-bug-id: 3311
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2017-07-27 16:22:36 +02:00
parent 1bd22a85b4
commit 6502bb0d2a
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 54 additions and 48 deletions

View File

@ -200,6 +200,8 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
enum pk_use_case use, int algo, gcry_mpi_t key[], enum pk_use_case use, int algo, gcry_mpi_t key[],
unsigned int keylength, const char *curvename) unsigned int keylength, const char *curvename)
{ {
int result = 0;
if (! initialized) if (! initialized)
return 1; return 1;
@ -214,47 +216,41 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
switch (use) switch (use)
{ {
case PK_USE_DECRYPTION: case PK_USE_DECRYPTION:
return 1; case PK_USE_VERIFICATION:
result = 1;
break;
case PK_USE_ENCRYPTION: case PK_USE_ENCRYPTION:
case PK_USE_SIGNING: case PK_USE_SIGNING:
return (keylength == 2048 result = (keylength == 2048
|| keylength == 3072 || keylength == 3072
|| keylength == 4096); || keylength == 4096);
case PK_USE_VERIFICATION: break;
return (keylength == 2048
|| keylength == 3072
|| keylength == 4096
|| keylength < 2048);
default: default:
log_assert (!"reached"); log_assert (!"reached");
} }
log_assert (!"reached"); break;
case PUBKEY_ALGO_DSA: case PUBKEY_ALGO_DSA:
if (key) if (use == PK_USE_VERIFICATION)
result = 1;
else if (use == PK_USE_SIGNING && key)
{ {
size_t P = gcry_mpi_get_nbits (key[0]); size_t P = gcry_mpi_get_nbits (key[0]);
size_t Q = gcry_mpi_get_nbits (key[1]); size_t Q = gcry_mpi_get_nbits (key[1]);
return ((use == PK_USE_SIGNING result = (Q == 256 && (P == 2048 || P == 3072));
&& Q == 256 }
&& (P == 2048 || P == 3072)) break;
|| (use == PK_USE_VERIFICATION
&& P < 2048));
}
else
return 0;
log_assert (!"reached");
case PUBKEY_ALGO_ELGAMAL: case PUBKEY_ALGO_ELGAMAL:
case PUBKEY_ALGO_ELGAMAL_E: case PUBKEY_ALGO_ELGAMAL_E:
return use == PK_USE_DECRYPTION; result = (use == PK_USE_DECRYPTION);
break;
case PUBKEY_ALGO_ECDH: case PUBKEY_ALGO_ECDH:
if (use == PK_USE_DECRYPTION) if (use == PK_USE_DECRYPTION)
return 1; result = 1;
else if (use == PK_USE_ENCRYPTION) else if (use == PK_USE_ENCRYPTION)
{ {
int result = 0;
char *curve = NULL; char *curve = NULL;
if (!curvename && key) if (!curvename && key)
@ -271,17 +267,17 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
|| !strcmp (curvename, "brainpoolP512r1"))); || !strcmp (curvename, "brainpoolP512r1")));
xfree (curve); xfree (curve);
return result;
} }
else break;
return 0;
case PUBKEY_ALGO_ECDSA: case PUBKEY_ALGO_ECDSA:
{ if (use == PK_USE_VERIFICATION)
int result = 0; result = 1;
char *curve = NULL; else
{
char *curve = NULL;
if (! curvename && key) if (! curvename && key)
{ {
curve = openpgp_oid_to_str (key[0]); curve = openpgp_oid_to_str (key[0]);
curvename = openpgp_oid_to_curve (curve, 0); curvename = openpgp_oid_to_curve (curve, 0);
@ -289,31 +285,30 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
curvename = curve; curvename = curve;
} }
result = ((use == PK_USE_SIGNING result = (use == PK_USE_SIGNING
&& curvename && curvename
&& (!strcmp (curvename, "brainpoolP256r1") && (!strcmp (curvename, "brainpoolP256r1")
|| !strcmp (curvename, "brainpoolP384r1") || !strcmp (curvename, "brainpoolP384r1")
|| !strcmp (curvename, "brainpoolP512r1"))) || !strcmp (curvename, "brainpoolP512r1")));
|| use == PK_USE_VERIFICATION); xfree (curve);
}
break;
xfree (curve);
return result;
}
case PUBKEY_ALGO_EDDSA: case PUBKEY_ALGO_EDDSA:
return 0; break;
default: default:
return 0; break;
} }
log_assert (!"reached"); break;
default: default:
/* The default policy is to allow all algorithms. */ /* The default policy is to allow all algorithms. */
return 1; result = 1;
} }
log_assert (!"reached"); return result;
} }

View File

@ -2168,6 +2168,16 @@ check_sig_and_print (CTX c, kbnode_t node)
mainpkhex); mainpkhex);
} }
/* Print compliance warning for Good signatures. */
if (!rc && pk && !opt.quiet
&& !gnupg_pk_is_compliant (opt.compliance, pk->pubkey_algo,
pk->pkey, nbits_from_pk (pk), NULL))
{
log_info (_("WARNING: This key is not suitable for signing"
" in %s mode\n"),
gnupg_compliance_option_string (opt.compliance));
}
/* For good signatures compute and print the trust information. /* For good signatures compute and print the trust information.
Note that in the Tofu trust model this may ask the user on Note that in the Tofu trust model this may ask the user on
how to resolve a conflict. */ how to resolve a conflict. */

View File

@ -162,10 +162,10 @@ check_signature2 (ctrl_t ctrl,
NULL)) NULL))
{ {
/* Compliance failure. */ /* Compliance failure. */
log_info (_("key %s not suitable for signature verification" log_error (_("key %s is not suitable for signature verification"
" while in %s mode\n"), " in %s mode\n"),
keystr_from_pk (pk), keystr_from_pk (pk),
gnupg_compliance_option_string (opt.compliance)); gnupg_compliance_option_string (opt.compliance));
rc = gpg_error (GPG_ERR_PUBKEY_ALGO); rc = gpg_error (GPG_ERR_PUBKEY_ALGO);
} }
else if(!pk->flags.valid) else if(!pk->flags.valid)
@ -207,6 +207,7 @@ check_signature2 (ctrl_t ctrl,
rc = gpg_error (GPG_ERR_GENERAL); rc = gpg_error (GPG_ERR_GENERAL);
} }
} }
} }
if( !rc && sig->sig_class < 2 && is_status_enabled() ) { if( !rc && sig->sig_class < 2 && is_status_enabled() ) {