]> andersk Git - openssh.git/blobdiff - kex.c
- djm@cvs.openbsd.org 2010/01/30 02:54:53
[openssh.git] / kex.c
diff --git a/kex.c b/kex.c
index 8610a7dab7f396b0ba0c7179b670a558ed51ded6..148cfee8046ad5af46be99c83f6b9affe0ec768a 100644 (file)
--- a/kex.c
+++ b/kex.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: kex.c,v 1.82 2009/10/24 11:13:54 andreas Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kex.c,v 1.66 2006/03/07 09:07:40 djm Exp $");
+
+#include <sys/param.h>
+
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include <openssl/crypto.h>
 
-#include "ssh2.h"
 #include "xmalloc.h"
+#include "ssh2.h"
 #include "buffer.h"
-#include "bufaux.h"
 #include "packet.h"
 #include "compat.h"
 #include "cipher.h"
-#include "kex.h"
 #include "key.h"
+#include "kex.h"
 #include "log.h"
 #include "mac.h"
 #include "match.h"
 #include "dispatch.h"
 #include "monitor.h"
+#include "roaming.h"
 
-#define KEX_COOKIE_LEN 16
-
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-# define evp_ssh_sha256() NULL
-#elif defined(HAVE_EVP_SHA256)
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+# if defined(HAVE_EVP_SHA256)
 # define evp_ssh_sha256 EVP_sha256
-#else
+# else
 extern const EVP_MD *evp_ssh_sha256(void);
+# endif
 #endif
 
 /* prototype */
@@ -80,10 +86,10 @@ static char **
 kex_buf2prop(Buffer *raw, int *first_kex_follows)
 {
        Buffer b;
-       int i;
+       u_int i;
        char **proposal;
 
-       proposal = xmalloc(PROPOSAL_MAX * sizeof(char *));
+       proposal = xcalloc(PROPOSAL_MAX, sizeof(char *));
 
        buffer_init(&b);
        buffer_append(&b, buffer_ptr(raw), buffer_len(raw));
@@ -101,7 +107,7 @@ kex_buf2prop(Buffer *raw, int *first_kex_follows)
                *first_kex_follows = i;
        debug2("kex_parse_kexinit: first_kex_follows %d ", i);
        i = buffer_get_int(&b);
-       debug2("kex_parse_kexinit: reserved %d ", i);
+       debug2("kex_parse_kexinit: reserved %u ", i);
        buffer_free(&b);
        return proposal;
 }
@@ -116,6 +122,7 @@ kex_prop_free(char **proposal)
        xfree(proposal);
 }
 
+/* ARGSUSED */
 static void
 kex_protocol_error(int type, u_int32_t seq, void *ctxt)
 {
@@ -187,6 +194,7 @@ kex_send_kexinit(Kex *kex)
        kex->flags |= KEX_INIT_SENT;
 }
 
