summaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
authormarkus@openbsd.org <markus@openbsd.org>2015-12-04 16:41:28 +0000
committerDamien Miller <djm@mindrot.org>2015-12-07 12:38:58 +1100
commit76c9fbbe35aabc1db977fb78e827644345e9442e (patch)
treee7c85e7e1471f1bd00b3a50a58e315c055f40b86 /kex.c
parent6064a8b8295cb5a17b5ebcfade53053377714f40 (diff)
upstream commit
implement SHA2-{256,512} for RSASSA-PKCS1-v1_5 signatures (user and host auth) based on draft-rsa-dsa-sha2-256-03.txt and draft-ssh-ext-info-04.txt; with & ok djm@ Upstream-ID: cf82ce532b2733e5c4b34bb7b7c94835632db309
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c82
1 files changed, 75 insertions, 7 deletions
diff --git a/kex.c b/kex.c
index b409f276b..c1371c432 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.c,v 1.112 2015/11/13 04:39:35 djm Exp $ */ 1/* $OpenBSD: kex.c,v 1.113 2015/12/04 16:41:28 markus 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 *
@@ -334,6 +334,20 @@ kex_reset_dispatch(struct ssh *ssh)
334 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); 334 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
335} 335}
336 336
337static int
338kex_send_ext_info(struct ssh *ssh)
339{
340 int r;
341
342 if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
343 (r = sshpkt_put_u32(ssh, 1)) != 0 ||
344 (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
345 (r = sshpkt_put_cstring(ssh, "rsa-sha2-256,rsa-sha2-512")) != 0 ||
346 (r = sshpkt_send(ssh)) != 0)
347 return r;
348 return 0;
349}
350
337int 351int
338kex_send_newkeys(struct ssh *ssh) 352kex_send_newkeys(struct ssh *ssh)
339{ 353{
@@ -346,9 +360,51 @@ kex_send_newkeys(struct ssh *ssh)
346 debug("SSH2_MSG_NEWKEYS sent"); 360 debug("SSH2_MSG_NEWKEYS sent");
347 debug("expecting SSH2_MSG_NEWKEYS"); 361 debug("expecting SSH2_MSG_NEWKEYS");
348 ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys); 362 ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
363 if (ssh->kex->ext_info_c)
364 if ((r = kex_send_ext_info(ssh)) != 0)
365 return r;
349 return 0; 366 return 0;
350} 367}
351 368
369int
370kex_input_ext_info(int type, u_int32_t seq, void *ctxt)
371{
372 struct ssh *ssh = ctxt;
373 struct kex *kex = ssh->kex;
374 u_int32_t i, ninfo;
375 char *name, *val, *found;
376 int r;
377
378 debug("SSH2_MSG_EXT_INFO received");
379 ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error);
380 if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0)
381 return r;
382 for (i = 0; i < ninfo; i++) {
383 if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0)
384 return r;
385 if ((r = sshpkt_get_cstring(ssh, &val, NULL)) != 0) {
386 free(name);
387 return r;
388 }
389 debug("%s: %s=<%s>", __func__, name, val);
390 if (strcmp(name, "server-sig-algs") == 0) {
391 found = match_list("rsa-sha2-256", val, NULL);
392 if (found) {
393 kex->rsa_sha2 = 256;
394 free(found);
395 }
396 found = match_list("rsa-sha2-512", val, NULL);
397 if (found) {
398 kex->rsa_sha2 = 512;
399 free(found);
400 }
401 }
402 free(name);
403 free(val);
404 }
405 return sshpkt_get_end(ssh);
406}
407
352static int 408static int
353kex_input_newkeys(int type, u_int32_t seq, void *ctxt) 409kex_input_newkeys(int type, u_int32_t seq, void *ctxt)
354{ 410{
@@ -531,6 +587,8 @@ kex_free(struct kex *kex)
531 free(kex->client_version_string); 587 free(kex->client_version_string);
532 free(kex->server_version_string); 588 free(kex->server_version_string);
533 free(kex->failed_choice); 589 free(kex->failed_choice);
590 free(kex->hostkey_alg);
591 free(kex->name);
534 free(kex); 592 free(kex);
535} 593}
536 594
@@ -627,17 +685,16 @@ choose_kex(struct kex *k, char *client, char *server)
627static int 685static int
628choose_hostkeyalg(struct kex *k, char *client, char *server) 686choose_hostkeyalg(struct kex *k, char *client, char *server)
629{ 687{
630 char *hostkeyalg = match_list(client, server, NULL); 688 k->hostkey_alg = match_list(client, server, NULL);
631 689
632 debug("kex: host key algorithm: %s", 690 debug("kex: host key algorithm: %s",
633 hostkeyalg ? hostkeyalg : "(no match)"); 691 k->hostkey_alg ? k->hostkey_alg : "(no match)");
634 if (hostkeyalg == NULL) 692 if (k->hostkey_alg == NULL)
635 return SSH_ERR_NO_HOSTKEY_ALG_MATCH; 693 return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
636 k->hostkey_type = sshkey_type_from_name(hostkeyalg); 694 k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
637 if (k->hostkey_type == KEY_UNSPEC) 695 if (k->hostkey_type == KEY_UNSPEC)
638 return SSH_ERR_INTERNAL_ERROR; 696 return SSH_ERR_INTERNAL_ERROR;
639 k->hostkey_nid = sshkey_ecdsa_nid_from_name(hostkeyalg); 697 k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
640 free(hostkeyalg);
641 return 0; 698 return 0;
642} 699}
643 700
@@ -702,6 +759,17 @@ kex_choose_conf(struct ssh *ssh)
702 } 759 }
703 } 760 }
704 761
762 /* Check whether client supports ext_info_c */
763 if (kex->server) {
764 char *ext;
765
766 ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL);
767 if (ext) {
768 kex->ext_info_c = 1;
769 free(ext);
770 }
771 }
772
705 /* Algorithm Negotiation */ 773 /* Algorithm Negotiation */
706 if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], 774 if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
707 sprop[PROPOSAL_KEX_ALGS])) != 0) { 775 sprop[PROPOSAL_KEX_ALGS])) != 0) {