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:34:06 +01:00
parent b0079ab39d
commit 99ef78aa0c
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
7 changed files with 73 additions and 18 deletions

View File

@ -1408,7 +1408,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++ )
@ -204,6 +206,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

@ -267,7 +267,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,11 @@
#include "tofu.h"
#include "key-clean.h"
static void write_record (ctrl_t ctrl, TRUSTREC *rec);
static void do_sync(void);
static u32
keyid_from_fpr20 (ctrl_t ctrl, const byte *fpr, u32 *keyid)
{
@ -312,10 +317,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++ )
@ -329,9 +335,33 @@ verify_own_keys (ctrl_t ctrl)
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)
{
@ -348,7 +378,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);
}
@ -789,7 +819,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;
@ -801,11 +832,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 ();
@ -814,13 +858,17 @@ tdb_update_ownertrust (ctrl_t ctrl, PKT_public_key *pk, unsigned int new_trust )
else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
{ /* no record yet - create a new one */
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;
fpr20_from_pk (pk, rec.r.trust.fingerprint);
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 ();
@ -1438,7 +1486,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

@ -119,7 +119,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 --*/