Commit 037a5c40 authored by Daniel Kahn Gillmor's avatar Daniel Kahn Gillmor

include upstream bugfixes and improvements (Closes: #863221)

parent 36c6f2e6
From: NIIBE Yutaka <gniibe@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@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;
From: NIIBE Yutaka <gniibe@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@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. */
From: Justus Winter <justus@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@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)
{
From: Justus Winter <justus@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@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:
From: Justus Winter <justus@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@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