mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-01 16:33:02 +01:00
Changed signature status cache
This commit is contained in:
parent
a3af543617
commit
1f4bdf4d26
12
NEWS
12
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)
|
||||
------------------------------------------------
|
||||
|
@ -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.
|
||||
</para></listitem></varlistentry>
|
||||
|
||||
|
||||
@ -1530,9 +1529,7 @@ Don't insert new keys into the keyrings while doing an import.
|
||||
<varlistentry>
|
||||
<term>--allow-secret-key-import</term>
|
||||
<listitem><para>
|
||||
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.
|
||||
</para></listitem></varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -1,3 +1,31 @@
|
||||
2001-09-25 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* 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 <wk@gnupg.org>
|
||||
|
||||
* g10.c, options.h: New option --no-auto-check-trustdb.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
12
g10/g10.c
12
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:
|
||||
|
32
g10/import.c
32
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]);
|
||||
|
18
g10/keydb.c
18
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
|
||||
|
@ -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);
|
||||
|
449
g10/keyring.c
449
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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*/
|
||||
|
BIN
g10/keyring.o
BIN
g10/keyring.o
Binary file not shown.
@ -109,7 +109,6 @@ struct {
|
||||
int show_session_key;
|
||||
int use_agent;
|
||||
int merge_only;
|
||||
int allow_secret_key_import;
|
||||
int try_all_secrets;
|
||||
int no_expensive_trust_checks;
|
||||
int no_sig_cache;
|
||||
|
@ -235,6 +235,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
unsigned int trustval;
|
||||
unsigned int sigcache;
|
||||
} PKT_ring_trust;
|
||||
|
||||
typedef struct {
|
||||
@ -306,7 +307,7 @@ typedef enum {
|
||||
SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */
|
||||
SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */
|
||||
SIGSUBPKT_FEATURES =30, /* feature flags */
|
||||
SIGSUBPKT_PRIV_VERIFY_CACHE =101, /* cache verification result */
|
||||
SIGSUBPKT_PRIV_VERIFY_CACHE =101, /* cache verification result (obsolete)*/
|
||||
|
||||
SIGSUBPKT_FLAG_CRITICAL=128
|
||||
} sigsubpkttype_t;
|
||||
|
@ -883,7 +883,7 @@ dump_sig_subpkt( int hashed, int type, int critical,
|
||||
printf(" %02x", buffer[i] );
|
||||
break;
|
||||
case SIGSUBPKT_PRIV_VERIFY_CACHE:
|
||||
p = "verification cache";
|
||||
p = "obsolete verification cache";
|
||||
break;
|
||||
default: p = "?"; break;
|
||||
}
|
||||
@ -936,7 +936,9 @@ parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
|
||||
break;
|
||||
return 0;
|
||||
case SIGSUBPKT_PRIV_VERIFY_CACHE:
|
||||
/* "GPG" 0x00 <mode> <stat>
|
||||
/* We used this in gpg 1.0.5 and 1.0.6 to cache signature
|
||||
* verification results - it is no longer used.
|
||||
* "GPG" 0x00 <mode> <stat>
|
||||
* 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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
144
g10/sig-check.c
144
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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user