diff --git a/doc/DETAILS b/doc/DETAILS index a02ba3597..420f67df3 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -1304,7 +1304,7 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: - 1 u8 :: =ownertrust=. - 1 u8 :: =depth=. - 1 u8 :: =min_ownertrust=. - - 1 byte :: Not used. + - 1 byte :: =flags=. - 1 u32 :: =validlist=. - 10 byte :: Not used. diff --git a/g10/tdbdump.c b/g10/tdbdump.c index 2c6f5c2fa..a86558b1a 100644 --- a/g10/tdbdump.c +++ b/g10/tdbdump.c @@ -109,7 +109,9 @@ export_ownertrust (ctrl_t ctrl) { if (rec.rectype == RECTYPE_TRUST) { - if (!rec.r.trust.ownertrust) + /* Skip records with no ownertrust set or those with trust + * set via --trusted-key. */ + if (!rec.r.trust.ownertrust || (rec.r.trust.flags & 1)) continue; p = rec.r.trust.fingerprint; for (i=0; i < 20; i++, p++ ) @@ -202,6 +204,7 @@ import_ownertrust (ctrl_t ctrl, const char *fname ) log_info("setting ownertrust to %u\n", otrust ); } rec.r.trust.ownertrust = otrust; + rec.r.trust.flags &= ~(rec.r.trust.flags & 1); write_record (ctrl, &rec); any = 1; } diff --git a/g10/tdbio.c b/g10/tdbio.c index 9bae2ed32..fdb887132 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -1486,16 +1486,19 @@ tdbio_dump_record (TRUSTREC *rec, estream_t fp) es_fprintf (fp, "trust "); for (i=0; i < 20; i++) es_fprintf (fp, "%02X", rec->r.trust.fingerprint[i]); - es_fprintf (fp, ", ot=%d, d=%d, vl=%lu\n", rec->r.trust.ownertrust, - rec->r.trust.depth, rec->r.trust.validlist); + es_fprintf (fp, ", ot=%d, d=%d, vl=%lu, mo=%d, f=%02x\n", + rec->r.trust.ownertrust, + rec->r.trust.depth, rec->r.trust.validlist, + rec->r.trust.min_ownertrust, rec->r.trust.flags); break; case RECTYPE_VALID: es_fprintf (fp, "valid "); for (i=0; i < 20; i++) es_fprintf(fp, "%02X", rec->r.valid.namehash[i]); - es_fprintf (fp, ", v=%d, next=%lu\n", rec->r.valid.validity, - rec->r.valid.next); + es_fprintf (fp, ", v=%d, next=%lu, f=%d, m=%d\n", + rec->r.valid.validity, rec->r.valid.next, + rec->r.valid.full_count, rec->r.valid.marginal_count); break; default: @@ -1631,7 +1634,7 @@ tdbio_read_record (ulong recnum, TRUSTREC *rec, int expected) rec->r.trust.ownertrust = *p++; rec->r.trust.depth = *p++; rec->r.trust.min_ownertrust = *p++; - p++; + rec->r.trust.flags = *p++; rec->r.trust.validlist = buf32_to_ulong(p); break; @@ -1726,7 +1729,7 @@ tdbio_write_record (ctrl_t ctrl, TRUSTREC *rec) *p++ = rec->r.trust.ownertrust; *p++ = rec->r.trust.depth; *p++ = rec->r.trust.min_ownertrust; - p++; + *p++ = rec->r.trust.flags; ulongtobuf( p, rec->r.trust.validlist); p += 4; break; diff --git a/g10/tdbio.h b/g10/tdbio.h index 267a37970..9452d76c9 100644 --- a/g10/tdbio.h +++ b/g10/tdbio.h @@ -79,6 +79,7 @@ struct trust_record { byte depth; ulong validlist; byte min_ownertrust; + byte flags; } trust; struct { byte namehash[20]; diff --git a/g10/trust.c b/g10/trust.c index bd1c89458..f7763bd0c 100644 --- a/g10/trust.c +++ b/g10/trust.c @@ -278,7 +278,7 @@ update_ownertrust (ctrl_t ctrl, PKT_public_key *pk, unsigned int new_trust) (void)pk; (void)new_trust; #else - tdb_update_ownertrust (ctrl, pk, new_trust); + tdb_update_ownertrust (ctrl, pk, new_trust, 0); #endif } diff --git a/g10/trustdb.c b/g10/trustdb.c index 116cbe604..3094bdcfc 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -39,6 +39,9 @@ #include "tofu.h" #include "key-clean.h" +static void write_record (ctrl_t ctrl, TRUSTREC *rec); +static void do_sync(void); + typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */ @@ -263,10 +266,11 @@ verify_own_keys (ctrl_t ctrl) TRUSTREC rec; ulong recnum; int rc; - struct key_item *k; + struct key_item *k, *k2; + int need_revalidation = 0; if (utk_list) - return; + return; /* Has already been run. */ /* scan the trustdb to find all ultimately trusted keys */ for (recnum=1; !tdbio_read_record (recnum, &rec, 0); recnum++ ) @@ -274,24 +278,47 @@ verify_own_keys (ctrl_t ctrl) if ( rec.rectype == RECTYPE_TRUST && (rec.r.trust.ownertrust & TRUST_MASK) == TRUST_ULTIMATE) { - byte *fpr = rec.r.trust.fingerprint; - int fprlen; - u32 kid[2]; + byte *fpr = rec.r.trust.fingerprint; + int fprlen; + u32 kid[2]; - /* Problem: We do only use fingerprints in the trustdb but - * we need the keyID here to indetify the key; we can only - * use that ugly hack to distinguish between 16 and 20 - * butes fpr - it does not work always so we better change - * the whole validation code to only work with - * fingerprints */ - fprlen = (!fpr[16] && !fpr[17] && !fpr[18] && !fpr[19])? 16:20; - keyid_from_fingerprint (ctrl, fpr, fprlen, kid); - if (!add_utk (kid)) - log_info(_("key %s occurs more than once in the trustdb\n"), - keystr(kid)); + /* Problem: We do only use fingerprints in the trustdb but + * we need the keyID here to indetify the key; we can only + * use that ugly hack to distinguish between 16 and 20 bytes + * fpr - it does not work always so we better change the + * whole validation code to only work with fingerprints */ + fprlen = (!fpr[16] && !fpr[17] && !fpr[18] && !fpr[19])? 16:20; + keyid_from_fingerprint (ctrl, fpr, fprlen, kid); + if (!add_utk (kid)) + log_info(_("key %s occurs more than once in the trustdb\n"), + keystr(kid)); + else if ((rec.r.trust.flags & 1)) + { + /* Record marked as inserted via --trusted-key. Is this + * still the case? */ + for (k2 = user_utk_list; k2; k2 = k2->next) + if (k2->kid[0] == kid[0] && k2->kid[1] == kid[1]) + break; + if (!k2) /* No - clear the flag. */ + { + if (DBG_TRUST) + log_debug ("clearing former --trusted-key %s\n", + keystr (kid)); + rec.r.trust.ownertrust = TRUST_UNKNOWN; + rec.r.trust.flags &= ~(rec.r.trust.flags & 1); + write_record (ctrl, &rec); + need_revalidation = 1; + } + } } } + if (need_revalidation) + { + tdb_revalidation_mark (ctrl); + do_sync (); + } + /* Put any --trusted-key keys into the trustdb */ for (k = user_utk_list; k; k = k->next) { @@ -308,7 +335,7 @@ verify_own_keys (ctrl_t ctrl) { tdb_update_ownertrust (ctrl, &pk, ((tdb_get_ownertrust (ctrl, &pk, 0) & ~TRUST_MASK) - | TRUST_ULTIMATE )); + | TRUST_ULTIMATE ), 1); release_public_key_parts (&pk); } @@ -749,7 +776,8 @@ tdb_get_min_ownertrust (ctrl_t ctrl, PKT_public_key *pk, int no_create) * The key should be a primary one. */ void -tdb_update_ownertrust (ctrl_t ctrl, PKT_public_key *pk, unsigned int new_trust ) +tdb_update_ownertrust (ctrl_t ctrl, PKT_public_key *pk, unsigned int new_trust, + int as_trusted_key) { TRUSTREC rec; gpg_error_t err; @@ -761,11 +789,24 @@ tdb_update_ownertrust (ctrl_t ctrl, PKT_public_key *pk, unsigned int new_trust ) if (!err) { if (DBG_TRUST) - log_debug ("update ownertrust from %u to %u\n", - (unsigned int)rec.r.trust.ownertrust, new_trust ); + log_debug ("update ownertrust from %u to %u%s\n", + (unsigned int)rec.r.trust.ownertrust, new_trust, + as_trusted_key? " via --trusted-key":""); if (rec.r.trust.ownertrust != new_trust) { rec.r.trust.ownertrust = new_trust; + /* Clear or set the trusted key flag if the new value is + * ultimate. This is required so that we know which keys + * have been added by --trusted-keys. */ + if ((rec.r.trust.ownertrust & TRUST_MASK) == TRUST_ULTIMATE) + { + if (as_trusted_key) + rec.r.trust.flags |= 1; + else + rec.r.trust.flags &= ~(rec.r.trust.flags & 1); + } + else + rec.r.trust.flags &= ~(rec.r.trust.flags & 1); write_record (ctrl, &rec); tdb_revalidation_mark (ctrl); do_sync (); @@ -776,13 +817,17 @@ tdb_update_ownertrust (ctrl_t ctrl, PKT_public_key *pk, unsigned int new_trust ) size_t dummy; if (DBG_TRUST) - log_debug ("insert ownertrust %u\n", new_trust ); + log_debug ("insert ownertrust %u%s\n", new_trust, + as_trusted_key? " via --trusted-key":""); memset (&rec, 0, sizeof rec); rec.recnum = tdbio_new_recnum (ctrl); rec.rectype = RECTYPE_TRUST; fingerprint_from_pk (pk, rec.r.trust.fingerprint, &dummy); rec.r.trust.ownertrust = new_trust; + if ((rec.r.trust.ownertrust & TRUST_MASK) == TRUST_ULTIMATE + && as_trusted_key) + rec.r.trust.flags = 1; write_record (ctrl, &rec); tdb_revalidation_mark (ctrl); do_sync (); @@ -1403,7 +1448,7 @@ ask_ownertrust (ctrl_t ctrl, u32 *kid, int minimum) { log_info("force trust for key %s to %s\n", keystr(kid),trust_value_to_string(opt.force_ownertrust)); - tdb_update_ownertrust (ctrl, pk, opt.force_ownertrust); + tdb_update_ownertrust (ctrl, pk, opt.force_ownertrust, 0); ot=opt.force_ownertrust; } else diff --git a/g10/trustdb.h b/g10/trustdb.h index d52fc53f2..758cfe3eb 100644 --- a/g10/trustdb.h +++ b/g10/trustdb.h @@ -121,7 +121,7 @@ const char *get_ownertrust_string (ctrl_t ctrl, PKT_public_key *pk, int no_create); void tdb_update_ownertrust (ctrl_t ctrl, PKT_public_key *pk, - unsigned int new_trust); + unsigned int new_trust, int as_trusted_key); int tdb_clear_ownertrusts (ctrl_t ctrl, PKT_public_key *pk); /*-- tdbdump.c --*/