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@
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_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 @@
 }
 
 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);