mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-01 16:33:02 +01:00
* options.h, gpg.c (main): Add --enable-dsa2 and --disable-dsa2. Defaults
to disable. * pkclist.c (algo_available): If --enable-dsa2 is set, we're allowed to truncate hashes to fit DSA keys. * sign.c (match_dsa_hash): New. Return the best match hash for a given q size. (do_sign, hash_for, sign_file): When signing with a DSA key, if it has q==160, assume it is an old DSA key and don't allow truncation unless --enable-dsa2 is also set. q!=160 always allows truncation since they must be DSA2 keys. (make_keysig_packet): If the user doesn't specify a --cert-digest-algo, use match_dsa_hash to pick the best hash for key signatures.
This commit is contained in:
parent
b625a6d1a9
commit
0f1c0a9f28
@ -1,3 +1,21 @@
|
|||||||
|
2006-04-20 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
|
* options.h, gpg.c (main): Add --enable-dsa2 and --disable-dsa2.
|
||||||
|
Defaults to disable.
|
||||||
|
|
||||||
|
* pkclist.c (algo_available): If --enable-dsa2 is set, we're
|
||||||
|
allowed to truncate hashes to fit DSA keys.
|
||||||
|
|
||||||
|
* sign.c (match_dsa_hash): New. Return the best match hash for a
|
||||||
|
given q size.
|
||||||
|
(do_sign, hash_for, sign_file): When signing with a DSA key, if it
|
||||||
|
has q==160, assume it is an old DSA key and don't allow truncation
|
||||||
|
unless --enable-dsa2 is also set. q!=160 always allows truncation
|
||||||
|
since they must be DSA2 keys.
|
||||||
|
(make_keysig_packet): If the user doesn't specify a
|
||||||
|
--cert-digest-algo, use match_dsa_hash to pick the best hash for
|
||||||
|
key signatures.
|
||||||
|
|
||||||
2006-04-19 David Shaw <dshaw@jabberwocky.com>
|
2006-04-19 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
* gpg.c (print_mds), armor.c (armor_filter, parse_hash_header):
|
* gpg.c (print_mds), armor.c (armor_filter, parse_hash_header):
|
||||||
|
@ -362,6 +362,8 @@ enum cmd_and_opt_values
|
|||||||
oAutoKeyLocate,
|
oAutoKeyLocate,
|
||||||
oNoAutoKeyLocate,
|
oNoAutoKeyLocate,
|
||||||
oAllowMultisigVerification,
|
oAllowMultisigVerification,
|
||||||
|
oEnableDSA2,
|
||||||
|
oDisableDSA2,
|
||||||
|
|
||||||
oNoop
|
oNoop
|
||||||
};
|
};
|
||||||
@ -699,6 +701,8 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
{ oDebugCCIDDriver, "debug-ccid-driver", 0, "@"},
|
{ oDebugCCIDDriver, "debug-ccid-driver", 0, "@"},
|
||||||
#endif
|
#endif
|
||||||
{ oAllowMultisigVerification, "allow-multisig-verification", 0, "@"},
|
{ oAllowMultisigVerification, "allow-multisig-verification", 0, "@"},
|
||||||
|
{ oEnableDSA2, "enable-dsa2", 0, "@"},
|
||||||
|
{ oDisableDSA2, "disable-dsa2", 0, "@"},
|
||||||
|
|
||||||
/* These two are aliases to help users of the PGP command line
|
/* These two are aliases to help users of the PGP command line
|
||||||
product use gpg with minimal pain. Many commands are common
|
product use gpg with minimal pain. Many commands are common
|
||||||
@ -2659,6 +2663,9 @@ main (int argc, char **argv )
|
|||||||
opt.allow_multisig_verification = 1;
|
opt.allow_multisig_verification = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case oEnableDSA2: opt.flags.dsa2=1; break;
|
||||||
|
case oDisableDSA2: opt.flags.dsa2=0; break;
|
||||||
|
|
||||||
case oNoop: break;
|
case oNoop: break;
|
||||||
|
|
||||||
default : pargs.err = configfp? 1:2; break;
|
default : pargs.err = configfp? 1:2; break;
|
||||||
|
@ -222,6 +222,7 @@ struct
|
|||||||
unsigned int require_cross_cert:1;
|
unsigned int require_cross_cert:1;
|
||||||
unsigned int use_embedded_filename:1;
|
unsigned int use_embedded_filename:1;
|
||||||
unsigned int utf8_filename:1;
|
unsigned int utf8_filename:1;
|
||||||
|
unsigned int dsa2:1;
|
||||||
} flags;
|
} flags;
|
||||||
|
|
||||||
/* Linked list of ways to find a key if the key isn't on the local
|
/* Linked list of ways to find a key if the key isn't on the local
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* pkclist.c
|
/* pkclist.c
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||||
* 2004, 2005 Free Software Foundation, Inc.
|
* 2006 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -1210,8 +1210,20 @@ algo_available( preftype_t preftype, int algo, void *hint )
|
|||||||
}
|
}
|
||||||
else if( preftype == PREFTYPE_HASH )
|
else if( preftype == PREFTYPE_HASH )
|
||||||
{
|
{
|
||||||
if(hint && ((*(int *)hint) != md_digest_length(algo)))
|
if(hint)
|
||||||
return 0;
|
{
|
||||||
|
if(opt.flags.dsa2)
|
||||||
|
{
|
||||||
|
/* If --enable-dsa2 is set, then we'll accept a hash
|
||||||
|
that is larger than we need. If --enable-dsa2 is not
|
||||||
|
set, then we won't accept any hash that isn't exactly
|
||||||
|
the right size. */
|
||||||
|
if((*(int *)hint) > md_digest_length(algo))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if(((*(int *)hint) != md_digest_length(algo)))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if((PGP6 || PGP7) && (algo != DIGEST_ALGO_MD5
|
if((PGP6 || PGP7) && (algo != DIGEST_ALGO_MD5
|
||||||
&& algo != DIGEST_ALGO_SHA1
|
&& algo != DIGEST_ALGO_SHA1
|
||||||
|
133
g10/sign.c
133
g10/sign.c
@ -319,10 +319,15 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* TODO: remove this check in the future once all the
|
/* If it's a DSA key, and q is 160 bits, it might be an
|
||||||
variable-q DSA stuff makes it into the standard. */
|
old-style DSA key. If the hash doesn't match the q, fail
|
||||||
if(!opt.expert
|
unless --enable-dsa2 is set. If the q isn't 160 bits, then
|
||||||
&& sk->pubkey_algo==PUBKEY_ALGO_DSA
|
allow any hash since it must be a DSA2 key (if the hash is
|
||||||
|
too small, we'll fail in encode_md_value). */
|
||||||
|
|
||||||
|
if(sk->pubkey_algo==PUBKEY_ALGO_DSA
|
||||||
|
&& (mpi_get_nbits(sk->skey[1])/8)==20
|
||||||
|
&& !opt.flags.dsa2
|
||||||
&& md_digest_length(digest_algo)!=20)
|
&& md_digest_length(digest_algo)!=20)
|
||||||
{
|
{
|
||||||
log_error(_("DSA requires the use of a 160 bit hash algorithm\n"));
|
log_error(_("DSA requires the use of a 160 bit hash algorithm\n"));
|
||||||
@ -384,6 +389,29 @@ complete_sig( PKT_signature *sig, PKT_secret_key *sk, MD_HANDLE md )
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
match_dsa_hash(unsigned int qbytes)
|
||||||
|
{
|
||||||
|
if(qbytes<=20)
|
||||||
|
return DIGEST_ALGO_SHA1;
|
||||||
|
#ifdef USE_SHA256
|
||||||
|
if(qbytes<=28)
|
||||||
|
return DIGEST_ALGO_SHA224;
|
||||||
|
if(qbytes<=32)
|
||||||
|
return DIGEST_ALGO_SHA256;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SHA512
|
||||||
|
if(qbytes<=48)
|
||||||
|
return DIGEST_ALGO_SHA384;
|
||||||
|
if(qbytes<=64)
|
||||||
|
return DIGEST_ALGO_SHA512;
|
||||||
|
#endif
|
||||||
|
return DEFAULT_DIGEST_ALGO;
|
||||||
|
/* DEFAULT_DIGEST_ALGO will certainly fail, but it's the best wrong
|
||||||
|
answer we have if the larger SHAs aren't there. */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
First try --digest-algo. If that isn't set, see if the recipient
|
First try --digest-algo. If that isn't set, see if the recipient
|
||||||
has a preferred algorithm (which is also filtered through
|
has a preferred algorithm (which is also filtered through
|
||||||
@ -405,21 +433,50 @@ hash_for(PKT_secret_key *sk)
|
|||||||
return opt.def_digest_algo;
|
return opt.def_digest_algo;
|
||||||
else if( recipient_digest_algo )
|
else if( recipient_digest_algo )
|
||||||
return recipient_digest_algo;
|
return recipient_digest_algo;
|
||||||
else if(sk->pubkey_algo==PUBKEY_ALGO_DSA
|
else if(sk->pubkey_algo==PUBKEY_ALGO_DSA)
|
||||||
|| (sk->is_protected && sk->protect.s2k.mode==1002))
|
|
||||||
{
|
{
|
||||||
/* The sk lives on a smartcard, or it's a DSA key. DSA requires
|
unsigned int qbytes=mpi_get_nbits(sk->skey[1])/8;
|
||||||
a 160-bit hash, and current smartcards only handle SHA-1 and
|
|
||||||
RIPEMD/160 (i.e. 160-bit hashes). This is correct now, but
|
/* It's a DSA key, so find a hash that is the same size as q or
|
||||||
may need revision as the cards add algorithms and/or DSA is
|
larger. If q is 160, assume it is an old DSA key and use a
|
||||||
expanded to use larger hashes. */
|
160-bit hash unless --enable-dsa2 is set, in which case act
|
||||||
|
like a new DSA key that just happens to have a 160-bit q
|
||||||
|
(i.e. allow truncation). If q is not 160, by definition it
|
||||||
|
must be a new DSA key. */
|
||||||
|
|
||||||
|
if(opt.personal_digest_prefs)
|
||||||
|
{
|
||||||
|
prefitem_t *prefs;
|
||||||
|
|
||||||
|
if(qbytes!=20 || opt.flags.dsa2)
|
||||||
|
{
|
||||||
|
for(prefs=opt.personal_digest_prefs;prefs->type;prefs++)
|
||||||
|
if(md_digest_length(prefs->value)>=qbytes)
|
||||||
|
return prefs->value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(prefs=opt.personal_digest_prefs;prefs->type;prefs++)
|
||||||
|
if(md_digest_length(prefs->value)==qbytes)
|
||||||
|
return prefs->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return match_dsa_hash(qbytes);
|
||||||
|
}
|
||||||
|
else if(sk->is_protected && sk->protect.s2k.mode==1002)
|
||||||
|
{
|
||||||
|
/* The sk lives on a smartcard, and current smartcards only
|
||||||
|
handle SHA-1 and RIPEMD/160. This is correct now, but may
|
||||||
|
need revision as the cards add algorithms. */
|
||||||
|
|
||||||
if(opt.personal_digest_prefs)
|
if(opt.personal_digest_prefs)
|
||||||
{
|
{
|
||||||
prefitem_t *prefs;
|
prefitem_t *prefs;
|
||||||
|
|
||||||
for(prefs=opt.personal_digest_prefs;prefs->type;prefs++)
|
for(prefs=opt.personal_digest_prefs;prefs->type;prefs++)
|
||||||
if(md_digest_length(prefs->value)==20)
|
if(prefs->value==DIGEST_ALGO_SHA1
|
||||||
|
|| prefs->value==DIGEST_ALGO_RMD160)
|
||||||
return prefs->value;
|
return prefs->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,22 +879,35 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
|||||||
int hashlen=0,algo;
|
int hashlen=0,algo;
|
||||||
|
|
||||||
/* Of course, if the recipient asks for something
|
/* Of course, if the recipient asks for something
|
||||||
unreasonable (like a non-160-bit hash for DSA, for
|
unreasonable (like a non-160-bit hash for DSA without
|
||||||
example), then don't do it. Check all sk's - if any
|
--enable-dsa2, for example), then don't do it. Check
|
||||||
are DSA, then the hash must be 160-bit. In the future
|
all sk's - if any are DSA, then the hash has
|
||||||
this can be more complex with different hashes for each
|
restrictions. In the future this can be more complex
|
||||||
sk, but so long as there is only one signing algorithm
|
with different hashes for each sk, but so long as there
|
||||||
with hash restrictions, this is ok. -dms */
|
is only one signing algorithm with hash restrictions,
|
||||||
|
this is ok. -dms */
|
||||||
/* Current smartcards only do 160-bit hashes as well.
|
|
||||||
Note that this may well have to change as the cards add
|
|
||||||
algorithms. */
|
|
||||||
|
|
||||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
|
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
|
||||||
if(sk_rover->sk->pubkey_algo==PUBKEY_ALGO_DSA
|
{
|
||||||
|| (sk_rover->sk->is_protected
|
if(sk_rover->sk->pubkey_algo==PUBKEY_ALGO_DSA)
|
||||||
&& sk_rover->sk->protect.s2k.mode==1002))
|
{
|
||||||
hashlen=20;
|
if(opt.flags.dsa2)
|
||||||
|
hashlen=mpi_get_nbits(sk_rover->sk->skey[1])/8;
|
||||||
|
else
|
||||||
|
hashlen=20;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(sk_rover->sk->is_protected
|
||||||
|
&& sk_rover->sk->protect.s2k.mode==1002)
|
||||||
|
{
|
||||||
|
/* Current smartcards only do 160-bit hashes.
|
||||||
|
Note that this may well have to change as the
|
||||||
|
cards add algorithms. */
|
||||||
|
|
||||||
|
hashlen=20;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if((algo=
|
if((algo=
|
||||||
select_algo_from_prefs(pk_list,PREFTYPE_HASH,-1,
|
select_algo_from_prefs(pk_list,PREFTYPE_HASH,-1,
|
||||||
@ -1350,16 +1420,19 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
|||||||
{
|
{
|
||||||
/* Basically, this means use SHA1 always unless it's a v3 RSA
|
/* Basically, this means use SHA1 always unless it's a v3 RSA
|
||||||
key making a v3 cert (use MD5), or the user specified
|
key making a v3 cert (use MD5), or the user specified
|
||||||
something (use whatever they said). They still must use a
|
something (use whatever they said), or it's DSA (use the
|
||||||
160-bit hash with DSA, or the signature will fail. Note
|
best match). They still can't pick an inappropriate hash
|
||||||
that this still allows the caller of make_keysig_packet to
|
for DSA or the signature will fail. Note that this still
|
||||||
override the user setting if it must. */
|
allows the caller of make_keysig_packet to override the
|
||||||
|
user setting if it must. */
|
||||||
|
|
||||||
if(opt.cert_digest_algo)
|
if(opt.cert_digest_algo)
|
||||||
digest_algo=opt.cert_digest_algo;
|
digest_algo=opt.cert_digest_algo;
|
||||||
else if(sk->pubkey_algo==PUBKEY_ALGO_RSA
|
else if(sk->pubkey_algo==PUBKEY_ALGO_RSA
|
||||||
&& pk->version<4 && sigversion<4)
|
&& pk->version<4 && sigversion<4)
|
||||||
digest_algo = DIGEST_ALGO_MD5;
|
digest_algo = DIGEST_ALGO_MD5;
|
||||||
|
else if(sk->pubkey_algo==PUBKEY_ALGO_DSA)
|
||||||
|
digest_algo = match_dsa_hash(mpi_get_nbits(sk->skey[1])/8);
|
||||||
else
|
else
|
||||||
digest_algo = DIGEST_ALGO_SHA1;
|
digest_algo = DIGEST_ALGO_SHA1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user