diff --git a/kernel-developer-pgp-guide.md b/kernel-developer-pgp-guide.md deleted file mode 100644 index c3cc1e9..0000000 --- a/kernel-developer-pgp-guide.md +++ /dev/null @@ -1,921 +0,0 @@ -# Kernel developer PGP guide - -Updated: 2018-01-24 - -*Status: CURRENT, BETA* - -### Target audience - -This document is aimed at Linux kernel developers, and especially subsystem -maintainers. It contains a subset of information discussed in the more -general "Protecting Code Integrity" guide found in the same repository. If you -are not a Linux kernel developer, you should read the more general guide -instead. - -This document covers the following topics: - -1. How to improve your PGP key security -2. When and how to use PGP with git -3. How to verify fellow kernel developer identities - -### Structure - -Each section is split into two areas: - -- A checklist of actionable items -- Free-form list of considerations that explain what dictated these decisions, - together with configuration instructions - -#### Checklist priority levels - -The items in each checklist include the priority level, which we hope will -help guide your decision: - -- _(ESSENTIAL)_ items should definitely be high on the consideration list. -- _(NICE)_ to have items will improve the overall security, but will affect how - you interact with your work environment, and probably require learning new - habits or unlearning old ones. - -Remember, these are only guidelines. If you feel these priority levels do not -reflect your commitment to security, you should adjust them as you see fit. - -## The role of PGP in Linux Kernel development - -PGP helps ensure the integrity of the code that is produced by the Linux -Kernel development community and, to a lesser degree, establish trusted -communication channels between developers via PGP-signed email exchange. - -The Linux Kernel source code is available in two main formats: - -- Distributed source repositories (git) -- Periodic release snapshots (tarballs) - -Both git repositories and tarballs carry PGP signatures of the kernel -developers who create official kernel releases. These signatures offer a -cryptographic guarantee that downloadable versions made available via -kernel.org or any other mirrors are identical to what these developers have on -their workstations. To this end: - -- git repositories provide PGP signatures on all tags -- tarballs provide detached PGP signatures with all downloads - -### Trusting the developers, not infrastructure - -Ever since the 2011 compromise of core kernel.org systems, the main operating -principle of the Kernel Archives project has been to assume that any part of -the infrastructure can be compromised at any time. For this reason, the -administrators have taken deliberate steps to emphasize that trust must always -be placed with developers and never with the code hosting infrastructure, -regardless of how good the security practices for the latter may be. - -The above guiding principle is the reason why this guide is needed. We want to -make sure that by placing trust into developers we do not simply shift the -blame for potential future security incidents to someone else. The goal is to -provide a set of guidelines developers can use to create a secure working -environment and safeguard the PGP keys used to establish the integrity of the -Linux Kernel itself. - -## PGP tools - -### Checklist - -- [ ] Make sure you use GnuPG version 2 _(ESSENTIAL)_ -- [ ] Configure gpg-agent _(ESSENTIAL)_ -- [ ] Set up a refresh cronjob _(ESSENTIAL)_ - -### Considerations - -### Installing GnuPG - -Your distro should already have GnuPG installed by default, you just need to -verify that you are using version 2.x and not the legacy 1.4 release -- -many distributions still package both, with the default `gpg` command invoking -GnuPG v.1. To check, run: - - $ gpg --version | head -n1 - -If you see `gpg (GnuPG) 1.4.x`, then you are using GnuPG v.1. Try the `gpg2` -command (if you don't have it, you may need to install the gnupg2 package): - - $ gpg2 --version | head -n1 - -If you see `gpg (GnuPG) 2.x.x`, then you are good to go. This guide will -assume you have the version 2.2 of GnuPG (or later). If you are using version -2.0 of GnuPG, then some of the commands in this guide will not work, and you -should consider installing the latest 2.2 version of GnuPG. Versions of -gnupg-2.1.11 and later should be compatible for the purposes of this guide as -well. - -##### Making sure you always use GnuPG v.2 - -If you have both `gpg` and `gpg2` commands, you should make sure you are -always using GnuPG v2, not the legacy version. You can enforce this by setting -the appropriate alias: - - $ alias gpg=gpg2 - -You can put that in your `.bashrc` to make sure it's always the case. - -#### Configure gpg-agent options - -The GnuPG agent is a helper tool that will start automatically whenever you -use the `gpg` command and run in the background with the purpose of caching -the private key passphrase. It is no longer necessary to start it manually -at the beginning of your shell session. - -There are two options you should know in order to tweak when the passphrase -should be expired from cache: - -- `default-cache-ttl` (seconds): If you use the same key again before the - time-to-live expires, the countdown will reset for another period. - The default is 600 (10 minutes). -- `max-cache-ttl` (seconds): Regardless of how recently you've used the key - since initial passphrase entry, if the maximum time-to-live countdown - expires, you'll have to enter the passphrase again. The default is 30 - minutes. - -If you find either of these defaults too short (or too long), you can edit -your `~/.gnupg/gpg-agent.conf` file to set your own values: - - # set to 30 minutes for regular ttl, and 2 hours for max ttl - default-cache-ttl 1800 - max-cache-ttl 7200 - -#### Set up a refresh cronjob - -You will need to regularly refresh your keyring in order to get the latest -changes on other people's public keys, which is best done with a daily -cronjob: - - $ crontab -e - -Add the following on a new line: - - @daily /usr/bin/gpg2 --refresh >/dev/null 2>&1 - -**NOTE**: check the full path to your `gpg` or `gpg2` command and use the `gpg2` -command if regular `gpg` for you is the legacy GnuPG v.1. - -## Protecting your master PGP key - -### Checklist - -- [ ] Understand the "master" key vs. subkeys _(ESSENTIAL)_ -- [ ] Ensure your private key passphrase is strong _(ESSENTIAL)_ -- [ ] Create a separate **[S]** subkey _(ESSENTIAL)_ -- [ ] Back up the master key using paperkey _(ESSENTIAL)_ -- [ ] Back up your whole `.gnupg` directory to encrypted media _(ESSENTIAL)_ -- [ ] Remove the master key from your homedir _(ESSENTIAL)_ - -### Considerations - -This guide assumes that you already have a PGP key that you use for Linux -Kernel development purposes. If you do not yet have one, please see the -"Protecting Code Integrity" document in this repository for guidance on how to -create a new one. - -You should also make a new key if your current one is weaker than 2048 bits -(RSA). - -#### Understanding the "Master" (Certify) key - -In this and next section we'll talk about the "master key" and "subkeys". It -is important to understand the following: - -1. There are no technical differences between the "master key" and "subkeys." -2. At creation time, we assign functional limitations to each key by - giving it specific capabilities. -3. A PGP key can have 4 capabilities. - - **[S]** key can be used for signing - - **[E]** key can be used for encryption - - **[A]** key can be used for authentication - - **[C]** key can be used for certifying other keys -4. A single key may have multiple capabilities. - -The key carrying the **[C]** (certify) capability is considered the "master" -key because it is the only key that can be used to indicate relationship with -other keys. Only the **[C]** key can be used to: - -- add or revoke other keys (subkeys) with S/E/A capabilities -- add, change or revoke identities (uids) associated with the key -- add or change the expiration date on itself or any subkey -- sign other people's keys for the web of trust purposes - -By default, GnuPG creates the following when generating new keys: - -- A master key carrying both Certify and Sign capabilities (**[SC]**) -- A separate subkey with the Encryption capability (**[E]**) - -If you used the default parameters when generating your key, then that is what -you will have. You can verify by running `gpg --list-secret-keys`, for -example: - - sec rsa2048 2018-01-23 [SC] [expires: 2020-01-23] - 000000000000000000000000AAAABBBBCCCCDDDD - uid [ultimate] Alice Dev - ssb rsa2048 2018-01-23 [E] [expires: 2020-01-23] - -Any key carrying the **[C]** capability is your master key, regardless of any -other capabilities it may have assigned to it. - -The long line under the `sec` entry is your key fingerprint -- whenever you -see `[fpr]` in the examples below, that 40-character string is what it refers -to. - -#### Ensure your passphrase is strong - -GnuPG uses passphrases to encrypt your private keys before storing them on -disk. This way, even if your `.gnupg` directory is leaked or stolen in its -entirety, the attackers cannot use your private keys without first obtaining -the passphrase to decrypt them. - -It is absolutely essential that your private keys are protected by a -strong passphrase. To set it or change it, use: - - $ gpg --change-passphrase [fpr] - -#### Create a separate Signing subkey - -Our goal is to protect your master key by moving it to offline media, so -if you only have a combined **[SC]** key, then you should create a separate -signing subkey. - -##### RSA vs. ECC subkeys - -GnuPG 2.1 and later has full support for Elliptic Curve Cryptography, with -ability to combine ECC subkeys with traditional RSA master keys. The main -upside of ECC cryptography is that it is much faster computationally and -creates much smaller signatures when compared byte for byte with 2048+ bit RSA -keys. - -Unless you plan on using a smartcard device that does not support ECC -operations, we recommend that you create an ECC signing subkey for your kernel -work: - - $ gpg --quick-add-key [fpr] ed25519 sign - -If for some reason you prefer to stay with RSA subkeys, just replace "ed25519" -with "rsa2048" in the above command. - -Remember to tell the keyservers about this change, so others can pull down -your new subkey: - - $ gpg --send-key [fpr] - -#### Back up your master key for disaster recovery - -The more signatures you have on your PGP key from other developers, the more -reasons you have to create a backup version that lives on something other than -digital media, for disaster recovery reasons. - -The best way to create a printable hardcopy of your private key is by using -the `paperkey` software written for this very purpose. See `man paperkey` for -more details on the output format and its benefits over other solutions. -Paperkey should already be packaged for most distributions. - -Run the following command to create a hardcopy backup of your private key: - - $ gpg --export-secret-key [fpr] | paperkey > /tmp/key-backup.txt - -Print out that file (or pipe the output straight to lpr), then take a pen and -write your passphrase on the margin of the paper. **This is strongly -recommended** because the key printout is still encrypted with that -passphrase, and if you ever change it you will not remember what it used to be -when you had created the backup -- *guaranteed*. - -Put the resulting printout and the hand-written passphrase into an envelope -and store in a secure and well-protected place, preferably away from your -home, such as your bank vault. - -**NOTE ON PRINTERS**: Your printer is probably no longer a simple dumb device -connected to your parallel port, but since the output is still encrypted with -your passphrase, printing out even to "cloud-integrated" modern printers -should remain a relatively safe operation. One option is to change the -passphrase on your master key immediately after you are done with paperkey. - -#### Back up your whole GnuPG directory - -**!!!Do not skip this step!!!** - -It is important to have a readily available backup of your PGP keys should you -need to recover them (this is different from the disaster-level preparedness -we did with `paperkey`). You will also rely on these external copies whenever -you need to use your Certify key -- such as when making changes to your own -key or signing other people's keys after conferences and meetups. - -##### Prepare detachable encrypted storage - -Start by getting a small USB "thumb" drive (preferably two!) that you will use -for backup purposes. You will need to encrypt them before using them for our -purposes: - -- [Ubuntu instructions](https://help.ubuntu.com/community/EncryptedFilesystemsOnRemovableStorage) - -For the encryption passphrase, you can use the same one as on your master key. - -##### Back up your GnuPG directory - -Once the encryption process is over, re-insert the USB drive and make sure it -gets properly mounted. Find out the full mount point of the device, for -example by running the `mount` command (under Linux, external media usually -gets mounted under `/media/disk`). - -Once you know the full mount path, copy your entire GnuPG directory there: - - $ cp -a ~/.gnupg [/media/disk/name]/gnupg-backup - -(Note: If you get any `Operation not supported on socket` errors, those are -benign and you can ignore them.) - -You should now test to make sure everything still works: - - $ gpg --homedir=[/media/disk/name]/gnupg-backup --list-key [fpr] - -If you don't get any errors, then you should be good to go. Unmount the USB -drive, distinctly label it so you don't blow it away next time you need to use -a random USB drive, and put in a safe place -- but not too far away, because -you'll need to use it every now and again for things like editing identities, -adding or revoking subkeys, or signing other people's keys. - -#### Remove the master key from your homedir - -The files in our home directory are not as well protected as we like to think. -They can be leaked or stolen via many different means: - -- by accident when making quick homedir copies to set up a new workstation -- by systems administrator negligence or malice -- via poorly secured backups -- via malware in desktop apps (browsers, pdf viewers, etc) -- via coercion when crossing international borders - -Protecting your key with a good passphrase greatly helps reduce the risk of -any of the above, but passphrases can be discovered via keyloggers, -shoulder-surfing, or any number of other means. For this reason, the -recommended setup is to remove your master key from your home directory and -store it on offline storage. - -##### Removing your master key - -Please see the previous section and make sure you have backed up your GnuPG -directory in its entirety. What we are about to do will render your key -useless if you do not have a usable backup! - -First, identify the keygrip of your master key: - - $ gpg --with-keygrip --list-key [fpr] - -The output will be something like this: - - pub rsa2048 2018-01-24 [SC] [expires: 2020-01-24] - 000000000000000000000000AAAABBBBCCCCDDDD - Keygrip = 1111000000000000000000000000000000000000 - uid [ultimate] Alice Dev - sub rsa2048 2018-01-24 [E] [expires: 2020-01-24] - Keygrip = 2222000000000000000000000000000000000000 - sub ed25519 2018-01-24 [S] - Keygrip = 3333000000000000000000000000000000000000 - -Find the keygrip entry that is beneath the `pub` line (right under the master -key fingerprint). This will correspond directly to a file in your `~/.gnupg` -directory: - - $ cd ~/.gnupg/private-keys-v1.d - $ ls - 1111000000000000000000000000000000000000.key - 2222000000000000000000000000000000000000.key - 3333000000000000000000000000000000000000.key - -All you have to do is simply remove the `.key` file that corresponds to the -master keygrip: - - $ cd ~/.gnupg/private-keys-v1.d - $ rm 1111000000000000000000000000000000000000.key - -Now, if you issue the `--list-secret-keys` command, it will show that the -master key is missing (the `#` indicates it is not available): - - $ gpg --list-secret-keys - sec# rsa2048 2018-01-24 [SC] [expires: 2020-01-24] - 000000000000000000000000AAAABBBBCCCCDDDD - uid [ultimate] Alice Dev - ssb rsa2048 2018-01-24 [E] [expires: 2020-01-24] - ssb ed25519 2018-01-24 [S] - -You should also remove any `secring.gpg` files in the `~/.gnupg` directory, -which are left over from earlier versions of GnuPG. - -##### If you don't have the "private-keys-v1.d" directory - -If you do not have a `~/.gnupg/private-keys-v1.d` directory, then your -secret keys are still stored in the legacy `secring.gpg` file used by GnuPG -v1. Making any changes to your key, such as changing the passphrase or adding -a subkey, should automatically convert the old `secring.gpg` format to use -`private-keys-v1.d` instead. - -Once you get that done, make sure to delete the obsolete `secring.gpg` file, -which still contains your private keys. - -## Move the subkeys to a dedicated crypto device - -### Checklist - -- [ ] Get a GnuPG-compatible hardware device _(NICE)_ -- [ ] Configure the device to work with GnuPG _(NICE)_ -- [ ] Set the user and admin PINs _(NICE)_ -- [ ] Move your subkeys to the device _(NICE)_ - -### Considerations - -Even though the master key is now safe from being leaked or stolen, the -subkeys are still in your home directory. Anyone who manages to get their -hands on those will be able to decrypt your communication or fake your -signatures (if they know the passphrase). Furthermore, each time a GnuPG -operation is performed, the keys are loaded into system memory and can be -stolen from there by sufficiently advanced malware (think Meltdown and -Spectre). - -The best way to completely protect your keys is to move them to a specialized -hardware device that is capable of smartcard operations. - -#### The benefits of smartcards - -A smartcard contains a cryptographic chip that is capable of storing private -keys and performing crypto operations directly on the card itself. Because the -key contents never leave the smartcard, the operating system of the computer -into which you plug in the hardware device is not able to retrieve the -private keys themselves. This is very different from the encrypted USB storage -device we used earlier for backup purposes -- while that USB device is plugged -in and mounted, the operating system is able to access the private key -contents. - -Using external encrypted USB media is not a substitute to having a -smartcard-capable device. - -#### Available smartcard devices - -Unless all your laptops and workstations have smartcard readers, the easiest -is to get a specialized USB device that implements smartcard functionality. -There are several options available: - -- [Nitrokey Start](https://shop.nitrokey.com/shop/product/nitrokey-start-6): - Open hardware and Free Software, based on FSI Japan's - [Gnuk](http://www.fsij.org/doc-gnuk/). Offers support for ECC keys, - but fewest security features (such as resistance to tampering or some - side-channel attacks). -- [Nitrokey Pro](https://shop.nitrokey.com/shop/product/nitrokey-pro-3): - Similar to the Nitrokey Start, but more tamper-resistant and offers more - security features, but no ECC support. -- [Yubikey 4](https://www.yubico.com/product/yubikey-4-series/): Proprietary - hardware and software, but cheaper than Nitrokey Pro and comes available in - the USB-C form that is more useful with newer laptops. Offers - additional security features such as FIDO U2F, but no ECC. - -[LWN has a good review](https://lwn.net/Articles/736231/) of some of the above -models, as well as several others. If you want to use ECC keys, your best bet -among commercially available devices is the Nitrokey Start. - -#### Configuring your smartcard device - -Your smartcard device should Just Work (TM) the moment you plug it into any -modern Linux workstation. You can verify it by running: - - $ gpg --card-status - -If you see full smartcard details, then you are good to go. Unfortunately, -troubleshooting all possible reasons why things may not be working for you is -way beyond the scope of this guide. If you are having trouble getting the card -to work with GnuPG, please seek help via usual support channels. - -##### Quick setup - -To configure your smartcard, you will need to use the GnuPG menu system, as -there are no convenient command-line switches: - - $ gpg --card-edit - [...omitted...] - gpg/card> admin - Admin commands are allowed - gpg/card> passwd - -You should set the user PIN (1), Admin PIN (3), and the Reset Code (4). Please -make sure to record and store these in a safe place -- especially the Admin -PIN and the Reset Code (which allows you to completely wipe the smartcard). -You so rarely need to use the Admin PIN, that you will inevitably forget what -it is if you do not record it. - -Getting back to the main card menu, you can also set other values (such as -name, sex, login data, etc), but it's not necessary and will additionally leak -information about your smartcard should you lose it. - -##### PINs don't have to be numbers - -Note, that despite having the name "PIN" (and implying that it must be a -"number"), neither the user PIN nor the admin PIN on the card need to be -numbers. - -#### Moving the subkeys to your smartcard - -Exit the card menu (using "q") and save all changes. Next, let's move your -subkeys onto the smartcard. You will need both your PGP key passphrase and the -admin PIN of the card for most operations. - - $ gpg --edit-key [fpr] - - Secret subkeys are available. - - pub rsa2048/AAAABBBBCCCCDDDD - created: 2018-01-23 expires: 2020-01-23 usage: SC - trust: ultimate validity: ultimate - ssb rsa2048/1111222233334444 - created: 2018-01-23 expires: never usage: E - ssb ed25519/5555666677778888 - created: 2017-12-07 expires: never usage: S - [ultimate] (1). Alice Dev - - gpg> - -Using `--edit-key` puts us into the menu mode again, and you will notice that -the key listing is a little different. From here on, all commands are done -from inside this menu mode, as indicated by `gpg>`. - -First, let's select the key we'll be putting onto the card -- you do this by -typing `key 1` (it's the first one in the listing, the **[E]** subkey): - - gpg> key 1 - -In the output, you should now see `ssb*` on the **[E]** key. The `*` indicates -which key is currently "selected." It works as a *toggle*, meaning that if you -type `key 1` again, the `*` will disappear and the key will not be selected -any more. - -Now, let's move that key onto the smartcard: - - gpg> keytocard - Please select where to store the key: - (2) Encryption key - Your selection? 2 - -Since it's our **[E]** key, it makes sense to put it into the Encryption slot. -When you submit your selection, you will be prompted first for your PGP key -passphrase, and then for the admin PIN. If the command returns without an -error, your key has been moved. - -**Important**: Now type `key 1` again to unselect the first key, and `key 2` -to select the **[S]** key: - - gpg> key 1 - gpg> key 2 - gpg> keytocard - Please select where to store the key: - (1) Signature key - (3) Authentication key - Your selection? 1 - -You can use the **[S]** key both for Signature and Authentication, but we want -to make sure it's in the Signature slot, so choose (1). Once again, if your -command returns without an error, then the operation was successful. - - gpg> q - Save changes? (y/N) y - -Saving the changes will delete the keys you moved to the card from your home -directory (but it's okay, because we have them in our backups should we need -to do this again for a replacement smartcard). - -##### Verifying that the keys were moved - -If you perform `--list-secret-keys` now, you will see a subtle difference in -the output: - - $ gpg --list-secret-keys - sec# rsa2048 2018-01-24 [SC] [expires: 2020-01-24] - 000000000000000000000000AAAABBBBCCCCDDDD - uid [ultimate] Alice Dev - ssb> rsa2048 2018-01-24 [E] [expires: 2020-01-24] - ssb> ed25519 2018-01-24 [S] - -The `>` in the `ssb>` output indicates that the subkey is only available on -the smartcard. If you go back into your secret keys directory and look at the -contents there, you will notice that the `.key` files there have been replaced -with stubs: - - $ cd ~/.gnupg/private-keys-v1.d - $ strings *.key | grep 'private-key' - -The output should contain `shadowed-private-key` to indicate that these files -are only stubs and the actual content is on the smartcard. - -#### Verifying that the smartcard is functioning - -To verify that the smartcard is working as intended, you can create a -signature: - - $ echo "Hello world" | gpg --clearsign > /tmp/test.asc - $ gpg --verify /tmp/test.asc - -This should ask for your smartcard PIN on your first command, and then show -"Good signature" after you run `gpg --verify`. - -Congratulations, you have successfully made it extremely difficult to steal -your digital developer identity! - -### Other common GnuPG operations - -Here is a quick reference for some common operations you'll need to do with -your PGP key. - -#### Mounting your master key offline storage - -You will need your master key for any of the operations below, so you will -first need to mount your backup offline storage and tell GnuPG to use it. - - $ export GNUPGHOME=/media/disk/name/gnupg-backup - $ gpg --list-secret-keys - -You want to make sure that you see `sec` and not `sec#` in the output (the `#` -means the key is not available and you're still using your regular home -directory location). - -##### Updating your regular GnuPG working directory - -After you make any changes to your key using the offline storage, you will -want to import these changes back into your regular working directory: - - $ gpg --export | gpg --homedir ~/.gnupg --import - $ unset GNUPGHOME - -#### Extending key expiration date - -The master key has the default expiration date of 2 years from the date of -creation. This is done both for security reasons and to make obsolete keys -eventually disappear from keyservers. - -To extend the expiration on your key by a year from current date, just run: - - $ gpg --quick-set-expire [fpr] 1y - -You can also use a specific date if that is easier to remember (e.g. your -birthday, January 1st, or Canada Day): - - $ gpg --quick-set-expire [fpr] 2020-07-01 - -Remember to send the updated key back to keyservers: - - $ gpg --send-key [fpr] - -## Using PGP with Git - -One of the core features of Git is its decentralized nature -- once a -repository is cloned to your system, you have full history of the project, -including all of its tags, commits and branches. However, with hundreds of -cloned repositories floating around, how does anyone verify that their copy of -linux.git has not been tampered with by a malicious third party? - -Or what happens if a backdoor is discovered in the code and the "Author" line -in the commit says it was done by you, while you're pretty sure you had -[nothing to do with it](https://github.com/jayphelps/git-blame-someone-else)? - -To address both of these issues, Git introduced PGP integration. Signed tags -prove the repository integrity by assuring that its contents are exactly the -same as on the workstation of the developer who created the tag, while signed -commits make it nearly impossible for someone to impersonate you without -having access to your PGP keys. - -### Checklist - -- [ ] Configure git to use your key _(ESSENTIAL)_ -- [ ] Configure git to always sign annotated tags _(NICE)_ -- [ ] Decide if you're going to use commit signing _(NICE)_ - -### Considerations - -#### Configure git to use your PGP key - -If you only have one secret key in your keyring, then you don't really need to -do anything extra, as it becomes your default key. - -However, if you happen to have multiple secret keys, you can tell git which -key should be used (`[fpr]` is the fingerprint of your key): - - $ git config --global user.signingKey [fpr] - -**IMPORTANT**: If you have a distinct `gpg2` command, then you should tell git -to always use it instead of the legacy `gpg` from version 1: - - $ git config --global gpg.program gpg2 - -#### How to work with signed tags - -To create a signed tag, simply pass the `-s` switch to the tag command: - - $ git tag -s [tagname] - -Our recommendation is to always sign git tags, as this allows other developers -to ensure that the git repository they are pulling from has not been -maliciously altered. - -##### How to verify signed tags - -To verify a signed tag, simply use the `verify-tag` command: - - $ git verify-tag [tagname] - -If you are verifying someone else's git tag, then you will need to import -their PGP key. Please refer to the "how to verify kernel developer identities" -section below. - -##### Verifying at pull time - -If you are pulling a tag from another fork of the project repository, git -should automatically verify the signature at the tip you're pulling and show -you the results during the merge operation: - - $ git pull [url] tags/sometag - -The merge message will contain something like this: - - Merge tag 'sometag' of [url] - - [Tag message] - - # gpg: Signature made [...] - # gpg: Good signature from [...] - -#### Configure git to always sign annotated tags - -Chances are, if you're creating an annotated tag, you'll want to sign it. To -force git to always sign annotated tags, you can set a global configuration -option: - - $ git config --global tag.forceSignAnnotated true - -Alternatively, you can just train your muscle memory to always pass the `-s` -switch: - - $ git tag -asm "Tag message" tagname - -#### How to work with signed commits - -It is easy to create signed commits, but it is much more difficult to -use them in Linux Kernel development, since it relies on patches sent to -the mailing list, and this workflow does not preserve PGP commit signatures. - -If you have your working git tree publicly available at some git hosting -service (kernel.org, infradead.org, ozlabs.org, or others), then the -recommendation is that you sign all your git commits even if upstream -developers do not directly benefit from this practice. Should there ever be a -need to perform code forensics or track code provenance, even externally -maintained trees carrying PGP commit signatures will be extremely valuable for -such purposes. - -##### Creating signed commits - -To create a signed commit, you just need to pass the `-S` flag to the `git -commit` command (it's capital `-S` due to collision with another flag): - - $ git commit -S - -#### Configure git to always sign commits - -You can tell git to always sign commits: - - git config --global commit.gpgSign true - -Or you can train your muscle memory to always pass the `-S` flag to all `git -commit` operations (this includes `--amend`). - -## How to verify kernel developer identities - -Signing tags and commits is easy, but how does one go about verifying that the -key used to sign something belongs to the actual kernel developer and not to -a malicious imposter? - -### Checklist - -- [ ] Configure auto-key-retrieval using WKD and DANE _(ESSENTIAL)_ -- [ ] Configure trust-model to `tofu+pgp` _(ESSENTIAL)_ -- [ ] Learn how to use keyservers (more) safely _(ESSENTIAL)_ - -### Considerations - -#### Configure auto-key-retrieval using WKD and DANE - -If you are not already someone with an extensive collection of other -developers' public keys, then you can jumpstart your keyring by relying -on key auto-discovery and auto-retrieval. GnuPG can piggyback on other -delegated trust technologies, namely DNSSEC and TLS, to get you going if the -prospect of starting your own Web of Trust from scratch is too daunting. - -Add the following to your `~/.gnupg/gpg.conf`: - - auto-key-locate wkd,dane,local - auto-key-retrieve - -DNS-Based Authentication of Named Entities ("DANE") is a method for publishing -public keys in DNS and securing them using DNSSEC signed zones. Web Key -Directory ("WKD") is the alternative method that uses https lookups for the -same purpose. When using either DANE or WKD for looking up public keys, GnuPG -will validate DNSSEC or TLS certificates, respectively, before adding -auto-retrieved public keys to your local keyring. - -Kernel.org publishes the WKD for all developers who have kernel.org accounts. -Once you have the above changes in your `gpg.conf`, you can auto-retrieve the -keys for Linus Torvalds and Greg Kroah-Hartman (if you don't already have -them): - - $ gpg --locate-keys torvalds@kernel.org gregkh@kernel.org - -If you have a kernel.org account, then you should make sure that you have -[added the kernel.org UID to your key](https://korg.wiki.kernel.org/userdoc/mail#adding_a_kernelorg_uid_to_your_pgp_key) -to make WKD more useful to other kernel developers. - -#### Web of Trust (WOT) vs. Trust on First Use (TOFU) - -PGP incorporates a trust delegation mechanism known as the "Web of Trust." At -its core, this is an attempt to replace the need for centralized Certification -Authorities of the HTTPS/TLS world. Instead of various software makers -dictating who should be your trusted certifying entity, PGP leaves this -responsibility to each user. - -Unfortunately, very few people understand how the Web of Trust works. While -it remains an important aspect of the OpenPGP specification, recent -versions of GnuPG (2.2 and above) have implemented an alternative mechanism -called "Trust on First Use" (TOFU). - -You can think of TOFU as "the SSH-like approach to trust." With SSH, the first -time you connect to a remote system, its key fingerprint is recorded and -remembered. If the key changes in the future, the SSH client will alert you -and refuse to connect, forcing you to make a decision on whether you choose to -trust the changed key or not. - -Similarly, the first time you import someone's PGP key, it is assumed to be -valid. If at any point in the future GnuPG comes across another key with the -same identity, both the previously imported key and the new key will be marked -as invalid and you will need to manually figure out which one to keep. - -We recommend that you use the combined TOFU+PGP trust model (which is the new -default in GnuPG v2). To set it, add (or modify) the `trust-model` setting in -`~/.gnupg/gpg.conf`: - - trust-model tofu+pgp - -#### Learn to use keyservers (more) safely - -If, despite setting `auto-key-retrieve`, you still get a "No public key" error -when trying to validate someone's tag, then you should attempt to lookup that -key using a keyserver. It is important to keep in mind that there is -absolutely no guarantee that the key you retrieve from a keyserver belongs to -the actual person -- that much is by design. You are supposed to use the Web -of Trust to establish key validity. - -How to properly maintain the Web of Trust is beyond the scope of this -document, simply because doing it properly requires both effort and dedication -that tends to be beyond the caring threshold of most human beings. Here are -some shortcuts that will help you reduce the risk of importing a malicious -key. - -First, let's say you've tried to run `git verify-tag` but it returned an error -saying the key is not found: - - $ git verify-tag sunxi-fixes-for-4.15-2 - gpg: Signature made Sun 07 Jan 2018 10:51:55 PM EST - gpg: using RSA key DA73759BF8619E484E5A3B47389A54219C0F2430 - gpg: issuer "wens@...org" - gpg: Can't check signature: No public key - -Let's query the keyserver for more info about that key fingerprint (the -fingerprint probably belongs to a subkey, so we can't use it directly without -finding out the ID of the master key it is associated with): - - $ gpg --search DA73759BF8619E484E5A3B47389A54219C0F2430 - gpg: data source: hkp://keys.gnupg.net - (1) Chen-Yu Tsai - 4096 bit RSA key C94035C21B4F2AEB, created: 2017-03-14, expires: 2019-03-15 - Keys 1-1 of 1 for "DA73759BF8619E484E5A3B47389A54219C0F2430". Enter number(s), N)ext, or Q)uit > q - -Locate the ID of the master key in the output, in our example -`C94035C21B4F2AEB`. Now say `q` and display the key of Linus Torvalds that you -have on your keyring: - - $ git --list-key torvalds@kernel.org - pub rsa2048 2011-09-20 [SC] - ABAF11C65A2970B130ABE3C479BE3E4300411886 - uid [ unknown] Linus Torvalds - sub rsa2048 2011-09-20 [E] - -Next, open the [PGP pathfinder](https://pgp.cs.uu.nl/). In the "From" field, -paste the key fingerprint of Linus Torvalds from the output above. In the "To" -field, paste they key-id you found via `gpg --search` of the unknown key, and -check the results: - -- [From Linus to Chen-Yu](https://pgp.cs.uu.nl/paths/79BE3E4300411886/to/C94035C21B4F2AEB.html) - -If you get a few decent trust paths, then it's a pretty good indication that -it is a valid key. You can add it to your keyring from the keyserver now: - - $ gpg --recv-key C94035C21B4F2AEB - -This process is not perfect, and you are obviously trusting the administrators -of the PGP Pathfinder service to not be malicious. However, if you do not -carefully maintain your own web of trust, then it is an improvement over -blindly trusting keyservers.