Project:Gentoo-keys/Generating GLEP 63 based OpenPGP keys

From Gentoo Wiki
Jump to: navigation, search
Warning
This page is a work in progress by Whissi (talk | contribs). Treat its contents with caution.
Warning
This article represents the views of a single Gentoo developer that are not consistent with the official best Gentoo practices. Please treat its contents with caution. When in doubt, please consult GLEP 63 as the official standard.

General info

In this guide we are going to show you how to create a GLEP 63 based OpenPGP Key following best practice.

OpenPGP

OpenPGP is one of the most widely used cryptographic standards in the world. The OpenPGP standard was originally derived from PGP (Pretty Good Privacy), first created by Phil Zimmermann in 1991, and is now maintained by the OpenPGP Working Group of the Internet Engineering Task Force. One of the most used open source implementations of the OpenPGP standard is the GNU Privacy Guard (GnuPG).

The OpenPGP standard is a hybrid scheme utilizing both asymmetrical and symmetrical cryptography to establish the cryptosystem. The asymmetrical components are used to establish a nPKI (Public Key Infrastructure) ad when mentioning keys in this document, it is a reference to the asymmetrical components. It is a hybrid system when used for data encryption, as the data itself is encrypted symmetrically using a random session key, which is afterwards encrypted individually using the asymmetrical encryption keys of each recipient.

OpenPGP keys (i.e. asymmetrical) normally consists of a primary key used for certification and signing and a subkey capable of Encryption. This is often extended to using a primary key for certification purposes only, and separate subkeys for Signing and Encryption. Such a scheme allows for the primary key to be stored offline, while the subkeys are used for day-to-day use.

When generating a new User ID, a new subkey, creating a certification (signature) of another key, or performing revocation procedures, the primary key will have to be used, and as such these operations are normally conducted on a more secure system. As certifications by other users are tied to the primary key, as components structured below the User ID and User Attribute, this allows for key-rotation without losing existing certificates of the key, e.g. in the event of a key compromise due to loss of a device.

GLEP 63

GLEP 63 is a proposal accepted by the Gentoo Council which provides both a minimum requirement and a recommended set of OpenPGP key management policies for the use of GnuPG by Gentoo Linux developers. It is intended to provide a basis for future improvements such as consistent ebuild or package signing and the possibility of verification of integrity by end users.

How to generate the perfect GLEP 63-compliant OpenPGP key

In the next few steps we will show you how to generate the perfect GLEP 63-compliant OpenPGP key. We used the term perfect key because this key should last for next 10 years and be flexible enough to support as many setups as possible (e.g. various hardware token). In the end this key should allow you to become part of the Web of Trust while helping to keep Gentoo secure.

Step 1: Install the tools you will need

We will need the normal GnuPG 2.x CLI client. If it is not installed yet, you can install it with

root #emerge --ask app-crypt/gnupg

Step 2: Backup your existing GnuPG setup

First, backup your existing GnuPG configuration, including your private keyring. You can display the location of your current GnuPG configuration and keyrings with:

user $gpgconf --list-dirs
sysconfdir:/etc/gnupg
bindir:/usr/bin
libexecdir:/usr/libexec
libdir:/usr/lib64/gnupg
datadir:/usr/share/gnupg
localedir:/usr/share/locale
socketdir:/home/larry/.gnupg
dirmngr-socket:/home/larry/.gnupg/S.dirmngr
agent-ssh-socket:/home/larry/.gnupg/S.gpg-agent.ssh
agent-extra-socket:/home/larry/.gnupg/S.gpg-agent.extra
agent-browser-socket:/home/larry/.gnupg/S.gpg-agent.browser
agent-socket:/home/larry/.gnupg/S.gpg-agent
homedir:/home/larry/.gnupg

Now that you know your GnuPG's current homedir (/home/larry/.gnupg in this example), you can create a backup of your current GnuPG configuration, including your keyrings:

user $(umask 077 && tar -caf $HOME/gnupg-backup_`date +%Y%m%d_%H%M%S`.tar.xz -C $HOME .gnupg)
tar: .gnupg/S.gpg-agent.extra: socket ignored
tar: .gnupg/S.gpg-agent.browser: socket ignored
tar: .gnupg/S.gpg-agent: socket ignored
tar: .gnupg/S.gpg-agent.ssh: socket ignored

