17 stable releases
1.10.0 | Aug 12, 2024 |
---|---|
1.9.0 | Jun 15, 2024 |
1.8.1 | Mar 19, 2024 |
1.6.1 | Dec 15, 2023 |
1.0.1 | Apr 8, 2021 |
#555 in Cryptography
960 downloads per month
545KB
11K
SLoC
A Sequoia-based OpenPGP Backend for Thunderbird
This is a drop-in replacement for the RNP library supported and shipped by Thunderbird.
This project is called the Octopus, because octopuses can fit themselves in unusual places, and in this project we reimplement the RNP API as used by Thunderbird using Sequoia.
[Octopuses'] soft bodies mean octopuses can fit into impossibly small nooks and crannies, as long as the holes are not smaller than the only hard parts of their bodies: their beaks. If all else fails, octopuses can lose an arm to an attacker and regrow one later.
A note of caution
The Thunderbird developers do not support replacing RNP, and have made it difficult to integrate our solution. We regularly run Thunderbird's tests using the Octopus, using the ESR91 and beta versions of Thunderbird. We are quite confident that the Octopus is safe to use, and offers at least the degree of security that you get with RNP.
Nevertheless, it is a good idea to make regular backups of your
Thunderbird profile and production keys (at least pubring.gpg
,
secring.gpg
, and openpgp.sqlite
) and know how to recover.
Known limitations
-
There may be dragons.
-
When Thunderbird auto-updates, it overwrites the Octopus' version of
librnp.so
with its own version. This issue has been reported to Thunderbird. -
Thunderbird reads and caches the available certificates on startup. Thus if you add a new certificate to gpg, even though the Octopus will load it, Thunderbird will not notice it until either you manually reimport the keys using Thunderbird's
OpenPGP Keyring Manager
,File
,Reload Key Cache
, or you restart Thunderbird.Note: Thunderbird only caches the list of keys and some meta-data, so it will normally take advantage of any updates inserted into the gpg keystore or fetched via Parcimonie.
Support
The Octopus is actively maintained by the Sequoia PGP team. We will respond to issues and support requests, but we are not actively developing new features (however, the Octopus should have feature parity with Thunderbird's default backend). Our mandate is specifically to improve the OpenPGP ecosystem, and more generally to improve internet freedom tools. If you want to contribute financially to the Octopus development, or the Sequoia PGP project in general, please do get in touch.
In the past, we were primarily financed by the pep foundation.
Currently, the Octopus is developed outside of Thunderbird. The main reasons for this is that the Thunderbird developers do not want to invest resources in supporting a new OpenPGP backend after having recently invested in RNP.
In terms of testing, the Octopus includes a number of unit tests. Our CI runs these checks against all commits on Debian and Windows. It also runs the OpenPGP relevant unit tests from Thunderbird on Debian.
Building & Installing
Using official Linux distribution packages
Fedora
The Octopus is available from the standard Fedora repositories since Fedora 34. The official Thunderbird package has also been adapted to allow users to choose which of the available PGP backends is used.
If the thunderbird
package is already installed (and at least at version
91), then swapping the RNP backend with the Octopus can be done by
running the following command:
sudo dnf swap thunderbird-librnp-rnp sequoia-octopus-librnp
Switching back to the default backend works the same way, only with reversed
arguments for the dnf swap
command:
sudo dnf swap sequoia-octopus-librnp thunderbird-librnp-rnp
If Thunderbird is not yet installed, then the preferred OpenPGP backend can be specified at install time, as well:
sudo dnf install thunderbird sequoia-octopus-librnp
openSUSE
The package sequoia-octopus-librnp
is available in openSUSE Tumbleweed.
Like in Fedora, this package is replacing the default library shipped in
MozillaThunderbird-openpgp-librnp
.
To install sequoia-octopus-librnp
run the command
sudo zypper install sequoia-octopus-librnp
and resolve the conflict by selecting to uninstall
MozillaThunderbird-openpgp-librnp
.
Switching back is done in a similar way:
sudo zypper install MozillaThunderbird-openpgp-librnp
and resolve the conflict by selecting to uninstall
sequoia-octopus-librnp
.
If Thunderbird is not yet installed, then the preferred OpenPGP backend can be specified at install time, as well:
sudo zypper install MozillaThunderbird sequoia-octopus-librnp
Building manually
First of all, you will need to install Sequoia's build dependencies.
Then, building the Octopus is only a matter of invoking cargo build
,
optionally with the --release
flag to build an optimized build
suitable for end users. Non-release builds print debugging and
tracing information to stderr. You may optionally select one of
Sequoia's cryptographic backends, for example, on Windows you'll
probably want to use the Windows CNG backend instead of the Nettle
backend.
The result of the build is a shared library (i.e. a *.so
on Linux
and *BSD, a *.dll
on Windows, etc.). To use it, make your
Thunderbird pick it up instead of the librnp.so
that it ships,
e.g. by replacing it. The details are dependent on your deployment,
and this is something distributors need to figure out. This document
will demonstrate how to replace RNP in a local build of Thunderbird.
Note: the Octopus is fully backwards compatible with RNP. In
particular, it uses the same format for storing keys and stores them
in the same way. Thus, if you decide you don't like the Octopus, you
can simply restore the original librnp
, restart Thunderbird, and
Thunderbird will work as before with all of your data. Of course, you
should still make a backup (of at least pubring.gpg
, secring.gpg
,
and openpgp.sqlite
).
Building on Linux
To use a debug build, do the following:
cargo build
cp target/debug/libsequoia_octopus_librnp.so path/to/thunderbird/obj-x86_64-pc-linux-gnu/dist/bin/librnp.so
To use a release build, do the following:
cargo build --release
cp target/release/libsequoia_octopus_librnp.so path/to/thunderbird/obj-x86_64-pc-linux-gnu/dist/bin/librnp.so
On Debian stable it is not possible to build contemporary versions of the Octopus. You can follow these instructions.
Selecting a different cryptographic backend
To select a different cryptographic backend, OpenSSL in this example, and create a debug build, do the following:
cargo build --no-default-features --features crypto-openssl,net
cp target/debug/libsequoia_octopus_librnp.so path/to/thunderbird/obj-x86_64-pc-linux-gnu/dist/bin/librnp.so
To use a release build, do the following:
cargo build --no-default-features --features crypto-openssl,net --release
cp target/release/libsequoia_octopus_librnp.so path/to/thunderbird/obj-x86_64-pc-linux-gnu/dist/bin/librnp.so
Please see https://gitlab.com/sequoia-pgp/sequoia/-/tree/main/openpgp#crypto-backends for a description of the available backends.
Building on Windows (MSVC)
There still exist some 32-bit installations of Thunderbird, even on 64-bit Windows. The bitness of Thunderbird and the Octopus must match, so please check with "About Thunderbird".
The MSVC toolchain only supports the Windows CNG cryptographic backend.
The following recipes create debug builds. To create a release build,
add --release
after cargo build
(cargo build --release ...
).
For a 64-bit build, run:
rustup target add x86_64-pc-windows-msvc
cargo build --no-default-features --features crypto-cng,net --target x86_64-pc-windows-msvc
cp target/x86_64-pc-windows-msvc/debug/sequoia_octopus_librnp.dll "C:\Program Files\Mozilla Thunderbird\rnp.dll"
For a 32-bit build, run:
rustup target add i686-pc-windows-msvc
cargo build --no-default-features --features crypto-cng --target i686-pc-windows-msvc
cp target/i686-pc-windows-msvc/debug/sequoia_octopus_librnp.dll "C:\Program Files (x86)\Mozilla Thunderbird\rnp.dll"
Building on Windows (MSYS2)
There still exist some 32-bit installations of Thunderbird, even on 64-bit Windows. The bitness of Thunderbird and the Octopus must match, so please check with "About Thunderbird".
The MSYS2 toolchain supports both the Nettle and the Windows CNG cryptographic backend.
The following recipes create debug builds. To create a release build,
add --release
after cargo build
(cargo build --release ...
).
For a 64-bit build with CNG, run:
rustup target add x86_64-pc-windows-gnu
cargo build --no-default-features --features crypto-cng,net --target x86_64-pc-windows-gnu
cp target/x86_64-pc-windows-gnu/debug/sequoia_octopus_librnp.dll "C:\Program Files\Mozilla Thunderbird\rnp.dll"
For a 32-bit build with CNG, run:
rustup target add i686-pc-windows-gnu
cargo build --no-default-features --features crypto-cng --target i686-pc-windows-gnu
cp target/i686-pc-windows-gnu/debug/sequoia_octopus_librnp.dll "C:\Program Files (x86)\Mozilla Thunderbird\rnp.dll"
For a 64-bit build with Nettle, run:
rustup target add x86_64-pc-windows-gnu
cargo build --target x86_64-pc-windows-gnu
cp target/x86_64-pc-windows-gnu/debug/sequoia_octopus_librnp.dll "C:\Program Files\Mozilla Thunderbird\rnp.dll"
For a 32-bit build with Nettle, run:
rustup target add i686-pc-windows-gnu
cargo build --target i686-pc-windows-gnu
cp target/i686-pc-windows-gnu/debug/sequoia_octopus_librnp.dll "C:\Program Files (x86)\Mozilla Thunderbird\rnp.dll"
Using Debian's Thunderbird
The following recipe was tested with version 1:115.5.0-1~deb12u1
of
Thunderbird (from Debian Bookworm). This uses dpkg
's diversion
mechanism to move librnp.so
out of the way.
$ sudo apt install thunderbird
...
thunderbird is already the newest version (1:78.9.0-1~deb10u1).
...
$ ls -l /usr/lib/thunderbird/librnp.so
-rw-r--r-- 1 root root 723248 Mar 24 19:57 /usr/lib/thunderbird/librnp.so
$ sudo dpkg-divert --divert /usr/lib/thunderbird/librnp-orig.so --rename /usr/lib/thunderbird/librnp.so
Adding 'local diversion of /usr/lib/thunderbird/librnp.so to /usr/lib/thunderbird/librnp-orig.so'
$ sudo cp .../target/release/libsequoia_octopus_librnp.so /usr/lib/thunderbird/
$ sudo ln -sf libsequoia_octopus_librnp.so /usr/lib/thunderbird/librnp.so
$ ls -l /usr/lib/thunderbird/*rnp*
-rw-r--r-- 1 root root 723248 Mar 24 19:57 /usr/lib/thunderbird/librnp-orig.so
lrwxrwxrwx 1 root root 28 Apr 7 13:59 /usr/lib/thunderbird/librnp.so -> libsequoia_octopus_librnp.so
-rwxr-xr-x 1 root root 129988280 Apr 7 14:01 /usr/lib/thunderbird/libsequoia_octopus_librnp.so
If you are using the debug version, then change 'release' to 'debug'.
To uninstall the Octopus, you just need to remove the symlink and the diversion.
$ sudo rm /usr/lib/thunderbird/librnp.so
$ sudo dpkg-divert --rename --remove /usr/lib/thunderbird/librnp.so
Removing 'local diversion of /usr/lib/thunderbird/librnp.so to /usr/lib/thunderbird/librnp-orig.so'
$ ls -l /usr/lib/thunderbird/*rnp*
-rw-r--r-- 1 root root 723248 Mar 24 19:57 /usr/lib/thunderbird/librnp.so
-rwxr-xr-x 1 root root 129988280 Apr 7 14:01 /usr/lib/thunderbird/libsequoia_octopus_librnp.so
Precompiled Binaries for Windows
If you are feeling particularly daring, you can download a precompiled
rnp.dll
for Windows:
- Octopus for 64-bit Thunderbird
- Octopus for 64-bit Thunderbird, debug version
- Octopus for 32-bit Thunderbird
These binaries are created by our CI. They correspond to the current
version of the main
branch. Before code is checked into the main
branch, it must first pass our unit tests on both Debian and Windows,
and it must past the Thunderbird unit tests on Debian.
To use the Octopus, replace the rnp.dll
binary in your Thunderbird
installation. Thunderbird is usually installed to C:\Program Files\Mozilla Thunderbird
.
If you encounter any errors and wish to investigate, there is also a debug build available for 64-bit Thunderbird.
Before starting Thunderbird with the Octopus, be sure to backup the
files pubring.gpg
, secring.gpg
, and openpgp.sqlite
in your
Thunderbird profile. Your Thunderbird profile is usually located in
C:\Users\USERNAME\AppData\Roaming\Thunderbird\Profiles\PROFILEXXX.default
.
Additional Features
This library includes a number of additional features that enhance Thunderbird.
GnuPG Keyring Integration
When Thunderbird starts, it asks RNP to parse its keyring. At this
point, the Octopus also runs gpg --export
and includes that in the
results. This makes the user's GnuPG keyring available to
Thunderbird. (From that point on the Octopus also monitors GnuPG's
keystore for updates.) This can be disabled by setting the
GNUPGHOME
environment variable to /dev/null
as follows:
GNUPGHOME=/dev/null thunderbird
The certificates imported from GnuPG can be used as normal. It is possible to examine them in Thunderbird's OpenPGP Key Manager, set their "acceptance", etc.
There are two known limitations. First, the first time an OpenPGP
operation is performed, Thunderbird scans the keystore and creates an
index of the available keys. Thunderbird does not currently update
this index on its own. Thus, keys that are added to gpg's keystore
will not be visible to Thunderbird until either the cache is manually
flushed (OpenPGP Keyring Manager
, File
, Reload Key Cache
), or
you restart Thunderbird. Second, if you remove a certificate managed
by GnuPG using the Thunderbird certificate manager, it will be removed
from the in-memory keystore, but it is currently not actually removed
from your gpg keystore. As such, it will reappear the next time
Thunderbird loads the keyring.
The Octopus carefully keeps track of what certificates were loaded from GnuPG and only writes them out to Thunderbird's keyring if they have been modified; modified certificates are not currently written back to GnuPG. But, closer integration with GnuPG's keyring is planned.
gpg agent Integration
The Octopus automatically monitors what keys are loaded into gpg's agent, and reports to Thunderbird that secret key material is available for them. This means that it is trivial to mark a key managed by the agent as a personal key in Thunderbird without modifying Thunderbird's configuration files. Also, attempts to decrypt messages encrypted to a key managed by the agent are automatically forwarded to the agent for decryption.
Unlike Thunderbird the Octopus talks directly to the agent. Thus,
it is not necessary to install GPGME; you only need to have gpg
in
your PATH
.
GnuPG's Web of Trust Data
Thunderbird only supports a custom "acceptance" mechanism for authenticating OpenPGP certificate. Thunderbird ignores key signatures, and it is not possible to add certification authorities.
When Thunderbird starts up, the Octopus reads gpg's trust database, and merges it into Thunderbird's acceptance database. This means certificates that are considered authenticated by GnuPG are also considered authenticated by Thunderbird.
This integration is done carefully. If a user has manually accepted a certificate in Thunderbird, that setting is not overridden. This happens not only during the initial import, but also later: when the user accepts a certificate in Thunderbird, the Octopus detects this and will no longer update that certificate's acceptance based on GnuPG's trust database.
The Octopus monitors GnuPG for changes to its trust database. So, unlike when a new certificate is added to GnuPG's keystore, it is not necessary to restart Thunderbird to notice changes to the trust database.
Parcimonie
Parcimonie is a feature that automatically refreshes the user's OpenPGP certificates in the background using a number of privacy preserving techniques. In particular, updates are staggered, and the time between updates is drawn from a memoryless distribution to frustrate an attacker who wants to predict when a user will check for an update. Enigmail had its own version of this mechanism, but it was removed when Enigmail was integrated into Thunderbird.
The Parcimonie feature in the Octopus currently checks for updates on various OpenPGP key servers (keys.openpgp.org, the Proton keyserver, the Mailvelope keyserver, and keyserver.ubuntu.com), and in the appropriate Web Key Directories (WKDs) using the aforementioned privacy preserving mechanisms. It checks for updates for all non-revoked, valid certificates about once a week, on average. It also supports merging updates from User ID-less certificates.
Before importing a certificate, we first check if it appears to be flooded. If so, we strip third-party certifications from keys that we don't have a certificate for as those certifications are effectively useless.
Weak Cryptography
The Octopus uses Sequoia, which rejects cryptographic algorithms that are known to be weak by default. Sequoia, and by extension, the Octopus, rejects certificates and messages that use weak cryptographic primitives. Because RNP does not have a mechanism to indicate that a certificate or component should not be used, the Octopus reports these keys as having expired one second after their creation time.
Honors system-wide crypto policy
The Octopus reads a configuration file (by default
/etc/crypto-policies/back-ends/sequoia.config
) to configure its
cryptographic policy. The file to load can be overridden using the
SEQUOIA_CRYPTO_POLICY
environment variable. For more information on
the format, see this document.
Non-Functional Advantages
Sequoia has a number of non-functional advantages relative to RNP.
Keys Encrypted at Rest
Sequoia automatically encrypts unencrypted secret key material in memory when it is not in use. This makes secret key exfiltration ala Heartbleed much harder, and protects against Spectre, Rowhammer, etc.-style attacks. OpenSSH uses the same type of protection.
RNP has the concept of locking and unlocking keys, but this is explicit, and Thunderbird does not always relock keys after use.
SHA-1 Mitigations
SHA-1 is broken. Unfortunately, SHA-1 is still widely used. To deal with this Sequoia implements a number of countermeasures:
- Sequoia uses SHA1-CD, a variant of SHA-1 that detects and mitigates collision attacks. This protection is also used by GitHub, among others.
Collision Protection
Sequoia includes a salt in signatures and self-signatures to defend against collision attacks, among others. OpenSSH does the same thing. Should the collision resistance of another hash be broken, this will frustrate attackers trying to perform a Shambles-style attack.
No Split Brain Problem
RNP maintains separate public and secret keyrings. This can lead to a so-called split-brain problem where a certificate is present in both keyrings, and confusingly one version is returned sometimes and the other version other times. This is also the model that GnuPG 1.x used, and is one of the reasons that GnuPG migrated to a single OpenPGP keystore in GnuPG 2.0 with only the secret key material held by the agent.
To avoid this problem, the Octopus merges the two databases. To
remain backwards compatible with RNP, when the Octopus writes out the
certificates, certificates with secret key material are written to
secring.gpg
and those without are written to pubring.gpg
.
Multi-threading
Thanks to Rust's safer concurrency paradigms, it is less dangerous and less complicated for the Octopus to use threads than libraries written in other languages. The Octopus uses this, for instance, to parse keyrings faster. And to perform updates in the background.
OpenPGP Conformance
Sequoia implements nearly all of the OpenPGP RFC. The missing bits are either obsolete or insecure.
RNP doesn't implement a number of important parts. For example, RNP doesn't handle "esoteric" keys, like shared keys where only the encryption subkey's secret key material is shared. This is a compatibility problem. More examples can be found in the OpenPGP interoperability test suite.
Debugging
When the Octopus is built in debug mode, it can emit tracing
information to stderr (or octopus.log
in your Thunderbird profile
directory on Windows). There are several modes available, depending
on the setting of the SEQUOIA_OCTOPUS_TRACING
environment variable:
modes are:
-
By default, only failures are traced.
-
call
traces all function invocations with their arguments and results. -
full
selects full tracing mode.
Please note that traces may contain sensitive information such as OpenPGP Fingerprints and User IDs, but they shouldn't contain secret key material. Always use the least verbose log level that demonstrates the problem, and review the log and remove sensitive information before submitting it to a public bug tracker.
Dependencies
~77MB
~1.5M SLoC