Updating the Expiration Date of a GPG key

DateReadtime 5 minutes Series Part 2 of Getting Started with GPG Tags

I use gpg to sign my git tags and recently I had an issue where signing failed. Something like:

$ git tag -m "1.5.0" v1.5.0
error: gpg failed to sign the data
error: unable to sign the tag

And after some debugging I discovered that my subkeys had expired!

echo "test" | gpg --clearsign
gpg -K --keyid-format SHORT

Now in order to renew my keys, I needed to recreate an air gapped machine and update the expiration dates, and then export the public key.

Creating an airgapped machine

If you have your private key on a flash drive, you can follow the steps below, skip to the next section if your private key is just available on your local machine's keyring.

I have previously discussed how to start an airgapped machine, but I'll briefly discuss the steps here:

  1. Download the latest LTS ubuntu desktop iso and flash it to a flash drive using "Startup Disk Creator".

    If you need to install that application on Ubuntu:

    sudo apt install usb-creator-gtk
    
  2. Boot the live USB, connect to the internet and download the desired packages:

    sudo add-apt-repository universe
    sudo apt update
    sudo apt-get --download-only install scdaemon libccid pcscd rng-tools5 gnupg2
    
  3. Copy those packages to another USB stick.

    cp -a /var/cache/apt/archives/*.deb /media/usb/my_packages
    
  4. Disconnect from the internet and restart the machine

  5. Install the packages to the live USB

    sudo dpkg -i /media/usb/my_packages/*.deb
    
  6. Connect the USB stick with the GPG keyring

Updating the expiration

To set the expiration, you can use the expire command in gpg --edit-key.

Edit the desired key

List your gpg keys:

paul@paul-Inspiron-N5010 ~> gpg --list-keys
/home/paul/.gnupg/pubring.gpg
-----------------------------
pub   2048R/2A8E8375 2014-03-28 [expires: 2019-03-27]
uid                  Paul R Schwendenman (Shared) <schwendenman.paul@gmail.com>
sub   2048R/D1369210 2014-03-28 [expires: 2019-03-27]

Edit the desired key:

paul@paul-Inspiron-N5010 ~> gpg --edit-key $KEYID
gpg (GnuPG) 1.4.20; Copyright (C) 2015 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.

pub  2048R/2A8E8375  created: 2014-03-28  expires: 2019-03-27  usage: SC
                     trust: ultimate      validity: ultimate
sub  2048R/D1369210  created: 2014-03-28  expires: 2019-03-27  usage: E
[ultimate] (1). Paul R Schwendenman (Shared) <schwendenman.paul@gmail.com>

Primary key

Set the expiration of the primary key:

ubuntu@ubuntu:~$ gpg --edit-key $KEYID
gpg (GnuPG) 2.2.35; Copyright (C) 2022 g10 Code GmbH
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/40D9D08813E47FC4
        created: 2018-06-23  expires: 2023-06-22  usage: SC
        trust: ultimate      validity: ultimate
ssb  rsa2048/2028FB2C79764B90
        created: 2018-06-23  expires: 2023-06-22  usage: S
ssb  rsa2048/6F57ECFEE1290B9A
        created: 2018-06-23  expires: 2023-06-22  usage: E
ssb  rsa2048/D85DC2BE4FE96A4E
        created: 2018-06-23  expires: 2023-06-22  usage: A
ssb  rsa4096/EE22F61DA7080D98
        created: 2019-01-08  expired: 2022-01-07  usage: S
ssb  rsa4096/3A6D709AC83AEE87
        created: 2019-01-08  expired: 2022-01-07  usage: E
ssb  rsa4096/BC1D2BD35CAB6EB2
        created: 2019-01-08  expired: 2022-01-07  usage: A
[ultimate] (1). Paul Schwendenman <schwendenman.paul@gmail.com>
[ultimate] (2)  Paul Schwendenman <paul@whatsdoom.com>

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) 5y
Key expires at Sun 27 Feb 2028 06:16:49 AM UTC
Is this correct? (y/N) y

sec  rsa4096/40D9D08813E47FC4
        created: 2018-06-23  expires: 2028-02-27  usage: SC
        trust: ultimate      validity: ultimate
ssb  rsa4096/EE22F61DA7080D98
        created: 2019-01-08  expired: 2022-01-07  usage: S
ssb  rsa4096/3A6D709AC83AEE87
        created: 2019-01-08  expired: 2022-01-07  usage: E
ssb  rsa4096/BC1D2BD35CAB6EB2
        created: 2019-01-08  expired: 2022-01-07  usage: A
[ultimate] (1)  Paul Schwendenman <schwendenman.paul@gmail.com>
[ultimate] (2). Paul Schwendenman <paul@whatsdoom.com>

gpg> save
ubuntu@ubuntu:~$

Subkeys

Note, you can also set the expiration of multiple sub keys at once:

gpg> key 1

sec  rsa4096/40D9D08813E47FC4
        created: 2018-06-23  expires: 2028-02-27  usage: SC
        trust: ultimate      validity: ultimate
ssb* rsa4096/EE22F61DA7080D98
        created: 2019-01-08  expired: 2022-01-07  usage: S
ssb  rsa4096/3A6D709AC83AEE87
        created: 2019-01-08  expired: 2022-01-07  usage: E
ssb  rsa4096/BC1D2BD35CAB6EB2
        created: 2019-01-08  expired: 2022-01-07  usage: A
[ultimate] (1)  Paul Schwendenman <schwendenman.paul@gmail.com>
[ultimate] (2). Paul Schwendenman <paul@whatsdoom.com>

gpg> key 2

sec  rsa4096/40D9D08813E47FC4
        created: 2018-06-23  expires: 2028-02-27  usage: SC
        trust: ultimate      validity: ultimate
ssb* rsa4096/EE22F61DA7080D98
        created: 2019-01-08  expired: 2022-01-07  usage: S
ssb* rsa4096/3A6D709AC83AEE87
        created: 2019-01-08  expired: 2022-01-07  usage: E
ssb  rsa4096/BC1D2BD35CAB6EB2
        created: 2019-01-08  expired: 2022-01-07  usage: A
[ultimate] (1)  Paul Schwendenman <schwendenman.paul@gmail.com>
[ultimate] (2). Paul Schwendenman <paul@whatsdoom.com>

gpg> key 3

sec  rsa4096/40D9D08813E47FC4
        created: 2018-06-23  expires: 2028-02-27  usage: SC
        trust: ultimate      validity: ultimate
ssb* rsa4096/EE22F61DA7080D98
        created: 2019-01-08  expired: 2022-01-07  usage: S
ssb* rsa4096/3A6D709AC83AEE87
        created: 2019-01-08  expired: 2022-01-07  usage: E
ssb* rsa4096/BC1D2BD35CAB6EB2
        created: 2019-01-08  expired: 2022-01-07  usage: A
[ultimate] (1)  Paul Schwendenman <schwendenman.paul@gmail.com>
[ultimate] (2). Paul Schwendenman <paul@whatsdoom.com>

gpg> expire
Are you sure you want to change the expiration time for multiple subkeys? (y/N) y
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 Wed 28 Feb 2024 06:17:58 AM UTC
Is this correct? (y/N) y

sec  rsa4096/40D9D08813E47FC4
        created: 2018-06-23  expires: 2028-02-27  usage: SC
        trust: ultimate      validity: ultimate
ssb* rsa4096/EE22F61DA7080D98
        created: 2019-01-08  expires: 2024-02-28  usage: S
ssb* rsa4096/3A6D709AC83AEE87
        created: 2019-01-08  expires: 2024-02-28  usage: E
ssb* rsa4096/BC1D2BD35CAB6EB2
        created: 2019-01-08  expires: 2024-02-28  usage: A
[ultimate] (1)  Paul Schwendenman <schwendenman.paul@gmail.com>
[ultimate] (2). Paul Schwendenman <paul@whatsdoom.com>

gpg> save
ubuntu@ubuntu:~$

Exporting the public key

$ gpg2 -a --export $KEYID > public-key.asc

Copy your public key to a USB for later use, I'd recommend the one we used to store the air gapped packages.

Importing the public key on your machine later:

$ gpg2 --import < public-key.asc

Maybe even upload it to a key server:

paul@paul-Inspiron-N5010 ~> gpg --keyserver pgp.mit.edu --send-keys $KEYID
gpg: sending key 2A8E8375 to hkp server pgp.mit.edu