(we use umask to restrict access to the backup file; Please note the parenthesis -- we are running the command in a subshell to avoid resetting umask afterwards; It is safe to ignore the warnings regarding ignored sockets above)

Note
If your homedir is not in $HOME/.gnupg, you have to adjust the end of the tar command above accordingly!
Important
In case you are using a customized GnuPG configuration it is possible that your keyring is not stored in GnuPG's homedir. We therefore recommend that you check that the output of
user $gpg --list-secret-keys
/home/larry/.gnupg/pubring.kbx
------------------------------
sec   rsa2048 2016-01-28 [SC] [expires: 2020-01-27]
      9AAC460432EA972BD950D9C6F76839562DD99092
uid           [ultimate] Larry the Cow <larry@the-cow.de>
ssb   rsa2048 2016-01-28 [E] [expires: 2018-01-27]
doesn't contain a path outside of the previous homedir value or include that path in the tar command above to create a complete backup.

Step 3: Update your gpg.conf

This step is optional but recommended: Make sure your gpg.conf (usually located in $HOME/.gnupg/gpg.conf) contains the following settings:

FILE $HOME/.gnupg/gpg.conf
# Assume that command line arguments are given as UTF8 strings.
utf8-strings

# when outputting certificates, view user IDs distinctly from keys:
fixed-list-mode

# long keyids are more collision-resistant than short keyids (it's trivial to make a key
# with any desired short keyid)
# NOTE: this breaks kmail gnupg support!
keyid-format 0xlong

# when multiple digests are supported by all recipients, choose the strongest one:
personal-digest-preferences SHA512 SHA384 SHA256 SHA224

# preferences chosen for new keys should prioritize stronger algorithms:
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 BZIP2 ZLIB ZIP Uncompressed

# You should always know at a glance which User IDs gpg thinks are legitimately bound to
# the keys in your keyring:
verify-options show-uid-validity
list-options show-uid-validity

# include an unambiguous indicator of which key made a signature:
# (see http://thread.gmane.org/gmane.mail.notmuch.general/3721/focus=7234)
# (and http://www.ietf.org/mail-archive/web/openpgp/current/msg00405.html)
sig-notation issuer-fpr@notations.openpgp.fifthhorseman.net=%g

# when making an OpenPGP certification, use a stronger digest than the default SHA1:
cert-digest-algo SHA512
s2k-cipher-algo AES256
s2k-digest-algo SHA512

Step 4: Create your new master key

With the configuration from above in place, your new master key can be created. The master key will only have the capability "Certify" and is only needed when the key is modified or when you sign someone else's key. Separating capabilities will allow you to split master key from subkeys so that you can keep master key in a secure, air-gaped, environment for example.

user $gpg --expert --full-generate-key
gpg (GnuPG) 2.2.9; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
   (9) ECC and ECC
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (13) Existing key
Your selection? 8

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? s

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? e

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 900d
Key expires at Fri 12 Feb 2021 03:38:44 PM CET
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: Larry the Cow
Email address: larry@the-cow.de
Comment:
You selected this USER-ID:
    "Larry the Cow <larry@the-cow.de>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key 5C6A132050668578 marked as ultimately trusted
gpg: revocation certificate stored as '/home/larry/.gnupg/openpgp-revocs.d/EFA6F1BD36FA9FDE3C0432975C6A132050668578.rev'
public and secret key created and signed.

pub   rsa4096 2018-08-27 [C] [expires: 2021-02-12]
      EFA6F1BD36FA9FDE3C0432975C6A132050668578
uid                      Larry the Cow <larry@the-cow.de>

Step 5: Create subkeys

To be able to sign commits or push signed to any Gentoo repository, we will need a subkey with "Sign" capability. Therefore we will create a RSA key with keysize of 2048 bits and a validity of 1 year (note that we will use the previous shown fingerprint when we specify which key we want to edit):

