зеркало из https://github.com/Azure/sonic-openssh.git
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@
This commit is contained in:
Родитель
8d4f87258f
Коммит
5104db7cbd
6
auth.h
6
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);
|
||||
|
|
3
kex.c
3
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;
|
||||
}
|
||||
|
|
7
kex.h
7
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
6
kexdhc.c
6
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;
|
||||
}
|
||||
|
|
8
kexdhs.c
8
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
16
ssh_api.c
16
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);
|
||||
|
|
|
@ -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@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@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",
|
||||
|
|
15
sshd.c
15
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@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@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 *
|
||||
|
|
Загрузка…
Ссылка в новой задаче