* packet.h, tdbio.h, tdbio.c (tdbio_read_record, tdbio_write_record),

trustdb.c (update_validity): Store temporary full & marginal counts in the
trustdb. (clear_validity, get_validity_counts): Return and clear temp
counts. (store_validation_status): Keep track of which keyids have been
stored. (validate_one_keyblock, validate_key_list): Use per-uid copies of
the full & marginal counts so they can be recalled for multiple levels.
(validate_keys): Only use unused keys for each new round.
(reset_unconnected_keys): Rename to reset_trust_records, and only skip
specifically excluded records.
This commit is contained in:
David Shaw 2003-01-06 22:56:08 +00:00
parent fd6d6fd147
commit af6e3ef045
5 changed files with 178 additions and 93 deletions

View File

@ -1,5 +1,19 @@
2003-01-06 David Shaw <dshaw@jabberwocky.com> 2003-01-06 David Shaw <dshaw@jabberwocky.com>
* packet.h, tdbio.h, tdbio.c (tdbio_read_record,
tdbio_write_record), trustdb.c (update_validity): Store temporary
full & marginal counts in the trustdb.
(clear_validity, get_validity_counts): Return and clear temp
counts.
(store_validation_status): Keep track of which keyids have been
stored.
(validate_one_keyblock, validate_key_list): Use per-uid copies of
the full & marginal counts so they can be recalled for multiple
levels.
(validate_keys): Only use unused keys for each new round.
(reset_unconnected_keys): Rename to reset_trust_records, and only
skip specifically excluded records.
* keylist.c (print_capabilities): Show 'D' for disabled keys in * keylist.c (print_capabilities): Show 'D' for disabled keys in
capabilities section. capabilities section.

View File

