[Pkg-gnupg-commit] [gnupg2] 01/20: include upstream bugfixes and improvements (Closes: #863221)

Daniel Kahn Gillmor dkg at fifthhorseman.net
Wed Jul 26 20:20:45 UTC 2017


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

dkg pushed a commit to branch experimental
in repository gnupg2.

commit 037a5c4049b87e4b5b243ec2c23b1a2c6d883546
Author: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
Date:   Fri May 26 20:04:34 2017 -0400

    include upstream bugfixes and improvements (Closes: #863221)
---
 ...ault-key-selection-for-signing-possibly-b.patch | 169 ++++++++++++
 ...t-Add-const-qualifier-for-read-only-table.patch | 115 ++++++++
 ...ort-different-digest-algorithms-for-ssh-f.patch | 224 +++++++++++++++
 ...ectly-render-SHA256-based-ssh-fingerprint.patch | 303 +++++++++++++++++++++
 ...-both-ssh-fingerprints-to-sshcontrol-file.patch |  79 ++++++
 ...digest-algorithms-for-ssh-fingerprints-co.patch | 141 ++++++++++
 ...init-libdns-resolver-on-towel-change-of-r.patch | 110 ++++++++
 ...s-towel-should-better-detect-a-changed-re.patch |  47 ++++
 debian/patches/series                              |   8 +
 9 files changed, 1196 insertions(+)

diff --git a/debian/patches/0020-g10-Fix-default-key-selection-for-signing-possibly-b.patch b/debian/patches/0020-g10-Fix-default-key-selection-for-signing-possibly-b.patch
new file mode 100644
index 0000000..70a6c48
--- /dev/null
+++ b/debian/patches/0020-g10-Fix-default-key-selection-for-signing-possibly-b.patch
@@ -0,0 +1,169 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Mon, 22 May 2017 09:27:36 +0900
+Subject: g10: Fix default-key selection for signing, possibly by card.
+
+* g10/call-agent.c (warn_version_mismatch): Revert.
+(start_agent): Suppress version mismatch if relevant.
+* g10/getkey.c (get_seckey_default_or_card): New.
+* g10/skclist.c (build_sk_list): Use get_seckey_default_or_card.
+
+--
+
+The change of 97a2394, which prefers available card than default key
+specified is too strong.
+
+Fixes-commit: 97a2394ecafaa6f58e4a1f70ecfd04408dc15606
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit fbb2259d22e6c6eadc2af722bdc52922da348677)
+---
+ g10/call-agent.c |  8 ++++----
+ g10/getkey.c     | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ g10/keydb.h      |  2 ++
+ g10/skclist.c    | 16 ++++------------
+ 4 files changed, 62 insertions(+), 16 deletions(-)
+
+diff --git a/g10/call-agent.c b/g10/call-agent.c
+index 4698a25..e6dbb73 100644
+--- a/g10/call-agent.c
++++ b/g10/call-agent.c
+@@ -184,8 +184,7 @@ default_inq_cb (void *opaque, const char *line)
+ 
+ 
+ /* Print a warning if the server's version number is less than our
+-   version number.  Returns an error code on a connection problem.
+-   Ignore an error for scdaemon (MODE==2).  */
++   version number.  Returns an error code on a connection problem.  */
+ static gpg_error_t
+ warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
+ {
+@@ -194,7 +193,7 @@ warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
+   const char *myversion = strusage (13);
+ 
+   err = get_assuan_server_version (ctx, mode, &serverversion);
+-  if (err && mode != 2)
++  if (err)
+     log_error (_("error getting version from '%s': %s\n"),
+                servername, gpg_strerror (err));
+   else if (compare_version_strings (serverversion, myversion) < 0)
+@@ -290,7 +289,8 @@ start_agent (ctrl_t ctrl, int flag_for_card)
+ 
+       memset (&info, 0, sizeof info);
+ 
+-      rc = warn_version_mismatch (agent_ctx, SCDAEMON_NAME, 2);
++      if (!(flag_for_card & FLAG_FOR_CARD_SUPPRESS_ERRORS))
++        rc = warn_version_mismatch (agent_ctx, SCDAEMON_NAME, 2);
+       if (!rc)
+         rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
+                               NULL, NULL, NULL, NULL,
+diff --git a/g10/getkey.c b/g10/getkey.c
+index a81041f..9ac32f7 100644
+--- a/g10/getkey.c
++++ b/g10/getkey.c
+@@ -3967,6 +3967,58 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
+     }
+ }
+ 
++gpg_error_t
++get_seckey_default_or_card (ctrl_t ctrl, PKT_public_key *pk,
++                            const byte *fpr_card, size_t fpr_len)
++{
++  gpg_error_t err;
++  strlist_t namelist = NULL;
++
++  const char *def_secret_key = parse_def_secret_key (ctrl);
++
++  if (def_secret_key)
++    add_to_strlist (&namelist, def_secret_key);
++  else if (fpr_card)
++    return get_pubkey_byfprint (ctrl, pk, NULL, fpr_card, fpr_len);
++
++  if (!fpr_card
++      || (def_secret_key && def_secret_key[strlen (def_secret_key)-1] == '!'))
++    err = key_byname (ctrl, NULL, namelist, pk, 1, 0, NULL, NULL);
++  else
++    { /* Default key is specified and card key is also available.  */
++      kbnode_t k, keyblock = NULL;
++
++      err = key_byname (ctrl, NULL, namelist, pk, 1, 0, &keyblock, NULL);
++      if (!err)
++        for (k = keyblock; k; k = k->next)
++          {
++            PKT_public_key *pk_candidate;
++            char fpr[MAX_FINGERPRINT_LEN];
++
++            if (k->pkt->pkttype != PKT_PUBLIC_KEY
++                &&k->pkt->pkttype != PKT_PUBLIC_SUBKEY)
++              continue;
++
++            pk_candidate = k->pkt->pkt.public_key;
++            if (!pk_candidate->flags.valid)
++              continue;
++            if (!((pk_candidate->pubkey_usage & USAGE_MASK) & pk->req_usage))
++              continue;
++            fingerprint_from_pk (pk_candidate, fpr, NULL);
++            if (!memcmp (fpr_card, fpr, fpr_len))
++              {
++                release_public_key_parts (pk);
++                copy_public_key (pk, pk_candidate);
++                break;
++              }
++          }
++      release_kbnode (keyblock);
++    }
++
++  free_strlist (namelist);
++
++  return err;
++}
+ 

+ /*********************************************
+  ***********  User ID printing helpers *******
+diff --git a/g10/keydb.h b/g10/keydb.h
+index 1da93a7..4016723 100644
+--- a/g10/keydb.h
++++ b/g10/keydb.h
+@@ -351,6 +351,8 @@ const char *parse_def_secret_key (ctrl_t ctrl);
+ 
+ /* Look up a secret key.  */
+ gpg_error_t get_seckey_default (ctrl_t ctrl, PKT_public_key *pk);
++gpg_error_t get_seckey_default_or_card (ctrl_t ctrl, PKT_public_key *pk,
++                                        const byte *fpr, size_t fpr_len);
+ 
+ /* Search for keys matching some criteria.  */
+ gpg_error_t getkey_bynames (ctrl_t ctrl,
+diff --git a/g10/skclist.c b/g10/skclist.c
+index 489277c..78890dc 100644
+--- a/g10/skclist.c
++++ b/g10/skclist.c
+@@ -137,7 +137,7 @@ build_sk_list (ctrl_t ctrl,
+       pk = xmalloc_clear (sizeof *pk);
+       pk->req_usage = use;
+ 
+-      /* Check if a card is available.  If any, use it.  */
++      /* Check if a card is available.  If any, use the key as a hint.  */
+       err = agent_scd_serialno (&serialno, NULL);
+       if (!err)
+         {
+@@ -146,19 +146,11 @@ build_sk_list (ctrl_t ctrl,
+           if (err)
+             log_error ("error retrieving key fingerprint from card: %s\n",
+                        gpg_strerror (err));
+-          else if (info.fpr1valid)
+-            {
+-              if ((err = get_pubkey_byfprint (ctrl, pk, NULL, info.fpr1, 20)))
+-                {
+-                  info.fpr1valid = 0;
+-                  log_error ("error on card key to sign: %s, try default\n",
+-                             gpg_strerror (err));
+-                }
+-            }
+         }
+ 
+-      if (!info.fpr1valid
+-          && (err = getkey_byname (ctrl, NULL, pk, NULL, 1, NULL)))
++      err = get_seckey_default_or_card (ctrl, pk,
++                                        info.fpr1valid? info.fpr1 : NULL, 20);
++      if (err)
+ 	{
+ 	  free_public_key (pk);
+ 	  pk = NULL;
diff --git a/debian/patches/0021-agent-Add-const-qualifier-for-read-only-table.patch b/debian/patches/0021-agent-Add-const-qualifier-for-read-only-table.patch
new file mode 100644
index 0000000..30d21ec
--- /dev/null
+++ b/debian/patches/0021-agent-Add-const-qualifier-for-read-only-table.patch
@@ -0,0 +1,115 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 23 May 2017 06:42:44 +0900
+Subject: agent: Add const qualifier for read-only table.
+
+* agent/call-pinentry.c (start_pinentry): Add const to tbl.
+* agent/command-ssh.c (request_specs): Add const.
+(ssh_key_types): Likewise.
+(request_spec_lookup): Add const to the return value and SPEC.
+(ssh_request_process): Likewise.
+* agent/protect.c (protect_info): Add const.
+(agent_unprotect): Add const to algotable.
+
+--
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 509e4a4d7491daf496b21e5892f4f63ab90e8e21)
+---
+ agent/call-pinentry.c |  2 +-
+ agent/command-ssh.c   | 10 +++++-----
+ agent/gpg-agent.c     |  2 +-
+ agent/protect.c       |  4 ++--
+ 4 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
+index 1ff4059..9d8e7f6 100644
+--- a/agent/call-pinentry.c
++++ b/agent/call-pinentry.c
+@@ -489,7 +489,7 @@ start_pinentry (ctrl_t ctrl)
+   {
+     /* Provide a few default strings for use by the pinentries.  This
+        may help a pinentry to avoid implementing localization code.  */
+-    static struct { const char *key, *value; int what; } tbl[] = {
++    static const struct { const char *key, *value; int what; } tbl[] = {
+       /* TRANSLATORS: These are labels for buttons etc used in
+          Pinentries.  An underscore indicates that the next letter
+          should be used as an accelerator.  Double the underscore for
+diff --git a/agent/command-ssh.c b/agent/command-ssh.c
+index 57e2e42..99c80c0 100644
+--- a/agent/command-ssh.c
++++ b/agent/command-ssh.c
+@@ -262,7 +262,7 @@ static gpg_error_t ssh_key_extract_comment (gcry_sexp_t key, char **comment);
+ /* Associating request types with the corresponding request
+    handlers.  */
+ 
+-static ssh_request_spec_t request_specs[] =
++static const ssh_request_spec_t request_specs[] =
+   {
+ #define REQUEST_SPEC_DEFINE(id, name, secret_input) \
+   { SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input }
+@@ -280,7 +280,7 @@ static ssh_request_spec_t request_specs[] =
+ 
+ 
+ /* Table holding key type specifications.  */
+-static ssh_key_type_spec_t ssh_key_types[] =
++static const ssh_key_type_spec_t ssh_key_types[] =
+   {
+     {
+       "ssh-ed25519", "Ed25519", GCRY_PK_EDDSA, "qd",  "q", "rs", "qd",
+@@ -3376,10 +3376,10 @@ ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
+ /* Return the request specification for the request identified by TYPE
+    or NULL in case the requested request specification could not be
+    found.  */
+-static ssh_request_spec_t *
++static const ssh_request_spec_t *
+ request_spec_lookup (int type)
+ {
+-  ssh_request_spec_t *spec;
++  const ssh_request_spec_t *spec;
+   unsigned int i;
+ 
+   for (i = 0; i < DIM (request_specs); i++)
+@@ -3403,7 +3403,7 @@ request_spec_lookup (int type)
+ static int
+ ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
+ {
+-  ssh_request_spec_t *spec;
++  const ssh_request_spec_t *spec;
+   estream_t response = NULL;
+   estream_t request = NULL;
+   unsigned char request_type;
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 098a335..e7eef2b 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -1922,7 +1922,7 @@ agent_copy_startup_env (ctrl_t ctrl)
+   const char *value;
+ 
+   for (idx=0; !err && names[idx]; idx++)
+-      if ((value = session_env_getenv (opt.startup_env, names[idx])))
++    if ((value = session_env_getenv (opt.startup_env, names[idx])))
+       err = session_env_setenv (ctrl->session_env, names[idx], value);
+ 
+   if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype)
+diff --git a/agent/protect.c b/agent/protect.c
+index a9de732..66c3741 100644
+--- a/agent/protect.c
++++ b/agent/protect.c
+@@ -54,7 +54,7 @@
+ 
+ /* A table containing the information needed to create a protected
+    private key.  */
+-static struct {
++static const struct {
+   const char *algo;
+   const char *parmlist;
+   int prot_from, prot_to;
+@@ -1010,7 +1010,7 @@ agent_unprotect (ctrl_t ctrl,
+                  gnupg_isotime_t protected_at,
+                  unsigned char **result, size_t *resultlen)
+ {
+-  static struct {
++  static const struct {
+     const char *name; /* Name of the protection method. */
+     int algo;         /* (A zero indicates the "openpgp-native" hack.)  */
+     int keylen;       /* Used key length in bytes.  */
diff --git a/debian/patches/0022-common-Support-different-digest-algorithms-for-ssh-f.patch b/debian/patches/0022-common-Support-different-digest-algorithms-for-ssh-f.patch
new file mode 100644
index 0000000..8e7c8ad
--- /dev/null
+++ b/debian/patches/0022-common-Support-different-digest-algorithms-for-ssh-f.patch
@@ -0,0 +1,224 @@
+From: Justus Winter <justus at g10code.com>
+Date: Fri, 4 Dec 2015 15:19:07 +0100
+Subject: common: Support different digest algorithms for ssh fingerprints.
+
+* common/ssh-utils.c (get_fingerprint): Add and honor 'algo' parameter.
+(ssh_get_fingerprint{,_string}): Likewise.
+* common/ssh-utils.h (ssh_get_fingerprint{,_string}): Update prototypes.
+* common/t-ssh-utils.c (main): Adapt accordingly.
+* agent/command-ssh.c (agent_raw_key_from_file): Likewise.
+(ssh_identity_register): Likewise.
+* agent/command.c (do_one_keyinfo): Likewise.
+* agent/findkey.c (modify_description): Likewise.
+--
+This lays the foundation to support other algorithms.
+
+GnuPG-bug-id: 2106
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 3ac1a9d3a018816233a855faff059b4e0657a0f1)
+---
+ agent/command-ssh.c  |  4 ++--
+ agent/command.c      |  2 +-
+ agent/findkey.c      |  2 +-
+ common/ssh-utils.c   | 59 +++++++++++++++++++++++++++-------------------------
+ common/ssh-utils.h   |  6 ++++--
+ common/t-ssh-utils.c |  4 ++--
+ 6 files changed, 41 insertions(+), 36 deletions(-)
+
+diff --git a/agent/command-ssh.c b/agent/command-ssh.c
+index 99c80c0..3dd3dd7 100644
+--- a/agent/command-ssh.c
++++ b/agent/command-ssh.c
+@@ -2760,7 +2760,7 @@ data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+       err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
+       if (err)
+         goto out;
+-      err = ssh_get_fingerprint_string (key, &fpr);
++      err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr);
+       if (!err)
+         {
+           gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
+@@ -3038,7 +3038,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+ 
+   bin2hex (key_grip_raw, 20, key_grip);
+ 
+-  err = ssh_get_fingerprint_string (key, &key_fpr);
++  err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &key_fpr);
+   if (err)
+     goto out;
+ 
+diff --git a/agent/command.c b/agent/command.c
+index df788ef..d370821 100644
+--- a/agent/command.c
++++ b/agent/command.c
+@@ -1201,7 +1201,7 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
+ 
+       if (!agent_raw_key_from_file (ctrl, grip, &key))
+         {
+-          ssh_get_fingerprint_string (key, &fpr);
++          ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr);
+           gcry_sexp_release (key);
+         }
+     }
+diff --git a/agent/findkey.c b/agent/findkey.c
+index b24d8f1..1f547b0 100644
+--- a/agent/findkey.c
++++ b/agent/findkey.c
+@@ -412,7 +412,7 @@ agent_modify_description (const char *in, const char *comment,
+ 
+                 case 'F': /* SSH style fingerprint.  */
+                   if (!ssh_fpr && key)
+-                    ssh_get_fingerprint_string (key, &ssh_fpr);
++                    ssh_get_fingerprint_string (key, GCRY_MD_MD5, &ssh_fpr);
+                   if (ssh_fpr)
+                     {
+                       if (out)
+diff --git a/common/ssh-utils.c b/common/ssh-utils.c
+index 60aa07b..3925602 100644
+--- a/common/ssh-utils.c
++++ b/common/ssh-utils.c
+@@ -65,12 +65,13 @@ is_eddsa (gcry_sexp_t keyparms)
+ }
+ 
+ 
+-/* Return the Secure Shell type fingerprint for KEY.  The length of
+-   the fingerprint is returned at R_LEN and the fingerprint itself at
+-   R_FPR.  In case of a error code is returned and NULL stored at
+-   R_FPR.  */
++/* Return the Secure Shell type fingerprint for KEY using digest ALGO.
++   The length of the fingerprint is returned at R_LEN and the
++   fingerprint itself at R_FPR.  In case of a error code is returned
++   and NULL stored at R_FPR.  */
+ static gpg_error_t
+-get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
++get_fingerprint (gcry_sexp_t key, int algo,
++                 void **r_fpr, size_t *r_len, int as_string)
+ {
+   gpg_error_t err;
+   gcry_sexp_t list = NULL;
+@@ -111,7 +112,7 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
+       goto leave;
+     }
+ 
+-  err = gcry_md_open (&md, GCRY_MD_MD5, 0);
++  err = gcry_md_open (&md, algo, 0);
+   if (err)
+     goto leave;
+ 
+@@ -229,23 +230,23 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
+         }
+     }
+ 
+-  *r_fpr = gcry_malloc (as_string? 61:20);
+-  if (!*r_fpr)
+-    {
+-      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+-      goto leave;
+-    }
+-
+   if (as_string)
+     {
+-      bin2hexcolon (gcry_md_read (md, GCRY_MD_MD5), 16, *r_fpr);
+-      *r_len = 3*16+1;
++      *r_fpr = (algo == GCRY_MD_MD5 ? bin2hexcolon : /* XXX we need base64 */ bin2hex)
++        (gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo), NULL);
++      *r_len = strlen (*r_fpr) + 1;
+       strlwr (*r_fpr);
+     }
+   else
+     {
+-      memcpy (*r_fpr, gcry_md_read (md, GCRY_MD_MD5), 16);
+-      *r_len = 16;
++      *r_len = gcry_md_get_algo_dlen (algo);
++      *r_fpr = xtrymalloc (*r_len);
++      if (!*r_fpr)
++        {
++          err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
++          goto leave;
++        }
++      memcpy (*r_fpr, gcry_md_read (md, algo), *r_len);
+     }
+   err = 0;
+ 
+@@ -257,28 +258,30 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
+   return err;
+ }
+ 
+-/* Return the Secure Shell type fingerprint for KEY.  The length of
+-   the fingerprint is returned at R_LEN and the fingerprint itself at
+-   R_FPR.  In case of an error an error code is returned and NULL
+-   stored at R_FPR.  */
++/* Return the Secure Shell type fingerprint for KEY using digest ALGO.
++   The length of the fingerprint is returned at R_LEN and the
++   fingerprint itself at R_FPR.  In case of an error an error code is
++   returned and NULL stored at R_FPR.  */
+ gpg_error_t
+-ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len)
++ssh_get_fingerprint (gcry_sexp_t key, int algo,
++                     void **r_fpr, size_t *r_len)
+ {
+-  return get_fingerprint (key, r_fpr, r_len, 0);
++  return get_fingerprint (key, algo, r_fpr, r_len, 0);
+ }
+ 
+ 
+-/* Return the Secure Shell type fingerprint for KEY as a string.  The
+-   fingerprint is mallcoed and stored at R_FPRSTR.  In case of an
+-   error an error code is returned and NULL stored at R_FPRSTR.  */
++/* Return the Secure Shell type fingerprint for KEY using digest ALGO
++   as a string.  The fingerprint is mallcoed and stored at R_FPRSTR.
++   In case of an error an error code is returned and NULL stored at
++   R_FPRSTR.  */
+ gpg_error_t
+-ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr)
++ssh_get_fingerprint_string (gcry_sexp_t key, int algo, char **r_fprstr)
+ {
+   gpg_error_t err;
+   size_t dummy;
+   void *string;
+ 
+-  err = get_fingerprint (key, &string, &dummy, 1);
++  err = get_fingerprint (key, algo, &string, &dummy, 1);
+   *r_fprstr = string;
+   return err;
+ }
+diff --git a/common/ssh-utils.h b/common/ssh-utils.h
+index 36d38a3..53d9f55 100644
+--- a/common/ssh-utils.h
++++ b/common/ssh-utils.h
+@@ -31,9 +31,11 @@
+ #define GNUPG_COMMON_SSH_UTILS_H
+ 
+ 
+-gpg_error_t ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len);
++gpg_error_t ssh_get_fingerprint (gcry_sexp_t key, int algo,
++				 void **r_fpr, size_t *r_len);
+ 
+-gpg_error_t ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr);
++gpg_error_t ssh_get_fingerprint_string (gcry_sexp_t key, int algo,
++					char **r_fprstr);
+ 
+ 
+ #endif /*GNUPG_COMMON_SSH_UTILS_H*/
+diff --git a/common/t-ssh-utils.c b/common/t-ssh-utils.c
+index f63ea95..a4e948f 100644
+--- a/common/t-ssh-utils.c
++++ b/common/t-ssh-utils.c
+@@ -262,7 +262,7 @@ main (int argc, char **argv)
+   if (argc == 2)
+     {
+       key = read_key (argv[1]);
+-      err = ssh_get_fingerprint_string (key, &string);
++      err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &string);
+       if (err)
+         {
+           fprintf (stderr, "%s:%d: error getting fingerprint: %s\n",
+@@ -287,7 +287,7 @@ main (int argc, char **argv)
+               exit (1);
+             }
+ 
+-          err = ssh_get_fingerprint_string (key, &string);
++          err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &string);
+           gcry_sexp_release (key);
+           if (err)
+             {
diff --git a/debian/patches/0023-common-Correctly-render-SHA256-based-ssh-fingerprint.patch b/debian/patches/0023-common-Correctly-render-SHA256-based-ssh-fingerprint.patch
new file mode 100644
index 0000000..5c99f60
--- /dev/null
+++ b/debian/patches/0023-common-Correctly-render-SHA256-based-ssh-fingerprint.patch
@@ -0,0 +1,303 @@
+From: Justus Winter <justus at g10code.com>
+Date: Wed, 24 May 2017 17:03:58 +0200
+Subject: common: Correctly render SHA256-based ssh fingerprints.
+
+* common/ssh-utils.c (dummy_realloc): New function.
+(dummy_free): Likewise.
+(get_fingerprint): Prepend the fingerprint with the name of the digest
+algorithm.  Correctly render SHA256-based ssh fingerprints.
+* common/t-ssh-utils.c (sample_keys): Add SHA256 hashes for the keys.
+(main): Add an option to dump the keys to gather fingerprints, also
+print the SHA256 fingerprint for keys given as arguments, and check
+the SHA256 fingerprints of the test keys.
+
+GnuPG-bug-id: 2106
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 3a07a69dfc87b4fff610740d3dde8e23f0d2f8bc)
+---
+ common/ssh-utils.c   | 73 ++++++++++++++++++++++++++++++++++++--
+ common/t-ssh-utils.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++------
+ 2 files changed, 158 insertions(+), 14 deletions(-)
+
+diff --git a/common/ssh-utils.c b/common/ssh-utils.c
+index 3925602..38d6e8a 100644
+--- a/common/ssh-utils.c
++++ b/common/ssh-utils.c
+@@ -64,6 +64,9 @@ is_eddsa (gcry_sexp_t keyparms)
+   return result;
+ }
+ 
++/* Dummy functions for es_mopen.  */
++static void *dummy_realloc (void *mem, size_t size) { (void) size; return mem; }
++static void dummy_free (void *mem) { (void) mem; }
+ 
+ /* Return the Secure Shell type fingerprint for KEY using digest ALGO.
+    The length of the fingerprint is returned at R_LEN and the
+@@ -232,10 +235,74 @@ get_fingerprint (gcry_sexp_t key, int algo,
+ 
+   if (as_string)
+     {
+-      *r_fpr = (algo == GCRY_MD_MD5 ? bin2hexcolon : /* XXX we need base64 */ bin2hex)
+-        (gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo), NULL);
++      const char *algo_name;
++      char *fpr;
++
++      /* Prefix string with the algorithm name and a colon.  */
++      algo_name = gcry_md_algo_name (algo);
++      *r_fpr = xtrymalloc (strlen (algo_name) + 1 + 3 * gcry_md_get_algo_dlen (algo) + 1);
++      if (*r_fpr == NULL)
++        {
++          err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
++          goto leave;
++        }
++
++      strncpy (*r_fpr, algo_name, strlen (algo_name));
++      fpr = (char *) *r_fpr + strlen (algo_name);
++      *fpr++ = ':';
++
++      if (algo == GCRY_MD_MD5)
++        {
++          bin2hexcolon (gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo), fpr);
++          strlwr (fpr);
++        }
++      else
++        {
++          struct b64state b64s;
++          estream_t stream;
++          char *p;
++          long int len;
++
++          /* Write the base64-encoded hash to fpr.  */
++          stream = es_mopen (fpr, 3 * gcry_md_get_algo_dlen (algo) + 1, 0,
++                             0, dummy_realloc, dummy_free, "w");
++          if (stream == NULL)
++            {
++              err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
++              goto leave;
++            }
++
++          err = b64enc_start_es (&b64s, stream, "");
++          if (err)
++            {
++              es_fclose (stream);
++              goto leave;
++            }
++
++          err = b64enc_write (&b64s,
++                              gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo));
++          if (err)
++            {
++              es_fclose (stream);
++              goto leave;
++            }
++
++          /* Finish, get the length, and close the stream.  */
++          err = b64enc_finish (&b64s);
++          len = es_ftell (stream);
++          es_fclose (stream);
++          if (err)
++            goto leave;
++
++          /* Terminate.  */
++          fpr[len] = 0;
++
++          /* Strip the trailing padding characters.  */
++          for (p = fpr + len - 1; p > fpr && *p == '='; p--)
++            *p = 0;
++        }
++
+       *r_len = strlen (*r_fpr) + 1;
+-      strlwr (*r_fpr);
+     }
+   else
+     {
+diff --git a/common/t-ssh-utils.c b/common/t-ssh-utils.c
+index a4e948f..1c9b87b 100644
+--- a/common/t-ssh-utils.c
++++ b/common/t-ssh-utils.c
+@@ -28,7 +28,12 @@
+ #include "ssh-utils.h"
+ 
+ 
+-static struct { const char *key; const char *fpr; } sample_keys[] = {
++static struct
++{
++  const char *key;
++  const char *fpr_md5;
++  const char *fpr_sha256;
++} sample_keys[] = {
+   { "(protected-private-key "
+     "(rsa "
+     "(n #"
+@@ -70,7 +75,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
+     ")"
+     "(comment passphrase_is_abc)"
+     ")",
+-    "c7:c6:a7:ec:04:6c:87:59:54:f2:88:58:09:e0:f2:b1"
++    "MD5:c7:c6:a7:ec:04:6c:87:59:54:f2:88:58:09:e0:f2:b1",
++    "SHA256:ksKb4DKk2SFX56GRtpt0szBnyjiYARSb2FNlUb7snnE"
+   },
+   {
+     "(protected-private-key "
+@@ -99,7 +105,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
+     ")"
+     "(comment sample_dsa_passphrase_is_abc)"
+     ")",
+-    "2d:b1:70:1a:04:9e:41:a3:ce:27:a5:c7:22:fe:3a:a3"
++    "MD5:2d:b1:70:1a:04:9e:41:a3:ce:27:a5:c7:22:fe:3a:a3",
++    "SHA256:z8+8HEuD/5QpegGS4tSK02dJF+a6o2V67VM2gOPz9oQ"
+   },
+   { /* OpenSSH 6.7p1 generated key:  */
+     "(protected-private-key "
+@@ -118,7 +125,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
+     ")"
+     "(comment \"ecdsa w/o comment\")"
+     ")", /* Passphrase="abc" */
+-    "93:4f:08:02:7d:cb:16:9b:0c:39:21:4b:cf:28:5a:19"
++    "MD5:93:4f:08:02:7d:cb:16:9b:0c:39:21:4b:cf:28:5a:19",
++    "SHA256:zSj4uXfE1hlQnESD2LO723fMGXsNwzHrfqOfqep37is"
+   },
+   { /* OpenSSH 6.7p1 generated key:  */
+     "(protected-private-key "
+@@ -139,7 +147,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
+     ")"
+     "(comment \"ecdsa w/o comment\")"
+     ")", /* Passphrase="abc" */
+-    "a3:cb:44:c8:56:15:25:62:85:fd:e8:04:7a:26:dc:76"
++    "MD5:a3:cb:44:c8:56:15:25:62:85:fd:e8:04:7a:26:dc:76",
++    "SHA256:JuQh5fjduynuuTEwI9C6yAKK1NnLX9PPd7TP0qZfbGs"
+   },
+   { /* OpenSSH 6.7p1 generated key:  */
+     "(protected-private-key "
+@@ -161,7 +170,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
+     ")"
+     "(comment \"ecdsa w/o comment\")"
+     ")", /* Passphrase="abc" */
+-    "1e:a6:94:ab:bd:81:73:5f:22:bc:0e:c7:89:f6:68:df"
++    "MD5:1e:a6:94:ab:bd:81:73:5f:22:bc:0e:c7:89:f6:68:df",
++    "SHA256:+pbRyYa2UBwDki1k4Wziu2CKrdJIbZM/hOWOQ/sNe/0"
+   },
+   { /* OpenSSH 6.7p1 generated key:  */
+     "(protected-private-key "
+@@ -180,7 +190,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
+     ")"
+     "(comment \"eddsa w/o comment\")"
+     ")", /* Passphrase="abc" */
+-    "f1:fa:c8:a6:40:bb:b9:a1:65:d7:62:65:ac:26:78:0e"
++    "MD5:f1:fa:c8:a6:40:bb:b9:a1:65:d7:62:65:ac:26:78:0e",
++    "SHA256:yhwBfYnTOnSXcWf1EOPo+oIIpNJ6w/bG36udZ96MmsQ"
+   },
+   {
+     NULL,
+@@ -259,9 +270,43 @@ main (int argc, char **argv)
+   char *string;
+   int idx;
+ 
+-  if (argc == 2)
++  /* --dump-keys dumps the keys as KEYGRIP.key.IDX.  Useful to compute
++       fingerprints to enhance the test vectors.  */
++  if (argc == 2 && strcmp (argv[1], "--dump-keys") == 0)
++    for (idx=0; sample_keys[idx].key; idx++)
++      {
++	FILE *s;
++	char *name;
++	char grip[20];
++	char *hexgrip;
++
++	err = keygrip_from_canon_sexp (sample_keys[idx].key,
++				       strlen (sample_keys[idx].key),
++				       grip);
++	if (err)
++	  {
++	    fprintf (stderr, "%s:%d: error computing keygrip: %s\n",
++		     __FILE__, __LINE__, gpg_strerror (err));
++	    exit (1);
++	  }
++	hexgrip = bin2hex (grip, 20, NULL);
++
++	name = xtryasprintf ("%s.key.%d", hexgrip, idx);
++	s = fopen (name, "w");
++	if (s == NULL)
++	  {
++	    fprintf (stderr, "%s:%d: error opening file: %s\n",
++		     __FILE__, __LINE__, gpg_strerror (gpg_error_from_syserror ()));
++	    exit (1);
++	  }
++	xfree (name);
++	fprintf (s, "%s", sample_keys[idx].key);
++	fclose (s);
++      }
++  else if (argc == 2)
+     {
+       key = read_key (argv[1]);
++
+       err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &string);
+       if (err)
+         {
+@@ -271,6 +316,17 @@ main (int argc, char **argv)
+         }
+       puts (string);
+       xfree (string);
++
++      err = ssh_get_fingerprint_string (key, GCRY_MD_SHA256, &string);
++      if (err)
++        {
++          fprintf (stderr, "%s:%d: error getting fingerprint: %s\n",
++                   __FILE__, __LINE__, gpg_strerror (err));
++          exit (1);
++        }
++      puts (string);
++      xfree (string);
++
+       gcry_sexp_release (key);
+     }
+   else
+@@ -288,7 +344,6 @@ main (int argc, char **argv)
+             }
+ 
+           err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &string);
+-          gcry_sexp_release (key);
+           if (err)
+             {
+               fprintf (stderr, "%s:%d: error getting fingerprint for "
+@@ -297,16 +352,38 @@ main (int argc, char **argv)
+               exit (1);
+             }
+ 
+-          if (strcmp (string, sample_keys[idx].fpr))
++          if (strcmp (string, sample_keys[idx].fpr_md5))
++            {
++              fprintf (stderr, "%s:%d: fingerprint mismatch for "
++                       "sample key %d\n",
++                       __FILE__, __LINE__, idx);
++              fprintf (stderr, "want: %s\n got: %s\n",
++                       sample_keys[idx].fpr_md5, string);
++              exit (1);
++            }
++          xfree (string);
++
++          err = ssh_get_fingerprint_string (key, GCRY_MD_SHA256, &string);
++          if (err)
++            {
++              fprintf (stderr, "%s:%d: error getting fingerprint for "
++                       "sample key %d: %s\n",
++                       __FILE__, __LINE__, idx, gpg_strerror (err));
++              exit (1);
++            }
++
++          if (strcmp (string, sample_keys[idx].fpr_sha256))
+             {
+               fprintf (stderr, "%s:%d: fingerprint mismatch for "
+                        "sample key %d\n",
+                        __FILE__, __LINE__, idx);
+               fprintf (stderr, "want: %s\n got: %s\n",
+-                       sample_keys[idx].fpr, string);
++                       sample_keys[idx].fpr_sha256, string);
+               exit (1);
+             }
+           xfree (string);
++
++          gcry_sexp_release (key);
+         }
+     }
+ 
diff --git a/debian/patches/0024-agent-Write-both-ssh-fingerprints-to-sshcontrol-file.patch b/debian/patches/0024-agent-Write-both-ssh-fingerprints-to-sshcontrol-file.patch
new file mode 100644
index 0000000..9e08e72
--- /dev/null
+++ b/debian/patches/0024-agent-Write-both-ssh-fingerprints-to-sshcontrol-file.patch
@@ -0,0 +1,79 @@
+From: Justus Winter <justus at g10code.com>
+Date: Wed, 24 May 2017 17:29:31 +0200
+Subject: agent: Write both ssh fingerprints to 'sshcontrol' file.
+
+* agent/command-ssh.c (add_control_entry): Hand in the key, write both
+the MD5- and the SHA256-based fingerprint to the 'sshcontrol' file
+when adding ssh keys.
+(ssh_identity_register): Adapt callsite.
+
+GnuPG-bug-id: 2106
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit a5f046d99a084b6a95268f03c1b588e8b78083cb)
+---
+ agent/command-ssh.c | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/agent/command-ssh.c b/agent/command-ssh.c
+index 3dd3dd7..b8edd1a 100644
+--- a/agent/command-ssh.c
++++ b/agent/command-ssh.c
+@@ -1040,12 +1040,14 @@ search_control_file (ssh_control_file_t cf, const char *hexgrip,
+    We can assume that the user wants to allow ssh using this key. */
+ static gpg_error_t
+ add_control_entry (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+-                   const char *hexgrip, const char *fmtfpr,
++                   const char *hexgrip, gcry_sexp_t key,
+                    int ttl, int confirm)
+ {
+   gpg_error_t err;
+   ssh_control_file_t cf;
+   int disabled;
++  char *fpr_md5 = NULL;
++  char *fpr_sha256 = NULL;
+ 
+   (void)ctrl;
+ 
+@@ -1059,19 +1061,31 @@ add_control_entry (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+       struct tm *tp;
+       time_t atime = time (NULL);
+ 
++      err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr_md5);
++      if (err)
++        goto out;
++
++      err = ssh_get_fingerprint_string (key, GCRY_MD_SHA256, &fpr_sha256);
++      if (err)
++        goto out;
++
+       /* Not yet in the file - add it. Because the file has been
+          opened in append mode, we simply need to write to it.  */
+       tp = localtime (&atime);
+       fprintf (cf->fp,
+                ("# %s key added on: %04d-%02d-%02d %02d:%02d:%02d\n"
+-                "# MD5 Fingerprint:  %s\n"
++                "# Fingerprints:  %s\n"
++                "#                %s\n"
+                 "%s %d%s\n"),
+                spec->name,
+                1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
+                tp->tm_hour, tp->tm_min, tp->tm_sec,
+-               fmtfpr, hexgrip, ttl, confirm? " confirm":"");
++               fpr_md5, fpr_sha256, hexgrip, ttl, confirm? " confirm":"");
+ 
+     }
++ out:
++  xfree (fpr_md5);
++  xfree (fpr_sha256);
+   close_control_file (cf);
+   return 0;
+ }
+@@ -3118,7 +3132,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+ 
+  key_exists:
+   /* And add an entry to the sshcontrol file.  */
+-  err = add_control_entry (ctrl, spec, key_grip, key_fpr, ttl, confirm);
++  err = add_control_entry (ctrl, spec, key_grip, key, ttl, confirm);
+ 
+ 
+  out:
diff --git a/debian/patches/0025-agent-Make-digest-algorithms-for-ssh-fingerprints-co.patch b/debian/patches/0025-agent-Make-digest-algorithms-for-ssh-fingerprints-co.patch
new file mode 100644
index 0000000..e6307a4
--- /dev/null
+++ b/debian/patches/0025-agent-Make-digest-algorithms-for-ssh-fingerprints-co.patch
@@ -0,0 +1,141 @@
+From: Justus Winter <justus at g10code.com>
+Date: Wed, 24 May 2017 17:48:42 +0200
+Subject: agent: Make digest algorithms for ssh fingerprints configurable.
+
+* agent/agent.h (opt): New field 'ssh_fingerprint_digest'.
+* agent/command-ssh.c (data_sign, ssh_identity_register): Honor the
+option for strings used to communicate with the user.
+* agent/findkey.c (agent_modify_description): Likewise.
+* agent/gpg-agent.c (cmd_and_opt_values): New value.
+(opts): New option '--ssh-fingerprint-digest'.
+(parse_rereadable_options): Set the default to MD5 for now.
+(main): Handle the new option.
+* doc/gpg-agent.texi: Document the new option.
+--
+
+OpenSSH has transitioned from using MD5 to compute key fingerprints to
+SHA256.  This patch makes the digest used when communicating key
+fingerprints to the user (e.g. in pinentry dialogs) configurable.
+For now this patch conservatively defaults to MD5.
+
+GnuPG-bug-id: 2106
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 525f2c482abb6bc2002eb878b03558fb43e6b004)
+---
+ agent/agent.h       | 4 ++++
+ agent/command-ssh.c | 4 ++--
+ agent/findkey.c     | 3 ++-
+ agent/gpg-agent.c   | 9 +++++++++
+ doc/gpg-agent.texi  | 7 +++++++
+ 5 files changed, 24 insertions(+), 3 deletions(-)
+
+diff --git a/agent/agent.h b/agent/agent.h
+index fadc8e8..0fa4e1b 100644
+--- a/agent/agent.h
++++ b/agent/agent.h
+@@ -167,6 +167,10 @@ struct
+      gpg-agent.c: If the value is less than 2 the name has not yet
+      been malloced. */
+   int browser_socket;
++
++  /* The digest algorithm to use for ssh fingerprints when
++   * communicating with the user.  */
++  int ssh_fingerprint_digest;
+ } opt;
+ 
+ 
+diff --git a/agent/command-ssh.c b/agent/command-ssh.c
+index b8edd1a..e450aed 100644
+--- a/agent/command-ssh.c
++++ b/agent/command-ssh.c
+@@ -2774,7 +2774,7 @@ data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+       err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
+       if (err)
+         goto out;
+-      err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr);
++      err = ssh_get_fingerprint_string (key, opt.ssh_fingerprint_digest, &fpr);
+       if (!err)
+         {
+           gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
+@@ -3052,7 +3052,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+ 
+   bin2hex (key_grip_raw, 20, key_grip);
+ 
+-  err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &key_fpr);
++  err = ssh_get_fingerprint_string (key, opt.ssh_fingerprint_digest, &key_fpr);
+   if (err)
+     goto out;
+ 
+diff --git a/agent/findkey.c b/agent/findkey.c
+index 1f547b0..cff0a7d 100644
+--- a/agent/findkey.c
++++ b/agent/findkey.c
+@@ -412,7 +412,8 @@ agent_modify_description (const char *in, const char *comment,
+ 
+                 case 'F': /* SSH style fingerprint.  */
+                   if (!ssh_fpr && key)
+-                    ssh_get_fingerprint_string (key, GCRY_MD_MD5, &ssh_fpr);
++                    ssh_get_fingerprint_string (key, opt.ssh_fingerprint_digest,
++                                                &ssh_fpr);
+                   if (ssh_fpr)
+                     {
+                       if (out)
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index e7eef2b..d522f18 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -132,6 +132,7 @@ enum cmd_and_opt_values
+   oKeepTTY,
+   oKeepDISPLAY,
+   oSSHSupport,
++  oSSHFingerprintDigest,
+   oPuttySupport,
+   oDisableScdaemon,
+   oDisableCheckOwnSocket,
+@@ -235,6 +236,8 @@ static ARGPARSE_OPTS opts[] = {
+                 /* */    N_("allow passphrase to be prompted through Emacs")),
+ 
+   ARGPARSE_s_n (oSSHSupport,   "enable-ssh-support", N_("enable ssh support")),
++  ARGPARSE_s_s (oSSHFingerprintDigest, "ssh-fingerprint-digest",
++                N_("digest to use when communicating ssh fingerprints")),
+   ARGPARSE_s_n (oPuttySupport, "enable-putty-support",
+ #ifdef HAVE_W32_SYSTEM
+                 /* */           N_("enable putty support")
+@@ -806,6 +809,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
+       opt.allow_emacs_pinentry = 0;
+       opt.disable_scdaemon = 0;
+       disable_check_own_socket = 0;
++      opt.ssh_fingerprint_digest = GCRY_MD_MD5;
+       return 1;
+     }
+ 
+@@ -1187,6 +1191,11 @@ main (int argc, char **argv )
+ 	case oSSHSupport:
+           ssh_support = 1;
+           break;
++	case oSSHFingerprintDigest:
++          opt.ssh_fingerprint_digest = gcry_md_map_name (pargs.r.ret_str);
++          if (opt.ssh_fingerprint_digest == 0)
++            log_error ("Unknown digest algorithm: %s\n", pargs.r.ret_str);
++          break;
+         case oPuttySupport:
+ #        ifdef HAVE_W32_SYSTEM
+           putty_support = 1;
+diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
+index 6ed0ff8..d61dc85 100644
+--- a/doc/gpg-agent.texi
++++ b/doc/gpg-agent.texi
+@@ -636,6 +636,13 @@ and allows the use of gpg-agent with the ssh implementation
+ @command{putty}.  This is similar to the regular ssh-agent support but
+ makes use of Windows message queue as required by @command{putty}.
+ 
++ at anchor{option --ssh-fingerprint-digest}
++ at item --ssh-fingerprint-digest
++ at opindex ssh-fingerprint-digest
++
++Select the digest algorithm used to compute ssh fingerprints that are
++communicated to the user, e.g. in pinentry dialogs.  OpenSSH has
++transitioned from using MD5 to the more secure SHA256.
+ 
+ @end table
+ 
diff --git a/debian/patches/0026-dirmngr-Re-init-libdns-resolver-on-towel-change-of-r.patch b/debian/patches/0026-dirmngr-Re-init-libdns-resolver-on-towel-change-of-r.patch
new file mode 100644
index 0000000..6f9b332
--- /dev/null
+++ b/debian/patches/0026-dirmngr-Re-init-libdns-resolver-on-towel-change-of-r.patch
@@ -0,0 +1,110 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Thu, 25 May 2017 11:33:07 +0200
+Subject: dirmngr: Re-init libdns resolver on towel change of resolv.conf
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+* dirmngr/dns-stuff.c: Include sys/stat.h.
+(RESOLV_CONF_NAME): New macro to replace a string.
+(resolv_conf_changed_p): New.
+(libdns_init): Call new function
+(libdns_res_open): Ditto.
+--
+
+Don't panic.  This is a simple change
+Suggested-by: Stefan Bühler <stbuehler at web.de>
+to avoid complicated if-up.d hooks to reload resolv.conf.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit b5f356e9fba2d99909f8f54d7b7e6836bed87b68)
+---
+ dirmngr/dns-stuff.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 46 insertions(+), 1 deletion(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index a6c14cd..a8ddbc6 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -45,6 +45,9 @@
+ # endif
+ # include <netdb.h>
+ #endif
++#ifdef HAVE_STAT
++# include <sys/stat.h>
++#endif
+ #include <string.h>
+ #include <unistd.h>
+ 
+@@ -111,6 +114,8 @@
+ #define DEFAULT_TIMEOUT 30
+ 
+ 
++#define RESOLV_CONF_NAME "/etc/resolv.conf"
++
+ /* Two flags to enable verbose and debug mode.  */
+ static int opt_verbose;
+ static int opt_debug;
+@@ -391,6 +396,37 @@ libdns_error_to_gpg_error (int serr)
+ #endif /*USE_LIBDNS*/
+ 
+ 
++/* Return true if resolve.conf changed since it was last loaded.  */
++#ifdef USE_LIBDNS
++static int
++resolv_conf_changed_p (void)
++{
++#if defined(HAVE_W32_SYSTEM) || !defined(HAVE_STAT)
++  return 0;
++#else
++  static time_t last_mtime;
++  const char *fname = RESOLV_CONF_NAME;
++  struct stat statbuf;
++  int changed;
++
++  if (stat (fname, &statbuf))
++    {
++      log_error ("stat'ing '%s' failed: %s\n",
++                 fname, gpg_strerror (gpg_error_from_syserror ()));
++      changed = 0;
++      last_mtime = 1; /* Force a "changed" result the next time stat
++                       * works.  */
++    }
++  else
++    {
++      changed = last_mtime && (last_mtime != statbuf.st_mtime);
++      last_mtime = statbuf.st_mtime;
++    }
++  return changed;
++#endif
++}
++#endif /*USE_LIBDNS*/
++
+ #ifdef USE_LIBDNS
+ /* Initialize libdns.  Returns 0 on success; prints a diagnostic and
+  * returns an error code on failure.  */
+@@ -496,7 +532,8 @@ libdns_init (void)
+ #else /* Unix */
+       const char *fname;
+ 
+-      fname = "/etc/resolv.conf";
++      fname = RESOLV_CONF_NAME;
++      resolv_conf_changed_p (); /* Reset timestamp.  */
+       err = libdns_error_to_gpg_error
+         (dns_resconf_loadpath (ld.resolv_conf, fname));
+       if (err)
+@@ -653,6 +690,14 @@ libdns_res_open (struct dns_resolver **r_res)
+ 
+   *r_res = NULL;
+ 
++  /* Force a reload if resolv.conf has changed.  */
++  if (resolv_conf_changed_p ())
++    {
++      if (opt_debug)
++        log_debug ("dns: resolv.conf changed - forcing reload\n");
++      libdns_reinit_pending = 1;
++    }
++
+   if (libdns_reinit_pending)
+     {
+       libdns_reinit_pending = 0;
diff --git a/debian/patches/0027-dirmngr-This-towel-should-better-detect-a-changed-re.patch b/debian/patches/0027-dirmngr-This-towel-should-better-detect-a-changed-re.patch
new file mode 100644
index 0000000..d38e30b
--- /dev/null
+++ b/debian/patches/0027-dirmngr-This-towel-should-better-detect-a-changed-re.patch
@@ -0,0 +1,47 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Thu, 25 May 2017 20:26:54 +0200
+Subject: dirmngr: This towel should better detect a changed resolv.conf.
+
+* dirmngr/dns-stuff.c (resolv_conf_changed_p): Fix initialization time
+issue.
+--
+
+Fixes-commit: b5f356e9fba2d99909f8f54d7b7e6836bed87b68
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit de3a0988ef9addccd6b5c7950fb8797afbc3978d)
+---
+ dirmngr/dns-stuff.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index a8ddbc6..7324aae 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -407,21 +407,23 @@ resolv_conf_changed_p (void)
+   static time_t last_mtime;
+   const char *fname = RESOLV_CONF_NAME;
+   struct stat statbuf;
+-  int changed;
++  int changed = 0;
+ 
+   if (stat (fname, &statbuf))
+     {
+       log_error ("stat'ing '%s' failed: %s\n",
+                  fname, gpg_strerror (gpg_error_from_syserror ()));
+-      changed = 0;
+       last_mtime = 1; /* Force a "changed" result the next time stat
+                        * works.  */
+     }
+-  else
++  else if (!last_mtime)
++    last_mtime = statbuf.st_mtime;
++  else if (last_mtime != statbuf.st_mtime)
+     {
+-      changed = last_mtime && (last_mtime != statbuf.st_mtime);
++      changed = 1;
+       last_mtime = statbuf.st_mtime;
+     }
++
+   return changed;
+ #endif
+ }
diff --git a/debian/patches/series b/debian/patches/series
index ff2555e..de9346c 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -17,3 +17,11 @@ skip-missing-signing-keys/0013-g10-Skip-signing-keys-where-no-secret-key-is-avai
 0017-gpgscm-Fix-checking-for-opcode-arguments.patch
 0018-docs-Point-to-https-dev.gnupg.org.patch
 0019-doc-Fix-spellings.patch
+0020-g10-Fix-default-key-selection-for-signing-possibly-b.patch
+0021-agent-Add-const-qualifier-for-read-only-table.patch
+0022-common-Support-different-digest-algorithms-for-ssh-f.patch
+0023-common-Correctly-render-SHA256-based-ssh-fingerprint.patch
+0024-agent-Write-both-ssh-fingerprints-to-sshcontrol-file.patch
+0025-agent-Make-digest-algorithms-for-ssh-fingerprints-co.patch
+0026-dirmngr-Re-init-libdns-resolver-on-towel-change-of-r.patch
+0027-dirmngr-This-towel-should-better-detect-a-changed-re.patch

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