summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordjm <djm@openbsd.org>2010-09-22 05:01:29 +0000
committerdjm <djm@openbsd.org>2010-09-22 05:01:29 +0000
commitfcae0388a3a8b1dc7667b3ad6cefa8b2508c2712 (patch)
tree793819f9ad2fd310ebe078ebb8d5f3af76e62b0b
parentFix a locking bug in accept(2) caught by sthen@ using my strict (diff)
downloadwireguard-openbsd-fcae0388a3a8b1dc7667b3ad6cefa8b2508c2712.tar.xz
wireguard-openbsd-fcae0388a3a8b1dc7667b3ad6cefa8b2508c2712.zip
add a KexAlgorithms knob to the client and server configuration to allow
selection of which key exchange methods are used by ssh(1) and sshd(8) and their order of preference. ok markus@
-rw-r--r--usr.bin/ssh/kex.c30
-rw-r--r--usr.bin/ssh/kex.h4
-rw-r--r--usr.bin/ssh/kexecdh.c12
-rw-r--r--usr.bin/ssh/kexecdhc.c5
-rw-r--r--usr.bin/ssh/kexecdhs.c5
-rw-r--r--usr.bin/ssh/readconf.c18
-rw-r--r--usr.bin/ssh/readconf.h3
-rw-r--r--usr.bin/ssh/servconf.c17
-rw-r--r--usr.bin/ssh/servconf.h3
-rw-r--r--usr.bin/ssh/ssh_config.515
-rw-r--r--usr.bin/ssh/sshconnect2.c4
-rw-r--r--usr.bin/ssh/sshd.c4
-rw-r--r--usr.bin/ssh/sshd_config.515
13 files changed, 111 insertions, 24 deletions
diff --git a/usr.bin/ssh/kex.c b/usr.bin/ssh/kex.c
index 5ab764083d0..2c04c5899b4 100644
--- a/usr.bin/ssh/kex.c
+++ b/usr.bin/ssh/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.85 2010/09/09 10:45:45 djm Exp $ */
+/* $OpenBSD: kex.c,v 1.86 2010/09/22 05:01:29 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@@ -51,6 +51,34 @@
static void kex_kexinit_finish(Kex *);
static void kex_choose_conf(Kex *);
+/* Validate KEX method name list */
+int
+kex_names_valid(const char *names)
+{
+ char *s, *cp, *p;
+
+ if (names == NULL || strcmp(names, "") == 0)
+ return 0;
+ s = cp = xstrdup(names);
+ for ((p = strsep(&cp, ",")); p && *p != '\0';
+ (p = strsep(&cp, ","))) {
+ if (strcmp(p, KEX_DHGEX_SHA256) != 0 &&
+ strcmp(p, KEX_DHGEX_SHA1) != 0 &&
+ strcmp(p, KEX_DH14) != 0 &&
+ strcmp(p, KEX_DH1) != 0 &&
+ (strncmp(p, KEX_ECDH_SHA2_STEM,
+ sizeof(KEX_ECDH_SHA2_STEM) - 1) != 0 ||
+ kex_ecdh_name_to_nid(p) == -1)) {
+ error("Unsupported KEX algorithm \"%.100s\"", p);
+ xfree(s);
+ return 0;
+ }
+ }
+ debug3("kex names ok: [%s]", names);
+ xfree(s);
+ return 1;
+}
+
/* put algorithm proposal into buffer */
static void
kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
diff --git a/usr.bin/ssh/kex.h b/usr.bin/ssh/kex.h
index 339c56bd99c..0279d0dd0dc 100644
--- a/usr.bin/ssh/kex.h
+++ b/usr.bin/ssh/kex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.51 2010/09/09 10:45:45 djm Exp $ */
+/* $OpenBSD: kex.h,v 1.52 2010/09/22 05:01:29 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -135,6 +135,8 @@ struct Kex {
void (*kex[KEX_MAX])(Kex *);
};
+int kex_names_valid(const char *);
+
Kex *kex_setup(char *[PROPOSAL_MAX]);
void kex_finish(Kex *);
diff --git a/usr.bin/ssh/kexecdh.c b/usr.bin/ssh/kexecdh.c
index 2e31b86cd52..7c1cb3e76f1 100644
--- a/usr.bin/ssh/kexecdh.c
+++ b/usr.bin/ssh/kexecdh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexecdh.c,v 1.2 2010/09/09 10:45:45 djm Exp $ */
+/* $OpenBSD: kexecdh.c,v 1.3 2010/09/22 05:01:29 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -44,15 +44,9 @@
int
kex_ecdh_name_to_nid(const char *kexname)
{
- int ret;
-
if (strlen(kexname) < sizeof(KEX_ECDH_SHA2_STEM) - 1)
fatal("%s: kexname too short \"%s\"", __func__, kexname);
- ret = key_curve_name_to_nid(kexname + sizeof(KEX_ECDH_SHA2_STEM) - 1);
- if (ret == -1)
- fatal("%s: unsupported curve negotiated \"%s\"", __func__,
- kexname);
- return ret;
+ return key_curve_name_to_nid(kexname + sizeof(KEX_ECDH_SHA2_STEM) - 1);
}
const EVP_MD *
@@ -60,6 +54,8 @@ kex_ecdh_name_to_evpmd(const char *kexname)
{
int nid = kex_ecdh_name_to_nid(kexname);
+ if (nid == -1)
+ fatal("%s: unsupported ECDH curve \"%s\"", __func__, kexname);
return key_ec_nid_to_evpmd(nid);
}
diff --git a/usr.bin/ssh/kexecdhc.c b/usr.bin/ssh/kexecdhc.c
index f6d9977c58c..218768ba8ad 100644
--- a/usr.bin/ssh/kexecdhc.c
+++ b/usr.bin/ssh/kexecdhc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexecdhc.c,v 1.1 2010/08/31 11:54:45 djm Exp $ */
+/* $OpenBSD: kexecdhc.c,v 1.2 2010/09/22 05:01:29 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -55,7 +55,8 @@ kexecdh_client(Kex *kex)
u_int klen, slen, sbloblen, hashlen;
int curve_nid;
- curve_nid = kex_ecdh_name_to_nid(kex->name);
+ if ((curve_nid = kex_ecdh_name_to_nid(kex->name)) == -1)
+ fatal("%s: unsupported ECDH curve \"%s\"", __func__, kex->name);
if ((client_key = EC_KEY_new_by_curve_name(curve_nid)) == NULL)
fatal("%s: EC_KEY_new_by_curve_name failed", __func__);
if (EC_KEY_generate_key(client_key) != 1)
diff --git a/usr.bin/ssh/kexecdhs.c b/usr.bin/ssh/kexecdhs.c
index d7333389301..1dee1722d9b 100644
--- a/usr.bin/ssh/kexecdhs.c
+++ b/usr.bin/ssh/kexecdhs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexecdhs.c,v 1.1 2010/08/31 11:54:45 djm Exp $ */
+/* $OpenBSD: kexecdhs.c,v 1.2 2010/09/22 05:01:29 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -57,7 +57,8 @@ kexecdh_server(Kex *kex)
u_int klen, slen, sbloblen, hashlen;
int curve_nid;
- curve_nid = kex_ecdh_name_to_nid(kex->name);
+ if ((curve_nid = kex_ecdh_name_to_nid(kex->name)) == -1)
+ fatal("%s: unsupported ECDH curve \"%s\"", __func__, kex->name);
if ((server_key = EC_KEY_new_by_curve_name(curve_nid)) == NULL)
fatal("%s: EC_KEY_new_by_curve_name failed", __func__);
if (EC_KEY_generate_key(server_key) != 1)
diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c
index 9a8b184b399..ee9e17d5e2a 100644
--- a/usr.bin/ssh/readconf.c
+++ b/usr.bin/ssh/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.188 2010/08/31 11:54:45 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.189 2010/09/22 05:01:29 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -129,6 +129,7 @@ typedef enum {
oHashKnownHosts,
oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
+ oKexAlgorithms,
oDeprecated, oUnsupported
} OpCodes;
@@ -237,6 +238,7 @@ static struct {
#else
{ "zeroknowledgepasswordauthentication", oUnsupported },
#endif
+ { "kexalgorithms", oKexAlgorithms },
{ NULL, oBadOption }
};
@@ -695,6 +697,18 @@ parse_int:
options->macs = xstrdup(arg);
break;
+ case oKexAlgorithms:
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing argument.",
+ filename, linenum);
+ if (!kex_names_valid(arg))
+ fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
+ filename, linenum, arg ? arg : "<NONE>");
+ if (*activep && options->kex_algorithms == NULL)
+ options->kex_algorithms = xstrdup(arg);
+ break;
+
case oHostKeyAlgorithms:
arg = strdelim(&s);
if (!arg || *arg == '\0')
@@ -1074,6 +1088,7 @@ initialize_options(Options * options)
options->cipher = -1;
options->ciphers = NULL;
options->macs = NULL;
+ options->kex_algorithms = NULL;
options->hostkeyalgorithms = NULL;
options->protocol = SSH_PROTO_UNKNOWN;
options->num_identity_files = 0;
@@ -1187,6 +1202,7 @@ fill_default_options(Options * options)
options->cipher = SSH_CIPHER_NOT_SET;
/* options->ciphers, default set in myproposals.h */
/* options->macs, default set in myproposals.h */
+ /* options->kex_algorithms, default set in myproposals.h */
/* options->hostkeyalgorithms, default set in myproposals.h */
if (options->protocol == SSH_PROTO_UNKNOWN)
options->protocol = SSH_PROTO_2;
diff --git a/usr.bin/ssh/readconf.h b/usr.bin/ssh/readconf.h
index 95d10467472..ae61466df2f 100644
--- a/usr.bin/ssh/readconf.h
+++ b/usr.bin/ssh/readconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.86 2010/07/19 09:15:12 djm Exp $ */
+/* $OpenBSD: readconf.h,v 1.87 2010/09/22 05:01:29 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -73,6 +73,7 @@ typedef struct {
char *ciphers; /* SSH2 ciphers in order of preference. */
char *macs; /* SSH2 macs in order of preference. */
char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */
+ char *kex_algorithms; /* SSH2 kex methods in order of preference. */
int protocol; /* Protocol in order of preference. */
char *hostname; /* Real host to connect. */
char *host_key_alias; /* hostname alias for .ssh/known_hosts */
diff --git a/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c
index 7ff40ba5822..3a6f8eae9b1 100644
--- a/usr.bin/ssh/servconf.c
+++ b/usr.bin/ssh/servconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.c,v 1.210 2010/09/01 15:21:35 naddy Exp $ */
+/* $OpenBSD: servconf.c,v 1.211 2010/09/22 05:01:29 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -102,6 +102,7 @@ initialize_server_options(ServerOptions *options)
options->num_deny_groups = 0;
options->ciphers = NULL;
options->macs = NULL;
+ options->kex_algorithms = NULL;
options->protocol = SSH_PROTO_UNKNOWN;
options->gateway_ports = -1;
options->num_subsystems = 0;
@@ -289,6 +290,7 @@ typedef enum {
sUsePrivilegeSeparation, sAllowAgentForwarding,
sZeroKnowledgePasswordAuthentication, sHostCertificate,
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
+ sKexAlgorithms,
sDeprecated, sUnsupported
} ServerOpCodes;
@@ -399,6 +401,7 @@ static struct {
{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
+ { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
{ NULL, sBadOption, 0 }
};
@@ -1088,6 +1091,18 @@ process_server_config_line(ServerOptions *options, char *line,
options->macs = xstrdup(arg);
break;
+ case sKexAlgorithms:
+ arg = strdelim(&cp);
+ if (!arg || *arg == '\0')
+ fatal("%s line %d: Missing argument.",
+ filename, linenum);
+ if (!kex_names_valid(arg))
+ fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
+ filename, linenum, arg ? arg : "<NONE>");
+ if (options->kex_algorithms == NULL)
+ options->kex_algorithms = xstrdup(arg);
+ break;
+
case sProtocol:
intptr = &options->protocol;
arg = strdelim(&cp);
diff --git a/usr.bin/ssh/servconf.h b/usr.bin/ssh/servconf.h
index 4bb7f1f5db1..1bdccb12375 100644
--- a/usr.bin/ssh/servconf.h
+++ b/usr.bin/ssh/servconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.93 2010/05/07 11:30:30 djm Exp $ */
+/* $OpenBSD: servconf.h,v 1.94 2010/09/22 05:01:29 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -72,6 +72,7 @@ typedef struct {
int tcp_keep_alive; /* If true, set SO_KEEPALIVE. */
char *ciphers; /* Supported SSH2 ciphers. */
char *macs; /* Supported SSH2 macs. */
+ char *kex_algorithms; /* SSH2 kex methods in order of preference. */
int protocol; /* Supported protocol versions. */
int gateway_ports; /* If true, allow remote connects to forwarded ports. */
SyslogFacility log_facility; /* Facility for system logging. */
diff --git a/usr.bin/ssh/ssh_config.5 b/usr.bin/ssh/ssh_config.5
index 33038ffcf30..6e49842a7c7 100644
--- a/usr.bin/ssh/ssh_config.5
+++ b/usr.bin/ssh/ssh_config.5
@@ -34,8 +34,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: ssh_config.5,v 1.139 2010/08/31 11:54:45 djm Exp $
-.Dd $Mdocdate: August 31 2010 $
+.\" $OpenBSD: ssh_config.5,v 1.140 2010/09/22 05:01:29 djm Exp $
+.Dd $Mdocdate: September 22 2010 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@@ -646,6 +646,17 @@ it may be zero or more of:
.Dq pam ,
and
.Dq skey .
+.It Cm KexAlgorithms
+Specifies the available KEX (Key Exchange) algorithms.
+Multiple algorithms must be comma-separated.
+The default is
+.Dq ecdh-sha2-nistp256 ,
+.Dq ecdh-sha2-nistp384 ,
+.Dq ecdh-sha2-nistp521 ,
+.Dq diffie-hellman-group-exchange-sha256 ,
+.Dq diffie-hellman-group-exchange-sha1 ,
+.Dq diffie-hellman-group14-sha1 ,
+.Dq diffie-hellman-group1-sha1 .
.It Cm LocalCommand
Specifies a command to execute on the local machine after successfully
connecting to the server.
diff --git a/usr.bin/ssh/sshconnect2.c b/usr.bin/ssh/sshconnect2.c
index bfb97b3d9fb..8b7db3a17c6 100644
--- a/usr.bin/ssh/sshconnect2.c
+++ b/usr.bin/ssh/sshconnect2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.184 2010/08/31 11:54:45 djm Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.185 2010/09/22 05:01:29 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -129,6 +129,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
if (options.hostkeyalgorithms != NULL)
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
options.hostkeyalgorithms;
+ if (options.kex_algorithms != NULL)
+ myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
if (options.rekey_limit)
packet_set_rekey_limit((u_int32_t)options.rekey_limit);
diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c
index de9976ef669..2611e984922 100644
--- a/usr.bin/ssh/sshd.c
+++ b/usr.bin/ssh/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.379 2010/08/31 12:33:38 djm Exp $ */
+/* $OpenBSD: sshd.c,v 1.380 2010/09/22 05:01:29 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2153,6 +2153,8 @@ do_ssh2_kex(void)
myproposal[PROPOSAL_COMP_ALGS_CTOS] =
myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com";
}
+ if (options.kex_algorithms != NULL)
+ myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
diff --git a/usr.bin/ssh/sshd_config.5 b/usr.bin/ssh/sshd_config.5
index 6f0a3d5e908..3a06326c9ca 100644
--- a/usr.bin/ssh/sshd_config.5
+++ b/usr.bin/ssh/sshd_config.5
@@ -34,8 +34,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: sshd_config.5,v 1.126 2010/08/31 11:54:45 djm Exp $
-.Dd $Mdocdate: August 31 2010 $
+.\" $OpenBSD: sshd_config.5,v 1.127 2010/09/22 05:01:30 djm Exp $
+.Dd $Mdocdate: September 22 2010 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@@ -539,6 +539,17 @@ Specifies whether to automatically destroy the user's ticket cache
file on logout.
The default is
.Dq yes .
+.It Cm KexAlgorithms
+Specifies the available KEX (Key Exchange) algorithms.
+Multiple algorithms must be comma-separated.
+The default is
+.Dq ecdh-sha2-nistp256 ,
+.Dq ecdh-sha2-nistp384 ,
+.Dq ecdh-sha2-nistp521 ,
+.Dq diffie-hellman-group-exchange-sha256 ,
+.Dq diffie-hellman-group-exchange-sha1 ,
+.Dq diffie-hellman-group14-sha1 ,
+.Dq diffie-hellman-group1-sha1 .
.It Cm KeyRegenerationInterval
In protocol version 1, the ephemeral server key is automatically regenerated
after this many seconds (if it has been used).