gpg: Remove stale ultimately trusted keys from the trustdb.

* g10/tdbdump.c (export_ownertrust): Skip records marked with the
option --trusted-key.
(import_ownertrust): Clear the trusted-key flag.
* g10/tdbio.h (struct trust_record): Add field flags.
* g10/tdbio.c (tdbio_dump_record): Improve output.
(tdbio_read_record, tdbio_write_record): Handle flags.
* g10/trustdb.c (verify_own_keys): Clear stale trusted-keys and set
the flag for new --trusted-keys.
(tdb_update_ownertrust): Add arg as_trusted_key.  Update callers.
--

GnuPG-bug-id: 5685
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2021-11-13 20:59:17 +01:00
parent 8fe3f57643
commit bc6d56282e
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
7 changed files with 84 additions and 32 deletions

View File

@ -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.

View File

@ -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;
}

View File

@ -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;

View File

@ -79,6 +79,7 @@ struct trust_record {
byte depth;
ulong validlist;
byte min_ownertrust;
byte flags;
} trust;
struct {
byte namehash[20];

View File

@ -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
}

View File

@ -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

View File

@ -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 --*/