diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 7 | ||||
-rw-r--r-- | g10/g10.c | 3 | ||||
-rw-r--r-- | g10/main.h | 2 | ||||
-rw-r--r-- | g10/options.h | 3 | ||||
-rw-r--r-- | g10/seskey.c | 15 | ||||
-rw-r--r-- | g10/sig-check.c | 19 | ||||
-rw-r--r-- | g10/sign.c | 2 |
7 files changed, 40 insertions, 11 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index 51c3973d0..1989b8f29 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,10 @@ +Mon Jun 5 23:41:54 CEST 2000 Werner Koch <[email protected]> + + * seskey.c (do_encode_md, encode_md_value): Add new arg v3compathack to work + around a bug in old versions. + * sig-check.c (do_check): use the aboved workaround when enabled. + * g10.c: New option --emulate-md-decode-bug + Mon Jun 5 12:37:43 CEST 2000 Werner Koch <[email protected]> * build-packet.c (do_mdc): New. @@ -187,6 +187,7 @@ enum cmd_and_opt_values { aNull = 0, oIgnoreTimeConflict, oNoRandomSeedFile, oEmu3DESS2KBug, /* will be removed in 1.1 */ + oEmuMDEncodeBug, aTest }; @@ -367,6 +368,7 @@ static ARGPARSE_OPTS opts[] = { { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" }, { oNoRandomSeedFile, "no-random-seed-file", 0, "@" }, { oEmu3DESS2KBug, "emulate-3des-s2k-bug", 0, "@"}, + { oEmuMDEncodeBug, "emulate-md-encode-bug", 0, "@"}, {0} }; @@ -843,6 +845,7 @@ main( int argc, char **argv ) break; case oEmuChecksumBug: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break; case oEmu3DESS2KBug: opt.emulate_bugs |= EMUBUG_3DESS2K; break; + case oEmuMDEncodeBug: opt.emulate_bugs |= EMUBUG_MDENCODE; break; case oCompressSigs: opt.compress_sigs = 1; break; case oRunAsShmCP: #ifndef USE_SHM_COPROCESSING diff --git a/g10/main.h b/g10/main.h index 9ec141ebc..54e68db18 100644 --- a/g10/main.h +++ b/g10/main.h @@ -109,7 +109,7 @@ void try_make_homedir( const char *fname ); 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 ); + int hash_algo, unsigned nbits, int v3compathack ); /*-- comment.c --*/ KBNODE make_comment_node( const char *s ); diff --git a/g10/options.h b/g10/options.h index f2090a2f0..f5657f70f 100644 --- a/g10/options.h +++ b/g10/options.h @@ -66,7 +66,7 @@ struct { int rfc1991; int rfc2440; int pgp2_workarounds; - unsigned emulate_bugs; /* bug emulation flags EMUBUG_xxxx */ + unsigned int emulate_bugs; /* bug emulation flags EMUBUG_xxxx */ int shm_coprocess; const char *set_filename; const char *comment_string; @@ -95,6 +95,7 @@ struct { #define EMUBUG_GPGCHKSUM 1 #define EMUBUG_3DESS2K 2 +#define EMUBUG_MDENCODE 4 #define DBG_PACKET_VALUE 1 /* debug packet reading/writing */ #define DBG_MPI_VALUE 2 /* debug mpi details */ diff --git a/g10/seskey.c b/g10/seskey.c index d0fe5f9bf..1ccead716 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -142,7 +142,7 @@ encode_session_key( DEK *dek, unsigned nbits ) static MPI do_encode_md( MD_HANDLE md, int algo, size_t len, unsigned nbits, - const byte *asn, size_t asnlen ) + const byte *asn, size_t asnlen, int v3compathack ) { int nframe = (nbits+7) / 8; byte *frame; @@ -162,7 +162,7 @@ do_encode_md( MD_HANDLE md, int algo, size_t len, unsigned nbits, frame = md_is_secure(md)? m_alloc_secure( nframe ) : m_alloc( nframe ); n = 0; frame[n++] = 0; - frame[n++] = algo; + frame[n++] = v3compathack? algo : 1; /* block type */ i = nframe - len - asnlen -3 ; assert( i > 1 ); memset( frame+n, 0xff, i ); n += i; @@ -179,8 +179,15 @@ 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 vare force the old behaviour. + */ MPI -encode_md_value( int pubkey_algo, MD_HANDLE md, int hash_algo, unsigned nbits ) +encode_md_value( int pubkey_algo, MD_HANDLE md, int hash_algo, + unsigned nbits, int v3compathack ) { int algo = hash_algo? hash_algo : md_get_algo(md); const byte *asn; @@ -197,7 +204,7 @@ encode_md_value( int pubkey_algo, MD_HANDLE md, int hash_algo, unsigned nbits ) } else { asn = md_asn_oid( algo, &asnlen, &mdlen ); - frame = do_encode_md( md, algo, mdlen, nbits, asn, asnlen ); + frame = do_encode_md( md, algo, mdlen, nbits, asn, asnlen, v3compathack); } return frame; } diff --git a/g10/sig-check.c b/g10/sig-check.c index 6c51cc89f..1a7e8664e 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -374,13 +374,24 @@ 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])); - + mpi_get_nbits(pk->pkey[0]), (sig->version < 4) ); ctx.sig = sig; ctx.md = digest; rc = pubkey_verify( pk->pubkey_algo, result, sig->data, pk->pkey, cmp_help, &ctx ); mpi_free( result ); + if( (opt.emulate_bugs & EMUBUG_MDENCODE) + && rc == G10ERR_BAD_SIGN && is_ELGAMAL(pk->pubkey_algo) ) { + /* In this case we try again because old GnuPG versions didn't encode + * the hash right. There is no problem with DSA here */ + result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo, + mpi_get_nbits(pk->pkey[0]), (sig->version < 4) ); + ctx.sig = sig; + ctx.md = digest; + rc = pubkey_verify( pk->pubkey_algo, result, sig->data, pk->pkey, + cmp_help, &ctx ); + } + if( !rc && sig->flags.unknown_critical ) { log_info(_("assuming bad signature due to an unknown critical bit\n")); rc = G10ERR_BAD_SIGN; @@ -518,7 +529,6 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, keyid_from_pk( pk, keyid ); md = md_open( algo, 0 ); - md_start_debug( md, "rsa" ); hash_public_key( md, pk ); hash_uid_node( unode, md, sig ); if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { @@ -526,8 +536,9 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, *is_selfsig = 1; rc = do_check( pk, sig, md, r_expired ); } - else + else { rc = do_signature_check( sig, md, r_expiredate, r_expired ); + } md_close(md); } else { diff --git a/g10/sign.c b/g10/sign.c index e4b1b8f4e..6b6d5c5d0 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -128,7 +128,7 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig, sig->digest_start[0] = dp[0]; sig->digest_start[1] = dp[1]; frame = encode_md_value( sk->pubkey_algo, md, - digest_algo, mpi_get_nbits(sk->skey[0])); + digest_algo, mpi_get_nbits(sk->skey[0]), 0 ); rc = pubkey_sign( sk->pubkey_algo, sig->data, frame, sk->skey ); mpi_free(frame); if( rc ) |