summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2014-04-20 13:44:47 +1000
committerDamien Miller <djm@mindrot.org>2014-04-20 13:44:47 +1000
commit5618210618256bbf5f4f71b2887ff186fd451736 (patch)
tree386f67c5cf63d521c18cb00120de0a3362a0808e
parentee70014dc13600b9c85719818eb8e4583689b622 (diff)
- (djm) [bufaux.c compat.c compat.h sshconnect2.c sshd.c version.h]
OpenSSH 6.5 and 6.6 sometimes encode a value used in the curve25519 key exchange incorrectly, causing connection failures about 0.2% of the time when this method is used against a peer that implements the method properly. Fix the problem and disable the curve25519 KEX when speaking to OpenSSH 6.5 or 6.6. This version will identify itself as 6.6.1 to enable the compatability code.
-rw-r--r--ChangeLog11
-rw-r--r--bufaux.c5
-rw-r--r--compat.c17
-rw-r--r--compat.h2
-rw-r--r--sshconnect2.c2
-rw-r--r--sshd.c3
-rw-r--r--version.h2
7 files changed, 39 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 9c59cc43..60f181a6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+20140420
+ - (djm) [bufaux.c compat.c compat.h sshconnect2.c sshd.c version.h]
+ OpenSSH 6.5 and 6.6 sometimes encode a value used in the curve25519
+ key exchange incorrectly, causing connection failures about 0.2% of
+ the time when this method is used against a peer that implements
+ the method properly.
+
+ Fix the problem and disable the curve25519 KEX when speaking to
+ OpenSSH 6.5 or 6.6. This version will identify itself as 6.6.1
+ to enable the compatability code.
+
20140313
- (djm) Release OpenSSH 6.6
diff --git a/bufaux.c b/bufaux.c
index e24b5fc0..f6a6f2ab 100644
--- a/bufaux.c
+++ b/bufaux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bufaux.c,v 1.56 2014/02/02 03:44:31 djm Exp $ */
+/* $OpenBSD: bufaux.c,v 1.57 2014/04/16 23:22:45 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -372,6 +372,9 @@ buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l)
if (l > 8 * 1024)
fatal("%s: length %u too long", __func__, l);
+ /* Skip leading zero bytes */
+ for (; l > 0 && *s == 0; l--, s++)
+ ;
p = buf = xmalloc(l + 1);
/*
* If most significant bit is set then prepend a zero byte to
diff --git a/compat.c b/compat.c
index 9d9fabef..2709dc5c 100644
--- a/compat.c
+++ b/compat.c
@@ -95,6 +95,9 @@ compat_datafellows(const char *version)
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
{ "OpenSSH_4*", 0 },
{ "OpenSSH_5*", SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT},
+ { "OpenSSH_6.6.1*", SSH_NEW_OPENSSH},
+ { "OpenSSH_6.5*,"
+ "OpenSSH_6.6*", SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD},
{ "OpenSSH*", SSH_NEW_OPENSSH },
{ "*MindTerm*", 0 },
{ "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
@@ -251,7 +254,6 @@ compat_cipher_proposal(char *cipher_prop)
return cipher_prop;
}
-
char *
compat_pkalg_proposal(char *pkalg_prop)
{
@@ -265,3 +267,16 @@ compat_pkalg_proposal(char *pkalg_prop)
return pkalg_prop;
}
+char *
+compat_kex_proposal(char *kex_prop)
+{
+ if (!(datafellows & SSH_BUG_CURVE25519PAD))
+ return kex_prop;
+ debug2("%s: original KEX proposal: %s", __func__, kex_prop);
+ kex_prop = filter_proposal(kex_prop, "curve25519-sha256@libssh.org");
+ debug2("%s: compat KEX proposal: %s", __func__, kex_prop);
+ if (*kex_prop == '\0')
+ fatal("No supported key exchange algorithms found");
+ return kex_prop;
+}
+
diff --git a/compat.h b/compat.h
index b174fa17..a6c3f3d7 100644
--- a/compat.h
+++ b/compat.h
@@ -59,6 +59,7 @@
#define SSH_BUG_RFWD_ADDR 0x02000000
#define SSH_NEW_OPENSSH 0x04000000
#define SSH_BUG_DYNAMIC_RPORT 0x08000000
+#define SSH_BUG_CURVE25519PAD 0x10000000
void enable_compat13(void);
void enable_compat20(void);
@@ -66,6 +67,7 @@ void compat_datafellows(const char *);
int proto_spec(const char *);
char *compat_cipher_proposal(char *);
char *compat_pkalg_proposal(char *);
+char *compat_kex_proposal(char *);
extern int compat13;
extern int compat20;
diff --git a/sshconnect2.c b/sshconnect2.c
index 7f4ff418..ec3ad6a5 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -195,6 +195,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
}
if (options.kex_algorithms != NULL)
myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
+ myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(
+ myproposal[PROPOSAL_KEX_ALGS]);
if (options.rekey_limit || options.rekey_interval)
packet_set_rekey_limits((u_int32_t)options.rekey_limit,
diff --git a/sshd.c b/sshd.c
index 7523de97..e9084b72 100644
--- a/sshd.c
+++ b/sshd.c
@@ -2462,6 +2462,9 @@ do_ssh2_kex(void)
if (options.kex_algorithms != NULL)
myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
+ myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(
+ myproposal[PROPOSAL_KEX_ALGS]);
+
if (options.rekey_limit || options.rekey_interval)
packet_set_rekey_limits((u_int32_t)options.rekey_limit,
(time_t)options.rekey_interval);
diff --git a/version.h b/version.h
index a1579ace..a33e77c9 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
/* $OpenBSD: version.h,v 1.70 2014/02/27 22:57:40 djm Exp $ */
-#define SSH_VERSION "OpenSSH_6.6"
+#define SSH_VERSION "OpenSSH_6.6.1"
#define SSH_PORTABLE "p1"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE