View | Details | Raw Unified | Return to bug 3063
Collapse All | Expand All

(-)a/kex.c (-21 / +62 lines)
Lines 334-351 kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp) Link Here
334
		r = SSH_ERR_ALLOC_FAIL;
334
		r = SSH_ERR_ALLOC_FAIL;
335
		goto out;
335
		goto out;
336
	}
336
	}
337
	if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */
337
	if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) { /* skip cookie */
338
		error("%s: consume cookie: %s", __func__, ssh_err(r));
338
		goto out;
339
		goto out;
340
	}
339
	/* extract kex init proposal strings */
341
	/* extract kex init proposal strings */
340
	for (i = 0; i < PROPOSAL_MAX; i++) {
342
	for (i = 0; i < PROPOSAL_MAX; i++) {
341
		if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0)
343
		if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) {
344
			error("%s: parse proposal %u: %s", __func__,
345
			    i, ssh_err(r));
342
			goto out;
346
			goto out;
347
		}
343
		debug2("%s: %s", proposal_names[i], proposal[i]);
348
		debug2("%s: %s", proposal_names[i], proposal[i]);
344
	}
349
	}
345
	/* first kex follows / reserved */
350
	/* first kex follows / reserved */
346
	if ((r = sshbuf_get_u8(b, &v)) != 0 ||	/* first_kex_follows */
351
	if ((r = sshbuf_get_u8(b, &v)) != 0 ||	/* first_kex_follows */
347
	    (r = sshbuf_get_u32(b, &i)) != 0)	/* reserved */
352
	    (r = sshbuf_get_u32(b, &i)) != 0) {	/* reserved */
353
		error("%s: parse: %s", __func__, ssh_err(r));
348
		goto out;
354
		goto out;
355
	}
349
	if (first_kex_follows != NULL)
356
	if (first_kex_follows != NULL)
350
		*first_kex_follows = v;
357
		*first_kex_follows = v;
351
	debug2("first_kex_follows %d ", v);
358
	debug2("first_kex_follows %d ", v);
Lines 398-403 kex_send_ext_info(struct ssh *ssh) Link Here
398
	int r;
405
	int r;
399
	char *algs;
406
	char *algs;
400
407
408
	debug("Sending SSH2_MSG_EXT_INFO");
401
	if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
409
	if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
402
		return SSH_ERR_ALLOC_FAIL;
410
		return SSH_ERR_ALLOC_FAIL;
403
	/* XXX filter algs list by allowed pubkey/hostbased types */
411
	/* XXX filter algs list by allowed pubkey/hostbased types */
Lines 405-412 kex_send_ext_info(struct ssh *ssh) Link Here
405
	    (r = sshpkt_put_u32(ssh, 1)) != 0 ||
413
	    (r = sshpkt_put_u32(ssh, 1)) != 0 ||
406
	    (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
414
	    (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
407
	    (r = sshpkt_put_cstring(ssh, algs)) != 0 ||
415
	    (r = sshpkt_put_cstring(ssh, algs)) != 0 ||
408
	    (r = sshpkt_send(ssh)) != 0)
416
	    (r = sshpkt_send(ssh)) != 0) {
417
		error("%s: compose: %s", __func__, ssh_err(r));
409
		goto out;
418
		goto out;
419
	}
410
	/* success */
420
	/* success */
411
	r = 0;
421
	r = 0;
412
 out:
422
 out:
Lines 424-434 kex_send_newkeys(struct ssh *ssh) Link Here
424
	    (r = sshpkt_send(ssh)) != 0)
434
	    (r = sshpkt_send(ssh)) != 0)
425
		return r;
435
		return r;
426
	debug("SSH2_MSG_NEWKEYS sent");
436
	debug("SSH2_MSG_NEWKEYS sent");
427
	debug("expecting SSH2_MSG_NEWKEYS");
428
	ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
437
	ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
429
	if (ssh->kex->ext_info_c)
438
	if (ssh->kex->ext_info_c && (ssh->kex->flags & KEX_INITIAL) != 0)
