1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-10 13:04:23 +01:00

gpg: Avoid using cached MD5 signature status.

* g10/sig-check.c (check_key_signature2): Avoid using a cached MD5
signature status.
* g10/keyring.c (keyring_get_keyblock): Ditto.
(write_keyblock): Ditto.

* g10/sig-check.c (do_check): Move reject warning to ...
* g10/misc.c (print_md5_rejected_note): new.
--

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2014-10-11 19:41:51 +02:00
parent f952fe8c6d
commit 9112fed78b
4 changed files with 145 additions and 125 deletions

View File

@ -434,11 +434,18 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
&& (pkt->pkt.ring_trust->sigcache & 1) ) { && (pkt->pkt.ring_trust->sigcache & 1) ) {
/* This is a ring trust packet with a checked signature /* This is a ring trust packet with a checked signature
* status cache following directly a signature paket. * status cache following directly a signature paket.
* Set the cache status into that signature packet. */ * Set the cache status into that signature packet.
*
* We do not use cached signatures made with MD5 to
* avoid using a cached status created with an older
* version of gpg. */
PKT_signature *sig = lastnode->pkt->pkt.signature; PKT_signature *sig = lastnode->pkt->pkt.signature;
sig->flags.checked = 1; if (sig->digest_algo != DIGEST_ALGO_MD5)
sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2); {
sig->flags.checked = 1;
sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2);
}
} }
/* Reset LASTNODE, so that we set the cache status only from /* Reset LASTNODE, so that we set the cache status only from
* the ring trust packet immediately following a signature. */ * the ring trust packet immediately following a signature. */
@ -490,8 +497,11 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
&& lastnode->pkt->pkttype == PKT_SIGNATURE && lastnode->pkt->pkttype == PKT_SIGNATURE
&& (pkt->pkt.ring_trust->sigcache & 1) ) { && (pkt->pkt.ring_trust->sigcache & 1) ) {
PKT_signature *sig = lastnode->pkt->pkt.signature; PKT_signature *sig = lastnode->pkt->pkt.signature;
sig->flags.checked = 1; if (sig->digest_algo != DIGEST_ALGO_MD5)
sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2); {
sig->flags.checked = 1;
sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2);
}
} }
*ret_kb = keyblock; *ret_kb = keyblock;
} }
@ -1354,7 +1364,7 @@ write_keyblock (IOBUF fp, KBNODE keyblock)
PKT_signature *sig = node->pkt->pkt.signature; PKT_signature *sig = node->pkt->pkt.signature;
unsigned int cacheval = 0; unsigned int cacheval = 0;
if (sig->flags.checked) if (sig->flags.checked && sig->digest_algo != DIGEST_ALGO_MD5)
{ {
cacheval |= 1; cacheval |= 1;
if (sig->flags.valid) if (sig->flags.valid)

View File

@ -63,9 +63,6 @@ extern int g10_errors_seen;
#else #else
void g10_exit(int rc); void g10_exit(int rc);
#endif #endif
void print_pubkey_algo_note( int algo );
void print_cipher_algo_note( int algo );
void print_digest_algo_note( int algo );
/*-- armor.c --*/ /*-- armor.c --*/
char *make_radix64_string( const byte *data, size_t len ); char *make_radix64_string( const byte *data, size_t len );
@ -82,6 +79,10 @@ u16 checksum( byte *p, unsigned n );
u16 checksum_mpi( gcry_mpi_t a ); u16 checksum_mpi( gcry_mpi_t a );
u32 buffer_to_u32( const byte *buffer ); u32 buffer_to_u32( const byte *buffer );
const byte *get_session_marker( size_t *rlen ); const byte *get_session_marker( size_t *rlen );
void print_pubkey_algo_note( int algo );
void print_cipher_algo_note( int algo );
void print_digest_algo_note( int algo );
void print_md5_rejected_note (void);
int map_cipher_openpgp_to_gcry (int algo); int map_cipher_openpgp_to_gcry (int algo);
#define openpgp_cipher_open(_a,_b,_c,_d) gcry_cipher_open((_a),map_cipher_openpgp_to_gcry((_b)),(_c),(_d)) #define openpgp_cipher_open(_a,_b,_c,_d) gcry_cipher_open((_a),map_cipher_openpgp_to_gcry((_b)),(_c),(_d))
#define openpgp_cipher_get_algo_keylen(_a) gcry_cipher_get_algo_keylen(map_cipher_openpgp_to_gcry((_a))) #define openpgp_cipher_get_algo_keylen(_a) gcry_cipher_get_algo_keylen(map_cipher_openpgp_to_gcry((_a)))

View File

@ -340,6 +340,22 @@ print_digest_algo_note( int algo )
} }
void
print_md5_rejected_note (void)
{
static int shown;
if (!shown)
{
fflush (stdout);
log_info
(_("Note: signatures using the %s algorithm are rejected\n"),
"MD5");
shown = 1;
}
}
/* Map OpenPGP algo numbers to those used by Libgcrypt. We need to do /* Map OpenPGP algo numbers to those used by Libgcrypt. We need to do
this for algorithms we implemented in Libgcrypt after they become this for algorithms we implemented in Libgcrypt after they become
part of OpenPGP. */ part of OpenPGP. */

View File

@ -272,16 +272,7 @@ do_check( PKT_public_key *pk, PKT_signature *sig, gcry_md_hd_t digest,
if (sig->digest_algo == GCRY_MD_MD5 if (sig->digest_algo == GCRY_MD_MD5
&& !opt.flags.allow_weak_digest_algos) && !opt.flags.allow_weak_digest_algos)
{ {
static int shown; print_md5_rejected_note ();
if (!shown)
{
log_info
(_("Note: signatures using the %s algorithm are rejected\n"),
"MD5");
shown = 1;
}
return GPG_ERR_DIGEST_ALGO; return GPG_ERR_DIGEST_ALGO;
} }
@ -549,9 +540,11 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
/* Check whether we have cached the result of a previous signature /* Check whether we have cached the result of a previous signature
check. Note that we may no longer have the pubkey or hash check. Note that we may no longer have the pubkey or hash
needed to verify a sig, but can still use the cached value. A needed to verify a sig, but can still use the cached value. A
cache refresh detects and clears these cases. */ cache refresh detects and clears these cases.
For safety reasons we ignore cache entries from MD5 signatures. */
if ( !opt.no_sig_cache ) { if ( !opt.no_sig_cache ) {
if (sig->flags.checked) { /*cached status available*/ if (sig->flags.checked && sig->digest_algo != DIGEST_ALGO_MD5) {
/*cached status available*/
if( is_selfsig ) { if( is_selfsig ) {
u32 keyid[2]; u32 keyid[2];