1
0
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:
Simon Tatham
2018-09-13 16:41:46 +01:00
parent 853bd8b284
commit 4f9a90fc1a
7 changed files with 210 additions and 204 deletions

99
ssh.c
View File

@@ -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) {