diff options
Diffstat (limited to '')
-rw-r--r-- | g10/tofu.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/g10/tofu.c b/g10/tofu.c index 7cf3fc7f4..da11d40a0 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -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); |