X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/5ff39d34a50802bab296b50eb09d097062e07f03..b96a6af60a1d126146158d662f755920c6edc998:/openssh/kex.c diff --git a/openssh/kex.c b/openssh/kex.c index 612b02f..b49c610 100644 --- a/openssh/kex.c +++ b/openssh/kex.c @@ -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.64 2005/07/25 11:59:39 markus Exp $"); #include @@ -53,10 +53,10 @@ static void kex_kexinit_finish(Kex *); static void kex_choose_conf(Kex *); /* put algorithm proposal into buffer */ -static void +void kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) { - int i; + u_int i; buffer_clear(b); /* @@ -105,7 +105,7 @@ kex_buf2prop(Buffer *raw, int *first_kex_follows) static void kex_prop_free(char **proposal) { - int i; + u_int i; for (i = 0; i < PROPOSAL_MAX; i++) xfree(proposal[i]); @@ -152,9 +152,9 @@ kex_finish(Kex *kex) void kex_send_kexinit(Kex *kex) { - u_int32_t rand = 0; + u_int32_t rnd = 0; u_char *cookie; - int i; + u_int i; if (kex == NULL) { error("kex_send_kexinit: no kex, cannot rekey"); @@ -172,9 +172,9 @@ kex_send_kexinit(Kex *kex) 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)); @@ -187,8 +187,7 @@ void kex_input_kexinit(int type, u_int32_t seq, void *ctxt) { char *ptr; - int dlen; - int i; + u_int i, dlen; Kex *kex = (Kex *)ctxt; debug("SSH2_MSG_KEXINIT received"); @@ -280,10 +279,12 @@ choose_comp(Comp *comp, char *client, char *server) char *name = match_list(client, server, NULL); if (name == NULL) fatal("no matching comp found: client %s server %s", client, server); - if (strcmp(name, "zlib") == 0) { - comp->type = 1; + if (strcmp(name, "zlib@openssh.com") == 0) { + comp->type = COMP_DELAYED; + } else if (strcmp(name, "zlib") == 0) { + comp->type = COMP_ZLIB; } else if (strcmp(name, "none") == 0) { - comp->type = 0; + comp->type = COMP_NONE; } else { fatal("unsupported comp %s", name); } @@ -294,13 +295,19 @@ choose_kex(Kex *k, char *client, char *server) { k->name = match_list(client, server, NULL); if (k->name == NULL) - fatal("No key exchange algorithm"); + 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; #ifdef GSSAPI - } else if (strncmp(k->name, KEX_GSS_SHA1, sizeof(KEX_GSS_SHA1)-1) == 0) { + } else if (strncmp(k->name, KEX_GSS_GEX_SHA1_ID, + sizeof(KEX_GSS_GEX_SHA1_ID)-1) == 0) { + k->kex_type = KEX_GSS_GEX_SHA1; + } else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID, + sizeof(KEX_GSS_GRP1_SHA1_ID)-1) == 0) { k->kex_type = KEX_GSS_GRP1_SHA1; #endif } else @@ -318,7 +325,7 @@ choose_hostkeyalg(Kex *k, char *client, char *server) xfree(hostkeyalg); } -static int +static int proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX]) { static int check[] = { @@ -349,9 +356,7 @@ kex_choose_conf(Kex *kex) char **my, **peer; char **cprop, **sprop; int nenc, nmac, ncomp; - int mode; - int ctos; /* direction: if true client-to-server */ - int need; + u_int mode, ctos, need; int first_kex_follows, type; my = kex_buf2prop(&kex->my, NULL); @@ -400,8 +405,8 @@ kex_choose_conf(Kex *kex) kex->we_need = need; /* ignore the next message if the proposals do not match */ - if (first_kex_follows && !proposals_match(my, peer) && - !(datafellows & SSH_BUG_FIRSTKEX)) { + if (first_kex_follows && !proposals_match(my, peer) && + !(datafellows & SSH_BUG_FIRSTKEX)) { type = packet_read(); debug2("skipping next packet (type %u)", type); } @@ -411,15 +416,19 @@ kex_choose_conf(Kex *kex) } static u_char * -derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret) +derive_key(Kex *kex, int id, u_int need, u_char *hash, BIGNUM *shared_secret) { Buffer b; const EVP_MD *evp_md = EVP_sha1(); EVP_MD_CTX md; char c = id; - int have; + u_int have; int mdsz = EVP_MD_size(evp_md); - u_char *digest = xmalloc(roundup(need, mdsz)); + u_char *digest; + + if (mdsz < 0) + fatal("derive_key: mdsz < 0"); + digest = xmalloc(roundup(need, mdsz)); buffer_init(&b); buffer_put_bignum2(&b, shared_secret); @@ -461,7 +470,7 @@ void kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret) { u_char *keys[NKEYS]; - int i, mode, ctos; + u_int i, mode, ctos; for (i = 0; i < NKEYS; i++) keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret); @@ -487,11 +496,44 @@ kex_get_newkeys(int mode) 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) || (u_int)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) || (u_int)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) void dump_digest(char *msg, u_char *digest, int len) { - int i; + u_int i; fprintf(stderr, "%s\n", msg); for (i = 0; i< len; i++) {