aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2023-01-12 19:52:27 +0000
committerWerner Koch <[email protected]>2023-01-12 19:52:27 +0000
commit338a5ecaa1f11abf24514c8df994170bdb1018f4 (patch)
tree5c4d36719b79b0eefee2a7fb641eab4f2c414620
parentdirmngr: Cleanup of the no-Tor check with --gpgconf-* commands (diff)
downloadgnupg-338a5ecaa1f11abf24514c8df994170bdb1018f4.tar.gz
gnupg-338a5ecaa1f11abf24514c8df994170bdb1018f4.zip
sm: Fix compliance checking for ECC signature verification.
* common/compliance.c (gnupg_pk_is_compliant): Also consider the gcrypt vids for ECDSA et al. (gnupg_pk_is_allowed): Ditto. * sm/verify.c (gpgsm_verify): Consider the curve. Print a compliance notice for a non-compliant key. * sm/certchain.c (gpgsm_validate_chain): Silence the "switching to chain model".
-rw-r--r--common/compliance.c16
-rw-r--r--common/compliance.h2
-rw-r--r--sm/certchain.c3
-rw-r--r--sm/verify.c17
4 files changed, 31 insertions, 7 deletions
diff --git a/common/compliance.c b/common/compliance.c
index 33a19fe06..315927575 100644
--- a/common/compliance.c
+++ b/common/compliance.c
@@ -83,7 +83,9 @@ gnupg_initialize_compliance (int gnupg_module_name)
log_assert (! initialized);
/* We accept both OpenPGP-style and gcrypt-style algorithm ids.
- * Assert that they are compatible. */
+ * Assert that they are compatible. At some places gcrypt ids are
+ * used which can't be encoded in an OpenPGP algo octet; we also
+ * assert this. */
log_assert ((int) GCRY_PK_RSA == (int) PUBKEY_ALGO_RSA);
log_assert ((int) GCRY_PK_RSA_E == (int) PUBKEY_ALGO_RSA_E);
log_assert ((int) GCRY_PK_RSA_S == (int) PUBKEY_ALGO_RSA_S);
@@ -91,6 +93,9 @@ gnupg_initialize_compliance (int gnupg_module_name)
log_assert ((int) GCRY_PK_DSA == (int) PUBKEY_ALGO_DSA);
log_assert ((int) GCRY_PK_ECC == (int) PUBKEY_ALGO_ECDH);
log_assert ((int) GCRY_PK_ELG == (int) PUBKEY_ALGO_ELGAMAL);
+ log_assert ((int) GCRY_PK_ECDSA > 255);
+ log_assert ((int) GCRY_PK_ECDH > 255);
+ log_assert ((int) GCRY_PK_EDDSA > 255);
log_assert ((int) GCRY_CIPHER_NONE == (int) CIPHER_ALGO_NONE);
log_assert ((int) GCRY_CIPHER_IDEA == (int) CIPHER_ALGO_IDEA);
log_assert ((int) GCRY_CIPHER_3DES == (int) CIPHER_ALGO_3DES);
@@ -159,6 +164,9 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
case PUBKEY_ALGO_ECDH:
case PUBKEY_ALGO_ECDSA:
case PUBKEY_ALGO_EDDSA:
+ case GCRY_PK_ECDSA:
+ case GCRY_PK_ECDH:
+ case GCRY_PK_EDDSA:
algotype = is_ecc;
break;
@@ -211,7 +219,9 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
result = (curvename
&& (algo == PUBKEY_ALGO_ECDH
- || algo == PUBKEY_ALGO_ECDSA)
+ || algo == PUBKEY_ALGO_ECDSA
+ || algo == GCRY_PK_ECDH
+ || algo == GCRY_PK_ECDSA)
&& (!strcmp (curvename, "brainpoolP256r1")
|| !strcmp (curvename, "brainpoolP384r1")
|| !strcmp (curvename, "brainpoolP512r1")));
@@ -292,6 +302,7 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
break;
case PUBKEY_ALGO_ECDH:
+ case GCRY_PK_ECDH:
if (use == PK_USE_DECRYPTION)
result = 1;
else if (use == PK_USE_ENCRYPTION)
@@ -316,6 +327,7 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
break;
case PUBKEY_ALGO_ECDSA:
+ case GCRY_PK_ECDSA:
if (use == PK_USE_VERIFICATION)
result = 1;
else
diff --git a/common/compliance.h b/common/compliance.h
index 455efa544..ead11472c 100644
--- a/common/compliance.h
+++ b/common/compliance.h
@@ -45,7 +45,7 @@ enum gnupg_compliance_mode
enum pk_use_case
{
PK_USE_ENCRYPTION, PK_USE_DECRYPTION,
- PK_USE_SIGNING, PK_USE_VERIFICATION,
+ PK_USE_SIGNING, PK_USE_VERIFICATION
};
/* Flags to distinguish public key algorithm variants. */
diff --git a/sm/certchain.c b/sm/certchain.c
index 9813eca8c..cbb6e1127 100644
--- a/sm/certchain.c
+++ b/sm/certchain.c
@@ -2195,7 +2195,8 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime,
/* The root CA indicated that the chain model is to be used but
* we have not yet used it. Thus do the validation again using
* the chain model. */
- do_list (0, listmode, listfp, _("switching to chain model"));
+ if (opt.verbose)
+ do_list (0, listmode, listfp, _("switching to chain model"));
rc = do_validate_chain (ctrl, cert, checktime,
r_exptime, listmode, listfp,
(flags |= VALIDATE_FLAG_CHAIN_MODEL),
diff --git a/sm/verify.c b/sm/verify.c
index 2e40c021f..9f1216f83 100644
--- a/sm/verify.c
+++ b/sm/verify.c
@@ -299,6 +299,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
unsigned int nbits;
int pkalgo;
char *pkalgostr = NULL;
+ char *pkcurve = NULL;
char *pkfpr = NULL;
unsigned int pkalgoflags, verifyflags;
@@ -457,7 +458,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
pkfpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
pkalgostr = gpgsm_pubkey_algo_string (cert, NULL);
- pkalgo = gpgsm_get_key_algo_info (cert, &nbits);
+ pkalgo = gpgsm_get_key_algo_info2 (cert, &nbits, &pkcurve);
/* Remap the ECC algo to the algo we use. Note that EdDSA has
* already been mapped. */
if (pkalgo == GCRY_PK_ECC)
@@ -513,9 +514,19 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
goto next_signer;
}
+ /* Print compliance warning for the key. */
+ if (!opt.quiet
+ && !gnupg_pk_is_compliant (opt.compliance, pkalgo, pkalgoflags,
+ NULL, nbits, pkcurve))
+ {
+ log_info (_("WARNING: This key is not suitable for signing"
+ " in %s mode\n"),
+ gnupg_compliance_option_string (opt.compliance));
+ }
+
/* Check compliance with CO_DE_VS. */
if (gnupg_pk_is_compliant (CO_DE_VS, pkalgo, pkalgoflags,
- NULL, nbits, NULL)
+ NULL, nbits, pkcurve)
&& gnupg_gcrypt_is_compliant (CO_DE_VS)
&& gnupg_digest_is_compliant (CO_DE_VS, sigval_hash_algo))
gpgsm_status (ctrl, STATUS_VERIFICATION_COMPLIANCE_MODE,
@@ -528,7 +539,6 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
gpgsm_errors_seen = 1;
}
-
/* Now we can check the signature. */
if (msgdigest)
{ /* Signed attributes are available. */
@@ -715,6 +725,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
gcry_sexp_release (sigval);
xfree (msgdigest);
xfree (pkalgostr);
+ xfree (pkcurve);
xfree (pkfpr);
ksba_cert_release (cert);
cert = NULL;