430
		if ((r = kex_send_ext_info(ssh)) != 0)
439
		if ((r = kex_send_ext_info(ssh)) != 0)
431
			return r;
440
			return r;
441
	debug("expecting SSH2_MSG_NEWKEYS");
432
	return 0;
442
	return 0;
433
}
443
}
434
444
Lines 500-522 kex_send_kexinit(struct ssh *ssh) Link Here
500
	struct kex *kex = ssh->kex;
510
	struct kex *kex = ssh->kex;
501
	int r;
511
	int r;
502
512
503
	if (kex == NULL)
513
	if (kex == NULL) {
514
		error("%s: no hex", __func__);
504
		return SSH_ERR_INTERNAL_ERROR;
515
		return SSH_ERR_INTERNAL_ERROR;
516
	}
505
	if (kex->flags & KEX_INIT_SENT)
517
	if (kex->flags & KEX_INIT_SENT)
506
		return 0;
518
		return 0;
507
	kex->done = 0;
519
	kex->done = 0;
508
520
509
	/* generate a random cookie */
521
	/* generate a random cookie */
510
	if (sshbuf_len(kex->my) < KEX_COOKIE_LEN)
522
	if (sshbuf_len(kex->my) < KEX_COOKIE_LEN) {
523
		error("%s: bad kex length: %zu < %d", __func__,
524
		    sshbuf_len(kex->my), KEX_COOKIE_LEN);
511
		return SSH_ERR_INVALID_FORMAT;
525
		return SSH_ERR_INVALID_FORMAT;
512
	if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL)
526
	}
527
	if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL) {
528
		error("%s: buffer error", __func__);
513
		return SSH_ERR_INTERNAL_ERROR;
529
		return SSH_ERR_INTERNAL_ERROR;
530
	}
514
	arc4random_buf(cookie, KEX_COOKIE_LEN);
531
	arc4random_buf(cookie, KEX_COOKIE_LEN);
515
532
516
	if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
533
	if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
517
	    (r = sshpkt_putb(ssh, kex->my)) != 0 ||
534
	    (r = sshpkt_putb(ssh, kex->my)) != 0 ||
518
	    (r = sshpkt_send(ssh)) != 0)
535
	    (r = sshpkt_send(ssh)) != 0) {
536
		error("%s: compose reply: %s", __func__, ssh_err(r));
519
		return r;
537
		return r;
538
	}
520
	debug("SSH2_MSG_KEXINIT sent");
539
	debug("SSH2_MSG_KEXINIT sent");
521
	kex->flags |= KEX_INIT_SENT;
540
	kex->flags |= KEX_INIT_SENT;
522
	return 0;
541
	return 0;
Lines 533-553 kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh) Link Here
533
	int r;
552
	int r;
534
553
535
	debug("SSH2_MSG_KEXINIT received");
554
	debug("SSH2_MSG_KEXINIT received");
536
	if (kex == NULL)
555
	if (kex == NULL) {
537
		return SSH_ERR_INVALID_ARGUMENT;
556
		error("%s: no hex", __func__);
538
557
		return SSH_ERR_INTERNAL_ERROR;
558
	}
539
	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
559
	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
540
	ptr = sshpkt_ptr(ssh, &dlen);
560
	ptr = sshpkt_ptr(ssh, &dlen);
541
	if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
561
	if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
542
		return r;
562
		return r;
543
563
544
	/* discard packet */
564
	/* discard packet */
545
	for (i = 0; i < KEX_COOKIE_LEN; i++)
565
	for (i = 0; i < KEX_COOKIE_LEN; i++) {
546
		if ((r = sshpkt_get_u8(ssh, NULL)) != 0)
566
		if ((r = sshpkt_get_u8(ssh, NULL)) != 0) {
567
			error("%s: discard cookie: %s", __func__, ssh_err(r));
547
			return r;
568
			return r;
548
	for (i = 0; i < PROPOSAL_MAX; i++)
569
		}
549
		if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0)
570
	}
571
	for (i = 0; i < PROPOSAL_MAX; i++) {
572
		if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
573
			error("%s: discard proposal: %s", __func__, ssh_err(r));
550
			return r;
574
			return r;
575
		}
576
	}
551
	/*
577
	/*
552
	 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
578
	 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
553
	 * KEX method has the server move first, but a server might be using
579
	 * KEX method has the server move first, but a server might be using
Lines 572-577 kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh) Link Here
572
	if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
598
	if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
573
		return (kex->kex[kex->kex_type])(ssh);
599
		return (kex->kex[kex->kex_type])(ssh);
574
600
601
	error("%s: unknown kex type %u", __func__, kex->kex_type);
575
	return SSH_ERR_INTERNAL_ERROR;
602
	return SSH_ERR_INTERNAL_ERROR;
576
}
603
}
577
604
Lines 705-710 choose_enc(struct sshenc *enc, char *client, char *server) Link Here
705
	if (name == NULL)
732
	if (name == NULL)
706
		return SSH_ERR_NO_CIPHER_ALG_MATCH;
733
		return SSH_ERR_NO_CIPHER_ALG_MATCH;
707
	if ((enc->cipher = cipher_by_name(name)) == NULL) {
734
	if ((enc->cipher = cipher_by_name(name)) == NULL) {
735
		error("%s: unsupported cipher %s", __func__, name);
708
		free(name);
736
		free(name);
709
		return SSH_ERR_INTERNAL_ERROR;
737
		return SSH_ERR_INTERNAL_ERROR;
710
	}
738
	}
Lines 726-731 choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) Link Here
726
	if (name == NULL)
754
	if (name == NULL)
727
		return SSH_ERR_NO_MAC_ALG_MATCH;
755
		return SSH_ERR_NO_MAC_ALG_MATCH;
728
	if (mac_setup(mac, name) < 0) {
756
	if (mac_setup(mac, name) < 0) {
757
		error("%s: unsupported MAC %s", __func__, name);
729
		free(name);
758
		free(name);
730
		return SSH_ERR_INTERNAL_ERROR;
759
		return SSH_ERR_INTERNAL_ERROR;
731
	}
760
	}
Lines 749-754 choose_comp(struct sshcomp *comp, char *client, char *server) Link Here
749
	} else if (strcmp(name, "none") == 0) {
778
	} else if (strcmp(name, "none") == 0) {
750
		comp->type = COMP_NONE;
779
		comp->type = COMP_NONE;
751
	} else {
780
	} else {
781
		error("%s: unsupported compression scheme %s", __func__, name);
752
		free(name);
782
		free(name);
753
		return SSH_ERR_INTERNAL_ERROR;
783
		return SSH_ERR_INTERNAL_ERROR;
754
	}
784
	}
Lines 766-773 choose_kex(struct kex *k, char *client, char *server) Link Here
766
	debug("kex: algorithm: %s", k->name ? k->name : "(no match)");
796
	debug("kex: algorithm: %s", k->name ? k->name : "(no match)");
767
	if (k->name == NULL)
797
	if (k->name == NULL)
768
		return SSH_ERR_NO_KEX_ALG_MATCH;
798
		return SSH_ERR_NO_KEX_ALG_MATCH;
769
	if ((kexalg = kex_alg_by_name(k->name)) == NULL)
799
	if ((kexalg = kex_alg_by_name(k->name)) == NULL) {
800
		error("%s: unsupported KEX method %s", __func__, k->name);
770
		return SSH_ERR_INTERNAL_ERROR;
801
		return SSH_ERR_INTERNAL_ERROR;
802
	}
771
	k->kex_type = kexalg->type;
803
	k->kex_type = kexalg->type;
772
	k->hash_alg = kexalg->hash_alg;
804
	k->hash_alg = kexalg->hash_alg;
773
	k->ec_nid = kexalg->ec_nid;
805
	k->ec_nid = kexalg->ec_nid;
Lines 784-791 choose_hostkeyalg(struct kex *k, char *client, char *server) Link Here
784
	if (k->hostkey_alg == NULL)
816
	if (k->hostkey_alg == NULL)
785
		return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
817
		return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
786
	k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
818
	k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
787
	if (k->hostkey_type == KEY_UNSPEC)
819
	if (k->hostkey_type == KEY_UNSPEC) {
820
		error("%s: unsupported hostkey algorithm %s", __func__,
821
		    k->hostkey_alg);
788
		return SSH_ERR_INTERNAL_ERROR;
822
		return SSH_ERR_INTERNAL_ERROR;
823
	}
789
	k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
824
	k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
790
	return 0;
825
	return 0;
791
}
826
}
Lines 954-959 derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, Link Here
954
	    kex->session_id_len) != 0 ||
989
	    kex->session_id_len) != 0 ||
955
	    ssh_digest_final(hashctx, digest, mdsz) != 0) {
990
	    ssh_digest_final(hashctx, digest, mdsz) != 0) {
956
		r = SSH_ERR_LIBCRYPTO_ERROR;
991
		r = SSH_ERR_LIBCRYPTO_ERROR;
992
		error("%s: KEX hash failed", __func__);
957
		goto out;
993
		goto out;
958
	}
994
	}
959
	ssh_digest_free(hashctx);
995
	ssh_digest_free(hashctx);
Lines 970-975 derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, Link Here
970
		    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
1006
		    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
971
		    ssh_digest_update(hashctx, digest, have) != 0 ||
1007
		    ssh_digest_update(hashctx, digest, have) != 0 ||
972
		    ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
1008
		    ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
1009
			error("%s: KDF failed", __func__);
973
			r = SSH_ERR_LIBCRYPTO_ERROR;
1010
			r = SSH_ERR_LIBCRYPTO_ERROR;
974
			goto out;
1011
			goto out;
975
		}
1012
		}
Lines 1033-1040 kex_load_hostkey(struct ssh *ssh, struct sshkey **prvp, struct sshkey **pubp) Link Here
1033
	*pubp = NULL;
1070
	*pubp = NULL;
1034
	*prvp = NULL;
1071
	*prvp = NULL;
1035
	if (kex->load_host_public_key == NULL ||
1072
	if (kex->load_host_public_key == NULL ||
1036
	    kex->load_host_private_key == NULL)
1073
	    kex->load_host_private_key == NULL) {
1074
		error("%s: missing hostkey loader", __func__);
1037
		return SSH_ERR_INVALID_ARGUMENT;
1075
		return SSH_ERR_INVALID_ARGUMENT;
1076
	}
1038
	*pubp = kex->load_host_public_key(kex->hostkey_type,
1077
	*pubp = kex->load_host_public_key(kex->hostkey_type,
1039
	    kex->hostkey_nid, ssh);
1078
	    kex->hostkey_nid, ssh);
1040
	*prvp = kex->load_host_private_key(kex->hostkey_type,
1079
	*prvp = kex->load_host_private_key(kex->hostkey_type,
Lines 1049-1056 kex_verify_host_key(struct ssh *ssh, struct sshkey *server_host_key) Link Here
1049
{
1088
{
1050
	struct kex *kex = ssh->kex;
1089
	struct kex *kex = ssh->kex;
1051
1090
1052
	if (kex->verify_host_key == NULL)
1091
	if (kex->verify_host_key == NULL) {
1092
		error("%s: missing hostkey verifier", __func__);
1053
		return SSH_ERR_INVALID_ARGUMENT;
1093
		return SSH_ERR_INVALID_ARGUMENT;
1094
	}
1054
	if (server_host_key->type != kex->hostkey_type ||
1095
	if (server_host_key->type != kex->hostkey_type ||
1055
	    (kex->hostkey_type == KEY_ECDSA &&
1096
	    (kex->hostkey_type == KEY_ECDSA &&
1056
	    server_host_key->ecdsa_nid != kex->hostkey_nid))
1097
	    server_host_key->ecdsa_nid != kex->hostkey_nid))

Return to bug 3063