sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget0/translations/zh_CN/process/maintainer-pgp-guidemodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget0/translations/zh_TW/process/maintainer-pgp-guidemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget0/translations/it_IT/process/maintainer-pgp-guidemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget0/translations/ja_JP/process/maintainer-pgp-guidemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget0/translations/ko_KR/process/maintainer-pgp-guidemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget0/translations/sp_SP/process/maintainer-pgp-guidemodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhtarget)}(h .. _pgpguide:h]h}(h]h ]h"]h$]h&]refidpgpguideuh1hhKhhhhhJ/var/lib/git/docbuild/linux/Documentation/process/maintainer-pgp-guide.rstubhsection)}(hhh](htitle)}(hKernel Maintainer PGP guideh]hKernel Maintainer PGP guide}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh field_list)}(hhh]hfield)}(hhh](h field_name)}(hAuthorh]hAuthor}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhKubh field_body)}(h6Konstantin Ryabitsev h]h paragraph)}(h5Konstantin Ryabitsev h](hKonstantin Ryabitsev <}(hhhhhNhNubh reference)}(hkonstantin@linuxfoundation.orgh]hkonstantin@linuxfoundation.org}(hhhhhNhNubah}(h]h ]h"]h$]h&]refuri%mailto:konstantin@linuxfoundation.orguh1hhhubh>}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh)}(hXKThis document is aimed at Linux kernel developers, and especially at subsystem maintainers. It contains a subset of information discussed in the more general "`Protecting Code Integrity`_" guide published by the Linux Foundation. Please read that document for more in-depth discussion on some of the topics mentioned in this guide.h](hThis document is aimed at Linux kernel developers, and especially at subsystem maintainers. It contains a subset of information discussed in the more general “}(hjhhhNhNubh)}(h`Protecting Code Integrity`_h]hProtecting Code Integrity}(hj%hhhNhNubah}(h]h ]h"]h$]h&]nameProtecting Code IntegrityrefuriFhttps://github.com/lfit/itpol/blob/master/protecting-code-integrity.mduh1hhjresolvedKubh” guide published by the Linux Foundation. Please read that document for more in-depth discussion on some of the topics mentioned in this guide.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hg.. _`Protecting Code Integrity`: https://github.com/lfit/itpol/blob/master/protecting-code-integrity.mdh]h}(h]protecting-code-integrityah ]h"]protecting code integrityah$]h&]j5j6uh1hhKhhhhhh referencedKubh)}(hhh](h)}(h+The role of PGP in Linux Kernel developmenth]h+The role of PGP in Linux Kernel development}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjOhhhhhKubh)}(hPGP 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.h]hPGP 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.}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjOhhubh)}(h>The Linux kernel source code is available in two main formats:h]h>The Linux kernel source code is available in two main formats:}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjOhhubh bullet_list)}(hhh](h list_item)}(h%Distributed source repositories (git)h]h)}(hjh]h%Distributed source repositories (git)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhj~hhhhhNubj)}(h&Periodic release snapshots (tarballs) h]h)}(h%Periodic release snapshots (tarballs)h]h%Periodic release snapshots (tarballs)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhj~hhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1j|hhhKhjOhhubh)}(hXDBoth 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:h]hXDBoth 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:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjOhhubj})}(hhh](j)}(h3git repositories provide PGP signatures on all tagsh]h)}(hjh]h3git repositories provide PGP signatures on all tags}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK#hjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j|hhhKhjhhubh)}(hIf 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::h](hxIf you used the default parameters when generating your key, then that is what you will have. You can verify by running }(hjnhhhNhNubj)}(h``gpg --list-secret-keys``h]hgpg --list-secret-keys}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjnubh, for example:}(hjnhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hsec ed25519 2022-12-20 [SC] [expires: 2024-12-19] 000000000000000000000000AAAABBBBCCCCDDDD uid [ultimate] Alice Dev ssb cv25519 2022-12-20 [E] [expires: 2024-12-19]h]hsec ed25519 2022-12-20 [SC] [expires: 2024-12-19] 000000000000000000000000AAAABBBBCCCCDDDD uid [ultimate] Alice Dev ssb cv25519 2022-12-20 [E] [expires: 2024-12-19]}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhKhjhhubh)}(hThe 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.h](hThe long line under the }(hjhhhNhNubj)}(h``sec``h]hsec}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh3 entry is your key fingerprint -- whenever you see }(hjhhhNhNubj)}(h ``[fpr]``h]h[fpr]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhF in the examples below, that 40-character string is what it refers to.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]understanding-pgp-subkeysah ]h"]understanding pgp subkeysah$]h&]uh1hhjhhhhhKxubh)}(hhh](h)}(h Ensure your passphrase is strongh]h Ensure your passphrase is strong}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hXGnuPG 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.h](hhGnuPG uses passphrases to encrypt your private keys before storing them on disk. This way, even if your }(hjhhhNhNubj)}(h ``.gnupg``h]h.gnupg}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh directory is leaked or stolen in its entirety, the attackers cannot use your private keys without first obtaining the passphrase to decrypt them.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(huIt is absolutely essential that your private keys are protected by a strong passphrase. To set it or change it, use::h]htIt is absolutely essential that your private keys are protected by a strong passphrase. To set it or change it, use:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(h$ gpg --change-passphrase [fpr]h]h$ gpg --change-passphrase [fpr]}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhKhjhhubeh}(h] ensure-your-passphrase-is-strongah ]h"] ensure your passphrase is strongah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(h Create a separate Signing subkeyh]h Create a separate Signing subkey}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj+hhhhhKubh)}(hOur goal is to protect your Certify key by moving it to offline media, so if you only have a combined **[SC]** key, then you should create a separate signing subkey::h](hfOur goal is to protect your Certify key by moving it to offline media, so if you only have a combined }(hj<hhhNhNubj )}(h**[SC]**h]h[SC]}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj<ubh7 key, then you should create a separate signing subkey:}(hj<hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj+hhubj)}(h'$ gpg --quick-addkey [fpr] ed25519 signh]h'$ gpg --quick-addkey [fpr] ed25519 sign}hj\sbah}(h]h ]h"]h$]h&]jjuh1jhhhKhj+hhubj_)}(hECC support in GnuPG Note, that if you intend to use a hardware token that does not support ED25519 ECC keys, you should choose "nistp256" instead or "ed25519." See the section below on recommended hardware devices.h](h)}(hECC support in GnuPGh]hECC support in GnuPG}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjjubh)}(hNote, that if you intend to use a hardware token that does not support ED25519 ECC keys, you should choose "nistp256" instead or "ed25519." See the section below on recommended hardware devices.h]hNote, that if you intend to use a hardware token that does not support ED25519 ECC keys, you should choose “nistp256” instead or “ed25519.” See the section below on recommended hardware devices.}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjjubeh}(h]h ]h"]h$]h&]uh1j^hj+hhhhhNubeh}(h] create-a-separate-signing-subkeyah ]h"] create a separate signing subkeyah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(h.Back up your Certify key for disaster recoveryh]h.Back up your Certify key for disaster recovery}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hThe 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.h]hThe 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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX"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.h](hPThe best way to create a printable hardcopy of your private key is by using the }(hjhhhNhNubj)}(h ``paperkey``h]hpaperkey}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh- software written for this very purpose. See }(hjhhhNhNubj)}(h``man paperkey``h]h man paperkey}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh for more details on the output format and its benefits over other solutions. Paperkey should already be packaged for most distributions.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hKRun the following command to create a hardcopy backup of your private key::h]hJRun the following command to create a hardcopy backup of your private key:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hA$ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txth]hA$ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhKhjhhubh)}(hXVPrint 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*.h](hPrint out that file (or pipe the output straight to lpr), then take a pen and write your passphrase on the margin of the paper. }(hjhhhNhNubj )}(h **This is strongly recommended**h]hThis is strongly recommended}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 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 -- }(hjhhhNhNubhemphasis)}(h *guaranteed*h]h guaranteed}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hPut 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.h]hPut 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.}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj_)}(hYour 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.h]h)}(hYour 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.h]hYour 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.}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjGubah}(h]h ]h"]h$]h&]uh1j^hjhhhhhNubeh}(h].back-up-your-certify-key-for-disaster-recoveryah ]h"].back up your certify key for disaster recoveryah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(h"Back up your whole GnuPG directoryh]h"Back up your whole GnuPG directory}(hjjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjghhhhhKubhwarning)}(h**!!!Do not skip this step!!!**h]h)}(hj|h]j )}(hj|h]h!!!Do not skip this step!!!}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj~ubah}(h]h ]h"]h$]h&]uh1hhhhKhjzubah}(h]h ]h"]h$]h&]uh1jxhjghhhhhNubh)}(hXxIt 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 summits.h](hIt 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 }(hjhhhNhNubj)}(h ``paperkey``h]hpaperkey}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh. 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 summits.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjghhubh)}(hStart by getting a small USB "thumb" drive (preferably two!) that you will use for backup purposes. You will need to encrypt them using LUKS -- refer to your distro's documentation on how to accomplish this.h]hStart by getting a small USB “thumb” drive (preferably two!) that you will use for backup purposes. You will need to encrypt them using LUKS -- refer to your distro’s documentation on how to accomplish this.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjghhubh)}(hKFor the encryption passphrase, you can use the same one as on your PGP key.h]hKFor the encryption passphrase, you can use the same one as on your PGP key.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjghhubh)}(hOnce the encryption process is over, re-insert the USB drive and make sure it gets properly mounted. Copy your entire ``.gnupg`` directory over to the encrypted storage::h](hvOnce the encryption process is over, re-insert the USB drive and make sure it gets properly mounted. Copy your entire }(hjhhhNhNubj)}(h ``.gnupg``h]h.gnupg}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh) directory over to the encrypted storage:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hjghhubj)}(h-$ cp -a ~/.gnupg /media/disk/foo/gnupg-backuph]h-$ cp -a ~/.gnupg /media/disk/foo/gnupg-backup}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhM hjghhubh)}(h9You should now test to make sure everything still works::h]h8You should now test to make sure everything still works:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjghhubj)}(h=$ gpg --homedir=/media/disk/foo/gnupg-backup --list-key [fpr]h]h=$ gpg --homedir=/media/disk/foo/gnupg-backup --list-key [fpr]}hj sbah}(h]h ]h"]h$]h&]jjuh1jhhhMhjghhubh)}(hXqIf 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.h]hXyIf 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.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjghhubeh}(h]"back-up-your-whole-gnupg-directoryah ]h"]"back up your whole gnupg directoryah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(h(Remove the Certify key from your homedirh]h(Remove the Certify key from your homedir}(hj9 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj6 hhhhhMubh)}(hThe 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:h]hThe 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:}(hjG hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj6 hhubj})}(hhh](j)}(hHby accident when making quick homedir copies to set up a new workstationh]h)}(hjZ h]hHby accident when making quick homedir copies to set up a new workstation}(hj\ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjX ubah}(h]h ]h"]h$]h&]uh1jhjU hhhhhNubj)}(h-by systems administrator negligence or maliceh]h)}(hjq h]h-by systems administrator negligence or malice}(hjs hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM!hjo ubah}(h]h ]h"]h$]h&]uh1jhjU hhhhhNubj)}(hvia poorly secured backupsh]h)}(hj h]hvia poorly secured backups}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM"hj ubah}(h]h ]h"]h$]h&]uh1jhjU hhhhhNubj)}(h8via malware in desktop apps (browsers, pdf viewers, etc)h]h)}(hj h]h8via malware in desktop apps (browsers, pdf viewers, etc)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM#hj ubah}(h]h ]h"]h$]h&]uh1jhjU hhhhhNubj)}(h1via coercion when crossing international borders h]h)}(h0via coercion when crossing international bordersh]h0via coercion when crossing international borders}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM$hj ubah}(h]h ]h"]h$]h&]uh1jhjU hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j|hhhM hj6 hhubh)}(hX>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 Certify key from your home directory and store it on offline storage.h]hX>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 Certify key from your home directory and store it on offline storage.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM&hj6 hhubjy)}(hPlease 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!h]h)}(hPlease 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!h]hPlease 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!}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM.hj ubah}(h]h ]h"]h$]h&]uh1jxhj6 hhhhhNubh)}(h1First, identify the keygrip of your Certify key::h]h0First, identify the keygrip of your Certify key:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM2hj6 hhubj)}(h%$ gpg --with-keygrip --list-key [fpr]h]h%$ gpg --with-keygrip --list-key [fpr]}hj sbah}(h]h ]h"]h$]h&]jjuh1jhhhM4hj6 hhubh)}(h(The output will be something like this::h]h'The output will be something like this:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM6hj6 hhubj)}(hXpub ed25519 2022-12-20 [SC] [expires: 2022-12-19] 000000000000000000000000AAAABBBBCCCCDDDD Keygrip = 1111000000000000000000000000000000000000 uid [ultimate] Alice Dev sub cv25519 2022-12-20 [E] [expires: 2022-12-19] Keygrip = 2222000000000000000000000000000000000000 sub ed25519 2022-12-20 [S] Keygrip = 3333000000000000000000000000000000000000h]hXpub ed25519 2022-12-20 [SC] [expires: 2022-12-19] 000000000000000000000000AAAABBBBCCCCDDDD Keygrip = 1111000000000000000000000000000000000000 uid [ultimate] Alice Dev sub cv25519 2022-12-20 [E] [expires: 2022-12-19] Keygrip = 2222000000000000000000000000000000000000 sub ed25519 2022-12-20 [S] Keygrip = 3333000000000000000000000000000000000000}hj" sbah}(h]h ]h"]h$]h&]jjuh1jhhhM8hj6 hhubh)}(hFind the keygrip entry that is beneath the ``pub`` line (right under the Certify key fingerprint). This will correspond directly to a file in your ``~/.gnupg`` directory::h](h+Find the keygrip entry that is beneath the }(hj0 hhhNhNubj)}(h``pub``h]hpub}(hj8 hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj0 ubha line (right under the Certify key fingerprint). This will correspond directly to a file in your }(hj0 hhhNhNubj)}(h ``~/.gnupg``h]h~/.gnupg}(hjJ hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj0 ubh directory:}(hj0 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMAhj6 hhubj)}(h$ cd ~/.gnupg/private-keys-v1.d $ ls 1111000000000000000000000000000000000000.key 2222000000000000000000000000000000000000.key 3333000000000000000000000000000000000000.keyh]h$ cd ~/.gnupg/private-keys-v1.d $ ls 1111000000000000000000000000000000000000.key 2222000000000000000000000000000000000000.key 3333000000000000000000000000000000000000.key}hjb sbah}(h]h ]h"]h$]h&]jjuh1jhhhMEhj6 hhubh)}(h_All you have to do is simply remove the .key file that corresponds to the Certify key keygrip::h]h^All you have to do is simply remove the .key file that corresponds to the Certify key keygrip:}(hjp hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMKhj6 hhubj)}(hQ$ cd ~/.gnupg/private-keys-v1.d $ rm 1111000000000000000000000000000000000000.keyh]hQ$ cd ~/.gnupg/private-keys-v1.d $ rm 1111000000000000000000000000000000000000.key}hj~ sbah}(h]h ]h"]h$]h&]jjuh1jhhhMNhj6 hhubh)}(hNow, if you issue the ``--list-secret-keys`` command, it will show that the Certify key is missing (the ``#`` indicates it is not available)::h](hNow, if you issue the }(hj hhhNhNubj)}(h``--list-secret-keys``h]h--list-secret-keys}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh< command, it will show that the Certify key is missing (the }(hj hhhNhNubj)}(h``#``h]h#}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh indicates it is not available):}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMQhj6 hhubj)}(hX$ gpg --list-secret-keys sec# ed25519 2022-12-20 [SC] [expires: 2024-12-19] 000000000000000000000000AAAABBBBCCCCDDDD uid [ultimate] Alice Dev ssb cv25519 2022-12-20 [E] [expires: 2024-12-19] ssb ed25519 2022-12-20 [S]h]hX$ gpg --list-secret-keys sec# ed25519 2022-12-20 [SC] [expires: 2024-12-19] 000000000000000000000000AAAABBBBCCCCDDDD uid [ultimate] Alice Dev ssb cv25519 2022-12-20 [E] [expires: 2024-12-19] ssb ed25519 2022-12-20 [S]}hj sbah}(h]h ]h"]h$]h&]jjuh1jhhhMThj6 hhubh)}(hYou should also remove any ``secring.gpg`` files in the ``~/.gnupg`` directory, which may be left over from previous versions of GnuPG.h](hYou should also remove any }(hj hhhNhNubj)}(h``secring.gpg``h]h secring.gpg}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh files in the }(hj hhhNhNubj)}(h ``~/.gnupg``h]h~/.gnupg}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhC directory, which may be left over from previous versions of GnuPG.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM[hj6 hhubh)}(hhh](h)}(h3If you don't have the "private-keys-v1.d" directoryh]h9If you don’t have the “private-keys-v1.d” directory}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhM_ubh)}(hXPIf 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.h](hIf you do not have a }(hj hhhNhNubj)}(h``~/.gnupg/private-keys-v1.d``h]h~/.gnupg/private-keys-v1.d}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhA directory, then your secret keys are still stored in the legacy }(hj hhhNhNubj)}(h``secring.gpg``h]h secring.gpg}(hj) hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 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 }(hj hhhNhNubj)}(h``secring.gpg``h]h secring.gpg}(hj; hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh format to use }(hj hhhNhNubj)}(h``private-keys-v1.d``h]hprivate-keys-v1.d}(hjM hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh instead.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMahj hhubh)}(hvOnce you get that done, make sure to delete the obsolete ``secring.gpg`` file, which still contains your private keys.h](h9Once you get that done, make sure to delete the obsolete }(hje hhhNhNubj)}(h``secring.gpg``h]h secring.gpg}(hjm hhhNhNubah}(h]h ]h"]h$]h&]uh1jhje ubh. file, which still contains your private keys.}(hje hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMghj hhubh)}(h.. _smartcards:h]h}(h]h ]h"]h$]h&]h smartcardsuh1hhMjhj hhhhubeh}(h]1if-you-don-t-have-the-private-keys-v1-d-directoryah ]h"]3if you don't have the "private-keys-v1.d" directoryah$]h&]uh1hhj6 hhhhhM_ubeh}(h](remove-the-certify-key-from-your-homedirah ]h"](remove the certify key from your homedirah$]h&]uh1hhjhhhhhMubeh}(h](protect-your-pgp-keyjeh ]h"](protect your pgp keyprotect_your_keyeh$]h&]uh1hhhhhhhhKmjL}j jxsjN}jjxsubh)}(hhh](h)}(h-Move the subkeys to a dedicated crypto deviceh]h-Move the subkeys to a dedicated crypto device}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMmubh)}(hXEven though the Certify 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).h]hXEven though the Certify 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).}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMohj hhubh)}(hThe best way to completely protect your keys is to move them to a specialized hardware device that is capable of smartcard operations.h]hThe best way to completely protect your keys is to move them to a specialized hardware device that is capable of smartcard operations.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMwhj hhubh)}(hhh](h)}(hThe benefits of smartcardsh]hThe benefits of smartcards}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhM{ubh)}(hXA 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.h]hXA 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.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM}hj hhubh)}(h\Using external encrypted USB media is not a substitute to having a smartcard-capable device.h]h\Using external encrypted USB media is not a substitute to having a smartcard-capable device.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubeh}(h]the-benefits-of-smartcardsah ]h"]the benefits of smartcardsah$]h&]uh1hhj hhhhhM{ubh)}(hhh](h)}(hAvailable smartcard devicesh]hAvailable smartcard devices}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(hUnless 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:h]hUnless 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:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj})}(hhh](j)}(h`Nitrokey Start`_: Open hardware and Free Software, based on FSI Japan's `Gnuk`_. One of the few available commercial devices that support ED25519 ECC keys, but offer fewest security features (such as resistance to tampering or some side-channel attacks).h]h)}(h`Nitrokey Start`_: Open hardware and Free Software, based on FSI Japan's `Gnuk`_. One of the few available commercial devices that support ED25519 ECC keys, but offer fewest security features (such as resistance to tampering or some side-channel attacks).h](h)}(h`Nitrokey Start`_h]hNitrokey Start}(hj7 hhhNhNubah}(h]h ]h"]h$]h&]nameNitrokey Startj57https://shop.nitrokey.com/shop/product/nitrokey-start-6uh1hhj3 j7Kubh:: Open hardware and Free Software, based on FSI Japan’s }(hj3 hhhNhNubh)}(h`Gnuk`_h]hGnuk}(hjL hhhNhNubah}(h]h ]h"]h$]h&]nameGnukj5https://www.fsij.org/doc-gnuk/uh1hhj3 j7Kubh. One of the few available commercial devices that support ED25519 ECC keys, but offer fewest security features (such as resistance to tampering or some side-channel attacks).}(hj3 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj/ ubah}(h]h ]h"]h$]h&]uh1jhj, hhhhhNubj)}(h`Nitrokey Pro 2`_: Similar to the Nitrokey Start, but more tamper-resistant and offers more security features. Pro 2 supports ECC cryptography (NISTP).h]h)}(h`Nitrokey Pro 2`_: Similar to the Nitrokey Start, but more tamper-resistant and offers more security features. Pro 2 supports ECC cryptography (NISTP).h](h)}(h`Nitrokey Pro 2`_h]hNitrokey Pro 2}(hju hhhNhNubah}(h]h ]h"]h$]h&]nameNitrokey Pro 2j5=https://shop.nitrokey.com/shop/product/nkpr2-nitrokey-pro-2-3uh1hhjq j7Kubh: Similar to the Nitrokey Start, but more tamper-resistant and offers more security features. Pro 2 supports ECC cryptography (NISTP).}(hjq hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjm ubah}(h]h ]h"]h$]h&]uh1jhj, hhhhhNubj)}(hX`Yubikey 5`_: 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, among others, and now finally supports NISTP and ED25519 ECC keys. h]h)}(hX`Yubikey 5`_: 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, among others, and now finally supports NISTP and ED25519 ECC keys.h](h)}(h `Yubikey 5`_h]h Yubikey 5}(hj hhhNhNubah}(h]h ]h"]h$]h&]name Yubikey 5j53https://www.yubico.com/products/yubikey-5-overview/uh1hhj j7KubhX : 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, among others, and now finally supports NISTP and ED25519 ECC keys.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jhj, hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j|hhhMhj hhubh)}(hYour choice will depend on cost, shipping availability in your geographical region, and open/proprietary hardware considerations.h]hYour choice will depend on cost, shipping availability in your geographical region, and open/proprietary hardware considerations.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj_)}(hIf you are listed in MAINTAINERS or have an account at kernel.org, you `qualify for a free Nitrokey Start`_ courtesy of The Linux Foundation.h]h)}(hIf you are listed in MAINTAINERS or have an account at kernel.org, you `qualify for a free Nitrokey Start`_ courtesy of The Linux Foundation.h](hGIf you are listed in MAINTAINERS or have an account at kernel.org, you }(hj hhhNhNubh)}(h$`qualify for a free Nitrokey Start`_h]h!qualify for a free Nitrokey Start}(hj hhhNhNubah}(h]h ]h"]h$]h&]name!qualify for a free Nitrokey Startj5Ihttps://www.kernel.org/nitrokey-digital-tokens-for-kernel-developers.htmluh1hhj j7Kubh" courtesy of The Linux Foundation.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1j^hj hhhhhNubh)}(hM.. _`Nitrokey Start`: https://shop.nitrokey.com/shop/product/nitrokey-start-6h]h}(h]nitrokey-startah ]h"]nitrokey startah$]h&]j5jG uh1hhMhj hhhhjNKubh)}(hS.. _`Nitrokey Pro 2`: https://shop.nitrokey.com/shop/product/nkpr2-nitrokey-pro-2-3h]h}(h]nitrokey-pro-2ah ]h"]nitrokey pro 2ah$]h&]j5j uh1hhMhj hhhhjNKubh)}(hD.. _`Yubikey 5`: https://www.yubico.com/products/yubikey-5-overview/h]h}(h] yubikey-5ah ]h"] yubikey 5ah$]h&]j5j uh1hhMhj hhhhjNKubh)}(h(.. _Gnuk: https://www.fsij.org/doc-gnuk/h]h}(h]gnukah ]h"]gnukah$]h&]j5j\ uh1hhMhj hhhhjNKubh)}(hr.. _`qualify for a free Nitrokey Start`: https://www.kernel.org/nitrokey-digital-tokens-for-kernel-developers.htmlh]h}(h]!qualify-for-a-free-nitrokey-startah ]h"]!qualify for a free nitrokey startah$]h&]j5j uh1hhMhj hhhhjNKubeh}(h]available-smartcard-devicesah ]h"]available smartcard devicesah$]h&]uh1hhj hhhhhMubh)}(hhh](h)}(hConfigure your smartcard deviceh]hConfigure your smartcard device}(hjG hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjD hhhhhMubh)}(hYour smartcard device should Just Work (TM) the moment you plug it into any modern Linux workstation. You can verify it by running::h]hYour smartcard device should Just Work (TM) the moment you plug it into any modern Linux workstation. You can verify it by running:}(hjU hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjD hhubj)}(h$ gpg --card-statush]h$ gpg --card-status}hjc sbah}(h]h ]h"]h$]h&]jjuh1jhhhMhjD hhubh)}(hX(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.h]hX(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.}(hjq hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjD hhubh)}(h{To configure your smartcard, you will need to use the GnuPG menu system, as there are no convenient command-line switches::h]hzTo configure your smartcard, you will need to use the GnuPG menu system, as there are no convenient command-line switches:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjD hhubj)}(h]$ gpg --card-edit [...omitted...] gpg/card> admin Admin commands are allowed gpg/card> passwdh]h]$ gpg --card-edit [...omitted...] gpg/card> admin Admin commands are allowed gpg/card> passwd}hj sbah}(h]h ]h"]h$]h&]jjuh1jhhhMhjD hhubh)}(hXSYou 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.h]hXSYou 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.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjD hhubh)}(hGetting 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.qh]hGetting 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.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjD hhubj_)}(heDespite having the name "PIN", neither the user PIN nor the admin PIN on the card need to be numbers.h]h)}(heDespite having the name "PIN", neither the user PIN nor the admin PIN on the card need to be numbers.h]hiDespite having the name “PIN”, neither the user PIN nor the admin PIN on the card need to be numbers.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1j^hjD hhhhhNubjy)}(hSome devices may require that you move the subkeys onto the device before you can change the passphrase. Please check the documentation provided by the device manufacturer.h]h)}(hSome devices may require that you move the subkeys onto the device before you can change the passphrase. Please check the documentation provided by the device manufacturer.h]hSome devices may require that you move the subkeys onto the device before you can change the passphrase. Please check the documentation provided by the device manufacturer.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jxhjD hhhhhNubeh}(h]configure-your-smartcard-deviceah ]h"]configure your smartcard deviceah$]h&]uh1hhj hhhhhMubh)}(hhh](h)}(h"Move the subkeys to your smartcardh]h"Move the subkeys to your smartcard}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(hExit 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::h]hExit 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:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj)}(hX$ gpg --edit-key [fpr] Secret subkeys are available. pub ed25519/AAAABBBBCCCCDDDD created: 2022-12-20 expires: 2024-12-19 usage: SC trust: ultimate validity: ultimate ssb cv25519/1111222233334444 created: 2022-12-20 expires: never usage: E ssb ed25519/5555666677778888 created: 2017-12-07 expires: never usage: S [ultimate] (1). Alice Dev gpg>h]hX$ gpg --edit-key [fpr] Secret subkeys are available. pub ed25519/AAAABBBBCCCCDDDD created: 2022-12-20 expires: 2024-12-19 usage: SC trust: ultimate validity: ultimate ssb cv25519/1111222233334444 created: 2022-12-20 expires: never usage: E ssb ed25519/5555666677778888 created: 2017-12-07 expires: never usage: S [ultimate] (1). Alice Dev gpg>}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMhj hhubh)}(hUsing ``--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>``.h](hUsing }(hjhhhNhNubj)}(h``--edit-key``h]h --edit-key}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 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 }(hjhhhNhNubj)}(h``gpg>``h]hgpg>}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hFirst, 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)::h](hXFirst, let’s select the key we’ll be putting onto the card -- you do this by typing }(hjNhhhNhNubj)}(h ``key 1``h]hkey 1}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjNubh+ (it’s the first one in the listing, the }(hjNhhhNhNubj )}(h**[E]**h]h[E]}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjNubh subkey):}(hjNhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj)}(h gpg> key 1h]h gpg> key 1}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMhj hhubh)}(hIn 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.h](h"In the output, you should now see }(hjhhhNhNubj)}(h``ssb*``h]hssb*}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh on the }(hjhhhNhNubj )}(h**[E]**h]h[E]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh key. The }(hjhhhNhNubj)}(h``*``h]h*}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh@ indicates which key is currently “selected.” It works as a }(hjhhhNhNubj )}(h*toggle*h]htoggle}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, meaning that if you type }(hjhhhNhNubj)}(h ``key 1``h]hkey 1}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh again, the }(hjhhhNhNubj)}(h``*``h]h*}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: will disappear and the key will not be selected any more.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(h-Now, let's move that key onto the smartcard::h]h.Now, let’s move that key onto the smartcard:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj)}(h\gpg> keytocard Please select where to store the key: (2) Encryption key Your selection? 2h]h\gpg> keytocard Please select where to store the key: (2) Encryption key Your selection? 2}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMhj hhubh)}(hXSince 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.h](hSince it’s our }(hj$hhhNhNubj )}(h**[E]**h]h[E]}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj$ubh 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.}(hj$hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hl**Important**: Now type ``key 1`` again to unselect the first key, and ``key 2`` to select the **[S]** key::h](j )}(h **Important**h]h Important}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjDubh : Now type }(hjDhhhNhNubj)}(h ``key 1``h]hkey 1}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjDubh& again to unselect the first key, and }(hjDhhhNhNubj)}(h ``key 2``h]hkey 2}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjDubh to select the }(hjDhhhNhNubj )}(h**[S]**h]h[S]}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjDubh key:}(hjDhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hj hhubj)}(hgpg> key 1 gpg> key 2 gpg> keytocard Please select where to store the key: (1) Signature key (3) Authentication key Your selection? 1h]hgpg> key 1 gpg> key 2 gpg> keytocard Please select where to store the key: (1) Signature key (3) Authentication key Your selection? 1}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhM hj hhubh)}(hYou 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::h](hYou can use the }(hjhhhNhNubj )}(h**[S]**h]h[S]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 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:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj)}(hgpg> q Save changes? (y/N) yh]hgpg> q Save changes? (y/N) y}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMhj hhubh)}(hSaving 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).h]hSaving 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).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hhh](h)}(h"Verifying that the keys were movedh]h"Verifying that the keys were moved}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhM!ubh)}(h[If you perform ``--list-secret-keys`` now, you will see a subtle difference in the output::h](hIf you perform }(hjhhhNhNubj)}(h``--list-secret-keys``h]h--list-secret-keys}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh5 now, you will see a subtle difference in the output:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM#hjhhubj)}(hX$ gpg --list-secret-keys sec# ed25519 2022-12-20 [SC] [expires: 2024-12-19] 000000000000000000000000AAAABBBBCCCCDDDD uid [ultimate] Alice Dev ssb> cv25519 2022-12-20 [E] [expires: 2024-12-19] ssb> ed25519 2022-12-20 [S]h]hX$ gpg --list-secret-keys sec# ed25519 2022-12-20 [SC] [expires: 2024-12-19] 000000000000000000000000AAAABBBBCCCCDDDD uid [ultimate] Alice Dev ssb> cv25519 2022-12-20 [E] [expires: 2024-12-19] ssb> ed25519 2022-12-20 [S]}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhM&hjhhubh)}(hThe ``>`` 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::h](hThe }(hjhhhNhNubj)}(h``>``h]h>}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in the }(hjhhhNhNubj)}(h``ssb>``h]hssb>}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 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 }(hjhhhNhNubj)}(h``.key``h]h.key}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh+ files there have been replaced with stubs:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM-hjhhubj)}(hD$ cd ~/.gnupg/private-keys-v1.d $ strings *.key | grep 'private-key'h]hD$ cd ~/.gnupg/private-keys-v1.d $ strings *.key | grep 'private-key'}hjcsbah}(h]h ]h"]h$]h&]jjuh1jhhhM2hjhhubh)}(hThe output should contain ``shadowed-private-key`` to indicate that these files are only stubs and the actual content is on the smartcard.h](hThe output should contain }(hjqhhhNhNubj)}(h``shadowed-private-key``h]hshadowed-private-key}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjqubhX to indicate that these files are only stubs and the actual content is on the smartcard.}(hjqhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM5hjhhubeh}(h]"verifying-that-the-keys-were-movedah ]h"]"verifying that the keys were movedah$]h&]uh1hhj hhhhhM!ubh)}(hhh](h)}(h+Verifying that the smartcard is functioningh]h+Verifying that the smartcard is functioning}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhM9ubh)}(hQTo verify that the smartcard is working as intended, you can create a signature::h]hPTo verify that the smartcard is working as intended, you can create a signature:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM;hjhhubj)}(hS$ echo "Hello world" | gpg --clearsign > /tmp/test.asc $ gpg --verify /tmp/test.asch]hS$ echo "Hello world" | gpg --clearsign > /tmp/test.asc $ gpg --verify /tmp/test.asc}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhM>hjhhubh)}(h|This should ask for your smartcard PIN on your first command, and then show "Good signature" after you run ``gpg --verify``.h](hoThis should ask for your smartcard PIN on your first command, and then show “Good signature” after you run }(hjhhhNhNubj)}(h``gpg --verify``h]h gpg --verify}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMAhjhhubh)}(hlCongratulations, you have successfully made it extremely difficult to steal your digital developer identity!h]hlCongratulations, you have successfully made it extremely difficult to steal your digital developer identity!}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMDhjhhubeh}(h]+verifying-that-the-smartcard-is-functioningah ]h"]+verifying that the smartcard is functioningah$]h&]uh1hhj hhhhhM9ubeh}(h]"move-the-subkeys-to-your-smartcardah ]h"]"move the subkeys to your smartcardah$]h&]uh1hhj hhhhhMubh)}(hhh](h)}(hOther common GnuPG operationsh]hOther common GnuPG operations}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMHubh)}(hYHere is a quick reference for some common operations you'll need to do with your PGP key.h]h[Here is a quick reference for some common operations you’ll need to do with your PGP key.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMJhjhhubh)}(hhh](h)}(h"Mounting your safe offline storageh]h"Mounting your safe offline storage}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj#hhhhhMNubh)}(hYou will need your Certify key for any of the operations below, so you will first need to mount your backup offline storage and tell GnuPG to use it::h]hYou will need your Certify key for any of the operations below, so you will first need to mount your backup offline storage and tell GnuPG to use it:}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMPhj#hhubj)}(hH$ export GNUPGHOME=/media/disk/foo/gnupg-backup $ gpg --list-secret-keysh]hH$ export GNUPGHOME=/media/disk/foo/gnupg-backup $ gpg --list-secret-keys}hjBsbah}(h]h ]h"]h$]h&]jjuh1jhhhMThj#hhubh)}(hYou 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).h](h#You want to make sure that you see }(hjPhhhNhNubj)}(h``sec``h]hsec}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjPubh and not }(hjPhhhNhNubj)}(h``sec#``h]hsec#}(hjjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjPubh in the output (the }(hjPhhhNhNubj)}(h``#``h]h#}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjPubh_ means the key is not available and you’re still using your regular home directory location).}(hjPhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMWhj#hhubeh}(h]"mounting-your-safe-offline-storageah ]h"]"mounting your safe offline storageah$]h&]uh1hhjhhhhhMNubh)}(hhh](h)}(hExtending key expiration dateh]hExtending key expiration date}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhM\ubh)}(hThe Certify 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.h]hThe Certify 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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM^hjhhubh)}(hLTo extend the expiration on your key by a year from current date, just run::h]hKTo extend the expiration on your key by a year from current date, just run:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMbhjhhubj)}(h!$ gpg --quick-set-expire [fpr] 1yh]h!$ gpg --quick-set-expire [fpr] 1y}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMehjhhubh)}(hqYou can also use a specific date if that is easier to remember (e.g. your birthday, January 1st, or Canada Day)::h]hpYou can also use a specific date if that is easier to remember (e.g. your birthday, January 1st, or Canada Day):}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMghjhhubj)}(h)$ gpg --quick-set-expire [fpr] 2025-07-01h]h)$ gpg --quick-set-expire [fpr] 2025-07-01}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMjhjhhubh)}(h5Remember to send the updated key back to keyservers::h]h4Remember to send the updated key back to keyservers:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMlhjhhubj)}(h$ gpg --send-key [fpr]h]h$ gpg --send-key [fpr]}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMnhjhhubeh}(h]extending-key-expiration-dateah ]h"]extending key expiration dateah$]h&]uh1hhjhhhhhM\ubh)}(hhh](h)}(h.Updating your work directory after any changesh]h.Updating your work directory after any changes}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMqubh)}(hAfter you make any changes to your key using the offline storage, you will want to import these changes back into your regular working directory::h]hAfter you make any changes to your key using the offline storage, you will want to import these changes back into your regular working directory:}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMshjhhubj)}(hB$ gpg --export | gpg --homedir ~/.gnupg --import $ unset GNUPGHOMEh]hB$ gpg --export | gpg --homedir ~/.gnupg --import $ unset GNUPGHOME}hj6sbah}(h]h ]h"]h$]h&]jjuh1jhhhMvhjhhubeh}(h].updating-your-work-directory-after-any-changesah ]h"].updating your work directory after any changesah$]h&]uh1hhjhhhhhMqubh)}(hhh](h)}(hUsing gpg-agent over sshh]hUsing gpg-agent over ssh}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjLhhhhhMzubh)}(hYou can forward your gpg-agent over ssh if you need to sign tags or commits on a remote system. Please refer to the instructions provided on the GnuPG wiki:h]hYou can forward your gpg-agent over ssh if you need to sign tags or commits on a remote system. Please refer to the instructions provided on the GnuPG wiki:}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM|hjLhhubj})}(hhh]j)}(h`Agent Forwarding over SSH`_ h]h)}(h`Agent Forwarding over SSH`_h]h)}(hjth]hAgent Forwarding over SSH}(hjvhhhNhNubah}(h]h ]h"]h$]h&]nameAgent Forwarding over SSHj5&https://wiki.gnupg.org/AgentForwardinguh1hhjrj7Kubah}(h]h ]h"]h$]h&]uh1hhhhMhjnubah}(h]h ]h"]h$]h&]uh1jhjkhhhhhNubah}(h]h ]h"]h$]h&]jjuh1j|hhhMhjLhhubh)}(hTIt works more smoothly if you can modify the sshd server settings on the remote end.h]hTIt works more smoothly if you can modify the sshd server settings on the remote end.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjLhhubh)}(hG.. _`Agent Forwarding over SSH`: https://wiki.gnupg.org/AgentForwardingh]h}(h]agent-forwarding-over-sshah ]h"]agent forwarding over sshah$]h&]j5juh1hhMhjLhhhhjNKubh)}(h.. _pgp_with_git:h]h}(h]h ]h"]h$]h&]h pgp-with-gituh1hhMhjLhhhhubeh}(h]using-gpg-agent-over-sshah ]h"]using gpg-agent over sshah$]h&]uh1hhjhhhhhMzubeh}(h]other-common-gnupg-operationsah ]h"]other common gnupg operationsah$]h&]uh1hhj hhhhhMHubeh}(h](-move-the-subkeys-to-a-dedicated-crypto-devicej eh ]h"](-move the subkeys to a dedicated crypto device smartcardseh$]h&]uh1hhhhhhhhMmjL}jj sjN}j j subh)}(hhh](h)}(hUsing PGP with Gith]hUsing PGP with Git}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hXkOne 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?h]hXkOne 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?}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hOr 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`_?h](hOr 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 }(hjhhhNhNubh)}(h`nothing to do with it`_h]hnothing to do with it}(hjhhhNhNubah}(h]h ]h"]h$]h&]namenothing to do with itj53https://github.com/jayphelps/git-blame-someone-elseuh1hhjj7Kubh?}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hXPTo 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.h]hXPTo 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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hP.. _`nothing to do with it`: https://github.com/jayphelps/git-blame-someone-elseh]h}(h]nothing-to-do-with-itah ]h"]nothing to do with itah$]h&]j5juh1hhMhjhhhhjNKubh)}(hhh](h)}(h!Configure git to use your PGP keyh]h!Configure git to use your PGP key}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj4hhhhhMubh)}(hXIf 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)::h](hIf 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 (}(hjEhhhNhNubj)}(h ``[fpr]``h]h[fpr]}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjEubh! is the fingerprint of your key):}(hjEhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj4hhubj)}(h+$ git config --global user.signingKey [fpr]h]h+$ git config --global user.signingKey [fpr]}hjesbah}(h]h ]h"]h$]h&]jjuh1jhhhMhj4hhubeh}(h]!configure-git-to-use-your-pgp-keyah ]h"]!configure git to use your pgp keyah$]h&]uh1hhjhhhhhMubh)}(hhh](h)}(hHow to work with signed tagsh]hHow to work with signed tags}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj{hhhhhMubh)}(hJTo create a signed tag, simply pass the ``-s`` switch to the tag command::h](h(To create a signed tag, simply pass the }(hjhhhNhNubj)}(h``-s``h]h-s}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh switch to the tag command:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj{hhubj)}(h$ git tag -s [tagname]h]h$ git tag -s [tagname]}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMhj{hhubh)}(hOur 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.h]hOur 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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj{hhubh)}(hhh](h)}(hHow to verify signed tagsh]hHow to verify signed tags}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(h?To verify a signed tag, simply use the ``verify-tag`` command::h](h'To verify a signed tag, simply use the }(hjhhhNhNubj)}(h``verify-tag``h]h verify-tag}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh command:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(h$ git verify-tag [tagname]h]h$ git verify-tag [tagname]}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMhjhhubh)}(hIf 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::h]hIf 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:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(h$ git pull [url] tags/sometagh]h$ git pull [url] tags/sometag}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMhjhhubh)}(h4The merge message will contain something like this::h]h3The merge message will contain something like this:}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hiMerge tag 'sometag' of [url] [Tag message] # gpg: Signature made [...] # gpg: Good signature from [...]h]hiMerge tag 'sometag' of [url] [Tag message] # gpg: Signature made [...] # gpg: Good signature from [...]}hj1sbah}(h]h ]h"]h$]h&]jjuh1jhhhMhjhhubh)}(hIf you are verifying someone else's git tag, then you will need to import their PGP key. Please refer to the ":ref:`verify_identities`" section below.h](hrIf you are verifying someone else’s git tag, then you will need to import their PGP key. Please refer to the “}(hj?hhhNhNubh)}(h:ref:`verify_identities`h]hinline)}(hjIh]hverify_identities}(hjMhhhNhNubah}(h]h ](xrefstdstd-refeh"]h$]h&]uh1jKhjGubah}(h]h ]h"]h$]h&]refdocprocess/maintainer-pgp-guide refdomainjXreftyperef refexplicitrefwarn reftargetverify_identitiesuh1hhhhMhj?ubh” section below.}(hj?hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubeh}(h]how-to-verify-signed-tagsah ]h"]how to verify signed tagsah$]h&]uh1hhj{hhhhhMubh)}(hhh](h)}(h+Configure git to always sign annotated tagsh]h+Configure git to always sign annotated tags}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj~hhhhhMubh)}(hChances 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::h]hChances 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:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj~hhubj)}(h1$ git config --global tag.forceSignAnnotated trueh]h1$ git config --global tag.forceSignAnnotated true}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMhj~hhubeh}(h]+configure-git-to-always-sign-annotated-tagsah ]h"]+configure git to always sign annotated tagsah$]h&]uh1hhj{hhhhhMubeh}(h]how-to-work-with-signed-tagsah ]h"]how to work with signed tagsah$]h&]uh1hhjhhhhhMubh)}(hhh](h)}(hHow to work with signed commitsh]hHow to work with signed commits}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hXIt 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. Furthermore, when rebasing your repository to match upstream, even your own PGP commit signatures will end up discarded. For this reason, most kernel developers don't bother signing their commits and will ignore signed commits in any external repositories that they rely upon in their work.h]hXIt 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. Furthermore, when rebasing your repository to match upstream, even your own PGP commit signatures will end up discarded. For this reason, most kernel developers don’t bother signing their commits and will ignore signed commits in any external repositories that they rely upon in their work.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hXHowever, 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.h]hXHowever, 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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(h,We recommend this for the following reasons:h]h,We recommend this for the following reasons:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hhh](j)}(hShould there ever be a need to perform code forensics or track code provenance, even externally maintained trees carrying PGP commit signatures will be valuable for such purposes.h]h)}(hShould there ever be a need to perform code forensics or track code provenance, even externally maintained trees carrying PGP commit signatures will be valuable for such purposes.h]hShould there ever be a need to perform code forensics or track code provenance, even externally maintained trees carrying PGP commit signatures will be valuable for such purposes.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hIf you ever need to re-clone your local repository (for example, after a disk failure), this lets you easily verify the repository integrity before resuming your work.h]h)}(hIf you ever need to re-clone your local repository (for example, after a disk failure), this lets you easily verify the repository integrity before resuming your work.h]hIf you ever need to re-clone your local repository (for example, after a disk failure), this lets you easily verify the repository integrity before resuming your work.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hwIf someone needs to cherry-pick your commits, this allows them to quickly verify their integrity before applying them. h]h)}(hvIf someone needs to cherry-pick your commits, this allows them to quickly verify their integrity before applying them.h]hvIf someone needs to cherry-pick your commits, this allows them to quickly verify their integrity before applying them.}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj)ubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]jgjhjihjjjkuh1jhjhhhhhMubh)}(hhh](h)}(hCreating signed commitsh]hCreating signed commits}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjGhhhhhMubh)}(hTo 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)::h](h5To create a signed commit, you just need to pass the }(hjXhhhNhNubj)}(h``-S``h]h-S}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjXubh flag to the }(hjXhhhNhNubj)}(h``git commit``h]h git commit}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjXubh command (it’s capital }(hjXhhhNhNubj)}(h``-S``h]h-S}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjXubh% due to collision with another flag):}(hjXhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjGhhubj)}(h$ git commit -Sh]h$ git commit -S}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMhjGhhubeh}(h]creating-signed-commitsah ]h"]creating signed commitsah$]h&]uh1hhjhhhhhMubh)}(hhh](h)}(h$Configure git to always sign commitsh]h$Configure git to always sign commits}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(h)You can tell git to always sign commits::h]h(You can tell git to always sign commits:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(h'git config --global commit.gpgSign trueh]h'git config --global commit.gpgSign true}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMhjhhubj_)}(h>Make sure you configure ``gpg-agent`` before you turn this on.h]h)}(hjh](hMake sure you configure }(hjhhhNhNubj)}(h ``gpg-agent``h]h gpg-agent}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh before you turn this on.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1j^hjhhhhhNubh)}(h.. _verify_identities:h]h}(h]h ]h"]h$]h&]hverify-identitiesuh1hhMhjhhhhubeh}(h]$configure-git-to-always-sign-commitsah ]h"]$configure git to always sign commitsah$]h&]uh1hhjhhhhhMubeh}(h]how-to-work-with-signed-commitsah ]h"]how to work with signed commitsah$]h&]uh1hhjhhhhhMubh)}(hhh](h)}(hHow to work with signed patchesh]hHow to work with signed patches}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj#hhhhhM ubh)}(hXaIt is possible to use your PGP key to sign patches sent to kernel developer mailing lists. Since existing email signature mechanisms (PGP-Mime or PGP-inline) tend to cause problems with regular code review tasks, you should use the tool kernel.org created for this purpose that puts cryptographic attestation signatures into message headers (a-la DKIM):h]hXaIt is possible to use your PGP key to sign patches sent to kernel developer mailing lists. Since existing email signature mechanisms (PGP-Mime or PGP-inline) tend to cause problems with regular code review tasks, you should use the tool kernel.org created for this purpose that puts cryptographic attestation signatures into message headers (a-la DKIM):}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj#hhubj})}(hhh]j)}(h`Patatt Patch Attestation`_ h]h)}(h`Patatt Patch Attestation`_h]h)}(hjKh]hPatatt Patch Attestation}(hjMhhhNhNubah}(h]h ]h"]h$]h&]namePatatt Patch Attestationj5 https://pypi.org/project/patatt/uh1hhjIj7Kubah}(h]h ]h"]h$]h&]uh1hhhhMhjEubah}(h]h ]h"]h$]h&]uh1jhjBhhhhhNubah}(h]h ]h"]h$]h&]jjuh1j|hhhMhj#hhubh)}(h@.. _`Patatt Patch Attestation`: https://pypi.org/project/patatt/h]h}(h]patatt-patch-attestationah ]h"]patatt patch attestationah$]h&]j5j\uh1hhMhj#hhhhjNKubh)}(hhh](h)}(h!Installing and configuring patatth]h!Installing and configuring patatt}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj{hhhhhMubh)}(hPatatt is packaged for many distributions already, so please check there first. You can also install it from pypi using "``pip install patatt``".h](h{Patatt is packaged for many distributions already, so please check there first. You can also install it from pypi using “}(hjhhhNhNubj)}(h``pip install patatt``h]hpip install patatt}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh”.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj{hhubh)}(hXIf you already have your PGP key configured with git (via the ``user.signingKey`` configuration parameter), then patatt requires no further configuration. You can start signing your patches by installing the git-send-email hook in the repository you want::h](h>If you already have your PGP key configured with git (via the }(hjhhhNhNubj)}(h``user.signingKey``h]huser.signingKey}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh configuration parameter), then patatt requires no further configuration. You can start signing your patches by installing the git-send-email hook in the repository you want:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj{hhubj)}(hpatatt install-hookh]hpatatt install-hook}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhM$hj{hhubh)}(hpNow any patches you send with ``git send-email`` will be automatically signed with your cryptographic signature.h](hNow any patches you send with }(hjhhhNhNubj)}(h``git send-email``h]hgit send-email}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh@ will be automatically signed with your cryptographic signature.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM&hj{hhubeh}(h]!installing-and-configuring-patattah ]h"]!installing and configuring patattah$]h&]uh1hhj#hhhhhMubh)}(hhh](h)}(hChecking patatt signaturesh]hChecking patatt signatures}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhM*ubh)}(hIf you are using ``b4`` to retrieve and apply patches, then it will automatically attempt to verify all DKIM and patatt signatures it encounters, for example::h](hIf you are using }(hjhhhNhNubj)}(h``b4``h]hb4}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh to retrieve and apply patches, then it will automatically attempt to verify all DKIM and patatt signatures it encounters, for example:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM,hjhhubj)}(hX$ b4 am 20220720205013.890942-1-broonie@kernel.org [...] Checking attestation on all messages, may take a moment... --- ✓ [PATCH v1 1/3] kselftest/arm64: Correct buffer allocation for SVE Z registers ✓ [PATCH v1 2/3] arm64/sve: Document our actual ABI for clearing registers on syscall ✓ [PATCH v1 3/3] kselftest/arm64: Enforce actual ABI for SVE syscalls --- ✓ Signed: openpgp/broonie@kernel.org ✓ Signed: DKIM/kernel.orgh]hX$ b4 am 20220720205013.890942-1-broonie@kernel.org [...] Checking attestation on all messages, may take a moment... --- ✓ [PATCH v1 1/3] kselftest/arm64: Correct buffer allocation for SVE Z registers ✓ [PATCH v1 2/3] arm64/sve: Document our actual ABI for clearing registers on syscall ✓ [PATCH v1 3/3] kselftest/arm64: Enforce actual ABI for SVE syscalls --- ✓ Signed: openpgp/broonie@kernel.org ✓ Signed: DKIM/kernel.org}hj3sbah}(h]h ]h"]h$]h&]jjuh1jhhhM0hjhhubj_)}(hPatatt and b4 are still in active development and you should check the latest documentation for these projects for any new or updated features.h]h)}(hPatatt and b4 are still in active development and you should check the latest documentation for these projects for any new or updated features.h]hPatatt and b4 are still in active development and you should check the latest documentation for these projects for any new or updated features.}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM=hjAubah}(h]h ]h"]h$]h&]uh1j^hjhhhhhNubh)}(h.. _kernel_identities:h]h}(h]h ]h"]h$]h&]hkernel-identitiesuh1hhMAhjhhhhubeh}(h]checking-patatt-signaturesah ]h"]checking patatt signaturesah$]h&]uh1hhj#hhhhhM*ubeh}(h](how-to-work-with-signed-patchesjeh ]h"](how to work with signed patchesverify_identitieseh$]h&]uh1hhjhhhhhM jL}jrjsjN}jjsubeh}(h](using-pgp-with-gitjeh ]h"](using pgp with git pgp_with_giteh$]h&]uh1hhhhhhhhMjL}j}jsjN}jjsubh)}(hhh](h)}(h)How to verify kernel developer identitiesh]h)How to verify kernel developer identities}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMDubh)}(hSigning 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?h]hSigning 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?}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMFhjhhubh)}(hhh](h)}(h/Configure auto-key-retrieval using WKD and DANEh]h/Configure auto-key-retrieval using WKD and DANE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMKubh)}(hXiIf 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.h]hXkIf 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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMMhjhhubh)}(h1Add the following to your ``~/.gnupg/gpg.conf``::h](hAdd the following to your }(hjhhhNhNubj)}(h``~/.gnupg/gpg.conf``h]h~/.gnupg/gpg.conf}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMThjhhubj)}(h0auto-key-locate wkd,dane,local auto-key-retrieveh]h0auto-key-locate wkd,dane,local auto-key-retrieve}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMVhjhhubh)}(hXDNS-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.h]hXDNS-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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMYhjhhubh)}(hKernel.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)::h](hvKernel.org publishes the WKD for all developers who have kernel.org accounts. Once you have the above changes in your }(hjhhhNhNubj)}(h ``gpg.conf``h]hgpg.conf}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhn, you can auto-retrieve the keys for Linus Torvalds and Greg Kroah-Hartman (if you don’t already have them):}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMahjhhubj)}(h9$ gpg --locate-keys torvalds@kernel.org gregkh@kernel.orgh]h9$ gpg --locate-keys torvalds@kernel.org gregkh@kernel.org}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMfhjhhubh)}(hIf you have a kernel.org account, then you should `add the kernel.org UID to your key`_ to make WKD more useful to other kernel developers.h](h2If you have a kernel.org account, then you should }(hj*hhhNhNubh)}(h%`add the kernel.org UID to your key`_h]h"add the kernel.org UID to your key}(hj2hhhNhNubah}(h]h ]h"]h$]h&]name"add the kernel.org UID to your keyj5Phttps://korg.wiki.kernel.org/userdoc/mail#adding_a_kernelorg_uid_to_your_pgp_keyuh1hhj*j7Kubh4 to make WKD more useful to other kernel developers.}(hj*hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhhjhhubh)}(hz.. _`add the kernel.org UID to your key`: https://korg.wiki.kernel.org/userdoc/mail#adding_a_kernelorg_uid_to_your_pgp_keyh]h}(h]"add-the-kernel-org-uid-to-your-keyah ]h"]"add the kernel.org uid to your keyah$]h&]j5jBuh1hhMkhjhhhhjNKubeh}(h]/configure-auto-key-retrieval-using-wkd-and-daneah ]h"]/configure auto-key-retrieval using wkd and daneah$]h&]uh1hhjhhhhhMKubh)}(hhh](h)}(h0Web of Trust (WOT) vs. Trust on First Use (TOFU)h]h0Web of Trust (WOT) vs. Trust on First Use (TOFU)}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjahhhhhMnubh)}(hXHPGP 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.h]hXLPGP 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.}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMphjahhubh)}(hXUnfortunately, 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.h]hXUnfortunately, 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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMvhjahhubh)}(hWe 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``::h](hWe 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 }(hjhhhNhNubj)}(h``trust-model``h]h trust-model}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh setting in }(hjhhhNhNubj)}(h``~/.gnupg/gpg.conf``h]h~/.gnupg/gpg.conf}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjahhubj)}(htrust-model tofu+pgph]htrust-model tofu+pgp}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhMhjahhubeh}(h]+web-of-trust-wot-vs-trust-on-first-use-tofuah ]h"]0web of trust (wot) vs. trust on first use (tofu)ah$]h&]uh1hhjhhhhhMnubh)}(hhh](h)}(h,Using the kernel.org web of trust repositoryh]h,Using the kernel.org web of trust repository}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hXKernel.org maintains a git repository with developers' public keys as a replacement for replicating keyserver networks that have gone mostly dark in the past few years. The full documentation for how to set up that repository as your source of public keys can be found here:h]hXKernel.org maintains a git repository with developers’ public keys as a replacement for replicating keyserver networks that have gone mostly dark in the past few years. The full documentation for how to set up that repository as your source of public keys can be found here:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj})}(hhh]j)}(h `Kernel developer PGP Keyring`_ h]h)}(h`Kernel developer PGP Keyring`_h]h)}(hjh]hKernel developer PGP Keyring}(hjhhhNhNubah}(h]h ]h"]h$]h&]nameKernel developer PGP Keyringj5)https://korg.docs.kernel.org/pgpkeys.htmluh1hhjj7Kubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubah}(h]h ]h"]h$]h&]jjuh1j|hhhMhjhhubh)}(hcIf you are a kernel developer, please consider submitting your key for inclusion into that keyring.h]hcIf you are a kernel developer, please consider submitting your key for inclusion into that keyring.}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hM.. _`Kernel developer PGP Keyring`: https://korg.docs.kernel.org/pgpkeys.htmlh]h}(h]kernel-developer-pgp-keyringah ]h"]kernel developer pgp keyringah$]h&]j5juh1hhMhjhhhhjNKubeh}(h],using-the-kernel-org-web-of-trust-repositoryah ]h"],using the kernel.org web of trust repositoryah$]h&]uh1hhjhhhhhMubeh}(h]()how-to-verify-kernel-developer-identitiesjceh ]h"]()how to verify kernel developer identitieskernel_identitieseh$]h&]uh1hhhhhhhhMDjL}jJjYsjN}jcjYsubeh}(h](kernel-maintainer-pgp-guideheh ]h"](kernel maintainer pgp guidepgpguideeh$]h&]uh1hhhhhhhhKjL}jUhsjN}hhsubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj}error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}(protecting code integrity](j%jenitrokey start]j7 agnuk]jL anitrokey pro 2]ju a yubikey 5]j a!qualify for a free nitrokey start]j aagent forwarding over ssh]jvanothing to do with it]japatatt patch attestation]jMa"add the kernel.org uid to your key]j2akernel developer pgp keyring]jaurefids}(h]haj ]jajB]j8aj]jxaj ]j aj]jaj]jajc]jYaunameids}(jUhjTjQjKjHjUjRjIj jHjEjjBjjjjjjj jj j jjj(j%jjjdjaj3 j0 j j j j jj jjj j jA j> j j j j j! j j- j* j9 j6 j j jjjjjjjjjjjjjIjFjjjjj}jj|jyj1j.jxjujjj{jxjjj jjjjjjrjjqjnjxjujjjijfjJjcjIjFj^j[jVjSjjjAj>j9j6u nametypes}(jUjTjKjUjIjHjjjjj j jj(jjdj3 j j jjj jA j j j! j- j9 j jjjjjjjIjjj}j|j1jxjj{jj jjjrjqjxjjijJjIj^jVjjAj9uh}(hhjQhjHjBjRjOj j jEj jBjXjjXjjijjjjj jjjj%jjj+jajj0 jgj j6 j j j j jj j j j> j j j j j j j j* j$ j6 j0 j jD jj jjjjjjjj#jjjFjjjLjjjjjyjj.j(juj4jj{jxjjj~jjjjGjjjj#jnj#jujojj{jfjjcjjFjj[jjSjMjjaj>jj6j0u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jKsRparse_messages]transform_messages](hsystem_message)}(hhh]h)}(hhh]h.Hyperlink target "pgpguide" is not referenced.}hjsbah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcehlineKuh1jubj)}(hhh]h)}(hhh]h4Hyperlink target "devs-not-infra" is not referenced.}hjsbah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypejsourcehlineK&uh1jubj)}(hhh]h)}(hhh]h/Hyperlink target "pgp-tools" is not referenced.}hj9sbah}(h]h ]h"]h$]h&]uh1hhj6ubah}(h]h ]h"]h$]h&]levelKtypejsourcehlineK:uh1jubj)}(hhh]h)}(hhh]h6Hyperlink target "protect-your-key" is not referenced.}hjSsbah}(h]h ]h"]h$]h&]uh1hhjPubah}(h]h ]h"]h$]h&]levelKtypejsourcehlineKjuh1jubj)}(hhh]h)}(hhh]h0Hyperlink target "smartcards" is not referenced.}hjmsbah}(h]h ]h"]h$]h&]uh1hhjjubah}(h]h ]h"]h$]h&]levelKtypejsourcehlineMjuh1jubj)}(hhh]h)}(hhh]h2Hyperlink target "pgp-with-git" is not referenced.}hjsbah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypejsourcehlineMuh1jubj)}(hhh]h)}(hhh]h7Hyperlink target "verify-identities" is not referenced.}hjsbah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypejsourcehlineMuh1jubj)}(hhh]h)}(hhh]h7Hyperlink target "kernel-identities" is not referenced.}hjsbah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypejsourcehlineMAuh1jube transformerN include_log] decorationNhhub.