gpg: Fix mixed invocation with --trusted-keys and --no-options.

* g10/trustdb.c: Move a function and some definitions around.
(user_utk_list): Rename to trusted_key_list.  Change all users.
(any_trusted_key_seen): New.
(tdb_register_trusted_key): Set it here.  Handle the new value "none".
(verify_own_keys): Do not delete a trusted key from the trustdb if a
trusted-key option was not used.
--

GnuPG-bug-id: 7025
This commit is contained in:
Werner Koch 2024-03-04 14:56:16 +01:00
parent 36a3550bff
commit 345794cfe6
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
2 changed files with 69 additions and 45 deletions

View File

@ -1776,7 +1776,9 @@ useful if you don't want to keep your secret keys (or one of them)
online but still want to be able to check the validity of a given
recipient's or signator's key. If the given key is not locally
available but an LDAP keyserver is configured the missing key is
imported from that server.
imported from that server. The value "none" is explicitly allowed to
distinguish between the use of any trusted-key option and no use of
this option at all (e.g. due to the @option{--no-options} option).
@item --add-desig-revoker [sensitive:]@var{fingerprint}
@opindex add-desig-revoker

View File

@ -39,8 +39,52 @@
#include "tofu.h"
#include "key-clean.h"
typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */
/*
* Structure to keep track of keys, this is used as an array where the
* item right after the last one has a keyblock set to NULL. Maybe we
* can drop this thing and replace it by key_item
*/
struct key_array
{
KBNODE keyblock;
};
/* Control information for the trust DB. */
static struct
{
int init;
int level;
char *dbname;
int no_trustdb;
} trustdb_args;
/* Some globals. */
static struct key_item *utk_list; /* all ultimately trusted keys */
/* A list used to temporary store trusted keys and a flag indicated
* whether any --trusted-key option has been seen. */
static struct key_item *trusted_key_list;
static int any_trusted_key_seen;
/* Flag whether a trustdb chekc is pending. */
static int pending_check_trustdb;
static void write_record (ctrl_t ctrl, TRUSTREC *rec);
static void do_sync(void);
static void do_sync (void);
static int validate_keys (ctrl_t ctrl, int interactive);
/**********************************************
************* some helpers *******************
**********************************************/
@ -54,7 +98,7 @@ keyid_from_fpr20 (ctrl_t ctrl, const byte *fpr, u32 *keyid)
keyid = dummy_keyid;
/* Problem: We do only use fingerprints in the trustdb but
* we need the keyID here to indetify the key; we can only
* we need the keyID here to identify 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
@ -88,40 +132,6 @@ keyid_from_fpr20 (ctrl_t ctrl, const byte *fpr, u32 *keyid)
return keyid[1];
}
typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */
/*
* Structure to keep track of keys, this is used as an array wherre
* the item right after the last one has a keyblock set to NULL.
* Maybe we can drop this thing and replace it by key_item
*/
struct key_array
{
KBNODE keyblock;
};
/* Control information for the trust DB. */
static struct
{
int init;
int level;
char *dbname;
int no_trustdb;
} trustdb_args;
/* Some globals. */
static struct key_item *user_utk_list; /* temp. used to store --trusted-keys */
static struct key_item *utk_list; /* all ultimately trusted keys */
static int pending_check_trustdb;
static int validate_keys (ctrl_t ctrl, int interactive);
/**********************************************
************* some helpers *******************
**********************************************/
static struct key_item *
new_key_item (void)
@ -245,11 +255,19 @@ tdb_register_trusted_keyid (u32 *keyid)
k = new_key_item ();
k->kid[0] = keyid[0];
k->kid[1] = keyid[1];
k->next = user_utk_list;
user_utk_list = k;
k->next = trusted_key_list;
trusted_key_list = k;
}
/* This is called for the option --trusted-key to register these keys
* for later syncing them into the trustdb. The special value "none"
* may be used to indicate that there is a trusted-key option but no
* key shall be inserted for it. This "none" value is helpful to
* distinguish between changing the gpg.conf from a trusted-key to no
* trusted-key options at all. Simply not specify the option would
* not allow to distinguish this case from the --no-options case as
* used for certain calls of gpg for example by gpg-wks-client. */
void
tdb_register_trusted_key (const char *string)
{
@ -257,6 +275,9 @@ tdb_register_trusted_key (const char *string)
KEYDB_SEARCH_DESC desc;
u32 kid[2];
any_trusted_key_seen = 1;
if (!strcmp (string, "none"))
return;
err = classify_user_id (string, &desc, 1);
if (!err)
{
@ -378,11 +399,12 @@ 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))
else if ((rec.r.trust.flags & 1)
&& any_trusted_key_seen)
{
/* Record marked as inserted via --trusted-key. Is this
* still the case? */
for (k2 = user_utk_list; k2; k2 = k2->next)
for (k2 = trusted_key_list; k2; k2 = k2->next)
if (k2->kid[0] == kid[0] && k2->kid[1] == kid[1])
break;
if (!k2) /* No - clear the flag. */
@ -406,7 +428,7 @@ verify_own_keys (ctrl_t ctrl)
}
/* Put any --trusted-key keys into the trustdb */
for (k = user_utk_list; k; k = k->next)
for (k = trusted_key_list; k; k = k->next)
{
if ( add_utk (k->kid) )
{ /* not yet in trustDB as ultimately trusted */
@ -431,9 +453,9 @@ verify_own_keys (ctrl_t ctrl)
}
}
/* release the helper table table */
release_key_items (user_utk_list);
user_utk_list = NULL;
/* Release the helper table. */
release_key_items (trusted_key_list);
trusted_key_list = NULL;
return;
}