# Sequoia Web of Trust

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.

## Introduction

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].

  [web of trust]: https://en.wikipedia.org/wiki/Web_of_trust
  [a superset]: https://www.oreilly.com/library/view/beautiful-security/9780596801786/ch07.html
  [X.509]: https://de.wikipedia.org/wiki/X.509
  [certification authorities]: https://en.wikipedia.org/wiki/Certificate_authority
  [undermine its security]: https://sslmate.com/resources/certificate_authority_failures

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.

  [OpenPGP CA]: https://openpgp-ca.org/

See the [spec] for an in-depth discussion of semantics and
implementation.

  [spec]: https://sequoia-pgp.gitlab.io/sequoia-wot

## Usage

Add this to your `Cargo.toml`:

```toml
[dependencies]
sequoia-wot = "0.2"
```

## sq-wot

`sq-wot` is a CLI to the library.  It implements four different
subcommands.

### `authenticate` a binding

A 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 address

The `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 certificate

The `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 bindings

The `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>"
...
```

# License

sequoia-wot is distributed under the terms of LGPL 2.0 or later.

See [LICENSE.txt](LICENSE.txt) and [CONTRIBUTING.md](CONTRIBUTING.md)
for details.
