TOFU for GnuPG

Neal H. Walfield neal at walfield.org
Thu Oct 29 15:06:51 CET 2015


Hi,

Last week, I checked in the TOFU code for GnuPG.  This code will be
part of the next release.  It would be great to get some additional
testing before this happens!


Background
----------

TOFU stands for Trust on First Use and is a concept that will be
familiar to anyone who regularly uses ssh.  When you ssh to a host for
the first time, ssh asks you to verify the host's key (most people
just say yes here).  When connecting to the same host in the future,
ssh checks that the key hasn't changed.  If it has, ssh displays a
warning.

TOFU for GnuPG works similarly.  When you verify a message from some
user for the first time, GnuPG saves the binding between the user id
(actually, the normalized email address) and the key.  When you verify
another message from that user, the saved bindings with that user's
address are retrieved.  If there is at least one such binding, but
none of them include the signer's key, then either the signer is using
a new key or someone is attacking you.  In this case, GnuPG displays a
warning and prompts you to verify the key and set an appropriate
policy (e.g., the key should be considered untrusted).

In contrast to the Web of Trust (WoT), TOFU's security guarantees are
rather weak.  When using the WoT correctly, you can have high
confidence that if GnuPG says a given key is controlled by a specific
user, then it probably is.  TOFU, on the other hand, is only able to
detect when the key associated with an email address has changed.  In
other words, TOFU detects inconsistencies.

Despite this, TOFU will be more secure than the WoT for most users in
practice.  This is because using the WoT requires a lot of effort.
First, you have to actively exchange fingerprints with other users and
sign their keys.  Most people can't be bothered to take the time to do
this.  Second, in order to actually use the WoT to verify keys that
you have not directly signed, you need to tell GnuPG how much you
trust other people to correctly verify keys the keys that they sign
(i.e., you need to set the owner trust).  In practice, even fewer
people do this.  But, even if you do do this, you can only confidently
set the owner trust for people that you've actually met.  Thus, the
WoT can only really be used to verify the keys of friends of friends.
This seriously limits the number of people you can securely
communicate with.

Happily you don't need to choose between TOFU and the WoT.  It is
possible to combine them using the tofu+pgp trust model.  In this
model, the trust level for a key under each model is computed and then
the maximum is taken according to the following ordering:

  unknown < undefined < marginal < fully < ultimate < expired < never

For users who want TOFU's ability to detect conflicts, but don't like
that TOFU assigns positive (marginal) trust to new keys without
prompting, it is possible to change the default policy to unknown or
to always prompt the user for the policy for new keys using the
--tofu-default-policy option.  When setting the default policy to
unknown, the WoT will be used for all trust judgments unless TOFU
detects a conflict.


How-to
------

In general, there is no reason to use the bare tofu model.  Instead,
tofu+pgp is the recommended model.  If you've never signed a key, then
this effectively degrades back to the tofu model.

To set the trust model to tofu+pgp, add the following to your
~/.gnupg/gpg.conf file:

  trust-model tofu+pgp

If you don't want TOFU to assign positive trust to new keys by
default, then you should also add the following to your gpg.conf file:

  tofu-default-policy unknown

These and a few other new options are described in detail in the
manual (search for tofu).


There isn't much more to do.

Verifying a message works as usual:

  $ gpg2 --verify EE37CF96-6.txt 
  gpg: Signature made Fri 18 Sep 2015 03:16:17 PM CEST using RSA key ID EE37CF96
  gpg: Good signature from "Testing (insecure!)" [unknown]
  gpg: Verified 5 messages signed by "Testing (insecure!)" (key: 362D 3527 F53A AD19 71AA  FDE6 5885 9975 EE37 CF96, policy: auto) in the past 42 minutes, 59 seconds.
  gpg: Warning: if you think you've seen more than 5 message signed by this key, then this key might be a forgery!  Carefully examine the email address for small variations (e.g., additional white space).  If the key is suspect, then use 'gpg --tofu-policy bad "362D 3527 F53A AD19 71AA  FDE6 5885 9975 EE37 CF96"' to mark it as being bad.

Here, the only change are a few additional messages.  First, some
statistics are displayed, namely, that we've verified 5 messages
signed by this key in the past last hour.  Further, a warning is
printed that the number of messages that we've verified is rather
small and we should be suspicious of this binding.  This information
is displayed to make it easier to recognize forged keys.

Unlike with ssh where the user types the name of the host to connect
to, an attacker is able to control the content of the user id field.
To work around the protections that TOFU offers, an attacker will use
a similarly looking, but different email address.  It's impossible to
reliably detect these forgeries.  Instead, we rely on the email client
to compare the sender with the signer and display a warning if these
don't match.  Further, we provide these statistics so that users will
become suspicious if suddenly GnuPG claims that it has only seen a
single message from a person with whom they are in regular contact.

Here we see what happens when GnuPG verifies a message and there is a
conflict:

  $ gpg2 --verify BC15C85A-1.txt 
  gpg: Signature made Fri 18 Sep 2015 02:06:17 PM CEST using RSA key ID BC15C85A
  gpg: Good signature from "Testing (insecure!)" [unknown]
  Please indicate whether you believe the binding <439D 954F 18F7 9CC4 F71B  ED91 CACE D996 BC15 C85A, testing (insecure!)> is legitimate (the key belongs to the stated owner) or a forgery (bad).
  
  Known user ids associated with this key:
    Testing (insecure!) (policy: ask)
  
  Statistics for keys with the email 'testing (insecure!)':
    439D 954F 18F7 9CC4 F71B  ED91 CACE D996 BC15 C85A (this key):
      0 signed messages.
    362D 3527 F53A AD19 71AA  FDE6 5885 9975 EE37 CF96 (policy: ask):
      6 messages signed over the past 1 month.
  
  Normally, there is only a single key associated with an email address.  However, people sometimes generate a new key if their key is too old or they think it might be compromised.  Alternatively, a new key may indicate a man-in-the-middleattack!  Before accepting this key, you should talk to or call the person to make sure this new key is legitimate.
  
  (G)ood/(A)ccept once/(U)nknown/(R)eject once/(B)ad? g
  gpg: Verified 0 messages signed by "Testing (insecure!)" (key: 439D 954F 18F7 9CC4 F71B  ED91 CACE D996 BC15 C85A, policy good).

In this case, I've marked the key as being good.


I'd appreciate any feedback regarding this new feature (both positive
and negative!).  In particular, I'm interested in learning how well
this fits into your work flow and whether or not you'll use it.

Note: GpgME has not yet been extended to support TOFU so these
messages might not be shown.


Thanks!

:) Neal



More information about the Gnupg-users mailing list