diff --git a/g10/keyring.c b/g10/keyring.c index 7482724ad..837df5e42 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -31,7 +31,7 @@ #include "util.h" #include "keyring.h" #include "packet.h" -#include "keydb.h" +#include "keydb.h" #include "options.h" #include "main.h" /*for check_key_signature()*/ #include "i18n.h" @@ -46,11 +46,11 @@ struct off_item { /*off_t off;*/ }; -typedef struct off_item **OffsetHashTable; +typedef struct off_item **OffsetHashTable; typedef struct keyring_name *KR_NAME; -struct keyring_name +struct keyring_name { struct keyring_name *next; int secret; @@ -79,7 +79,7 @@ struct keyring_handle { int error; } current; struct { - CONST_KR_NAME kr; + CONST_KR_NAME kr; off_t offset; size_t pk_no; size_t uid_no; @@ -102,7 +102,7 @@ static struct off_item * new_offset_item (void) { struct off_item *k; - + k = xmalloc_clear (sizeof *k); return k; } @@ -121,7 +121,7 @@ release_offset_items (struct off_item *k) } #endif -static OffsetHashTable +static OffsetHashTable new_offset_hash_table (void) { struct off_item **tbl; @@ -164,7 +164,7 @@ update_offset_hash_table (OffsetHashTable tbl, u32 *kid, off_t off) for (k = tbl[(kid[1] & 0x07ff)]; k; k = k->next) { - if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) + if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) { /*k->off = off;*/ return; @@ -194,14 +194,14 @@ update_offset_hash_table_from_kb (OffsetHashTable tbl, KBNODE node, off_t off) } } -/* +/* * Register a filename for plain keyring files. ptr is set to a * pointer to be used to create a handles etc, or the already-issued * pointer if it has already been registered. The function returns 1 * if a new keyring was registered. */ int -keyring_register_filename (const char *fname, int secret, int readonly, +keyring_register_filename (const char *fname, int secret, int readonly, void **ptr) { KR_NAME kr; @@ -217,7 +217,7 @@ keyring_register_filename (const char *fname, int secret, int readonly, if (readonly) kr->readonly = 1; *ptr=kr; - return 0; + return 0; } } @@ -251,12 +251,12 @@ keyring_is_writable (void *token) return r? (r->readonly || !access (r->fname, W_OK)) : 0; } - + /* Create a new handle for the resource associated with TOKEN. SECRET is just just as a cross-check. - + The returned handle must be released using keyring_release (). */ KEYRING_HANDLE keyring_new (void *token, int secret) @@ -265,7 +265,7 @@ keyring_new (void *token, int secret) KR_NAME resource = token; assert (resource && !resource->secret == !secret); - + hd = xmalloc_clear (sizeof *hd); hd->resource = resource; hd->secret = !!secret; @@ -273,7 +273,7 @@ keyring_new (void *token, int secret) return hd; } -void +void keyring_release (KEYRING_HANDLE hd) { if (!hd) @@ -300,7 +300,7 @@ keyring_get_resource_name (KEYRING_HANDLE hd) * Lock the keyring with the given handle, or unlock if YES is false. * We ignore the handle and lock all registered files. */ -int +int keyring_lock (KEYRING_HANDLE hd, int yes) { KR_NAME kr; @@ -323,7 +323,7 @@ keyring_lock (KEYRING_HANDLE hd, int yes) } if (rc) return rc; - + /* and now set the locks */ for (kr=kr_names; kr; kr = kr->next) { if (!keyring_is_writable(kr)) @@ -334,7 +334,7 @@ keyring_lock (KEYRING_HANDLE hd, int yes) log_info ("can't lock `%s'\n", kr->fname ); rc = G10ERR_GENERAL; } - else + else kr->is_locked = 1; } } @@ -347,10 +347,10 @@ keyring_lock (KEYRING_HANDLE hd, int yes) ; else if (release_dotlock (kr->lockhd)) log_info ("can't unlock `%s'\n", kr->fname ); - else + else kr->is_locked = 0; } - } + } return rc; } @@ -360,7 +360,7 @@ keyring_lock (KEYRING_HANDLE hd, int yes) /* * Return the last found keyring. Caller must free it. * The returned keyblock has the kbode flag bit 0 set for the node with - * the public key used to locate the keyblock or flag bit 1 set for + * the public key used to locate the keyblock or flag bit 1 set for * the user ID node. */ int @@ -406,7 +406,7 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) init_packet (pkt); continue; } - if (rc) { + if (rc) { log_error ("keyring_get_keyblock: read error: %s\n", g10_errstr(rc) ); rc = G10ERR_INV_KEYRING; @@ -426,19 +426,26 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) } in_cert = 1; - if (pkt->pkttype == PKT_RING_TRUST) + if (pkt->pkttype == PKT_RING_TRUST) { /*(this code is duplicated after the loop)*/ - if ( lastnode + if ( lastnode && lastnode->pkt->pkttype == PKT_SIGNATURE && (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. - * 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; - - sig->flags.checked = 1; - sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2); + + if (sig->digest_algo != DIGEST_ALGO_MD5) + { + sig->flags.checked = 1; + sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2); + } } /* Reset LASTNODE, so that we set the cache status only from * the ring trust packet immediately following a signature. */ @@ -468,7 +475,7 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) if (++uid_no == hd->found.uid_no) node->flag |= 2; break; - + default: break; } @@ -478,7 +485,7 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) } set_packet_list_mode(save_mode); - if (rc == -1 && keyblock) + if (rc == -1 && keyblock) rc = 0; /* got the entire keyblock */ if (rc || !ret_kb) @@ -486,12 +493,15 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) else { /*(duplicated form the loop body)*/ if ( pkt && pkt->pkttype == PKT_RING_TRUST - && lastnode + && lastnode && lastnode->pkt->pkttype == PKT_SIGNATURE && (pkt->pkt.ring_trust->sigcache & 1) ) { PKT_signature *sig = lastnode->pkt->pkt.signature; - sig->flags.checked = 1; - sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2); + if (sig->digest_algo != DIGEST_ALGO_MD5) + { + sig->flags.checked = 1; + sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2); + } } *ret_kb = keyblock; } @@ -500,7 +510,7 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) iobuf_close(a); /* Make sure that future search operations fail immediately when - * we know that we are working on a invalid keyring + * we know that we are working on a invalid keyring */ if (rc == G10ERR_INV_KEYRING) hd->current.error = rc; @@ -571,11 +581,11 @@ keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb) if (hd->current.kr->readonly) return gpg_error (GPG_ERR_EACCES); } - else + else fname = hd->resource? hd->resource->fname:NULL; if (!fname) - return G10ERR_GENERAL; + return G10ERR_GENERAL; /* Close this one otherwise we will lose the position for * a next search. Fixme: it would be better to adjust the position @@ -590,7 +600,7 @@ keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb) { update_offset_hash_table_from_kb (kr_offtbl, kb, 0); } - + return rc; } @@ -639,10 +649,10 @@ keyring_delete_keyblock (KEYRING_HANDLE hd) -/* +/* * Start the next search on this handle right at the beginning */ -int +int keyring_search_reset (KEYRING_HANDLE hd) { assert (hd); @@ -652,17 +662,17 @@ keyring_search_reset (KEYRING_HANDLE hd) hd->current.iobuf = NULL; hd->current.eof = 0; hd->current.error = 0; - + hd->found.kr = NULL; hd->found.offset = 0; - return 0; + return 0; } static int prepare_search (KEYRING_HANDLE hd) { - if (hd->current.error) + if (hd->current.error) return hd->current.error; /* still in error state */ if (hd->current.kr && !hd->current.eof) { @@ -671,7 +681,7 @@ prepare_search (KEYRING_HANDLE hd) return 0; /* okay */ } - if (!hd->current.kr && hd->current.eof) + if (!hd->current.kr && hd->current.eof) return -1; /* still EOF */ if (!hd->current.kr) { /* start search with first keyring */ @@ -683,7 +693,7 @@ prepare_search (KEYRING_HANDLE hd) assert (!hd->current.iobuf); } else { /* EOF */ - iobuf_close (hd->current.iobuf); + iobuf_close (hd->current.iobuf); hd->current.iobuf = NULL; hd->current.kr = NULL; hd->current.eof = 1; @@ -841,7 +851,7 @@ compare_name (int mode, const char *name, const char *uid, size_t uidlen) int i; const char *s, *se; - if (mode == KEYDB_SEARCH_MODE_EXACT) { + if (mode == KEYDB_SEARCH_MODE_EXACT) { for (i=0; name[i] && uidlen; i++, uidlen--) if (uid[i] != name[i]) break; @@ -852,7 +862,7 @@ compare_name (int mode, const char *name, const char *uid, size_t uidlen) if (ascii_memistr( uid, uidlen, name )) return 0; } - else if ( mode == KEYDB_SEARCH_MODE_MAIL + else if ( mode == KEYDB_SEARCH_MODE_MAIL || mode == KEYDB_SEARCH_MODE_MAILSUB || mode == KEYDB_SEARCH_MODE_MAILEND) { for (i=0, s= uid; i < uidlen && *s != '<'; s++, i++) @@ -864,7 +874,7 @@ compare_name (int mode, const char *name, const char *uid, size_t uidlen) ; if (i < uidlen) { i = se - s; - if (mode == KEYDB_SEARCH_MODE_MAIL) { + if (mode == KEYDB_SEARCH_MODE_MAIL) { if( strlen(name)-2 == i && !ascii_memcasecmp( s, name+1, i) ) return 0; @@ -888,11 +898,11 @@ compare_name (int mode, const char *name, const char *uid, size_t uidlen) } -/* +/* * Search through the keyring(s), starting at the current position, * for a keyblock which contains one of the keys described in the DESC array. */ -int +int keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc, size_t *descindex) { @@ -912,28 +922,28 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, /* figure out what information we need */ need_uid = need_words = need_keyid = need_fpr = any_skip = 0; - for (n=0; n < ndesc; n++) + for (n=0; n < ndesc; n++) { - switch (desc[n].mode) + switch (desc[n].mode) { - case KEYDB_SEARCH_MODE_EXACT: + case KEYDB_SEARCH_MODE_EXACT: case KEYDB_SEARCH_MODE_SUBSTR: case KEYDB_SEARCH_MODE_MAIL: case KEYDB_SEARCH_MODE_MAILSUB: case KEYDB_SEARCH_MODE_MAILEND: need_uid = 1; break; - case KEYDB_SEARCH_MODE_WORDS: + case KEYDB_SEARCH_MODE_WORDS: need_uid = 1; need_words = 1; break; - case KEYDB_SEARCH_MODE_SHORT_KID: + case KEYDB_SEARCH_MODE_SHORT_KID: case KEYDB_SEARCH_MODE_LONG_KID: need_keyid = 1; break; - case KEYDB_SEARCH_MODE_FPR16: + case KEYDB_SEARCH_MODE_FPR16: case KEYDB_SEARCH_MODE_FPR20: - case KEYDB_SEARCH_MODE_FPR: + case KEYDB_SEARCH_MODE_FPR: need_fpr = 1; break; case KEYDB_SEARCH_MODE_FIRST: @@ -942,7 +952,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, break; default: break; } - if (desc[n].skipfnc) + if (desc[n].skipfnc) { any_skip = 1; need_keyid = 1; @@ -961,7 +971,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, else if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID) { struct off_item *oi; - + oi = lookup_offset_hash_table (kr_offtbl, desc[0].u.kid); if (!oi) { /* We know that we don't have this key */ @@ -970,9 +980,9 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, return -1; } /* We could now create a positive search status and return. - * However the problem is that another instance of gpg may + * However the problem is that another instance of gpg may * have changed the keyring so that the offsets are not valid - * anymore - therefore we don't do it + * anymore - therefore we don't do it */ } @@ -983,13 +993,13 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, log_debug ("word search mode does not yet work\n"); /* FIXME: here is a long standing bug in our function and in addition we just use the first search description */ - for (n=0; n < ndesc && !name; n++) + for (n=0; n < ndesc && !name; n++) { - if (desc[n].mode == KEYDB_SEARCH_MODE_WORDS) + if (desc[n].mode == KEYDB_SEARCH_MODE_WORDS) name = desc[n].u.name; } assert (name); - if ( !hd->word_match.name || strcmp (hd->word_match.name, name) ) + if ( !hd->word_match.name || strcmp (hd->word_match.name, name) ) { /* name changed */ xfree (hd->word_match.name); @@ -1007,23 +1017,23 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, main_offset = 0; pk_no = uid_no = 0; initial_skip = 1; /* skip until we see the start of a keyblock */ - while (!(rc=search_packet (hd->current.iobuf, &pkt, &offset, need_uid))) + while (!(rc=search_packet (hd->current.iobuf, &pkt, &offset, need_uid))) { byte afp[MAX_FINGERPRINT_LEN]; size_t an; - if (pkt.pkttype == PKT_PUBLIC_KEY || pkt.pkttype == PKT_SECRET_KEY) + if (pkt.pkttype == PKT_PUBLIC_KEY || pkt.pkttype == PKT_SECRET_KEY) { main_offset = offset; pk_no = uid_no = 0; initial_skip = 0; } - if (initial_skip) + if (initial_skip) { free_packet (&pkt); continue; } - + pk = NULL; sk = NULL; uid = NULL; @@ -1044,13 +1054,13 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, if (use_offtbl && !kr_offtbl_ready) update_offset_hash_table (kr_offtbl, aki, main_offset); } - else if (pkt.pkttype == PKT_USER_ID) + else if (pkt.pkttype == PKT_USER_ID) { uid = pkt.pkt.user_id; ++uid_no; } else if ( pkt.pkttype == PKT_SECRET_KEY - || pkt.pkttype == PKT_SECRET_SUBKEY) + || pkt.pkttype == PKT_SECRET_SUBKEY) { sk = pkt.pkt.secret_key; ++pk_no; @@ -1062,28 +1072,28 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, } if (need_keyid) keyid_from_sk (sk, aki); - + } - for (n=0; n < ndesc; n++) + for (n=0; n < ndesc; n++) { switch (desc[n].mode) { - case KEYDB_SEARCH_MODE_NONE: + case KEYDB_SEARCH_MODE_NONE: BUG (); break; - case KEYDB_SEARCH_MODE_EXACT: + case KEYDB_SEARCH_MODE_EXACT: case KEYDB_SEARCH_MODE_SUBSTR: case KEYDB_SEARCH_MODE_MAIL: case KEYDB_SEARCH_MODE_MAILSUB: case KEYDB_SEARCH_MODE_MAILEND: - case KEYDB_SEARCH_MODE_WORDS: + case KEYDB_SEARCH_MODE_WORDS: if ( uid && !compare_name (desc[n].mode, desc[n].u.name, - uid->name, uid->len)) + uid->name, uid->len)) goto found; break; - - case KEYDB_SEARCH_MODE_SHORT_KID: + + case KEYDB_SEARCH_MODE_SHORT_KID: if ((pk||sk) && desc[n].u.kid[1] == aki[1]) goto found; break; @@ -1097,19 +1107,19 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, goto found; break; case KEYDB_SEARCH_MODE_FPR20: - case KEYDB_SEARCH_MODE_FPR: + case KEYDB_SEARCH_MODE_FPR: if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 20)) goto found; break; - case KEYDB_SEARCH_MODE_FIRST: + case KEYDB_SEARCH_MODE_FIRST: if (pk||sk) goto found; break; - case KEYDB_SEARCH_MODE_NEXT: + case KEYDB_SEARCH_MODE_NEXT: if (pk||sk) goto found; break; - default: + default: rc = G10ERR_INV_ARG; goto found; } @@ -1121,7 +1131,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, meaningful if this function returns with no errors. */ if(descindex) *descindex=n; - for (n=any_skip?0:ndesc; n < ndesc; n++) + for (n=any_skip?0:ndesc; n < ndesc; n++) { if (desc[n].skipfnc && desc[n].skipfnc (desc[n].skipfncvalue, aki, uid)) @@ -1147,12 +1157,12 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, if (use_offtbl && !kr_offtbl_ready) { KR_NAME kr; - + /* First set the did_full_scan flag for this keyring (ignore secret keyrings) */ for (kr=kr_names; kr; kr = kr->next) { - if (!kr->secret && hd->resource == kr) + if (!kr->secret && hd->resource == kr) { kr->did_full_scan = 1; break; @@ -1162,14 +1172,14 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, offtbl ready */ for (kr=kr_names; kr; kr = kr->next) { - if (!kr->secret && !kr->did_full_scan) + if (!kr->secret && !kr->did_full_scan) break; } if (!kr) kr_offtbl_ready = 1; } } - else + else hd->current.error = rc; free_packet(&pkt); @@ -1181,7 +1191,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, static int create_tmp_file (const char *template, char **r_bakfname, char **r_tmpfname, IOBUF *r_fp) -{ +{ char *bakfname, *tmpfname; mode_t oldmask; @@ -1205,7 +1215,7 @@ create_tmp_file (const char *template, strcpy (tmpfname,template); strcpy (tmpfname+strlen(template)-4, EXTSEP_S "tmp"); } - else + else { /* file does not end with gpg; hmmm */ bakfname = xmalloc (strlen( template ) + 5); strcpy (stpcpy(bakfname, template), EXTSEP_S "bak"); @@ -1239,7 +1249,7 @@ create_tmp_file (const char *template, xfree (bakfname); return rc; } - + *r_bakfname = bakfname; *r_tmpfname = tmpfname; return 0; @@ -1272,7 +1282,7 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, /* first make a backup file except for secret keyrings */ if (!secret) - { + { #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) remove (bakfname); #endif @@ -1284,7 +1294,7 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, return rc; } } - + /* then rename the file */ #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) remove( fname ); @@ -1309,7 +1319,7 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, statbuf.st_mode=S_IRUSR | S_IWUSR; if (((secret && !opt.preserve_permissions) - || !stat (bakfname,&statbuf)) + || !stat (bakfname,&statbuf)) && !chmod (fname,statbuf.st_mode)) ; else @@ -1337,10 +1347,10 @@ write_keyblock (IOBUF fp, KBNODE keyblock) { KBNODE kbctx = NULL, node; int rc; - - while ( (node = walk_kbnode (keyblock, &kbctx, 0)) ) + + while ( (node = walk_kbnode (keyblock, &kbctx, 0)) ) { - if (node->pkt->pkttype == PKT_RING_TRUST) + if (node->pkt->pkttype == PKT_RING_TRUST) continue; /* we write it later on our own */ if ( (rc = build_packet (fp, node->pkt) )) @@ -1349,12 +1359,12 @@ write_keyblock (IOBUF fp, KBNODE keyblock) node->pkt->pkttype, g10_errstr(rc) ); return rc; } - if (node->pkt->pkttype == PKT_SIGNATURE) + if (node->pkt->pkttype == PKT_SIGNATURE) { /* always write a signature cache packet */ PKT_signature *sig = node->pkt->pkt.signature; unsigned int cacheval = 0; - - if (sig->flags.checked) + + if (sig->flags.checked && sig->digest_algo != DIGEST_ALGO_MD5) { cacheval |= 1; if (sig->flags.valid) @@ -1363,7 +1373,7 @@ write_keyblock (IOBUF fp, KBNODE keyblock) iobuf_put (fp, 0xb0); /* old style packet 12, 1 byte len*/ iobuf_put (fp, 2); /* 2 bytes */ iobuf_put (fp, 0); /* unused */ - if (iobuf_put (fp, cacheval)) + if (iobuf_put (fp, cacheval)) { rc = gpg_error_from_syserror (); log_error ("writing sigcache packet failed\n"); @@ -1374,7 +1384,7 @@ write_keyblock (IOBUF fp, KBNODE keyblock) return 0; } -/* +/* * Walk over all public keyrings, check the signatures and replace the * keyring with a new one where the signature cache is then updated. * This is only done for the public keyrings. @@ -1419,7 +1429,7 @@ keyring_rebuild_cache (void *token,int noisy) * the original file is closed */ tmpfp = NULL; } - rc = lastresname? rename_tmp_file (bakfilename, tmpfilename, + rc = lastresname? rename_tmp_file (bakfilename, tmpfilename, lastresname, 0) : 0; xfree (tmpfilename); tmpfilename = NULL; xfree (bakfilename); bakfilename = NULL; @@ -1432,10 +1442,10 @@ keyring_rebuild_cache (void *token,int noisy) if (rc) goto leave; } - + release_kbnode (keyblock); rc = keyring_get_keyblock (hd, &keyblock); - if (rc) + if (rc) { log_error ("keyring_get_keyblock failed: %s\n", g10_errstr(rc)); goto leave; @@ -1479,7 +1489,7 @@ keyring_rebuild_cache (void *token,int noisy) sigcount++; } } - + /* write the keyblock to the temporary file */ rc = write_keyblock (tmpfp, keyblock); if (rc) @@ -1489,10 +1499,10 @@ keyring_rebuild_cache (void *token,int noisy) log_info(_("%lu keys cached so far (%lu signatures)\n"), count, sigcount ); - } /* end main loop */ + } /* end main loop */ if (rc == -1) rc = 0; - if (rc) + if (rc) { log_error ("keyring_search failed: %s\n", g10_errstr(rc)); goto leave; @@ -1520,8 +1530,8 @@ keyring_rebuild_cache (void *token,int noisy) leave: if (tmpfp) iobuf_cancel (tmpfp); - xfree (tmpfilename); - xfree (bakfilename); + xfree (tmpfilename); + xfree (bakfilename); release_kbnode (keyblock); keyring_lock (hd, 0); keyring_release (hd); @@ -1544,13 +1554,13 @@ do_copy (int mode, const char *fname, KBNODE root, int secret, char *bakfname = NULL; char *tmpfname = NULL; - /* Open the source file. Because we do a rename, we have to check the + /* Open the source file. Because we do a rename, we have to check the permissions of the file */ if (access (fname, W_OK)) return gpg_error_from_syserror (); fp = iobuf_open (fname); - if (mode == 1 && !fp && errno == ENOENT) { + if (mode == 1 && !fp && errno == ENOENT) { /* insert mode but file does not exist: create a new file */ KBNODE kbctx, node; mode_t oldmask; diff --git a/g10/main.h b/g10/main.h index 4cf2cc788..e97b936e8 100644 --- a/g10/main.h +++ b/g10/main.h @@ -63,9 +63,6 @@ extern int g10_errors_seen; #else void g10_exit(int rc); #endif -void print_pubkey_algo_note( int algo ); -void print_cipher_algo_note( int algo ); -void print_digest_algo_note( int algo ); /*-- armor.c --*/ 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 ); u32 buffer_to_u32( const byte *buffer ); 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); #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))) diff --git a/g10/misc.c b/g10/misc.c index ef03776ef..17494aca4 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -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 this for algorithms we implemented in Libgcrypt after they become part of OpenPGP. */ diff --git a/g10/sig-check.c b/g10/sig-check.c index ed4fa8978..299969345 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -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 && !opt.flags.allow_weak_digest_algos) { - static int shown; - - if (!shown) - { - log_info - (_("Note: signatures using the %s algorithm are rejected\n"), - "MD5"); - shown = 1; - } - + print_md5_rejected_note (); 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. Note that we may no longer have the pubkey or hash 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 (sig->flags.checked) { /*cached status available*/ + if (sig->flags.checked && sig->digest_algo != DIGEST_ALGO_MD5) { + /*cached status available*/ if( is_selfsig ) { u32 keyid[2];