By Justus and Neal | April 8, 2021
We are thrilled to release the first version of the Octopus, an alternate OpenPGP backend for Thunderbird built on top of Sequoia.
The Octopus is a drop-in replacement for RNP, the OpenPGP library shipped with Thunderbird 78. In addition to providing all of the RNP functionality that Thunderbird uses, the Octopus also includes a number of enhancements. These fall into several categories. The Octopus restores some functionality that was present in Enigmail, but removed or has not yet been reimplemented in Thunderbird’s OpenPGP integration. In particular, the Octopus uses GnuPG’s keystore, interacts with gpg-agent, integrates GnuPG’s web of trust information, and updates certificates in the background. The Octopus includes a number of security fixes and improvements. For instance, it fixes Thunderbird’s insecure message composition, and automatically encrypts in-memory secret key material at rest. The Octopus adds a few performance improvements, such as, parsing the keyring in the background and using multiple threads. And, the Octopus has better support for parsing less usual, but not necessarily esoteric, certificates and keys.
The update from Thunderbird 68 to Thunderbird 78 brought a big change: the old extension mechanism was retired in favor of a safer approach, WebExtensions. This was an invasive change. Many add-ons including the popular Enigmail extension and the Autocrypt extension had to be reworked or even rewritten.
Recognizing that OpenPGP is essential for many existing Thunderbird users, the Thunderbird project decided to natively support OpenPGP. This is a positive development as it makes OpenPGP accessible to more people, and allows for tighter integration between the OpenPGP support and Thunderbird. In September 2020, Thunderbird 78.2.1 was released and, for the first time, Thunderbird offered OpenPGP functionality by default.
Rather than starting from scratch, the Thunderbird team lifted a lot of the user interface and plumbing code from Enigmail. They also replaced GnuPG with RNP, which is significantly easier to bundle than GnuPG.
Unfortunately, due to time constraints many features that Enigmail users enjoyed were removed to ensure that Thunderbird users at least had something that understands rudimentary OpenPGP. For instance, instead of using OpenPGP’s native authentication mechanisms, Thunderbird has a custom acceptance mechanism. Because the usual OpenPGP artifacts are not created, it is difficult to synchronize these judgments with another OpenPGP implementation or even another Thunderbird installation.
Our new project, the Octopus, is an alternative OpenPGP backend for Thunderbird. The Octopus implements the RNP functionality that Thunderbird uses in an ABI compatible manner to RNP, i.e. it is a drop-in replacement for the library ships with Thunderbird 78. In addition to implementing the functionality that RNP provides in terms of Sequoia, it also restores missing features, like GnuPG integration, and has a number of non-functional advantages including security fixes and additional protections.
In this demo, you can see Aron Salih sending an encrypted mail to Elise Sophia using the stock Thunderbird. Then, Elise Sophia downloads Thunderbird, replaces the RNP library with the Octopus, decrypts the mail, and replies.
We recently learned (1, 2) that Red Hat decided to disable OpenPGP support in their Thunderbird builds, because RNP uses Botan as the underlying cryptographic library, but Botan is not supported by Red Hat Enterprise Linux (see Fedora Crypto Consolidation).
Seeing that Sequoia’s default cryptographic library, Nettle, is supported by Redhat Enterprise Linux, we realized that we could fill the gap by providing a library that uses Sequoia and provides the same interface that RNP provides, or at least the subset that is actually used by Thunderbird.
Later we realized that it is not complicated to restore some of the oft-requested functionality directly in the Octopus. And, as we also missed that functionality ourselves, we decided to add it to the Octopus.
How complete is it?
The Octopus implements all of the functions that Thunderbird uses. And, we are happy to report, all of Thunderbird’s OpenPGP tests pass with flying colors. You can read the full log here, but the gist is:
$ ./mach test mail/test/browser/openpgp mail/extensions/openpgp/test [...] Overall Summary =============== mochitest-browser ~~~~~~~~~~~~~~~~~ Ran 65 checks (61 subtests, 4 tests) Expected results: 65 Unexpected results: 0 OK xpcshell ~~~~~~~~ Ran 67 checks (66 subtests, 1 tests) Expected results: 67 Unexpected results: 0 OK
And, here is the video of the Mochitests running. It is too fast to see any details, but it is still fun to look at:
The Octopus is actively developed by the Sequoia PGP team. We are primarily financed by the pep foundation. Our mandate is specifically to improve the OpenPGP ecosystem, and more generally to improve internet freedom tools.
Currently, the Octopus is developed outside of Thunderbird. There are two main reasons for this. First, the Thunderbird developers do not want to invest resources in supporting a new OpenPGP backend after having recently invested in RNP. Second, Sequoia and the Octopus are licensed under the GPLv2+. Although the GPLv2+ is compatible with MPL 2.0, adding GPLv2+ code to Thunderbird is not currently aligned with their licensing strategy.
Admittedly, implementing another library’s API is a bit dodgy. Long-term we’d like to see Thunderbird adopt SOP. SOP is a Stateless OpenPGP API. The current version only targets the CLI, but there is work to standardize a C API and ABI. Using SOP would allow increased choice for users. It also gives Thunderbird more freedom to easily change their implementation should the need arise.
The Octopus includes a number of additional features that enhance Thunderbird. We suspect that for many users, the integration with GnuPG will be most interesting. But, we’ve also added a Parcimonie implementation, and fixed some security weaknesses.
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:
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
OpenPGP Keyring Manager,
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
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 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 keys.openpgp.org 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.
This feature is controlled by the
net feature, which is enabled by
default. To disable it (and elide the dependencies on
tokio), build as follows:
cargo build --no-default-features --features sequoia-openpgp/default
The Octopus uses Sequoia, which rejects cryptographic algorithms that are known to be weak by default. Unfortunately, RNP still accepts MD5, among other vulnerable algorithms, without warning. Thunderbird has patched MD5 out of the version of RNP that they distribute, however, Thunderbird continues to support unlimited use of SHA-1, which is known to be vulnerable to collision attacks. 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.
Protection from Surreptitious Forwarding
When Thunderbird creates an email it uses the RFC 1847 Encapsulation method construct, which has been known to be broken for over 20 years. The issue is that if Alice signs a message and sends it to Bob, Bob can use the signature in a different context.
This security issue can be fixed by using OpenPGP’s intended recipient feature. Then, if Bob forwards the signed message (e.g., “I owe you 100 Euros”) to Carol, Carol’s MUA will mark the signature as invalid as she is not the intended recipient of the message.
In the Octopus, we detect the use of the encapsulation method and automatically and transparently replace it with the safer combined method whenever possible. Specifically, when we encrypt a message, we check whether we just generated the signed part. If so, we fix it. Because this generates another signature, if you are using a key managed by gpg’s agent, you may be prompted to authorize a second signature.
Sequoia also 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.
Sequoia only accepts SHA-1 in safer contexts. For instance, SHA-1 over messages, and its use in third-party certifications are rejected by default. But, SHA-1 self-signatures that are not suspicious are allowed.
Sequoia has announced a timeline to completely deprecate the use of SHA-1: in 2023 SHA-1 will no longer be accepted for digital signatures.
RNP accepts SHA-1 everywhere without any additional protections. By default, it even accepts. Happily, Thunderbird carries a patch to disable MD5 support.
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
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.
Sequoia implements nearly all. The only notable missing bit is the lack of ElGamal support.
RNP doesn’t implement a number of important parts. For instance, it does not reject unknown critical subpackets and notations. This is a security problem. RNP doesn’t handle unknown packet versions. This is a future compatibility problem. RNP also 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.
Over the past couple of months, we had several productive email exchanges and a meeting with Magnus and Kai from the Thunderbird team. We’re grateful for the help they provided and their feedback.