mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-23 10:29:58 +01:00
* sign.c (hash_for, sign_file): When encrypting and signing at the same
time, consult the various hash prefs to pick a hash algorithm to use. Pass in a 160-bit hint if any of the signing keys are DSA. * keydb.h, pkclist.c (select_algo_from_prefs, algo_available): Pass a "hints" opaque pointer in to let the caller give hints as to what algorithms would be acceptable. The only current hint is for PREFTYPE_HASH to require a 160-bit hash for DSA. Change all callers in encode.c (encode_crypt, encrypt_filter) and sign.c (sign_file). If we settle on MD5 as the best algorithm based solely on recepient keys and SHA1 is also a possibility, use SHA1 unless the user intentionally chose MD5. This is as per 2440:13. * exec.c (make_tempdir): Fix duplicated filename problem.
This commit is contained in:
parent
ae02cf4630
commit
fd08b13528
@ -1,3 +1,21 @@
|
|||||||
|
2002-06-04 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
|
* sign.c (hash_for, sign_file): When encrypting and signing at the
|
||||||
|
same time, consult the various hash prefs to pick a hash algorithm
|
||||||
|
to use. Pass in a 160-bit hint if any of the signing keys are
|
||||||
|
DSA.
|
||||||
|
|
||||||
|
* keydb.h, pkclist.c (select_algo_from_prefs, algo_available):
|
||||||
|
Pass a "hints" opaque pointer in to let the caller give hints as
|
||||||
|
to what algorithms would be acceptable. The only current hint is
|
||||||
|
for PREFTYPE_HASH to require a 160-bit hash for DSA. Change all
|
||||||
|
callers in encode.c (encode_crypt, encrypt_filter) and sign.c
|
||||||
|
(sign_file). If we settle on MD5 as the best algorithm based
|
||||||
|
solely on recepient keys and SHA1 is also a possibility, use SHA1
|
||||||
|
unless the user intentionally chose MD5. This is as per 2440:13.
|
||||||
|
|
||||||
|
* exec.c (make_tempdir): Fix duplicated filename problem.
|
||||||
|
|
||||||
2002-06-03 David Shaw <dshaw@jabberwocky.com>
|
2002-06-03 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
* packet.h, parse-packet.c (enum_sig_subpkt): Report back from
|
* packet.h, parse-packet.c (enum_sig_subpkt): Report back from
|
||||||
|
@ -336,7 +336,7 @@ encode_crypt( const char *filename, STRLIST remusr )
|
|||||||
/* create a session key */
|
/* create a session key */
|
||||||
cfx.dek = m_alloc_secure_clear (sizeof *cfx.dek);
|
cfx.dek = m_alloc_secure_clear (sizeof *cfx.dek);
|
||||||
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
|
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
|
||||||
cfx.dek->algo = select_algo_from_prefs( pk_list, PREFTYPE_SYM );
|
cfx.dek->algo = select_algo_from_prefs( pk_list, PREFTYPE_SYM, NULL );
|
||||||
/* The only way select_algo_from_prefs can fail here is when
|
/* The only way select_algo_from_prefs can fail here is when
|
||||||
mixing v3 and v4 keys, as v4 keys have an implicit
|
mixing v3 and v4 keys, as v4 keys have an implicit
|
||||||
preference entry for 3DES, and the pk_list cannot be empty.
|
preference entry for 3DES, and the pk_list cannot be empty.
|
||||||
@ -415,7 +415,8 @@ encode_crypt( const char *filename, STRLIST remusr )
|
|||||||
|
|
||||||
if(compr_algo==-1)
|
if(compr_algo==-1)
|
||||||
{
|
{
|
||||||
if((compr_algo=select_algo_from_prefs( pk_list, PREFTYPE_ZIP))==-1)
|
if((compr_algo=
|
||||||
|
select_algo_from_prefs(pk_list,PREFTYPE_ZIP,NULL))==-1)
|
||||||
compr_algo=DEFAULT_COMPRESS_ALGO;
|
compr_algo=DEFAULT_COMPRESS_ALGO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,7 +486,7 @@ encrypt_filter( void *opaque, int control,
|
|||||||
|
|
||||||
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
|
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
|
||||||
efx->cfx.dek->algo =
|
efx->cfx.dek->algo =
|
||||||
select_algo_from_prefs( efx->pk_list, PREFTYPE_SYM );
|
select_algo_from_prefs( efx->pk_list, PREFTYPE_SYM, NULL );
|
||||||
if( efx->cfx.dek->algo == -1 ) {
|
if( efx->cfx.dek->algo == -1 ) {
|
||||||
/* because 3DES is implicitly in the prefs, this can only
|
/* because 3DES is implicitly in the prefs, this can only
|
||||||
* happen if we do not have any public keys in the list */
|
* happen if we do not have any public keys in the list */
|
||||||
|
16
g10/exec.c
16
g10/exec.c
@ -93,10 +93,12 @@ static int win_system(const char *command)
|
|||||||
/* Makes a temp directory and filenames */
|
/* Makes a temp directory and filenames */
|
||||||
static int make_tempdir(struct exec_info *info)
|
static int make_tempdir(struct exec_info *info)
|
||||||
{
|
{
|
||||||
char *tmp=opt.temp_dir,*name=info->name;
|
char *tmp=opt.temp_dir,*namein=info->name,*nameout;
|
||||||
|
|
||||||
if(!name)
|
if(!namein)
|
||||||
name=info->binary?"tempfile" EXTSEP_S "bin":"tempfile" EXTSEP_S "txt";
|
namein=info->binary?"tempin" EXTSEP_S "bin":"tempin" EXTSEP_S "txt";
|
||||||
|
|
||||||
|
nameout=info->binary?"tempout" EXTSEP_S "bin":"tempout" EXTSEP_S "txt";
|
||||||
|
|
||||||
/* Make up the temp dir and files in case we need them */
|
/* Make up the temp dir and files in case we need them */
|
||||||
|
|
||||||
@ -151,14 +153,14 @@ static int make_tempdir(struct exec_info *info)
|
|||||||
info->madedir=1;
|
info->madedir=1;
|
||||||
|
|
||||||
info->tempfile_in=m_alloc(strlen(info->tempdir)+
|
info->tempfile_in=m_alloc(strlen(info->tempdir)+
|
||||||
strlen(DIRSEP_S)+strlen(name)+1);
|
strlen(DIRSEP_S)+strlen(namein)+1);
|
||||||
sprintf(info->tempfile_in,"%s" DIRSEP_S "%s",info->tempdir,name);
|
sprintf(info->tempfile_in,"%s" DIRSEP_S "%s",info->tempdir,namein);
|
||||||
|
|
||||||
if(!info->writeonly)
|
if(!info->writeonly)
|
||||||
{
|
{
|
||||||
info->tempfile_out=m_alloc(strlen(info->tempdir)+
|
info->tempfile_out=m_alloc(strlen(info->tempdir)+
|
||||||
strlen(DIRSEP_S)+strlen(name)+1);
|
strlen(DIRSEP_S)+strlen(nameout)+1);
|
||||||
sprintf(info->tempfile_out,"%s" DIRSEP_S "%s",info->tempdir,name);
|
sprintf(info->tempfile_out,"%s" DIRSEP_S "%s",info->tempdir,nameout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ void show_revocation_reason( PKT_public_key *pk, int mode );
|
|||||||
int check_signatures_trust( PKT_signature *sig );
|
int check_signatures_trust( PKT_signature *sig );
|
||||||
void release_pk_list( PK_LIST pk_list );
|
void release_pk_list( PK_LIST pk_list );
|
||||||
int build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use );
|
int build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use );
|
||||||
int select_algo_from_prefs( PK_LIST pk_list, int preftype );
|
int select_algo_from_prefs( PK_LIST pk_list, int preftype, void *hint );
|
||||||
int select_mdc_from_pklist (PK_LIST pk_list);
|
int select_mdc_from_pklist (PK_LIST pk_list);
|
||||||
|
|
||||||
/*-- skclist.c --*/
|
/*-- skclist.c --*/
|
||||||
|
@ -970,7 +970,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
|
|||||||
such a broken preference list, so I'm including it. -dms */
|
such a broken preference list, so I'm including it. -dms */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
algo_available( int preftype, int algo )
|
algo_available( int preftype, int algo, void *hint )
|
||||||
{
|
{
|
||||||
if( preftype == PREFTYPE_SYM ) {
|
if( preftype == PREFTYPE_SYM ) {
|
||||||
if( opt.pgp6 && ( algo != 1 && algo != 2 && algo != 3) )
|
if( opt.pgp6 && ( algo != 1 && algo != 2 && algo != 3) )
|
||||||
@ -983,6 +983,14 @@ algo_available( int preftype, int algo )
|
|||||||
return algo && !check_cipher_algo( algo );
|
return algo && !check_cipher_algo( algo );
|
||||||
}
|
}
|
||||||
else if( preftype == PREFTYPE_HASH ) {
|
else if( preftype == PREFTYPE_HASH ) {
|
||||||
|
int bits=0;
|
||||||
|
|
||||||
|
if(hint)
|
||||||
|
bits=*(int *)hint;
|
||||||
|
|
||||||
|
if(bits && (bits != md_digest_length(algo)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if( (opt.pgp6 || opt.pgp7 ) && ( algo != 1 && algo != 2 && algo != 3) )
|
if( (opt.pgp6 || opt.pgp7 ) && ( algo != 1 && algo != 2 && algo != 3) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1004,7 +1012,7 @@ algo_available( int preftype, int algo )
|
|||||||
* Return -1 if we could not find an algorithm.
|
* Return -1 if we could not find an algorithm.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
select_algo_from_prefs( PK_LIST pk_list, int preftype )
|
select_algo_from_prefs( PK_LIST pk_list, int preftype, void *hint )
|
||||||
{
|
{
|
||||||
PK_LIST pkr;
|
PK_LIST pkr;
|
||||||
u32 bits[8];
|
u32 bits[8];
|
||||||
@ -1022,9 +1030,9 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype )
|
|||||||
|
|
||||||
memset( mask, 0, 8 * sizeof *mask );
|
memset( mask, 0, 8 * sizeof *mask );
|
||||||
if( preftype == PREFTYPE_SYM ) {
|
if( preftype == PREFTYPE_SYM ) {
|
||||||
if( pkr->pk->version < 4 &&
|
if( opt.pgp2 &&
|
||||||
pkr->pk->selfsigversion < 4 &&
|
pkr->pk->version < 4 &&
|
||||||
opt.pgp2 )
|
pkr->pk->selfsigversion < 4 )
|
||||||
mask[0] |= (1<<1); /* IDEA is implicitly there for v3 keys
|
mask[0] |= (1<<1); /* IDEA is implicitly there for v3 keys
|
||||||
with v3 selfsigs (rfc2440:12.1) if
|
with v3 selfsigs (rfc2440:12.1) if
|
||||||
--pgp2 mode is on. This doesn't
|
--pgp2 mode is on. This doesn't
|
||||||
@ -1033,6 +1041,21 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype )
|
|||||||
else
|
else
|
||||||
mask[0] |= (1<<2); /* 3DES is implicitly there for everyone else */
|
mask[0] |= (1<<2); /* 3DES is implicitly there for everyone else */
|
||||||
}
|
}
|
||||||
|
else if( preftype == PREFTYPE_HASH ) {
|
||||||
|
/* While I am including this code for completeness, note
|
||||||
|
that currently --pgp2 mode locks the hash at MD5, so this
|
||||||
|
function will never even be called. Even if the hash
|
||||||
|
wasn't locked at MD5, we don't support sign+encrypt in
|
||||||
|
--pgp2 mode, and that's the only time PREFTYPE_HASH is
|
||||||
|
used anyway. -dms */
|
||||||
|
if( opt.pgp2 &&
|
||||||
|
pkr->pk->version < 4 &&
|
||||||
|
pkr->pk->selfsigversion < 4 )
|
||||||
|
mask[0] |= (1<<1); /* MD5 is there for v3 keys with v3
|
||||||
|
selfsigs when --pgp2 is on. */
|
||||||
|
else
|
||||||
|
mask[0] |= (1<<2); /* SHA1 is there for everyone else */
|
||||||
|
}
|
||||||
else if( preftype == PREFTYPE_ZIP )
|
else if( preftype == PREFTYPE_ZIP )
|
||||||
mask[0] |= (1<<0); /* Uncompressed is implicit */
|
mask[0] |= (1<<0); /* Uncompressed is implicit */
|
||||||
|
|
||||||
@ -1086,7 +1109,7 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype )
|
|||||||
for(j=0; prefs[j].type; j++ ) {
|
for(j=0; prefs[j].type; j++ ) {
|
||||||
if( prefs[j].type == preftype ) {
|
if( prefs[j].type == preftype ) {
|
||||||
if( (bits[prefs[j].value/32] & (1<<(prefs[j].value%32))) ) {
|
if( (bits[prefs[j].value/32] & (1<<(prefs[j].value%32))) ) {
|
||||||
if( algo_available( preftype, prefs[j].value ) ) {
|
if( algo_available( preftype, prefs[j].value, hint ) ) {
|
||||||
any = 1;
|
any = 1;
|
||||||
i = prefs[j].value;
|
i = prefs[j].value;
|
||||||
break;
|
break;
|
||||||
@ -1098,7 +1121,7 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype )
|
|||||||
if( !prefs || !any ) {
|
if( !prefs || !any ) {
|
||||||
for(j=0; j < 256; j++ )
|
for(j=0; j < 256; j++ )
|
||||||
if( (bits[j/32] & (1<<(j%32))) ) {
|
if( (bits[j/32] & (1<<(j%32))) ) {
|
||||||
if( algo_available( preftype, j ) ) {
|
if( algo_available( preftype, j, hint ) ) {
|
||||||
i = j;
|
i = j;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1115,6 +1138,29 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype )
|
|||||||
i = 1; /* yep; we can use compression algo 1 */
|
i = 1; /* yep; we can use compression algo 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* "If you are building an authentication system, the recipient
|
||||||
|
may specify a preferred signing algorithm. However, the signer
|
||||||
|
would be foolish to use a weak algorithm simply because the
|
||||||
|
recipient requests it." RFC2440:13. If we settle on MD5, and
|
||||||
|
SHA1 is also available, use SHA1 instead. Of course, if the
|
||||||
|
user intentinally chose MD5 (by putting it in their personal
|
||||||
|
prefs), then we should do what they say. */
|
||||||
|
|
||||||
|
if(preftype==PREFTYPE_HASH &&
|
||||||
|
i==DIGEST_ALGO_MD5 && (bits[0] & (1<<DIGEST_ALGO_SHA1)))
|
||||||
|
{
|
||||||
|
i=DIGEST_ALGO_SHA1;
|
||||||
|
|
||||||
|
if(opt.personal_prefs)
|
||||||
|
for(j=0; prefs[j].type; j++ )
|
||||||
|
if(opt.personal_prefs[j].type==PREFTYPE_HASH &&
|
||||||
|
opt.personal_prefs[j].value==DIGEST_ALGO_MD5)
|
||||||
|
{
|
||||||
|
i=DIGEST_ALGO_MD5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1138,7 +1184,7 @@ select_mdc_from_pklist (PK_LIST pk_list)
|
|||||||
else
|
else
|
||||||
mdc = pkr->pk->mdc_feature;
|
mdc = pkr->pk->mdc_feature;
|
||||||
if (!mdc)
|
if (!mdc)
|
||||||
return 0; /* at least on recipeint does not support it */
|
return 0; /* at least one recipient does not support it */
|
||||||
}
|
}
|
||||||
return 1; /* can be used */
|
return 1; /* can be used */
|
||||||
}
|
}
|
||||||
|
30
g10/sign.c
30
g10/sign.c
@ -49,6 +49,8 @@
|
|||||||
#define LF "\n"
|
#define LF "\n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int recipient_digest_algo=0;
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Create a notation. It is assumed that the stings in STRLIST
|
* Create a notation. It is assumed that the stings in STRLIST
|
||||||
* are already checked to contain only printable data and have a valid
|
* are already checked to contain only printable data and have a valid
|
||||||
@ -332,6 +334,8 @@ hash_for(int pubkey_algo, int packet_version )
|
|||||||
{
|
{
|
||||||
if( opt.def_digest_algo )
|
if( opt.def_digest_algo )
|
||||||
return opt.def_digest_algo;
|
return opt.def_digest_algo;
|
||||||
|
if( recipient_digest_algo )
|
||||||
|
return recipient_digest_algo;
|
||||||
if( pubkey_algo == PUBKEY_ALGO_DSA )
|
if( pubkey_algo == PUBKEY_ALGO_DSA )
|
||||||
return DIGEST_ALGO_SHA1;
|
return DIGEST_ALGO_SHA1;
|
||||||
if( pubkey_algo == PUBKEY_ALGO_RSA && packet_version < 4 )
|
if( pubkey_algo == PUBKEY_ALGO_RSA && packet_version < 4 )
|
||||||
@ -673,6 +677,28 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
|||||||
iobuf_push_filter( inp, text_filter, &tfx );
|
iobuf_push_filter( inp, text_filter, &tfx );
|
||||||
mfx.md = md_open(0, 0);
|
mfx.md = md_open(0, 0);
|
||||||
|
|
||||||
|
/* If we're encrypting and signing, it is reasonable to pick the
|
||||||
|
hash algorithm to use out of the recepient key prefs. */
|
||||||
|
if(pk_list && !opt.def_digest_algo)
|
||||||
|
{
|
||||||
|
int hashlen=0,algo;
|
||||||
|
|
||||||
|
/* Of course, if the recipient asks for something unreasonable
|
||||||
|
(like a non-160-bit hash for DSA, for example), then don't
|
||||||
|
do it. Check all sk's - if any are DSA, then the hash must
|
||||||
|
be 160-bit. In the future this can be more complex with
|
||||||
|
different hashes for each sk, but so long as there is only
|
||||||
|
one signing algorithm with hash restrictions, this is
|
||||||
|
ok. -dms */
|
||||||
|
|
||||||
|
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
|
||||||
|
if(sk_rover->sk->pubkey_algo==PUBKEY_ALGO_DSA)
|
||||||
|
hashlen=20;
|
||||||
|
|
||||||
|
if((algo=select_algo_from_prefs(pk_list,PREFTYPE_HASH,&hashlen))>0)
|
||||||
|
recipient_digest_algo=algo;
|
||||||
|
}
|
||||||
|
|
||||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
||||||
PKT_secret_key *sk = sk_rover->sk;
|
PKT_secret_key *sk = sk_rover->sk;
|
||||||
md_enable(mfx.md, hash_for(sk->pubkey_algo, sk->version ));
|
md_enable(mfx.md, hash_for(sk->pubkey_algo, sk->version ));
|
||||||
@ -707,7 +733,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
|||||||
Still, if it did fail, we'll also end up with the
|
Still, if it did fail, we'll also end up with the
|
||||||
default. */
|
default. */
|
||||||
|
|
||||||
if((compr_algo=select_algo_from_prefs( pk_list, PREFTYPE_ZIP))==-1)
|
if((compr_algo=
|
||||||
|
select_algo_from_prefs(pk_list,PREFTYPE_ZIP,NULL))==-1)
|
||||||
compr_algo=DEFAULT_COMPRESS_ALGO;
|
compr_algo=DEFAULT_COMPRESS_ALGO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -788,6 +815,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
|||||||
md_close( mfx.md );
|
md_close( mfx.md );
|
||||||
release_sk_list( sk_list );
|
release_sk_list( sk_list );
|
||||||
release_pk_list( pk_list );
|
release_pk_list( pk_list );
|
||||||
|
recipient_digest_algo=0;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user