I am trying to attach an imported ssh key to an existing primary key. The imported ssh key exists inside ~/.gnupg/private-keys-v1.d/ and is usable through the gpg-agent. When I associate it manually to a primary key, it works perfectly. I am looking for a way to automate the process through a bash script.
For this example:
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA is the fingerprint of the primary key
- BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB is the keygrip of the imported ssh key to associate to the primary key
Manual execution (it works):
bob@computer:~$ gpg --expert --edit-key AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
gpg (GnuPG) 2.2.12; 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/AAAAAAAAAAAAAAAA
created: 2020-04-01 expires: never usage: SCEA
trust: ultimate validity: ultimate
[ultimate] (1). My name <[email protected]>
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? 13
Enter the keygrip: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
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? e
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions:
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? a
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Authenticate
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? q
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) 0
Key does not expire at all
Is this correct? (y/N) y
Really create? (y/N) y
sec rsa2048/AAAAAAAAAAAAAAAA
created: 2020-04-01 expires: never usage: SCEA
trust: ultimate validity: ultimate
ssb rsa4096/8022F3DA9BFC5AC3
created: 2020-04-01 expires: never usage: A
[ultimate] (1). My name <[email protected]>
gpg> save
bob@computer:~$
We can see that the subkey has been successful associated to the primary key. That's the one with the fingerprint 8022F3DA9BFC5AC3.
Now I will show you the two ways I tried to do it automatically through a bash script.
First, I tried with argument --command-fd (it does not work):
{
echo addkey
echo 13 # Existing key
echo BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
echo
echo S #
echo E #
echo A #
echo Q #
echo 0 # key does not expire
echo save
} | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Then I tried with argument --command-file (it does not work):
cat > /tmp/cmd << EOF
addkey
13
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
S
E
A
Q
0
save
EOF
gpg --expert --command-file=/tmp/cmd --status-fd=1 --pinentry-mode=loopback --edit-key AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
None of these two methods works. The prompt 'Enter the keygrip: ' always shows up. I really want to avoid user interaction in this process. I've tried many stream redirection like piping (with command yes), Here Documents, Here Strings, process substitution, etc. Nothing seems to work to inject the keygrip without a human intervention.
Thanks to a workmate who suggests me the following solution using the expect tool:
Even if this solution works, I am not completely satisfied about it for the following reasons:
So if anyone has a better solution, I am still interested .
For this operation I suspect that using the key fingerprint is not sufficient, instead you need the keygrip of the subkey that you want to import.
Here is how I would do it:
Locate the desired subkey and copy the Keygrip value just below (40 hex characters). Compare this with your current value. There must be something context-specific causing the unattended execution to fail although I can't exactly pinpoint the reason right now. Don't think it has to do with GPG Agent but not sure.
References:
What is a "key grip"?