summaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c657
1 files changed, 397 insertions, 260 deletions
diff --git a/kex.c b/kex.c
index 891852b54..be938ad04 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.c,v 1.99 2014/04/29 18:01:49 markus Exp $ */ 1/* $OpenBSD: kex.c,v 1.105 2015/01/30 00:22:25 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -25,7 +25,7 @@
25 25
26#include "includes.h" 26#include "includes.h"
27 27
28#include <sys/param.h> 28#include <sys/param.h> /* MAX roundup */
29 29
30#include <signal.h> 30#include <signal.h>
31#include <stdarg.h> 31#include <stdarg.h>
@@ -37,20 +37,22 @@
37#include <openssl/crypto.h> 37#include <openssl/crypto.h>
38#endif 38#endif
39 39
40#include "xmalloc.h"
41#include "ssh2.h" 40#include "ssh2.h"
42#include "buffer.h"
43#include "packet.h" 41#include "packet.h"
44#include "compat.h" 42#include "compat.h"
45#include "cipher.h" 43#include "cipher.h"
46#include "key.h" 44#include "sshkey.h"
47#include "kex.h" 45#include "kex.h"
48#include "log.h" 46#include "log.h"
49#include "mac.h" 47#include "mac.h"
50#include "match.h" 48#include "match.h"
49#include "misc.h"
51#include "dispatch.h" 50#include "dispatch.h"
52#include "monitor.h" 51#include "monitor.h"
53#include "roaming.h" 52#include "roaming.h"
53
54#include "ssherr.h"
55#include "sshbuf.h"
54#include "digest.h" 56#include "digest.h"
55 57
56#ifdef GSSAPI 58#ifdef GSSAPI
@@ -66,12 +68,12 @@ extern const EVP_MD *evp_ssh_sha256(void);
66#endif 68#endif
67 69
68/* prototype */ 70/* prototype */
69static void kex_kexinit_finish(Kex *); 71static int kex_choose_conf(struct ssh *);
70static void kex_choose_conf(Kex *); 72static int kex_input_newkeys(int, u_int32_t, void *);
71 73
72struct kexalg { 74struct kexalg {
73 char *name; 75 char *name;
74 int type; 76 u_int type;
75 int ec_nid; 77 int ec_nid;
76 int hash_alg; 78 int hash_alg;
77}; 79};
@@ -93,11 +95,10 @@ static const struct kexalg kexalgs[] = {
93 SSH_DIGEST_SHA512 }, 95 SSH_DIGEST_SHA512 },
94# endif /* OPENSSL_HAS_NISTP521 */ 96# endif /* OPENSSL_HAS_NISTP521 */
95#endif /* OPENSSL_HAS_ECC */ 97#endif /* OPENSSL_HAS_ECC */
96 { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
97#endif /* WITH_OPENSSL */ 98#endif /* WITH_OPENSSL */
98#ifdef HAVE_EVP_SHA256 99#if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL)
99 { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, 100 { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
100#endif /* HAVE_EVP_SHA256 */ 101#endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */
101 { NULL, -1, -1, -1}, 102 { NULL, -1, -1, -1},
102}; 103};
103static const struct kexalg kexalg_prefixes[] = { 104static const struct kexalg kexalg_prefixes[] = {
@@ -112,7 +113,7 @@ static const struct kexalg kexalg_prefixes[] = {
112char * 113char *
113kex_alg_list(char sep) 114kex_alg_list(char sep)
114{ 115{
115 char *ret = NULL; 116 char *ret = NULL, *tmp;
116 size_t nlen, rlen = 0; 117 size_t nlen, rlen = 0;
117 const struct kexalg *k; 118 const struct kexalg *k;
118 119
@@ -120,7 +121,11 @@ kex_alg_list(char sep)
120 if (ret != NULL) 121 if (ret != NULL)
121 ret[rlen++] = sep; 122 ret[rlen++] = sep;
122 nlen = strlen(k->name); 123 nlen = strlen(k->name);
123 ret = xrealloc(ret, 1, rlen + nlen + 2); 124 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
125 free(ret);
126 return NULL;
127 }
128 ret = tmp;
124 memcpy(ret + rlen, k->name, nlen + 1); 129 memcpy(ret + rlen, k->name, nlen + 1);
125 rlen += nlen; 130 rlen += nlen;
126 } 131 }
@@ -151,7 +156,8 @@ kex_names_valid(const char *names)
151 156
152 if (names == NULL || strcmp(names, "") == 0) 157 if (names == NULL || strcmp(names, "") == 0)
153 return 0; 158 return 0;
154 s = cp = xstrdup(names); 159 if ((s = cp = strdup(names)) == NULL)
160 return 0;
155 for ((p = strsep(&cp, ",")); p && *p != '\0'; 161 for ((p = strsep(&cp, ",")); p && *p != '\0';
156 (p = strsep(&cp, ","))) { 162 (p = strsep(&cp, ","))) {
157 if (kex_alg_by_name(p) == NULL) { 163 if (kex_alg_by_name(p) == NULL) {
@@ -166,56 +172,75 @@ kex_names_valid(const char *names)
166} 172}
167 173
168/* put algorithm proposal into buffer */ 174/* put algorithm proposal into buffer */
169static void 175int
170kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) 176kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
171{ 177{
172 u_int i; 178 u_int i;
179 int r;
180
181 sshbuf_reset(b);
173 182
174 buffer_clear(b);
175 /* 183 /*
176 * add a dummy cookie, the cookie will be overwritten by 184 * add a dummy cookie, the cookie will be overwritten by
177 * kex_send_kexinit(), each time a kexinit is set 185 * kex_send_kexinit(), each time a kexinit is set
178 */ 186 */
179 for (i = 0; i < KEX_COOKIE_LEN; i++) 187 for (i = 0; i < KEX_COOKIE_LEN; i++) {
180 buffer_put_char(b, 0); 188 if ((r = sshbuf_put_u8(b, 0)) != 0)
181 for (i = 0; i < PROPOSAL_MAX; i++) 189 return r;
182 buffer_put_cstring(b, proposal[i]); 190 }
183 buffer_put_char(b, 0); /* first_kex_packet_follows */ 191 for (i = 0; i < PROPOSAL_MAX; i++) {
184 buffer_put_int(b, 0); /* uint32 reserved */ 192 if ((r = sshbuf_put_cstring(b, proposal[i])) != 0)
193 return r;
194 }
195 if ((r = sshbuf_put_u8(b, 0)) != 0 || /* first_kex_packet_follows */
196 (r = sshbuf_put_u32(b, 0)) != 0) /* uint32 reserved */
197 return r;
198 return 0;
185} 199}
186 200
187/* parse buffer and return algorithm proposal */ 201/* parse buffer and return algorithm proposal */
188static char ** 202int
189kex_buf2prop(Buffer *raw, int *first_kex_follows) 203kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
190{ 204{
191 Buffer b; 205 struct sshbuf *b = NULL;
206 u_char v;
192 u_int i; 207 u_int i;
193 char **proposal; 208 char **proposal = NULL;
194 209 int r;
195 proposal = xcalloc(PROPOSAL_MAX, sizeof(char *)); 210
196 211 *propp = NULL;
197 buffer_init(&b); 212 if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL)
198 buffer_append(&b, buffer_ptr(raw), buffer_len(raw)); 213 return SSH_ERR_ALLOC_FAIL;
199 /* skip cookie */ 214 if ((b = sshbuf_fromb(raw)) == NULL) {
200 for (i = 0; i < KEX_COOKIE_LEN; i++) 215 r = SSH_ERR_ALLOC_FAIL;
201 buffer_get_char(&b); 216 goto out;
217 }
218 if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */
219 goto out;
202 /* extract kex init proposal strings */ 220 /* extract kex init proposal strings */
203 for (i = 0; i < PROPOSAL_MAX; i++) { 221 for (i = 0; i < PROPOSAL_MAX; i++) {
204 proposal[i] = buffer_get_cstring(&b,NULL); 222 if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0)
223 goto out;
205 debug2("kex_parse_kexinit: %s", proposal[i]); 224 debug2("kex_parse_kexinit: %s", proposal[i]);
206 } 225 }
207 /* first kex follows / reserved */ 226 /* first kex follows / reserved */
208 i = buffer_get_char(&b); 227 if ((r = sshbuf_get_u8(b, &v)) != 0 ||
228 (r = sshbuf_get_u32(b, &i)) != 0)
229 goto out;
209 if (first_kex_follows != NULL) 230 if (first_kex_follows != NULL)
210 *first_kex_follows = i; 231 *first_kex_follows = i;
211 debug2("kex_parse_kexinit: first_kex_follows %d ", i); 232 debug2("kex_parse_kexinit: first_kex_follows %d ", v);
212 i = buffer_get_int(&b);
213 debug2("kex_parse_kexinit: reserved %u ", i); 233 debug2("kex_parse_kexinit: reserved %u ", i);
214 buffer_free(&b); 234 r = 0;
215 return proposal; 235 *propp = proposal;
236 out:
237 if (r != 0 && proposal != NULL)
238 kex_prop_free(proposal);
239 sshbuf_free(b);
240 return r;
216} 241}
217 242
218static void 243void
219kex_prop_free(char **proposal) 244kex_prop_free(char **proposal)
220{ 245{
221 u_int i; 246 u_int i;
@@ -226,97 +251,111 @@ kex_prop_free(char **proposal)
226} 251}
227 252
228/* ARGSUSED */ 253/* ARGSUSED */
229static void 254static int
230kex_protocol_error(int type, u_int32_t seq, void *ctxt) 255kex_protocol_error(int type, u_int32_t seq, void *ctxt)
231{ 256{
232 error("Hm, kex protocol error: type %d seq %u", type, seq); 257 error("Hm, kex protocol error: type %d seq %u", type, seq);
258 return 0;
233} 259}
234 260
235static void 261static void
236kex_reset_dispatch(void) 262kex_reset_dispatch(struct ssh *ssh)
237{ 263{
238 dispatch_range(SSH2_MSG_TRANSPORT_MIN, 264 ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN,
239 SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error); 265 SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
240 dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); 266 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
241} 267}
242 268
243void 269int
244kex_finish(Kex *kex) 270kex_send_newkeys(struct ssh *ssh)
245{ 271{
246 kex_reset_dispatch(); 272 int r;
247 273
248 packet_start(SSH2_MSG_NEWKEYS); 274 kex_reset_dispatch(ssh);
249 packet_send(); 275 if ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 ||
250 /* packet_write_wait(); */ 276 (r = sshpkt_send(ssh)) != 0)
277 return r;
251 debug("SSH2_MSG_NEWKEYS sent"); 278 debug("SSH2_MSG_NEWKEYS sent");
252
253 debug("expecting SSH2_MSG_NEWKEYS"); 279 debug("expecting SSH2_MSG_NEWKEYS");
254 packet_read_expect(SSH2_MSG_NEWKEYS); 280 ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
255 packet_check_eom(); 281 return 0;
256 debug("SSH2_MSG_NEWKEYS received"); 282}
283
284static int
285kex_input_newkeys(int type, u_int32_t seq, void *ctxt)
286{
287 struct ssh *ssh = ctxt;
288 struct kex *kex = ssh->kex;
289 int r;
257 290
291 debug("SSH2_MSG_NEWKEYS received");
292 ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error);
293 if ((r = sshpkt_get_end(ssh)) != 0)
294 return r;
258 kex->done = 1; 295 kex->done = 1;
259 buffer_clear(&kex->peer); 296 sshbuf_reset(kex->peer);
260 /* buffer_clear(&kex->my); */ 297 /* sshbuf_reset(kex->my); */
261 kex->flags &= ~KEX_INIT_SENT; 298 kex->flags &= ~KEX_INIT_SENT;
262 free(kex->name); 299 free(kex->name);
263 kex->name = NULL; 300 kex->name = NULL;
301 return 0;
264} 302}
265 303
266void 304int
267kex_send_kexinit(Kex *kex) 305kex_send_kexinit(struct ssh *ssh)
268{ 306{
269 u_int32_t rnd = 0;
270 u_char *cookie; 307 u_char *cookie;
271 u_int i; 308 struct kex *kex = ssh->kex;
309 int r;
272 310
273 if (kex == NULL) { 311 if (kex == NULL)
274 error("kex_send_kexinit: no kex, cannot rekey"); 312 return SSH_ERR_INTERNAL_ERROR;
275 return; 313 if (kex->flags & KEX_INIT_SENT)
276 } 314 return 0;
277 if (kex->flags & KEX_INIT_SENT) {
278 debug("KEX_INIT_SENT");
279 return;
280 }
281 kex->done = 0; 315 kex->done = 0;
282 316
283 /* generate a random cookie */ 317 /* generate a random cookie */
284 if (buffer_len(&kex->my) < KEX_COOKIE_LEN) 318 if (sshbuf_len(kex->my) < KEX_COOKIE_LEN)
285 fatal("kex_send_kexinit: kex proposal too short"); 319 return SSH_ERR_INVALID_FORMAT;
286 cookie = buffer_ptr(&kex->my); 320 if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL)
287 for (i = 0; i < KEX_COOKIE_LEN; i++) { 321 return SSH_ERR_INTERNAL_ERROR;
288 if (i % 4 == 0) 322 arc4random_buf(cookie, KEX_COOKIE_LEN);
289 rnd = arc4random(); 323
290 cookie[i] = rnd; 324 if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
291 rnd >>= 8; 325 (r = sshpkt_putb(ssh, kex->my)) != 0 ||
292 } 326 (r = sshpkt_send(ssh)) != 0)
293 packet_start(SSH2_MSG_KEXINIT); 327 return r;
294 packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my));
295 packet_send();
296 debug("SSH2_MSG_KEXINIT sent"); 328 debug("SSH2_MSG_KEXINIT sent");
297 kex->flags |= KEX_INIT_SENT; 329 kex->flags |= KEX_INIT_SENT;
330 return 0;
298} 331}
299 332
300/* ARGSUSED */ 333/* ARGSUSED */
301void 334int
302kex_input_kexinit(int type, u_int32_t seq, void *ctxt) 335kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
303{ 336{
304 char *ptr; 337 struct ssh *ssh = ctxt;
305 u_int i, dlen; 338 struct kex *kex = ssh->kex;
306 Kex *kex = (Kex *)ctxt; 339 const u_char *ptr;
340 u_int i;
341 size_t dlen;
342 int r;
307 343
308 debug("SSH2_MSG_KEXINIT received"); 344 debug("SSH2_MSG_KEXINIT received");
309 if (kex == NULL) 345 if (kex == NULL)
310 fatal("kex_input_kexinit: no kex, cannot rekey"); 346 return SSH_ERR_INVALID_ARGUMENT;
311 347
312 ptr = packet_get_raw(&dlen); 348 ptr = sshpkt_ptr(ssh, &dlen);
313 buffer_append(&kex->peer, ptr, dlen); 349 if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
350 return r;
314 351
315 /* discard packet */ 352 /* discard packet */
316 for (i = 0; i < KEX_COOKIE_LEN; i++) 353 for (i = 0; i < KEX_COOKIE_LEN; i++)
317 packet_get_char(); 354 if ((r = sshpkt_get_u8(ssh, NULL)) != 0)
355 return r;
318 for (i = 0; i < PROPOSAL_MAX; i++) 356 for (i = 0; i < PROPOSAL_MAX; i++)
319 free(packet_get_string(NULL)); 357 if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0)
358 return r;
320 /* 359 /*
321 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported 360 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
322 * KEX method has the server move first, but a server might be using 361 * KEX method has the server move first, but a server might be using
@@ -327,55 +366,129 @@ kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
327 * for cases where the server *doesn't* go first. I guess we should 366 * for cases where the server *doesn't* go first. I guess we should
328 * ignore it when it is set for these cases, which is what we do now. 367 * ignore it when it is set for these cases, which is what we do now.
329 */ 368 */
330 (void) packet_get_char(); /* first_kex_follows */ 369 if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || /* first_kex_follows */
331 (void) packet_get_int(); /* reserved */ 370 (r = sshpkt_get_u32(ssh, NULL)) != 0 || /* reserved */
332 packet_check_eom(); 371 (r = sshpkt_get_end(ssh)) != 0)
372 return r;
373
374 if (!(kex->flags & KEX_INIT_SENT))
375 if ((r = kex_send_kexinit(ssh)) != 0)
376 return r;
377 if ((r = kex_choose_conf(ssh)) != 0)
378 return r;
379
380 if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
381 return (kex->kex[kex->kex_type])(ssh);
333 382
334 kex_kexinit_finish(kex); 383 return SSH_ERR_INTERNAL_ERROR;
335} 384}
336 385
337Kex * 386int
338kex_setup(char *proposal[PROPOSAL_MAX]) 387kex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], struct kex **kexp)
339{ 388{
340 Kex *kex; 389 struct kex *kex;
341 390 int r;
342 kex = xcalloc(1, sizeof(*kex)); 391
343 buffer_init(&kex->peer); 392 *kexp = NULL;
344 buffer_init(&kex->my); 393 if ((kex = calloc(1, sizeof(*kex))) == NULL)
345 kex_prop2buf(&kex->my, proposal); 394 return SSH_ERR_ALLOC_FAIL;
395 if ((kex->peer = sshbuf_new()) == NULL ||
396 (kex->my = sshbuf_new()) == NULL) {
397 r = SSH_ERR_ALLOC_FAIL;
398 goto out;
399 }
400 if ((r = kex_prop2buf(kex->my, proposal)) != 0)
401 goto out;
346 kex->done = 0; 402 kex->done = 0;
403 kex_reset_dispatch(ssh);
404 r = 0;
405 *kexp = kex;
406 out:
407 if (r != 0)
408 kex_free(kex);
409 return r;
410}
347 411
348 kex_send_kexinit(kex); /* we start */ 412void
349 kex_reset_dispatch(); 413kex_free_newkeys(struct newkeys *newkeys)
350 414{
351 return kex; 415 if (newkeys == NULL)
416 return;
417 if (newkeys->enc.key) {
418 explicit_bzero(newkeys->enc.key, newkeys->enc.key_len);
419 free(newkeys->enc.key);
420 newkeys->enc.key = NULL;
421 }
422 if (newkeys->enc.iv) {
423 explicit_bzero(newkeys->enc.iv, newkeys->enc.block_size);
424 free(newkeys->enc.iv);
425 newkeys->enc.iv = NULL;
426 }
427 free(newkeys->enc.name);
428 explicit_bzero(&newkeys->enc, sizeof(newkeys->enc));
429 free(newkeys->comp.name);
430 explicit_bzero(&newkeys->comp, sizeof(newkeys->comp));
431 mac_clear(&newkeys->mac);
432 if (newkeys->mac.key) {
433 explicit_bzero(newkeys->mac.key, newkeys->mac.key_len);
434 free(newkeys->mac.key);
435 newkeys->mac.key = NULL;
436 }
437 free(newkeys->mac.name);
438 explicit_bzero(&newkeys->mac, sizeof(newkeys->mac));
439 explicit_bzero(newkeys, sizeof(*newkeys));
440 free(newkeys);
352} 441}
353 442
354static void 443void
355kex_kexinit_finish(Kex *kex) 444kex_free(struct kex *kex)
356{ 445{
357 if (!(kex->flags & KEX_INIT_SENT)) 446 u_int mode;
358 kex_send_kexinit(kex);
359 447
360 kex_choose_conf(kex); 448#ifdef WITH_OPENSSL
449 if (kex->dh)
450 DH_free(kex->dh);
451#ifdef OPENSSL_HAS_ECC
452 if (kex->ec_client_key)
453 EC_KEY_free(kex->ec_client_key);
454#endif /* OPENSSL_HAS_ECC */
455#endif /* WITH_OPENSSL */
456 for (mode = 0; mode < MODE_MAX; mode++) {
457 kex_free_newkeys(kex->newkeys[mode]);
458 kex->newkeys[mode] = NULL;
459 }
460 sshbuf_free(kex->peer);
461 sshbuf_free(kex->my);
462 free(kex->session_id);
463 free(kex->client_version_string);
464 free(kex->server_version_string);
465 free(kex);
466}
361 467
362 if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX && 468int
363 kex->kex[kex->kex_type] != NULL) { 469kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
364 (kex->kex[kex->kex_type])(kex); 470{
365 } else { 471 int r;
366 fatal("Unsupported key exchange %d", kex->kex_type); 472
473 if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0)
474 return r;
475 if ((r = kex_send_kexinit(ssh)) != 0) { /* we start */
476 kex_free(ssh->kex);
477 ssh->kex = NULL;
478 return r;
367 } 479 }
480 return 0;
368} 481}
369 482
370static void 483static int
371choose_enc(Enc *enc, char *client, char *server) 484choose_enc(struct sshenc *enc, char *client, char *server)
372{ 485{
373 char *name = match_list(client, server, NULL); 486 char *name = match_list(client, server, NULL);
487
374 if (name == NULL) 488 if (name == NULL)
375 fatal("no matching cipher found: client %s server %s", 489 return SSH_ERR_NO_CIPHER_ALG_MATCH;
376 client, server);
377 if ((enc->cipher = cipher_by_name(name)) == NULL) 490 if ((enc->cipher = cipher_by_name(name)) == NULL)
378 fatal("matching cipher is not supported: %s", name); 491 return SSH_ERR_INTERNAL_ERROR;
379 enc->name = name; 492 enc->name = name;
380 enc->enabled = 0; 493 enc->enabled = 0;
381 enc->iv = NULL; 494 enc->iv = NULL;
@@ -383,31 +496,34 @@ choose_enc(Enc *enc, char *client, char *server)
383 enc->key = NULL; 496 enc->key = NULL;
384 enc->key_len = cipher_keylen(enc->cipher); 497 enc->key_len = cipher_keylen(enc->cipher);
385 enc->block_size = cipher_blocksize(enc->cipher); 498 enc->block_size = cipher_blocksize(enc->cipher);
499 return 0;
386} 500}
387 501
388static void 502static int
389choose_mac(Mac *mac, char *client, char *server) 503choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server)
390{ 504{
391 char *name = match_list(client, server, NULL); 505 char *name = match_list(client, server, NULL);
506
392 if (name == NULL) 507 if (name == NULL)
393 fatal("no matching mac found: client %s server %s", 508 return SSH_ERR_NO_MAC_ALG_MATCH;
394 client, server);
395 if (mac_setup(mac, name) < 0) 509 if (mac_setup(mac, name) < 0)
396 fatal("unsupported mac %s", name); 510 return SSH_ERR_INTERNAL_ERROR;
397 /* truncate the key */ 511 /* truncate the key */
398 if (datafellows & SSH_BUG_HMAC) 512 if (ssh->compat & SSH_BUG_HMAC)
399 mac->key_len = 16; 513 mac->key_len = 16;
400 mac->name = name; 514 mac->name = name;
401 mac->key = NULL; 515 mac->key = NULL;
402 mac->enabled = 0; 516 mac->enabled = 0;
517 return 0;
403} 518}
404 519
405static void 520static int
406choose_comp(Comp *comp, char *client, char *server) 521choose_comp(struct sshcomp *comp, char *client, char *server)
407{ 522{
408 char *name = match_list(client, server, NULL); 523 char *name = match_list(client, server, NULL);
524
409 if (name == NULL) 525 if (name == NULL)
410 fatal("no matching comp found: client %s server %s", client, server); 526 return SSH_ERR_NO_COMPRESS_ALG_MATCH;
411 if (strcmp(name, "zlib@openssh.com") == 0) { 527 if (strcmp(name, "zlib@openssh.com") == 0) {
412 comp->type = COMP_DELAYED; 528 comp->type = COMP_DELAYED;
413 } else if (strcmp(name, "zlib") == 0) { 529 } else if (strcmp(name, "zlib") == 0) {
@@ -415,36 +531,42 @@ choose_comp(Comp *comp, char *client, char *server)
415 } else if (strcmp(name, "none") == 0) { 531 } else if (strcmp(name, "none") == 0) {
416 comp->type = COMP_NONE; 532 comp->type = COMP_NONE;
417 } else { 533 } else {
418 fatal("unsupported comp %s", name); 534 return SSH_ERR_INTERNAL_ERROR;
419 } 535 }
420 comp->name = name; 536 comp->name = name;
537 return 0;
421} 538}
422 539
423static void 540static int
424choose_kex(Kex *k, char *client, char *server) 541choose_kex(struct kex *k, char *client, char *server)
425{ 542{
426 const struct kexalg *kexalg; 543 const struct kexalg *kexalg;
427 544
428 k->name = match_list(client, server, NULL); 545 k->name = match_list(client, server, NULL);
546
429 if (k->name == NULL) 547 if (k->name == NULL)
430 fatal("Unable to negotiate a key exchange method"); 548 return SSH_ERR_NO_KEX_ALG_MATCH;
431 if ((kexalg = kex_alg_by_name(k->name)) == NULL) 549 if ((kexalg = kex_alg_by_name(k->name)) == NULL)
432 fatal("unsupported kex alg %s", k->name); 550 return SSH_ERR_INTERNAL_ERROR;
433 k->kex_type = kexalg->type; 551 k->kex_type = kexalg->type;
434 k->hash_alg = kexalg->hash_alg; 552 k->hash_alg = kexalg->hash_alg;
435 k->ec_nid = kexalg->ec_nid; 553 k->ec_nid = kexalg->ec_nid;
554 return 0;
436} 555}
437 556
438static void 557static int
439choose_hostkeyalg(Kex *k, char *client, char *server) 558choose_hostkeyalg(struct kex *k, char *client, char *server)
440{ 559{
441 char *hostkeyalg = match_list(client, server, NULL); 560 char *hostkeyalg = match_list(client, server, NULL);
561
442 if (hostkeyalg == NULL) 562 if (hostkeyalg == NULL)
443 fatal("no hostkey alg"); 563 return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
444 k->hostkey_type = key_type_from_name(hostkeyalg); 564 k->hostkey_type = sshkey_type_from_name(hostkeyalg);
445 if (k->hostkey_type == KEY_UNSPEC) 565 if (k->hostkey_type == KEY_UNSPEC)
446 fatal("bad hostkey alg '%s'", hostkeyalg); 566 return SSH_ERR_INTERNAL_ERROR;
567 k->hostkey_nid = sshkey_ecdsa_nid_from_name(hostkeyalg);
447 free(hostkeyalg); 568 free(hostkeyalg);
569 return 0;
448} 570}
449 571
450static int 572static int
@@ -471,18 +593,20 @@ proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
471 return (1); 593 return (1);
472} 594}
473 595
474static void 596static int
475kex_choose_conf(Kex *kex) 597kex_choose_conf(struct ssh *ssh)
476{ 598{
477 Newkeys *newkeys; 599 struct kex *kex = ssh->kex;
478 char **my, **peer; 600 struct newkeys *newkeys;
601 char **my = NULL, **peer = NULL;
479 char **cprop, **sprop; 602 char **cprop, **sprop;
480 int nenc, nmac, ncomp; 603 int nenc, nmac, ncomp;
481 u_int mode, ctos, need, dh_need, authlen; 604 u_int mode, ctos, need, dh_need, authlen;
482 int first_kex_follows, type; 605 int r, first_kex_follows;
483 606
484 my = kex_buf2prop(&kex->my, NULL); 607 if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0 ||
485 peer = kex_buf2prop(&kex->peer, &first_kex_follows); 608 (r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)
609 goto out;
486 610
487 if (kex->server) { 611 if (kex->server) {
488 cprop=peer; 612 cprop=peer;
@@ -494,8 +618,9 @@ kex_choose_conf(Kex *kex)
494 618
495 /* Check whether server offers roaming */ 619 /* Check whether server offers roaming */
496 if (!kex->server) { 620 if (!kex->server) {
497 char *roaming; 621 char *roaming = match_list(KEX_RESUME,
498 roaming = match_list(KEX_RESUME, peer[PROPOSAL_KEX_ALGS], NULL); 622 peer[PROPOSAL_KEX_ALGS], NULL);
623
499 if (roaming) { 624 if (roaming) {
500 kex->roaming = 1; 625 kex->roaming = 1;
501 free(roaming); 626 free(roaming);
@@ -504,28 +629,39 @@ kex_choose_conf(Kex *kex)
504 629
505 /* Algorithm Negotiation */ 630 /* Algorithm Negotiation */
506 for (mode = 0; mode < MODE_MAX; mode++) { 631 for (mode = 0; mode < MODE_MAX; mode++) {
507 newkeys = xcalloc(1, sizeof(*newkeys)); 632 if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) {
633 r = SSH_ERR_ALLOC_FAIL;
634 goto out;
635 }
508 kex->newkeys[mode] = newkeys; 636 kex->newkeys[mode] = newkeys;
509 ctos = (!kex->server && mode == MODE_OUT) || 637 ctos = (!kex->server && mode == MODE_OUT) ||
510 (kex->server && mode == MODE_IN); 638 (kex->server && mode == MODE_IN);
511 nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; 639 nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC;
512 nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; 640 nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC;
513 ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; 641 ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
514 choose_enc(&newkeys->enc, cprop[nenc], sprop[nenc]); 642 if ((r = choose_enc(&newkeys->enc, cprop[nenc],
515 /* ignore mac for authenticated encryption */ 643 sprop[nenc])) != 0)
644 goto out;
516 authlen = cipher_authlen(newkeys->enc.cipher); 645 authlen = cipher_authlen(newkeys->enc.cipher);
517 if (authlen == 0) 646 /* ignore mac for authenticated encryption */
518 choose_mac(&newkeys->mac, cprop[nmac], sprop[nmac]); 647 if (authlen == 0 &&
519 choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]); 648 (r = choose_mac(ssh, &newkeys->mac, cprop[nmac],
649 sprop[nmac])) != 0)
650 goto out;
651 if ((r = choose_comp(&newkeys->comp, cprop[ncomp],
652 sprop[ncomp])) != 0)
653 goto out;
520 debug("kex: %s %s %s %s", 654 debug("kex: %s %s %s %s",
521 ctos ? "client->server" : "server->client", 655 ctos ? "client->server" : "server->client",
522 newkeys->enc.name, 656 newkeys->enc.name,
523 authlen == 0 ? newkeys->mac.name : "<implicit>", 657 authlen == 0 ? newkeys->mac.name : "<implicit>",
524 newkeys->comp.name); 658 newkeys->comp.name);
525 } 659 }
526 choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); 660 if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
527 choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], 661 sprop[PROPOSAL_KEX_ALGS])) != 0 ||
528 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); 662 (r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
663 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0)
664 goto out;
529 need = dh_need = 0; 665 need = dh_need = 0;
530 for (mode = 0; mode < MODE_MAX; mode++) { 666 for (mode = 0; mode < MODE_MAX; mode++) {
531 newkeys = kex->newkeys[mode]; 667 newkeys = kex->newkeys[mode];
@@ -544,45 +680,47 @@ kex_choose_conf(Kex *kex)
544 680
545 /* ignore the next message if the proposals do not match */ 681 /* ignore the next message if the proposals do not match */
546 if (first_kex_follows && !proposals_match(my, peer) && 682 if (first_kex_follows && !proposals_match(my, peer) &&
547 !(datafellows & SSH_BUG_FIRSTKEX)) { 683 !(ssh->compat & SSH_BUG_FIRSTKEX))
548 type = packet_read(); 684 ssh->dispatch_skip_packets = 1;
549 debug2("skipping next packet (type %u)", type); 685 r = 0;
550 } 686 out:
551
552 kex_prop_free(my); 687 kex_prop_free(my);
553 kex_prop_free(peer); 688 kex_prop_free(peer);
689 return r;
554} 690}
555 691
556static u_char * 692static int
557derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen, 693derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
558 const u_char *shared_secret, u_int slen) 694 const struct sshbuf *shared_secret, u_char **keyp)
559{ 695{
560 Buffer b; 696 struct kex *kex = ssh->kex;
561 struct ssh_digest_ctx *hashctx; 697 struct ssh_digest_ctx *hashctx = NULL;
562 char c = id; 698 char c = id;
563 u_int have; 699 u_int have;
564 size_t mdsz; 700 size_t mdsz;
565 u_char *digest; 701 u_char *digest;
702 int r;
566 703
567 if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0) 704 if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
568 fatal("bad kex md size %zu", mdsz); 705 return SSH_ERR_INVALID_ARGUMENT;
569 digest = xmalloc(roundup(need, mdsz)); 706 if ((digest = calloc(1, roundup(need, mdsz))) == NULL) {
570 707 r = SSH_ERR_ALLOC_FAIL;
571 buffer_init(&b); 708 goto out;
572 buffer_append(&b, shared_secret, slen); 709 }
573 710
574 /* K1 = HASH(K || H || "A" || session_id) */ 711 /* K1 = HASH(K || H || "A" || session_id) */
575 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL) 712 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
576 fatal("%s: ssh_digest_start failed", __func__); 713 ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
577 if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
578 ssh_digest_update(hashctx, hash, hashlen) != 0 || 714 ssh_digest_update(hashctx, hash, hashlen) != 0 ||
579 ssh_digest_update(hashctx, &c, 1) != 0 || 715 ssh_digest_update(hashctx, &c, 1) != 0 ||
580 ssh_digest_update(hashctx, kex->session_id, 716 ssh_digest_update(hashctx, kex->session_id,
581 kex->session_id_len) != 0) 717 kex->session_id_len) != 0 ||
582 fatal("%s: ssh_digest_update failed", __func__); 718 ssh_digest_final(hashctx, digest, mdsz) != 0) {
583 if (ssh_digest_final(hashctx, digest, mdsz) != 0) 719 r = SSH_ERR_LIBCRYPTO_ERROR;
584 fatal("%s: ssh_digest_final failed", __func__); 720 goto out;
721 }
585 ssh_digest_free(hashctx); 722 ssh_digest_free(hashctx);
723 hashctx = NULL;
586 724
587 /* 725 /*
588 * expand key: 726 * expand key:
@@ -590,107 +728,115 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
590 * Key = K1 || K2 || ... || Kn 728 * Key = K1 || K2 || ... || Kn
591 */ 729 */
592 for (have = mdsz; need > have; have += mdsz) { 730 for (have = mdsz; need > have; have += mdsz) {
593 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL) 731 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
594 fatal("%s: ssh_digest_start failed", __func__); 732 ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
595 if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
596 ssh_digest_update(hashctx, hash, hashlen) != 0 || 733 ssh_digest_update(hashctx, hash, hashlen) != 0 ||
597 ssh_digest_update(hashctx, digest, have) != 0) 734 ssh_digest_update(hashctx, digest, have) != 0 ||
598 fatal("%s: ssh_digest_update failed", __func__); 735 ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
599 if (ssh_digest_final(hashctx, digest + have, mdsz) != 0) 736 r = SSH_ERR_LIBCRYPTO_ERROR;
600 fatal("%s: ssh_digest_final failed", __func__); 737 goto out;
738 }
601 ssh_digest_free(hashctx); 739 ssh_digest_free(hashctx);
740 hashctx = NULL;
602 } 741 }
603 buffer_free(&b);
604#ifdef DEBUG_KEX 742#ifdef DEBUG_KEX
605 fprintf(stderr, "key '%c'== ", c); 743 fprintf(stderr, "key '%c'== ", c);
606 dump_digest("key", digest, need); 744 dump_digest("key", digest, need);
607#endif 745#endif
608 return digest; 746 *keyp = digest;
747 digest = NULL;
748 r = 0;
749 out:
750 if (digest)
751 free(digest);
752 ssh_digest_free(hashctx);
753 return r;
609} 754}
610 755
611Newkeys *current_keys[MODE_MAX];
612
613#define NKEYS 6 756#define NKEYS 6
614void 757int
615kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, 758kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
616 const u_char *shared_secret, u_int slen) 759 const struct sshbuf *shared_secret)
617{ 760{
761 struct kex *kex = ssh->kex;
618 u_char *keys[NKEYS]; 762 u_char *keys[NKEYS];
619 u_int i, mode, ctos; 763 u_int i, j, mode, ctos;
764 int r;
620 765
621 for (i = 0; i < NKEYS; i++) { 766 for (i = 0; i < NKEYS; i++) {
622 keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen, 767 if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen,
623 shared_secret, slen); 768 shared_secret, &keys[i])) != 0) {
769 for (j = 0; j < i; j++)
770 free(keys[j]);
771 return r;
772 }
624 } 773 }
625
626 debug2("kex_derive_keys");
627 for (mode = 0; mode < MODE_MAX; mode++) { 774 for (mode = 0; mode < MODE_MAX; mode++) {
628 current_keys[mode] = kex->newkeys[mode];
629 kex->newkeys[mode] = NULL;
630 ctos = (!kex->server && mode == MODE_OUT) || 775 ctos = (!kex->server && mode == MODE_OUT) ||
631 (kex->server && mode == MODE_IN); 776 (kex->server && mode == MODE_IN);
632 current_keys[mode]->enc.iv = keys[ctos ? 0 : 1]; 777 kex->newkeys[mode]->enc.iv = keys[ctos ? 0 : 1];
633 current_keys[mode]->enc.key = keys[ctos ? 2 : 3]; 778 kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];
634 current_keys[mode]->mac.key = keys[ctos ? 4 : 5]; 779 kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];
635 } 780 }
781 return 0;
636} 782}
637 783
638#ifdef WITH_OPENSSL 784#ifdef WITH_OPENSSL
639void 785int
640kex_derive_keys_bn(Kex *kex, u_char *hash, u_int hashlen, const BIGNUM *secret) 786kex_derive_keys_bn(struct ssh *ssh, u_char *hash, u_int hashlen,
787 const BIGNUM *secret)
641{ 788{
642 Buffer shared_secret; 789 struct sshbuf *shared_secret;
643 790 int r;
644 buffer_init(&shared_secret); 791
645 buffer_put_bignum2(&shared_secret, secret); 792 if ((shared_secret = sshbuf_new()) == NULL)
646 kex_derive_keys(kex, hash, hashlen, 793 return SSH_ERR_ALLOC_FAIL;
647 buffer_ptr(&shared_secret), buffer_len(&shared_secret)); 794 if ((r = sshbuf_put_bignum2(shared_secret, secret)) == 0)
648 buffer_free(&shared_secret); 795 r = kex_derive_keys(ssh, hash, hashlen, shared_secret);
796 sshbuf_free(shared_secret);
797 return r;
649} 798}
650#endif 799#endif
651 800
652Newkeys *
653kex_get_newkeys(int mode)
654{
655 Newkeys *ret;
656
657 ret = current_keys[mode];
658 current_keys[mode] = NULL;
659 return ret;
660}
661
662#ifdef WITH_SSH1 801#ifdef WITH_SSH1
663void 802int
664derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, 803derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
665 u_int8_t cookie[8], u_int8_t id[16]) 804 u_int8_t cookie[8], u_int8_t id[16])
666{ 805{
667 u_int8_t nbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH]; 806 u_int8_t hbuf[2048], sbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
668 int len; 807 struct ssh_digest_ctx *hashctx = NULL;
669 struct ssh_digest_ctx *hashctx; 808 size_t hlen, slen;
670 809 int r;
671 if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) 810
672 fatal("%s: ssh_digest_start", __func__); 811 hlen = BN_num_bytes(host_modulus);
673 812 slen = BN_num_bytes(server_modulus);
674 len = BN_num_bytes(host_modulus); 813 if (hlen < (512 / 8) || (u_int)hlen > sizeof(hbuf) ||
675 if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) 814 slen < (512 / 8) || (u_int)slen > sizeof(sbuf))
676 fatal("%s: bad host modulus (len %d)", __func__, len); 815 return SSH_ERR_KEY_BITS_MISMATCH;
677 BN_bn2bin(host_modulus, nbuf); 816 if (BN_bn2bin(host_modulus, hbuf) <= 0 ||
678 if (ssh_digest_update(hashctx, nbuf, len) != 0) 817 BN_bn2bin(server_modulus, sbuf) <= 0) {
679 fatal("%s: ssh_digest_update failed", __func__); 818 r = SSH_ERR_LIBCRYPTO_ERROR;
680 819 goto out;
681 len = BN_num_bytes(server_modulus); 820 }
682 if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) 821 if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) {
683 fatal("%s: bad server modulus (len %d)", __func__, len); 822 r = SSH_ERR_ALLOC_FAIL;
684 BN_bn2bin(server_modulus, nbuf); 823 goto out;
685 if (ssh_digest_update(hashctx, nbuf, len) != 0 || 824 }
686 ssh_digest_update(hashctx, cookie, 8) != 0) 825 if (ssh_digest_update(hashctx, hbuf, hlen) != 0 ||
687 fatal("%s: ssh_digest_update failed", __func__); 826 ssh_digest_update(hashctx, sbuf, slen) != 0 ||
688 if (ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) 827 ssh_digest_update(hashctx, cookie, 8) != 0 ||
689 fatal("%s: ssh_digest_final failed", __func__); 828 ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) {
829 r = SSH_ERR_LIBCRYPTO_ERROR;
830 goto out;
831 }
690 memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5)); 832 memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
691 833 r = 0;
692 explicit_bzero(nbuf, sizeof(nbuf)); 834 out:
835 ssh_digest_free(hashctx);
836 explicit_bzero(hbuf, sizeof(hbuf));
837 explicit_bzero(sbuf, sizeof(sbuf));
693 explicit_bzero(obuf, sizeof(obuf)); 838 explicit_bzero(obuf, sizeof(obuf));
839 return r;
694} 840}
695#endif 841#endif
696 842
@@ -698,16 +844,7 @@ derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
698void 844void
699dump_digest(char *msg, u_char *digest, int len) 845dump_digest(char *msg, u_char *digest, int len)
700{ 846{
701 int i;
702
703 fprintf(stderr, "%s\n", msg); 847 fprintf(stderr, "%s\n", msg);
704 for (i = 0; i < len; i++) { 848 sshbuf_dump_data(digest, len, stderr);
705 fprintf(stderr, "%02x", digest[i]);
706 if (i%32 == 31)
707 fprintf(stderr, "\n");
708 else if (i%8 == 7)
709 fprintf(stderr, " ");
710 }
711 fprintf(stderr, "\n");
712} 849}
713#endif 850#endif