mirror of
https://github.com/QubesOS/qubes-doc.git
synced 2025-08-07 22:22:21 -04:00
Revamp "Verifying signatures" and "Qubes security pack"
- Standardize syntax, formatting, and orthography - Update links - Clarify and improve language - Deduplicate content - Add info regarding keys not directly signed by the QMSK (https://github.com/QubesOS/qubes-doc/pull/1180#discussion_r672939404) - Add general info about digital signature use - Improve page organization (#1179) - Update info and instructions regarding the QMSK - Miscelanneous fixes and improvements
This commit is contained in:
parent
39d4be00cc
commit
05dcacd7b5
2 changed files with 405 additions and 388 deletions
|
@ -18,177 +18,130 @@ ref: 213
|
||||||
title: Qubes security pack (qubes-secpack)
|
title: Qubes security pack (qubes-secpack)
|
||||||
---
|
---
|
||||||
|
|
||||||
The **Qubes Security Pack** (`qubes-secpack`) is a Git repository that
|
The **Qubes Security Pack** (qubes-secpack) is a Git repository that contains:
|
||||||
contains:
|
|
||||||
|
|
||||||
* [Qubes Security Bulletins (QSBs)](/security/qsb/)
|
- [Qubes security bulletins (QSBs)](/security/qsb/)
|
||||||
* [Qubes Canaries](/security/canary/)
|
- [Qubes canaries](/security/canary/)
|
||||||
* [Signed Qubes ISO digests](/security/verifying-signatures/#how-to-verify-qubes-iso-digests)
|
- [Qubes ISO cryptographic hash values](/security/verifying-signatures/#how-to-verify-the-cryptographic-hash-values-of-qubes-isos)
|
||||||
* [Qubes fund information](https://github.com/QubesOS/qubes-secpack/tree/master/fund)
|
- [Qubes fund information](https://github.com/QubesOS/qubes-secpack/tree/master/fund)
|
||||||
* [Qubes PGP keys](https://keys.qubes-os.org/keys/)
|
- [Qubes PGP keys](https://keys.qubes-os.org/keys/)
|
||||||
* Security-related information and announcements (e.g., key revocations)
|
- Security-related information and announcements (e.g., key revocations)
|
||||||
|
|
||||||
While `qubes-secpack` itself is independent of any particular host, its current
|
While qubes-secpack itself is independent of any particular host, its current
|
||||||
official location is:
|
official location is:
|
||||||
|
|
||||||
<https://github.com/QubesOS/qubes-secpack>
|
<https://github.com/QubesOS/qubes-secpack>
|
||||||
|
|
||||||
## How to obtain, verify, and read
|
## How to obtain, verify, and read
|
||||||
|
|
||||||
The following example demonstrates one method of obtaining the `qubes-secpack`,
|
The following example demonstrates one method of obtaining the qubes-secpack,
|
||||||
verifying its contents, and reading them.
|
verifying its authenticity, and reading the contents.
|
||||||
|
|
||||||
1. Clone the `qubes-secpack` repo.
|
1. Use Git to clone the qubes-secpack repo.
|
||||||
|
|
||||||
```shell_session
|
```shell_session
|
||||||
$ git clone https://github.com/QubesOS/qubes-secpack.git
|
$ git clone https://github.com/QubesOS/qubes-secpack.git
|
||||||
Cloning into 'qubes-secpack'...
|
Cloning into 'qubes-secpack'...
|
||||||
remote: Counting objects: 195, done.
|
remote: Counting objects: 195, done.
|
||||||
remote: Total 195 (delta 0), reused 0 (delta 0)
|
remote: Total 195 (delta 0), reused 0 (delta 0)
|
||||||
Receiving objects: 100% (195/195), 130.94 KiB | 207.00 KiB/s, done.
|
Receiving objects: 100% (195/195), 130.94 KiB | 207.00 KiB/s, done.
|
||||||
Resolving deltas: 100% (47/47), done.
|
Resolving deltas: 100% (47/47), done.
|
||||||
Checking connectivity... done.
|
Checking connectivity... done.
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Import the included PGP keys.
|
2. Import the included PGP keys.
|
||||||
|
|
||||||
```shell_session
|
```shell_session
|
||||||
$ gpg --import qubes-secpack/keys/*/*
|
$ gpg --import qubes-secpack/keys/*/*
|
||||||
gpg: directory `/home/user/.gnupg' created
|
gpg: directory `/home/user/.gnupg' created
|
||||||
gpg: new configuration file `/home/user/.gnupg/gpg.conf' created
|
gpg: new configuration file `/home/user/.gnupg/gpg.conf' created
|
||||||
gpg: WARNING: options in `/home/user/.gnupg/gpg.conf' are not yet active during this run
|
gpg: WARNING: options in `/home/user/.gnupg/gpg.conf' are not yet active during this run
|
||||||
gpg: keyring `/home/user/.gnupg/secring.gpg' created
|
gpg: keyring `/home/user/.gnupg/secring.gpg' created
|
||||||
gpg: keyring `/home/user/.gnupg/pubring.gpg' created
|
gpg: keyring `/home/user/.gnupg/pubring.gpg' created
|
||||||
gpg: /home/user/.gnupg/trustdb.gpg: trustdb created
|
gpg: /home/user/.gnupg/trustdb.gpg: trustdb created
|
||||||
gpg: key C37BB66B: public key "Joanna Rutkowska (Qubes OS signing key) <joanna@invisiblethingslab.com>" imported
|
gpg: key C37BB66B: public key "Joanna Rutkowska (Qubes OS signing key) <joanna@invisiblethingslab.com>" imported
|
||||||
gpg: key 1E30A75D: public key "Joanna Rutkowska (Qubes OS signing key) <joanna@invisiblethingslab.com>" imported
|
gpg: key 1E30A75D: public key "Joanna Rutkowska (Qubes OS signing key) <joanna@invisiblethingslab.com>" imported
|
||||||
gpg: key 74EADABC: public key "Joanna Rutkowska (Qubes OS signing key) <joanna@invisiblethingslab.com>" imported
|
gpg: key 74EADABC: public key "Joanna Rutkowska (Qubes OS signing key) <joanna@invisiblethingslab.com>" imported
|
||||||
gpg: key 65EF29CA: public key "Joanna Rutkowska (Qubes OS Signing Key) <joanna@invisiblethingslab.com>" imported
|
gpg: key 65EF29CA: public key "Joanna Rutkowska (Qubes OS Signing Key) <joanna@invisiblethingslab.com>" imported
|
||||||
gpg: key 34898310: public key "Joanna Rutkowska (Qubes OS Signing Key) <joanna@invisiblethingslab.com>" imported
|
gpg: key 34898310: public key "Joanna Rutkowska (Qubes OS Signing Key) <joanna@invisiblethingslab.com>" imported
|
||||||
gpg: key B298547C: public key "Marek Marczykowski (Qubes OS signing key) <marmarek@mimuw.edu.pl>" imported
|
gpg: key B298547C: public key "Marek Marczykowski (Qubes OS signing key) <marmarek@mimuw.edu.pl>" imported
|
||||||
gpg: key AB5EEF90: public key "Marek Marczykowski (Qubes OS signing key) <marmarek@invisiblethingslab.com>" imported
|
gpg: key AB5EEF90: public key "Marek Marczykowski (Qubes OS signing key) <marmarek@invisiblethingslab.com>" imported
|
||||||
gpg: key A603BCB6: public key "Marek Marczykowski (Qubes OS signing key) <marmarek@invisiblethingslab.com>" imported
|
gpg: key A603BCB6: public key "Marek Marczykowski (Qubes OS signing key) <marmarek@invisiblethingslab.com>" imported
|
||||||
gpg: key 42CFA724: public key "Marek Marczykowski-Górecki (Qubes OS signing key) <marmarek@invisiblethingslab.com>" imported
|
gpg: key 42CFA724: public key "Marek Marczykowski-Górecki (Qubes OS signing key) <marmarek@invisiblethingslab.com>" imported
|
||||||
gpg: key 15CE40BF: public key "Wojciech Zygmunt Porczyk (Qubes OS signing key) <woju@invisiblethingslab.com>" imported
|
gpg: key 15CE40BF: public key "Wojciech Zygmunt Porczyk (Qubes OS signing key) <woju@invisiblethingslab.com>" imported
|
||||||
gpg: key 36879494: public key "Qubes Master Signing Key" imported
|
gpg: key 36879494: public key "Qubes Master Signing Key" imported
|
||||||
gpg: key 211093A7: public key "Qubes OS Release 1 Signing Key" imported
|
gpg: key 211093A7: public key "Qubes OS Release 1 Signing Key" imported
|
||||||
gpg: key 0A40E458: public key "Qubes OS Release 2 Signing Key" imported
|
gpg: key 0A40E458: public key "Qubes OS Release 2 Signing Key" imported
|
||||||
gpg: key 03FA5082: public key "Qubes OS Release 3 Signing Key" imported
|
gpg: key 03FA5082: public key "Qubes OS Release 3 Signing Key" imported
|
||||||
gpg: key 92C7B3DC: public key "Joanna Rutkowska (Qubes Security Pack Signing Key) <joanna@invisiblethingslab.com>" imported
|
gpg: key 92C7B3DC: public key "Joanna Rutkowska (Qubes Security Pack Signing Key) <joanna@invisiblethingslab.com>" imported
|
||||||
gpg: key 1830E06A: public key "Marek Marczykowski-Górecki (Qubes security pack) <marmarek@invisiblethingslab.com>" imported
|
gpg: key 1830E06A: public key "Marek Marczykowski-Górecki (Qubes security pack) <marmarek@invisiblethingslab.com>" imported
|
||||||
gpg: key 3F48CB21: public key "Qubes OS Security Team <security@qubes-os.org>" imported
|
gpg: key 3F48CB21: public key "Qubes OS Security Team <security@qubes-os.org>" imported
|
||||||
gpg: Total number processed: 17
|
gpg: Total number processed: 17
|
||||||
gpg: imported: 17 (RSA: 17)
|
gpg: imported: 17 (RSA: 17)
|
||||||
gpg: no ultimately trusted keys found
|
gpg: no ultimately trusted keys found
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Verify and trust the Qubes Master Signing Key.
|
3. [Authenticate and set the trust level of the Qubes Master Signing Key
|
||||||
|
(QMSK).](#how-to-import-and-authenticate-the-qubes-master-signing-key)
|
||||||
|
|
||||||
```shell_session
|
**Note:** Only some keys in the qubes-secpack are signed by the QMSK. Keys
|
||||||
$ gpg --edit-key 36879494
|
that are not signed directly by the QMSK are still signed indirectly by
|
||||||
gpg (GnuPG) 1.4.18; Copyright (C) 2014 Free Software Foundation, Inc.
|
virtue of being included in the qubes-secpack, which is itself signed (via
|
||||||
This is free software: you are free to change and redistribute it.
|
Git tags and/or commits) by keys that are in turn signed by the QMSK.
|
||||||
There is NO WARRANTY, to the extent permitted by law.
|
|
||||||
|
|
||||||
|
|
||||||
pub 4096R/36879494 created: 2010-04-01 expires: never usage: SC
|
|
||||||
trust: unknown validity: unknown
|
|
||||||
[ unknown] (1). Qubes Master Signing Key
|
|
||||||
|
|
||||||
gpg> fpr
|
|
||||||
pub 4096R/36879494 2010-04-01 Qubes Master Signing Key
|
|
||||||
Primary key fingerprint: 427F 11FD 0FAA 4B08 0123 F01C DDFA 1A3E 3687 9494
|
|
||||||
|
|
||||||
gpg> trust
|
|
||||||
pub 4096R/36879494 created: 2010-04-01 expires: never usage: SC
|
|
||||||
trust: unknown validity: unknown
|
|
||||||
[ unknown] (1). Qubes Master Signing Key
|
|
||||||
|
|
||||||
Please decide how far you trust this user to correctly verify other users' keys
|
|
||||||
(by looking at passports, checking fingerprints from different sources, etc.)
|
|
||||||
|
|
||||||
1 = I don't know or won't say
|
|
||||||
2 = I do NOT trust
|
|
||||||
3 = I trust marginally
|
|
||||||
4 = I trust fully
|
|
||||||
5 = I trust ultimately
|
|
||||||
m = back to the main menu
|
|
||||||
|
|
||||||
Your decision? 5
|
|
||||||
Do you really want to set this key to ultimate trust? (y/N) y
|
|
||||||
|
|
||||||
pub 4096R/36879494 created: 2010-04-01 expires: never usage: SC
|
|
||||||
trust: ultimate validity: unknown
|
|
||||||
[ unknown] (1). Qubes Master Signing Key
|
|
||||||
Please note that the shown key validity is not necessarily correct
|
|
||||||
unless you restart the program.
|
|
||||||
|
|
||||||
gpg> q
|
|
||||||
```
|
|
||||||
|
|
||||||
**Important!**
|
|
||||||
|
|
||||||
In order to verify the authenticity of the Qubes Master Signing Key prior to
|
|
||||||
trusting it, you should obtain the Qubes Master Signing Key fingerprint from
|
|
||||||
a trustworthy source (ideally, multiple sources) *other than* this website
|
|
||||||
and visually compare it (them) to the fingerprint displayed in the preceding
|
|
||||||
step, ensuring they match. You can read more about digital signatures and
|
|
||||||
key verification [here](/security/verifying-signatures/).
|
|
||||||
|
|
||||||
4. Verify signed Git tags.
|
4. Verify signed Git tags.
|
||||||
|
|
||||||
```shell_session
|
```shell_session
|
||||||
$ cd qubes-secpack/
|
$ cd qubes-secpack/
|
||||||
$ git tag -v `git describe`
|
$ git tag -v `git describe`
|
||||||
object 2bb7f0b966593d8ed74e140a04d60c68b96b164e
|
object 2bb7f0b966593d8ed74e140a04d60c68b96b164e
|
||||||
type commit
|
type commit
|
||||||
tag joanna_sec_2bb7f0b9
|
tag joanna_sec_2bb7f0b9
|
||||||
tagger Joanna Rutkowska <joanna@invisiblethingslab.com> 1468335706 +0000
|
tagger Joanna Rutkowska <joanna@invisiblethingslab.com> 1468335706 +0000
|
||||||
|
|
||||||
Tag for commit 2bb7f0b966593d8ed74e140a04d60c68b96b164e
|
Tag for commit 2bb7f0b966593d8ed74e140a04d60c68b96b164e
|
||||||
gpg: Signature made 2016-07-12T08:01:46 PDT
|
gpg: Signature made 2016-07-12T08:01:46 PDT
|
||||||
gpg: using RSA key 0x4E6829BC92C7B3DC
|
gpg: using RSA key 0x4E6829BC92C7B3DC
|
||||||
gpg: Good signature from "Joanna Rutkowska (Qubes Security Pack Signing Key) <joanna@invisiblethingslab.com>" [full]
|
gpg: Good signature from "Joanna Rutkowska (Qubes Security Pack Signing Key) <joanna@invisiblethingslab.com>" [full]
|
||||||
```
|
```
|
||||||
|
|
||||||
(The final line of output confirms that the signature is good.)
|
The final line of output confirms that the signature is good.
|
||||||
|
|
||||||
5. Verify detached PGP signatures.
|
5. Verify detached PGP signatures.
|
||||||
|
|
||||||
```shell_session
|
```shell_session
|
||||||
$ cd canaries/
|
$ cd canaries/
|
||||||
$ gpg --verify canary-001-2015.txt.sig.joanna canary-001-2015.txt
|
$ gpg --verify canary-001-2015.txt.sig.joanna canary-001-2015.txt
|
||||||
gpg: Signature made Mon Jan 5 20:21:40 2015 UTC using RSA key ID 92C7B3DC
|
gpg: Signature made Mon Jan 5 20:21:40 2015 UTC using RSA key ID 92C7B3DC
|
||||||
gpg: Good signature from "Joanna Rutkowska (Qubes Security Pack Signing Key) <joanna@invisiblethingslab.com>"
|
gpg: Good signature from "Joanna Rutkowska (Qubes Security Pack Signing Key) <joanna@invisiblethingslab.com>"
|
||||||
$ gpg --verify canary-001-2015.txt.sig.marmarek canary-001-2015.txt
|
$ gpg --verify canary-001-2015.txt.sig.marmarek canary-001-2015.txt
|
||||||
gpg: Signature made Mon Jan 5 20:13:37 2015 UTC using RSA key ID 1830E06A
|
gpg: Signature made Mon Jan 5 20:13:37 2015 UTC using RSA key ID 1830E06A
|
||||||
gpg: Good signature from "Marek Marczykowski-Górecki (Qubes security pack) <marmarek@invisiblethingslab.com>"
|
gpg: Good signature from "Marek Marczykowski-Górecki (Qubes security pack) <marmarek@invisiblethingslab.com>"
|
||||||
```
|
```
|
||||||
|
|
||||||
(The fourth and final lines of output confirm that the two signatures are
|
The fourth and final lines of output confirm that the two signatures are
|
||||||
good.)
|
good.
|
||||||
|
|
||||||
The same procedures can be applied to any directory or file in the
|
The same procedures can be applied to any directory or file in the
|
||||||
`qubes-secpack`. Two methods of verification (signed Git tags and detached PGP
|
qubes-secpack. Two methods of verification (signed Git tags and detached PGP
|
||||||
signatures) are provided to ensure that the system is robust (e.g., against a
|
signatures) are provided to ensure that the system is robust (e.g., against a
|
||||||
potential failure in Git tag-based verification) and to give users more options
|
potential failure in Git tag-based verification) and to give users more options
|
||||||
to verify the files.
|
to verify the files.
|
||||||
|
|
||||||
## PGP key inclusion criteria
|
## PGP key inclusion criteria
|
||||||
|
|
||||||
The `qubes-secpack` generally includes only those PGP keys used to sign some
|
The qubes-secpack generally includes only those PGP keys used to sign some kind
|
||||||
kind of official project artifact, such as Qubes release ISOs (release signing
|
of official project asset, such as Qubes release ISOs (release signing keys),
|
||||||
keys), Git tags and commits (code signing, doc signing, and security team
|
Git tags and commits (code signing, doc signing, and security team keys), and
|
||||||
keys), and the `qubes-secpack`'s own files and Git tags (security team keys
|
the qubes-secpack's own files and Git tags (security team keys again). This
|
||||||
again). This means that email keys are generally not included, even for
|
means that email keys are generally not included, even for official project
|
||||||
official project email addresses. There is one exception to this rule: the
|
email addresses. There is one exception to this rule: the official [Qubes
|
||||||
official [Qubes Security Team](/security/#qubes-security-team) email address,
|
security team](/security/#qubes-security-team) email address, which is used to
|
||||||
which is used to report security vulnerabilities in Qubes OS to our security
|
report security vulnerabilities in Qubes OS to our security team.
|
||||||
team.
|
|
||||||
|
|
||||||
## History and rationale
|
## History and rationale
|
||||||
|
|
||||||
On 2013-01-05, Joanna Rutkowska announced the `qubes-secpack` and explained its
|
On 2013-01-05, Joanna Rutkowska announced the qubes-secpack and explained its
|
||||||
rationale in an
|
rationale in an
|
||||||
[email](https://groups.google.com/d/msg/qubes-devel/twkOEaMLtNI/lZyGx6_jFCEJ)
|
[email](https://groups.google.com/d/msg/qubes-devel/twkOEaMLtNI/lZyGx6_jFCEJ)
|
||||||
to the Qubes mailing lists:
|
to the Qubes mailing lists:
|
||||||
|
|
|
@ -11,7 +11,13 @@ ref: 211
|
||||||
title: Verifying signatures
|
title: Verifying signatures
|
||||||
---
|
---
|
||||||
|
|
||||||
## What Digital Signatures Can and Cannot Prove
|
The Qubes OS Project uses [digital
|
||||||
|
signatures](https://en.wikipedia.org/wiki/Digital_signature) to guarantee the
|
||||||
|
authenticity and integrity of certain important assets. This page explains how
|
||||||
|
to verify those signatures. It is extremely important for your security to
|
||||||
|
understand and apply these practices.
|
||||||
|
|
||||||
|
## What digital signatures can and cannot prove
|
||||||
|
|
||||||
Most people --- even programmers --- are confused about the basic concepts
|
Most people --- even programmers --- are confused about the basic concepts
|
||||||
underlying digital signatures. Therefore, most people should read this section,
|
underlying digital signatures. Therefore, most people should read this section,
|
||||||
|
@ -24,15 +30,15 @@ third party). **Integrity** ensures that the contents of the file have not been
|
||||||
tampered with (i.e., that a third party has not undetectably altered its
|
tampered with (i.e., that a third party has not undetectably altered its
|
||||||
contents *en route*).
|
contents *en route*).
|
||||||
|
|
||||||
Digital signatures **cannot** prove any other property, e.g., that the signed
|
Digital signatures **cannot** prove, e.g., that the signed file is not
|
||||||
file is not malicious. In fact, there is nothing that could stop someone from
|
malicious. In fact, there is nothing that could stop someone from signing a
|
||||||
signing a malicious program (and it happens from time to time in reality).
|
malicious program (and it happens from time to time in reality).
|
||||||
|
|
||||||
The point is that we must decide who we will trust (e.g., Linus Torvalds,
|
The point is that we must decide who we will trust (e.g., Linus Torvalds,
|
||||||
Microsoft, or the Qubes Project) and assume that if a given file was signed by
|
Microsoft, or the Qubes Project) and assume that if a given file was signed by
|
||||||
a trusted party, then it should not be malicious or negligently buggy. The
|
a trusted party, then it should not be malicious or negligently buggy. The
|
||||||
decision of whether to trust any given party is beyond the scope of digital
|
decision of whether to trust any given party is beyond the scope of digital
|
||||||
signatures. It's more of a sociological and political decision.
|
signatures. It's more of a social and political decision.
|
||||||
|
|
||||||
Once we make the decision to trust certain parties, digital signatures are
|
Once we make the decision to trust certain parties, digital signatures are
|
||||||
useful, because they make it possible for us to limit our trust only to those
|
useful, because they make it possible for us to limit our trust only to those
|
||||||
|
@ -41,8 +47,8 @@ between us and them, e.g., server compromises (qubes-os.org will surely be
|
||||||
compromised one day, so [don't blindly trust the live version of this
|
compromised one day, so [don't blindly trust the live version of this
|
||||||
site](/faq/#should-i-trust-this-website)), dishonest IT staff at the hosting
|
site](/faq/#should-i-trust-this-website)), dishonest IT staff at the hosting
|
||||||
company, dishonest staff at the ISPs, Wi-Fi attacks, etc. We call this
|
company, dishonest staff at the ISPs, Wi-Fi attacks, etc. We call this
|
||||||
philosophy [Distrusting the
|
philosophy [distrusting the
|
||||||
Infrastructure](/faq/#what-does-it-mean-to-distrust-the-infrastructure).
|
infrastructure](/faq/#what-does-it-mean-to-distrust-the-infrastructure).
|
||||||
|
|
||||||
By verifying all the files we download that purport to be authored by a party
|
By verifying all the files we download that purport to be authored by a party
|
||||||
we've chosen to trust, we eliminate concerns about the bad things discussed
|
we've chosen to trust, we eliminate concerns about the bad things discussed
|
||||||
|
@ -52,127 +58,120 @@ them).
|
||||||
|
|
||||||
However, for digital signatures to make any sense, we must ensure that the
|
However, for digital signatures to make any sense, we must ensure that the
|
||||||
public keys we use for signature verification are indeed the original ones.
|
public keys we use for signature verification are indeed the original ones.
|
||||||
Anybody can generate a GPG key pair that purports to belong to "The Qubes
|
Anybody can generate a cryptographic key that purports to belong to "The Qubes
|
||||||
Project," but of course only the key pair that we (i.e., the Qubes developers)
|
OS Project," but of course only the keys that we (the real Qubes developers)
|
||||||
generated is the legitimate one. The next section explains how to verify the
|
generate are the genuine ones. The next rest of this page explains how to
|
||||||
validity of the Qubes signing keys in the process of verifying a Qubes ISO.
|
verify the authenticity of the various keys used in the project and how to use
|
||||||
(However, the same general principles apply to all cases in which you may wish
|
those keys to verify certain important assets.
|
||||||
to verify a PGP signature, such as [verifying
|
|
||||||
repos](#how-to-verify-qubes-repos), not just verifying ISOs.)
|
|
||||||
|
|
||||||
## How to Verify Qubes ISO Signatures
|
## How to obtain and authenticate PGP keys
|
||||||
|
|
||||||
This section will guide you through the process of verifying a Qubes ISO by
|
We use [PGP](https://en.wikipedia.org/wiki/Pretty_Good_Privacy) (specifically,
|
||||||
checking its PGP signature. There are three basic steps in this process:
|
the [OpenPGP](https://en.wikipedia.org/wiki/Pretty_Good_Privacy#OpenPGP)
|
||||||
|
standard). Before we begin, you'll need software that can manage PGP keys and
|
||||||
|
verify PGP signatures. Any program that complies with the OpenPGP standard will
|
||||||
|
do, but here are some examples for popular operating systems:
|
||||||
|
|
||||||
1. [Get the Qubes Master Signing Key and verify its
|
**Linux:** [GnuPG](https://gnupg.org/download/index.html)
|
||||||
authenticity](#1-get-the-qubes-master-signing-key-and-verify-its-authenticity)
|
([documentation](https://www.gnupg.org/documentation/)). Open a terminal and
|
||||||
2. [Get the Release Signing Key](#2-get-the-release-signing-key)
|
use the `gpg2` command. If you don't already have GnuPG installed, install it
|
||||||
3. [Verify your Qubes ISO](#3-verify-your-qubes-iso)
|
via your distro's package manager or from the website.
|
||||||
|
|
||||||
If you run into any problems, please consult the [Troubleshooting
|
|
||||||
FAQ](#troubleshooting-faq) below.
|
|
||||||
|
|
||||||
### Preparation
|
|
||||||
|
|
||||||
Before we begin, you'll need a program that can verify PGP signatures. Any such
|
|
||||||
program will do, but here are some examples for popular operating systems:
|
|
||||||
|
|
||||||
**Windows:** [Gpg4win](https://gpg4win.org/download.html)
|
|
||||||
([documentation](https://www.gpg4win.org/documentation.html)). Use the Windows
|
|
||||||
command line (`cmd.exe`) to enter commands.
|
|
||||||
|
|
||||||
**Mac:** [GPG Suite](https://gpgtools.org/)
|
**Mac:** [GPG Suite](https://gpgtools.org/)
|
||||||
([documentation](https://gpgtools.tenderapp.com/kb)). Open a terminal to enter
|
([documentation](https://gpgtools.tenderapp.com/kb)). Open a terminal to enter
|
||||||
commands.
|
commands.
|
||||||
|
|
||||||
**Linux:** `gpg2` from your package manager or from
|
**Windows:** [Gpg4win](https://gpg4win.org/download.html)
|
||||||
[gnupg.org](https://gnupg.org/download/index.html)
|
([documentation](https://www.gpg4win.org/documentation.html)). Use the Windows
|
||||||
([documentation](https://www.gnupg.org/documentation/)). Open a terminal to
|
command line (`cmd.exe`) to enter commands.
|
||||||
enter commands.
|
|
||||||
|
|
||||||
The commands below will use `gpg2`, but if that doesn't work for you, try `gpg`
|
Throughout this page, we'll use GnuPG via the `gpg2` command. If that doesn't
|
||||||
instead. If that still doesn't work, please consult the documentation for your
|
work for you, try `gpg` instead. If that still doesn't work, please consult the
|
||||||
specific program (see links above).
|
documentation for your specific program (see links above) and the
|
||||||
|
[troubleshooting FAQ](#troubleshooting-faq) below.
|
||||||
|
|
||||||
### 1. Get the Qubes Master Signing Key and verify its authenticity
|
### How to import and authenticate the Qubes Master Signing Key
|
||||||
|
|
||||||
Every file published by the Qubes Project (ISO, RPM, TGZ files and Git
|
Many important Qubes OS Project assets (e.g., ISOs, RPMs, TGZs, and Git
|
||||||
repositories) is digitally signed by one of the developer keys or Release
|
objects) are digitally signed by an official team member's key or by a release
|
||||||
Signing Keys. Each such key is signed by the [Qubes Master Signing
|
signing key (RSK). Each such key is, in turn, signed by the [Qubes Master
|
||||||
Key](https://keys.qubes-os.org/keys/qubes-master-signing-key.asc)
|
Signing Key
|
||||||
(`0xDDFA1A3E36879494`). The developer signing keys are set to expire after one
|
(QMSK)](https://keys.qubes-os.org/keys/qubes-master-signing-key.asc)
|
||||||
year, while the Qubes Master Signing Key and Release Signing Keys have no
|
(`0x427F11FD0FAA4B080123F01CDDFA1A3E36879494`). In this way, the QMSK is the
|
||||||
expiration date. This Qubes Master Signing Key was generated on and is kept
|
ultimate root of trust for the Qubes OS Project.
|
||||||
only on a dedicated, air-gapped "vault" machine, and the private portion will
|
|
||||||
(hopefully) never leave this isolated machine.
|
|
||||||
|
|
||||||
There are several ways to get the Qubes Master Signing Key.
|
The developer signing keys are set to expire after one year, while the QMSK and
|
||||||
|
RSKs have no expiration date. Th QMSK was generated on and is kept only on a
|
||||||
|
dedicated, air-gapped "vault" machine, and the private portion will (hopefully)
|
||||||
|
never leave this isolated machine.
|
||||||
|
|
||||||
- If you have access to an existing Qubes installation, it's available in every
|
There are several ways to get the QMSK.
|
||||||
VM ([except dom0](https://github.com/QubesOS/qubes-issues/issues/2544)):
|
|
||||||
|
|
||||||
```shell_session
|
- If you're on Qubes OS, it's available in every
|
||||||
$ gpg2 --import /usr/share/qubes/qubes-master-key.asc
|
qube ([except dom0](https://github.com/QubesOS/qubes-issues/issues/2544)):
|
||||||
```
|
|
||||||
|
|
||||||
- If you're on Fedora, you can get it in the `distribution-gpg-keys` package:
|
```shell_session
|
||||||
|
$ gpg2 --import /usr/share/qubes/qubes-master-key.asc
|
||||||
|
```
|
||||||
|
|
||||||
|
- If you're on Fedora, you can get it in the [distribution-gpg-keys](https://github.com/xsuchy/distribution-gpg-keys) package:
|
||||||
|
|
||||||
```shell_session
|
```shell_session
|
||||||
$ dnf install distribution-gpg-keys
|
$ dnf install distribution-gpg-keys
|
||||||
```
|
$ gpg2 --import /usr/share/distribution-gpg-keys/qubes/*
|
||||||
|
```
|
||||||
|
|
||||||
- If you’re on Debian, it may already be included in your keyring.
|
- If you’re on Debian, it may already be included in your keyring.
|
||||||
|
|
||||||
- Fetch it with GPG:
|
- Fetch it with GPG:
|
||||||
|
|
||||||
```shell_session
|
```shell_session
|
||||||
$ gpg2 --fetch-keys https://keys.qubes-os.org/keys/qubes-master-signing-key.asc
|
$ gpg2 --fetch-keys https://keys.qubes-os.org/keys/qubes-master-signing-key.asc
|
||||||
```
|
```
|
||||||
|
|
||||||
- Download it as a
|
|
||||||
[file](https://keys.qubes-os.org/keys/qubes-master-signing-key.asc), then
|
|
||||||
import it with GPG:
|
|
||||||
|
|
||||||
```shell_session
|
|
||||||
$ gpg2 --import ./qubes-master-signing-key.asc
|
|
||||||
```
|
|
||||||
|
|
||||||
- Get it from a public
|
- Get it from a public
|
||||||
[keyserver](https://en.wikipedia.org/wiki/Key_server_%28cryptographic%29#Keyserver_examples)
|
[keyserver](https://en.wikipedia.org/wiki/Key_server_%28cryptographic%29#Keyserver_examples)
|
||||||
(specified on first use with `--keyserver <URI>` along with keyserver options
|
(specified on first use with `--keyserver <URI>` along with keyserver options
|
||||||
to include key signatures), e.g.:
|
to include key signatures), e.g.:
|
||||||
|
|
||||||
```shell_session
|
```shell_session
|
||||||
$ gpg2 --keyserver-options no-self-sigs-only,no-import-clean --keyserver hkp://pool.sks-keyservers.net:11371 --recv-keys 0x427F11FD0FAA4B080123F01CDDFA1A3E36879494
|
$ gpg2 --keyserver-options no-self-sigs-only,no-import-clean --keyserver hkp://keyserver.ubuntu.com --recv-keys 0x427F11FD0FAA4B080123F01CDDFA1A3E36879494
|
||||||
```
|
```
|
||||||
|
|
||||||
The Qubes Master Signing Key is also available in the [Qubes Security
|
- Download it as a file, then import the file.
|
||||||
Pack](/security/pack/) and in the archives of the project's
|
|
||||||
[developer](https://groups.google.com/d/msg/qubes-devel/RqR9WPxICwg/kaQwknZPDHkJ)
|
|
||||||
and
|
|
||||||
[user](https://groups.google.com/d/msg/qubes-users/CLnB5uFu_YQ/ZjObBpz0S9UJ)
|
|
||||||
[mailing lists](/support/).
|
|
||||||
|
|
||||||
Once you have obtained the Qubes Master Signing Key, you must verify that it is
|
Here are some example download locations:
|
||||||
authentic rather than a forgery. Anyone can create a PGP key with the name
|
|
||||||
"Qubes Master Signing Key," so you cannot rely on the name alone. You also
|
- [Qubes security pack](/security/pack/)
|
||||||
|
- [Qubes keyserver](https://keys.qubes-os.org/keys/qubes-master-signing-key.asc)
|
||||||
|
- [Email to qubes-devel](https://groups.google.com/d/msg/qubes-devel/RqR9WPxICwg/kaQwknZPDHkJ)
|
||||||
|
- [Email to qubes-users](https://groups.google.com/d/msg/qubes-users/CLnB5uFu_YQ/ZjObBpz0S9UJ)
|
||||||
|
|
||||||
|
Once you have the key as a file, import it:
|
||||||
|
|
||||||
|
```shell_session
|
||||||
|
$ gpg2 --import /<PATH_TO_FILE>/qubes-master-signing-key.asc
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you've obtained the QMSK, you must verify that it's authentic rather than
|
||||||
|
a forgery. Anyone can create a PGP key with the name "Qubes Master Signing Key"
|
||||||
|
and the short key ID `0x36879494`, so you cannot rely on these alone. You also
|
||||||
should not rely on any single website, not even over HTTPS.
|
should not rely on any single website, not even over HTTPS.
|
||||||
|
|
||||||
So, what *should* you do? One option is to use the PGP [Web of
|
So, what *should* you do? One option is to use the PGP [Web of
|
||||||
Trust](https://en.wikipedia.org/wiki/Web_of_trust). In addition, some operating
|
Trust](https://en.wikipedia.org/wiki/Web_of_trust). In addition, some operating
|
||||||
systems include the means to acquire the Qubes Master Signing Key in a secure
|
systems include the means to acquire the QMSK in a secure way. For example, on
|
||||||
way. For example, on Fedora, `dnf install distribution-gpg-keys` will get you
|
Fedora, `dnf install distribution-gpg-keys` will get you the QMSK along with
|
||||||
the Qubes Master Signing Key along with several other Qubes keys. On Debian,
|
several other Qubes keys. On Debian, your keyring may already contain the
|
||||||
your keyring may already contain the necessary keys.
|
necessary keys.
|
||||||
|
|
||||||
Another option is to rely on the key's fingerprint. Every PGP key has a
|
Perhaps the most common route is to rely on the key's fingerprint. Every PGP
|
||||||
fingerprint that uniquely identifies it among all PGP keys (viewable with `gpg2
|
key has a fingerprint that uniquely identifies it among all PGP keys (viewable
|
||||||
--fingerprint <KEY_ID>`). Therefore, if you know the genuine Qubes Master
|
with `gpg2 --fingerprint <KEY_ID>`). Therefore, if you know the genuine QMSK
|
||||||
Signing Key fingerprint, then you always have an easy way to confirm whether
|
fingerprint, then you always have an easy way to confirm whether any purported
|
||||||
any purported copy of it is authentic, simply by comparing the fingerprints.
|
copy of it is authentic, simply by comparing the fingerprints.
|
||||||
|
|
||||||
For example, here is the Qubes Master Signing Key fingerprint:
|
For example, here is the QMSK fingerprint:
|
||||||
|
|
||||||
```
|
```
|
||||||
pub 4096R/36879494 2010-04-01
|
pub 4096R/36879494 2010-04-01
|
||||||
|
@ -213,12 +212,12 @@ Here are some ideas for how to do that:
|
||||||
Once you've obtained the fingerprint from enough independent sources in enough
|
Once you've obtained the fingerprint from enough independent sources in enough
|
||||||
different ways that you feel confident that you know the genuine fingerprint,
|
different ways that you feel confident that you know the genuine fingerprint,
|
||||||
keep it in a safe place. Every time you need to check whether a key claiming to
|
keep it in a safe place. Every time you need to check whether a key claiming to
|
||||||
be the Qubes Master Signing Key is authentic, compare that key's fingerprint to
|
be the QMSK is authentic, compare that key's fingerprint to your trusted copy
|
||||||
your trusted copy and confirm they match.
|
and confirm they match.
|
||||||
|
|
||||||
Now that you've imported the authentic Qubes Master Signing Key, set its trust
|
Now that you've imported the authentic QMSK, set its trust level to "ultimate"
|
||||||
level to "ultimate" so that it can be used to automatically verify all the keys
|
so that it can be used to automatically verify all the keys signed by the QMSK
|
||||||
signed by the Qubes Master Signing Key (in particular, Release Signing Keys).
|
(in particular, RSKs).
|
||||||
|
|
||||||
```
|
```
|
||||||
$ gpg2 --edit-key 0x427F11FD0FAA4B080123F01CDDFA1A3E36879494
|
$ gpg2 --edit-key 0x427F11FD0FAA4B080123F01CDDFA1A3E36879494
|
||||||
|
@ -261,16 +260,11 @@ unless you restart the program.
|
||||||
gpg> q
|
gpg> q
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, when you import any of the legitimate Qubes developer keys and Release
|
Now, when you import any of the release signing keys and many Qubes team member
|
||||||
Signing Keys used to sign ISOs, RPMs, TGZs, Git tags, and Git commits, they
|
keys, they will already be trusted in virtue of being signed by the QMSK.
|
||||||
will already be trusted in virtue of being signed by the Qubes Master Signing
|
|
||||||
Key.
|
|
||||||
|
|
||||||
Before proceeding to the next step, make sure the Qubes Master Signing Key is
|
Before proceeding to the next step, let's do a final sanity check to make sure
|
||||||
in your keyring with the correct trust level. (Note: We have already verified
|
the QMSK is in your keyring with the correct trust level.
|
||||||
the authenticity of the key, so this final check is not about security. Rather,
|
|
||||||
it's just a sanity check to make sure that we've imported the key into our
|
|
||||||
keyring correctly.)
|
|
||||||
|
|
||||||
```
|
```
|
||||||
$ gpg2 -k "Qubes Master Signing Key"
|
$ gpg2 -k "Qubes Master Signing Key"
|
||||||
|
@ -279,46 +273,53 @@ pub rsa4096 2010-04-01 [SC]
|
||||||
uid [ultimate] Qubes Master Signing Key
|
uid [ultimate] Qubes Master Signing Key
|
||||||
```
|
```
|
||||||
|
|
||||||
If you don't see the Qubes Master Signing Key here with a trust level of
|
If you don't see the QMSK here with a trust level of "ultimate," go back and
|
||||||
"ultimate," go back and follow the instructions in this section carefully.
|
follow the instructions in this section carefully and consult the
|
||||||
|
[troubleshooting FAQ](#troubleshooting-faq) below.
|
||||||
|
|
||||||
### 2. Get the Release Signing Key
|
### How to import and authenticate release signing keys
|
||||||
|
|
||||||
The filename of the Release Signing Key for your version is usually
|
Every Qubes OS release is signed by a **release signing key (RSK)**, which is
|
||||||
`qubes-release-X-signing-key.asc`, where `X` is the major version number of
|
in turn signed by the Qubes Master Signing Key (QMSK). Before we proceed, you
|
||||||
your Qubes release. There are several ways to get the Release Signing Key for
|
must first [import and authenticate the Qubes Master Signing
|
||||||
your Qubes release.
|
Key](#how-to-import-and-authenticate-the-qubes-master-signing-key).
|
||||||
|
|
||||||
|
The first step is to obtain the correct RSK. The filename of the RSK for your
|
||||||
|
Qubes OS release is usually `qubes-release-X-signing-key.asc`, where `X` is the
|
||||||
|
major version number of your Qubes release. There are several ways to get the
|
||||||
|
RSK for your Qubes release.
|
||||||
|
|
||||||
- If you have access to an existing Qubes installation, the release keys are
|
- If you have access to an existing Qubes installation, the release keys are
|
||||||
available in dom0 in `/etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-*`. These can be
|
available in dom0 in `/etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-*`. These can be
|
||||||
[copied](/doc/how-to-copy-from-dom0/#copying-from-dom0) into other VMs for
|
[copied](/doc/how-to-copy-from-dom0/#copying-from-dom0) into other qubes for
|
||||||
further use. In addition, every other VM contains the release key
|
further use. In addition, every other qube contains the release key
|
||||||
corresponding to that installation's release in
|
corresponding to that installation's release in
|
||||||
`/etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-*`. If you wish to use one of these keys,
|
`/etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-*`. If you wish to use one of these keys,
|
||||||
make sure to import it into your keyring, e.g.:
|
make sure to import it into your keyring, e.g.:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ gpg2 --import /etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-*
|
$ gpg2 --import /etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-*
|
||||||
```
|
```
|
||||||
|
|
||||||
- Fetch it with GPG:
|
- Fetch it with GPG:
|
||||||
|
|
||||||
```shell_session
|
```shell_session
|
||||||
$ gpg2 --keyserver-options no-self-sigs-only,no-import-clean --fetch-keys https://keys.qubes-os.org/keys/qubes-release-X-signing-key.asc
|
$ gpg2 --keyserver-options no-self-sigs-only,no-import-clean --fetch-keys https://keys.qubes-os.org/keys/qubes-release-X-signing-key.asc
|
||||||
```
|
```
|
||||||
|
|
||||||
- Download it as a file. You can find the Release Signing Key for your Qubes
|
- Download it as a file. You can find the RSK for your Qubes
|
||||||
version on the [Downloads](/downloads/) page. You can also download all the
|
release on the [downloads](/downloads/) page. You can also download all the
|
||||||
currently used developers' signing keys, Release Signing Keys, and the Qubes
|
currently used developers' signing keys, RSKs, and the Qubes
|
||||||
Master Signing Key from the [Qubes Security Pack](/security/pack/) and the
|
Master Signing Key from the [Qubes security pack](/security/pack/) and the
|
||||||
[Qubes OS Keyserver](https://keys.qubes-os.org/keys/). Once you've downloaded
|
[Qubes keyserver](https://keys.qubes-os.org/keys/). Once you've downloaded
|
||||||
your Release Signing Key, import it with GPG:
|
your RSK, import it with GPG:
|
||||||
|
|
||||||
```shell_session
|
```shell_session
|
||||||
$ gpg2 --keyserver-options no-self-sigs-only,no-import-clean --import ./qubes-release-X-signing-key.asc
|
$ gpg2 --keyserver-options no-self-sigs-only,no-import-clean --import ./qubes-release-X-signing-key.asc
|
||||||
```
|
```
|
||||||
|
|
||||||
The Release Signing Key should be signed by the Qubes Master Signing Key:
|
Now that you have the correct RSK, you simply need to verify that it is signed
|
||||||
|
by the QMSK:
|
||||||
|
|
||||||
```shell_session
|
```shell_session
|
||||||
$ gpg2 --check-signatures "Qubes OS Release X Signing Key"
|
$ gpg2 --check-signatures "Qubes OS Release X Signing Key"
|
||||||
|
@ -334,13 +335,14 @@ gpg: 2 good signatures
|
||||||
This is just an example, so the output you receive will not look exactly the
|
This is just an example, so the output you receive will not look exactly the
|
||||||
same. What matters is the line that shows that this key is signed by the Qubes
|
same. What matters is the line that shows that this key is signed by the Qubes
|
||||||
Master Signing Key with a `sig!` prefix. This verifies the authenticity of the
|
Master Signing Key with a `sig!` prefix. This verifies the authenticity of the
|
||||||
Release Signing Key. Note that the `!` flag after the `sig` tag is important
|
RSK. Note that the `!` flag after the `sig` tag is important because it means
|
||||||
because it means that the key signature is valid. A `sig-` prefix would
|
that the key signature is valid. A `sig-` prefix would indicate a bad signature
|
||||||
indicate a bad signature and `sig%` would mean that gpg encountered an error
|
and `sig%` would mean that gpg encountered an error while verifying the
|
||||||
while verifying the signature. It is not necessary to independently verify the
|
signature. It is not necessary to independently verify the authenticity of the
|
||||||
authenticity of the Release Signing Key, since you already verified the
|
RSK, since you already verified the authenticity of the QMSK.
|
||||||
authenticity of the Qubes Master Signing Key. Before proceeding to the next
|
|
||||||
step, make sure the Release Signing Key is in your keyring:
|
As a final sanity check, make sure the RSK is in your keyring with the correct
|
||||||
|
trust level:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ gpg2 -k "Qubes OS Release"
|
$ gpg2 -k "Qubes OS Release"
|
||||||
|
@ -349,49 +351,48 @@ pub rsa4096 2017-03-06 [SC]
|
||||||
uid [ full ] Qubes OS Release X Signing Key
|
uid [ full ] Qubes OS Release X Signing Key
|
||||||
```
|
```
|
||||||
|
|
||||||
If you don't see the correct Release Signing Key here, go back and follow the
|
If you don't see the correct RSK here with a trust level of "full" or higher,
|
||||||
instructions in this section carefully.
|
go back and follow the instructions in this section carefully, and consult the
|
||||||
|
[troubleshooting FAQ](#troubleshooting-faq) below.
|
||||||
|
|
||||||
### 3. Verify your Qubes ISO
|
### How to obtain and authenticate other signing keys
|
||||||
|
|
||||||
Every Qubes ISO is released with a detached PGP signature file, which you can
|
Please see the [Qubes security pack](/security/pack/) documentation.
|
||||||
find on the [Downloads](/downloads/) page alongside the ISO. If the filename of
|
|
||||||
your ISO is `Qubes-RX-x86_64.iso`, then the name of the signature file for that
|
|
||||||
ISO is `Qubes-RX-x86_64.iso.asc`, where `X` is a specific version of Qubes. The
|
|
||||||
signature filename is always the same as the ISO filename followed by `.asc`.
|
|
||||||
|
|
||||||
Download both the ISO and its signature file. Put both of them in the same
|
## How to verify the cryptographic hash values of Qubes ISOs
|
||||||
directory, then navigate to that directory. Now, you can verify the ISO by
|
|
||||||
executing this GPG command in the directory that contains both files:
|
|
||||||
|
|
||||||
```shell_session
|
There are two ways to verify Qubes ISO: cryptographic hash values and detached
|
||||||
$ gpg2 -v --verify Qubes-RX-x86_64.iso.asc Qubes-RX-x86_64.iso
|
PGP signatures. Both methods are equally secure. Using just one method is
|
||||||
gpg: armor header: Version: GnuPG v1
|
sufficient to verify your Qubes ISO. Using both methods is not necessary, but
|
||||||
gpg: Signature made Tue 08 Mar 2016 07:40:56 PM PST using RSA key ID 03FA5082
|
you can do so if you like. One method might be more convenient than another in
|
||||||
gpg: using PGP trust model
|
certain circumstances, so we provide both. This section covers cryptographic
|
||||||
gpg: Good signature from "Qubes OS Release X Signing Key"
|
hash values. For the other method, see [how to verify detached PGP signatures
|
||||||
gpg: binary signature, digest algorithm SHA256
|
on Qubes ISOs](#how-to-verify-detached-pgp-signatures-on-qubes-isos).
|
||||||
```
|
|
||||||
|
|
||||||
This is just an example, so the output you receive will not look exactly the
|
Before we proceed, you must first complete the following prerequisite steps:
|
||||||
same. What matters is the line that says `Good signature from "Qubes OS Release
|
|
||||||
X Signing Key"`. This confirms that the signature on the ISO is good.
|
|
||||||
|
|
||||||
## How to Verify Qubes ISO Digests
|
1. [Import and authenticate the Qubes Master Signing Key.](#how-to-import-and-authenticate-the-qubes-master-signing-key)
|
||||||
|
2. [Import and authenticate your release signing key.](#how-to-import-and-authenticate-release-signing-keys)
|
||||||
|
|
||||||
Each Qubes ISO is also accompanied by a plain text file ending in `.DIGESTS`.
|
Each Qubes ISO is accompanied by a set of **cyrptographic hash values**
|
||||||
This file contains the output of running several different cryptographic hash
|
contained in a plain text file ending in `.DIGESTS`, which can find on the
|
||||||
functions on the ISO in order to obtain alphanumeric outputs known as "digests"
|
[downloads](/downloads/) page alongside the ISO. This file contains the output
|
||||||
or "hash values." These hash values are provided as an alternative verification
|
of running several different cryptographic hash functions on the ISO (a process
|
||||||
method to PGP signatures (though the digest file is itself also PGP-signed ---
|
known as "hashing") in order to obtain alphanumeric outputs known as "hash
|
||||||
see below). If you've already verified the signatures on the ISO directly, then
|
values or "digests."
|
||||||
verifying digests is not necessary. You can find the `.DIGESTS` for your ISO on
|
|
||||||
the [Downloads](/downloads/) page, and you can always find all the digest files
|
One convenient property of hash values is that they can be generated on any
|
||||||
for every Qubes ISO in the [Qubes Security Pack](/security/pack/).
|
computer. This means, for example, that you can download a Qubes ISO on one
|
||||||
|
computer, hash it, then visually compare that hash value to one you generated
|
||||||
|
or have saved on a different computer.
|
||||||
|
|
||||||
|
In addition to the `.DIGESTS` files on the [downloads](/downloads/) page
|
||||||
|
alongside each ISO, and you can always find all the digest files for every
|
||||||
|
Qubes ISO in the [Qubes security pack](/security/pack/).
|
||||||
|
|
||||||
If the filename of your ISO is `Qubes-RX-x86_64.iso`, then the name of the
|
If the filename of your ISO is `Qubes-RX-x86_64.iso`, then the name of the
|
||||||
digest file for that ISO is `Qubes-RX-x86_64.iso.DIGESTS`, where `X` is a
|
digest file for that ISO is `Qubes-RX-x86_64.iso.DIGESTS`, where `X` is a
|
||||||
specific version of Qubes. The digest filename is always the same as the ISO
|
specific release of Qubes. The digest filename is always the same as the ISO
|
||||||
filename followed by `.DIGESTS`. Since the digest file is a plain text file,
|
filename followed by `.DIGESTS`. Since the digest file is a plain text file,
|
||||||
you can open it with any text editor. Inside, you should find text that looks
|
you can open it with any text editor. Inside, you should find text that looks
|
||||||
similar to this:
|
similar to this:
|
||||||
|
@ -424,9 +425,9 @@ g8JqGYYptgkxjQdX3YAy9VDsCJ/6EkFc2lkQHbgZxjXqyrEMbgeSXtMltZ7cCqw1
|
||||||
```
|
```
|
||||||
|
|
||||||
Four digests have been computed for this ISO. The hash functions used, in order
|
Four digests have been computed for this ISO. The hash functions used, in order
|
||||||
from top to bottom, are MD5, SHA1, SHA256, and SHA512. One way to verify that
|
from top to bottom, are MD5, SHA-1, SHA-256, and SHA-512. One way to verify
|
||||||
the ISO you downloaded matches any of these hash values is by using the
|
that the ISO you downloaded matches any of these hash values is by using the
|
||||||
respective `*sum` programs:
|
respective `*sum` command:
|
||||||
|
|
||||||
```shell_session
|
```shell_session
|
||||||
$ md5sum -c Qubes-RX-x86_64.iso.DIGESTS
|
$ md5sum -c Qubes-RX-x86_64.iso.DIGESTS
|
||||||
|
@ -474,51 +475,106 @@ Therefore, we should also verify the authenticity of the listed hash values.
|
||||||
Since `Qubes-RX-x86_64.iso.DIGESTS` is a clearsigned PGP file, we can use GPG
|
Since `Qubes-RX-x86_64.iso.DIGESTS` is a clearsigned PGP file, we can use GPG
|
||||||
to verify it from the command line:
|
to verify it from the command line:
|
||||||
|
|
||||||
1. [Get the Qubes Master Signing Key and verify its
|
1. [Import and authenticate the Qubes Master Signing Key.](#how-to-import-and-authenticate-the-qubes-master-signing-key)
|
||||||
authenticity](#1-get-the-qubes-master-signing-key-and-verify-its-authenticity)
|
2. [Import and authenticate your release signing key.](#how-to-import-and-authenticate-release-signing-keys)
|
||||||
2. [Get the Release Signing Key](#2-get-the-release-signing-key)
|
|
||||||
3. Verify the signature in the digest file:
|
3. Verify the signature in the digest file:
|
||||||
|
|
||||||
```shell_session
|
```shell_session
|
||||||
$ gpg2 -v --verify Qubes-RX-x86_64.iso.DIGESTS
|
$ gpg2 -v --verify Qubes-RX-x86_64.iso.DIGESTS
|
||||||
gpg: armor header: Hash: SHA256
|
gpg: armor header: Hash: SHA256
|
||||||
gpg: armor header: Version: GnuPG v2
|
gpg: armor header: Version: GnuPG v2
|
||||||
gpg: original file name=''
|
gpg: original file name=''
|
||||||
gpg: Signature made Tue 20 Sep 2016 10:37:03 AM PDT using RSA key ID 03FA5082
|
gpg: Signature made Tue 20 Sep 2016 10:37:03 AM PDT using RSA key ID 03FA5082
|
||||||
gpg: using PGP trust model
|
gpg: using PGP trust model
|
||||||
gpg: Good signature from "Qubes OS Release X Signing Key"
|
gpg: Good signature from "Qubes OS Release X Signing Key"
|
||||||
gpg: textmode signature, digest algorithm SHA256
|
gpg: textmode signature, digest algorithm SHA256
|
||||||
```
|
```
|
||||||
|
|
||||||
The signature is good. If our copy of the `Qubes OS Release X Signing Key` is
|
This is just an example, so the output you receive will not look exactly the
|
||||||
being validated by the authentic Qubes Master Signing Key (see
|
same. What matters is the line that says `Good signature from "Qubes OS Release
|
||||||
[above](#1-get-the-qubes-master-signing-key-and-verify-its-authenticity)), we
|
X Signing Key"`. This confirms that the signature on digest file is good.
|
||||||
can be confident that these hash values came from the Qubes devs.
|
|
||||||
|
|
||||||
## How to Verify Qubes Repos
|
If you don't see a good signature here, go back and follow the instructions in
|
||||||
|
this section carefully, and consult the [troubleshooting
|
||||||
|
FAQ](#troubleshooting-faq) below.
|
||||||
|
|
||||||
|
## How to verify detached PGP signatures on Qubes ISOs
|
||||||
|
|
||||||
|
There are two ways to verify Qubes ISO: cryptographic hash values and detached
|
||||||
|
PGP signatures. Both methods are equally secure. Using just one method is
|
||||||
|
sufficient to verify your Qubes ISO. Using both methods is not necessary, but
|
||||||
|
you can do so if you like. One method might be more convenient than another in
|
||||||
|
certain circumstances, so we provide both. This section covers detached PGP
|
||||||
|
signatures. For the other method, see [how to verify the cryptographic hash
|
||||||
|
values of Qubes
|
||||||
|
ISOs](#how-to-verify-the-cryptographic-hash-values-of-qubes-isos).
|
||||||
|
|
||||||
|
Before we proceed, you must first complete the following prerequisite steps:
|
||||||
|
|
||||||
|
1. [Import and authenticate the Qubes Master Signing Key.](#how-to-import-and-authenticate-the-qubes-master-signing-key)
|
||||||
|
2. [Import and authenticate your release signing key.](#how-to-import-and-authenticate-release-signing-keys)
|
||||||
|
|
||||||
|
Every Qubes ISO is released with a **detached PGP signature** file, which you
|
||||||
|
can find on the [downloads](/downloads/) page alongside the ISO. If the
|
||||||
|
filename of your ISO is `Qubes-RX-x86_64.iso`, then the name of the signature
|
||||||
|
file for that ISO is `Qubes-RX-x86_64.iso.asc`, where `X` is a specific release
|
||||||
|
of Qubes. The signature filename is always the same as the ISO filename
|
||||||
|
followed by `.asc`.
|
||||||
|
|
||||||
|
Download both the ISO and its signature file. Put both of them in the same
|
||||||
|
directory, then navigate to that directory. Now, you can verify the ISO by
|
||||||
|
executing this GPG command in the directory that contains both files:
|
||||||
|
|
||||||
|
```shell_session
|
||||||
|
$ gpg2 -v --verify Qubes-RX-x86_64.iso.asc Qubes-RX-x86_64.iso
|
||||||
|
gpg: armor header: Version: GnuPG v1
|
||||||
|
gpg: Signature made Tue 08 Mar 2016 07:40:56 PM PST using RSA key ID 03FA5082
|
||||||
|
gpg: using PGP trust model
|
||||||
|
gpg: Good signature from "Qubes OS Release X Signing Key"
|
||||||
|
gpg: binary signature, digest algorithm SHA256
|
||||||
|
```
|
||||||
|
|
||||||
|
This is just an example, so the output you receive will not look exactly the
|
||||||
|
same. What matters is the line that says `Good signature from "Qubes OS Release
|
||||||
|
X Signing Key"`. This confirms that the signature on the ISO is good.
|
||||||
|
|
||||||
|
If you don't see a good signature here, go back and follow the instructions in
|
||||||
|
this section carefully, and consult the [troubleshooting
|
||||||
|
FAQ](#troubleshooting-faq) below.
|
||||||
|
|
||||||
|
## How to verify signatures on Git repository tags and commits
|
||||||
|
|
||||||
Whenever you use one of the [Qubes repositories](https://github.com/QubesOS),
|
Whenever you use one of the [Qubes repositories](https://github.com/QubesOS),
|
||||||
you should use Git to verify the PGP signature in a tag on the latest commit or
|
you should use Git to verify the PGP signature in a tag on the latest commit or
|
||||||
on the latest commit itself. (One or both may be present, but only one is
|
on the latest commit itself. (One or both may be present, but only one is
|
||||||
required.) If there is no trusted signed tag or commit on top, any commits after
|
required.) If there is no trusted signed tag or commit on top, any commits
|
||||||
the latest trusted signed tag or commit should **not** be trusted. If you come
|
after the latest trusted signed tag or commit should **not** be trusted. If you
|
||||||
across a repo with any unsigned commits, you should not add any of your own
|
come across a repo with any unsigned commits, you should not add any of your
|
||||||
signed tags or commits on top of them unless you personally vouch for the
|
own signed tags or commits on top of them unless you personally vouch for the
|
||||||
trustworthiness of the unsigned commits. Instead, ask the person who pushed the
|
trustworthiness of the unsigned commits. Instead, ask the person who pushed the
|
||||||
unsigned commits to sign them.
|
unsigned commits to sign them.
|
||||||
|
|
||||||
You should always perform this verification on a trusted local machine with
|
You should always perform this verification on a trusted local machine with
|
||||||
properly validated keys (which are available in the [Qubes Security
|
properly authenticated keys rather than relying on a third party, such as
|
||||||
Pack](/security/pack/)) rather than relying on a third party, such as GitHub.
|
GitHub. While the GitHub interface may claim that a commit has a verified
|
||||||
While the GitHub interface may claim that a commit has a verified signature
|
signature from a member of the Qubes team, this is only trustworthy if GitHub
|
||||||
from a member of the Qubes team, this is only trustworthy if GitHub has
|
has performed the signature check correctly, the account identity is authentic,
|
||||||
performed the signature check correctly, the account identity is authentic, the
|
the user's key has not been replaced by an admin, GitHub's servers have not
|
||||||
user's key has not been replaced by an admin, GitHub's servers have not been
|
been compromised, and so on. Since there's no way for you to be certain that
|
||||||
compromised, and so on. Since there's no way for you to be certain that all
|
all such conditions hold, you're much better off verifying signatures yourself.
|
||||||
such conditions hold, you're much better off verifying signatures yourself.
|
(Also see: [distrusting the
|
||||||
|
infrastructure](/faq/#what-does-it-mean-to-distrust-the-infrastructure).)
|
||||||
|
|
||||||
Also see: [Distrusting the
|
Before we proceed, you must first complete the following prerequisite steps:
|
||||||
Infrastructure](/faq/#what-does-it-mean-to-distrust-the-infrastructure)
|
|
||||||
|
1. [Import and authenticate the Qubes Master Signing Key.](#how-to-import-and-authenticate-the-qubes-master-signing-key)
|
||||||
|
2. [Import and authenticate keys from the Qubes security pack (qubes-secpack)](/security/pack/)
|
||||||
|
|
||||||
|
**Note:** Only some keys in the qubes-secpack are signed by the QMSK. Keys that
|
||||||
|
are not signed directly by the QMSK are still signed indirectly by virtue of
|
||||||
|
being included in the qubes-secpack, which is itself signed (via Git tags
|
||||||
|
and/or commits) by keys that are in turn signed by the QMSK. If a key is not
|
||||||
|
signed directly by the QMSK, you may need to set its trust level directly.
|
||||||
|
|
||||||
To verify a signature on a Git tag:
|
To verify a signature on a Git tag:
|
||||||
|
|
||||||
|
@ -548,17 +604,18 @@ $ git verify-commit <commit ID>
|
||||||
|
|
||||||
### Why am I getting "Can't check signature: public key not found"?
|
### Why am I getting "Can't check signature: public key not found"?
|
||||||
|
|
||||||
You don't have the correct [Release Signing
|
You don't have the correct [release signing
|
||||||
Key](#2-get-the-release-signing-key).
|
key](#how-to-import-and-authenticate-release-signing-keys).
|
||||||
|
|
||||||
### Why am I getting "BAD signature from 'Qubes OS Release X Signing Key'"?
|
### Why am I getting "BAD signature from 'Qubes OS Release X Signing Key'"?
|
||||||
|
|
||||||
The problem could be one or more of the following:
|
The problem could be one or more of the following:
|
||||||
|
|
||||||
- You're trying to verify the wrong file(s). Read this page again carefully.
|
- You're trying to verify the wrong file(s). Read this page again carefully.
|
||||||
- You're using the wrong GPG command. Follow the examples in [Verify your Qubes
|
- You're using the wrong GPG command. Follow the provided examples carefully,
|
||||||
ISO](#3-verify-your-qubes-iso) carefully.
|
or try using `gpg` instead of `gpg2` (or vice versa).
|
||||||
- The ISO or [signature file](#3-verify-your-qubes-iso) is bad (e.g.,
|
- The ISO or [detached PGP signature
|
||||||
|
file](#how-to-verify-detached-pgp-signatures-on-qubes-isos) is bad (e.g.,
|
||||||
incomplete or corrupt download). Try downloading the signature file again
|
incomplete or corrupt download). Try downloading the signature file again
|
||||||
from a different source, then try verifying again. If you still get the same
|
from a different source, then try verifying again. If you still get the same
|
||||||
result, try downloading the ISO again from a different source, then try
|
result, try downloading the ISO again from a different source, then try
|
||||||
|
@ -567,7 +624,8 @@ The problem could be one or more of the following:
|
||||||
### Why am I getting "bash: gpg2: command not found"?
|
### Why am I getting "bash: gpg2: command not found"?
|
||||||
|
|
||||||
You don't have `gpg2` installed. Please install it using the method appropriate
|
You don't have `gpg2` installed. Please install it using the method appropriate
|
||||||
for your environment (e.g., via your package manager).
|
for your environment (e.g., via your package manager), or try using `gpg`
|
||||||
|
instead.
|
||||||
|
|
||||||
### Why am I getting "No such file or directory"?
|
### Why am I getting "No such file or directory"?
|
||||||
|
|
||||||
|
@ -575,38 +633,41 @@ Your working directory does not contain the required files. Go back and follow
|
||||||
the instructions more carefully, making sure that you put all required files in
|
the instructions more carefully, making sure that you put all required files in
|
||||||
the same directory *and* navigate to that directory.
|
the same directory *and* navigate to that directory.
|
||||||
|
|
||||||
### Why am I getting "can't open signed data `Qubes-RX-x86_64.iso' / can't hash datafile: file open error"?
|
### Why am I getting "can't open signed data 'Qubes-RX-x86\_64.iso' / can't hash datafile: file open error"?
|
||||||
|
|
||||||
The correct ISO is not in your working directory.
|
The correct ISO is not in your working directory.
|
||||||
|
|
||||||
### Why am I getting "can't open `Qubes-RX-x86_64.iso.asc' / verify signatures failed: file open error"?
|
### Why am I getting "can't open 'Qubes-RX-x86\_64.iso.asc' / verify signatures failed: file open error"?
|
||||||
|
|
||||||
The correct [signature file](#3-verify-your-qubes-iso) is not in your working
|
The correct [detached PGP signature
|
||||||
directory.
|
file](#how-to-verify-detached-pgp-signatures-on-qubes-isos) is not in your
|
||||||
|
working directory.
|
||||||
|
|
||||||
### Why am I getting "no valid OpenPGP data found"?
|
### Why am I getting "no valid OpenPGP data found"?
|
||||||
|
|
||||||
Either you don't have the correct [signature file](#3-verify-your-qubes-iso),
|
Either you don't have the correct [detached PGP signature
|
||||||
or you inverted the arguments to `gpg2`. ([The signature file goes
|
file](#how-to-verify-detached-pgp-signatures-on-qubes-isos), or you inverted
|
||||||
first.](#3-verify-your-qubes-iso))
|
the arguments to `gpg2`. (The signature file goes first.)
|
||||||
|
|
||||||
### Why am I getting "WARNING: This key is not certified with a trusted signature! There is no indication that the signature belongs to the owner."?
|
### Why am I getting "WARNING: This key is not certified with a trusted signature! There is no indication that the signature belongs to the owner."?
|
||||||
|
|
||||||
Several possibilities:
|
There are several possibilities:
|
||||||
* you don't have the [Qubes Master Signing
|
- You don't have the [Qubes Master Signing
|
||||||
Key](#1-get-the-qubes-master-signing-key-and-verify-its-authenticity)
|
Key](#how-to-import-and-authenticate-the-qubes-master-signing-key).
|
||||||
* you didn't [set its trust level
|
- [You have not set the Qubes Master Signing Key's trust level
|
||||||
correctly](#1-get-the-qubes-master-signing-key-and-verify-its-authenticity)
|
correctly.](#how-to-import-and-authenticate-the-qubes-master-signing-key)
|
||||||
* in the case of verifying a Git commit or tag, you haven't yet chosen to
|
- [In the case of a key that is not directly signed by the Qubes Master Signing
|
||||||
place ultimate PGP trust in the individual signer's key
|
Key, you have not set that key's trust level
|
||||||
|
correctly.](#how-to-verify-signatures-on-git-repository-tags-and-commits)
|
||||||
|
|
||||||
### Why am I getting "X signature not checked due to a missing key"?
|
### Why am I getting "X signature not checked due to a missing key"?
|
||||||
|
|
||||||
You don't have the keys that created those signatures in your keyring. For
|
You don't have the keys that created those signatures in your keyring. For the
|
||||||
present purposes, you don't need them as long as you have the [Qubes Master
|
purpose of verifying a Qubes ISO, you don't need them as long as you have the
|
||||||
Signing Key](#1-get-the-qubes-master-signing-key-and-verify-its-authenticity)
|
[Qubes Master Signing
|
||||||
and the [Release Signing Key](#2-get-the-release-signing-key) for your Qubes
|
Key](#how-to-import-and-authenticate-the-qubes-master-signing-key) and the
|
||||||
version.
|
[release signing key](#how-to-import-and-authenticate-release-signing-keys) for
|
||||||
|
your Qubes release.
|
||||||
|
|
||||||
### Why am I seeing additional signatures on a key with "[User ID not found]" or from a revoked key?
|
### Why am I seeing additional signatures on a key with "[User ID not found]" or from a revoked key?
|
||||||
|
|
||||||
|
@ -618,32 +679,33 @@ keys.
|
||||||
|
|
||||||
### Why am I getting "verify signatures failed: unexpected data"?
|
### Why am I getting "verify signatures failed: unexpected data"?
|
||||||
|
|
||||||
You're not verifying against the correct [signature
|
You're not verifying against the correct [detached PGP signature
|
||||||
file](#3-verify-your-qubes-iso).
|
file](#how-to-verify-detached-pgp-signatures-on-qubes-isos).
|
||||||
|
|
||||||
### Why am I getting "not a detached signature"?
|
### Why am I getting "not a detached signature"?
|
||||||
|
|
||||||
You're not verifying against the correct [signature
|
You're not verifying against the correct [detached PGP signature
|
||||||
file](#3-verify-your-qubes-iso).
|
file](#how-to-verify-detached-pgp-signatures-on-qubes-isos).
|
||||||
|
|
||||||
### Why am I getting "CRC error; [...] no signature found [...]"?
|
### Why am I getting "CRC error; [...] no signature found [...]"?
|
||||||
|
|
||||||
You're not verifying against the correct [signature
|
You're not verifying against the correct [detached PGP signature
|
||||||
file](#3-verify-your-qubes-iso), or the signature file has been modified. Try
|
file](#how-to-verify-detached-pgp-signatures-on-qubes-isos), or the signature
|
||||||
downloading it again or from a different source.
|
file has been modified. Try downloading it again or from a different source.
|
||||||
|
|
||||||
### Do I have to verify the ISO against both the [signature file](#3-verify-your-qubes-iso) and the [digest file](#how-to-verify-qubes-iso-digests)?
|
### Do I have to verify both the [detached PGP signature file](#how-to-verify-detached-pgp-signatures-on-qubes-isos) and the [cryptographic hash values](#how-to-verify-the-cryptographic-hash-values-of-qubes-isos)?
|
||||||
|
|
||||||
No, either method is sufficient by itself.
|
No, either method is sufficient by itself, but you can do both if you like.
|
||||||
|
|
||||||
### Why am I getting "no properly formatted X checksum lines found"?
|
### Why am I getting "no properly formatted X checksum lines found"?
|
||||||
|
|
||||||
You're not checking the correct [digest
|
You're not checking the correct [cryptographic hash
|
||||||
file](#how-to-verify-qubes-iso-digests).
|
values](#how-to-verify-the-cryptographic-hash-values-of-qubes-isos).
|
||||||
|
|
||||||
### Why am I getting "WARNING: X lines are improperly formatted"?
|
### Why am I getting "WARNING: X lines are improperly formatted"?
|
||||||
|
|
||||||
Read [How to Verify Qubes ISO Digests](#how-to-verify-qubes-iso-digests) again.
|
Read [how to verify the cryptographic hash values of Qubes
|
||||||
|
ISOs](#how-to-verify-the-cryptographic-hash-values-of-qubes-isos) again.
|
||||||
|
|
||||||
### Why am I getting "WARNING: 1 listed file could not be read"?
|
### Why am I getting "WARNING: 1 listed file could not be read"?
|
||||||
|
|
||||||
|
@ -653,11 +715,13 @@ The correct ISO is not in your working directory.
|
||||||
|
|
||||||
Carefully read this page again to be certain that you didn't skip any steps. In
|
Carefully read this page again to be certain that you didn't skip any steps. In
|
||||||
particular, make sure you have the [Qubes Master Signing
|
particular, make sure you have the [Qubes Master Signing
|
||||||
Key](#1-get-the-qubes-master-signing-key-and-verify-its-authenticity), the
|
Key](#how-to-import-and-authenticate-the-qubes-master-signing-key), the
|
||||||
[Release Signing Key](#2-get-the-release-signing-key), *and* the [signature
|
[release signing key](#how-to-import-and-authenticate-release-signing-keys) for
|
||||||
file](#3-verify-your-qubes-iso) and/or [digest
|
your Qubes release, *and* the [cryptographic hash
|
||||||
file](#how-to-verify-qubes-iso-digests) all for the *correct* Qubes OS version.
|
values](#how-to-verify-the-cryptographic-hash-values-of-qubes-isos) and/or
|
||||||
If your question is about GPG, please see the [GPG
|
[detached PGP signature
|
||||||
documentation](https://www.gnupg.org/documentation/). Still have question?
|
file](#how-to-verify-detached-pgp-signatures-on-qubes-isos), all for the
|
||||||
Please see [Help, Support, Mailing Lists, and Forum](/support/) for places
|
*correct* Qubes OS release. If your question is about GPG, please see the
|
||||||
where you can ask!
|
[GnuPG documentation](https://www.gnupg.org/documentation/). Still have
|
||||||
|
question? Please see [help, support, mailing lists, and forum](/support/) for
|
||||||
|
places where you can ask!
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue