Page MenuHome GnuPG

GPG does not import secret subkeys from --export-secret-subkeys output if subkey stubs existed before
Open, NormalPublic

Description

This is similar to T1543, but there the commenter writes:

if the secret key is deleted from the keyring, then afterwards --import properly imports all the subkeys from the file.

But this is not the case for me. Even when I delete the secret keys and do the import after that, the keys always come back as ssb> instead of ssb.

Example:

I start with

➤ gpg2 --list-secret-keys
/home/niklas/.gnupg/pubring.gpg
-------------------------------

gpg: error computing keygrip
sec#  rsa4096/2DFBFA03 2015-11-21 [SC] [expires: 2021-11-19]
      Key fingerprint = C339 0A90 6C9D 275E 4116  EE00 AC34 326A 2DFB FA03
uid         [ unknown] Niklas Hambüchen <niklas@nh2.me>
uid         [ unknown] Niklas Hambuechen <mail@nh2.me>
uid         [ unknown] Niklas Hambuechen <niklas@nh2.me>
uid         [ unknown] Niklas Hambuechen <nh2@deditus.de>
uid         [ unknown] Niklas Hambüchen <mail@nh2.me>
uid         [ unknown] Niklas Hambüchen <nh2@deditus.de>
ssb>  rsa2048/5E1316BA 2015-11-21 [E] [expires: 2021-11-19]
ssb>  rsa2048/A2A0E898 2015-11-21 [S] [expires: 2021-11-19]
ssb>  rsa2048/41F742E3 2015-11-21 [A] [expires: 2021-11-19]

Then I delete it:

➤ gpg2 --delete-secret-and-public-key 2DFBFA03
gpg (GnuPG) 2.1.11; Copyright (C) 2016 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.

pub  rsa4096/2DFBFA03 2015-11-21 Niklas Hambüchen <niklas@nh2.me>

Delete this key from the keyring? (y/N) y

and it's gone from the listing of --list-secret-keys.

Then I import it from another machine that has the non-stub secret subkeys keys (shown as ssb on that machine) like this:

➤ ssh othermachine 'gpg2 --armor --export-secret-subkeys 2DFBFA03' | gpg2 --import
gpg: key 2DFBFA03: public key "Niklas Hambüchen <niklas@nh2.me>" imported
gpg: To migrate 'secring.gpg', with each smartcard, run: gpg --card-status
gpg: key 2DFBFA03: secret key imported
gpg: Total number processed: 5
gpg:               imported: 1
gpg:       secret keys read: 5
gpg:  secret keys unchanged: 3

And that leaves me with:

➤ gpg2 --list-secret-keys
/home/niklas/.gnupg/pubring.gpg
-------------------------------

gpg: error computing keygrip
sec#  rsa4096/2DFBFA03 2015-11-21 [SC] [expires: 2021-11-19]
      Key fingerprint = C339 0A90 6C9D 275E 4116  EE00 AC34 326A 2DFB FA03
uid         [ unknown] Niklas Hambüchen <niklas@nh2.me>
uid         [ unknown] Niklas Hambuechen <mail@nh2.me>
uid         [ unknown] Niklas Hambuechen <niklas@nh2.me>
uid         [ unknown] Niklas Hambuechen <nh2@deditus.de>
uid         [ unknown] Niklas Hambüchen <mail@nh2.me>
uid         [ unknown] Niklas Hambüchen <nh2@deditus.de>
ssb>  rsa2048/5E1316BA 2015-11-21 [E] [expires: 2021-11-19]
ssb>  rsa2048/A2A0E898 2015-11-21 [S] [expires: 2021-11-19]
ssb>  rsa2048/41F742E3 2015-11-21 [A] [expires: 2021-11-19]

Note how the keys are ssb> stubs again!

Also, why did the import say secret keys unchanged: 3? Didn't I delete them?

I suspect that GPG stores some information somewhere that makes it remember something that lives on past deletion. And my usual workaround for this issue is to fully remove the ~/.gnupg directory; then importing works fine.

I'm using gpg (GnuPG) 2.1.11, and gpg (GnuPG) 2.0.22 on the othermachine where I export them from.

Event Timeline

nh2 created this object in space S1 Public.

Potentially useful to know: This is how the import looks like into an empty ~/.gnupg directory:

➤ mv ~/.gnupg/ ~/.gnupg.orig
                                                                                                                                                                         
➤ ssh k4 cat ~/.gnupg/gpg-niklas-hambuechen-0x2DFBFA03-secret-subkeys.asc | gpg2 --import
gpg: directory '/home/niklas/.gnupg' created
gpg: new configuration file '/home/niklas/.gnupg/dirmngr.conf' created
gpg: new configuration file '/home/niklas/.gnupg/gpg.conf' created
gpg: keybox '/home/niklas/.gnupg/pubring.kbx' created
Enter passphrase for key '/home/niklas/.ssh/id_rsa': 
gpg: /home/niklas/.gnupg/trustdb.gpg: trustdb created
gpg: key 2DFBFA03: public key "Niklas Hambüchen <niklas@nh2.me>" imported
gpg: To migrate 'secring.gpg', with each smartcard, run: gpg --card-status
gpg: key 2DFBFA03: secret key imported
gpg: Total number processed: 5
gpg:               imported: 1
gpg:       secret keys read: 5
gpg:   secret keys imported: 3

Notice this time it says secret keys imported: 3 instead of secret keys unchanged: 3.

It also popped up a window asking for my passphrase, which it didn't do before.

gnupg 2.1.11 is pretty old and has quite some bugs. Please try at least the Debian version which is 2.1.18 plus a couple of backported fixes. Or yet better, the current stable 2.2.x

werner triaged this task as Normal priority.Oct 24 2017, 3:09 PM
werner added a project: Info Needed.

In agent_write_private_key of agent/findkey.c, when file is available, it returns GPG_ERR_EEXIST error. Thus, private (stub) key will be kept.

I'm going to support this use case by the following approach, in 2.3.

(1) When importing private key, the front-end side (gpg) will check if key is already there, by agent's KEYINFO command.
(2) If not available, it's same as current behavior.
(3) If stub key is available, do force import.
(4) Otherwise, raise GPG_ERR_EEXIST error.