user $gpg --expert --edit-key EFA6F1BD36FA9FDE3C0432975C6A132050668578
gpg (GnuPG) 2.2.9; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
gpg: next trustdb check due at 2020-01-27
sec  rsa4096/5C6A132050668578
     created: 2018-08-27  expires: 2021-02-12  usage: C
     trust: ultimate      validity: ultimate
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> addkey
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
Your selection? 8

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? e

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Tue 27 Aug 2019 04:48:13 PM CEST
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

sec  rsa4096/5C6A132050668578
     created: 2018-08-27  expires: 2021-02-12  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa2048/3B3FD31FA2609F1F
     created: 2018-08-27  expires: 2019-08-27  usage: S
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> q
Save changes? (y/N) y
Note
We chose a keysize of 2048bits instead of 4096bits because signing with a 4096bit key is much slower than using a 2048bits key while security improvement in using a 4096bits key over a 2048bits key is minimal[1].


We chose an expiration date in 1 year to enable something like a dead man switch. TODO: Explain dead man switch.


Of course you could also create an ECC subkey instead of an RSA subkey for signing. But as best practice we recommend keeping RSA keys for now because using ECC would cause trouble for anyone outside Gentoo who wants to verify stuff you signed if they don't have ECC support yet.

But don't worry: The good thing about this perfect OpenGPG key setup is, that it allows you to switch to ECC subkeys in future if ECC support become a standard without the need to re-create a new complete new key so you won't lose your gained Web of Trust.

Now it is also recommended that you will create a subkey you can use for encryption. This will allow you to encrypt files against your OpenPGP key and allow others to send you encrypted messages for example:

user $gpg --expert --edit-key EFA6F1BD36FA9FDE3C0432975C6A132050668578
gpg (GnuPG) 2.2.9; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa4096/5C6A132050668578
     created: 2018-08-27  expires: 2021-02-12  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa2048/3B3FD31FA2609F1F
     created: 2018-08-27  expires: 2019-08-27  usage: S
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> addkey
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
Your selection? 8

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? s

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Tue 27 Aug 2019 05:05:35 PM CEST
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

sec  rsa4096/5C6A132050668578
     created: 2018-08-27  expires: 2021-02-12  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa2048/3B3FD31FA2609F1F
     created: 2018-08-27  expires: 2019-08-27  usage: S
ssb  rsa2048/B08BA148BB85CE7B
     created: 2018-08-27  expires: 2019-08-27  usage: E
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> q
Save changes? (y/N) y

Step 6: Add a subkey for authentication

This step is optional. If you want to use your OpenPGP key for SSH authentication as well, it is recommended to add a dedicated subkey just for authentication:

user $gpg --expert --edit-key EFA6F1BD36FA9FDE3C0432975C6A132050668578
gpg (GnuPG) 2.2.9; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa4096/5C6A132050668578
     created: 2018-08-27  expires: 2021-02-12  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa2048/3B3FD31FA2609F1F
     created: 2018-08-27  expires: 2019-08-27  usage: S
ssb  rsa2048/B08BA148BB85CE7B
     created: 2018-08-27  expires: 2019-08-27  usage: E
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> addkey
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
Your selection? 11

Possible actions for a ECDSA/EdDSA key: Sign Authenticate
Current allowed actions: Sign

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? s

Possible actions for a ECDSA/EdDSA key: Sign Authenticate
Current allowed actions:

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? a

Possible actions for a ECDSA/EdDSA key: Sign Authenticate
Current allowed actions: Authenticate

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
Please select which elliptic curve you want:
   (1) Curve 25519
   (3) NIST P-256
   (4) NIST P-384
   (5) NIST P-521
   (6) Brainpool P-256
   (7) Brainpool P-384
   (8) Brainpool P-512
   (9) secp256k1
Your selection? 1
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Tue 27 Aug 2019 05:18:12 PM CEST
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

sec  rsa4096/5C6A132050668578
     created: 2018-08-27  expires: 2021-02-12  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa2048/3B3FD31FA2609F1F
     created: 2018-08-27  expires: 2019-08-27  usage: S
ssb  rsa2048/B08BA148BB85CE7B
     created: 2018-08-27  expires: 2019-08-27  usage: E
