I'm pleased to announce the release of version 0.4.0 and 0.4.1 of the sequoia-wot crate, our web of trust engine. After releasing 0.4.0, we identified an issue that prevented building 0.4.0 in a reproducible manner. I fixed that, and then immediately released 0.4.1.
sequoia-wot 0.4.0 and 0.4.1 have been published on crates.io:
You can also fetch 0.4.1 using the v0.4.1 tag:
which I signed:
$ git verify-tag v0.4.1 gpg: Signature made Wed Jan 25 16:02:18 2023 GMT gpg: using RSA key C03FA6411B03AE12576461187223B56678E02528 gpg: Good signature from "Neal H. Walfield firstname.lastname@example.org" gpg: "Neal H. Walfield email@example.com" gpg: "Neal H. Walfield firstname.lastname@example.org" gpg: "Neal H. Walfield email@example.com" gpg: "Neal H. Walfield firstname.lastname@example.org" gpg: "Neal H. Walfield email@example.com"
This release includes a lot of new functionality.
- sequoia-wot now supports certification networks.
By default sequoia-wot works on authentication networks. An authentication network draws a distinction between two types of certifications: ones that confirm an identity should be associated with a certificate ("Alice says that this is Bob's certificate"), and ones that delegate the ability to assert identities ("Alice says that she trusts Bob when he says this is Carol's certificate").
In a certification network, all certifications delegate the ability to assert identities. This is the type of network that PGP path finding tools use, like:
And the graph-paths.py tool from the Linux kernel community's wotmate:
sq-wot exposes this functionality via the `--certification-network` option.
As an example of where this is useful, let's say Sam Hartman, a previous Debian project leader, wants to authenticate a certificate for Jonathan Carter, the current Debian project leader. Unfortunately, Sam can't directly authenticate Jonathan's certificate:
``` $ sq-wot --keyring /usr/share/keyrings/debian-keyring.gpg -r 332D4CE3A2FAE5439B7E25B2283681BA6FE7F41D authenticate C7203C0A920670BF94F00BB1B01D1A72AC8DC9A1 'Jonathan Carter firstname.lastname@example.org' No paths found. ```
Using a certification network, however, he can see that he certified Steve McIntyre's certificate, who in turn certified a different User ID on Jonathan's certificate:
``` $ sq-wot --certification-network --keyring /usr/share/keyrings/debian-keyring.gpg -r 332D4CE3A2FAE5439B7E25B2283681BA6FE7F41D authenticate C7203C0A920670BF94F00BB1B01D1A72AC8DC9A1 'Jonathan Carter email@example.com' [ ] C7203C0A920670BF94F00BB1B01D1A72AC8DC9A1 Jonathan Carter firstname.lastname@example.org: doubly authenticated (800%) Path #1 of 8, trust amount 120: ◯ 332D4CE3A2FAE5439B7E25B2283681BA6FE7F41D ("Sam Hartman email@example.com") │ certified the following certificate on 2019-06-28 ├ CEBB52301D617E910390FE16587979573442684E ("Steve McIntyre firstname.lastname@example.org") │ certified the following certificate on 2015-08-22 ├ C7203C0A920670BF94F00BB1B01D1A72AC8DC9A1 ("Jonathan Carter email@example.com") │ certified the following binding on 2023-01-31 └ C7203C0A920670BF94F00BB1B01D1A72AC8DC9A1 "Jonathan Carter firstname.lastname@example.org" ... ```
Sam can now reevaluate whether he is willing to consider Steve to be a trusted introducer for Jonathan. If so, he could upgrade his certification of Steve's certificate to a delegation thereby making him a trusted introducer:
``` $ sq certify --depth 1 sam.pgp steve.pgp "Steve McIntyre email@example.com" ```
Sam also needs to consider whether the two User IDs on Jonathan's certificate refer to the same person.
- sequoia-wot can now fetch missing certificates from key servers and WKD. The certificates are also cached locally to speed up future runs, and reduce load on the keyservers.
This functionality is enabled in sq-wot by the `--network` option. It can be supplied in addition to a local keyring or alone. If a local keyring is supplied, then the certificates in the local keyring are preferred. The network backend only uses the configured keyserver if a certificate is missing.
Combining this option with `--certification-network` makes sq-wot as powerful as a PGP path finding tool with access to a keyserver's database, because that's exactly what it is.
- sequoia-wot understands gossip.
Sometimes there are no paths from a trust root to the binding that you are trying to authenticate in the certification network. In that case, it may still be helpful to find out who has certified a particular certificate. That is, it may be helpful to listen to other's gossip. The `--gossip` option finds arbitrary paths to a particular certificate by treating all certificates as if they were trust roots albeit with zero trust. (This is similar to wotmate's graph-to-full.py.)
Returning to our previous example, Sam can find out who else certified Jonathan's certificate by running:
``` $ sq-wot --gossip --keyring /usr/share/keyrings/debian-keyring.gpg authenticate C7203C0A920670BF94F00BB1B01D1A72AC8DC9A1 'Jonathan Carter firstname.lastname@example.org' ```
- sequoia-wot includes a path validator and linter.
Instead of searching for an arbitrary path in the web of trust, it is possible to validate a specific path. If the path is invalid, it is also linted: the certificates and the certifications are checked for validity (not revoked, not expired, using safe cryptography, etc.). This is particularly helpful when you think a path ought to be valid, but `sq-wot authenticate` doesn't find it.
In the following example, we see that although Linus (79BE3E4300411886) certified greg k-h's certificate (38DBBDC86092693E), the path from Linus to greg k-h is not valid, because the certification uses SHA-1, which is rejected, because it is not secure:
``` $ sq-wot --keyring kernel.pgp path ABAF11C65A2970B130ABE3C479BE3E4300411886 647F28654894E3BD457199BE38DBBDC86092693E 'Greg Kroah-Hartman (Linux kernel stable release signing key) email@example.com' [ ] 647F28654894E3BD457199BE38DBBDC86092693E Greg Kroah-Hartman (Linux kernel stable release signing key) firstname.lastname@example.org: not authenticated (0%) ◯ ABAF11C65A2970B130ABE3C479BE3E4300411886 ("Linus Torvalds email@example.com") │ No adequate certification found. │ 79BE3E4300411886 did not certify <38DBBDC86092693E, "Greg Kroah-Hartman (Linux kernel stable release signing key) firstname.lastname@example.org"> │ No active certifications by 79BE3E4300411886 for <38DBBDC86092693E, "Greg Kroah-Hartman (Linux kernel stable release signing key) email@example.com"> had a trust amount of at least 120 │ Certification (BA80 by 79BE3E4300411886 on 38DBBDC86092693E at 2011-10-25 19:51.53) is adequate, but it is not valid │ BA80 by 79BE3E4300411886 on 38DBBDC86092693E at 2011-10-25 19:51.53: policy violation │ Policy rejected non-revocation signature (GenericCertification) requiring collision resistance │ SHA1 is not considered secure since 2013-02-01T00:00:00Z └ 647F28654894E3BD457199BE38DBBDC86092693E "Greg Kroah-Hartman (Linux kernel stable release signing key) firstname.lastname@example.org" ```
The main visible, non-functional improvement in sequoia-wot is better performance. Whereas the previous versions of the sequoia-wot library parsed and validated all certificates at start up time, the library has been restructured to only fetch, parse, and validate those certificates that are actually relevant to the given operation.
Scanning the keyring, parsing, and validating the relevant certificates, and authenticating a binding takes about 100 ms on my keyring:
``` $ gpg --export --export-options export-local-sigs > keyring.pgp $ ls -lh keyring.pgp -rw-r--r-- 1 us us 30M Jan 27 15:06 keyring.pgp $ sq keyring list keyring.pgp | wc -l 834 $ time sq-wot --keyring keyring.pgp -r 8F17777118A33DDA9BA48E62AACB3243630052D9 authenticate CBCD8F030588653EEDD7E2659B7DD433F254904A 'Justus Winter email@example.com' [✓] CBCD8F030588653EEDD7E2659B7DD433F254904A Justus Winter firstname.lastname@example.org: fully authenticated (100%) ◯ 8F17777118A33DDA9BA48E62AACB3243630052D9 ("Neal H. Walfield email@example.com") │ certified the following binding on 2022-10-07 └ CBCD8F030588653EEDD7E2659B7DD433F254904A "Justus Winter firstname.lastname@example.org"
real 0m0.107s user 0m0.056s sys 0m0.051s ```
This is about three times longer than `gpg --list-keys CBCD8F030588653EEDD7E2659B7DD433F254904A`. Unlike sq-wot, however, gpg uses a cache. Listing all authenticated bindings using `sq-wot list` takes 4.5 seconds on my test system. Running `gpg --check-trustdb` takes significantly longer:
``` $ time gpg --check-trustdb real 1m29.038s user 1m1.604s sys 0m27.420s $ time sq-wot --keyring keyring.pgp -r 8F17777118A33DDA9BA48E62AACB3243630052D9 list >/dev/null
real 0m4.270s user 0m4.154s sys 0m0.116s ```
This performance improvement was achieved by restructuring how the web of trust engine fetches certificates. Instead of having to provide all of the certificates upfront, the engine looks up certificates using a storage abstraction, the new Store and Backend traits.
This storage abstraction can be implemented by applications to interface with their own certificate stores, e.g., an SQLite database, etc.
Neal on behalf of the whole Sequoia PGP team