diff options
Diffstat (limited to 'kex.c')
-rw-r--r-- | kex.c | 96 |
1 files changed, 70 insertions, 26 deletions
@@ -28,13 +28,14 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "includes.h" | 30 | #include "includes.h" |
31 | RCSID("$Id: kex.c,v 1.8 2000/05/09 01:03:01 damien Exp $"); | 31 | RCSID("$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 | |||
52 | Buffer * | 55 | Buffer * |
53 | kex_init(char *myproposal[PROPOSAL_MAX]) | 56 | kex_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 */ | ||
79 | void | ||
80 | kex_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 | ||
77 | int | 124 | int |
@@ -134,12 +181,6 @@ dh_new_group1() | |||
134 | } | 181 | } |
135 | 182 | ||
136 | void | 183 | void |
137 | bignum_print(BIGNUM *b) | ||
138 | { | ||
139 | BN_print_fp(stderr,b); | ||
140 | } | ||
141 | |||
142 | void | ||
143 | dump_digest(unsigned char *digest, int len) | 184 | dump_digest(unsigned char *digest, int len) |
144 | { | 185 | { |
145 | int i; | 186 | int i; |
@@ -246,10 +287,13 @@ char * | |||
246 | get_match(char *client, char *server) | 287 | get_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 | } |
267 | void | 318 | void |
@@ -355,7 +406,6 @@ choose_hostkeyalg(Kex *k, char *client, char *server) | |||
355 | Kex * | 406 | Kex * |
356 | kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server) | 407 | kex_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 | } |