1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

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".
--

Backported-from-master: 338a5ecaa1f11abf24514c8df994170bdb1018f4
This commit is contained in:
Werner Koch 2023-01-12 20:52:27 +01:00
parent 818051432c
commit f2d25b04d7
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
4 changed files with 34 additions and 7 deletions

View File

@ -88,7 +88,9 @@ gnupg_initialize_compliance (int gnupg_module_name)
log_assert (! initialized); log_assert (! initialized);
/* We accept both OpenPGP-style and gcrypt-style algorithm ids. /* 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 == (int) PUBKEY_ALGO_RSA);
log_assert ((int) GCRY_PK_RSA_E == (int) PUBKEY_ALGO_RSA_E); log_assert ((int) GCRY_PK_RSA_E == (int) PUBKEY_ALGO_RSA_E);
log_assert ((int) GCRY_PK_RSA_S == (int) PUBKEY_ALGO_RSA_S); log_assert ((int) GCRY_PK_RSA_S == (int) PUBKEY_ALGO_RSA_S);
@ -96,6 +98,9 @@ gnupg_initialize_compliance (int gnupg_module_name)
log_assert ((int) GCRY_PK_DSA == (int) PUBKEY_ALGO_DSA); 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_ECC == (int) PUBKEY_ALGO_ECDH);
log_assert ((int) GCRY_PK_ELG == (int) PUBKEY_ALGO_ELGAMAL); 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_NONE == (int) CIPHER_ALGO_NONE);
log_assert ((int) GCRY_CIPHER_IDEA == (int) CIPHER_ALGO_IDEA); log_assert ((int) GCRY_CIPHER_IDEA == (int) CIPHER_ALGO_IDEA);
log_assert ((int) GCRY_CIPHER_3DES == (int) CIPHER_ALGO_3DES); log_assert ((int) GCRY_CIPHER_3DES == (int) CIPHER_ALGO_3DES);
@ -164,6 +169,9 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
case PUBKEY_ALGO_ECDH: case PUBKEY_ALGO_ECDH:
case PUBKEY_ALGO_ECDSA: case PUBKEY_ALGO_ECDSA:
case PUBKEY_ALGO_EDDSA: case PUBKEY_ALGO_EDDSA:
case GCRY_PK_ECDSA:
case GCRY_PK_ECDH:
case GCRY_PK_EDDSA:
algotype = is_ecc; algotype = is_ecc;
break; break;
@ -216,7 +224,9 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
result = (curvename result = (curvename
&& (algo == PUBKEY_ALGO_ECDH && (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, "brainpoolP256r1")
|| !strcmp (curvename, "brainpoolP384r1") || !strcmp (curvename, "brainpoolP384r1")
|| !strcmp (curvename, "brainpoolP512r1"))); || !strcmp (curvename, "brainpoolP512r1")));
@ -297,6 +307,7 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
break; break;
case PUBKEY_ALGO_ECDH: case PUBKEY_ALGO_ECDH:
case GCRY_PK_ECDH:
if (use == PK_USE_DECRYPTION) if (use == PK_USE_DECRYPTION)
result = 1; result = 1;
else if (use == PK_USE_ENCRYPTION) else if (use == PK_USE_ENCRYPTION)
@ -321,6 +332,7 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
break; break;
case PUBKEY_ALGO_ECDSA: case PUBKEY_ALGO_ECDSA:
case GCRY_PK_ECDSA:
if (use == PK_USE_VERIFICATION) if (use == PK_USE_VERIFICATION)
result = 1; result = 1;
else else

View File

@ -47,7 +47,7 @@ enum gnupg_compliance_mode
enum pk_use_case enum pk_use_case
{ {
PK_USE_ENCRYPTION, PK_USE_DECRYPTION, 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. */ /* Flags to distinguish public key algorithm variants. */

View File

@ -2149,7 +2149,11 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime,
&& !(flags & VALIDATE_FLAG_CHAIN_MODEL) && !(flags & VALIDATE_FLAG_CHAIN_MODEL)
&& (rootca_flags.valid && rootca_flags.chain_model)) && (rootca_flags.valid && rootca_flags.chain_model))
{ {
do_list (0, listmode, listfp, _("switching to chain model")); /* 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. */
if (opt.verbose)
do_list (0, listmode, listfp, _("switching to chain model"));
rc = do_validate_chain (ctrl, cert, checktime, rc = do_validate_chain (ctrl, cert, checktime,
r_exptime, listmode, listfp, r_exptime, listmode, listfp,
(flags |= VALIDATE_FLAG_CHAIN_MODEL), (flags |= VALIDATE_FLAG_CHAIN_MODEL),

View File

@ -300,6 +300,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
unsigned int nbits; unsigned int nbits;
int pkalgo; int pkalgo;
char *pkalgostr = NULL; char *pkalgostr = NULL;
char *pkcurve = NULL;
char *pkfpr = NULL; char *pkfpr = NULL;
unsigned int pkalgoflags, verifyflags; unsigned int pkalgoflags, verifyflags;
@ -458,7 +459,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); pkfpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
pkalgostr = gpgsm_pubkey_algo_string (cert, NULL); 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 /* Remap the ECC algo to the algo we use. Note that EdDSA has
* already been mapped. */ * already been mapped. */
if (pkalgo == GCRY_PK_ECC) 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; 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. */ /* Check compliance with CO_DE_VS. */
if (gnupg_pk_is_compliant (CO_DE_VS, pkalgo, pkalgoflags, if (gnupg_pk_is_compliant (CO_DE_VS, pkalgo, pkalgoflags,
NULL, nbits, NULL) NULL, nbits, pkcurve)
&& gnupg_gcrypt_is_compliant (CO_DE_VS) && gnupg_gcrypt_is_compliant (CO_DE_VS)
&& gnupg_digest_is_compliant (CO_DE_VS, sigval_hash_algo)) && gnupg_digest_is_compliant (CO_DE_VS, sigval_hash_algo))
gpgsm_status (ctrl, STATUS_VERIFICATION_COMPLIANCE_MODE, 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; gpgsm_errors_seen = 1;
} }
/* Now we can check the signature. */ /* Now we can check the signature. */
if (msgdigest) if (msgdigest)
{ /* Signed attributes are available. */ { /* Signed attributes are available. */
@ -709,6 +719,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
gcry_sexp_release (sigval); gcry_sexp_release (sigval);
xfree (msgdigest); xfree (msgdigest);
xfree (pkalgostr); xfree (pkalgostr);
xfree (pkcurve);
xfree (pkfpr); xfree (pkfpr);
ksba_cert_release (cert); ksba_cert_release (cert);
cert = NULL; cert = NULL;