[openssh-commits] [openssh] 07/13: upstream commit

git+noreply at mindrot.org git+noreply at mindrot.org
Tue Jan 27 00:34:03 EST 2015


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

djm pushed a commit to branch master
in repository openssh.

commit 5104db7cbd6cdd9c5971f4358e74414862fc1022
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Mon Jan 26 06:10:03 2015 +0000

    upstream commit
    
    correctly match ECDSA subtype (== curve) for
     offered/recevied host keys. Fixes connection-killing host key mismatches when
     a server offers multiple ECDSA keys with different curve type (an extremely
     unlikely configuration).
    
    ok markus, "looks mechanical" deraadt@
---
 auth.h       |  6 +++---
 kex.c        |  3 ++-
 kex.h        |  7 ++++---
 kexc25519c.c |  6 ++++--
 kexc25519s.c |  8 +++++---
 kexdhc.c     |  6 ++++--
 kexdhs.c     |  8 +++++---
 kexecdhc.c   |  6 ++++--
 kexecdhs.c   |  8 +++++---
 kexgexc.c    |  8 +++++++-
 kexgexs.c    |  8 +++++---
 ssh_api.c    | 16 +++++++++-------
 sshconnect.c |  5 +++--
 sshd.c       | 15 ++++++++-------
 14 files changed, 68 insertions(+), 42 deletions(-)

diff --git a/auth.h b/auth.h
index 60d1c33..d282619 100644
--- a/auth.h
+++ b/auth.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.h,v 1.80 2015/01/19 20:16:15 markus Exp $ */
+/* $OpenBSD: auth.h,v 1.81 2015/01/26 06:10:03 djm Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -204,8 +204,8 @@ check_key_in_hostfiles(struct passwd *, Key *, const char *,
 /* hostkey handling */
 Key	*get_hostkey_by_index(int);
 Key	*get_hostkey_public_by_index(int, struct ssh *);
-Key	*get_hostkey_public_by_type(int, struct ssh *);
-Key	*get_hostkey_private_by_type(int, struct ssh *);
+Key	*get_hostkey_public_by_type(int, int, struct ssh *);
+Key	*get_hostkey_private_by_type(int, int, struct ssh *);
 int	 get_hostkey_index(Key *, struct ssh *);
 int	 ssh1_session_key(BIGNUM *);
 int	 sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, u_char *, size_t, u_int);
diff --git a/kex.c b/kex.c
index 5b7b1e8..7eb3185 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.103 2015/01/20 23:14:00 deraadt Exp $ */
+/* $OpenBSD: kex.c,v 1.104 2015/01/26 06:10:03 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
@@ -546,6 +546,7 @@ choose_hostkeyalg(struct kex *k, char *client, char *server)
 	k->hostkey_type = sshkey_type_from_name(hostkeyalg);
 	if (k->hostkey_type == KEY_UNSPEC)
 		return SSH_ERR_INTERNAL_ERROR;
+	k->hostkey_nid = sshkey_ecdsa_nid_from_name(hostkeyalg);
 	free(hostkeyalg);
 	return 0;
 }
diff --git a/kex.h b/kex.h
index 1798eea..45d3577 100644
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.69 2015/01/19 20:16:15 markus Exp $ */
+/* $OpenBSD: kex.h,v 1.70 2015/01/26 06:10:03 djm Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -116,6 +116,7 @@ struct kex {
 	int	server;
 	char	*name;
 	int	hostkey_type;
+	int	hostkey_nid;
 	u_int	kex_type;
 	int	roaming;
 	struct sshbuf *my;
@@ -127,8 +128,8 @@ struct kex {
 	char	*client_version_string;
 	char	*server_version_string;
 	int	(*verify_host_key)(struct sshkey *, struct ssh *);
-	struct sshkey *(*load_host_public_key)(int, struct ssh *);
-	struct sshkey *(*load_host_private_key)(int, struct ssh *);
+	struct sshkey *(*load_host_public_key)(int, int, struct ssh *);
+	struct sshkey *(*load_host_private_key)(int, int, struct ssh *);
 	int	(*host_key_index)(struct sshkey *, struct ssh *);
 	int	(*sign)(struct sshkey *, struct sshkey *,
 	    u_char **, size_t *, u_char *, size_t, u_int);
diff --git a/kexc25519c.c b/kexc25519c.c
index 833ce05..b7ef65d 100644
--- a/kexc25519c.c
+++ b/kexc25519c.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexc25519c.c,v 1.6 2015/01/19 20:16:15 markus Exp $ */
+/* $OpenBSD: kexc25519c.c,v 1.7 2015/01/26 06:10:03 djm Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
@@ -92,7 +92,9 @@ input_kex_c25519_reply(int type, u_int32_t seq, void *ctxt)
 	    (r = sshkey_from_blob(server_host_key_blob, sbloblen,
 	    &server_host_key)) != 0)
 		goto out;
-	if (server_host_key->type != kex->hostkey_type) {
+	if (server_host_key->type != kex->hostkey_type ||
+	    (kex->hostkey_type == KEY_ECDSA &&
+	    server_host_key->ecdsa_nid != kex->hostkey_nid)) {
 		r = SSH_ERR_KEY_TYPE_MISMATCH;
 		goto out;
 	}
diff --git a/kexc25519s.c b/kexc25519s.c
index d840856..b2d2c85 100644
--- a/kexc25519s.c
+++ b/kexc25519s.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexc25519s.c,v 1.7 2015/01/20 07:55:33 djm Exp $ */
+/* $OpenBSD: kexc25519s.c,v 1.8 2015/01/26 06:10:03 djm Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
@@ -75,8 +75,10 @@ input_kex_c25519_init(int type, u_int32_t seq, void *ctxt)
 		r = SSH_ERR_INVALID_ARGUMENT;
 		goto out;
 	}
-	server_host_public = kex->load_host_public_key(kex->hostkey_type, ssh);
-	server_host_private = kex->load_host_private_key(kex->hostkey_type, ssh);
+	server_host_public = kex->load_host_public_key(kex->hostkey_type,
+	    kex->hostkey_nid, ssh);
+	server_host_private = kex->load_host_private_key(kex->hostkey_type,
+	    kex->hostkey_nid, ssh);
 	if (server_host_public == NULL) {
 		r = SSH_ERR_NO_HOSTKEY_LOADED;
 		goto out;
diff --git a/kexdhc.c b/kexdhc.c
index 52b7522..af259f1 100644
--- a/kexdhc.c
+++ b/kexdhc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexdhc.c,v 1.17 2015/01/19 20:16:15 markus Exp $ */
+/* $OpenBSD: kexdhc.c,v 1.18 2015/01/26 06:10:03 djm Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
@@ -114,7 +114,9 @@ input_kex_dh(int type, u_int32_t seq, void *ctxt)
 	    (r = sshkey_from_blob(server_host_key_blob, sbloblen,
 	    &server_host_key)) != 0)
 		goto out;
-	if (server_host_key->type != kex->hostkey_type) {
+	if (server_host_key->type != kex->hostkey_type ||
+	    (kex->hostkey_type == KEY_ECDSA &&
+	    server_host_key->ecdsa_nid != kex->hostkey_nid)) {
 		r = SSH_ERR_KEY_TYPE_MISMATCH;
 		goto out;
 	}
diff --git a/kexdhs.c b/kexdhs.c
index 0bfa08b..de7c05b 100644
--- a/kexdhs.c
+++ b/kexdhs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexdhs.c,v 1.21 2015/01/20 07:55:33 djm Exp $ */
+/* $OpenBSD: kexdhs.c,v 1.22 2015/01/26 06:10:03 djm Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
@@ -101,8 +101,10 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt)
 		r = SSH_ERR_INVALID_ARGUMENT;
 		goto out;
 	}
-	server_host_public = kex->load_host_public_key(kex->hostkey_type, ssh);
-	server_host_private = kex->load_host_private_key(kex->hostkey_type, ssh);
+	server_host_public = kex->load_host_public_key(kex->hostkey_type,
+	    kex->hostkey_nid, ssh);
+	server_host_private = kex->load_host_private_key(kex->hostkey_type,
+	    kex->hostkey_nid, ssh);
 	if (server_host_public == NULL) {
 		r = SSH_ERR_NO_HOSTKEY_LOADED;
 		goto out;
diff --git a/kexecdhc.c b/kexecdhc.c
index 3f362c5..90220ce 100644
--- a/kexecdhc.c
+++ b/kexecdhc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexecdhc.c,v 1.9 2015/01/19 20:16:15 markus Exp $ */
+/* $OpenBSD: kexecdhc.c,v 1.10 2015/01/26 06:10:03 djm Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
@@ -124,7 +124,9 @@ input_kex_ecdh_reply(int type, u_int32_t seq, void *ctxt)
 	    (r = sshkey_from_blob(server_host_key_blob, sbloblen,
 	    &server_host_key)) != 0)
 		goto out;
-	if (server_host_key->type != kex->hostkey_type) {
+	if (server_host_key->type != kex->hostkey_type ||
+	    (kex->hostkey_type == KEY_ECDSA &&
+	    server_host_key->ecdsa_nid != kex->hostkey_nid)) {
 		r = SSH_ERR_KEY_TYPE_MISMATCH;
 		goto out;
 	}
diff --git a/kexecdhs.c b/kexecdhs.c
index f47a7b2..0adb80e 100644
--- a/kexecdhs.c
+++ b/kexecdhs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexecdhs.c,v 1.13 2015/01/20 07:55:33 djm Exp $ */
+/* $OpenBSD: kexecdhs.c,v 1.14 2015/01/26 06:10:03 djm Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
@@ -95,8 +95,10 @@ input_kex_ecdh_init(int type, u_int32_t seq, void *ctxt)
 		r = SSH_ERR_INVALID_ARGUMENT;
 		goto out;
 	}
-	server_host_public = kex->load_host_public_key(kex->hostkey_type, ssh);
-	server_host_private = kex->load_host_private_key(kex->hostkey_type, ssh);
+	server_host_public = kex->load_host_public_key(kex->hostkey_type,
+	    kex->hostkey_nid, ssh);
+	server_host_private = kex->load_host_private_key(kex->hostkey_type,
+	    kex->hostkey_nid, ssh);
 	if (server_host_public == NULL) {
 		r = SSH_ERR_NO_HOSTKEY_LOADED;
 		goto out;
diff --git a/kexgexc.c b/kexgexc.c
index 0898824..e8e059a 100644
--- a/kexgexc.c
+++ b/kexgexc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgexc.c,v 1.19 2015/01/19 20:16:15 markus Exp $ */
+/* $OpenBSD: kexgexc.c,v 1.20 2015/01/26 06:10:03 djm Exp $ */
 /*
  * Copyright (c) 2000 Niels Provos.  All rights reserved.
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
@@ -176,6 +176,12 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt)
 		r = SSH_ERR_KEY_TYPE_MISMATCH;
 		goto out;
 	}
+	if (server_host_key->type != kex->hostkey_type ||
+	    (kex->hostkey_type == KEY_ECDSA &&
+	    server_host_key->ecdsa_nid != kex->hostkey_nid)) {
+		r = SSH_ERR_KEY_TYPE_MISMATCH;
+		goto out;
+	}
 	if (kex->verify_host_key(server_host_key, ssh) == -1) {
 		r = SSH_ERR_SIGNATURE_INVALID;
 		goto out;
diff --git a/kexgexs.c b/kexgexs.c
index ca5ee13..9c281d2 100644
--- a/kexgexs.c
+++ b/kexgexs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgexs.c,v 1.23 2015/01/20 23:14:00 deraadt Exp $ */
+/* $OpenBSD: kexgexs.c,v 1.24 2015/01/26 06:10:03 djm Exp $ */
 /*
  * Copyright (c) 2000 Niels Provos.  All rights reserved.
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
@@ -160,8 +160,10 @@ input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt)
 		r = SSH_ERR_INVALID_ARGUMENT;
 		goto out;
 	}
-	server_host_public = kex->load_host_public_key(kex->hostkey_type, ssh);
-	server_host_private = kex->load_host_private_key(kex->hostkey_type, ssh);
+	server_host_public = kex->load_host_public_key(kex->hostkey_type,
+	    kex->hostkey_nid, ssh);
+	server_host_private = kex->load_host_private_key(kex->hostkey_type,
+	    kex->hostkey_nid, ssh);
 	if (server_host_public == NULL) {
 		r = SSH_ERR_NO_HOSTKEY_LOADED;
 		goto out;
diff --git a/ssh_api.c b/ssh_api.c
index 1df995c..9794e0e 100644
--- a/ssh_api.c
+++ b/ssh_api.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh_api.c,v 1.1 2015/01/19 20:30:23 markus Exp $ */
+/* $OpenBSD: ssh_api.c,v 1.2 2015/01/26 06:10:03 djm Exp $ */
 /*
  * Copyright (c) 2012 Markus Friedl.  All rights reserved.
  *
@@ -38,8 +38,8 @@ int	_ssh_send_banner(struct ssh *, char **);
 int	_ssh_read_banner(struct ssh *, char **);
 int	_ssh_order_hostkeyalgs(struct ssh *);
 int	_ssh_verify_host_key(struct sshkey *, struct ssh *);
-struct sshkey *_ssh_host_public_key(int, struct ssh *);
-struct sshkey *_ssh_host_private_key(int, struct ssh *);
+struct sshkey *_ssh_host_public_key(int, int, struct ssh *);
+struct sshkey *_ssh_host_private_key(int, int, struct ssh *);
 int	_ssh_host_key_sign(struct sshkey *, struct sshkey *, u_char **,
     size_t *, u_char *, size_t, u_int);
 
@@ -425,28 +425,30 @@ _ssh_exchange_banner(struct ssh *ssh)
 }
 
 struct sshkey *
-_ssh_host_public_key(int type, struct ssh *ssh)
+_ssh_host_public_key(int type, int nid, struct ssh *ssh)
 {
 	struct key_entry *k;
 
 	debug3("%s: need %d", __func__, type);
 	TAILQ_FOREACH(k, &ssh->public_keys, next) {
 		debug3("%s: check %s", __func__, sshkey_type(k->key));
-		if (k->key->type == type)
+		if (k->key->type == type &&
+		    (type != KEY_ECDSA || k->key->ecdsa_nid == nid))
 			return (k->key);
 	}
 	return (NULL);
 }
 
 struct sshkey *
-_ssh_host_private_key(int type, struct ssh *ssh)
+_ssh_host_private_key(int type, int nid, struct ssh *ssh)
 {
 	struct key_entry *k;
 
 	debug3("%s: need %d", __func__, type);
 	TAILQ_FOREACH(k, &ssh->private_keys, next) {
 		debug3("%s: check %s", __func__, sshkey_type(k->key));
-		if (k->key->type == type)
+		if (k->key->type == type &&
+		    (type != KEY_ECDSA || k->key->ecdsa_nid == nid))
 			return (k->key);
 	}
 	return (NULL);
diff --git a/sshconnect.c b/sshconnect.c
index ae3b642..df921be 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.257 2015/01/26 03:04:46 djm Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.258 2015/01/26 06:10:03 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -1243,7 +1243,8 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
 		goto out;
 	}
 
-	debug("Server host key: %s %s", sshkey_type(host_key), fp);
+	debug("Server host key: %s %s",
+	    compat20 ? sshkey_ssh_name(host_key) : sshkey_type(host_key), fp);
 
 	if (sshkey_equal(previous_host_key, host_key)) {
 		debug2("%s: server host key %s %s matches cached key",
diff --git a/sshd.c b/sshd.c
index f2ee10d..004ddd4 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.439 2015/01/26 03:04:46 djm Exp $ */
+/* $OpenBSD: sshd.c,v 1.440 2015/01/26 06:10:03 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -836,7 +836,7 @@ list_hostkey_types(void)
 }
 
 static Key *
-get_hostkey_by_type(int type, int need_private, struct ssh *ssh)
+get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
 {
 	int i;
 	Key *key;
@@ -857,7 +857,8 @@ get_hostkey_by_type(int type, int need_private, struct ssh *ssh)
 				key = sensitive_data.host_pubkeys[i];
 			break;
 		}
-		if (key != NULL && key->type == type)
+		if (key != NULL && key->type == type &&
+		    (key->type != KEY_ECDSA || key->ecdsa_nid == nid))
 			return need_private ?
 			    sensitive_data.host_keys[i] : key;
 	}
@@ -865,15 +866,15 @@ get_hostkey_by_type(int type, int need_private, struct ssh *ssh)
 }
 
 Key *
-get_hostkey_public_by_type(int type, struct ssh *ssh)
+get_hostkey_public_by_type(int type, int nid, struct ssh *ssh)
 {
-	return get_hostkey_by_type(type, 0, ssh);
+	return get_hostkey_by_type(type, nid, 0, ssh);
 }
 
 Key *
-get_hostkey_private_by_type(int type, struct ssh *ssh)
+get_hostkey_private_by_type(int type, int nid, struct ssh *ssh)
 {
-	return get_hostkey_by_type(type, 1, ssh);
+	return get_hostkey_by_type(type, nid, 1, ssh);
 }
 
 Key *

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list