@ -49,7 +49,7 @@ typedef enum {
PKT_OLD_COMMENT =16, /* comment packet from an OpenPGP draft */ PKT_OLD_COMMENT =16, /* comment packet from an OpenPGP draft */
PKT_ATTRIBUTE =17, /* PGP's attribute packet */ PKT_ATTRIBUTE =17, /* PGP's attribute packet */
PKT_ENCRYPTED_MDC =18, /* integrity protected encrypted data */ PKT_ENCRYPTED_MDC =18, /* integrity protected encrypted data */
PKT_MDC =19, /* manipulaion detection code packet */ PKT_MDC =19, /* manipulation detection code packet */
PKT_COMMENT =61, /* new comment packet (private) */ PKT_COMMENT =61, /* new comment packet (private) */
PKT_GPG_CONTROL =63 /* internal control packet */ PKT_GPG_CONTROL =63 /* internal control packet */
} pkttype_t; } pkttype_t;
@ -169,6 +169,8 @@ typedef struct {
unsigned long attrib_len; unsigned long attrib_len;
int help_key_usage; int help_key_usage;
u32 help_key_expire; u32 help_key_expire;
int help_full_count;
int help_marginal_count;
int is_primary; int is_primary;
int is_revoked; int is_revoked;
int is_expired; int is_expired;

View File

@ -1218,6 +1218,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
memcpy( rec->r.valid.namehash, p, 20); p+=20; memcpy( rec->r.valid.namehash, p, 20); p+=20;
rec->r.valid.validity = *p++; rec->r.valid.validity = *p++;
rec->r.valid.next = buftoulong(p); p += 4; rec->r.valid.next = buftoulong(p); p += 4;
rec->r.valid.full_count = *p++;
rec->r.valid.marginal_count = *p++;
break; break;
default: default:
log_error( "%s: invalid record type %d at recnum %lu\n", log_error( "%s: invalid record type %d at recnum %lu\n",
@ -1299,6 +1301,8 @@ tdbio_write_record( TRUSTREC *rec )
memcpy( p, rec->r.valid.namehash, 20); p += 20; memcpy( p, rec->r.valid.namehash, 20); p += 20;
*p++ = rec->r.valid.validity; *p++ = rec->r.valid.validity;
ulongtobuf( p, rec->r.valid.next); p += 4; ulongtobuf( p, rec->r.valid.next); p += 4;
*p++ = rec->r.valid.full_count;
*p++ = rec->r.valid.marginal_count;
break; break;
default: default:

View File

@ -50,7 +50,7 @@ struct trust_record {
ulong recnum; ulong recnum;
union { union {
struct { /* version record: */ struct { /* version record: */
byte version; /* should be 3 */ byte version; /* should be 3 */
byte marginals; byte marginals;
byte completes; byte completes;
byte cert_depth; byte cert_depth;
@ -84,6 +84,8 @@ struct trust_record {
byte namehash[20]; byte namehash[20];
ulong next; ulong next;
byte validity; byte validity;
byte full_count;
byte marginal_count;
} valid; } valid;
} r; } r;
}; };

View File

@ -287,9 +287,8 @@ verify_own_keys(void)
(ulong)kid[1]); (ulong)kid[1]);
} }
} }
/* the --trusted-key option is again deprecated; however we automagically /* Put any --trusted-key keys into the trustdb */
* add those keys to the trustdb */
for (k = user_utk_list; k; k = k->next) for (k = user_utk_list; k; k = k->next)
{ {
if ( add_utk (k->kid) ) if ( add_utk (k->kid) )
@ -796,13 +795,19 @@ clear_ownertrusts (PKT_public_key *pk)
* Note: Caller has to do a sync * Note: Caller has to do a sync
*/ */
static void static void
update_validity (PKT_public_key *pk, const byte *namehash, update_validity (PKT_public_key *pk, PKT_user_id *uid,
int depth, int validity) int depth, int validity)
{ {
TRUSTREC trec, vrec; TRUSTREC trec, vrec;
int rc; int rc;
ulong recno; ulong recno;
byte namehash[20];
if( uid->attrib_data )
rmd160_hash_buffer (namehash,uid->attrib_data,uid->attrib_len);
else
rmd160_hash_buffer (namehash, uid->name, uid->len );
rc = read_trust_record (pk, &trec); rc = read_trust_record (pk, &trec);
if (rc && rc != -1) if (rc && rc != -1)
{ {
@ -840,6 +845,8 @@ update_validity (PKT_public_key *pk, const byte *namehash,
vrec.r.valid.next = trec.r.trust.validlist; vrec.r.valid.next = trec.r.trust.validlist;
} }
vrec.r.valid.validity = validity; vrec.r.valid.validity = validity;
vrec.r.valid.full_count = uid->help_full_count;
vrec.r.valid.marginal_count = uid->help_marginal_count;
write_record (&vrec); write_record (&vrec);
trec.r.trust.depth = depth; trec.r.trust.depth = depth;
trec.r.trust.validlist = vrec.recnum; trec.r.trust.validlist = vrec.recnum;
@ -872,14 +879,15 @@ clear_validity (PKT_public_key *pk)
write_record(&trec); write_record(&trec);
} }
/* reset validity for all user IDs */
recno = trec.r.trust.validlist; recno = trec.r.trust.validlist;
while (recno) while (recno)
{ {
read_record (recno, &vrec, RECTYPE_VALID); read_record (recno, &vrec, RECTYPE_VALID);
if ((vrec.r.valid.validity & TRUST_MASK)) if ((vrec.r.valid.validity & TRUST_MASK)
|| vrec.r.valid.marginal_count || vrec.r.valid.full_count)
{ {
vrec.r.valid.validity &= ~TRUST_MASK; vrec.r.valid.validity &= ~TRUST_MASK;
vrec.r.valid.marginal_count = vrec.r.valid.full_count = 0;
write_record (&vrec); write_record (&vrec);
any = 1; any = 1;
} }
@ -1033,7 +1041,6 @@ get_validity (PKT_public_key *pk, const byte *namehash)
return validity; return validity;
} }
int int
get_validity_info (PKT_public_key *pk, const byte *namehash) get_validity_info (PKT_public_key *pk, const byte *namehash)
{ {
@ -1051,17 +1058,51 @@ get_validity_info (PKT_public_key *pk, const byte *namehash)
return c; return c;
} }
static void
get_validity_counts (PKT_public_key *pk, PKT_user_id *uid)
{
TRUSTREC trec, vrec;
ulong recno;
byte namehash[20];
if(pk==NULL || uid==NULL)
BUG();
if( uid->attrib_data )
rmd160_hash_buffer (namehash,uid->attrib_data,uid->attrib_len);
else
rmd160_hash_buffer (namehash, uid->name, uid->len );
uid->help_marginal_count=uid->help_full_count=0;
init_trustdb ();
if(read_trust_record (pk, &trec)!=0)
return;
/* loop over all user IDs */
recno = trec.r.trust.validlist;
while (recno)
{
read_record (recno, &vrec, RECTYPE_VALID);
if(memcmp(vrec.r.valid.namehash,namehash,20)==0)
{
uid->help_marginal_count=vrec.r.valid.marginal_count;
uid->help_full_count=vrec.r.valid.full_count;
/* printf("Fetched marginal %d, full %d\n",uid->help_marginal_count,uid->help_full_count); */
break;
}
recno = vrec.r.valid.next;
}
}
void void
list_trust_path( const char *username ) list_trust_path( const char *username )
{ {
} }
/**************** /****************
* Enumerate all keys, which are needed to build all trust paths for * Enumerate all keys, which are needed to build all trust paths for
* the given key. This function does not return the key itself or * the given key. This function does not return the key itself or
@ -1149,7 +1190,7 @@ mark_keyblock_seen (KeyHashTable tbl, KBNODE node)
{ {
for ( ;node; node = node->next ) for ( ;node; node = node->next )
if (node->pkt->pkttype == PKT_PUBLIC_KEY if (node->pkt->pkttype == PKT_PUBLIC_KEY
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY) || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
{ {
u32 aki[2]; u32 aki[2];
@ -1159,7 +1200,6 @@ mark_keyblock_seen (KeyHashTable tbl, KBNODE node)
} }
static void static void
dump_key_array (int depth, struct key_array *keys) dump_key_array (int depth, struct key_array *keys)
{ {
@ -1197,10 +1237,9 @@ dump_key_array (int depth, struct key_array *keys)
static void static void
store_validation_status (int depth, KBNODE keyblock) store_validation_status (int depth, KBNODE keyblock, KeyHashTable stored)
{ {
KBNODE node; KBNODE node;
byte namehash[20];
int status; int status;
int any = 0; int any = 0;
@ -1209,7 +1248,6 @@ store_validation_status (int depth, KBNODE keyblock)
if (node->pkt->pkttype == PKT_USER_ID) if (node->pkt->pkttype == PKT_USER_ID)
{ {
PKT_user_id *uid = node->pkt->pkt.user_id; PKT_user_id *uid = node->pkt->pkt.user_id;
if (node->flag & 4) if (node->flag & 4)
status = TRUST_FULLY; status = TRUST_FULLY;
else if (node->flag & 2) else if (node->flag & 2)
@ -1221,13 +1259,11 @@ store_validation_status (int depth, KBNODE keyblock)
if (status) if (status)
{ {
if( uid->attrib_data )
rmd160_hash_buffer (namehash,uid->attrib_data,uid->attrib_len);
else
rmd160_hash_buffer (namehash, uid->name, uid->len );
update_validity (keyblock->pkt->pkt.public_key, update_validity (keyblock->pkt->pkt.public_key,
namehash, depth, status); uid, depth, status);
mark_keyblock_seen(stored,keyblock);
any = 1; any = 1;
} }
} }
@ -1449,9 +1485,10 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist,
{ {
struct key_item *kr; struct key_item *kr;
KBNODE node, uidnode=NULL; KBNODE node, uidnode=NULL;
PKT_user_id *uid=NULL;
PKT_public_key *pk = kb->pkt->pkt.public_key; PKT_public_key *pk = kb->pkt->pkt.public_key;
u32 main_kid[2]; u32 main_kid[2];
int issigned=0, any_signed = 0, fully_count =0, marginal_count = 0; int issigned=0, any_signed = 0;
keyid_from_pk(pk, main_kid); keyid_from_pk(pk, main_kid);
for (node=kb; node; node = node->next) for (node=kb; node; node = node->next)
@ -1460,22 +1497,23 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist,
{ {
if (uidnode && issigned) if (uidnode && issigned)
{ {
if (fully_count >= opt.completes_needed if (uid->help_full_count >= opt.completes_needed
|| marginal_count >= opt.marginals_needed ) || uid->help_marginal_count >= opt.marginals_needed )
uidnode->flag |= 4; uidnode->flag |= 4;
else if (fully_count || marginal_count) else if (uid->help_full_count || uid->help_marginal_count)
uidnode->flag |= 2; uidnode->flag |= 2;
uidnode->flag |= 1; uidnode->flag |= 1;
any_signed = 1; any_signed = 1;
} }
uidnode = node; uidnode = node;
uid=uidnode->pkt->pkt.user_id;
issigned = 0; issigned = 0;
fully_count = marginal_count = 0; get_validity_counts(pk,uid);
mark_usable_uid_certs (kb, uidnode, main_kid, klist, mark_usable_uid_certs (kb, uidnode, main_kid, klist,
curtime, next_expire); curtime, next_expire);
} }
else if (node->pkt->pkttype == PKT_SIGNATURE else if (node->pkt->pkttype == PKT_SIGNATURE
&& (node->flag & (1<<8)) ) && (node->flag & (1<<8)) && uid)
{ {
/* Note that we are only seeing unrevoked sigs here */ /* Note that we are only seeing unrevoked sigs here */
PKT_signature *sig = node->pkt->pkt.signature; PKT_signature *sig = node->pkt->pkt.signature;
@ -1535,12 +1573,12 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist,
pk->trust_regexp=sig->trust_regexp; pk->trust_regexp=sig->trust_regexp;
} }
if (kr->ownertrust == TRUST_ULTIMATE) if (kr->ownertrust == TRUST_ULTIMATE)
fully_count = opt.completes_needed; uid->help_full_count = opt.completes_needed;
else if (kr->ownertrust == TRUST_FULLY) else if (kr->ownertrust == TRUST_FULLY)
fully_count++; uid->help_full_count++;
else if (kr->ownertrust == TRUST_MARGINAL) else if (kr->ownertrust == TRUST_MARGINAL)
marginal_count++; uid->help_marginal_count++;
issigned = 1; issigned = 1;
} }
} }
@ -1548,10 +1586,10 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist,
if (uidnode && issigned) if (uidnode && issigned)
{ {
if (fully_count >= opt.completes_needed if (uid->help_full_count >= opt.completes_needed
|| marginal_count >= opt.marginals_needed ) || uid->help_marginal_count >= opt.marginals_needed )
uidnode->flag |= 4; uidnode->flag |= 4;
else if (fully_count || marginal_count) else if (uid->help_full_count || uid->help_marginal_count)
uidnode->flag |= 2; uidnode->flag |= 2;
uidnode->flag |= 1; uidnode->flag |= 1;
any_signed = 1; any_signed = 1;
@ -1576,7 +1614,7 @@ search_skipfnc (void *opaque, u32 *kid)
* Caller hast to release the returned array. * Caller hast to release the returned array.
*/ */
static struct key_array * static struct key_array *
validate_key_list (KEYDB_HANDLE hd, KeyHashTable visited, validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
struct key_item *klist, u32 curtime, u32 *next_expire) struct key_item *klist, u32 curtime, u32 *next_expire)
{ {
KBNODE keyblock = NULL; KBNODE keyblock = NULL;
@ -1600,7 +1638,7 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable visited,
memset (&desc, 0, sizeof desc); memset (&desc, 0, sizeof desc);
desc.mode = KEYDB_SEARCH_MODE_FIRST; desc.mode = KEYDB_SEARCH_MODE_FIRST;
desc.skipfnc = search_skipfnc; desc.skipfnc = search_skipfnc;
desc.skipfncvalue = visited; desc.skipfncvalue = full_trust;
rc = keydb_search (hd, &desc, 1); rc = keydb_search (hd, &desc, 1);
if (rc == -1) if (rc == -1)
{ {
@ -1643,10 +1681,12 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable visited,
if (pk->has_expired || pk->is_revoked) if (pk->has_expired || pk->is_revoked)
{ {
/* it does not make sense to look further at those keys */ /* it does not make sense to look further at those keys */
mark_keyblock_seen (visited, keyblock); mark_keyblock_seen (full_trust, keyblock);
} }
else if (validate_one_keyblock (keyblock, klist, curtime, next_expire)) else if (validate_one_keyblock (keyblock, klist, curtime, next_expire))
{ {
KBNODE node;
if (pk->expiredate && pk->expiredate >= curtime if (pk->expiredate && pk->expiredate >= curtime
&& pk->expiredate < *next_expire) && pk->expiredate < *next_expire)
*next_expire = pk->expiredate; *next_expire = pk->expiredate;
@ -1656,8 +1696,17 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable visited,
keys = m_realloc (keys, (maxkeys+1) * sizeof *keys); keys = m_realloc (keys, (maxkeys+1) * sizeof *keys);
} }
keys[nkeys++].keyblock = keyblock; keys[nkeys++].keyblock = keyblock;
/* this key is signed - don't check it again */
mark_keyblock_seen (visited, keyblock); /* Optimization - if all uids are fully trusted, then we
never need to consider this key as a candidate again. */
for (node=keyblock; node; node = node->next)
if (node->pkt->pkttype == PKT_USER_ID && !(node->flag & 4))
break;
if(node==NULL)
mark_keyblock_seen (full_trust, keyblock);
keyblock = NULL; keyblock = NULL;
} }
@ -1676,9 +1725,9 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable visited,
return keys; return keys;
} }
/* Caller must sync */
static void static void
reset_unconnected_keys (KEYDB_HANDLE hd, KeyHashTable visited) reset_trust_records (KEYDB_HANDLE hd, KeyHashTable exclude)
{ {
int rc; int rc;
KBNODE keyblock = NULL; KBNODE keyblock = NULL;
@ -1694,8 +1743,11 @@ reset_unconnected_keys (KEYDB_HANDLE hd, KeyHashTable visited)
memset (&desc, 0, sizeof desc); memset (&desc, 0, sizeof desc);
desc.mode = KEYDB_SEARCH_MODE_FIRST; desc.mode = KEYDB_SEARCH_MODE_FIRST;
desc.skipfnc = search_skipfnc; if(exclude)
desc.skipfncvalue = visited; {
desc.skipfnc = search_skipfnc;
desc.skipfncvalue = exclude;
}
rc = keydb_search (hd, &desc, 1); rc = keydb_search (hd, &desc, 1);
if (rc && rc != -1 ) if (rc && rc != -1 )
log_error ("keydb_search_first failed: %s\n", g10_errstr(rc)); log_error ("keydb_search_first failed: %s\n", g10_errstr(rc));
@ -1723,11 +1775,9 @@ reset_unconnected_keys (KEYDB_HANDLE hd, KeyHashTable visited)
log_error ("keydb_search_next failed: %s\n", g10_errstr(rc)); log_error ("keydb_search_next failed: %s\n", g10_errstr(rc));
} }
if (opt.verbose) if (opt.verbose)
log_info ("%d unconnected keys (%d trust records cleared)\n", log_info ("%d keys processed (%d validity counts cleared)\n",
count, nreset); count, nreset);
do_sync (); }
}
/* /*
* Run the key validation procedure. * Run the key validation procedure.
@ -1767,12 +1817,14 @@ validate_keys (int interactive)
int depth; int depth;
int key_count; int key_count;
int ot_unknown, ot_undefined, ot_never, ot_marginal, ot_full, ot_ultimate; int ot_unknown, ot_undefined, ot_never, ot_marginal, ot_full, ot_ultimate;
KeyHashTable visited; KeyHashTable stored,used,full_trust;
u32 start_time, next_expire; u32 start_time, next_expire;
start_time = make_timestamp (); start_time = make_timestamp ();
next_expire = 0xffffffff; /* set next expire to the year 2106 */ next_expire = 0xffffffff; /* set next expire to the year 2106 */
visited = new_key_hash_table (); stored = new_key_hash_table ();
used = new_key_hash_table ();
full_trust = new_key_hash_table ();
/* Fixme: Instead of always building a UTK list, we could just build it /* Fixme: Instead of always building a UTK list, we could just build it
* here when needed */ * here when needed */
if (!utk_list) if (!utk_list)
@ -1781,7 +1833,12 @@ validate_keys (int interactive)
goto leave; goto leave;
} }
/* mark all UTKs as visited and set validity to ultimate */ kdb = keydb_new (0);
reset_trust_records (kdb,NULL);
/* mark all UTKs as used and fully_trusted and set validity to
ultimate */
for (k=utk_list; k; k = k->next) for (k=utk_list; k; k = k->next)
{ {
KBNODE keyblock; KBNODE keyblock;
@ -1794,21 +1851,14 @@ validate_keys (int interactive)
" trusted key %08lX not found\n"), (ulong)k->kid[1]); " trusted key %08lX not found\n"), (ulong)k->kid[1]);
continue; continue;
} }
mark_keyblock_seen (visited, keyblock); mark_keyblock_seen (used, keyblock);
mark_keyblock_seen (stored, keyblock);
mark_keyblock_seen (full_trust, keyblock);
pk = keyblock->pkt->pkt.public_key; pk = keyblock->pkt->pkt.public_key;
for (node=keyblock; node; node = node->next) for (node=keyblock; node; node = node->next)
{ {
if (node->pkt->pkttype == PKT_USER_ID) if (node->pkt->pkttype == PKT_USER_ID)
{ update_validity (pk, node->pkt->pkt.user_id, 0, TRUST_ULTIMATE);
byte namehash[20];
PKT_user_id *uid = node->pkt->pkt.user_id;
if( uid->attrib_data )
rmd160_hash_buffer (namehash,uid->attrib_data,uid->attrib_len);
else
rmd160_hash_buffer (namehash, uid->name, uid->len );
update_validity (pk, namehash, 0, TRUST_ULTIMATE);
}
} }
if ( pk->expiredate && pk->expiredate >= start_time if ( pk->expiredate && pk->expiredate >= start_time
&& pk->expiredate < next_expire) && pk->expiredate < next_expire)
@ -1819,7 +1869,6 @@ validate_keys (int interactive)
} }
klist = utk_list; klist = utk_list;
kdb = keydb_new (0);
log_info(_("%d marginal(s) needed, %d complete(s) needed, %s trust model\n"), log_info(_("%d marginal(s) needed, %d complete(s) needed, %s trust model\n"),
opt.marginals_needed,opt.completes_needed, opt.marginals_needed,opt.completes_needed,
@ -1886,7 +1935,8 @@ validate_keys (int interactive)
} }
/* Find all keys which are signed by a key in kdlist */ /* Find all keys which are signed by a key in kdlist */
keys = validate_key_list (kdb, visited, klist, start_time, &next_expire); keys = validate_key_list (kdb, full_trust, klist,
start_time, &next_expire);
if (!keys) if (!keys)
{ {
log_error ("validate_key_list failed\n"); log_error ("validate_key_list failed\n");
@ -1901,14 +1951,14 @@ validate_keys (int interactive)
if (opt.verbose > 1) if (opt.verbose > 1)
dump_key_array (depth, keys); dump_key_array (depth, keys);
log_info (_("checking at depth %d signed=%d" for (kar=keys; kar->keyblock; kar++)
store_validation_status (depth, kar->keyblock, stored);
log_info (_("checking at depth %d valid=%d"
" ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%d\n"), " ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%d\n"),
depth, key_count, ot_unknown, ot_undefined, depth, key_count, ot_unknown, ot_undefined,
ot_never, ot_marginal, ot_full, ot_ultimate ); ot_never, ot_marginal, ot_full, ot_ultimate );
for (kar=keys; kar->keyblock; kar++)
store_validation_status (depth, kar->keyblock);
/* Build a new kdlist from all fully valid keys in KEYS */ /* Build a new kdlist from all fully valid keys in KEYS */
if (klist != utk_list) if (klist != utk_list)
release_key_items (klist); release_key_items (klist);
@ -1919,39 +1969,52 @@ validate_keys (int interactive)
{ {
if (node->pkt->pkttype == PKT_USER_ID && (node->flag & 4)) if (node->pkt->pkttype == PKT_USER_ID && (node->flag & 4))
{ {
k = new_key_item (); u32 kid[2];
keyid_from_pk (kar->keyblock->pkt->pkt.public_key, k->kid);
k->ownertrust = get_ownertrust (kar->keyblock /* have we used this key already? */
->pkt->pkt.public_key); keyid_from_pk (kar->keyblock->pkt->pkt.public_key, kid);
k->min_ownertrust = get_min_ownertrust (kar->keyblock if(test_key_hash_table(used,kid)==0)
->pkt->pkt.public_key); {
k->trust_depth= /* Normally we add both the primary and subkey
kar->keyblock->pkt->pkt.public_key->trust_depth; ids to the hash via mark_keyblock_seen, but
k->trust_value= since we aren't using this hash as a skipfnc,
kar->keyblock->pkt->pkt.public_key->trust_value; that doesn't matter here. */
if(kar->keyblock->pkt->pkt.public_key->trust_regexp) add_key_hash_table (used,kid);
k->trust_regexp= k = new_key_item ();
m_strdup(kar->keyblock->pkt-> k->kid[0]=kid[0];
pkt.public_key->trust_regexp); k->kid[1]=kid[1];
k->next = klist; k->ownertrust =
klist = k; get_ownertrust (kar->keyblock->pkt->pkt.public_key);
break; k->min_ownertrust =
} get_min_ownertrust(kar->keyblock->pkt->pkt.public_key);
} k->trust_depth=
} kar->keyblock->pkt->pkt.public_key->trust_depth;
k->trust_value=
kar->keyblock->pkt->pkt.public_key->trust_value;
if(kar->keyblock->pkt->pkt.public_key->trust_regexp)
k->trust_regexp=
m_strdup(kar->keyblock->pkt->
pkt.public_key->trust_regexp);
k->next = klist;
klist = k;
break;
}
}
}
}
release_key_array (keys); release_key_array (keys);
keys = NULL; keys = NULL;
if (!klist) if (!klist)
break; /* no need to dive in deeper */ break; /* no need to dive in deeper */
} }
reset_unconnected_keys (kdb, visited);
leave: leave:
keydb_release (kdb); keydb_release (kdb);
release_key_array (keys); release_key_array (keys);
release_key_items (klist); release_key_items (klist);
release_key_hash_table (visited); release_key_hash_table (full_trust);
release_key_hash_table (used);
release_key_hash_table (stored);
if (!rc && !quit) /* mark trustDB as checked */ if (!rc && !quit) /* mark trustDB as checked */
{ {
if (next_expire == 0xffffffff || next_expire < start_time ) if (next_expire == 0xffffffff || next_expire < start_time )