mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 01:48:00 +00:00
Diffie-Hellman group exchange in SSH2. Currently #ifdeffed out
(change the sense of #ifdef DO_DIFFIE_HELLMAN_GEX in ssh.c) because it's _far_ too slow. Will be re-enabled once the bignum routines work a bit faster (or rather a _lot_ faster). [originally from svn r962]
This commit is contained in:
parent
862d6a496d
commit
cc9d7ba87e
88
ssh.c
88
ssh.c
@ -87,6 +87,10 @@
|
|||||||
#define SSH2_MSG_NEWKEYS 21 /* 0x15 */
|
#define SSH2_MSG_NEWKEYS 21 /* 0x15 */
|
||||||
#define SSH2_MSG_KEXDH_INIT 30 /* 0x1e */
|
#define SSH2_MSG_KEXDH_INIT 30 /* 0x1e */
|
||||||
#define SSH2_MSG_KEXDH_REPLY 31 /* 0x1f */
|
#define SSH2_MSG_KEXDH_REPLY 31 /* 0x1f */
|
||||||
|
#define SSH2_MSG_KEX_DH_GEX_REQUEST 30 /* 0x1e */
|
||||||
|
#define SSH2_MSG_KEX_DH_GEX_GROUP 31 /* 0x1f */
|
||||||
|
#define SSH2_MSG_KEX_DH_GEX_INIT 32 /* 0x20 */
|
||||||
|
#define SSH2_MSG_KEX_DH_GEX_REPLY 33 /* 0x21 */
|
||||||
#define SSH2_MSG_USERAUTH_REQUEST 50 /* 0x32 */
|
#define SSH2_MSG_USERAUTH_REQUEST 50 /* 0x32 */
|
||||||
#define SSH2_MSG_USERAUTH_FAILURE 51 /* 0x33 */
|
#define SSH2_MSG_USERAUTH_FAILURE 51 /* 0x33 */
|
||||||
#define SSH2_MSG_USERAUTH_SUCCESS 52 /* 0x34 */
|
#define SSH2_MSG_USERAUTH_SUCCESS 52 /* 0x34 */
|
||||||
@ -180,7 +184,12 @@ extern void x11_invent_auth(char *, int, char *, int);
|
|||||||
const static struct ssh_cipher *ciphers[] = { &ssh_blowfish_ssh2, &ssh_3des_ssh2 };
|
const static struct ssh_cipher *ciphers[] = { &ssh_blowfish_ssh2, &ssh_3des_ssh2 };
|
||||||
|
|
||||||
extern const struct ssh_kex ssh_diffiehellman;
|
extern const struct ssh_kex ssh_diffiehellman;
|
||||||
const static struct ssh_kex *kex_algs[] = { &ssh_diffiehellman };
|
extern const struct ssh_kex ssh_diffiehellman_gex;
|
||||||
|
const static struct ssh_kex *kex_algs[] = {
|
||||||
|
#ifdef DO_DIFFIE_HELLMAN_GEX
|
||||||
|
&ssh_diffiehellman_gex,
|
||||||
|
#endif
|
||||||
|
&ssh_diffiehellman };
|
||||||
|
|
||||||
extern const struct ssh_signkey ssh_dss;
|
extern const struct ssh_signkey ssh_dss;
|
||||||
const static struct ssh_signkey *hostkey_algs[] = { &ssh_dss };
|
const static struct ssh_signkey *hostkey_algs[] = { &ssh_dss };
|
||||||
@ -806,8 +815,8 @@ static int ssh_versioncmp(char *a, char *b) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility routine for putting an SSH-protocol `string' into a SHA
|
* Utility routines for putting an SSH-protocol `string' and
|
||||||
* state.
|
* `uint32' into a SHA state.
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
static void sha_string(SHA_State *s, void *str, int len) {
|
static void sha_string(SHA_State *s, void *str, int len) {
|
||||||
@ -817,6 +826,12 @@ static void sha_string(SHA_State *s, void *str, int len) {
|
|||||||
SHA_Bytes(s, str, len);
|
SHA_Bytes(s, str, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sha_uint32(SHA_State *s, unsigned i) {
|
||||||
|
unsigned char intblk[4];
|
||||||
|
PUT_32BIT(intblk, i);
|
||||||
|
SHA_Bytes(s, intblk, 4);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SSH2 packet construction functions.
|
* SSH2 packet construction functions.
|
||||||
*/
|
*/
|
||||||
@ -2157,9 +2172,10 @@ static void ssh2_mkkey(Bignum K, char *H, char *sessid, char chr, char *keyspace
|
|||||||
*/
|
*/
|
||||||
static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
||||||
{
|
{
|
||||||
static int i, len;
|
static int i, len, nbits;
|
||||||
static char *str;
|
static char *str;
|
||||||
static Bignum e, f, K;
|
static Bignum p, g, e, f, K;
|
||||||
|
static int kex_init_value, kex_reply_value;
|
||||||
static const struct ssh_mac **maclist;
|
static const struct ssh_mac **maclist;
|
||||||
static int nmacs;
|
static int nmacs;
|
||||||
static const struct ssh_cipher *cscipher_tobe = NULL;
|
static const struct ssh_cipher *cscipher_tobe = NULL;
|
||||||
@ -2366,27 +2382,60 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Currently we only support Diffie-Hellman and DSS, so let's
|
* If we're doing Diffie-Hellman group exchange, start by
|
||||||
* bomb out if those aren't selected.
|
* requesting a group.
|
||||||
*/
|
*/
|
||||||
if (kex != &ssh_diffiehellman || hostkey != &ssh_dss) {
|
if (kex == &ssh_diffiehellman_gex) {
|
||||||
bombout(("internal fault: chaos in SSH 2 transport layer"));
|
int csbits, scbits;
|
||||||
crReturn(0);
|
|
||||||
|
logevent("Doing Diffie-Hellman group exchange");
|
||||||
|
/*
|
||||||
|
* Work out number of bits. We start with the maximum key
|
||||||
|
* length of either cipher...
|
||||||
|
*/
|
||||||
|
csbits = cscipher_tobe->keylen;
|
||||||
|
scbits = sccipher_tobe->keylen;
|
||||||
|
nbits = (csbits > scbits ? csbits : scbits);
|
||||||
|
/* The keys only have 160-bit entropy, since they're based on
|
||||||
|
* a SHA-1 hash. So cap the key size at 160 bits. */
|
||||||
|
if (nbits > 160) nbits = 160;
|
||||||
|
/*
|
||||||
|
* ... and then work out how big a DH group we will need to
|
||||||
|
* allow that much data.
|
||||||
|
*/
|
||||||
|
nbits = 512 << ((nbits-1) / 64);
|
||||||
|
ssh2_pkt_init(SSH2_MSG_KEX_DH_GEX_REQUEST);
|
||||||
|
ssh2_pkt_adduint32(nbits);
|
||||||
|
ssh2_pkt_send();
|
||||||
|
|
||||||
|
crWaitUntil(ispkt);
|
||||||
|
if (pktin.type != SSH2_MSG_KEX_DH_GEX_GROUP) {
|
||||||
|
bombout(("expected key exchange group packet from server"));
|
||||||
|
crReturn(0);
|
||||||
|
}
|
||||||
|
p = ssh2_pkt_getmp();
|
||||||
|
g = ssh2_pkt_getmp();
|
||||||
|
dh_setup_group(p, g);
|
||||||
|
kex_init_value = SSH2_MSG_KEX_DH_GEX_INIT;
|
||||||
|
kex_reply_value = SSH2_MSG_KEX_DH_GEX_REPLY;
|
||||||
|
} else {
|
||||||
|
dh_setup_group1();
|
||||||
|
kex_init_value = SSH2_MSG_KEXDH_INIT;
|
||||||
|
kex_reply_value = SSH2_MSG_KEXDH_REPLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logevent("Doing Diffie-Hellman key exchange");
|
||||||
/*
|
/*
|
||||||
* Now we begin the fun. Generate and send e for Diffie-Hellman.
|
* Now generate and send e for Diffie-Hellman.
|
||||||
*/
|
*/
|
||||||
dh_setup_group1();
|
|
||||||
|
|
||||||
e = dh_create_e();
|
e = dh_create_e();
|
||||||
ssh2_pkt_init(SSH2_MSG_KEXDH_INIT);
|
ssh2_pkt_init(kex_init_value);
|
||||||
ssh2_pkt_addmp(e);
|
ssh2_pkt_addmp(e);
|
||||||
ssh2_pkt_send();
|
ssh2_pkt_send();
|
||||||
|
|
||||||
crWaitUntil(ispkt);
|
crWaitUntil(ispkt);
|
||||||
if (pktin.type != SSH2_MSG_KEXDH_REPLY) {
|
if (pktin.type != kex_reply_value) {
|
||||||
bombout(("expected key exchange packet from server"));
|
bombout(("expected key exchange reply packet from server"));
|
||||||
crReturn(0);
|
crReturn(0);
|
||||||
}
|
}
|
||||||
ssh2_pkt_getstring(&hostkeydata, &hostkeylen);
|
ssh2_pkt_getstring(&hostkeydata, &hostkeylen);
|
||||||
@ -2396,6 +2445,11 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
|||||||
K = dh_find_K(f);
|
K = dh_find_K(f);
|
||||||
|
|
||||||
sha_string(&exhash, hostkeydata, hostkeylen);
|
sha_string(&exhash, hostkeydata, hostkeylen);
|
||||||
|
if (kex == &ssh_diffiehellman_gex) {
|
||||||
|
sha_uint32(&exhash, nbits);
|
||||||
|
sha_mpint(&exhash, p);
|
||||||
|
sha_mpint(&exhash, g);
|
||||||
|
}
|
||||||
sha_mpint(&exhash, e);
|
sha_mpint(&exhash, e);
|
||||||
sha_mpint(&exhash, f);
|
sha_mpint(&exhash, f);
|
||||||
sha_mpint(&exhash, K);
|
sha_mpint(&exhash, K);
|
||||||
@ -2433,7 +2487,7 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
|||||||
fingerprint = hostkey->fingerprint(hkey);
|
fingerprint = hostkey->fingerprint(hkey);
|
||||||
verify_ssh_host_key(savedhost, savedport, hostkey->keytype,
|
verify_ssh_host_key(savedhost, savedport, hostkey->keytype,
|
||||||
keystr, fingerprint);
|
keystr, fingerprint);
|
||||||
if (first_kex) { /* don't bother logging this in rekeys */
|
if (first_kex) { /* don't bother logging this in rekeys */
|
||||||
logevent("Host key fingerprint is:");
|
logevent("Host key fingerprint is:");
|
||||||
logevent(fingerprint);
|
logevent(fingerprint);
|
||||||
}
|
}
|
||||||
|
1
ssh.h
1
ssh.h
@ -187,6 +187,7 @@ int bignum_cmp(Bignum a, Bignum b);
|
|||||||
char *bignum_decimal(Bignum x);
|
char *bignum_decimal(Bignum x);
|
||||||
|
|
||||||
void dh_setup_group1(void);
|
void dh_setup_group1(void);
|
||||||
|
void dh_setup_group(Bignum pval, Bignum gval);
|
||||||
void dh_cleanup(void);
|
void dh_cleanup(void);
|
||||||
Bignum dh_create_e(void);
|
Bignum dh_create_e(void);
|
||||||
Bignum dh_find_K(Bignum f);
|
Bignum dh_find_K(Bignum f);
|
||||||
|
13
sshdh.c
13
sshdh.c
@ -4,6 +4,10 @@ struct ssh_kex ssh_diffiehellman = {
|
|||||||
"diffie-hellman-group1-sha1"
|
"diffie-hellman-group1-sha1"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ssh_kex ssh_diffiehellman_gex = {
|
||||||
|
"diffie-hellman-group-exchange-sha1"
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The prime p used in the key exchange.
|
* The prime p used in the key exchange.
|
||||||
*/
|
*/
|
||||||
@ -49,6 +53,15 @@ void dh_setup_group1(void) {
|
|||||||
dh_init();
|
dh_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise DH for an alternative group.
|
||||||
|
*/
|
||||||
|
void dh_setup_group(Bignum pval, Bignum gval) {
|
||||||
|
p = copybn(pval);
|
||||||
|
g = copybn(gval);
|
||||||
|
dh_init();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clean up.
|
* Clean up.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user