On 07/09/13 07:10 AM, Peter Lebbing wrote:
On 27/06/13 18:55, Jack Bates wrote:
except that I am using the key id of a subkey, with an exclamation
mark, to export just one subkey instead of all the subkeys belonging to the
primary key. The subkey with that key id definitely doesn't already exist in the
destination keyring, although the destination keyring does already contain a
different subkey.
I believe once GnuPG has a secret key, it won't update it anymore with any
subsequent imports. So to get the additional subkey, re-export the whole thing,
delete the existing one on the other system and import your re-exported whole
thing.
I'm also wondering why you're being so explicit about it in the first place,
with transferring little chunks at a time using the exclamation mark instead of
the whole thing. Is there something specific you're trying to achieve?
gpg: secret keys unchanged: 1
This message to me implies it is actually possible to change something about a
secret key. I haven't figured out what yet.
Thank you for following up Peter, I looked again and I think it's a
difference between public vs. secret subkeys. It will merge a new public
subkey with existing subkeys, but it won't merge a new secret subkey
with existing ones. Here is a first crack at a patch to merge new secret
subkeys similar to how it already handles public ones:
http://nottheoilrig.com/gnupg/201309120/merge.patch
I'd love to contribute a change like this to GnuPG, would a change like
this be welcome? (considered for inclusion?) If so, can anyone help me
review it and get it into shape? What is the right way to submit a patch
to GnuPG?
Here's what GnuPG does before and after the patch:
# Generate primary key
$ gpg2 --gen-key
pub 4096R/B575FAD1 2013-09-12
Key fingerprint = 19C1 3488 6B2A A80C E30A 6A96 4CB2 EAFB
B575 FAD1
uid John Doe <j...@example.com>
# Add subkey
$ gpg2 --edit-key B575FAD1 addkey
pub 4096R/B575FAD1 created: 2013-09-12 expires: never
usage: SC
trust: ultimate validity: ultimate
sub 4096R/3BEA5E48 created: 2013-09-12 expires: 2013-09-13
usage: S
# Export secret subkey
$ gpg2 --export-secret-subkeys 3BEA5E48! > 3BEA5E48
# Add another subkey
gpg2 --edit-key B575FAD1 addkey
pub 4096R/B575FAD1 created: 2013-09-12 expires: never
usage: SC
trust: ultimate validity: ultimate
sub 4096R/3BEA5E48 created: 2013-09-12 expires: 2013-09-13
usage: S
sub 4096R/1F01C58C created: 2013-09-12 expires: 2013-09-13
usage: S
# Export other secret subkey
$ gpg2 --export-secret-subkeys 1F01C58C! > 1F01C58C
# Start over with an empty keyring
$ rm -r ~/.gnupg
# Import first subkey
$ gpg2 --import 3BEA5E48
gpg: key B575FAD1: secret key imported
gpg: key B575FAD1: public key "John Doe <j...@example.com>" imported
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
gpg: secret keys read: 1
gpg: secret keys imported: 1
Here's what it does before the patch:
# Import second subkey
$ gpg2 --import 1F01C58C
gpg: key B575FAD1: already in secret keyring
gpg: Total number processed: 1
gpg: secret keys read: 1
gpg: secret keys unchanged: 1
$ gpg2 -K
sec# 4096R/B575FAD1 2013-09-12
uid John Doe <j...@example.com>
ssb 4096R/3BEA5E48 2013-09-12
And here's what happens after the patch:
# Import second subkey
$ gpg2 --import 1F01C58C
gpg: key B575FAD1: "John Doe <j...@example.com>" 1 new signature
gpg: key B575FAD1: "John Doe <j...@example.com>" 1 new subkey
gpg: key B575FAD1: "John Doe <j...@example.com>" 1 new signature
gpg: key B575FAD1: "John Doe <j...@example.com>" 1 new subkey
gpg: Total number processed: 1
gpg: new subkeys: 2
gpg: new signatures: 2
gpg: secret keys read: 1
$ gpg2 -K
sec# 4096R/B575FAD1 2013-09-12
uid John Doe <j...@example.com>
ssb 4096R/3BEA5E48 2013-09-12
ssb 4096R/1F01C58C 2013-09-12
I looked at the code in gnupg/g10/import.c and when you import
something, the import() procedure gets called once by
import_keys_internal(), etc. The import_one() procedure gets called if
import() finds a PKT_PUBLIC_KEY keyblock and import_secret_one() gets
called if it finds a PKT_SECRET_KEY keyblock. After import_secret_one()
imports a new secret key, it converts it to a public key with
sec_to_pub_keyblock() and passes that to import_one().
import_one() and import_secret_one() both check if the key already
exists in the keyring. If import_one() finds that it does, it reads the
existing keyblock, calls merge_blocks(), and if anything changed it
writes back the updated keyblock.
However if import_secret_one() finds that the key already exists,
currently it just says:
1273 else if( !rc )
1274 { /* we can't merge secret keys */
1275 log_error( _("key %s: already in secret keyring\n"),
1276 keystr_from_sk(sk));
1277 stats->secret_dups++;
1278 if (is_status_enabled ())
1279 print_import_ok (NULL, sk, 16);
1280
1281 /* TODO: if we ever do merge secret keys, make sure to handle
1282 the sec_to_pub_keyblock feature as well. */
1283 }
To make the patch, I cargo-culted a combination of code from where
import_secret_one() imports new secret keys and where import_one()
merges new public subkeys with existing ones. It reads the existing
keyblock, calls merge_blocks(), and writes back the updated keyblock if
anything changed.
I am grateful for feedback or help getting the patch into shape, if this
is a welcome change.
Thanks!
_______________________________________________
Gnupg-users mailing list
Gnupg-users@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-users