From 1f4bdf4d2631e89769c0d3eabe3818bffcc45711 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 25 Sep 2001 15:20:59 +0000 Subject: [PATCH] Changed signature status cache --- NEWS | 12 ++ doc/gpg.sgml | 5 +- g10/ChangeLog | 28 +++ g10/build-packet.c | 2 +- g10/export.c | 3 + g10/g10.c | 12 +- g10/import.c | 32 ++-- g10/keydb.c | 18 +- g10/keydb.h | 1 + g10/keyring.c | 449 ++++++++++++++++++++++++++++++++++----------- g10/keyring.h | 2 +- g10/keyring.o | Bin 57216 -> 61904 bytes g10/options.h | 1 - g10/packet.h | 3 +- g10/parse-packet.c | 18 +- g10/sig-check.c | 144 ++------------- g10/tdbio.c | 4 +- g10/trustdb.c | 25 ++- 18 files changed, 478 insertions(+), 281 deletions(-) diff --git a/NEWS b/NEWS index 1de9000b6..648f0cef9 100644 --- a/NEWS +++ b/NEWS @@ -37,6 +37,18 @@ * The entire keyring management has been revamped. + * The way signature stati are store has changed, so that v3 + signatures can be supported. To increase the speed of many + operations for existing keys you can use the new + --rebuild-keydb-caches command. + + * The entire key validation process (trustdb) has been revamped. + See the man page entries for --update-trustdb, --check-trustdb + and --no-auto-check-trustdb. + + * --trusted-keys is again obsolete, --edit can be used to set the + ownertrust of any key to ultimately trusted. + Noteworthy changes in version 1.0.6 (2001-05-29) ------------------------------------------------ diff --git a/doc/gpg.sgml b/doc/gpg.sgml index 717f7e394..386b256e2 100644 --- a/doc/gpg.sgml +++ b/doc/gpg.sgml @@ -513,7 +513,6 @@ command --update-trustdb. There are a few other options which control how this command works. Most notable here is the --merge-only option which does not insert new keys but does only the merging of new signatures, user-IDs and subkeys. -See also the option --allow-secret-key-import. @@ -1530,9 +1529,7 @@ Don't insert new keys into the keyrings while doing an import. --allow-secret-key-import -Allow import of secret keys. The import command normally skips secret -keys because a secret key can otherwise be used to attack the trust -calculation. +This is an obsolete option and is not used anywhere. diff --git a/g10/ChangeLog b/g10/ChangeLog index 96ef0c6fa..e33e175d6 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,31 @@ +2001-09-25 Werner Koch + + * g10.c, options.h, import.c: Removed the entire + allow-secret-key-import stuff because the validity is now + controlled by other means. + + * g10.c: New command --rebuild-keydb-caches. + * keydb.c (keydb_rebuild_caches): New. + * keyring.c (do_copy): Moved some code to + (create_tmp_file, rename_tmp_file, write_keyblock): new functions. + (keyring_rebuild_cache): New. + + * packet.h (PKT_ring_trust): Add sigcache field. + * parse-packet.c (parse_trust): Parse sigcache. + * keyring.c (do_copy): Always insert a sigcache packet. + (keyring_get_keyblock): Copy the sigcache packet to the signature. + * sig-check.c (cache_sig_result): Renamed from + cache_selfsig_result. Changed implementation to use the flag bits + and changed all callers. + (mdc_kludge_check): Removed this unused code. + (do_check): Do not set the sig flags here. + + * import.c (read_block): Make sure that ring_trust packets are + never imported. + * export.c (do_export_stream): and never export them. + + * trustdb.c (make_key_array): Skip revoked and expired keys. + 2001-09-24 Werner Koch * g10.c, options.h: New option --no-auto-check-trustdb. diff --git a/g10/build-packet.c b/g10/build-packet.c index 1b7e0d838..271fd0920 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -135,7 +135,7 @@ build_packet( IOBUF out, PACKET *pkt ) rc = do_onepass_sig( out, ctb, pkt->pkt.onepass_sig ); break; case PKT_RING_TRUST: - break; /* ignore it */ + break; /* ignore it (keyring.c does write it directly)*/ default: log_bug("invalid packet type in build_packet()\n"); break; diff --git a/g10/export.c b/g10/export.c index 0c235233f..4c4a4de67 100644 --- a/g10/export.c +++ b/g10/export.c @@ -186,6 +186,9 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any ) * secret keyring */ if( !secret && node->pkt->pkttype == PKT_COMMENT ) continue; + /* make sure that ring_trust packets never get exported */ + if (node->pkt->pkttype == PKT_RING_TRUST) + continue; /* do not export packets which are marked as not exportable */ if( node->pkt->pkttype == PKT_SIGNATURE ) { const char *p; diff --git a/g10/g10.c b/g10/g10.c index 04b73e163..6210fe9e4 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -112,7 +112,7 @@ enum cmd_and_opt_values { aNull = 0, aEnArmor, aGenRandom, aPipeMode, - aRefreshCaches, + aRebuildKeydbCaches, aRefreshKeys, oTextmode, @@ -441,6 +441,7 @@ static ARGPARSE_OPTS opts[] = { { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" }, { oNoExpensiveTrustChecks, "no-expensive-trust-checks", 0, "@" }, { aDeleteSecretAndPublicKey, "delete-secret-and-public-key",256, "@" }, + { aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"}, { oPreservePermissions, "preserve-permissions", 0, "@"}, { oPreferenceList, "preference-list", 2, "@"}, { oEmu3DESS2KBug, "emulate-3des-s2k-bug", 0, "@"}, @@ -848,6 +849,7 @@ main( int argc, char **argv ) case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break; case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break; case aPipeMode: set_cmd( &cmd, aPipeMode); break; + case aRebuildKeydbCaches: set_cmd( &cmd, aRebuildKeydbCaches); break; case oArmor: opt.armor = 1; opt.no_armor=0; break; case oOutput: opt.outfile = pargs.r.ret_str; break; @@ -1078,7 +1080,7 @@ main( int argc, char **argv ) opt.override_session_key = pargs.r.ret_str; break; case oMergeOnly: opt.merge_only = 1; break; - case oAllowSecretKeyImport: opt.allow_secret_key_import = 1; break; + case oAllowSecretKeyImport: /* obsolete */ break; case oTryAllSecrets: opt.try_all_secrets = 1; break; case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break; case oEnableSpecialFilenames: @@ -1689,6 +1691,12 @@ main( int argc, char **argv ) run_in_pipemode (); break; + case aRebuildKeydbCaches: + if (argc) + wrong_args ("--rebuild-keydb-caches"); + keydb_rebuild_caches (); + break; + case aListPackets: opt.list_packets=2; default: diff --git a/g10/import.c b/g10/import.c index dc17505ef..e15f07c86 100644 --- a/g10/import.c +++ b/g10/import.c @@ -55,13 +55,13 @@ struct stats_s { static int import( IOBUF inp, int fast, const char* fname, - int allow_secret, struct stats_s *stats ); + struct stats_s *stats ); static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root ); static void remove_bad_stuff (KBNODE keyblock); static int import_one( const char *fname, KBNODE keyblock, int fast, struct stats_s *stats); static int import_secret_one( const char *fname, KBNODE keyblock, - int allow, struct stats_s *stats ); + struct stats_s *stats ); static int import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats); static int chk_self_sigs( const char *fname, KBNODE keyblock, @@ -144,8 +144,7 @@ import_keys( char **fnames, int nnames, int fast, void *stats_handle ) if( !inp ) log_error(_("can't open `%s': %s\n"), fname, strerror(errno) ); else { - int rc = import( inp, fast, fname, - opt.allow_secret_key_import, stats ); + int rc = import( inp, fast, fname, stats ); iobuf_close(inp); if( rc ) log_error("import from `%s' failed: %s\n", fname, @@ -170,8 +169,7 @@ import_keys_stream( IOBUF inp, int fast, void *stats_handle ) if (!stats) stats = import_new_stats_handle (); - rc = import( inp, fast, "[stream]", - opt.allow_secret_key_import, stats ); + rc = import( inp, fast, "[stream]", stats); if (!stats_handle) { import_print_stats (stats); import_release_stats_handle (stats); @@ -181,8 +179,7 @@ import_keys_stream( IOBUF inp, int fast, void *stats_handle ) } static int -import( IOBUF inp, int fast, const char* fname, int allow_secret, - struct stats_s *stats ) +import( IOBUF inp, int fast, const char* fname, struct stats_s *stats ) { PACKET *pending_pkt = NULL; KBNODE keyblock; @@ -201,8 +198,7 @@ import( IOBUF inp, int fast, const char* fname, int allow_secret, if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY ) rc = import_one( fname, keyblock, fast, stats ); else if( keyblock->pkt->pkttype == PKT_SECRET_KEY ) - rc = import_secret_one( fname, keyblock, - allow_secret, stats ); + rc = import_secret_one( fname, keyblock, stats ); else if( keyblock->pkt->pkttype == PKT_SIGNATURE && keyblock->pkt->pkt.signature->sig_class == 0x20 ) rc = import_revoke_cert( fname, keyblock, stats ); @@ -344,6 +340,11 @@ read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root ) init_packet(pkt); break; + case PKT_RING_TRUST: + /* skip those packets */ + free_packet( pkt ); + init_packet(pkt); + break; case PKT_PUBLIC_KEY: case PKT_SECRET_KEY: @@ -386,7 +387,8 @@ remove_bad_stuff (KBNODE keyblock) for (node=keyblock; node; node = node->next ) { if( node->pkt->pkttype == PKT_SIGNATURE ) { - /* delete the subpackets we use for the verification cache */ + /* delete the subpackets we used to use for the + verification cache */ delete_sig_subpkt (node->pkt->pkt.signature->unhashed, SIGSUBPKT_PRIV_VERIFY_CACHE); } @@ -606,7 +608,7 @@ import_one( const char *fname, KBNODE keyblock, int fast, * with the trust calculation. */ static int -import_secret_one( const char *fname, KBNODE keyblock, int allow, +import_secret_one( const char *fname, KBNODE keyblock, struct stats_s *stats) { PKT_secret_key *sk; @@ -634,12 +636,6 @@ import_secret_one( const char *fname, KBNODE keyblock, int allow, putc('\n', stderr); } stats->secret_read++; - if (!allow) { - log_info ( _("secret key %08lX not imported " - "(use %s to allow for it)\n"), - (ulong)keyid[1], "--allow-secret-key-import"); - return 0; - } if( !uidnode ) { log_error( _("key %08lX: no user ID\n"), (ulong)keyid[1]); diff --git a/g10/keydb.c b/g10/keydb.c index 7a7a43e3e..6cd3cf93f 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -320,7 +320,7 @@ lock_all (KEYDB_HANDLE hd) } if (rc) { - /* revert the alreadt set locks */ + /* revert the already set locks */ for (i--; i >= 0; i--) { switch (hd->active[i].type) { case KEYDB_RESOURCE_TYPE_NONE: @@ -517,6 +517,22 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) return rc; } +/* + * Rebuild the caches of all key resources. + */ +void +keydb_rebuild_caches (void) +{ + int rc; + + rc = keyring_rebuild_cache (); + if (rc) + log_error (_("failed to rebuild all keyring caches: %s\n"), + g10_errstr (rc)); + /* add other types here */ +} + + /* * Start the next search on this handle right at the beginning diff --git a/g10/keydb.h b/g10/keydb.h index 67a9e10f2..ba7d58528 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -148,6 +148,7 @@ int keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb); int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb); int keydb_delete_keyblock (KEYDB_HANDLE hd); int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved); +void keydb_rebuild_caches (void); int keydb_search_reset (KEYDB_HANDLE hd); int keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc); int keydb_search_first (KEYDB_HANDLE hd); diff --git a/g10/keyring.c b/g10/keyring.c index a55dcc621..b0dabe740 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -32,6 +32,7 @@ #include "packet.h" #include "keydb.h" #include "options.h" +#include "main.h" /*for check_key_signature()*/ #include "i18n.h" typedef struct keyring_name *KR_NAME; @@ -219,7 +220,7 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) { PACKET *pkt; int rc; - KBNODE keyblock = NULL, node; + KBNODE keyblock = NULL, node, lastnode; IOBUF a; int in_cert = 0; int pk_no = 0; @@ -246,6 +247,7 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) pkt = m_alloc (sizeof *pkt); init_packet (pkt); hd->found.n_packets = 0;; + lastnode = NULL; while ((rc=parse_packet (a, pkt)) != -1) { hd->found.n_packets++; if (rc == G10ERR_UNKNOWN_PACKET) { @@ -273,36 +275,64 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) } in_cert = 1; - node = new_kbnode (pkt); - if (!keyblock) - keyblock = node; - else - add_kbnode (keyblock, node); - - if ( pkt->pkttype == PKT_PUBLIC_KEY - || pkt->pkttype == PKT_PUBLIC_SUBKEY - || pkt->pkttype == PKT_SECRET_KEY - || pkt->pkttype == PKT_SECRET_SUBKEY) { - if (++pk_no == hd->found.pk_no) - node->flag |= 1; + if (pkt->pkttype == PKT_RING_TRUST) { + /*(this code is duplicated after the loop)*/ + if ( lastnode + && lastnode->pkt->pkttype == PKT_SIGNATURE + && (pkt->pkt.ring_trust->sigcache & 1) ) { + /* 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 */ + PKT_signature *sig = lastnode->pkt->pkt.signature; + + 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 folling a signature */ + lastnode = NULL; } - else if ( pkt->pkttype == PKT_USER_ID) { - if (++uid_no == hd->found.uid_no) - node->flag |= 2; + else { + node = lastnode = new_kbnode (pkt); + if (!keyblock) + keyblock = node; + else + add_kbnode (keyblock, node); + + if ( pkt->pkttype == PKT_PUBLIC_KEY + || pkt->pkttype == PKT_PUBLIC_SUBKEY + || pkt->pkttype == PKT_SECRET_KEY + || pkt->pkttype == PKT_SECRET_SUBKEY) { + if (++pk_no == hd->found.pk_no) + node->flag |= 1; + } + else if ( pkt->pkttype == PKT_USER_ID) { + if (++uid_no == hd->found.uid_no) + node->flag |= 2; + } } pkt = m_alloc (sizeof *pkt); init_packet(pkt); } - if (rc == -1 && keyblock) + if (rc == -1 && keyblock) rc = 0; /* got the entire keyblock */ if (rc || !ret_kb) release_kbnode (keyblock); - else + else { + /*(duplicated form the loop body)*/ + if ( pkt && pkt->pkttype == PKT_RING_TRUST + && 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); + } *ret_kb = keyblock; - + } free_packet (pkt); m_free (pkt); iobuf_close(a); @@ -874,6 +904,285 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc) } + +static int +create_tmp_file (const char *template, + char **r_bakfname, char **r_tmpfname, IOBUF *r_fp) +{ + char *bakfname, *tmpfname; + + *r_bakfname = NULL; + *r_tmpfname = NULL; + +# ifdef USE_ONLY_8DOT3 + /* Here is another Windoze bug?: + * you cant rename("pubring.gpg.tmp", "pubring.gpg"); + * but rename("pubring.gpg.tmp", "pubring.aaa"); + * works. So we replace .gpg by .bak or .tmp + */ + if (strlen (template) > 4 + && !strcmp (template+strlen(template)-4, EXTSEP_S "gpg") ) + { + bakfname = m_alloc (strlen (template) + 1); + strcpy (bakfname, template); + strcpy (bakfname+strlen(template)-4, EXTSEP_S "bak"); + + tmpfname = m_alloc (strlen( template ) + 1 ); + strcpy (tmpfname,template); + strcpy (tmpfname+strlen(template)-4, EXTSEP_S "tmp"); + } + else + { /* file does not end with gpg; hmmm */ + bakfname = m_alloc (strlen( template ) + 5); + strcpy (stpcpy(bakfname, template), EXTSEP_S "bak"); + + tmpfname = m_alloc (strlen( template ) + 5); + strcpy (stpcpy(tmpfname, template), EXTSEP_S "tmp"); + } +# else /* Posix file names */ + bakfname = m_alloc (strlen( template ) + 2); + strcpy (stpcpy (bakfname,template),"~"); + + tmpfname = m_alloc (strlen( template ) + 5); + strcpy (stpcpy(tmpfname,template), EXTSEP_S "tmp"); +# endif /* Posix filename */ + + *r_fp = iobuf_create (tmpfname); + if (!*r_fp) { + log_error ("can't create `%s': %s\n", tmpfname, strerror(errno) ); + m_free (tmpfname); + m_free (bakfname); + return G10ERR_OPEN_FILE; + } + + *r_bakfname = bakfname; + *r_tmpfname = tmpfname; + return 0; +} + + +static int +rename_tmp_file (const char *bakfname, const char *tmpfname, + const char *fname, int secret ) +{ + int rc=0; + + /* restrict the permissions for secret keyrings */ +#ifndef HAVE_DOSISH_SYSTEM + if (secret && !opt.preserve_permissions) + { + if (chmod (tmpfname, S_IRUSR | S_IWUSR) ) + { + log_error ("chmod of `%s' failed: %s\n", + tmpfname, strerror(errno) ); + return G10ERR_WRITE_FILE; + } + } +#endif + + /* invalidate close caches*/ + iobuf_ioctl (NULL, 2, 0, (char*)tmpfname ); + iobuf_ioctl (NULL, 2, 0, (char*)bakfname ); + iobuf_ioctl (NULL, 2, 0, (char*)fname ); + + /* first make a backup file except for secret keyrings */ + if (!secret) + { +#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) + remove (bakfname); +#endif + if (rename (fname, bakfname) ) + { + log_error ("renaming `%s' to `%s' failed: %s\n", + fname, bakfname, strerror(errno) ); + return G10ERR_RENAME_FILE; + } + } + + /* then rename the file */ +#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) + remove( fname ); +#endif + if (rename (tmpfname, fname) ) + { + log_error ("renaming `%s' to `%s' failed: %s\n", + tmpfname, fname, strerror(errno) ); + rc = G10ERR_RENAME_FILE; + if (secret) + { + log_info(_("WARNING: 2 files with confidential" + " information exists.\n")); + log_info(_("%s is the unchanged one\n"), fname ); + log_info(_("%s is the new one\n"), tmpfname ); + log_info(_("Please fix this possible security flaw\n")); + } + return rc; + } + + return 0; +} + + +static int +write_keyblock (IOBUF fp, KBNODE keyblock) +{ + KBNODE kbctx = NULL, node; + int rc; + + while ( (node = walk_kbnode (keyblock, &kbctx, 0)) ) + { + if (node->pkt->pkttype == PKT_RING_TRUST) + continue; /* we write it later on our own */ + + if ( (rc = build_packet (fp, node->pkt) )) + { + log_error ("build_packet(%d) failed: %s\n", + node->pkt->pkttype, g10_errstr(rc) ); + return rc; + } + 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) + { + cacheval |= 1; + if (sig->flags.valid) + cacheval |= 2; + } + 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)) { + log_error ("writing sigcache packet failed\n"); + return G10ERR_WRITE_FILE; + } + } + } + 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. + */ +int +keyring_rebuild_cache () +{ + KEYRING_HANDLE hd; + KEYDB_SEARCH_DESC desc; + KBNODE keyblock = NULL, node; + const char *lastresname = NULL, *resname; + IOBUF tmpfp = NULL; + char *tmpfilename = NULL; + char *bakfilename = NULL; + int rc; + ulong count = 0, sigcount = 0; + + hd = keyring_new (0); + memset (&desc, 0, sizeof desc); + desc.mode = KEYDB_SEARCH_MODE_FIRST; + + while ( !(rc = keyring_search (hd, &desc, 1)) ) + { + desc.mode = KEYDB_SEARCH_MODE_NEXT; + resname = keyring_get_resource_name (hd); + if (lastresname != resname ) + { /* we have switched to a new keyring - commit changes */ + if (tmpfp) + { + if (iobuf_close (tmpfp)) + { + log_error ("error closing `%s': %s\n", + tmpfilename, strerror (errno)); + rc = G10ERR_CLOSE_FILE; + goto leave; + } + /* because we have switched resources, we can be sure that + * the original file is closed */ + tmpfp = NULL; + } + rc = lastresname? rename_tmp_file (bakfilename, tmpfilename, + lastresname, 0) : 0; + m_free (tmpfilename); tmpfilename = NULL; + m_free (bakfilename); bakfilename = NULL; + if (rc) + goto leave; + lastresname = resname; + if (!opt.quiet) + log_info (_("checking keyring `%s'\n"), resname); + rc = create_tmp_file (resname, &bakfilename, &tmpfilename, &tmpfp); + if (rc) + goto leave; + } + + release_kbnode (keyblock); + rc = keyring_get_keyblock (hd, &keyblock); + if (rc) + { + log_error ("keyring_get_keyblock failed: %s\n", g10_errstr(rc)); + goto leave; + } + assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY); + + /* check all signature to set the signature's cache flags */ + for (node=keyblock; node; node=node->next) + { + if (node->pkt->pkttype == PKT_SIGNATURE) + { + check_key_signature (keyblock, node, NULL); + sigcount++; + } + } + + /* write the keyblock to the temporary file */ + rc = write_keyblock (tmpfp, keyblock); + if (rc) + goto leave; + + if ( !(++count % 50) && !opt.quiet) + log_info(_("%lu keys so far checked (%lu signatures)\n"), + count, sigcount ); + + } /* end main loop */ + if (rc == -1) + rc = 0; + if (rc) + { + log_error ("keyring_search failed: %s\n", g10_errstr(rc)); + goto leave; + } + log_info(_("%lu keys checked (%lu signatures)\n"), count, sigcount ); + if (tmpfp) + { + if (iobuf_close (tmpfp)) + { + log_error ("error closing `%s': %s\n", + tmpfilename, strerror (errno)); + rc = G10ERR_CLOSE_FILE; + goto leave; + } + /* because we have switched resources, we can be sure that + * the original file is closed */ + tmpfp = NULL; + } + rc = lastresname? rename_tmp_file (bakfilename, tmpfilename, + lastresname, 0) : 0; + m_free (tmpfilename); tmpfilename = NULL; + m_free (bakfilename); bakfilename = NULL; + + leave: + if (tmpfp) + iobuf_cancel (tmpfp); + m_free (tmpfilename); + m_free (bakfilename); + release_kbnode (keyblock); + keyring_release (hd); + return rc; +} + /**************** * Perform insert/delete/update operation. @@ -932,38 +1241,9 @@ do_copy (int mode, const char *fname, KBNODE root, int secret, } /* create the new file */ - #ifdef USE_ONLY_8DOT3 - /* Here is another Windoze bug?: - * you cant rename("pubring.gpg.tmp", "pubring.gpg"); - * but rename("pubring.gpg.tmp", "pubring.aaa"); - * works. So we replace .gpg by .bak or .tmp - */ - if( strlen (fname) > 4 - && !strcmp (fname+strlen(fname)-4, EXTSEP_S "gpg") ) { - bakfname = m_alloc( strlen (fname) + 1 ); - strcpy(bakfname, fname); - strcpy(bakfname+strlen(fname)-4, EXTSEP_S "bak"); - tmpfname = m_alloc( strlen( fname ) + 1 ); - strcpy(tmpfname,fname); - strcpy(tmpfname+strlen(fname)-4, EXTSEP_S "tmp"); - } - else { /* file does not end with gpg; hmmm */ - bakfname = m_alloc( strlen( fname ) + 5 ); - strcpy(stpcpy(bakfname, fname), EXTSEP_S "bak"); - tmpfname = m_alloc( strlen( fname ) + 5 ); - strcpy(stpcpy(tmpfname, fname), EXTSEP_S "tmp"); - } - #else - bakfname = m_alloc( strlen( fname ) + 2 ); - strcpy(stpcpy(bakfname,fname),"~"); - tmpfname = m_alloc( strlen( fname ) + 5 ); - strcpy(stpcpy(tmpfname,fname), EXTSEP_S "tmp"); - #endif - newfp = iobuf_create (tmpfname); - if (!newfp) { - log_error ("%s: can't create: %s\n", tmpfname, strerror(errno) ); + rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); + if (rc) { iobuf_close(fp); - rc = G10ERR_OPEN_FILE; goto leave; } @@ -1003,20 +1283,12 @@ do_copy (int mode, const char *fname, KBNODE root, int secret, } if( mode == 1 || mode == 3 ) { /* insert or update */ - KBNODE kbctx, node; - - /* append the new data */ - kbctx=NULL; - while( (node = walk_kbnode( root, &kbctx, 0 )) ) { - if( (rc = build_packet( newfp, node->pkt )) ) { - log_error("build_packet(%d) failed: %s\n", - node->pkt->pkttype, g10_errstr(rc) ); - iobuf_close(fp); - iobuf_cancel(newfp); - rc = G10ERR_WRITE_FILE; - goto leave; - } - } + rc = write_keyblock (newfp, root); + if (rc) { + iobuf_close(fp); + iobuf_cancel(newfp); + goto leave; + } } if( mode == 2 || mode == 3 ) { /* delete or update */ @@ -1043,58 +1315,11 @@ do_copy (int mode, const char *fname, KBNODE root, int secret, rc = G10ERR_CLOSE_FILE; goto leave; } - /* if the new file is a secring, restrict the permissions */ - #ifndef HAVE_DOSISH_SYSTEM - if( secret && !opt.preserve_permissions ) { - if( chmod( tmpfname, S_IRUSR | S_IWUSR ) ) { - log_error("%s: chmod failed: %s\n", - tmpfname, strerror(errno) ); - rc = G10ERR_WRITE_FILE; - goto leave; - } - } - #endif - /* rename and make backup file */ - if( !secret ) { /* but not for secret keyrings */ - iobuf_ioctl (NULL, 2, 0, (char *)bakfname ); - iobuf_ioctl (NULL, 2, 0, (char *)fname ); - #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove( bakfname ); - #endif - if( rename( fname, bakfname ) ) { - log_error("%s: rename to `%s' failed: %s\n", - fname, bakfname, strerror(errno) ); - rc = G10ERR_RENAME_FILE; - goto leave; - } - } - iobuf_ioctl (NULL, 2, 0, (char*)tmpfname ); - iobuf_ioctl (NULL, 2, 0, (char*)fname ); - #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove( fname ); - #endif - if( rename( tmpfname, fname ) ) { - log_error("%s: rename to `%s' failed: %s\n", - tmpfname, fname,strerror(errno) ); - rc = G10ERR_RENAME_FILE; - if( secret ) { - log_info(_( - "WARNING: 2 files with confidential information exists.\n")); - log_info(_("%s is the unchanged one\n"), fname ); - log_info(_("%s is the new one\n"), tmpfname ); - log_info(_("Please fix this possible security flaw\n")); - } - goto leave; - } + rc = rename_tmp_file (bakfname, tmpfname, fname, secret); leave: m_free(bakfname); m_free(tmpfname); return rc; } - - - - - diff --git a/g10/keyring.h b/g10/keyring.h index 253b86eab..141df45ea 100644 --- a/g10/keyring.h +++ b/g10/keyring.h @@ -39,6 +39,6 @@ int keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb); int keyring_delete_keyblock (KEYRING_HANDLE hd); int keyring_search_reset (KEYRING_HANDLE hd); int keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc); - +int keyring_rebuild_cache (void); #endif /*GPG_KEYRING_H*/ diff --git a/g10/keyring.o b/g10/keyring.o index a188ed02459d541957e5a43062a31dc6bf61dea5..66731335ee8d2dab6b73663e2df0cb9a4bcc3b9a 100644 GIT binary patch delta 19677 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

