mirror of git://git.gnupg.org/gnupg.git
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.
This commit is contained in:
parent
890e9849b5
commit
de87c8e1ea
|
@ -1660,6 +1660,7 @@ finish_sig_check (ksba_crl_t crl, gcry_md_hd_t md, int algo,
|
||||||
size_t n;
|
size_t n;
|
||||||
gcry_sexp_t s_sig = NULL, s_hash = NULL, s_pkey = NULL;
|
gcry_sexp_t s_sig = NULL, s_hash = NULL, s_pkey = NULL;
|
||||||
unsigned int saltlen = 0; /* (used only with use_pss) */
|
unsigned int saltlen = 0; /* (used only with use_pss) */
|
||||||
|
int pkalgo;
|
||||||
|
|
||||||
/* This also stops debugging on the MD. */
|
/* This also stops debugging on the MD. */
|
||||||
gcry_md_final (md);
|
gcry_md_final (md);
|
||||||
|
@ -1787,6 +1788,53 @@ finish_sig_check (ksba_crl_t crl, gcry_md_hd_t md, int algo,
|
||||||
gcry_md_read (md, algo),
|
gcry_md_read (md, algo),
|
||||||
saltlen);
|
saltlen);
|
||||||
}
|
}
|
||||||
|
else if ((pkalgo = pk_algo_from_sexp (s_pkey)) == GCRY_PK_ECC)
|
||||||
|
{
|
||||||
|
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"),
|
||||||
|
gcry_pk_algo_name (pkalgo), qbits0);
|
||||||
|
err = gpg_error (GPG_ERR_INTERNAL);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we're too short. */
|
||||||
|
n = gcry_md_get_algo_dlen (algo);
|
||||||
|
if (n < qbits/8)
|
||||||
|
{
|
||||||
|
log_error (_("a %u bit hash is not valid for a %u bit %s key\n"),
|
||||||
|
(unsigned int)n*8,
|
||||||
|
qbits0,
|
||||||
|
gcry_pk_algo_name (pkalgo));
|
||||||
|
if (n < 20)
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_INTERNAL);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Truncate. */
|
||||||
|
if (n > qbits/8)
|
||||||
|
n = qbits/8;
|
||||||
|
|
||||||
|
err = gcry_sexp_build (&s_hash, NULL, "%b",
|
||||||
|
(int)n,
|
||||||
|
gcry_md_read (md, algo));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
err = gcry_sexp_build (&s_hash, NULL,
|
err = gcry_sexp_build (&s_hash, NULL,
|
||||||
|
|
|
@ -231,7 +231,8 @@ allowed_ca (ksba_cert_t cert, int *chainlen)
|
||||||
/* The German SigG Root CA's certificate does not flag
|
/* The German SigG Root CA's certificate does not flag
|
||||||
itself as a CA; thus we relax this requirement if we
|
itself as a CA; thus we relax this requirement if we
|
||||||
trust a root CA. I think this is reasonable. Note, that
|
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)
|
if (chainlen)
|
||||||
*chainlen = 3; /* That is what the SigG implements. */
|
*chainlen = 3; /* That is what the SigG implements. */
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
|
@ -954,7 +955,7 @@ check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
|
||||||
int digestlen;
|
int digestlen;
|
||||||
unsigned char *digest;
|
unsigned char *digest;
|
||||||
int use_pss = 0;
|
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. */
|
/* Hash the target certificate using the algorithm from that certificate. */
|
||||||
algoid = ksba_cert_get_digest_algo (cert);
|
algoid = ksba_cert_get_digest_algo (cert);
|
||||||
|
@ -1108,19 +1109,48 @@ check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
|
||||||
digest,
|
digest,
|
||||||
saltlen);
|
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
|
unsigned int qbits0, qbits;
|
||||||
* then to get test data for DSA-2. Meanwhile DSA has been
|
|
||||||
* replaced by ECDSA which we do not yet support. */
|
qbits0 = gcry_pk_get_nbits (s_pkey);
|
||||||
if (digestlen != 20)
|
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");
|
log_error (_("a %u bit hash is not valid for a %u bit %s key\n"),
|
||||||
gcry_md_close (md);
|
(unsigned int)digestlen*8,
|
||||||
gcry_sexp_release (s_sig);
|
qbits0,
|
||||||
gcry_sexp_release (s_pkey);
|
"ECDSA");
|
||||||
return gpg_error (GPG_ERR_INTERNAL);
|
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))",
|
err = gcry_sexp_build (&s_hash, NULL, "(data(flags raw)(value %b))",
|
||||||
(int)digestlen, digest);
|
(int)digestlen, digest);
|
||||||
}
|
}
|
||||||
|
@ -1134,6 +1164,8 @@ check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
|
||||||
err = gcry_pk_verify (s_sig, s_hash, s_pkey);
|
err = gcry_pk_verify (s_sig, s_hash, s_pkey);
|
||||||
if (DBG_X509)
|
if (DBG_X509)
|
||||||
log_debug ("gcry_pk_verify: %s\n", gpg_strerror (err));
|
log_debug ("gcry_pk_verify: %s\n", gpg_strerror (err));
|
||||||
|
|
||||||
|
leave:
|
||||||
gcry_md_close (md);
|
gcry_md_close (md);
|
||||||
gcry_sexp_release (s_sig);
|
gcry_sexp_release (s_sig);
|
||||||
gcry_sexp_release (s_hash);
|
gcry_sexp_release (s_hash);
|
||||||
|
|
Loading…
Reference in New Issue