[Pkg-gnupg-commit] [gnupg2] 40/159: g10: factor out a function for secret key retrieval.

Daniel Kahn Gillmor dkg at fifthhorseman.net
Wed Jan 27 13:23:52 UTC 2016


This is an automated email from the git hooks/post-receive script.

dkg pushed a commit to branch master
in repository gnupg2.

commit e644aa7f5943174e3f7ba9408af71531fd125a0b
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Thu Dec 17 13:03:56 2015 +0900

    g10: factor out a function for secret key retrieval.
    
    * g10/export.c (receive_seckey_from_agent): New.
    (do_export_stream): Use it.
    
    --
    
    Also fixed a memory leak of WRAPPEDKEY on a successful path of
    build_packet.
    
    In the log message, key is now by a hexgrip instead of a format by
    keystr_with_sub.
---
 g10/export.c | 153 ++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 83 insertions(+), 70 deletions(-)

diff --git a/g10/export.c b/g10/export.c
index f7ad1b2..95ddb9d 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -825,6 +825,78 @@ print_status_exported (PKT_public_key *pk)
 }
 
 
+/*
+ * Receive a secret key from agent specified by HEXGRIP.
+ *
+ * Since the key data from agant is encrypted, decrypt it by CIPHERHD.
+ * Then, parse the decrypted key data in transfer format, and put
+ * secret papameters into PK.
+ *
+ * CACHE_NONCE_ADDR is used to share nonce for multple key retrievals.
+ */
+gpg_error_t
+receive_seckey_from_agent (ctrl_t ctrl, gcry_cipher_hd_t cipherhd,
+                           char **cache_nonce_addr, const char *hexgrip,
+                           PKT_public_key *pk)
+{
+  gpg_error_t err = 0;
+  unsigned char *wrappedkey = NULL;
+  size_t wrappedkeylen;
+  unsigned char *key = NULL;
+  size_t keylen, realkeylen;
+  gcry_sexp_t s_skey;
+  char *prompt;
+
+  if (opt.verbose)
+    log_info ("key %s: asking agent for the secret parts\n", hexgrip);
+
+  prompt = gpg_format_keydesc (pk, FORMAT_KEYDESC_EXPORT,1);
+  err = agent_export_key (ctrl, hexgrip, prompt, cache_nonce_addr,
+                          &wrappedkey, &wrappedkeylen);
+  xfree (prompt);
+
+  if (err)
+    goto unwraperror;
+  if (wrappedkeylen < 24)
+    {
+      err = gpg_error (GPG_ERR_INV_LENGTH);
+      goto unwraperror;
+    }
+  keylen = wrappedkeylen - 8;
+  key = xtrymalloc_secure (keylen);
+  if (!key)
+    {
+      err = gpg_error_from_syserror ();
+      goto unwraperror;
+    }
+  err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
+  if (err)
+    goto unwraperror;
+  realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
+  if (!realkeylen)
+    goto unwraperror; /* Invalid csexp.  */
+
+  err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen);
+  if (!err)
+    {
+      err = transfer_format_to_openpgp (s_skey, pk);
+      gcry_sexp_release (s_skey);
+    }
+
+ unwraperror:
+  xfree (key);
+  xfree (wrappedkey);
+  if (err)
+    {
+      log_error ("key %s: error receiving key from agent:"
+                 " %s%s\n", hexgrip, gpg_strerror (err),
+                 gpg_err_code (err) == GPG_ERR_FULLY_CANCELED?
+                 "":_(" - skipped"));
+    }
+  return err;
+}
+
+
 /* Export the keys identified by the list of strings in USERS to the
    stream OUT.  If Secret is false public keys will be exported.  With
    secret true secret keys will be exported; in this case 1 means the
@@ -1203,83 +1275,24 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
                 }
               else if (!err)
                 {
-                  /* FIXME: Move this spaghetti code into a separate
-                     function.  */
-                  unsigned char *wrappedkey = NULL;
-                  size_t wrappedkeylen;
-                  unsigned char *key = NULL;
-                  size_t keylen, realkeylen;
-                  gcry_sexp_t s_skey;
-
-                  if (opt.verbose)
-                    log_info ("key %s: asking agent for the secret parts\n",
-                              keystr_with_sub (keyid, subkid));
-
-                  {
-                    char *prompt = gpg_format_keydesc (pk,
-                                                       FORMAT_KEYDESC_EXPORT,1);
-                    err = agent_export_key (ctrl, hexgrip, prompt, &cache_nonce,
-                                            &wrappedkey, &wrappedkeylen);
-                    xfree (prompt);
-                  }
-                  if (err)
-                    goto unwraperror;
-                  if (wrappedkeylen < 24)
-                    {
-                      err = gpg_error (GPG_ERR_INV_LENGTH);
-                      goto unwraperror;
-                    }
-                  keylen = wrappedkeylen - 8;
-                  key = xtrymalloc_secure (keylen);
-                  if (!key)
-                    {
-                      err = gpg_error_from_syserror ();
-                      goto unwraperror;
-                    }
-                  err = gcry_cipher_decrypt (cipherhd, key, keylen,
-                                             wrappedkey, wrappedkeylen);
-                  if (err)
-                    goto unwraperror;
-                  realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
-                  if (!realkeylen)
-                    goto unwraperror; /* Invalid csexp.  */
-
-                  err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen);
-                  xfree (key);
-                  key = NULL;
-                  if (err)
-                    goto unwraperror;
-                  err = transfer_format_to_openpgp (s_skey, pk);
-                  gcry_sexp_release (s_skey);
-                  if (err)
-                    goto unwraperror;
-
-                  err = build_packet (out, node->pkt);
-                  if (!err && node->pkt->pkttype == PKT_PUBLIC_KEY)
-                    {
-                      stats->exported++;
-                      print_status_exported (node->pkt->pkt.public_key);
-                    }
-                  goto unwraperror_leave;
-
-                unwraperror:
-                  xfree (wrappedkey);
-                  xfree (key);
+                  err = receive_seckey_from_agent (ctrl, cipherhd, &cache_nonce,
+                                                   hexgrip, pk);
                   if (err)
                     {
-                      log_error ("key %s: error receiving key from agent:"
-                                 " %s%s\n",
-                                 keystr_with_sub (keyid, subkid),
-                                 gpg_strerror (err),
-                                 gpg_err_code (err) == GPG_ERR_FULLY_CANCELED?
-                                 "":_(" - skipped"));
                       if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
                         goto leave;
                       skip_until_subkey = 1;
                       err = 0;
                     }
-                unwraperror_leave:
-                  ;
+                  else
+                    {
+                      err = build_packet (out, node->pkt);
+                      if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+                        {
+                          stats->exported++;
+                          print_status_exported (node->pkt->pkt.public_key);
+                        }
+                    }
                 }
               else
                 {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git



More information about the Pkg-gnupg-commit mailing list