1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

dirmngr: Support ECDSA for CRLs

* dirmngr/crlcache.c (finish_sig_check): Support ECDSA.
* dirmngr/validate.c (check_cert_sig): Ditto.  Remove the never
used support for DSA.

(cherry picked from commit de87c8e1ea)
This commit is contained in:
Werner Koch 2022-11-15 08:53:41 +01:00
parent 7c3aeb2a57
commit 502d43ac30
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
2 changed files with 114 additions and 12 deletions

View file

@ -231,7 +231,8 @@ allowed_ca (ksba_cert_t cert, int *chainlen)
/* The German SigG Root CA's certificate does not flag
itself as a CA; thus we relax this requirement if we
trust a root CA. I think this is reasonable. Note, that
gpgsm implements a far stricter scheme here. */
gpgsm implements a far stricter scheme here but also
features a "relax" flag in the trustlist.txt. */
if (chainlen)
*chainlen = 3; /* That is what the SigG implements. */
if (opt.verbose)
@ -952,15 +953,24 @@ check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
int digestlen;
unsigned char *digest;
int use_pss = 0;
unsigned int saltlen;
unsigned int saltlen; /* (use is controlled by use_pss) */
/* Hash the target certificate using the algorithm from that certificate. */
algoid = ksba_cert_get_digest_algo (cert);
algo = gcry_md_map_name (algoid);
if (!algo && algoid && !strcmp (algoid, "1.2.840.113549.1.1.10"))
use_pss = 1;
else if (!algo && algoid && !strcmp (algoid, "1.2.840.10045.4.3.1"))
algo = GCRY_MD_SHA224; /* ecdsa-with-sha224 */
else if (!algo && algoid && !strcmp (algoid, "1.2.840.10045.4.3.2"))
algo = GCRY_MD_SHA256; /* ecdsa-with-sha256 */
else if (!algo && algoid && !strcmp (algoid, "1.2.840.10045.4.3.3"))
algo = GCRY_MD_SHA384; /* ecdsa-with-sha384 */
else if (!algo && algoid && !strcmp (algoid, "1.2.840.10045.4.3.4"))
algo = GCRY_MD_SHA512; /* ecdsa-with-sha512 */
else if (!algo)
{
log_debug ("XXXXX %s\n", __func__);
log_error (_("unknown hash algorithm '%s'\n"), algoid? algoid:"?");
return gpg_error (GPG_ERR_GENERAL);
}
@ -1106,19 +1116,48 @@ check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
digest,
saltlen);
}
else if (pk_algo_from_sexp (s_pkey) == GCRY_PK_DSA)
else if (pk_algo_from_sexp (s_pkey) == GCRY_PK_ECC)
{
/* NB.: We support only SHA-1 here because we had problems back
* then to get test data for DSA-2. Meanwhile DSA has been
* replaced by ECDSA which we do not yet support. */
if (digestlen != 20)
unsigned int qbits0, qbits;
qbits0 = gcry_pk_get_nbits (s_pkey);
qbits = qbits0 == 521? 512 : qbits0;
if ((qbits%8))
{
log_error ("ECDSA requires the hash length to be a"
" multiple of 8 bits\n");
err = gpg_error (GPG_ERR_INTERNAL);
goto leave;
}
/* Don't allow any Q smaller than 160 bits. */
if (qbits < 160)
{
log_error (_("%s key uses an unsafe (%u bit) hash\n"),
"ECDSA", qbits0);
err = gpg_error (GPG_ERR_INTERNAL);
goto leave;
}
/* Check if we're too short. */
if (digestlen < qbits/8)
{
log_error ("DSA requires the use of a 160 bit hash algorithm\n");
gcry_md_close (md);
gcry_sexp_release (s_sig);
gcry_sexp_release (s_pkey);
return gpg_error (GPG_ERR_INTERNAL);
log_error (_("a %u bit hash is not valid for a %u bit %s key\n"),
(unsigned int)digestlen*8,
qbits0,
"ECDSA");
if (digestlen < 20)
{
err = gpg_error (GPG_ERR_INTERNAL);
goto leave;
}
}
/* Truncate. */
if (digestlen > qbits/8)
digestlen = qbits/8;
err = gcry_sexp_build (&s_hash, NULL, "(data(flags raw)(value %b))",
(int)digestlen, digest);
}
@ -1132,6 +1171,8 @@ check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
err = gcry_pk_verify (s_sig, s_hash, s_pkey);
if (DBG_X509)
log_debug ("gcry_pk_verify: %s\n", gpg_strerror (err));
leave:
gcry_md_close (md);
gcry_sexp_release (s_sig);
gcry_sexp_release (s_hash);