I am writing a bash script which generates unattended GPG keys, I have looked through Unattended Usage of GPG and was surprised to find that 'Currently only one subkey can be handled.'

I am unable to find if there is a way to modify a GPG key to add a second subkey using the unattended generation functions available, or if I'll have to add the subkey manually myself.

I have attempted to use here documents, here strings and creating a file with one input per line as well as using printf similar to below:

printf 'addkey' | gpg2 --edit-key 'test@test.com'

With none of these solutions working:

balthasar@magi:~$ printf 'addkey' | gpg2 --edit-key 'test3@test.com'
printf 'addkey' | gpg2 --edit-key 'test3@test.com'
gpg (GnuPG) 2.0.26; Copyright (C) 2013 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  4096R/AB96CED4  created: 2016-12-02  expires: 2017-09-02  usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/71804CF2  created: 2016-12-02  expires: 2017-09-02  usage: E   
[ultimate] (1). test3 <test3@test.com>


My GPG Key File

Key-Type: RSA
Key-Length: 4096
Key-Usage: sign
Subkey-Type: RSA
Subkey-Length: 2048
Subkey-Usage: encrypt
Name-Real: Foo Bar
Name-Email: foobar@test.com
Expire-Date: 2017-09-02

UPDATE: 4, December 2016

I have passed the first hurdle of getting some input to GPG by using the following snippet:

~$ stty -echo; gpg2 --edit-key <keyname> "addkey"

However I am unable to 'pipe' input after running the addkey command.


To have gpg2 read your commands from stdin, use --command-fd=0. To have gpg2 read the passphrase of the master key from where it reads your commands from, use --pinentry-mode=loopback. (gpg2 --help does not list these switches, but they are documented in the man page.) Using these switches, you can communicate with gpg2 non-interactively.

I added a subkey to an existing master key by running bash commands similar to the following ones:

passphrase="my passphrase"
    echo addkey
    echo 4     # RSA (sign only)
    echo 4096  # key length
    echo 0     # key does not expire
    echo y     # is this correct?
    echo y     # really create?
    echo "$passphrase"
    echo save
} | gpg2 --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key $key
| improve this answer | |

Save for the year 2019, this how you do it in an ephemeral home directory:

export GNUPGHOME=$(mktemp -d)
gpg --batch --passphrase '' \
    --quick-generate-key "Firstname Lastname <lastname@example.com>" ed25519 cert 1y

FPR=$(gpg --list-options show-only-fpr-mbox --list-secret-keys | awk '{print $1}')

gpg --batch --passphrase '' \
    --quick-add-key $FPR ed25519 sign 1y
gpg --batch --passphrase '' \
    --quick-add-key $FPR cv25519 encrypt 1y

The trick is to use --quick-add-key.

An authentication subkey can be added similarly. We get:

$ gpg -K
sec   ed25519 2019-04-11 [C] [expires: 2020-04-10]
uid           [ultimate] Firstname Lastname <lastname@example.com>
ssb   ed25519 2019-04-11 [S] [expires: 2020-04-10]
ssb   cv25519 2019-04-11 [E] [expires: 2020-04-10]

$ gpg --version
gpg (GnuPG) 2.2.12
libgcrypt 1.8.4
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy