mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
* certcheck.c (do_encode_md): Add arg PKEY. Add support for DSA2
and all ECDSA sizes. (get_dsa_qbits): New. (pk_algo_from_sexp): A key will never contain ecdsa as algorithm, so remove that.
This commit is contained in:
parent
4c48abebfe
commit
e3a8e6b727
@ -1,3 +1,11 @@
|
|||||||
|
2007-04-19 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* certcheck.c (do_encode_md): Add arg PKEY. Add support for DSA2
|
||||||
|
and all ECDSA sizes.
|
||||||
|
(get_dsa_qbits): New.
|
||||||
|
(pk_algo_from_sexp): A key will never contain ecdsa as algorithm,
|
||||||
|
so remove that.
|
||||||
|
|
||||||
2007-04-18 Werner Koch <wk@g10code.com>
|
2007-04-18 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* certcheck.c (do_encode_md): Support 160 bit ECDSA.
|
* certcheck.c (do_encode_md): Support 160 bit ECDSA.
|
||||||
|
@ -35,10 +35,38 @@
|
|||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
/* Return the number of bits of the Q parameter from the DSA key
|
||||||
|
KEY. */
|
||||||
|
static unsigned int
|
||||||
|
get_dsa_qbits (gcry_sexp_t key)
|
||||||
|
{
|
||||||
|
gcry_sexp_t l1, l2;
|
||||||
|
gcry_mpi_t q;
|
||||||
|
unsigned int nbits;
|
||||||
|
|
||||||
|
l1 = gcry_sexp_find_token (key, "public-key", 0);
|
||||||
|
if (!l1)
|
||||||
|
return 0; /* Does not contain a key object. */
|
||||||
|
l2 = gcry_sexp_cadr (l1);
|
||||||
|
gcry_sexp_release (l1);
|
||||||
|
l1 = gcry_sexp_find_token (l2, "q", 1);
|
||||||
|
gcry_sexp_release (l2);
|
||||||
|
if (!l1)
|
||||||
|
return 0; /* Invalid object. */
|
||||||
|
q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
|
||||||
|
gcry_sexp_release (l1);
|
||||||
|
if (!q)
|
||||||
|
return 0; /* Missing value. */
|
||||||
|
nbits = gcry_mpi_get_nbits (q);
|
||||||
|
gcry_mpi_release (q);
|
||||||
|
|
||||||
|
return nbits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_encode_md (gcry_md_hd_t md, int algo, int pkalgo, unsigned int nbits,
|
do_encode_md (gcry_md_hd_t md, int algo, int pkalgo, unsigned int nbits,
|
||||||
gcry_mpi_t *r_val)
|
gcry_sexp_t pkey, gcry_mpi_t *r_val)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
size_t nframe;
|
size_t nframe;
|
||||||
@ -46,17 +74,54 @@ do_encode_md (gcry_md_hd_t md, int algo, int pkalgo, unsigned int nbits,
|
|||||||
|
|
||||||
if (pkalgo == GCRY_PK_DSA || pkalgo == GCRY_PK_ECDSA)
|
if (pkalgo == GCRY_PK_DSA || pkalgo == GCRY_PK_ECDSA)
|
||||||
{
|
{
|
||||||
|
unsigned int qbits;
|
||||||
|
|
||||||
|
if ( pkalgo == GCRY_PK_ECDSA )
|
||||||
|
qbits = gcry_pk_get_nbits (pkey);
|
||||||
|
else
|
||||||
|
qbits = get_dsa_qbits (pkey);
|
||||||
|
|
||||||
|
if ( (qbits%8) )
|
||||||
|
{
|
||||||
|
log_error(_("DSA requires the hash length to be a"
|
||||||
|
" multiple of 8 bits\n"));
|
||||||
|
return gpg_error (GPG_ERR_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't allow any Q smaller than 160 bits. We don't want
|
||||||
|
someone to issue signatures from a key with a 16-bit Q or
|
||||||
|
something like that, which would look correct but allow
|
||||||
|
trivial forgeries. Yes, I know this rules out using MD5 with
|
||||||
|
DSA. ;) */
|
||||||
|
if (qbits < 160)
|
||||||
|
{
|
||||||
|
log_error (_("%s key uses an unsafe (%u bit) hash\n"),
|
||||||
|
gcry_pk_algo_name (pkalgo), qbits);
|
||||||
|
return gpg_error (GPG_ERR_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we're too short. Too long is safe as we'll
|
||||||
|
automatically left-truncate. */
|
||||||
nframe = gcry_md_get_algo_dlen (algo);
|
nframe = gcry_md_get_algo_dlen (algo);
|
||||||
if (nframe != 20)
|
if (nframe < 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"),
|
||||||
return gpg_error (GPG_ERR_INTERNAL);
|
(unsigned int)nframe*8,
|
||||||
|
gcry_pk_get_nbits (pkey),
|
||||||
|
gcry_pk_algo_name (pkalgo));
|
||||||
|
/* FIXME: we need to check the requirements for ECDSA. */
|
||||||
|
if (nframe < 20 || pkalgo == GCRY_PK_DSA )
|
||||||
|
return gpg_error (GPG_ERR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = xtrymalloc (nframe);
|
frame = xtrymalloc (nframe);
|
||||||
if (!frame)
|
if (!frame)
|
||||||
return out_of_core ();
|
return out_of_core ();
|
||||||
memcpy (frame, gcry_md_read (md, algo), nframe);
|
memcpy (frame, gcry_md_read (md, algo), nframe);
|
||||||
n = nframe;
|
n = nframe;
|
||||||
|
/* Truncate. */
|
||||||
|
if (n > qbits/8)
|
||||||
|
n = qbits/8;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -143,8 +208,6 @@ pk_algo_from_sexp (gcry_sexp_t pkey)
|
|||||||
algo = GCRY_PK_RSA;
|
algo = GCRY_PK_RSA;
|
||||||
else if (n==3 && !memcmp (name, "dsa", 3))
|
else if (n==3 && !memcmp (name, "dsa", 3))
|
||||||
algo = GCRY_PK_DSA;
|
algo = GCRY_PK_DSA;
|
||||||
else if (n==5 && !memcmp (name, "ecdsa", 5))
|
|
||||||
algo = GCRY_PK_ECDSA;
|
|
||||||
/* Because this function is called only for verification we can
|
/* Because this function is called only for verification we can
|
||||||
assume that ECC actually means ECDSA. */
|
assume that ECC actually means ECDSA. */
|
||||||
else if (n==3 && !memcmp (name, "ecc", 3))
|
else if (n==3 && !memcmp (name, "ecc", 3))
|
||||||
@ -158,10 +221,9 @@ pk_algo_from_sexp (gcry_sexp_t pkey)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* Check the signature on CERT using the ISSUER-CERT. This function
|
||||||
Check the signature on CERT using the ISSUER-CERT. This function
|
does only test the cryptographic signature and nothing else. It is
|
||||||
does only test the cryptographic signature and nothing else. It is
|
assumed that the ISSUER_CERT is valid. */
|
||||||
assumed that the ISSUER_CERT is valid. */
|
|
||||||
int
|
int
|
||||||
gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
|
gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
|
||||||
{
|
{
|
||||||
@ -249,7 +311,7 @@ gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = do_encode_md (md, algo, pk_algo_from_sexp (s_pkey),
|
rc = do_encode_md (md, algo, pk_algo_from_sexp (s_pkey),
|
||||||
gcry_pk_get_nbits (s_pkey), &frame);
|
gcry_pk_get_nbits (s_pkey), s_pkey, &frame);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
gcry_md_close (md);
|
gcry_md_close (md);
|
||||||
@ -322,7 +384,7 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
|
|||||||
|
|
||||||
|
|
||||||
rc = do_encode_md (md, algo, pk_algo_from_sexp (s_pkey),
|
rc = do_encode_md (md, algo, pk_algo_from_sexp (s_pkey),
|
||||||
gcry_pk_get_nbits (s_pkey), &frame);
|
gcry_pk_get_nbits (s_pkey), s_pkey, &frame);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
gcry_sexp_release (s_sig);
|
gcry_sexp_release (s_sig);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user