summaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c96
1 files changed, 70 insertions, 26 deletions
diff --git a/kex.c b/kex.c
index 221e03041..199e04264 100644
--- a/kex.c
+++ b/kex.c
@@ -28,13 +28,14 @@
28 */ 28 */
29 29
30#include "includes.h" 30#include "includes.h"
31RCSID("$Id: kex.c,v 1.8 2000/05/09 01:03:01 damien Exp $"); 31RCSID("$Id: kex.c,v 1.9 2000/05/30 03:44:53 damien Exp $");
32 32
33#include "ssh.h" 33#include "ssh.h"
34#include "ssh2.h" 34#include "ssh2.h"
35#include "xmalloc.h" 35#include "xmalloc.h"
36#include "buffer.h" 36#include "buffer.h"
37#include "bufaux.h" 37#include "bufaux.h"
38#include "packet.h"
38#include "cipher.h" 39#include "cipher.h"
39#include "compat.h" 40#include "compat.h"
40 41
@@ -49,15 +50,17 @@ RCSID("$Id: kex.c,v 1.8 2000/05/09 01:03:01 damien Exp $");
49 50
50#include "kex.h" 51#include "kex.h"
51 52
53#define KEX_COOKIE_LEN 16
54
52Buffer * 55Buffer *
53kex_init(char *myproposal[PROPOSAL_MAX]) 56kex_init(char *myproposal[PROPOSAL_MAX])
54{ 57{
55 char c = 0; 58 int first_kex_packet_follows = 0;
56 unsigned char cookie[16]; 59 unsigned char cookie[KEX_COOKIE_LEN];
57 u_int32_t rand = 0; 60 u_int32_t rand = 0;
58 int i; 61 int i;
59 Buffer *ki = xmalloc(sizeof(*ki)); 62 Buffer *ki = xmalloc(sizeof(*ki));
60 for (i = 0; i < 16; i++) { 63 for (i = 0; i < KEX_COOKIE_LEN; i++) {
61 if (i % 4 == 0) 64 if (i % 4 == 0)
62 rand = arc4random(); 65 rand = arc4random();
63 cookie[i] = rand & 0xff; 66 cookie[i] = rand & 0xff;
@@ -67,11 +70,55 @@ kex_init(char *myproposal[PROPOSAL_MAX])
67 buffer_append(ki, (char *)cookie, sizeof cookie); 70 buffer_append(ki, (char *)cookie, sizeof cookie);
68 for (i = 0; i < PROPOSAL_MAX; i++) 71 for (i = 0; i < PROPOSAL_MAX; i++)
69 buffer_put_cstring(ki, myproposal[i]); 72 buffer_put_cstring(ki, myproposal[i]);
70 buffer_append(ki, &c, 1); /* boolean first_kex_packet_follows */ 73 buffer_put_char(ki, first_kex_packet_follows);
71 buffer_put_int(ki, 0); /* uint32 0 (reserved for future extension) */ 74 buffer_put_int(ki, 0); /* uint32 reserved */
72 return ki; 75 return ki;
73} 76}
74 77
78/* send kexinit, parse and save reply */
79void
80kex_exchange_kexinit(
81 Buffer *my_kexinit, Buffer *peer_kexint,
82 char *peer_proposal[PROPOSAL_MAX])
83{
84 int i;
85 char *ptr;
86 int plen;
87
88 debug("send KEXINIT");
89 packet_start(SSH2_MSG_KEXINIT);
90 packet_put_raw(buffer_ptr(my_kexinit), buffer_len(my_kexinit));
91 packet_send();
92 packet_write_wait();
93 debug("done");
94
95 /*
96 * read and save raw KEXINIT payload in buffer. this is used during
97 * computation of the session_id and the session keys.
98 */
99 debug("wait KEXINIT");
100 packet_read_expect(&plen, SSH2_MSG_KEXINIT);
101 ptr = packet_get_raw(&plen);
102 buffer_append(peer_kexint, ptr, plen);
103
104 /* parse packet and save algorithm proposal */
105 /* skip cookie */
106 for (i = 0; i < KEX_COOKIE_LEN; i++)
107 packet_get_char();
108 /* extract kex init proposal strings */
109 for (i = 0; i < PROPOSAL_MAX; i++) {
110 peer_proposal[i] = packet_get_string(NULL);
111 debug("got kexinit: %s", peer_proposal[i]);
112 }
113 /* first kex follow / reserved */
114 i = packet_get_char();
115 debug("first kex follow: %d ", i);
116 i = packet_get_int();
117 debug("reserved: %d ", i);
118 packet_done();
119 debug("done");
120}
121
75/* diffie-hellman-group1-sha1 */ 122/* diffie-hellman-group1-sha1 */
76 123
77int 124int
@@ -134,12 +181,6 @@ dh_new_group1()
134} 181}
135 182
136void 183void
137bignum_print(BIGNUM *b)
138{
139 BN_print_fp(stderr,b);
140}
141
142void
143dump_digest(unsigned char *digest, int len) 184dump_digest(unsigned char *digest, int len)
144{ 185{
145 int i; 186 int i;
@@ -246,10 +287,13 @@ char *
246get_match(char *client, char *server) 287get_match(char *client, char *server)
247{ 288{
248 char *sproposals[MAX_PROP]; 289 char *sproposals[MAX_PROP];
249 char *p; 290 char *c, *s, *p, *ret;
250 int i, j, nproposals; 291 int i, j, nproposals;
251 292
252 for ((p = strtok(server, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { 293 c = xstrdup(client);
294 s = xstrdup(server);
295
296 for ((p = strtok(s, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) {
253 if (i < MAX_PROP) 297 if (i < MAX_PROP)
254 sproposals[i] = p; 298 sproposals[i] = p;
255 else 299 else
@@ -257,11 +301,18 @@ get_match(char *client, char *server)
257 } 301 }
258 nproposals = i; 302 nproposals = i;
259 303
260 for ((p = strtok(client, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { 304 for ((p = strtok(c, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) {
261 for (j = 0; j < nproposals; j++) 305 for (j = 0; j < nproposals; j++) {
262 if (strcmp(p, sproposals[j]) == 0) 306 if (strcmp(p, sproposals[j]) == 0) {
263 return xstrdup(p); 307 ret = xstrdup(p);
308 xfree(c);
309 xfree(s);
310 return ret;
311 }
312 }
264 } 313 }
314 xfree(c);
315 xfree(s);
265 return NULL; 316 return NULL;
266} 317}
267void 318void
@@ -355,7 +406,6 @@ choose_hostkeyalg(Kex *k, char *client, char *server)
355Kex * 406Kex *
356kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server) 407kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server)
357{ 408{
358 int i;
359 int mode; 409 int mode;
360 int ctos; /* direction: if true client-to-server */ 410 int ctos; /* direction: if true client-to-server */
361 int need; 411 int need;
@@ -383,10 +433,6 @@ kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server
383 choose_kex(k, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); 433 choose_kex(k, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
384 choose_hostkeyalg(k, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], 434 choose_hostkeyalg(k, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
385 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); 435 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);
386 for (i = 0; i < PROPOSAL_MAX; i++) {
387 xfree(cprop[i]);
388 xfree(sprop[i]);
389 }
390 need = 0; 436 need = 0;
391 for (mode = 0; mode < MODE_MAX; mode++) { 437 for (mode = 0; mode < MODE_MAX; mode++) {
392 if (need < k->enc[mode].key_len) 438 if (need < k->enc[mode].key_len)
@@ -396,9 +442,7 @@ kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server
396 if (need < k->mac[mode].key_len) 442 if (need < k->mac[mode].key_len)
397 need = k->mac[mode].key_len; 443 need = k->mac[mode].key_len;
398 } 444 }
399 /* need runden? */ 445 /* XXX need runden? */
400#define WE_NEED 32
401 k->we_need = WE_NEED;
402 k->we_need = need; 446 k->we_need = need;
403 return k; 447 return k;
404} 448}