=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/kex.c,v retrieving revision 1.55 retrieving revision 1.55.2.2 diff -u -r1.55 -r1.55.2.2 --- src/usr.bin/ssh/kex.c 2003/04/01 10:31:26 1.55 +++ src/usr.bin/ssh/kex.c 2004/08/19 22:37:31 1.55.2.2 @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: kex.c,v 1.55 2003/04/01 10:31:26 markus Exp $"); +RCSID("$OpenBSD: kex.c,v 1.55.2.2 2004/08/19 22:37:31 brad Exp $"); #include @@ -148,7 +148,7 @@ void kex_send_kexinit(Kex *kex) { - u_int32_t rand = 0; + u_int32_t rnd = 0; u_char *cookie; int i; @@ -168,9 +168,9 @@ cookie = buffer_ptr(&kex->my); for (i = 0; i < KEX_COOKIE_LEN; i++) { if (i % 4 == 0) - rand = arc4random(); - cookie[i] = rand; - rand >>= 8; + rnd = arc4random(); + cookie[i] = rnd; + rnd >>= 8; } packet_start(SSH2_MSG_KEXINIT); packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my)); @@ -293,6 +293,8 @@ fatal("no kex alg"); if (strcmp(k->name, KEX_DH1) == 0) { k->kex_type = KEX_DH_GRP1_SHA1; + } else if (strcmp(k->name, KEX_DH14) == 0) { + k->kex_type = KEX_DH_GRP14_SHA1; } else if (strcmp(k->name, KEX_DHGEX) == 0) { k->kex_type = KEX_DH_GEX_SHA1; } else @@ -310,7 +312,7 @@ xfree(hostkeyalg); } -static int +static int proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX]) { static int check[] = { @@ -392,7 +394,7 @@ kex->we_need = need; /* ignore the next message if the proposals do not match */ - if (first_kex_follows && !proposals_match(my, peer) && + if (first_kex_follows && !proposals_match(my, peer) && !(datafellows & SSH_BUG_FIRSTKEX)) { type = packet_read(); debug2("skipping next packet (type %u)", type); @@ -477,6 +479,39 @@ ret = current_keys[mode]; current_keys[mode] = NULL; return ret; +} + +void +derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, + u_int8_t cookie[8], u_int8_t id[16]) +{ + const EVP_MD *evp_md = EVP_md5(); + EVP_MD_CTX md; + u_int8_t nbuf[2048], obuf[EVP_MAX_MD_SIZE]; + int len; + + EVP_DigestInit(&md, evp_md); + + len = BN_num_bytes(host_modulus); + if (len < (512 / 8) || len > sizeof(nbuf)) + fatal("%s: bad host modulus (len %d)", __func__, len); + BN_bn2bin(host_modulus, nbuf); + EVP_DigestUpdate(&md, nbuf, len); + + len = BN_num_bytes(server_modulus); + if (len < (512 / 8) || len > sizeof(nbuf)) + fatal("%s: bad server modulus (len %d)", __func__, len); + BN_bn2bin(server_modulus, nbuf); + EVP_DigestUpdate(&md, nbuf, len); + + EVP_DigestUpdate(&md, cookie, 8); + + EVP_DigestFinal(&md, obuf, NULL); + memcpy(id, obuf, 16); + + memset(nbuf, 0, sizeof(nbuf)); + memset(obuf, 0, sizeof(obuf)); + memset(&md, 0, sizeof(md)); } #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH)