summaryrefslogtreecommitdiff
path: root/usr.bin/ssh
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2000-04-12 07:03:07 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2000-04-12 07:03:07 +0000
commit3f6547314a456d02e3306664e55213db57f93a14 (patch)
treeb34510294f7588b64651fe5b068096dcbfff738d /usr.bin/ssh
parent4cba919149b8a5f18774f2399edd94a9062ca307 (diff)
check for reasonable public DH values
Diffstat (limited to 'usr.bin/ssh')
-rw-r--r--usr.bin/ssh/kex.c46
-rw-r--r--usr.bin/ssh/kex.h3
-rw-r--r--usr.bin/ssh/sshconnect.c7
-rw-r--r--usr.bin/ssh/sshd.c6
4 files changed, 50 insertions, 12 deletions
diff --git a/usr.bin/ssh/kex.c b/usr.bin/ssh/kex.c
index cc2543a0ea1..2308c9398f5 100644
--- a/usr.bin/ssh/kex.c
+++ b/usr.bin/ssh/kex.c
@@ -28,7 +28,7 @@
*/
#include "includes.h"
-RCSID("$Id: kex.c,v 1.2 2000/04/12 06:37:02 markus Exp $");
+RCSID("$Id: kex.c,v 1.3 2000/04/12 07:03:05 markus Exp $");
#include "ssh.h"
#include "ssh2.h"
@@ -74,8 +74,36 @@ kex_init(char *myproposal[PROPOSAL_MAX])
/* diffie-hellman-group1-sha1 */
+int
+dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
+{
+ int i;
+ int n = BN_num_bits(dh_pub);
+ int bits_set = 0;
+
+ /* we only accept g==2 */
+ if (!BN_is_word(dh->g, 2)) {
+ log("invalid DH base != 2");
+ return 0;
+ }
+ if (dh_pub->neg) {
+ log("invalid public DH value: negativ");
+ return 0;
+ }
+ for (i = 0; i <= n; i++)
+ if (BN_is_bit_set(dh_pub, i))
+ bits_set++;
+ debug("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
+
+ /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
+ if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1))
+ return 1;
+ log("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p));
+ return 0;
+}
+
DH *
-new_dh_group1()
+dh_new_group1()
{
static char *group1 =
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
@@ -85,19 +113,23 @@ new_dh_group1()
"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
"FFFFFFFF" "FFFFFFFF";
DH *dh;
- int ret;
+ int ret, tries = 0;
dh = DH_new();
if(dh == NULL)
fatal("DH_new");
- ret = BN_hex2bn(&dh->p,group1);
+ ret = BN_hex2bn(&dh->p, group1);
if(ret<0)
fatal("BN_hex2bn");
dh->g = BN_new();
if(dh->g == NULL)
fatal("DH_new g");
- BN_set_word(dh->g,2);
- if (DH_generate_key(dh) == 0)
- fatal("DH_generate_key");
+ BN_set_word(dh->g, 2);
+ do {
+ if (DH_generate_key(dh) == 0)
+ fatal("DH_generate_key");
+ if (tries++ > 10)
+ fatal("dh_new_group1: too many bad keys: giving up");
+ } while (!dh_pub_is_valid(dh, dh->pub_key));
return dh;
}
diff --git a/usr.bin/ssh/kex.h b/usr.bin/ssh/kex.h
index f9e79994888..5395ebc3f08 100644
--- a/usr.bin/ssh/kex.h
+++ b/usr.bin/ssh/kex.h
@@ -91,7 +91,8 @@ struct Kex {
};
Buffer *kex_init(char *myproposal[PROPOSAL_MAX]);
-DH *new_dh_group1();
+int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
+DH *dh_new_group1();
Kex *kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server);
int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret);
void bignum_print(BIGNUM *b);
diff --git a/usr.bin/ssh/sshconnect.c b/usr.bin/ssh/sshconnect.c
index 3391c33b640..e8b4f16b9ac 100644
--- a/usr.bin/ssh/sshconnect.c
+++ b/usr.bin/ssh/sshconnect.c
@@ -10,7 +10,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.62 2000/04/12 06:36:48 markus Exp $");
+RCSID("$OpenBSD: sshconnect.c,v 1.63 2000/04/12 07:03:06 markus Exp $");
#include <ssl/bn.h>
#include "xmalloc.h"
@@ -1393,7 +1393,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
debug("Sending SSH2_MSG_KEXDH_INIT.");
/* generate and send 'e', client DH public key */
- dh = new_dh_group1();
+ dh = dh_new_group1();
packet_start(SSH2_MSG_KEXDH_INIT);
packet_put_bignum2(dh->pub_key);
packet_send();
@@ -1440,6 +1440,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
/* signed H */
signature = packet_get_string(&slen);
+ if (!dh_pub_is_valid(dh, dh_server_pub))
+ packet_disconnect("bad server public DH value");
+
klen = DH_size(dh);
kbuf = xmalloc(klen);
kout = DH_compute_key(kbuf, dh_server_pub, dh);
diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c
index 7d8963ffa22..088da20c550 100644
--- a/usr.bin/ssh/sshd.c
+++ b/usr.bin/ssh/sshd.c
@@ -14,7 +14,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.100 2000/04/12 06:37:02 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.101 2000/04/12 07:03:06 markus Exp $");
#include "xmalloc.h"
#include "rsa.h"
@@ -1166,7 +1166,7 @@ do_ssh2_kex()
#endif
/* generate DH key */
- dh = new_dh_group1(); /* XXX depends on 'kex' */
+ dh = dh_new_group1(); /* XXX depends on 'kex' */
#ifdef DEBUG_KEXDH
fprintf(stderr, "\np= ");
@@ -1177,6 +1177,8 @@ do_ssh2_kex()
bignum_print(dh->pub_key);
fprintf(stderr, "\n");
#endif
+ if (!dh_pub_is_valid(dh, dh_client_pub))
+ packet_disconnect("bad client public DH value");
klen = DH_size(dh);
kbuf = xmalloc(klen);