mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-08 12:44:23 +01:00
* main.h, seskey.c (encode_md_value): Modify to allow a q size greater
than 160 bits as per DSA2. This will allow us to verify and issue DSA2 signatures for some backwards compatibility once we start generating DSA2 keys. * sign.c (do_sign), sig-check.c (do_check): Change all callers. * sign.c (do_sign): Enforce the 160-bit check for new signatures here since encode_md_value can handle non-160-bit digests now. This will need to come out once the standard for DSA2 is firmed up.
This commit is contained in:
parent
a43c1bc874
commit
92e1528bf2
@ -1,3 +1,16 @@
|
||||
2006-03-30 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* main.h, seskey.c (encode_md_value): Modify to allow a q size
|
||||
greater than 160 bits as per DSA2. This will allow us to verify
|
||||
and issue DSA2 signatures for some backwards compatibility once we
|
||||
start generating DSA2 keys.
|
||||
* sign.c (do_sign), sig-check.c (do_check): Change all callers.
|
||||
|
||||
* sign.c (do_sign): Enforce the 160-bit check for new signatures
|
||||
here since encode_md_value can handle non-160-bit digests now.
|
||||
This will need to come out once the standard for DSA2 is firmed
|
||||
up.
|
||||
|
||||
2006-03-22 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* getkey.c (parse_auto_key_locate): Silently strip out duplicates
|
||||
|
@ -203,8 +203,8 @@ void try_make_homedir( const char *fname );
|
||||
/*-- seskey.c --*/
|
||||
void make_session_key( DEK *dek );
|
||||
MPI encode_session_key( DEK *dek, unsigned nbits );
|
||||
MPI encode_md_value( int pubkey_algo, MD_HANDLE md,
|
||||
int hash_algo, unsigned nbits );
|
||||
MPI encode_md_value( PKT_public_key *pk, PKT_secret_key *sk,
|
||||
MD_HANDLE md, int hash_algo );
|
||||
|
||||
/*-- import.c --*/
|
||||
int parse_import_options(char *str,unsigned int *options,int noisy);
|
||||
|
90
g10/seskey.c
90
g10/seskey.c
@ -195,36 +195,76 @@ do_encode_md( MD_HANDLE md, int algo, size_t len, unsigned nbits,
|
||||
|
||||
/****************
|
||||
* Encode a message digest into an MPI.
|
||||
* v3compathack is used to work around a bug in old GnuPG versions
|
||||
* which did put the algo identifier inseatd of the block type 1 into
|
||||
* the encoded value. Setting this flag forces the old behaviour.
|
||||
* If it's for a DSA signature, make sure that the hash is large
|
||||
* enough to fill up q. If the hash is too big, take the leftmost
|
||||
* bits.
|
||||
*/
|
||||
MPI
|
||||
encode_md_value( int pubkey_algo, MD_HANDLE md,
|
||||
int hash_algo, unsigned nbits )
|
||||
encode_md_value( PKT_public_key *pk, PKT_secret_key *sk,
|
||||
MD_HANDLE md, int hash_algo )
|
||||
{
|
||||
int algo = hash_algo? hash_algo : md_get_algo(md);
|
||||
const byte *asn;
|
||||
size_t asnlen, mdlen;
|
||||
MPI frame;
|
||||
MPI frame;
|
||||
|
||||
if( pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
mdlen = md_digest_length (hash_algo);
|
||||
if (mdlen != 20) {
|
||||
log_error (_("DSA requires the use of a 160 bit hash algorithm\n"));
|
||||
return NULL;
|
||||
}
|
||||
assert(hash_algo);
|
||||
assert(pk || sk);
|
||||
|
||||
frame = md_is_secure(md)? mpi_alloc_secure((md_digest_length(hash_algo)
|
||||
+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB )
|
||||
: mpi_alloc((md_digest_length(hash_algo)
|
||||
+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
|
||||
mpi_set_buffer( frame, md_read(md, hash_algo),
|
||||
md_digest_length(hash_algo), 0 );
|
||||
if((pk?pk->pubkey_algo:sk->pubkey_algo) == PUBKEY_ALGO_DSA)
|
||||
{
|
||||
/* It's a DSA signature, so find out the size of q. */
|
||||
|
||||
unsigned int qbytes=mpi_get_nbits(pk?pk->pkey[1]:sk->skey[1]);
|
||||
|
||||
/* Make sure it is a multiple of 8 bits. */
|
||||
|
||||
if(qbytes%8)
|
||||
{
|
||||
log_error(_("DSA requires the hash length to be a"
|
||||
" multiple of 8 bits\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Don't allow any q smaller than 160 bits. This might need a
|
||||
revisit as the DSA2 design firms up, but for now, 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(qbytes<160)
|
||||
{
|
||||
log_error(_("DSA key %s uses an unsafe (%u bit) hash\n"),
|
||||
pk?keystr_from_pk(pk):keystr_from_sk(sk),qbytes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qbytes/=8;
|
||||
|
||||
/* Check if we're too short. Too long is safe as we'll
|
||||
automatically left-truncate. */
|
||||
|
||||
if(md_digest_length(hash_algo) < qbytes)
|
||||
{
|
||||
log_error(_("DSA key %s requires a %u bit or larger hash\n"),
|
||||
pk?keystr_from_pk(pk):keystr_from_sk(sk),qbytes*8);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
frame = md_is_secure(md)? mpi_alloc_secure((qbytes+BYTES_PER_MPI_LIMB-1)
|
||||
/ BYTES_PER_MPI_LIMB )
|
||||
: mpi_alloc((qbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
|
||||
|
||||
mpi_set_buffer( frame, md_read(md, hash_algo), qbytes, 0 );
|
||||
}
|
||||
else {
|
||||
asn = md_asn_oid( algo, &asnlen, &mdlen );
|
||||
frame = do_encode_md( md, algo, mdlen, nbits, asn, asnlen );
|
||||
else
|
||||
{
|
||||
const byte *asn;
|
||||
size_t asnlen,mdlen;
|
||||
|
||||
asn = md_asn_oid( hash_algo, &asnlen, &mdlen );
|
||||
frame = do_encode_md( md, hash_algo, mdlen,
|
||||
mpi_get_nbits(pk?pk->pkey[0]:sk->skey[0]),
|
||||
asn, asnlen );
|
||||
}
|
||||
return frame;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
@ -274,8 +274,7 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
|
||||
}
|
||||
md_final( digest );
|
||||
|
||||
result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
|
||||
mpi_get_nbits(pk->pkey[0]) );
|
||||
result = encode_md_value( pk, NULL, digest, sig->digest_algo );
|
||||
if (!result)
|
||||
return G10ERR_GENERAL;
|
||||
ctx.sig = sig;
|
||||
|
17
g10/sign.c
17
g10/sign.c
@ -319,8 +319,17 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
|
||||
}
|
||||
else
|
||||
{
|
||||
frame = encode_md_value( sk->pubkey_algo, md,
|
||||
digest_algo, mpi_get_nbits(sk->skey[0]) );
|
||||
/* TODO: remove this check in the future once all the
|
||||
variable-q DSA stuff makes it into the standard. */
|
||||
if(!opt.expert
|
||||
&& sk->pubkey_algo==PUBKEY_ALGO_DSA
|
||||
&& md_digest_length(digest_algo)!=20)
|
||||
{
|
||||
log_error(_("DSA requires the use of a 160 bit hash algorithm\n"));
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
|
||||
frame = encode_md_value( NULL, sk, md, digest_algo );
|
||||
if (!frame)
|
||||
return G10ERR_GENERAL;
|
||||
rc = pubkey_sign( sk->pubkey_algo, sig->data, frame, sk->skey );
|
||||
@ -336,9 +345,7 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
|
||||
if( get_pubkey( pk, sig->keyid ) )
|
||||
rc = G10ERR_NO_PUBKEY;
|
||||
else {
|
||||
frame = encode_md_value (pk->pubkey_algo, md,
|
||||
sig->digest_algo,
|
||||
mpi_get_nbits(pk->pkey[0]) );
|
||||
frame = encode_md_value (pk, NULL, md, sig->digest_algo );
|
||||
if (!frame)
|
||||
rc = G10ERR_GENERAL;
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user