g10: Default to the "good" TOFU policy for keys signed by a UTK.

* g10/tofu.c (signed_by_utk): New function.
(get_trust): If a key is signed by an ultimately trusted key, then
set any bindings to good.

--
Signed-off-by: Neal H. Walfield <neal@g10code.com>
This commit is contained in:
Neal H. Walfield 2016-09-14 15:17:27 +02:00
parent f4e11f2e9e
commit 8df8aa13c7
1 changed files with 97 additions and 0 deletions

View File

@ -1285,6 +1285,48 @@ cross_sigs (kbnode_t a, kbnode_t b)
return 1;
}
/* Return whether the key was signed by an ultimately trusted key. */
static int
signed_by_utk (kbnode_t a)
{
kbnode_t n;
for (n = a; n; n = n->next)
{
PKT_signature *sig;
if (n->pkt->pkttype != PKT_SIGNATURE)
continue;
sig = n->pkt->pkt.signature;
if (! (sig->sig_class == 0x10
|| sig->sig_class == 0x11
|| sig->sig_class == 0x12
|| sig->sig_class == 0x13))
/* Not a signature over a user id. */
continue;
/* SIG is on SIGNEE's keyblock. If SIG was generated by the
signer, then it's a match. */
if (tdb_keyid_is_utk (sig->keyid))
{
/* Match! */
if (DBG_TRUST)
log_debug ("TOFU: %s is signed by an ultimately trusted key.\n",
pk_keyid_str (a->pkt->pkt.public_key));
return 1;
}
}
if (DBG_TRUST)
log_debug ("TOFU: %s is NOT signed by an ultimately trusted key.\n",
pk_keyid_str (a->pkt->pkt.public_key));
return 0;
}
enum
{
@ -2121,6 +2163,61 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk,
* In summary: POLICY is ask or none.
*/
/* Before continuing, see if the key is signed by an ultimately
trusted key. */
{
int fingerprint_raw_len = strlen (fingerprint) / 2;
char fingerprint_raw[fingerprint_raw_len];
int len = 0;
int is_signed_by_utk = 0;
if (fingerprint_raw_len != 20
|| ((len = hex2bin (fingerprint,
fingerprint_raw, fingerprint_raw_len))
!= strlen (fingerprint)))
{
if (DBG_TRUST)
log_debug ("TOFU: Bad fingerprint: %s (len: %zd, parsed: %d)\n",
fingerprint, strlen (fingerprint), len);
}
else
{
int lookup_err;
kbnode_t kb;
lookup_err = get_pubkey_byfprint (NULL, &kb,
fingerprint_raw,
fingerprint_raw_len);
if (lookup_err)
{
if (DBG_TRUST)
log_debug ("TOFU: Looking up %s: %s\n",
fingerprint, gpg_strerror (lookup_err));
}
else
{
is_signed_by_utk = signed_by_utk (kb);
release_kbnode (kb);
}
}
if (is_signed_by_utk)
{
if (record_binding (dbs, fingerprint, email, user_id,
TOFU_POLICY_GOOD, 0, now) != 0)
{
log_error (_("error setting TOFU binding's trust level"
" to %s\n"), "good");
trust_level = _tofu_GET_TRUST_ERROR;
}
else
trust_level = TRUST_FULLY;
goto out;
}
}
/* Look for conflicts. This is needed in all 3 cases. */
conflict_set = build_conflict_set (dbs, fingerprint, email);
conflict_set_count = strlist_length (conflict_set);