ssb  ed25519/4286BF690A6B34B8
     created: 2018-08-27  expires: 2019-08-27  usage: A
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> q
Save changes? (y/N) y

Summary

The creation of your new, perfect GLEP 63-compliant OpenPGP key is now completed. Let's view your new key:

user $gpg --list-key EFA6F1BD36FA9FDE3C0432975C6A132050668578
pub   rsa4096/0x5C6A132050668578 2018-08-27 [C] [expires: 2021-02-12]
      EFA6F1BD36FA9FDE3C0432975C6A132050668578
uid                   [ultimate] Larry the Cow <larry@the-cow.de>
sub   rsa2048/0x3B3FD31FA2609F1F 2018-08-27 [S] [expires: 2019-08-27]
sub   rsa2048/0xB08BA148BB85CE7B 2018-08-27 [E] [expires: 2019-08-27]
sub   ed25519/0x4286BF690A6B34B8 2018-08-27 [A] [expires: 2019-08-27]

Next steps

Submit your new key to the keyserver

Once you're satisfied with the newly generated key is configured as you want it, the key should be published to an operational keyserver pool using:

user $gpg --keyserver pool.sks-keyservers.net --send-keys EFA6F1BD36FA9FDE3C0432975C6A132050668578
gpg: sending key 0x5C6A132050668578 to hkp://pool.sks-keyservers.net

Updating LDAP

It is important that you update the LDAP entry on woodpecker, so that your new key will be recognized and is allowed to push to Gentoo repositories. See this FAQ entry for more details.

Split key

Add information how to split key so that you can keep master key on an air-gaped system for example and/or use keycard, YubiKey...

Fix an existing key

If you already have an existing OpenPGP key and maybe want to keep your received signatures (i.e. Web of Trust status), it maybe possible to just fix your existing key to become GLEP 63-compliant. The following guide will show you some examples and how you fix them.

Let's assume your key looks like

user $gpg --list-key 9AAC460432EA972BD950D9C6F76839562DD99092
pub   rsa2048/0xF76839562DD99092 2016-01-28 [SC] [expires: 2026-01-25]
      9AAC460432EA972BD950D9C6F76839562DD99092
uid                   [ultimate] Larry the Cow <larry@the-cow.de>
sub   rsa2048/0x594CA20866E92013 2016-01-28 [E]
sub   rsa1024/0x5AD7FB3114AA19AD 2016-01-28 [SA] [expires: 2019-01-27]

What's wrong with this key? Let's assume today's date is 2018-08-27:

  • This key violates
    2. Signing subkey that is different from the primary key, and does not have any other capabilities enabled
    because the subkey (0x5AD7FB3114AA19AD) has both, "Sign" and "Authenticate" capability enabled.
  • This key violates
    3. Primary key and the signing subkey are both of type EITHER:\na) RSA, >=2048 bits (OpenPGP v4 key format or later only),
    because the signing subkey has a keysize <2048 bits.
  • This key violates
    4. Expiration date on key and all subkeys set to no more than 900 days into the future.
    because the master key doesn't expire within next 900 days and the encryption subkey (0x594CA20866E92013) has no expiration date set at all.
  • This key violates
    6. UID using your @gentoo.org e-mail included in the key.
    because Larry the Cow hasn't added his Gentoo UID (@gentoo.org address).

Replace an invalid subkey

To fix a violation of requirement #2 and #3 we have to replace violating subkey with new subkey. Because you cannot really remove a subkey, we will expire the offending subkey first and add a new afterwards.

We cannot set a negative expire value but we want to do it now, so we need a workaround: We will use sys-libs/libfaketime and work in the history:

root #emerge --ask sys-libs/libfaketime
user $faketime -f "-2d" bash

Now verify that sys-libs/libfaketime is properly configured:

user $date
Sun Aug 26 20:21:32 CEST 2018

We are now 2 days in the past in this bash process, so we can expire the invalid subkey:

user $gpg --expert --edit-key 9AAC460432EA972BD950D9C6F76839562DD99092
gpg (GnuPG) 2.2.9; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2026-01-25  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: never       usage: E
ssb  rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expires: 2019-01-27  usage: SA
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> key 2

sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2026-01-25  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: never       usage: E
ssb* rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expires: 2019-01-27  usage: SA
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> expire
Changing expiration time for a subkey.
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1d
Key expires at Sun 26 Aug 2018 08:23:54 PM CEST
Is this correct? (y/N) y

sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2026-01-25  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: never       usage: E
ssb* rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expires: 2018-08-26  usage: SA
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> save

Now we can reset date to normal:

user $exit

When we now view the key again, the violating subkey will no longer be displayed:

user $gpg --list-key 9AAC460432EA972BD950D9C6F76839562DD99092
pub   rsa2048/0xF76839562DD99092 2016-01-28 [SC] [expires: 2026-01-25]
      9AAC460432EA972BD950D9C6F76839562DD99092
uid                   [ultimate] Larry the Cow <larry@the-cow.de>
sub   rsa2048/0x594CA20866E92013 2016-01-28 [E]

Now we can add our new, valid, signing subkey:

user $gpg --expert --edit-key 9AAC460432EA972BD950D9C6F76839562DD99092
gpg (GnuPG) 2.2.9; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2026-01-25  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: never       usage: E
ssb  rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expired: 2018-08-26  usage: SA
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> addkey
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
Your selection? 8

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? e

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Tue 27 Aug 2019 08:31:22 PM CEST
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2026-01-25  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: never       usage: E
ssb  rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expired: 2018-08-26  usage: SA
ssb  rsa2048/0x0B45B2392BA396A2
     created: 2018-08-27  expires: 2019-08-27  usage: S
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> q
Save changes? (y/N) y
Note
GnuPG will always use the most recent, usable, subkey. Because the previous signing key is now marked as expired and there's a newer unexpired subkey with signing capability, the previous subkey will no longer being used.
Warning
In this example we have disabled a subkey which could have been used for authentication. If you used this key for authentication don't forget to add a new subkey for authentication (see step 6) and update your authorized_keys file/LDAP or you will lose access to systems where you previously used this key for authentication.

Invalid expiration date

