Hi everyone,
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:
https://crates.io/crates/sequoia-wot
You can also fetch 0.4.1 using the v0.4.1 tag:
https://gitlab.com/sequoia-pgp/sequoia-wot/-/tags/v0.4.1
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 <neal(a)walfield.org>"
gpg: "Neal H. Walfield <neal(a)g10code.com>"
gpg: "Neal H. Walfield <neal(a)gnupg.org>"
gpg: "Neal H. Walfield <neal(a)pep-project.org>"
gpg: "Neal H. Walfield <neal(a)pep.foundation>"
gpg: "Neal H. Walfield <neal(a)sequoia-pgp.org>"
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:
https://the.earth.li/~noodles/pathfind.html
And the graph-paths.py tool from the Linux kernel community's
wotmate:
https://github.com/mricon/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 <jcc(a)debian.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 <jcc(a)debian.org>'
[ ] C7203C0A920670BF94F00BB1B01D1A72AC8DC9A1 Jonathan Carter <jcc(a)debian.org>: doubly authenticated (800%)
Path #1 of 8, trust amount 120:
◯ 332D4CE3A2FAE5439B7E25B2283681BA6FE7F41D ("Sam Hartman <hartmans(a)debian.org>")
│ certified the following certificate on 2019-06-28
├ CEBB52301D617E910390FE16587979573442684E ("Steve McIntyre <93sam(a)debian.org>")
│ certified the following certificate on 2015-08-22
├ C7203C0A920670BF94F00BB1B01D1A72AC8DC9A1 ("Jonathan Carter <jcarter(a)linux.com>")
│ certified the following binding on 2023-01-31
└ C7203C0A920670BF94F00BB1B01D1A72AC8DC9A1 "Jonathan Carter <jcc(a)debian.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 <93sam(a)debian.org>"
```
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 <jcc(a)debian.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) <greg(a)kroah.com>'
[ ] 647F28654894E3BD457199BE38DBBDC86092693E Greg Kroah-Hartman (Linux kernel stable release signing key) <greg(a)kroah.com>: not authenticated (0%)
◯ ABAF11C65A2970B130ABE3C479BE3E4300411886 ("Linus Torvalds <torvalds(a)kernel.org>")
│ No adequate certification found.
│ 79BE3E4300411886 did not certify <38DBBDC86092693E, "Greg Kroah-Hartman (Linux kernel stable release signing key) <greg(a)kroah.com>">
│ No active certifications by 79BE3E4300411886 for <38DBBDC86092693E, "Greg Kroah-Hartman (Linux kernel stable release signing key) <greg(a)kroah.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) <greg(a)kroah.com>"
```
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 <justus(a)sequoia-pgp.org>'
[✓] CBCD8F030588653EEDD7E2659B7DD433F254904A Justus Winter <justus(a)sequoia-pgp.org>: fully authenticated (100%)
◯ 8F17777118A33DDA9BA48E62AACB3243630052D9 ("Neal H. Walfield <neal(a)g10code.com>")
│ certified the following binding on 2022-10-07
└ CBCD8F030588653EEDD7E2659B7DD433F254904A "Justus Winter <justus(a)sequoia-pgp.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.
https://docs.rs/sequoia-wot/0.4.1/sequoia_wot/store/index.html
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
Hi everyone,
I'm pleased to announce the release of version 1.1.4 of the buffered
reader crate. It has been published on crates.io:
https://crates.io/crates/buffered-reader
You can also fetch it using the buffered-reader/v1.1.4 tag:
https://gitlab.com/sequoia-pgp/sequoia/-/tags/buffered-reader%2Fv1.1.4
which I signed:
$ git verify-tag buffered-reader/v1.1.4
gpg: Signature made Fri Jan 6 21:40:10 2023 GMT
gpg: using RSA key C03FA6411B03AE12576461187223B56678E02528
gpg: Good signature from "Neal H. Walfield <neal(a)walfield.org>"
gpg: "Neal H. Walfield <neal(a)g10code.com>"
gpg: "Neal H. Walfield <neal(a)gnupg.org>"
gpg: "Neal H. Walfield <neal(a)pep-project.org>"
gpg: "Neal H. Walfield <neal(a)pep.foundation>"
gpg: "Neal H. Walfield <neal(a)sequoia-pgp.org>"
This release fixes a performance bug in the generic buffered reader
(`buffered_reader::Generic`). When the amount of data that is
requested (e.g., via `BufferedReader::data`) exceeds the default
buffer size, exactly that amount of data was read from the underlying
reader. This is problematic for two reasons. First, as users of a
buffered reader often do not immediately consume the data that is
read, most reads are forwarded to the underlying buffered reader.
Second, most reads are for one byte. Because
`buffered_reader::Generic` keeps all data in a single vec, this
resulted in a lot of copying, which hurt performance.
Neal on behalf of the whole Sequoia PGP team