diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 316 |
1 files changed, 192 insertions, 124 deletions
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: sshd.c,v 1.132 2000/10/13 18:34:46 markus Exp $"); | 43 | RCSID("$OpenBSD: sshd.c,v 1.134 2000/11/12 19:50:38 markus Exp $"); |
44 | 44 | ||
45 | #include "xmalloc.h" | 45 | #include "xmalloc.h" |
46 | #include "rsa.h" | 46 | #include "rsa.h" |
@@ -61,7 +61,6 @@ RCSID("$OpenBSD: sshd.c,v 1.132 2000/10/13 18:34:46 markus Exp $"); | |||
61 | #include <openssl/dsa.h> | 61 | #include <openssl/dsa.h> |
62 | #include <openssl/rsa.h> | 62 | #include <openssl/rsa.h> |
63 | #include "key.h" | 63 | #include "key.h" |
64 | #include "dsa.h" | ||
65 | #include "dh.h" | 64 | #include "dh.h" |
66 | 65 | ||
67 | #include "auth.h" | 66 | #include "auth.h" |
@@ -140,9 +139,11 @@ char *server_version_string = NULL; | |||
140 | * not very useful. Currently, memory locking is not implemented. | 139 | * not very useful. Currently, memory locking is not implemented. |
141 | */ | 140 | */ |
142 | struct { | 141 | struct { |
143 | RSA *private_key; /* Private part of empheral server key. */ | 142 | Key *server_key; /* empheral server key */ |
144 | RSA *host_key; /* Private part of host key. */ | 143 | Key *ssh1_host_key; /* ssh1 host key */ |
145 | Key *dsa_host_key; /* Private DSA host key. */ | 144 | Key **host_keys; /* all private host keys */ |
145 | int have_ssh1_key; | ||
146 | int have_ssh2_key; | ||
146 | } sensitive_data; | 147 | } sensitive_data; |
147 | 148 | ||
148 | /* | 149 | /* |
@@ -154,10 +155,6 @@ int key_used = 0; | |||
154 | /* This is set to true when SIGHUP is received. */ | 155 | /* This is set to true when SIGHUP is received. */ |
155 | int received_sighup = 0; | 156 | int received_sighup = 0; |
156 | 157 | ||
157 | /* Public side of the server key. This value is regenerated regularly with | ||
158 | the private key. */ | ||
159 | RSA *public_key; | ||
160 | |||
161 | /* session identifier, used by RSA-auth */ | 158 | /* session identifier, used by RSA-auth */ |
162 | unsigned char session_id[16]; | 159 | unsigned char session_id[16]; |
163 | 160 | ||
@@ -266,6 +263,17 @@ grace_alarm_handler(int sig) | |||
266 | */ | 263 | */ |
267 | /* XXX do we really want this work to be done in a signal handler ? -m */ | 264 | /* XXX do we really want this work to be done in a signal handler ? -m */ |
268 | void | 265 | void |
266 | generate_empheral_server_key(void) | ||
267 | { | ||
268 | log("Generating %s%d bit RSA key.", sensitive_data.server_key ? "new " : "", | ||
269 | options.server_key_bits); | ||
270 | if (sensitive_data.server_key != NULL) | ||
271 | key_free(sensitive_data.server_key); | ||
272 | sensitive_data.server_key = key_generate(KEY_RSA1, options.server_key_bits); | ||
273 | arc4random_stir(); | ||
274 | log("RSA key generation complete."); | ||
275 | } | ||
276 | void | ||
269 | key_regeneration_alarm(int sig) | 277 | key_regeneration_alarm(int sig) |
270 | { | 278 | { |
271 | int save_errno = errno; | 279 | int save_errno = errno; |
@@ -273,21 +281,8 @@ key_regeneration_alarm(int sig) | |||
273 | /* Check if we should generate a new key. */ | 281 | /* Check if we should generate a new key. */ |
274 | if (key_used) { | 282 | if (key_used) { |
275 | /* This should really be done in the background. */ | 283 | /* This should really be done in the background. */ |
276 | log("Generating new %d bit RSA key.", options.server_key_bits); | 284 | generate_empheral_server_key(); |
277 | |||
278 | if (sensitive_data.private_key != NULL) | ||
279 | RSA_free(sensitive_data.private_key); | ||
280 | sensitive_data.private_key = RSA_new(); | ||
281 | |||
282 | if (public_key != NULL) | ||
283 | RSA_free(public_key); | ||
284 | public_key = RSA_new(); | ||
285 | |||
286 | rsa_generate_key(sensitive_data.private_key, public_key, | ||
287 | options.server_key_bits); | ||
288 | arc4random_stir(); | ||
289 | key_used = 0; | 285 | key_used = 0; |
290 | log("RSA key generation complete."); | ||
291 | } | 286 | } |
292 | /* Reschedule the alarm. */ | 287 | /* Reschedule the alarm. */ |
293 | signal(SIGALRM, key_regeneration_alarm); | 288 | signal(SIGALRM, key_regeneration_alarm); |
@@ -422,18 +417,93 @@ sshd_exchange_identification(int sock_in, int sock_out) | |||
422 | } | 417 | } |
423 | 418 | ||
424 | 419 | ||
420 | /* Destroy the host and server keys. They will no longer be needed. */ | ||
425 | void | 421 | void |
426 | destroy_sensitive_data(void) | 422 | destroy_sensitive_data(void) |
427 | { | 423 | { |
428 | /* Destroy the private and public keys. They will no longer be needed. */ | 424 | int i; |
429 | if (public_key) | 425 | |
430 | RSA_free(public_key); | 426 | if (sensitive_data.server_key) { |
431 | if (sensitive_data.private_key) | 427 | key_free(sensitive_data.server_key); |
432 | RSA_free(sensitive_data.private_key); | 428 | sensitive_data.server_key = NULL; |
433 | if (sensitive_data.host_key) | 429 | } |
434 | RSA_free(sensitive_data.host_key); | 430 | for(i = 0; i < options.num_host_key_files; i++) { |
435 | if (sensitive_data.dsa_host_key != NULL) | 431 | if (sensitive_data.host_keys[i]) { |
436 | key_free(sensitive_data.dsa_host_key); | 432 | key_free(sensitive_data.host_keys[i]); |
433 | sensitive_data.host_keys[i] = NULL; | ||
434 | } | ||
435 | } | ||
436 | sensitive_data.ssh1_host_key = NULL; | ||
437 | } | ||
438 | Key * | ||
439 | load_private_key_autodetect(const char *filename) | ||
440 | { | ||
441 | struct stat st; | ||
442 | int type; | ||
443 | Key *public, *private; | ||
444 | |||
445 | if (stat(filename, &st) < 0) { | ||
446 | perror(filename); | ||
447 | return NULL; | ||
448 | } | ||
449 | /* | ||
450 | * try to load the public key. right now this only works for RSA1, | ||
451 | * since SSH2 keys are fully encrypted | ||
452 | */ | ||
453 | type = KEY_RSA1; | ||
454 | public = key_new(type); | ||
455 | if (!load_public_key(filename, public, NULL)) { | ||
456 | /* ok, so we will assume this is 'some' key */ | ||
457 | type = KEY_UNSPEC; | ||
458 | } | ||
459 | key_free(public); | ||
460 | |||
461 | /* Ok, try key with empty passphrase */ | ||
462 | private = key_new(type); | ||
463 | if (load_private_key(filename, "", private, NULL)) { | ||
464 | debug("load_private_key_autodetect: type %d %s", | ||
465 | private->type, key_type(private)); | ||
466 | return private; | ||
467 | } | ||
468 | key_free(private); | ||
469 | return NULL; | ||
470 | } | ||
471 | |||
472 | char * | ||
473 | list_hostkey_types(void) | ||
474 | { | ||
475 | static char buf[1024]; | ||
476 | int i; | ||
477 | buf[0] = '\0'; | ||
478 | for(i = 0; i < options.num_host_key_files; i++) { | ||
479 | Key *key = sensitive_data.host_keys[i]; | ||
480 | if (key == NULL) | ||
481 | continue; | ||
482 | switch(key->type) { | ||
483 | case KEY_RSA: | ||
484 | case KEY_DSA: | ||
485 | strlcat(buf, key_ssh_name(key), sizeof buf); | ||
486 | strlcat(buf, ",", sizeof buf); | ||
487 | break; | ||
488 | } | ||
489 | } | ||
490 | i = strlen(buf); | ||
491 | if (i > 0 && buf[i-1] == ',') | ||
492 | buf[i-1] = '\0'; | ||
493 | debug("list_hostkey_types: %s", buf); | ||
494 | return buf; | ||
495 | } | ||
496 | |||
497 | Key * | ||
498 | get_hostkey_by_type(int type) | ||
499 | { | ||
500 | int i; | ||
501 | for(i = 0; i < options.num_host_key_files; i++) { | ||
502 | Key *key = sensitive_data.host_keys[i]; | ||
503 | if (key != NULL && key->type == type) | ||
504 | return key; | ||
505 | } | ||
506 | return NULL; | ||
437 | } | 507 | } |
438 | 508 | ||
439 | /* | 509 | /* |
@@ -555,7 +625,11 @@ main(int ac, char **av) | |||
555 | options.key_regeneration_time = atoi(optarg); | 625 | options.key_regeneration_time = atoi(optarg); |
556 | break; | 626 | break; |
557 | case 'h': | 627 | case 'h': |
558 | options.host_key_file = optarg; | 628 | if (options.num_host_key_files >= MAX_HOSTKEYS) { |
629 | fprintf(stderr, "too many host keys.\n"); | ||
630 | exit(1); | ||
631 | } | ||
632 | options.host_key_files[options.num_host_key_files++] = optarg; | ||
559 | break; | 633 | break; |
560 | case 'V': | 634 | case 'V': |
561 | client_version_string = optarg; | 635 | client_version_string = optarg; |
@@ -610,39 +684,39 @@ main(int ac, char **av) | |||
610 | 684 | ||
611 | debug("sshd version %.100s", SSH_VERSION); | 685 | debug("sshd version %.100s", SSH_VERSION); |
612 | 686 | ||
613 | sensitive_data.dsa_host_key = NULL; | 687 | /* load private host keys */ |
614 | sensitive_data.host_key = NULL; | 688 | sensitive_data.host_keys = xmalloc(options.num_host_key_files*sizeof(Key*)); |
689 | sensitive_data.server_key = NULL; | ||
690 | sensitive_data.ssh1_host_key = NULL; | ||
691 | sensitive_data.have_ssh1_key = 0; | ||
692 | sensitive_data.have_ssh2_key = 0; | ||
615 | 693 | ||
616 | /* check if RSA support exists */ | 694 | for(i = 0; i < options.num_host_key_files; i++) { |
617 | if ((options.protocol & SSH_PROTO_1) && | 695 | Key *key = load_private_key_autodetect(options.host_key_files[i]); |
618 | rsa_alive() == 0) { | 696 | if (key == NULL) { |
619 | log("no RSA support in libssl and libcrypto. See ssl(8)"); | ||
620 | log("Disabling protocol version 1"); | ||
621 | options.protocol &= ~SSH_PROTO_1; | ||
622 | } | ||
623 | /* Load the RSA/DSA host key. It must have empty passphrase. */ | ||
624 | if (options.protocol & SSH_PROTO_1) { | ||
625 | Key k; | ||
626 | sensitive_data.host_key = RSA_new(); | ||
627 | k.type = KEY_RSA; | ||
628 | k.rsa = sensitive_data.host_key; | ||
629 | errno = 0; | ||
630 | if (!load_private_key(options.host_key_file, "", &k, NULL)) { | ||
631 | error("Could not load host key: %.200s: %.100s", | 697 | error("Could not load host key: %.200s: %.100s", |
632 | options.host_key_file, strerror(errno)); | 698 | options.host_key_files[i], strerror(errno)); |
633 | log("Disabling protocol version 1"); | 699 | continue; |
634 | options.protocol &= ~SSH_PROTO_1; | ||
635 | } | 700 | } |
636 | k.rsa = NULL; | 701 | switch(key->type){ |
637 | } | 702 | case KEY_RSA1: |
638 | if (options.protocol & SSH_PROTO_2) { | 703 | sensitive_data.ssh1_host_key = key; |
639 | sensitive_data.dsa_host_key = key_new(KEY_DSA); | 704 | sensitive_data.have_ssh1_key = 1; |
640 | if (!load_private_key(options.host_dsa_key_file, "", sensitive_data.dsa_host_key, NULL)) { | 705 | break; |
641 | 706 | case KEY_RSA: | |
642 | error("Could not load DSA host key: %.200s", options.host_dsa_key_file); | 707 | case KEY_DSA: |
643 | log("Disabling protocol version 2"); | 708 | sensitive_data.have_ssh2_key = 1; |
644 | options.protocol &= ~SSH_PROTO_2; | 709 | break; |
645 | } | 710 | } |
711 | sensitive_data.host_keys[i] = key; | ||
712 | } | ||
713 | if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { | ||
714 | log("Disabling protocol version 1. Could not load host key"); | ||
715 | options.protocol &= ~SSH_PROTO_1; | ||
716 | } | ||
717 | if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { | ||
718 | log("Disabling protocol version 2. Could not load host key"); | ||
719 | options.protocol &= ~SSH_PROTO_2; | ||
646 | } | 720 | } |
647 | if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) { | 721 | if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) { |
648 | if (silent == 0) | 722 | if (silent == 0) |
@@ -664,11 +738,11 @@ main(int ac, char **av) | |||
664 | * hate software patents. I dont know if this can go? Niels | 738 | * hate software patents. I dont know if this can go? Niels |
665 | */ | 739 | */ |
666 | if (options.server_key_bits > | 740 | if (options.server_key_bits > |
667 | BN_num_bits(sensitive_data.host_key->n) - SSH_KEY_BITS_RESERVED && | 741 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - SSH_KEY_BITS_RESERVED && |
668 | options.server_key_bits < | 742 | options.server_key_bits < |
669 | BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) { | 743 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { |
670 | options.server_key_bits = | 744 | options.server_key_bits = |
671 | BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED; | 745 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED; |
672 | debug("Forcing server key to %d bits to make it differ from host key.", | 746 | debug("Forcing server key to %d bits to make it differ from host key.", |
673 | options.server_key_bits); | 747 | options.server_key_bits); |
674 | } | 748 | } |
@@ -707,9 +781,6 @@ main(int ac, char **av) | |||
707 | /* Reinitialize the log (because of the fork above). */ | 781 | /* Reinitialize the log (because of the fork above). */ |
708 | log_init(av0, options.log_level, options.log_facility, log_stderr); | 782 | log_init(av0, options.log_level, options.log_facility, log_stderr); |
709 | 783 | ||
710 | /* Do not display messages to stdout in RSA code. */ | ||
711 | rsa_set_verbose(0); | ||
712 | |||
713 | /* Initialize the random number generator. */ | 784 | /* Initialize the random number generator. */ |
714 | arc4random_stir(); | 785 | arc4random_stir(); |
715 | 786 | ||
@@ -731,16 +802,8 @@ main(int ac, char **av) | |||
731 | * ttyfd happens to be one of those. | 802 | * ttyfd happens to be one of those. |
732 | */ | 803 | */ |
733 | debug("inetd sockets after dupping: %d, %d", sock_in, sock_out); | 804 | debug("inetd sockets after dupping: %d, %d", sock_in, sock_out); |
734 | 805 | if (options.protocol & SSH_PROTO_1) | |
735 | if (options.protocol & SSH_PROTO_1) { | 806 | generate_empheral_server_key(); |
736 | public_key = RSA_new(); | ||
737 | sensitive_data.private_key = RSA_new(); | ||
738 | log("Generating %d bit RSA key.", options.server_key_bits); | ||
739 | rsa_generate_key(sensitive_data.private_key, public_key, | ||
740 | options.server_key_bits); | ||
741 | arc4random_stir(); | ||
742 | log("RSA key generation complete."); | ||
743 | } | ||
744 | } else { | 807 | } else { |
745 | for (ai = options.listen_addrs; ai; ai = ai->ai_next) { | 808 | for (ai = options.listen_addrs; ai; ai = ai->ai_next) { |
746 | if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) | 809 | if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) |
@@ -818,14 +881,7 @@ main(int ac, char **av) | |||
818 | } | 881 | } |
819 | } | 882 | } |
820 | if (options.protocol & SSH_PROTO_1) { | 883 | if (options.protocol & SSH_PROTO_1) { |
821 | public_key = RSA_new(); | 884 | generate_empheral_server_key(); |
822 | sensitive_data.private_key = RSA_new(); | ||
823 | |||
824 | log("Generating %d bit RSA key.", options.server_key_bits); | ||
825 | rsa_generate_key(sensitive_data.private_key, public_key, | ||
826 | options.server_key_bits); | ||
827 | arc4random_stir(); | ||
828 | log("RSA key generation complete."); | ||
829 | 885 | ||
830 | /* Schedule server key regeneration alarm. */ | 886 | /* Schedule server key regeneration alarm. */ |
831 | signal(SIGALRM, key_regeneration_alarm); | 887 | signal(SIGALRM, key_regeneration_alarm); |
@@ -1065,6 +1121,8 @@ main(int ac, char **av) | |||
1065 | */ | 1121 | */ |
1066 | if (remote_port >= IPPORT_RESERVED || | 1122 | if (remote_port >= IPPORT_RESERVED || |
1067 | remote_port < IPPORT_RESERVED / 2) { | 1123 | remote_port < IPPORT_RESERVED / 2) { |
1124 | debug("Rhosts Authentication methods disabled, " | ||
1125 | "originating port not trusted."); | ||
1068 | options.rhosts_authentication = 0; | 1126 | options.rhosts_authentication = 0; |
1069 | options.rhosts_rsa_authentication = 0; | 1127 | options.rhosts_rsa_authentication = 0; |
1070 | } | 1128 | } |
@@ -1145,14 +1203,14 @@ do_ssh1_kex() | |||
1145 | packet_put_char(cookie[i]); | 1203 | packet_put_char(cookie[i]); |
1146 | 1204 | ||
1147 | /* Store our public server RSA key. */ | 1205 | /* Store our public server RSA key. */ |
1148 | packet_put_int(BN_num_bits(public_key->n)); | 1206 | packet_put_int(BN_num_bits(sensitive_data.server_key->rsa->n)); |
1149 | packet_put_bignum(public_key->e); | 1207 | packet_put_bignum(sensitive_data.server_key->rsa->e); |
1150 | packet_put_bignum(public_key->n); | 1208 | packet_put_bignum(sensitive_data.server_key->rsa->n); |
1151 | 1209 | ||
1152 | /* Store our public host RSA key. */ | 1210 | /* Store our public host RSA key. */ |
1153 | packet_put_int(BN_num_bits(sensitive_data.host_key->n)); | 1211 | packet_put_int(BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); |
1154 | packet_put_bignum(sensitive_data.host_key->e); | 1212 | packet_put_bignum(sensitive_data.ssh1_host_key->rsa->e); |
1155 | packet_put_bignum(sensitive_data.host_key->n); | 1213 | packet_put_bignum(sensitive_data.ssh1_host_key->rsa->n); |
1156 | 1214 | ||
1157 | /* Put protocol flags. */ | 1215 | /* Put protocol flags. */ |
1158 | packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); | 1216 | packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); |
@@ -1190,8 +1248,9 @@ do_ssh1_kex() | |||
1190 | packet_send(); | 1248 | packet_send(); |
1191 | packet_write_wait(); | 1249 | packet_write_wait(); |
1192 | 1250 | ||
1193 | debug("Sent %d bit public key and %d bit host key.", | 1251 | debug("Sent %d bit server key and %d bit host key.", |
1194 | BN_num_bits(public_key->n), BN_num_bits(sensitive_data.host_key->n)); | 1252 | BN_num_bits(sensitive_data.server_key->rsa->n), |
1253 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); | ||
1195 | 1254 | ||
1196 | /* Read clients reply (cipher type and session key). */ | 1255 | /* Read clients reply (cipher type and session key). */ |
1197 | packet_read_expect(&plen, SSH_CMSG_SESSION_KEY); | 1256 | packet_read_expect(&plen, SSH_CMSG_SESSION_KEY); |
@@ -1223,39 +1282,39 @@ do_ssh1_kex() | |||
1223 | * Decrypt it using our private server key and private host key (key | 1282 | * Decrypt it using our private server key and private host key (key |
1224 | * with larger modulus first). | 1283 | * with larger modulus first). |
1225 | */ | 1284 | */ |
1226 | if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0) { | 1285 | if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) { |
1227 | /* Private key has bigger modulus. */ | 1286 | /* Private key has bigger modulus. */ |
1228 | if (BN_num_bits(sensitive_data.private_key->n) < | 1287 | if (BN_num_bits(sensitive_data.server_key->rsa->n) < |
1229 | BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) { | 1288 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { |
1230 | fatal("do_connection: %s: private_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", | 1289 | fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", |
1231 | get_remote_ipaddr(), | 1290 | get_remote_ipaddr(), |
1232 | BN_num_bits(sensitive_data.private_key->n), | 1291 | BN_num_bits(sensitive_data.server_key->rsa->n), |
1233 | BN_num_bits(sensitive_data.host_key->n), | 1292 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), |
1234 | SSH_KEY_BITS_RESERVED); | 1293 | SSH_KEY_BITS_RESERVED); |
1235 | } | 1294 | } |
1236 | rsa_private_decrypt(session_key_int, session_key_int, | 1295 | rsa_private_decrypt(session_key_int, session_key_int, |
1237 | sensitive_data.private_key); | 1296 | sensitive_data.server_key->rsa); |
1238 | rsa_private_decrypt(session_key_int, session_key_int, | 1297 | rsa_private_decrypt(session_key_int, session_key_int, |
1239 | sensitive_data.host_key); | 1298 | sensitive_data.ssh1_host_key->rsa); |
1240 | } else { | 1299 | } else { |
1241 | /* Host key has bigger modulus (or they are equal). */ | 1300 | /* Host key has bigger modulus (or they are equal). */ |
1242 | if (BN_num_bits(sensitive_data.host_key->n) < | 1301 | if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < |
1243 | BN_num_bits(sensitive_data.private_key->n) + SSH_KEY_BITS_RESERVED) { | 1302 | BN_num_bits(sensitive_data.server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { |
1244 | fatal("do_connection: %s: host_key %d < private_key %d + SSH_KEY_BITS_RESERVED %d", | 1303 | fatal("do_connection: %s: host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d", |
1245 | get_remote_ipaddr(), | 1304 | get_remote_ipaddr(), |
1246 | BN_num_bits(sensitive_data.host_key->n), | 1305 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), |
1247 | BN_num_bits(sensitive_data.private_key->n), | 1306 | BN_num_bits(sensitive_data.server_key->rsa->n), |
1248 | SSH_KEY_BITS_RESERVED); | 1307 | SSH_KEY_BITS_RESERVED); |
1249 | } | 1308 | } |
1250 | rsa_private_decrypt(session_key_int, session_key_int, | 1309 | rsa_private_decrypt(session_key_int, session_key_int, |
1251 | sensitive_data.host_key); | 1310 | sensitive_data.ssh1_host_key->rsa); |
1252 | rsa_private_decrypt(session_key_int, session_key_int, | 1311 | rsa_private_decrypt(session_key_int, session_key_int, |
1253 | sensitive_data.private_key); | 1312 | sensitive_data.server_key->rsa); |
1254 | } | 1313 | } |
1255 | 1314 | ||
1256 | compute_session_id(session_id, cookie, | 1315 | compute_session_id(session_id, cookie, |
1257 | sensitive_data.host_key->n, | 1316 | sensitive_data.ssh1_host_key->rsa->n, |
1258 | sensitive_data.private_key->n); | 1317 | sensitive_data.server_key->rsa->n); |
1259 | 1318 | ||
1260 | /* Destroy the private and public keys. They will no longer be needed. */ | 1319 | /* Destroy the private and public keys. They will no longer be needed. */ |
1261 | destroy_sensitive_data(); | 1320 | destroy_sensitive_data(); |
@@ -1269,8 +1328,8 @@ do_ssh1_kex() | |||
1269 | len = BN_num_bytes(session_key_int); | 1328 | len = BN_num_bytes(session_key_int); |
1270 | if (len < 0 || len > sizeof(session_key)) | 1329 | if (len < 0 || len > sizeof(session_key)) |
1271 | fatal("do_connection: bad len from %s: session_key_int %d > sizeof(session_key) %d", | 1330 | fatal("do_connection: bad len from %s: session_key_int %d > sizeof(session_key) %d", |
1272 | get_remote_ipaddr(), | 1331 | get_remote_ipaddr(), |
1273 | len, (int) sizeof(session_key)); | 1332 | len, sizeof(session_key)); |
1274 | memset(session_key, 0, sizeof(session_key)); | 1333 | memset(session_key, 0, sizeof(session_key)); |
1275 | BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len); | 1334 | BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len); |
1276 | 1335 | ||
@@ -1314,6 +1373,8 @@ do_ssh2_kex() | |||
1314 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = | 1373 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = |
1315 | myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; | 1374 | myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; |
1316 | } | 1375 | } |
1376 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); | ||
1377 | |||
1317 | server_kexinit = kex_init(myproposal); | 1378 | server_kexinit = kex_init(myproposal); |
1318 | client_kexinit = xmalloc(sizeof(*client_kexinit)); | 1379 | client_kexinit = xmalloc(sizeof(*client_kexinit)); |
1319 | buffer_init(client_kexinit); | 1380 | buffer_init(client_kexinit); |
@@ -1379,6 +1440,11 @@ ssh_dh1_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit) | |||
1379 | BIGNUM *shared_secret = 0; | 1440 | BIGNUM *shared_secret = 0; |
1380 | DH *dh; | 1441 | DH *dh; |
1381 | BIGNUM *dh_client_pub = 0; | 1442 | BIGNUM *dh_client_pub = 0; |
1443 | Key *hostkey; | ||
1444 | |||
1445 | hostkey = get_hostkey_by_type(kex->hostkey_type); | ||
1446 | if (hostkey == NULL) | ||
1447 | fatal("Unsupported hostkey type %d", kex->hostkey_type); | ||
1382 | 1448 | ||
1383 | /* KEXDH */ | 1449 | /* KEXDH */ |
1384 | debug("Wait SSH2_MSG_KEXDH_INIT."); | 1450 | debug("Wait SSH2_MSG_KEXDH_INIT."); |
@@ -1431,8 +1497,7 @@ ssh_dh1_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit) | |||
1431 | xfree(kbuf); | 1497 | xfree(kbuf); |
1432 | 1498 | ||
1433 | /* XXX precompute? */ | 1499 | /* XXX precompute? */ |
1434 | dsa_make_key_blob(sensitive_data.dsa_host_key, | 1500 | key_to_blob(hostkey, &server_host_key_blob, &sbloblen); |
1435 | &server_host_key_blob, &sbloblen); | ||
1436 | 1501 | ||
1437 | /* calc H */ /* XXX depends on 'kex' */ | 1502 | /* calc H */ /* XXX depends on 'kex' */ |
1438 | hash = kex_hash( | 1503 | hash = kex_hash( |
@@ -1463,7 +1528,7 @@ ssh_dh1_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit) | |||
1463 | 1528 | ||
1464 | /* sign H */ | 1529 | /* sign H */ |
1465 | /* XXX hashlen depends on KEX */ | 1530 | /* XXX hashlen depends on KEX */ |
1466 | dsa_sign(sensitive_data.dsa_host_key, &signature, &slen, hash, 20); | 1531 | key_sign(hostkey, &signature, &slen, hash, 20); |
1467 | 1532 | ||
1468 | destroy_sensitive_data(); | 1533 | destroy_sensitive_data(); |
1469 | 1534 | ||
@@ -1503,6 +1568,11 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit) | |||
1503 | BIGNUM *shared_secret = 0; | 1568 | BIGNUM *shared_secret = 0; |
1504 | DH *dh; | 1569 | DH *dh; |
1505 | BIGNUM *dh_client_pub = 0; | 1570 | BIGNUM *dh_client_pub = 0; |
1571 | Key *hostkey; | ||
1572 | |||
1573 | hostkey = get_hostkey_by_type(kex->hostkey_type); | ||
1574 | if (hostkey == NULL) | ||
1575 | fatal("Unsupported hostkey type %d", kex->hostkey_type); | ||
1506 | 1576 | ||
1507 | /* KEXDHGEX */ | 1577 | /* KEXDHGEX */ |
1508 | debug("Wait SSH2_MSG_KEX_DH_GEX_REQUEST."); | 1578 | debug("Wait SSH2_MSG_KEX_DH_GEX_REQUEST."); |
@@ -1564,8 +1634,7 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit) | |||
1564 | xfree(kbuf); | 1634 | xfree(kbuf); |
1565 | 1635 | ||
1566 | /* XXX precompute? */ | 1636 | /* XXX precompute? */ |
1567 | dsa_make_key_blob(sensitive_data.dsa_host_key, | 1637 | key_to_blob(hostkey, &server_host_key_blob, &sbloblen); |
1568 | &server_host_key_blob, &sbloblen); | ||
1569 | 1638 | ||
1570 | /* calc H */ /* XXX depends on 'kex' */ | 1639 | /* calc H */ /* XXX depends on 'kex' */ |
1571 | hash = kex_hash_gex( | 1640 | hash = kex_hash_gex( |
@@ -1597,7 +1666,7 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit) | |||
1597 | 1666 | ||
1598 | /* sign H */ | 1667 | /* sign H */ |
1599 | /* XXX hashlen depends on KEX */ | 1668 | /* XXX hashlen depends on KEX */ |
1600 | dsa_sign(sensitive_data.dsa_host_key, &signature, &slen, hash, 20); | 1669 | key_sign(hostkey, &signature, &slen, hash, 20); |
1601 | 1670 | ||
1602 | destroy_sensitive_data(); | 1671 | destroy_sensitive_data(); |
1603 | 1672 | ||
@@ -1617,4 +1686,3 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit) | |||
1617 | /* have keys, free DH */ | 1686 | /* have keys, free DH */ |
1618 | DH_free(dh); | 1687 | DH_free(dh); |
1619 | } | 1688 | } |
1620 | |||