mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-31 10:34:32 -05:00
Turn SSH hashes into a classoid.
The new version of ssh_hash has the same nice property as ssh2_mac, that I can make the generic interface object type function directly as a BinarySink so that clients don't have to call h->sink() and worry about the separate sink object they get back from that.
This commit is contained in:
99
ssh.c
99
ssh.c
@@ -668,8 +668,7 @@ enum RekeyClass {
|
||||
|
||||
struct ssh_tag {
|
||||
char *v_c, *v_s;
|
||||
void *exhash;
|
||||
BinarySink *exhash_bs;
|
||||
ssh_hash *exhash;
|
||||
|
||||
Socket s;
|
||||
|
||||
@@ -4780,11 +4779,10 @@ static void add_to_commasep(strbuf *buf, const char *data)
|
||||
static void ssh2_mkkey(Ssh ssh, strbuf *out, Bignum K, unsigned char *H,
|
||||
char chr, int keylen)
|
||||
{
|
||||
const struct ssh_hash *h = ssh->kex->hash;
|
||||
const struct ssh_hashalg *h = ssh->kex->hash;
|
||||
int keylen_padded;
|
||||
unsigned char *key;
|
||||
void *s, *s2;
|
||||
BinarySink *bs;
|
||||
ssh_hash *s, *s2;
|
||||
|
||||
if (keylen == 0)
|
||||
return;
|
||||
@@ -4805,32 +4803,30 @@ static void ssh2_mkkey(Ssh ssh, strbuf *out, Bignum K, unsigned char *H,
|
||||
key = strbuf_append(out, keylen_padded);
|
||||
|
||||
/* First hlen bytes. */
|
||||
s = h->init();
|
||||
bs = h->sink(s);
|
||||
s = ssh_hash_new(h);
|
||||
if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
|
||||
put_mp_ssh2(bs, K);
|
||||
put_data(bs, H, h->hlen);
|
||||
put_byte(bs, chr);
|
||||
put_data(bs, ssh->v2_session_id, ssh->v2_session_id_len);
|
||||
h->final(s, key);
|
||||
put_mp_ssh2(s, K);
|
||||
put_data(s, H, h->hlen);
|
||||
put_byte(s, chr);
|
||||
put_data(s, ssh->v2_session_id, ssh->v2_session_id_len);
|
||||
ssh_hash_final(s, key);
|
||||
|
||||
/* Subsequent blocks of hlen bytes. */
|
||||
if (keylen_padded > h->hlen) {
|
||||
int offset;
|
||||
|
||||
s = h->init();
|
||||
bs = h->sink(s);
|
||||
s = ssh_hash_new(h);
|
||||
if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
|
||||
put_mp_ssh2(bs, K);
|
||||
put_data(bs, H, h->hlen);
|
||||
put_mp_ssh2(s, K);
|
||||
put_data(s, H, h->hlen);
|
||||
|
||||
for (offset = h->hlen; offset < keylen_padded; offset += h->hlen) {
|
||||
put_data(bs, key + offset - h->hlen, h->hlen);
|
||||
s2 = h->copy(s);
|
||||
h->final(s2, key + offset);
|
||||
put_data(s, key + offset - h->hlen, h->hlen);
|
||||
s2 = ssh_hash_copy(s);
|
||||
ssh_hash_final(s2, key + offset);
|
||||
}
|
||||
|
||||
h->free(s);
|
||||
ssh_hash_free(s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5600,14 +5596,13 @@ static void do_ssh2_transport(void *vctx)
|
||||
get_string(pktin); /* server->client language */
|
||||
s->ignorepkt = get_bool(pktin) && !s->guessok;
|
||||
|
||||
ssh->exhash = ssh->kex->hash->init();
|
||||
ssh->exhash_bs = ssh->kex->hash->sink(ssh->exhash);
|
||||
put_stringz(ssh->exhash_bs, ssh->v_c);
|
||||
put_stringz(ssh->exhash_bs, ssh->v_s);
|
||||
put_string(ssh->exhash_bs, s->our_kexinit, s->our_kexinitlen);
|
||||
ssh->exhash = ssh_hash_new(ssh->kex->hash);
|
||||
put_stringz(ssh->exhash, ssh->v_c);
|
||||
put_stringz(ssh->exhash, ssh->v_s);
|
||||
put_string(ssh->exhash, s->our_kexinit, s->our_kexinitlen);
|
||||
sfree(s->our_kexinit);
|
||||
/* Include the type byte in the hash of server's KEXINIT */
|
||||
put_string(ssh->exhash_bs,
|
||||
put_string(ssh->exhash,
|
||||
(const char *)BinarySource_UPCAST(pktin)->data - 1,
|
||||
BinarySource_UPCAST(pktin)->len + 1);
|
||||
|
||||
@@ -5844,18 +5839,18 @@ static void do_ssh2_transport(void *vctx)
|
||||
* involve user interaction. */
|
||||
set_busy_status(ssh->frontend, BUSY_NOT);
|
||||
|
||||
put_stringpl(ssh->exhash_bs, s->hostkeydata);
|
||||
put_stringpl(ssh->exhash, s->hostkeydata);
|
||||
if (dh_is_gex(ssh->kex)) {
|
||||
if (!(ssh->remote_bugs & BUG_SSH2_OLDGEX))
|
||||
put_uint32(ssh->exhash_bs, DH_MIN_SIZE);
|
||||
put_uint32(ssh->exhash_bs, s->pbits);
|
||||
put_uint32(ssh->exhash, DH_MIN_SIZE);
|
||||
put_uint32(ssh->exhash, s->pbits);
|
||||
if (!(ssh->remote_bugs & BUG_SSH2_OLDGEX))
|
||||
put_uint32(ssh->exhash_bs, DH_MAX_SIZE);
|
||||
put_mp_ssh2(ssh->exhash_bs, s->p);
|
||||
put_mp_ssh2(ssh->exhash_bs, s->g);
|
||||
put_uint32(ssh->exhash, DH_MAX_SIZE);
|
||||
put_mp_ssh2(ssh->exhash, s->p);
|
||||
put_mp_ssh2(ssh->exhash, s->g);
|
||||
}
|
||||
put_mp_ssh2(ssh->exhash_bs, s->e);
|
||||
put_mp_ssh2(ssh->exhash_bs, s->f);
|
||||
put_mp_ssh2(ssh->exhash, s->e);
|
||||
put_mp_ssh2(ssh->exhash, s->f);
|
||||
|
||||
dh_cleanup(ssh->kex_ctx);
|
||||
freebn(s->f);
|
||||
@@ -5893,19 +5888,19 @@ static void do_ssh2_transport(void *vctx)
|
||||
}
|
||||
|
||||
s->hostkeydata = get_string(pktin);
|
||||
put_stringpl(ssh->exhash_bs, s->hostkeydata);
|
||||
put_stringpl(ssh->exhash, s->hostkeydata);
|
||||
s->hkey = ssh_key_new_pub(ssh->hostkey_alg, s->hostkeydata);
|
||||
|
||||
{
|
||||
strbuf *pubpoint = strbuf_new();
|
||||
ssh_ecdhkex_getpublic(s->eckey, BinarySink_UPCAST(pubpoint));
|
||||
put_string(ssh->exhash_bs, pubpoint->u, pubpoint->len);
|
||||
put_string(ssh->exhash, pubpoint->u, pubpoint->len);
|
||||
strbuf_free(pubpoint);
|
||||
}
|
||||
|
||||
{
|
||||
ptrlen keydata = get_string(pktin);
|
||||
put_stringpl(ssh->exhash_bs, keydata);
|
||||
put_stringpl(ssh->exhash, keydata);
|
||||
s->K = ssh_ecdhkex_getkey(s->eckey, keydata.ptr, keydata.len);
|
||||
if (!get_err(pktin) && !s->K) {
|
||||
ssh_ecdhkex_freekey(s->eckey);
|
||||
@@ -6100,7 +6095,7 @@ static void do_ssh2_transport(void *vctx)
|
||||
if (ssh->hostkey_alg) {
|
||||
s->hkey = ssh_key_new_pub(ssh->hostkey_alg,
|
||||
s->hostkeydata);
|
||||
put_string(ssh->exhash_bs,
|
||||
put_string(ssh->exhash,
|
||||
s->hostkeydata.ptr, s->hostkeydata.len);
|
||||
}
|
||||
/*
|
||||
@@ -6149,18 +6144,18 @@ static void do_ssh2_transport(void *vctx)
|
||||
set_busy_status(ssh->frontend, BUSY_NOT);
|
||||
|
||||
if (!s->hkey)
|
||||
put_stringz(ssh->exhash_bs, "");
|
||||
put_stringz(ssh->exhash, "");
|
||||
if (dh_is_gex(ssh->kex)) {
|
||||
/* min, preferred, max */
|
||||
put_uint32(ssh->exhash_bs, s->pbits);
|
||||
put_uint32(ssh->exhash_bs, s->pbits);
|
||||
put_uint32(ssh->exhash_bs, s->pbits * 2);
|
||||
put_uint32(ssh->exhash, s->pbits);
|
||||
put_uint32(ssh->exhash, s->pbits);
|
||||
put_uint32(ssh->exhash, s->pbits * 2);
|
||||
|
||||
put_mp_ssh2(ssh->exhash_bs, s->p);
|
||||
put_mp_ssh2(ssh->exhash_bs, s->g);
|
||||
put_mp_ssh2(ssh->exhash, s->p);
|
||||
put_mp_ssh2(ssh->exhash, s->g);
|
||||
}
|
||||
put_mp_ssh2(ssh->exhash_bs, s->e);
|
||||
put_mp_ssh2(ssh->exhash_bs, s->f);
|
||||
put_mp_ssh2(ssh->exhash, s->e);
|
||||
put_mp_ssh2(ssh->exhash, s->f);
|
||||
|
||||
/*
|
||||
* MIC verification is done below, after we compute the hash
|
||||
@@ -6192,7 +6187,7 @@ static void do_ssh2_transport(void *vctx)
|
||||
}
|
||||
|
||||
s->hostkeydata = get_string(pktin);
|
||||
put_stringpl(ssh->exhash_bs, s->hostkeydata);
|
||||
put_stringpl(ssh->exhash, s->hostkeydata);
|
||||
s->hkey = ssh_key_new_pub(ssh->hostkey_alg, s->hostkeydata);
|
||||
|
||||
rsakeydata = get_string(pktin);
|
||||
@@ -6203,7 +6198,7 @@ static void do_ssh2_transport(void *vctx)
|
||||
crStopV;
|
||||
}
|
||||
|
||||
put_stringpl(ssh->exhash_bs, rsakeydata);
|
||||
put_stringpl(ssh->exhash, rsakeydata);
|
||||
|
||||
/*
|
||||
* Next, set up a shared secret K, of precisely KLEN -
|
||||
@@ -6249,7 +6244,7 @@ static void do_ssh2_transport(void *vctx)
|
||||
put_string(s->pktout, outstr, outstrlen);
|
||||
ssh_pkt_write(ssh, s->pktout);
|
||||
|
||||
put_string(ssh->exhash_bs, outstr, outstrlen);
|
||||
put_string(ssh->exhash, outstr, outstrlen);
|
||||
|
||||
strbuf_free(buf);
|
||||
sfree(outstr);
|
||||
@@ -6270,9 +6265,9 @@ static void do_ssh2_transport(void *vctx)
|
||||
}
|
||||
}
|
||||
|
||||
put_mp_ssh2(ssh->exhash_bs, s->K);
|
||||
assert(ssh->kex->hash->hlen <= sizeof(s->exchange_hash));
|
||||
ssh->kex->hash->final(ssh->exhash, s->exchange_hash);
|
||||
put_mp_ssh2(ssh->exhash, s->K);
|
||||
assert(ssh_hash_alg(ssh->exhash)->hlen <= sizeof(s->exchange_hash));
|
||||
ssh_hash_final(ssh->exhash, s->exchange_hash);
|
||||
|
||||
#ifndef NO_GSSAPI
|
||||
if (ssh->kex->main_type == KEXTYPE_GSS) {
|
||||
|
Reference in New Issue
Block a user