1

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 <bob@server.com>

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 <bob@server.com>

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.

djoproject
  • 157
  • 2
  • 7

2 Answers2

1

Thanks to a workmate who suggests me the following solution using the expect tool:

expect << EOF
spawn bash -c "{ echo addkey; echo 13; echo S; echo E; echo A; echo Q; echo 0; echo save; } | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
expect "Enter the keygrip: " { send "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\r" }
expect eof
EOF

Even if this solution works, I am not completely satisfied about it for the following reasons:

  • It is really ugly
  • Need to install expect, I wanted a gpg+bash solution only
  • it may create debug issue if an error occurs

So if anyone has a better solution, I am still interested .

djoproject
  • 157
  • 2
  • 7
  • Thank you for posting this. I was able to reproduce your issue and I did not find a way to provide the `Keygrip` without interaction. I'm afraid using `expect` is the right way to do it and all you can do is 'prettify' this command. The one possible alternative I have in mind is xdotool, that depends on X. It may already be present on your machines but is not what I would consider a better option. – Kate Apr 03 '20 at 16:16
0

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:

gpg --list-keys --with-keygrip AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

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"?

Kate
  • 487
  • 3
  • 8
  • Already using the keygrip. This is not a keygrip vs fingerprint issue, but an argument passing issue. I will update the question to be more specific. – djoproject Apr 02 '20 at 08:02