W|Cqzz;qtPNuxqWzwEgmyji zNNpzbC~Xn5HAXAuh+lh@d7Snb^LVX{`C4r&^F-|s^Yz*%%#*aQm~YU2VxH{bB<%v} zss8~nRWl6o1MxI1oO!0!fq9k|&3v=gi+Q#-5IhUZ)i1u3=gtDjU&*5&3tS++7Id>+ zE%jf^L-Zl3uMrk5_x0;!O3>e-Pe<-Y+_9YAB^XG;eB< zPV=K$+DyE{Cgd%$QC_hGMW_c9V(=mU9GPQ8iY&hlTqfpfbPX`l9d=50Xfi+uh((%nTPDuX2CDgo$YO1TV*_5IIX6Bs%G7RT{W1*~RT*&C(Q=q` zHJdq4dz^WN_7wB&+GggJ+UwwE=!`!SJ!^zWJBo;T8ePZQ+LMMvTHT?E5&6;w)(rY&Wo za%~0k8(Kc|HtlKVx3uS&cW5s$zpZU!en;B{{tG(kM<>Z!JJWIJ^^2#}%-Aw4(%LKi zQ6(LCO!{N5#|KrKdr97>(Q!{9AohD^{sB+Ft38AJzGrYh(0=b^Mc#uR7kp%C$((RV zO9THX+q;)Xk(TiieClLF4{H;!cAG7vf&0wU(8HdFe(q`LQLQzX|D|WJzS6FddTg1v zba+PVTWvIF_(5~;5P#R)tNlsMbBFK@&}nTA=dINqVm{*;xSzBQtp8binYL^S0dd|l za&_9fjvD%ZX&*6P)($gY(42b~<-I8H9PQv0KfDr}|KvH^GGn0cDVpdt;A!9(F;<_1 z2h0Uvt4#QHcvReu2r=yh_bPU;Wn*>N%McLPN*js<#C3WrM-85+J1!;tBz+9)Z_pE& zC+n^kr|8&>o&Mv{(igMQG`)a%s_s0UP@&WG7g?XI|Al#`zMFZLzL)tX{XOQJ^$(e6 z>z^=Nb9L8^^YnjlLaH7*ZK%iY4LD72Cf5ozXo21u{209D7vpqVDbFeogp% zg9}7Jr<0SasGvU->`tQ_+x}6J);q9>5zF)iSY)4r%S5Ie7c#;Fu*d&-`qiXF2#6K> zI0wP2boZg-4t<_SPs@rzK-{UXbP$}cyIafZ(RvXl6zIjwcjmxJI3Eqypg)_UgP!@7I$+PZu2KI-w)A3Rg=aXpL6c|vy|&erQs zu>L9iS>~tp=Okk~2gEaa6(>CFnRn0We`Edgy1SA$c&6G5dKk?egn)QaZ^HbN-i7%! zJ(js#@6G(WK58yU-qdF?Z`0Gk)8J}9hNCeGpR1TmmMW$JT`9R(&e^*q-!BKf)L}cq zA7}j$93ys-xp);^CMx6*zonRl_(R3+4zk}ftOs;gU+o#z5B1JeC<0Ci&q#ix2OKr@ zUs(D)jvUodj|>6vwVusfqu<8-onFBFy?!6_aeXcG34J~DDg9~YA3ZzHKlLqAFNgS` z{w5p!q`%GlvtG??8lN%yjN{CWjbE6<47nX39uQX*&)mvLW^QA+4}Wcq`K*sJ7BhD++y}vq#%-+cWH@&$?AQU(*(lbsdYaTP z>dYNRJoBB#21i?OKxV^b%_J5&k>0c4;e9d$gKsJiBcmBndvwz6Av1+pSM;_ z`*y5i_sD+8xC(j-0r7~mci1-E%lE5>ySHyK=#(CXa_*t|oTZ+w19&i*h=iM*1d+@7 z*NiDtB0@lv8}y`P*TIa}`M?-=g6{;u&f z8&w$3GjB6CGjBKcGrwhg%Dlt)nt7LT3S5jv_~Fq;;3p-om9J+uD{dU6GE^w}woKS! zINznb&?mB;N)R;)svBDT?g|U}9n5d#JK8Yczm27g_P3W7WHsp*ERYoMPwGV>J z#2&fS$`psg<~7NC4O(iu6uV2U%Cpp}4Rt%FE%5`RD>6{P-N_j2Ao!5s-h2-m^H~46 zk;(jpaXa&u#(m7k4EKuko$(Coe=yt|&p(YS^$>^3Y7O^c>Sv>lGyGz>4^!toSDQLR z{auDn@U458|tTF^d6O+oNK-|wkaD+MDVH%X? zW(p^?G#4_rHr>aIHs-CYk1}(a+nesAS_jj81nFoNuuW&v-Osw1&VEJ>iZ-8e2c@gI znKN`V-I42V?q_`u^CRY-9=_WAnf0;eui%03mLHxYe~$qdz(e#@J4xz&CJo9>#Fl7e zs?%OnKuIA@8nrfwvn98=!Y1UE8l;CBL`)S^AeR#tAa9IFkmZm*AO?DdY>-K7M=r{M z7;L(akVDMSeh?5t&1lMr5D>%7s~rT7GzT${Hr*#`zd48XyYqyx~Igpg&o{o_MF~mF!ZX7S@S*lope=xSE(~MDW^-ti z5X-=2;w8D8uT&fkyETewJNScQI!d3DyvamXv0ZUAm_h($s@|wLjjAeeqoW#7%!`n^wrPEvHe74zXKFIuzxsLf=^BH#s-(~LMguj~A%)8CQ%iuR@UQ7qfPR!NjXyy;h3CtgQR{cTqu8`gmhs=^tMEuRO>_0Kxhx<>>^=$K*XLTPo z|H}HK=6>cc&2N~$GLJKVZJuF1X4Zk#4*s3_D<^z!w%`?a+U(4H#_Y}flX(O4&*qKH z=goBH3+58$i>CXf?IrVR*8ggm8#to*-e&gs-eqp&dyl!X?+fN;zHgW#eSc?e?z_a? z!WTOH0-}|#i<;m8(b{*7WVwU4@eSsLj=s^%oqX;#(Z!d}`mVkV=5D@K%-wzNLwtMjqf6Jyswcuj{~B&FA}^TOUsXCNn6IJl3$iv z$v5Bv@v=$Z7XMS~Uy+WelloUp`nEW18OFarY%%F;WSZm^^amjd2?gQ}dFSW>_Jirp zL7@VlNdyQr_=L_WVrmeD7<`EPBX2Z*zD8l9WM_ef)?E86rI^EoWtR(BAb>tE3?b@df`_D0z&wze!E`ue9vT3SweYA`(o|AZ-J;o{8n;R|I`L@<3>b|w;rXU8TCMGN9Y zPRjh$r3@7B9jpKZd-j=f%W4Sba<^0U$X-h+6DMv((gy5v?SWKgYIDs@w5*j73bbeZp zW|`DyEw{gVtLdzqG$hm9ykZ6kIpb*|P$DJ*ip^P^wJ0SgeSY5J%mpdVin!LvnXv$c z4xlnHl4-Jnf%dywyI3?;bJBC=l;SS@n}Rx>ja;&g6u~T&S=5XnH#JbXtxj8>mxZN- zMbsaYh1RO8_??_SxoRre;oGxfmn~nA9_p~iGg;}kxlN$L?QgdG?Gtak-gp33@__yW z%m2LN!^Z7{IV)3AGc!|i)3K<6xoT1OA24{Ry>)j_yA%d zfBev=@Pd-d?>9=T0KS_a$_y?i0*u8v-q z3TH2HQfMQUlN@93qz0FJt?aTr(RSHh)1LR<3-*+Ko$L*J+D{QQNhw2U=ZwxyO((6`gebjVVdV<0f48Uws8LI8n-|m77`EPUE-S@@Ynfv^9`M&;-yyv&0_t)r29c}$U zw?^527h+wQ-RnR%eQig3@`0YdwH<{Bv!@=w7J49(lusS#+30yF50A0;AL!-_tHm!a z>@x?tH@XvN;h`0F`|56u=KT%5Z)}gN?xu?~_QL9(`n)gf2dh!q7Z@`88I)FC9r?Rk zzQhsj!>=@8-PS%)-NASCm=KTJSG~W{qU$;xzq-)m@2Tn69Q1C8;^SanLsva~H2gkv zI*@*+&|0O_k1puzaeB`|_VnI_zGtQ{Hz~dvae9e;N~P1yn%=a@mp@2HG$ARhWkkJMy;2_Gt}FFsUW81+j9 zN^gVsaY%ZRfOJdrY+w-jktgM$456?0LUH1sMvIKfggd z^gK^Ck#yC5yn(?+#CPh>Pw1$?oek2RpA0!wPz9efNUv!SKiMFD-W#W@zK+U5feH+L zT}L{Khi?0!INkVbG0k3wf*P2J_zSoSE?4n6h)3b>xl6_K5I>4IUJ^?C`wSs1cpVJ_|nB(w2wJ7u*VW@)8<3lJO`hGAJf1C?& z@;`_8dOTs%13GzZdxP}%8^pf|#cBMh0jEO>759a1%qrdiaZ=HTdPv_JdgG%T#FHDu z7c__mRs1SQS>Qc(??a`18eCtUE5+jF^Ya#_I0fJy ziDM^gc?#}Lslmm|vjkmD=pYiyvxCkNs4^^Go)*kh^@s&&i_(L^^xK2Nx%fConX;6( zvH2^5>EgE3%%v$y=V#%1A(qDe)@2D*;HaUiTMC~u_A{TfZAupkr_@~gl}`rPXFtic zGd}G!47+oGctV3au7lL^zBHR8UUu9~vV)NS3W3r$E4zK9?_|I8XqnBbed%4DsY&sYyJc>b*zBk2t;s3HAc@6%ZjMCq#^!X&a;&lX?iT|Nuoi+ASwT7ile?MDt=QVEFwynO9>dr(KTHxF~{UbX;K@S95R zRB{&?z_6Mm3T%Nhora_@B-sz7I2y7{#s8?}K_v^DARV520+Q^{G({ZWa7Bbe4uMA? zNpFo;Fo6=#gSS+?j^cQ&KbZ;|CPY)*Oz7uDi6lqh_l_h-;=m?33jdxPk_tSl8iCcN!Znrgxz_Pu&ak8J9;y!TQF=7AVpVF{9cHw zN%p`sMd`;V{RE|-q4aZ*carh=&$aw3L+B<{bFts%Q%pCF0Jno1I`&sDM%l3f23NtE+v(xaoV zw5Iiso*p4Z0+tQQSlqJPIEF2hY^!8PNLm#`NlwB)!X`Zmep01BOL`Q%i6qLcAURZs z??|HO|A3?hoTfNBa#dT5KPe*HLV=9!NFrlAN%UkiNsL`0NsQfONV1XCATU0Hl<^ZRH^t!6i*W3Taw6kM(KOtT-JOT|2_b! zXe>z>OqK~4V~V5YDJ0RbB_uIKcc^$NN%Z(plIZb9rQfdf6-xgeBz5Qmile;aBvH@L zq_>bzrxF@rDNzM|Nn#ERR}!mCXu1$kNm&hrhWTRBY=%u4Nz9Fr(2-pQ$!-_|8td*t z%%dJ-Rh@#3)*r_^3epC^!|0TSe}W^jVN5^gkAg83kQ4)nhTTFEar_cq%I}msj>5E| zn7w@*{f#)P$u3jLwMuSPatkV>^pU88q&WogdLd#);9oA1V&@nrOd<9u`SBS0rLR8y EFYclo3jhEB delta 15583 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 QINbv7L;JY@I`y~z0)*O?eE + /* We used this in gpg 1.0.5 and 1.0.6 to cache signature + * verification results - it is no longer used. + * "GPG" 0x00 * where mode == 1: valid data, stat == 0: invalid signature * stat == 1: valid signature * (because we use private data, we check our marker) */ @@ -1732,8 +1734,18 @@ parse_trust( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt ) c = iobuf_get_noeof(inp); pkt->pkt.ring_trust = m_alloc( sizeof *pkt->pkt.ring_trust ); pkt->pkt.ring_trust->trustval = c; + pkt->pkt.ring_trust->sigcache = 0; + if (!c && pktlen==2) { + c = iobuf_get_noeof (inp); + /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/ + if ( !(c & 0x80) ) + pkt->pkt.ring_trust->sigcache = c; + } if( list_mode ) - printf(":trust packet: flag=%02x\n", c ); + printf(":trust packet: flag=%02x sigcache=%02x\n", + pkt->pkt.ring_trust->trustval, + pkt->pkt.ring_trust->sigcache); + } diff --git a/g10/sig-check.c b/g10/sig-check.c index fe63a1381..754bc2fd7 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -120,96 +120,6 @@ do_signature_check( PKT_signature *sig, MD_HANDLE digest, } -#if 0 /* not anymore used */ -/**************** - * Check the MDC which is contained in SIG. - * The MD_HANDLE should be currently open, so that this function - * is able to append some data, before finalizing the digest. - */ -int -mdc_kludge_check( PKT_signature *sig, MD_HANDLE digest ) -{ - int rc=0; - - if( (rc=check_digest_algo(sig->digest_algo)) ) - return rc; - - /* make sure the digest algo is enabled (in case of a detached mdc??) */ - md_enable( digest, sig->digest_algo ); - - /* complete the digest */ - if( sig->version >= 4 ) - md_putc( digest, sig->version ); - md_putc( digest, sig->sig_class ); - if( sig->version < 4 ) { - u32 a = sig->timestamp; - md_putc( digest, (a >> 24) & 0xff ); - md_putc( digest, (a >> 16) & 0xff ); - md_putc( digest, (a >> 8) & 0xff ); - md_putc( digest, a & 0xff ); - } - else { - byte buf[6]; - size_t n; - md_putc( digest, sig->pubkey_algo ); - md_putc( digest, sig->digest_algo ); - if( sig->hashed ) { - n = sig->hashed->len; - md_putc (digest, (n >> 8) ); - md_putc (digest, n ); - md_write (digest, sig->hashed->data, n); - n += 6; - } - else - n = 6; - /* add some magic */ - buf[0] = sig->version; - buf[1] = 0xff; - buf[2] = n >> 24; - buf[3] = n >> 16; - buf[4] = n >> 8; - buf[5] = n; - md_write( digest, buf, 6 ); - } - md_final( digest ); - - rc = G10ERR_BAD_SIGN; - { const byte *s1 = md_read( digest, sig->digest_algo ); - int s1len = md_digest_length( sig->digest_algo ); - - log_hexdump( "MDC calculated", s1, s1len ); - - if( !sig->data[0] ) - log_debug("sig_data[0] is NULL\n"); - else { - unsigned s2len; - byte *s2; - s2 = mpi_get_buffer( sig->data[0], &s2len, NULL ); - log_hexdump( "MDC stored ", s2, s2len ); - - if( s2len != s1len ) - log_debug("MDC check: len differ: %d/%d\n", s1len, s2len); - else if( memcmp( s1, s2, s1len ) ) - log_debug("MDC check: hashs differ\n"); - else - rc = 0; - m_free(s2); - } - } - - if( !rc && sig->flags.unknown_critical ) { - log_info(_("assuming bad MDC due to an unknown critical bit\n")); - rc = G10ERR_BAD_SIGN; - } - sig->flags.checked = 1; - sig->flags.valid = !rc; - - /* FIXME: check that we are actually in an encrypted packet */ - - return rc; -} -#endif - /**************** * This function gets called by pubkey_verify() if the algorithm needs it. */ @@ -402,8 +312,6 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest, log_info(_("assuming bad signature due to an unknown critical bit\n")); rc = G10ERR_BAD_SIGN; } - sig->flags.checked = 1; - sig->flags.valid = !rc; return rc; } @@ -442,31 +350,20 @@ hash_uid_node( KBNODE unode, MD_HANDLE md, PKT_signature *sig ) } static void -cache_selfsig_result ( PKT_signature *sig, int result ) +cache_sig_result ( PKT_signature *sig, int result ) { - byte buf[6]; - - if ( opt.no_sig_cache ) - return; - - buf[0] = 'G'; - buf[1] = 'P'; - buf[2] = 'G'; - buf[3] = 0; if ( !result ) { - buf[4] = 1; /* mark cache valid */ - buf[5] = 1; /* mark signature valid */ + sig->flags.checked = 1; + sig->flags.valid = 1; } else if ( result == G10ERR_BAD_SIGN ) { - buf[4] = 1; /* mark cache valid */ - buf[5] = 0; /* mark signature invalid */ + sig->flags.checked = 1; + sig->flags.valid = 0; } else { - buf[4] = 0; /* mark cache invalid */ - buf[5] = 0; + sig->flags.checked = 0; + sig->flags.valid = 0; } - - build_sig_subpkt (sig, SIGSUBPKT_PRIV_VERIFY_CACHE, buf, 6 ); } /**************** @@ -503,20 +400,9 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, sig = node->pkt->pkt.signature; algo = sig->digest_algo; - #if 0 /* I am not sure whether this is a good thing to do */ - if( sig->flags.checked ) - log_debug("check_key_signature: already checked: %s\n", - sig->flags.valid? "good":"bad" ); - #endif - - /* Check whether we have cached the result of a previous signature check.*/ + /* check whether we have cached the result of a previous signature check.*/ if ( !opt.no_sig_cache ) { - const byte *p; - size_t len; - - p = parse_sig_subpkt( sig->unhashed, - SIGSUBPKT_PRIV_VERIFY_CACHE, &len ); - if ( p && len >= 2 && p[0] == 1 ) { /* cache hit */ + if (sig->flags.checked) { /*cached status available*/ if( is_selfsig ) { u32 keyid[2]; @@ -524,7 +410,7 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) *is_selfsig = 1; } - return p[1] == 1? 0 : G10ERR_BAD_SIGN; + return sig->flags.valid? 0 : G10ERR_BAD_SIGN; } } @@ -535,7 +421,7 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, md = md_open( algo, 0 ); hash_public_key( md, pk ); rc = do_check( pk, sig, md, r_expired ); - cache_selfsig_result ( sig, rc ); + cache_sig_result ( sig, rc ); md_close(md); } else if( sig->sig_class == 0x28 ) { /* subkey revocation */ @@ -546,7 +432,7 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, hash_public_key( md, pk ); hash_public_key( md, snode->pkt->pkt.public_key ); rc = do_check( pk, sig, md, r_expired ); - cache_selfsig_result ( sig, rc ); + cache_sig_result ( sig, rc ); md_close(md); } else { @@ -571,7 +457,7 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, hash_public_key( md, pk ); hash_public_key( md, snode->pkt->pkt.public_key ); rc = do_check( pk, sig, md, r_expired ); - cache_selfsig_result ( sig, rc ); + cache_sig_result ( sig, rc ); md_close(md); } else { @@ -585,7 +471,7 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, md = md_open( algo, 0 ); hash_public_key( md, pk ); rc = do_check( pk, sig, md, r_expired ); - cache_selfsig_result ( sig, rc ); + cache_sig_result ( sig, rc ); md_close(md); } else { /* all other classes */ @@ -602,11 +488,11 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, if( is_selfsig ) *is_selfsig = 1; rc = do_check( pk, sig, md, r_expired ); - cache_selfsig_result ( sig, rc ); } else { rc = do_signature_check( sig, md, r_expiredate, r_expired ); } + cache_sig_result ( sig, rc ); md_close(md); } else { diff --git a/g10/tdbio.c b/g10/tdbio.c index 0ef1ec086..59bcc8530 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -768,7 +768,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum ) rc = tdbio_read_record( rec.r.hlst.next, &rec, RECTYPE_HLST); if( rc ) { - log_error( "scan keyhashtbl read hlst failed: %s\n", + log_error( "upd_hashtable: read hlst failed: %s\n", g10_errstr(rc) ); return rc; } @@ -923,7 +923,7 @@ drop_from_hashtable( ulong table, byte *key, int keylen, ulong recnum ) rc = tdbio_read_record( rec.r.hlst.next, &rec, RECTYPE_HLST); if( rc ) { - log_error( "scan keyhashtbl read hlst failed: %s\n", + log_error( "drop_from_hashtable: read hlst failed: %s\n", g10_errstr(rc) ); return rc; } diff --git a/g10/trustdb.c b/g10/trustdb.c index 9ed3a2860..fb06e858d 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -718,9 +718,11 @@ get_validity (PKT_public_key *pk, const byte *namehash) if ( (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) ) validity |= TRUST_FLAG_DISABLED; - /* for convenience set some flags from the key */ + /* set some flags direct from the key */ if (pk->is_revoked) validity |= TRUST_FLAG_REVOKED; + /* Note: expiration is a trust value and not a flag - don't know why + * I initially designed it that way */ if (pk->has_expired) validity = (validity & ~TRUST_MASK) | TRUST_EXPIRED; @@ -879,6 +881,9 @@ make_key_array (KEYDB_HANDLE hd, KeyHashTable visited, desc.mode = KEYDB_SEARCH_MODE_NEXT; /* change mode */ do { + PKT_public_key *pk; + u32 kid[2]; + rc = keydb_get_keyblock (hd, &keyblock); if (rc) { @@ -896,18 +901,25 @@ make_key_array (KEYDB_HANDLE hd, KeyHashTable visited, continue; } + /* prepare the keyblock for further processing */ + merge_keys_and_selfsig (keyblock); clear_kbnode_flags (keyblock); - if (cmpfnc (keyblock, cmpval)) - { - u32 kid[2]; + pk = keyblock->pkt->pkt.public_key; + keyid_from_pk (pk, kid); /*(cheap: should already be cached in the pk)*/ + if (pk->has_expired || pk->is_revoked) + { + /* it does not make sense to look further at those keys */ + add_key_hash_table (visited, kid); + } + else if (cmpfnc (keyblock, cmpval)) + { if (nkeys == maxkeys) { maxkeys += 1000; keys = m_realloc (keys, (maxkeys+1) * sizeof *keys); } keys[nkeys++].keyblock = keyblock; /* This key is signed - don't check it again */ - keyid_from_pk (keyblock->pkt->pkt.public_key, kid); add_key_hash_table (visited, kid); } else @@ -1018,10 +1030,11 @@ cmp_kid_for_make_key_array (KBNODE kb, void *opaque) struct key_item *klist = opaque; struct key_item *kr; KBNODE node, uidnode=NULL; + PKT_public_key *pk = kb->pkt->pkt.public_key; u32 main_kid[2]; int issigned=0, any_signed = 0, fully_count =0, marginal_count = 0; - keyid_from_pk(kb->pkt->pkt.public_key, main_kid); + keyid_from_pk(pk, main_kid); for (node=kb; node; node = node->next) { if (node->pkt->pkttype == PKT_USER_ID)