A Rust library for authenticating bindings between User IDs and certificates using OpenPGP's web of trust. This library is designed around OpenPGP's data structures, but it does not require OpenPGP data. Instead, it is possible to manually describe a web of trust.
This crate also includes a CLI tool, sq-wot
, for authenticating
bindings and exploring a web of trust.
The [web of trust] is a decentralized trust model popularized by PGP. It is [a superset] of [X.509], which is a hierarchical trust model, and is the most popular trust model on the public internet today. As used on the public internet, however, it relies on a handful of global [certification authorities] (CAs) who often [undermine its security].
The web of trust is more nuanced than X.509. A user can partially trust a CA thereby preventing a single bad actor from compromising their security. And those who have stronger security requirements can use the web of trust in a completely decentralized manner.
Today, the tooling around the web of trust is primitive at best. Many people interpret this lack of good tooling as a sign that the web of trust is intrinsically difficult to use. We disagree and think that efforts like our [OpenPGP CA] provide evidence that this is not the case.
See the [spec] for an in-depth discussion of semantics and implementation.
To use sequoia-wot
from your crate add the following your crate's
Cargo.toml
:
toml
[dependencies]
sequoia-wot = "0.3"
sequoia-openpgp = "1"
This will use sequoia-openpgp
's default cryptographic backend, which
is currently Nettle.
To select a different cryptographic backend, such as OpenSSL, you would then compile your crate as follows:
shell
$ cargo build --release --features sequoia-openpgp/crypto-openssl
See [sequoia-openpgp
's README] for more details, include the
different backends' [build requirements].
sq-wot
is a CLI to the library. It implements four different
subcommands.
authenticate
a bindingA binding is a User ID and certificate pair. sq-wot authenticate
authenticates a binding. It looks like this:
```text $ sq-wot --gpg authenticate 'Justus Winter justus@sequoia-pgp.org' 'CBCD 8F03 0588 653E EDD7 E265 9B7D D433 F254 904A' [✓] CBCD8F030588653EEDD7E2659B7DD433F254904A Justus Winter justus@sequoia-pgp.org: fully authenticated (133%) Path #1 of 2, trust amount 40: ◯ CBCD8F030588653EEDD7E2659B7DD433F254904A "Justus Winter justus@sequoia-pgp.org"
Path #2 of 2, trust amount 120: ◯ F7173B3C7C685CD9ECC4191B74E445BA0E15C957 ("Neal H. Walfield (Code Signing Key) neal@pep.foundation") │ certified the following binding on 2022-02-04 └ CBCD8F030588653EEDD7E2659B7DD433F254904A "Justus Winter justus@sequoia-pgp.org" ```
sq-wot
prints out the paths from the trust roots to the specified
binding. Here, I also marked the certificate that I'm trying to
authenticate as a partially trusted trusted root in gpg
. As such,
there are two paths. The first path is because the certificate is a
root and has a self signature with the specified User ID; the second
path is because I certified that binding.
The --gpg
option tells sq-wot
to read my trust roots from gpg
and to read gpg
's keyring. Trust roots can also be specified
explicitly using the --trust-root
or -r
option. Likewise,
keyrings can be specified using --keyring
or -k
. For instance, I
can confirm that Clint Adams certified dkg's certificate for the User
ID <dkg@debian.org>
:
$ sq-wot -r 0xF6D3495BB0AE9A02 -k /usr/share/keyrings/debian-keyring.gpg authenticate "<dkg@debian.org>" C29F8A0C01F35E34D816AA5CE092EB3A5CA10DBA
[✓] C29F8A0C01F35E34D816AA5CE092EB3A5CA10DBA <dkg@debian.org>: fully authenticated (100%)
◯ 2100A32C46F895AF3A08783AF6D3495BB0AE9A02 ("Clint Adams (GNU) <clint@gnu.org>")
│ certified the following binding on 2021-01-01 (expiry: 2023-12-24)
└ C29F8A0C01F35E34D816AA5CE092EB3A5CA10DBA "<dkg@debian.org>"
Note that I used the whole User ID, not just the email address. It is
also possible to add the --email
flag. Then sq-wot
will look for
User ID's that contain the email address. For instance:
$ sq-wot --gpg authenticate --email justus@sequoia-pgp.org 'CBCD 8F03 0588 653E EDD7 E265 9B7D D433 F254 904A'
...
lookup
by email addressThe lookup
subcommand finds certificates that are authenticated for
the specified User ID. As before, I can use the --email
option:
``` $ sq-wot --gpg lookup --email justus@sequoia-pgp.org [✓] CBCD8F030588653EEDD7E2659B7DD433F254904A Justus Winter justus@sequoia-pgp.org: fully authenticated (133%) Path #1 of 2, trust amount 40: ◯ CBCD8F030588653EEDD7E2659B7DD433F254904A "Justus Winter justus@sequoia-pgp.org"
Path #2 of 2, trust amount 120: ◯ F7173B3C7C685CD9ECC4191B74E445BA0E15C957 ("Neal H. Walfield (Code Signing Key) neal@pep.foundation") │ certified the following binding on 2022-02-04 └ CBCD8F030588653EEDD7E2659B7DD433F254904A "Justus Winter justus@sequoia-pgp.org" ```
identify
by certificateThe identify
subcommand finds all bindings that can be authenticated
for a given certificate:
``` $ sq-wot --gpg identify 'CBCD 8F03 0588 653E EDD7 E265 9B7D D433 F254 904A' [✓] CBCD8F030588653EEDD7E2659B7DD433F254904A Justus Winter justus@pep.foundation: fully authenticated (133%) Path #1 of 2, trust amount 40: ◯ CBCD8F030588653EEDD7E2659B7DD433F254904A "Justus Winter justus@pep.foundation"
Path #2 of 2, trust amount 120: ◯ F7173B3C7C685CD9ECC4191B74E445BA0E15C957 ("Neal H. Walfield (Code Signing Key) neal@pep.foundation") │ certified the following binding on 2022-02-04 └ CBCD8F030588653EEDD7E2659B7DD433F254904A "Justus Winter justus@pep.foundation"
[✓] CBCD8F030588653EEDD7E2659B7DD433F254904A Justus Winter justus@sequoia-pgp.org: fully authenticated (133%) Path #1 of 2, trust amount 40: ◯ CBCD8F030588653EEDD7E2659B7DD433F254904A "Justus Winter justus@sequoia-pgp.org"
Path #2 of 2, trust amount 120: ◯ F7173B3C7C685CD9ECC4191B74E445BA0E15C957 ("Neal H. Walfield (Code Signing Key) neal@pep.foundation") │ certified the following binding on 2022-02-04 └ CBCD8F030588653EEDD7E2659B7DD433F254904A "Justus Winter justus@sequoia-pgp.org" ... ```
list
all authenticated bindingsThe list
subcommands finds all bindings that can be authenticated
for all certificates:
``` $ sq-wot --gpg list [✓] 8F17777118A33DDA9BA48E62AACB3243630052D9 Neal H. Walfield neal@pep.foundation: fully authenticated (100%) ◯ 8F17777118A33DDA9BA48E62AACB3243630052D9 "Neal H. Walfield neal@pep.foundation"
[✓] 8F17777118A33DDA9BA48E62AACB3243630052D9 Neal H. Walfield neal@sequoia-pgp.org: fully authenticated (100%) ◯ 8F17777118A33DDA9BA48E62AACB3243630052D9 "Neal H. Walfield neal@sequoia-pgp.org" ... [✓] CBCD8F030588653EEDD7E2659B7DD433F254904A Justus Winter justus@sequoia-pgp.org: fully authenticated (133%) Path #1 of 2, trust amount 40: ◯ CBCD8F030588653EEDD7E2659B7DD433F254904A "Justus Winter justus@sequoia-pgp.org"
Path #2 of 2, trust amount 120: ◯ F7173B3C7C685CD9ECC4191B74E445BA0E15C957 ("Neal H. Walfield (Code Signing Key) neal@pep.foundation") │ certified the following binding on 2022-02-04 └ CBCD8F030588653EEDD7E2659B7DD433F254904A "Justus Winter justus@sequoia-pgp.org" ... ```
sequoia-wot is distributed under the terms of LGPL 2.0 or later.
See LICENSE.txt and CONTRIBUTING.md for details.