An OpenPGP key can have an expiration date for the master key itself and a unique/Independent expiration date for each subkey. In the example above, we have to fix two expiration dates:

  • For the master key (currently set to 2026-01-25 which violates the maximum expiration date of 900 days)
  • For the encryption key (doesn't have an expiration date at the moment but GLEP 63 requires that every key has an expiration date set)

To fix this, we edit key and set a new expiration date:

user $gpg --expert --edit-key 9AAC460432EA972BD950D9C6F76839562DD99092
gpg (GnuPG) 2.2.9; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2026-01-25  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: never       usage: E
ssb  rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expired: 2018-08-26  usage: SA
ssb  rsa2048/0x0B45B2392BA396A2
     created: 2018-08-27  expires: 2019-08-27  usage: S
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> expire
Changing expiration time for the primary key.
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 900d
Key expires at Fri 12 Feb 2021 07:42:06 PM CET
Is this correct? (y/N) y

sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2021-02-12  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: never       usage: E
ssb  rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expired: 2018-08-26  usage: SA
ssb  rsa2048/0x0B45B2392BA396A2
     created: 2018-08-27  expires: 2019-08-27  usage: S
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> save

Changing the expiration date for the encryption subkey (0x594CA20866E92013) works the same, we just have to make sure we selected the right subkey:

user $gpg --expert --edit-key 9AAC460432EA972BD950D9C6F76839562DD99092
gpg (GnuPG) 2.2.9; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
gpg: next trustdb check due at 2021-02-12
sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2021-02-12  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: never       usage: E
ssb  rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expired: 2018-08-26  usage: SA
ssb  rsa2048/0x0B45B2392BA396A2
     created: 2018-08-27  expires: 2019-08-27  usage: S
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> key 1

sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2021-02-12  usage: SC
     trust: ultimate      validity: ultimate
ssb* rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: never       usage: E
ssb  rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expired: 2018-08-26  usage: SA
ssb  rsa2048/0x0B45B2392BA396A2
     created: 2018-08-27  expires: 2019-08-27  usage: S
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> expire
Changing expiration time for a subkey.
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Tue 27 Aug 2019 08:45:55 PM CEST
Is this correct? (y/N) y

sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2021-02-12  usage: SC
     trust: ultimate      validity: ultimate
ssb* rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: 2019-08-27  usage: E
ssb  rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expired: 2018-08-26  usage: SA
ssb  rsa2048/0x0B45B2392BA396A2
     created: 2018-08-27  expires: 2019-08-27  usage: S
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> save

Of course, you could have changed expiration date for both keys in one step. This guide used two steps to demonstrate how to switch/select key you are working on.

Adding missing Gentoo UID

GLEP 63 requires that the UID of the key is your Gentoo e-mail address. Let's add one to our key:

user $gpg --expert --edit-key 9AAC460432EA972BD950D9C6F76839562DD99092
gpg (GnuPG) 2.2.9; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2021-02-12  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: 2019-08-27  usage: E
ssb  rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expired: 2018-08-26  usage: SA
ssb  rsa2048/0x0B45B2392BA396A2
     created: 2018-08-27  expires: 2019-08-27  usage: S
[ultimate] (1). Larry the Cow <larry@the-cow.de>

gpg> adduid
Real name: Larry the Cow
Email address: larry@gentoo.org
Comment:
You selected this USER-ID:
    "Larry the Cow <larry@gentoo.org>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o

sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2021-02-12  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: 2019-08-27  usage: E
ssb  rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expired: 2018-08-26  usage: SA
ssb  rsa2048/0x0B45B2392BA396A2
     created: 2018-08-27  expires: 2019-08-27  usage: S
[ultimate] (1)  Larry the Cow <larry@the-cow.de>
[ unknown] (2). Larry the Cow <larry@gentoo.org>

gpg> uid 2

sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2021-02-12  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: 2019-08-27  usage: E
ssb  rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expired: 2018-08-26  usage: SA
ssb  rsa2048/0x0B45B2392BA396A2
     created: 2018-08-27  expires: 2019-08-27  usage: S
[ultimate] (1)  Larry the Cow <larry@the-cow.de>
[ unknown] (2)* Larry the Cow <larry@gentoo.org>

gpg> trust
sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2021-02-12  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: 2019-08-27  usage: E
ssb  rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expired: 2018-08-26  usage: SA
ssb  rsa2048/0x0B45B2392BA396A2
     created: 2018-08-27  expires: 2019-08-27  usage: S
[ultimate] (1)  Larry the Cow <larry@the-cow.de>
[ unknown] (2)* Larry the Cow <larry@gentoo.org>

Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

sec  rsa2048/0xF76839562DD99092
     created: 2016-01-28  expires: 2021-02-12  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/0x594CA20866E92013
     created: 2016-01-28  expires: 2019-08-27  usage: E
ssb  rsa1024/0x5AD7FB3114AA19AD
     created: 2016-01-28  expired: 2018-08-26  usage: SA
ssb  rsa2048/0x0B45B2392BA396A2
     created: 2018-08-27  expires: 2019-08-27  usage: S
[ultimate] (1)  Larry the Cow <larry@the-cow.de>
[ unknown] (2)* Larry the Cow <larry@gentoo.org>

gpg> save

Summary

Now that we have fixed all issues, our now GLEP 63-compliant key looks like

user $gpg --list-key 9AAC460432EA972BD950D9C6F76839562DD99092
pub   rsa2048/0xF76839562DD99092 2016-01-28 [SC] [expires: 2021-02-12]
      9AAC460432EA972BD950D9C6F76839562DD99092
uid                   [ultimate] Larry the Cow <larry@gentoo.org>
uid                   [ultimate] Larry the Cow <larry@the-cow.de>
sub   rsa2048/0x594CA20866E92013 2016-01-28 [E] [expires: 2019-08-27]
sub   rsa2048/0x0B45B2392BA396A2 2018-08-27 [S] [expires: 2019-08-27]
Don't forget to submit your updated key to the keyservers so that Gentoo can pick up the changes.
  1. [1], Why doesn’t GnuPG default to using RSA-4096?