summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2014-12-21 22:27:55 +0000
committerDamien Miller <djm@mindrot.org>2014-12-22 09:32:29 +1100
commit56d1c83cdd1ac76f1c6bd41e01e80dad834f3994 (patch)
tree700a872e702c686c1815bb1049eb93e88079b598
parent058f839fe15c51be8b3a844a76ab9a8db550be4f (diff)
upstream commit
Add FingerprintHash option to control algorithm used for key fingerprints. Default changes from MD5 to SHA256 and format from hex to base64. Feedback and ok naddy@ markus@
-rw-r--r--auth-rsa.c5
-rw-r--r--auth.c5
-rw-r--r--auth2-hostbased.c7
-rw-r--r--auth2-pubkey.c16
-rw-r--r--digest-libc.c22
-rw-r--r--digest-openssl.c22
-rw-r--r--digest.h8
-rw-r--r--dns.c11
-rw-r--r--key.c7
-rw-r--r--key.h4
-rw-r--r--krl.c8
-rw-r--r--readconf.c24
-rw-r--r--readconf.h4
-rw-r--r--servconf.c24
-rw-r--r--servconf.h4
-rw-r--r--ssh-add.113
-rw-r--r--ssh-add.c54
-rw-r--r--ssh-agent.113
-rw-r--r--ssh-agent.c15
-rw-r--r--ssh-keygen.113
-rw-r--r--ssh-keygen.c58
-rw-r--r--ssh-keysign.c5
-rw-r--r--ssh.16
-rw-r--r--sshconnect.c27
-rw-r--r--sshconnect2.c6
-rw-r--r--sshd_config.513
-rw-r--r--sshkey.c113
-rw-r--r--sshkey.h16
28 files changed, 374 insertions, 149 deletions
diff --git a/auth-rsa.c b/auth-rsa.c
index e9f4ede2..ff7a1322 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-rsa.c,v 1.88 2014/07/15 15:54:14 millert Exp $ */
+/* $OpenBSD: auth-rsa.c,v 1.89 2014/12/21 22:27:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -236,7 +236,8 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file,
"actual %d vs. announced %d.",
file, linenum, BN_num_bits(key->rsa->n), bits);
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+ fp = key_fingerprint(key, options.fingerprint_hash,
+ SSH_FP_DEFAULT);
debug("matching key found: file %s, line %lu %s %s",
file, linenum, key_type(key), fp);
free(fp);
diff --git a/auth.c b/auth.c
index 348ddc39..b259c6ef 100644
--- a/auth.c
+++ b/auth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.c,v 1.107 2014/12/04 02:24:32 djm Exp $ */
+/* $OpenBSD: auth.c,v 1.108 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -679,7 +679,8 @@ auth_key_is_revoked(Key *key)
if (options.revoked_keys_file == NULL)
return 0;
- if ((fp = sshkey_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX)) == NULL) {
+ if ((fp = sshkey_fingerprint(key, options.fingerprint_hash,
+ SSH_FP_DEFAULT)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
error("%s: fingerprint key: %s", __func__, ssh_err(r));
goto out;
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index 6787e4ca..b7ae3535 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-hostbased.c,v 1.18 2014/07/15 15:54:14 millert Exp $ */
+/* $OpenBSD: auth2-hostbased.c,v 1.19 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -208,13 +208,14 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
if (host_status == HOST_OK) {
if (key_is_cert(key)) {
fp = key_fingerprint(key->cert->signature_key,
- SSH_FP_MD5, SSH_FP_HEX);
+ options.fingerprint_hash, SSH_FP_DEFAULT);
verbose("Accepted certificate ID \"%s\" signed by "
"%s CA %s from %s@%s", key->cert->key_id,
key_type(key->cert->signature_key), fp,
cuser, lookup);
} else {
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+ fp = key_fingerprint(key, options.fingerprint_hash,
+ SSH_FP_DEFAULT);
verbose("Accepted %s public key %s from %s@%s",
key_type(key), fp, cuser, lookup);
}
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 0a3c1dee..04b70e36 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-pubkey.c,v 1.42 2014/12/04 02:24:32 djm Exp $ */
+/* $OpenBSD: auth2-pubkey.c,v 1.43 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -213,7 +213,7 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
if (key_is_cert(key)) {
fp = key_fingerprint(key->cert->signature_key,
- SSH_FP_MD5, SSH_FP_HEX);
+ options.fingerprint_hash, SSH_FP_DEFAULT);
auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s",
key_type(key), key->cert->key_id,
(unsigned long long)key->cert->serial,
@@ -221,7 +221,8 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
free(fp);
} else {
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+ fp = key_fingerprint(key, options.fingerprint_hash,
+ SSH_FP_DEFAULT);
auth_info(authctxt, "%s %s%s%s", key_type(key), fp,
extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
free(fp);
@@ -365,8 +366,8 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
continue;
if (!key_is_cert_authority)
continue;
- fp = key_fingerprint(found, SSH_FP_MD5,
- SSH_FP_HEX);
+ fp = key_fingerprint(found, options.fingerprint_hash,
+ SSH_FP_DEFAULT);
debug("matching CA found: file %s, line %lu, %s %s",
file, linenum, key_type(found), fp);
/*
@@ -406,7 +407,8 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
if (key_is_cert_authority)
continue;
found_key = 1;
- fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
+ fp = key_fingerprint(found, options.fingerprint_hash,
+ SSH_FP_DEFAULT);
debug("matching key found: file %s, line %lu %s %s",
file, linenum, key_type(found), fp);
free(fp);
@@ -432,7 +434,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
return 0;
ca_fp = key_fingerprint(key->cert->signature_key,
- SSH_FP_MD5, SSH_FP_HEX);
+ options.fingerprint_hash, SSH_FP_DEFAULT);
if (sshkey_in_file(key->cert->signature_key,
options.trusted_user_ca_keys, 1, 0) != 0) {
diff --git a/digest-libc.c b/digest-libc.c
index 1b4423a0..169ded07 100644
--- a/digest-libc.c
+++ b/digest-libc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: digest-libc.c,v 1.3 2014/06/24 01:13:21 djm Exp $ */
+/* $OpenBSD: digest-libc.c,v 1.4 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
* Copyright (c) 2014 Markus Friedl. All rights reserved.
@@ -126,6 +126,26 @@ ssh_digest_by_alg(int alg)
return &(digests[alg]);
}
+int
+ssh_digest_alg_by_name(const char *name)
+{
+ int alg;
+
+ for (alg = 0; alg < SSH_DIGEST_MAX; alg++) {
+ if (strcasecmp(name, digests[alg].name) == 0)
+ return digests[alg].id;
+ }
+ return -1;
+}
+
+const char *
+ssh_digest_alg_name(int alg)
+{
+ const struct ssh_digest *digest = ssh_digest_by_alg(alg);
+
+ return digest == NULL ? NULL : digest->name;
+}
+
size_t
ssh_digest_bytes(int alg)
{
diff --git a/digest-openssl.c b/digest-openssl.c
index 02b17034..bb58ff22 100644
--- a/digest-openssl.c
+++ b/digest-openssl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: digest-openssl.c,v 1.4 2014/07/03 03:26:43 djm Exp $ */
+/* $OpenBSD: digest-openssl.c,v 1.5 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
*
@@ -74,6 +74,26 @@ ssh_digest_by_alg(int alg)
return &(digests[alg]);
}
+int
+ssh_digest_alg_by_name(const char *name)
+{
+ int alg;
+
+ for (alg = 0; digests[alg].id != -1; alg++) {
+ if (strcasecmp(name, digests[alg].name) == 0)
+ return digests[alg].id;
+ }
+ return -1;
+}
+
+const char *
+ssh_digest_alg_name(int alg)
+{
+ const struct ssh_digest *digest = ssh_digest_by_alg(alg);
+
+ return digest == NULL ? NULL : digest->name;
+}
+
size_t
ssh_digest_bytes(int alg)
{
diff --git a/digest.h b/digest.h
index 6afb197f..3fe07346 100644
--- a/digest.h
+++ b/digest.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: digest.h,v 1.6 2014/07/03 04:36:45 djm Exp $ */
+/* $OpenBSD: digest.h,v 1.7 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
*
@@ -33,6 +33,12 @@
struct sshbuf;
struct ssh_digest_ctx;
+/* Looks up a digest algorithm by name */
+int ssh_digest_alg_by_name(const char *name);
+
+/* Returns the algorithm name for a digest identifier */
+const char *ssh_digest_alg_name(int alg);
+
/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
size_t ssh_digest_bytes(int alg);
diff --git a/dns.c b/dns.c
index c4d073cf..4b8ae44c 100644
--- a/dns.c
+++ b/dns.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dns.c,v 1.31 2014/06/24 01:13:21 djm Exp $ */
+/* $OpenBSD: dns.c,v 1.32 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
@@ -41,6 +41,7 @@
#include "key.h"
#include "dns.h"
#include "log.h"
+#include "digest.h"
static const char *errset_text[] = {
"success", /* 0 ERRSET_SUCCESS */
@@ -80,7 +81,7 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
u_char **digest, u_int *digest_len, Key *key)
{
int success = 0;
- enum fp_type fp_type = 0;
+ int fp_alg = -1;
switch (key->type) {
case KEY_RSA:
@@ -110,17 +111,17 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
switch (*digest_type) {
case SSHFP_HASH_SHA1:
- fp_type = SSH_FP_SHA1;
+ fp_alg = SSH_DIGEST_SHA1;
break;
case SSHFP_HASH_SHA256:
- fp_type = SSH_FP_SHA256;
+ fp_alg = SSH_DIGEST_SHA256;
break;
default:
*digest_type = SSHFP_HASH_RESERVED; /* 0 */
}
if (*algorithm && *digest_type) {
- *digest = key_fingerprint_raw(key, fp_type, digest_len);
+ *digest = key_fingerprint_raw(key, fp_alg, digest_len);
if (*digest == NULL)
fatal("dns_read_key: null from key_fingerprint_raw()");
success = 1;
diff --git a/key.c b/key.c
index dd0f448a..b821d9e1 100644
--- a/key.c
+++ b/key.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: key.c,v 1.123 2014/12/04 20:47:36 djm Exp $ */
+/* $OpenBSD: key.c,v 1.124 2014/12/21 22:27:56 djm Exp $ */
/*
* placed in the public domain
*/
@@ -40,8 +40,7 @@ key_new_private(int type)
}
u_char*
-key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
- u_int *dgst_raw_length)
+key_fingerprint_raw(const Key *k, int dgst_alg, u_int *dgst_raw_length)
{
u_char *ret = NULL;
size_t dlen;
@@ -49,7 +48,7 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
if (dgst_raw_length != NULL)
*dgst_raw_length = 0;
- if ((r = sshkey_fingerprint_raw(k, dgst_type, &ret, &dlen)) != 0)
+ if ((r = sshkey_fingerprint_raw(k, dgst_alg, &ret, &dlen)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
if (dlen > INT_MAX)
fatal("%s: giant len %zu", __func__, dlen);
diff --git a/key.h b/key.h
index 212a169f..de786573 100644
--- a/key.h
+++ b/key.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: key.h,v 1.43 2014/12/04 20:47:36 djm Exp $ */
+/* $OpenBSD: key.h,v 1.44 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -67,7 +67,7 @@ void key_add_private(Key *);
Key *key_new_private(int);
void key_free(Key *);
Key *key_demote(const Key *);
-u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *);
+u_char *key_fingerprint_raw(const Key *, int, u_int *);
int key_write(const Key *, FILE *);
int key_read(Key *, char **);
diff --git a/krl.c b/krl.c
index 5a5cdde0..3439e9c2 100644
--- a/krl.c
+++ b/krl.c
@@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $OpenBSD: krl.c,v 1.20 2014/12/04 01:49:59 djm Exp $ */
+/* $OpenBSD: krl.c,v 1.21 2014/12/21 22:27:56 djm Exp $ */
#include "includes.h"
@@ -36,6 +36,7 @@
#include "misc.h"
#include "log.h"
#include "ssherr.h"
+#include "digest.h"
#include "krl.h"
@@ -411,7 +412,8 @@ ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key)
int r;
debug3("%s: revoke type %s by sha1", __func__, sshkey_type(key));
- if ((r = sshkey_fingerprint_raw(key, SSH_FP_SHA1, &blob, &len)) != 0)
+ if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1,
+ &blob, &len)) != 0)
return r;
return revoke_blob(&krl->revoked_sha1s, blob, len);
}
@@ -1151,7 +1153,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
/* Check explicitly revoked hashes first */
memset(&rb, 0, sizeof(rb));
- if ((r = sshkey_fingerprint_raw(key, SSH_FP_SHA1,
+ if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1,
&rb.blob, &rb.len)) != 0)
return r;
erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
diff --git a/readconf.c b/readconf.c
index e0386935..399b73e9 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.223 2014/12/04 02:24:32 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.224 2014/12/21 22:27:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -60,6 +60,7 @@
#include "mac.h"
#include "uidswap.h"
#include "myproposal.h"
+#include "digest.h"
/* Format of the configuration file:
@@ -155,6 +156,7 @@ typedef enum {
oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
+ oFingerprintHash,
oIgnoredUnknownOption, oDeprecated, oUnsupported
} OpCodes;
@@ -270,6 +272,7 @@ static struct {
{ "streamlocalbindmask", oStreamLocalBindMask },
{ "streamlocalbindunlink", oStreamLocalBindUnlink },
{ "revokedhostkeys", oRevokedHostKeys },
+ { "fingerprinthash", oFingerprintHash },
{ "ignoreunknown", oIgnoreUnknown },
{ NULL, oBadOption }
@@ -1460,6 +1463,18 @@ parse_int:
charptr = &options->revoked_host_keys;
goto parse_string;
+ case oFingerprintHash:
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing argument.",
+ filename, linenum);
+ if ((value = ssh_digest_alg_by_name(arg)) == -1)
+ fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
+ filename, linenum, arg);
+ if (*activep)
+ options->fingerprint_hash = value;
+ break;
+
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
@@ -1637,6 +1652,7 @@ initialize_options(Options * options)
options->canonicalize_fallback_local = -1;
options->canonicalize_hostname = -1;
options->revoked_host_keys = NULL;
+ options->fingerprint_hash = -1;
}
/*
@@ -1814,6 +1830,9 @@ fill_default_options(Options * options)
options->canonicalize_fallback_local = 1;
if (options->canonicalize_hostname == -1)
options->canonicalize_hostname = SSH_CANONICALISE_NO;
+ if (options->fingerprint_hash == -1)
+ options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
+
#define CLEAR_ON_NONE(v) \
do { \
if (option_clear_or_none(v)) { \
@@ -2071,6 +2090,8 @@ fmt_intarg(OpCodes code, int val)
return fmt_multistate_int(val, multistate_requesttty);
case oCanonicalizeHostname:
return fmt_multistate_int(val, multistate_canonicalizehostname);
+ case oFingerprintHash:
+ return ssh_digest_alg_name(val);
case oProtocol:
switch (val) {
case SSH_PROTO_1:
@@ -2205,6 +2226,7 @@ dump_client_config(Options *o, const char *host)
dump_cfg_fmtint(oControlMaster, o->control_master);
dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
+ dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
dump_cfg_fmtint(oForwardAgent, o->forward_agent);
dump_cfg_fmtint(oForwardX11, o->forward_x11);
dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
diff --git a/readconf.h b/readconf.h
index 49858bff..11a7332c 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.104 2014/12/04 02:24:32 djm Exp $ */
+/* $OpenBSD: readconf.h,v 1.105 2014/12/21 22:27:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -146,6 +146,8 @@ typedef struct {
char *revoked_host_keys;
+ int fingerprint_hash;
+
char *ignored_unknown; /* Pattern list of unknown tokens to ignore */
} Options;
diff --git a/servconf.c b/servconf.c
index 99396fb1..abc3c72f 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: servconf.c,v 1.255 2014/11/24 03:39:22 jsg Exp $ */
+/* $OpenBSD: servconf.c,v 1.256 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -55,6 +55,7 @@
#include "hostfile.h"
#include "auth.h"
#include "myproposal.h"
+#include "digest.h"
static void add_listen_addr(ServerOptions *, char *, int);
static void add_one_listen_addr(ServerOptions *, char *, int);
@@ -158,6 +159,7 @@ initialize_server_options(ServerOptions *options)
options->ip_qos_interactive = -1;
options->ip_qos_bulk = -1;
options->version_addendum = NULL;
+ options->fingerprint_hash = -1;
}
void
@@ -313,6 +315,8 @@ fill_default_server_options(ServerOptions *options)
options->fwd_opts.streamlocal_bind_mask = 0177;
if (options->fwd_opts.streamlocal_bind_unlink == -1)
options->fwd_opts.streamlocal_bind_unlink = 0;
+ if (options->fingerprint_hash == -1)
+ options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
/* Turn privilege separation on by default */
if (use_privsep == -1)
use_privsep = PRIVSEP_NOSANDBOX;
@@ -362,7 +366,7 @@ typedef enum {
sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
sStreamLocalBindMask, sStreamLocalBindUnlink,
- sAllowStreamLocalForwarding,
+ sAllowStreamLocalForwarding, sFingerprintHash,
sDeprecated, sUnsupported
} ServerOpCodes;
@@ -493,6 +497,7 @@ static struct {
{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
+ { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
{ NULL, sBadOption, 0 }
};
@@ -1670,6 +1675,18 @@ process_server_config_line(ServerOptions *options, char *line,
intptr = &options->fwd_opts.streamlocal_bind_unlink;
goto parse_flag;
+ case sFingerprintHash:
+ arg = strdelim(&cp);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing argument.",
+ filename, linenum);
+ if ((value = ssh_digest_alg_by_name(arg)) == -1)
+ fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
+ filename, linenum, arg);
+ if (*activep)
+ options->fingerprint_hash = value;
+ break;
+
case sDeprecated:
logit("%s line %d: Deprecated option %s",
filename, linenum, arg);
@@ -1912,6 +1929,8 @@ fmt_intarg(ServerOpCodes code, int val)
return fmt_multistate_int(val, multistate_tcpfwd);
case sAllowStreamLocalForwarding:
return fmt_multistate_int(val, multistate_tcpfwd);
+ case sFingerprintHash:
+ return ssh_digest_alg_name(val);
case sProtocol:
switch (val) {
case SSH_PROTO_1:
@@ -2073,6 +2092,7 @@ dump_config(ServerOptions *o)
dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
+ dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
/* string arguments */
dump_cfg_string(sPidFile, o->pid_file);
diff --git a/servconf.h b/servconf.h
index 766db3a3..49b228bd 100644
--- a/servconf.h
+++ b/servconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.114 2014/07/15 15:54:14 millert Exp $ */
+/* $OpenBSD: servconf.h,v 1.115 2014/12/21 22:27:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -185,6 +185,8 @@ typedef struct {
u_int num_auth_methods;
char *auth_methods[MAX_AUTH_METHODS];
+
+ int fingerprint_hash;
} ServerOptions;
/* Information about the incoming connection as used by Match */
diff --git a/ssh-add.1 b/ssh-add.1
index 9da7a283..926456f0 100644
--- a/ssh-add.1
+++ b/ssh-add.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-add.1,v 1.60 2014/08/30 15:33:50 sobrado Exp $
+.\" $OpenBSD: ssh-add.1,v 1.61 2014/12/21 22:27:56 djm Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: August 30 2014 $
+.Dd $Mdocdate: December 21 2014 $
.Dt SSH-ADD 1
.Os
.Sh NAME
@@ -44,6 +44,7 @@
.Sh SYNOPSIS
.Nm ssh-add
.Op Fl cDdkLlXx
+.Op Fl E Ar fingerprint_hash
.Op Fl t Ar life
.Op Ar
.Nm ssh-add
@@ -108,6 +109,14 @@ If no public key is found at a given path,
will append
.Pa .pub
and retry.
+.It Fl E Ar fingerprint_hash
+Specifies the hash algorithm used when displaying key fingerprints.
+Valid options are:
+.Dq md5
+and
+.Dq sha256 .
+The default is
+.Dq sha256 .
.It Fl e Ar pkcs11
Remove keys provided by the PKCS#11 shared library
.Ar pkcs11 .
diff --git a/ssh-add.c b/ssh-add.c
index ba11aa15..3680ab07 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-add.c,v 1.114 2014/11/26 18:34:51 millert Exp $ */
+/* $OpenBSD: ssh-add.c,v 1.115 2014/12/21 22:27:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -63,6 +63,7 @@
#include "pathnames.h"
#include "misc.h"
#include "ssherr.h"
+#include "digest.h"
/* argv0 */
extern char *__progname;
@@ -79,6 +80,8 @@ static char *default_files[] = {
NULL
};
+static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
+
/* Default lifetime (0 == forever) */
static int lifetime = 0;
@@ -340,8 +343,8 @@ list_identities(AuthenticationConnection *ac, int do_fp)
key = ssh_get_next_identity(ac, &comment, version)) {
had_identities = 1;
if (do_fp) {
- fp = key_fingerprint(key, SSH_FP_MD5,
- SSH_FP_HEX);
+ fp = key_fingerprint(key, fingerprint_hash,
+ SSH_FP_DEFAULT);
printf("%d %s %s (%s)\n",
key_size(key), fp, comment, key_type(key));
free(fp);
@@ -408,6 +411,7 @@ usage(void)
fprintf(stderr, "usage: %s [options] [file ...]\n", __progname);
fprintf(stderr, "Options:\n");
fprintf(stderr, " -l List fingerprints of all identities.\n");
+ fprintf(stderr, " -E hash Specify hash algorithm used for fingerprints.\n");
fprintf(stderr, " -L List public key parameters of all identities.\n");
fprintf(stderr, " -k Load only keys and not certificates.\n");
fprintf(stderr, " -c Require confirmation to sign using identities\n");
@@ -428,6 +432,7 @@ main(int argc, char **argv)
AuthenticationConnection *ac = NULL;
char *pkcs11provider = NULL;
int i, ch, deleting = 0, ret = 0, key_only = 0;
+ int xflag = 0, lflag = 0, Dflag = 0;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
@@ -446,21 +451,28 @@ main(int argc, char **argv)
"Could not open a connection to your authentication agent.\n");
exit(2);
}
- while ((ch = getopt(argc, argv, "klLcdDxXe:s:t:")) != -1) {
+ while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:t:")) != -1) {
switch (ch) {
+ case 'E':
+ fingerprint_hash = ssh_digest_alg_by_name(optarg);
+ if (fingerprint_hash == -1)
+ fatal("Invalid hash algorithm \"%s\"", optarg);
+ break;
case 'k':
key_only = 1;
break;
case 'l':
case 'L':
- if (list_identities(ac, ch == 'l' ? 1 : 0) == -1)
- ret = 1;
- goto done;
+ if (lflag != 0)
+ fatal("-%c flag already specified", lflag);
+ lflag = ch;
+ break;
case 'x':
case 'X':
- if (lock_agent(ac, ch == 'x' ? 1 : 0) == -1)
- ret = 1;
- goto done;
+ if (xflag != 0)
+ fatal("-%c flag already specified", xflag);
+ xflag = ch;
+ break;
case 'c':
confirm = 1;
break;
@@ -468,9 +480,8 @@ main(int argc, char **argv)
deleting = 1;
break;
case 'D':
- if (delete_all(ac) == -1)
- ret = 1;
- goto done;
+ Dflag = 1;
+ break;
case 's':
pkcs11provider = optarg;
break;
@@ -491,6 +502,23 @@ main(int argc, char **argv)
goto done;
}
}
+
+ if ((xflag != 0) + (lflag != 0) + (Dflag != 0) > 1)
+ fatal("Invalid combination of actions");
+ else if (xflag) {
+ if (lock_agent(ac, xflag == 'x' ? 1 : 0) == -1)
+ ret = 1;
+ goto done;
+ } else if (lflag) {
+ if (list_identities(ac, lflag == 'l' ? 1 : 0) == -1)
+ ret = 1;
+ goto done;
+ } else if (Dflag) {
+ if (delete_all(ac) == -1)
+ ret = 1;
+ goto done;
+ }
+
argc -= optind;
argv += optind;
if (pkcs11provider != NULL) {
diff --git a/ssh-agent.1 b/ssh-agent.1
index b5506532..6759afec 100644
--- a/ssh-agent.1
+++ b/ssh-agent.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-agent.1,v 1.56 2014/08/30 15:33:50 sobrado Exp $
+.\" $OpenBSD: ssh-agent.1,v 1.57 2014/12/21 22:27:56 djm Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: August 30 2014 $
+.Dd $Mdocdate: December 21 2014 $
.Dt SSH-AGENT 1
.Os
.Sh NAME
@@ -45,6 +45,7 @@
.Op Fl c | s
.Op Fl d
.Op Fl a Ar bind_address
+.Op Fl E Ar fingerprint_hash
.Op Fl t Ar life
.Op Ar command Op Ar arg ...
.Nm ssh-agent
@@ -96,6 +97,14 @@ Debug mode.
When this option is specified
.Nm
will not fork.
+.It Fl E Ar fingerprint_hash
+Specifies the hash algorithm used when displaying key fingerprints.
+Valid options are:
+.Dq md5
+and
+.Dq sha256 .
+The default is
+.Dq sha256 .
.It Fl k
Kill the current agent (given by the
.Ev SSH_AGENT_PID
diff --git a/ssh-agent.c b/ssh-agent.c
index 9c11d48d..c2dc1fa0 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.191 2014/11/18 20:54:28 krw Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.192 2014/12/21 22:27:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -142,6 +142,8 @@ extern char *__progname;
/* Default lifetime in seconds (0 == forever) */
static long lifetime = 0;
+static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
+
static void
close_socket(SocketEntry *e)
{
@@ -203,7 +205,7 @@ confirm_key(Identity *id)
char *p;
int ret = -1;
- p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
+ p = key_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT);
if (ask_permission("Allow use of key %s?\nKey fingerprint %s.",
id->comment, p))
ret = 0;
@@ -1026,7 +1028,7 @@ usage(void)
{
fprintf(stderr,
"usage: ssh-agent [-c | -s] [-d] [-a bind_address] [-t life]\n"
- " [command [arg ...]]\n"
+ " [-E fingerprint_hash] [command [arg ...]]\n"
" ssh-agent [-c | -s] -k\n");
exit(1);
}
@@ -1069,8 +1071,13 @@ main(int ac, char **av)
__progname = ssh_get_progname(av[0]);
seed_rng();
- while ((ch = getopt(ac, av, "cdksa:t:")) != -1) {
+ while ((ch = getopt(ac, av, "cdksE:a:t:")) != -1) {
switch (ch) {
+ case 'E':
+ fingerprint_hash = ssh_digest_alg_by_name(optarg);
+ if (fingerprint_hash == -1)
+