2.1 migration and smartcard stub

NIIBE Yutaka gniibe at fsij.org
Fri Oct 16 17:02:03 CEST 2015


At Debconf15, I was asked about 2.1 migration.  The bug is filed
in Debian:

    gnupg2: gnupg 2.1 secret keys migration skips keys on smartcard

I think that GnuPG 2.1 should emit some message for smartkey stub.

In the end of this message, I put my proposal patch.  It memorizes if
there were stub in private key migration, and if so, emit a message
which suggests invocation of "gpg --card-status" with smartcard.
Currently, the message is:

    To migrate private key stubs for smartcard, run: gpg --card-status with smartcard

But, I'm not sure if new PO message is worth for that.  I'm not sure
if "gpg" in the message would be better than "gpg2" (there are
instances of "gpg" as well as "gpg2" in existing code to emit
messages), or not.

I'm not good at using plural form.  Please correct the message string.

Situation is: Private key (or private sub key) for smartcard has a
stub (reference) to the specific card, instead of key material (which
is on the card).  A single smartcard can have multiple private
(sub)keys.  A user can use multiple smartcards.  If a user uses
multiple smartcards, invocation should be done for each smartcard.

Perhaps, it would be good not to expose internal term "stub", and
following would be better:

    To migrate secring.gpg for smartcard, with each smartcard, run:
       gpg --card-status

diff --git a/g10/import.c b/g10/import.c
index 048b136..0e784bc 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -1331,6 +1331,7 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock,
   unsigned char *wrappedkey = NULL;
   size_t wrappedkeylen;
   char *cache_nonce = NULL;
+  int stub_key_found = 0;

   /* Get the current KEK.  */
   err = agent_keywrap_key (ctrl, 0, &kek, &keklen);
@@ -1391,7 +1392,10 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock,
          has been inserted and a stub key is in turn generated by the
          agent.  */
       if (ski->s2k.mode == 1001 || ski->s2k.mode == 1002)
-        continue;
+        {
+          stub_key_found = 1;
+          continue;
+        }

       /* Convert our internal secret key object into an S-expression.  */
       nskey = pubkey_get_nskey (pk->pubkey_algo);
@@ -1568,6 +1572,10 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock,

+  if (!err && stub_key_found)
+    /* We need to notify user how to migrate stub keys.  */
+    err = gpg_error (GPG_ERR_NOT_PROCESSED);
   gcry_sexp_release (curve);
   xfree (cache_nonce);
@@ -1757,8 +1765,17 @@ import_secret_one (ctrl_t ctrl, const char *fname, kbnode_t keyblock,
                        keystr_from_pk (pk));
+              gpg_error_t err;
 	      nr_prev = stats->secret_imported;
-              if (!transfer_secret_keys (ctrl, stats, keyblock, batch))
+              err = transfer_secret_keys (ctrl, stats, keyblock, batch);
+              if (gpg_err_code (err) == GPG_ERR_NOT_PROCESSED)
+                {
+                  log_info (_("To migrate private key stubs for smartcard, "
+                              "run: gpg --card-status with smartcard\n"));
+                  err = 0;
+                }
+              if (!err)
 		  int status = 16;
                   if (!opt.quiet)

More information about the Gnupg-devel mailing list