+/* ARGSUSED */
 void
 kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
 {
@@ -218,8 +226,7 @@ kex_setup(char *proposal[PROPOSAL_MAX])
 {
        Kex *kex;
 
-       kex = xmalloc(sizeof(*kex));
-       memset(kex, 0, sizeof(*kex));
+       kex = xcalloc(1, sizeof(*kex));
        buffer_init(&kex->peer);
        buffer_init(&kex->my);
        kex_prop2buf(&kex->my, proposal);
@@ -252,7 +259,8 @@ choose_enc(Enc *enc, char *client, char *server)
 {
        char *name = match_list(client, server, NULL);
        if (name == NULL)
-               fatal("no matching cipher found: client %s server %s", client, server);
+               fatal("no matching cipher found: client %s server %s",
+                   client, server);
        if ((enc->cipher = cipher_by_name(name)) == NULL)
                fatal("matching cipher is not supported: %s", name);
        enc->name = name;
@@ -262,13 +270,15 @@ choose_enc(Enc *enc, char *client, char *server)
        enc->key_len = cipher_keylen(enc->cipher);
        enc->block_size = cipher_blocksize(enc->cipher);
 }
+
 static void
 choose_mac(Mac *mac, char *client, char *server)
 {
        char *name = match_list(client, server, NULL);
        if (name == NULL)
-               fatal("no matching mac found: client %s server %s", client, server);
-       if (mac_init(mac, name) < 0)
+               fatal("no matching mac found: client %s server %s",
+                   client, server);
+       if (mac_setup(mac, name) < 0)
                fatal("unsupported mac %s", name);
        /* truncate the key */
        if (datafellows & SSH_BUG_HMAC)
@@ -277,6 +287,7 @@ choose_mac(Mac *mac, char *client, char *server)
        mac->key = NULL;
        mac->enabled = 0;
 }
+
 static void
 choose_comp(Comp *comp, char *client, char *server)
 {
@@ -294,12 +305,13 @@ choose_comp(Comp *comp, char *client, char *server)
        }
        comp->name = name;
 }
+
 static void
 choose_kex(Kex *k, char *client, char *server)
 {
        k->name = match_list(client, server, NULL);
        if (k->name == NULL)
-               fatal("no kex alg");
+               fatal("Unable to negotiate a key exchange method");
        if (strcmp(k->name, KEX_DH1) == 0) {
                k->kex_type = KEX_DH_GRP1_SHA1;
                k->evp_md = EVP_sha1();
@@ -309,9 +321,11 @@ choose_kex(Kex *k, char *client, char *server)
        } else if (strcmp(k->name, KEX_DHGEX_SHA1) == 0) {
                k->kex_type = KEX_DH_GEX_SHA1;
                k->evp_md = EVP_sha1();
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
        } else if (strcmp(k->name, KEX_DHGEX_SHA256) == 0) {
                k->kex_type = KEX_DH_GEX_SHA256;
                k->evp_md = evp_ssh_sha256();
+#endif
        } else
                fatal("bad kex alg %s", k->name);
 }
@@ -373,12 +387,22 @@ kex_choose_conf(Kex *kex)
                sprop=peer;
        }
 
+       /* Check whether server offers roaming */
+       if (!kex->server) {
+               char *roaming;
+               roaming = match_list(KEX_RESUME, peer[PROPOSAL_KEX_ALGS], NULL);
+               if (roaming) {
+                       kex->roaming = 1;
+                       xfree(roaming);
+               }
+       }
+
        /* Algorithm Negotiation */
        for (mode = 0; mode < MODE_MAX; mode++) {
-               newkeys = xmalloc(sizeof(*newkeys));
-               memset(newkeys, 0, sizeof(*newkeys));
+               newkeys = xcalloc(1, sizeof(*newkeys));
                kex->newkeys[mode] = newkeys;
-               ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
+               ctos = (!kex->server && mode == MODE_OUT) ||
+                   (kex->server && mode == MODE_IN);
                nenc  = ctos ? PROPOSAL_ENC_ALGS_CTOS  : PROPOSAL_ENC_ALGS_STOC;
                nmac  = ctos ? PROPOSAL_MAC_ALGS_CTOS  : PROPOSAL_MAC_ALGS_STOC;
                ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
@@ -431,7 +455,7 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
 
        if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0)
                fatal("bad kex md size %d", mdsz);
-       digest = xmalloc(roundup(need, mdsz));
+       digest = xmalloc(roundup(need, mdsz));
 
        buffer_init(&b);
        buffer_put_bignum2(&b, shared_secret);
@@ -484,7 +508,8 @@ kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret)
        for (mode = 0; mode < MODE_MAX; mode++) {
                current_keys[mode] = kex->newkeys[mode];
                kex->newkeys[mode] = NULL;
-               ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
+               ctos = (!kex->server && mode == MODE_OUT) ||
+                   (kex->server && mode == MODE_IN);
                current_keys[mode]->enc.iv  = keys[ctos ? 0 : 1];
                current_keys[mode]->enc.key = keys[ctos ? 2 : 3];
                current_keys[mode]->mac.key = keys[ctos ? 4 : 5];
@@ -541,7 +566,7 @@ dump_digest(char *msg, u_char *digest, int len)
        u_int i;
 
        fprintf(stderr, "%s\n", msg);
-       for (i = 0; i< len; i++) {
+       for (i = 0; i < len; i++) {
                fprintf(stderr, "%02x", digest[i]);
                if (i%32 == 31)
                        fprintf(stderr, "\n");
This page took 0.195051 seconds and 4 git commands to generate.