summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/ssh/compat.c12
-rw-r--r--usr.bin/ssh/compat.h3
-rw-r--r--usr.bin/ssh/dh.c19
-rw-r--r--usr.bin/ssh/dh.h7
-rw-r--r--usr.bin/ssh/ssh2.h5
-rw-r--r--usr.bin/ssh/sshconnect2.c35
-rw-r--r--usr.bin/ssh/sshd.c34
-rw-r--r--usr.bin/ssh/version.h4
8 files changed, 91 insertions, 28 deletions
diff --git a/usr.bin/ssh/compat.c b/usr.bin/ssh/compat.c
index f5fbb3305a6..c5400a48db4 100644
--- a/usr.bin/ssh/compat.c
+++ b/usr.bin/ssh/compat.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: compat.c,v 1.41 2001/03/27 10:57:00 markus Exp $");
+RCSID("$OpenBSD: compat.c,v 1.42 2001/03/27 17:46:49 provos Exp $");
#include <regex.h>
@@ -60,10 +60,14 @@ compat_datafellows(const char *version)
int bugs;
} check[] = {
{ "^OpenSSH[-_]2\\.[012]",
- SSH_OLD_SESSIONID|SSH_BUG_BANNER },
- { "^OpenSSH_2\\.3\\.0", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES },
+ SSH_OLD_SESSIONID|SSH_BUG_BANNER|
+ SSH_OLD_DHGEX },
+ { "^OpenSSH_2\\.3\\.0", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES|
+ SSH_OLD_DHGEX},
{ "^OpenSSH_2\\.5\\.[01]p1",
- SSH_BUG_BIGENDIANAES },
+ SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX },
+ { "^OpenSSH_2\\.5\\.[012]",
+ SSH_OLD_DHGEX },
{ "^OpenSSH", 0 },
{ "MindTerm", 0 },
{ "^2\\.1\\.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
diff --git a/usr.bin/ssh/compat.h b/usr.bin/ssh/compat.h
index 03f236117f3..e4ca5c1bc7a 100644
--- a/usr.bin/ssh/compat.h
+++ b/usr.bin/ssh/compat.h
@@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* RCSID("$OpenBSD: compat.h,v 1.20 2001/03/27 10:57:00 markus Exp $"); */
+/* RCSID("$OpenBSD: compat.h,v 1.21 2001/03/27 17:46:49 provos Exp $"); */
#ifndef COMPAT_H
#define COMPAT_H
@@ -45,6 +45,7 @@
#define SSH_BUG_SCANNER 0x0800
#define SSH_BUG_BIGENDIANAES 0x1000
#define SSH_BUG_RSASIGMD5 0x2000
+#define SSH_OLD_DHGEX 0x4000
void enable_compat13(void);
void enable_compat20(void);
diff --git a/usr.bin/ssh/dh.c b/usr.bin/ssh/dh.c
index ac73f8400d5..5f441ee1c81 100644
--- a/usr.bin/ssh/dh.c
+++ b/usr.bin/ssh/dh.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: dh.c,v 1.8 2001/03/05 17:58:22 stevesk Exp $");
+RCSID("$OpenBSD: dh.c,v 1.9 2001/03/27 17:46:49 provos Exp $");
#include "xmalloc.h"
@@ -69,6 +69,8 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
if (cp == NULL || *strsize == '\0' ||
(dhg->size = atoi(strsize)) == 0)
goto fail;
+ /* The whole group is one bit larger */
+ dhg->size++;
gen = strsep(&cp, " "); /* gen */
if (cp == NULL || *gen == '\0')
goto fail;
@@ -95,7 +97,7 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
}
DH *
-choose_dh(int minbits)
+choose_dh(int min, int wantbits, int max)
{
FILE *f;
char line[1024];
@@ -118,8 +120,11 @@ choose_dh(int minbits)
BN_free(dhg.g);
BN_free(dhg.p);
- if ((dhg.size > minbits && dhg.size < best) ||
- (dhg.size > best && best < minbits)) {
+ if (dhg.size > max || dhg.size < min)
+ continue;
+
+ if ((dhg.size > wantbits && dhg.size < best) ||
+ (dhg.size > best && best < wantbits)) {
best = dhg.size;
bestcount = 0;
}
@@ -129,8 +134,8 @@ choose_dh(int minbits)
fclose (f);
if (bestcount == 0) {
- log("WARNING: no primes in %s, using old prime", _PATH_DH_PRIMES);
- return (dh_new_group1());
+ log("WARNING: no suitable primes in %s", _PATH_DH_PRIMES);
+ return (NULL);
}
f = fopen(_PATH_DH_PRIMES, "r");
@@ -143,6 +148,8 @@ choose_dh(int minbits)
while (fgets(line, sizeof(line), f)) {
if (!parse_prime(linenum, line, &dhg))
continue;
+ if (dhg.size > max || dhg.size < min)
+ continue;
if (dhg.size != best)
continue;
if (linenum++ != which) {
diff --git a/usr.bin/ssh/dh.h b/usr.bin/ssh/dh.h
index f08d70e3f06..70b326e9fa7 100644
--- a/usr.bin/ssh/dh.h
+++ b/usr.bin/ssh/dh.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dh.h,v 1.2 2001/01/29 01:58:15 niklas Exp $ */
+/* $OpenBSD: dh.h,v 1.3 2001/03/27 17:46:49 provos Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
@@ -32,6 +32,9 @@ struct dhgroup {
BIGNUM *p;
};
-DH *choose_dh(int minbits);
+DH *choose_dh(int min, int nbits, int max);
+
+#define DH_GRP_MIN 1024
+#define DH_GRP_MAX 8192
#endif
diff --git a/usr.bin/ssh/ssh2.h b/usr.bin/ssh/ssh2.h
index fe0146cbdb9..e45aef275fe 100644
--- a/usr.bin/ssh/ssh2.h
+++ b/usr.bin/ssh/ssh2.h
@@ -52,7 +52,7 @@
*
* 192-255 Local extensions
*/
-/* RCSID("$OpenBSD: ssh2.h,v 1.5 2000/10/11 04:02:17 provos Exp $"); */
+/* RCSID("$OpenBSD: ssh2.h,v 1.6 2001/03/27 17:46:49 provos Exp $"); */
/* transport layer: generic */
@@ -74,10 +74,11 @@
#define SSH2_MSG_KEXDH_REPLY 31
/* dh-group-exchange */
-#define SSH2_MSG_KEX_DH_GEX_REQUEST 30
+#define SSH2_MSG_KEX_DH_GEX_REQUEST_OLD 30
#define SSH2_MSG_KEX_DH_GEX_GROUP 31
#define SSH2_MSG_KEX_DH_GEX_INIT 32
#define SSH2_MSG_KEX_DH_GEX_REPLY 33
+#define SSH2_MSG_KEX_DH_GEX_REQUEST 34
/* user authentication: generic */
diff --git a/usr.bin/ssh/sshconnect2.c b/usr.bin/ssh/sshconnect2.c
index f636fb3d92f..da8c8229ca0 100644
--- a/usr.bin/ssh/sshconnect2.c
+++ b/usr.bin/ssh/sshconnect2.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.56 2001/03/26 08:07:09 markus Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.57 2001/03/27 17:46:49 provos Exp $");
#include <openssl/bn.h>
#include <openssl/md5.h>
@@ -46,6 +46,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.56 2001/03/26 08:07:09 markus Exp $");
#include "sshconnect.h"
#include "authfile.h"
#include "cli.h"
+#include "dh.h"
#include "dispatch.h"
#include "authfd.h"
#include "log.h"
@@ -309,7 +310,7 @@ ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
int plen, dlen;
u_int klen, kout;
char *signature = NULL;
- u_int slen, nbits;
+ u_int slen, nbits, min, max;
char *server_host_key_blob = NULL;
Key *server_host_key;
u_int sbloblen;
@@ -322,14 +323,31 @@ ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
nbits = dh_estimate(kex->we_need * 8);
- debug("Sending SSH2_MSG_KEX_DH_GEX_REQUEST.");
- packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST);
- packet_put_int(nbits);
+ if (datafellows & SSH_OLD_DHGEX) {
+ debug("Sending SSH2_MSG_KEX_DH_GEX_REQUEST_OLD.");
+
+ /* Old GEX request */
+ packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD);
+ packet_put_int(nbits);
+ min = DH_GRP_MIN;
+ max = DH_GRP_MAX;
+ } else {
+ debug("Sending SSH2_MSG_KEX_DH_GEX_REQUEST.");
+
+ /* New GEX request */
+ min = DH_GRP_MIN;
+ max = MIN(DH_GRP_MAX, nbits * 1.25);
+
+ packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST);
+ packet_put_int(min);
+ packet_put_int(nbits);
+ packet_put_int(max);
+ }
packet_send();
packet_write_wait();
#ifdef DEBUG_KEXDH
- fprintf(stderr, "\nnbits = %d", nbits);
+ fprintf(stderr, "\nmin = %d, nbits = %d, max = %d", min, nbits, max);
#endif
debug("Wait SSH2_MSG_KEX_DH_GEX_GROUP.");
@@ -344,6 +362,11 @@ ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
if ((g = BN_new()) == NULL)
fatal("BN_new");
packet_get_bignum2(g, &dlen);
+
+ if (BN_num_bits(p) < min || BN_num_bits(p) > max)
+ fatal("DH_GEX group out of range: %d !< %d !< %d",
+ min, BN_num_bits(p), max);
+
dh = dh_new_group(g, p);
dh_gen_key(dh, kex->we_need * 8);
diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c
index 7714cc76054..8317371c203 100644
--- a/usr.bin/ssh/sshd.c
+++ b/usr.bin/ssh/sshd.c
@@ -40,7 +40,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.180 2001/03/27 10:34:08 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.181 2001/03/27 17:46:49 provos Exp $");
#include <openssl/dh.h>
#include <openssl/bn.h>
@@ -1588,7 +1588,7 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
int i;
#endif
int payload_len, dlen;
- int slen, nbits;
+ int slen, nbits, type, min, max;
u_char *signature = NULL;
u_char *server_host_key_blob = NULL;
u_int sbloblen;
@@ -1606,9 +1606,33 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
/* KEXDHGEX */
debug("Wait SSH2_MSG_KEX_DH_GEX_REQUEST.");
- packet_read_expect(&payload_len, SSH2_MSG_KEX_DH_GEX_REQUEST);
- nbits = packet_get_int();
- dh = choose_dh(nbits);
+ type = packet_read(&payload_len);
+ if (type != SSH2_MSG_KEX_DH_GEX_REQUEST_OLD &&
+ type != SSH2_MSG_KEX_DH_GEX_REQUEST)
+ packet_disconnect("Protocol error: expected type %d or %d, got %d",
+ SSH2_MSG_KEX_DH_GEX_REQUEST_OLD,
+ SSH2_MSG_KEX_DH_GEX_REQUEST,
+ type);
+ if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) {
+ nbits = packet_get_int();
+ min = DH_GRP_MIN;
+ max = DH_GRP_MAX;
+ } else {
+ min = packet_get_int();
+ nbits = packet_get_int();
+ max = packet_get_int();
+
+ min = MAX(DH_GRP_MIN, min);
+ max = MIN(DH_GRP_MAX, max);
+ }
+
+ if (max < min || nbits < min || max < nbits)
+ fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
+ min, nbits, max);
+
+ dh = choose_dh(min, nbits, max);
+ if (dh == NULL)
+ packet_disconnect("Protocol error: no matching DH grp found");
debug("Sending SSH2_MSG_KEX_DH_GEX_GROUP.");
packet_start(SSH2_MSG_KEX_DH_GEX_GROUP);
diff --git a/usr.bin/ssh/version.h b/usr.bin/ssh/version.h
index 0061c5f8024..845b320b89f 100644
--- a/usr.bin/ssh/version.h
+++ b/usr.bin/ssh/version.h
@@ -1,3 +1,3 @@
-/* $OpenBSD: version.h,v 1.20 2001/03/19 17:12:10 markus Exp $ */
+/* $OpenBSD: version.h,v 1.21 2001/03/27 17:46:50 provos Exp $ */
-#define SSH_VERSION "OpenSSH_2.5.2"
+#define SSH_VERSION "OpenSSH_2.5.3"