Software verification is a critical step in the use of secure applications but it has traditionally been hard to provide, especially from a user experience perspective.
Usual solutions are:
HTTPS
HTTPS is not enough in the case of Tails because we rely on mirrors hosted by third parties.
Note that all these mirrors already use HTTPS.
HTTPS also doesn't protect from interrupted downloads leading to broken Tails installations.
OpenPGP signatures
Unless the user knows how to verify the signing key through the OpenPGP Web-of-Trust, this technique ultimately relies on a correct download of the signing key.
Tails provides 3 mechanisms for users to verify the image downloaded through a third party mirror, while relying on cryptographic information fetched from our website through HTTPS.
JavaScript verification
The main verification mechanism relies on JavaScript code on the download page. See below for more details.
BitTorrent download
The Torrent file downloaded through HTTPS from our website includes a checksum of the image. BitTorrent clients automatically verify this checksum when the download finishes.
OpenPGP signature
We advertise OpenPGP as an optional verification technique, possibly done on top of the other 2 techniques and ideally through the OpenPGP Web-of-Trust. We assume that this technique is only relevant for people who are already knowledgeable about OpenPGP. As a consequence:
We only provide simplified instructions on how to perform the verification, insisting on aspects that might still be relevant for this public: verification of the date, command line options, warning when the signing key is not trusted, etc.
We take more time to develop the verification of the signing key through the OpenPGP Web of Trust because it is the only technique that is really stronger than HTTPS.
Related documents
Scope of the JavaScript verification
Goals
Provide a simple, automated, and cross-platform technique to verify USB and ISO images of the current version of Tails.
Allow verifying any current Tails image: downloaded over BitTorrent, copied from a friend, downloaded from one of our mirrors.
Non goals
Verify deprecated Tails images.
Verify Tails images downloaded from nightly.tails.boum.org.
Threat model
We are considering here an attacker who can:
[A] Provide a malicious Tails image to the user for example by operating a rogue Tails mirror.
[H] Operate a website that is loaded in a different tab in the same browser. This threat is taken care of by the internals of the browser and the proper coding of the JavaScript.
We are not considering an attacker who can:
[B] Do a man-in-the-middle attack by providing a rogue HTTPS certificate for https://tails.boum.org/ signed by a certificate authority trusted by the browser but under the control of the attacker.
Since the JavaScript verification is targeted at new users, a MitM or exploit on our website could defeat any verification technique by providing simplified instructions or by faking the verification.
Note that our website is already in the HSTS preload list of major browsers, which forces HTTPS connections to our website, even for first time visitors.
[C] Insert malicious content on https://tails.boum.org/ through an exploit on our website as this could trick new users to skip the Tails image verification all the way. To prevent this kind of attack we should instead:
- Monitor externally the most relevant parts of our website.
- Work on integrating full upgrades in Tails Upgrader to limit the number of times people have to rely on our website to upgrade. See #7499.
[D] Insert malicious information in our main Git repository as such an attacker could do attack [C] as well.
[E] Insert targeted malware in the user's computer or web browser as this could defeat any possible verification mechanism that such JavaScript can do.
For example, we cannot protect from a malicious extension installed in the web browser.
[G] Insert malicious content on https://tails.boum.org/ after taking control of the web server, or entire system, behind it. Such an attacker could do attack [C] as well but in such a way that could be much harder to detect (for example by serving malicious content only to some users).
[J] Provide a malicious copy of our website on a similar looking URL that could pretend that verification has succeeded without actually verifying anything.
Functioning
Image description file
When verifying a Tails image, the JavaScript:
Downloads an image description file (IDF) from:
https://tails.boum.org/install/v2/Tails/amd64/stable/latest.json
The IDF is served with the HTTP headers
Access-Control-Allow-Origin: *
to allow developers to test the verification locally from afile:///
URL.Verifies that the checksum of the image is present in the IDF.
Forge library
The JavaScript uses the Forge library to calculate the checksum.
We chose Forge because it was the fastest in this benchmark of JavaScript checksum implementations.
We cannot use the native SubtleCrypto.digest() API because it cannot read files as streams and would require loading the entire image in memory before computing its checksum.
We also rely on reading the image as a stream to display the progress bar, which is really important since the whole verification takes close to 1 minute.
Browser compatibility
Internet Explorer is not supported because our JavaScript uses the readAsBinaryString API.
Browsers without JavaScript are instructed to either enable JavaScript or calculate the checksum using GtkHash.