diff options
Diffstat (limited to 'packet.c')
-rw-r--r-- | packet.c | 108 |
1 files changed, 52 insertions, 56 deletions
@@ -37,7 +37,7 @@ | |||
37 | */ | 37 | */ |
38 | 38 | ||
39 | #include "includes.h" | 39 | #include "includes.h" |
40 | RCSID("$OpenBSD: packet.c,v 1.56 2001/03/03 21:41:07 millert Exp $"); | 40 | RCSID("$OpenBSD: packet.c,v 1.57 2001/04/03 23:32:12 markus Exp $"); |
41 | 41 | ||
42 | #include "xmalloc.h" | 42 | #include "xmalloc.h" |
43 | #include "buffer.h" | 43 | #include "buffer.h" |
@@ -121,21 +121,9 @@ static int interactive_mode = 0; | |||
121 | int use_ssh2_packet_format = 0; | 121 | int use_ssh2_packet_format = 0; |
122 | 122 | ||
123 | /* Session key information for Encryption and MAC */ | 123 | /* Session key information for Encryption and MAC */ |
124 | Kex *kex = NULL; | 124 | Newkeys *newkeys[MODE_MAX]; |
125 | 125 | ||
126 | void | 126 | void |
127 | packet_set_kex(Kex *k) | ||
128 | { | ||
129 | if( k->mac[MODE_IN ].key == NULL || | ||
130 | k->enc[MODE_IN ].key == NULL || | ||
131 | k->enc[MODE_IN ].iv == NULL || | ||
132 | k->mac[MODE_OUT].key == NULL || | ||
133 | k->enc[MODE_OUT].key == NULL || | ||
134 | k->enc[MODE_OUT].iv == NULL) | ||
135 | fatal("bad KEX"); | ||
136 | kex = k; | ||
137 | } | ||
138 | void | ||
139 | clear_enc_keys(Enc *enc, int len) | 127 | clear_enc_keys(Enc *enc, int len) |
140 | { | 128 | { |
141 | memset(enc->iv, 0, len); | 129 | memset(enc->iv, 0, len); |
@@ -150,6 +138,7 @@ packet_set_ssh2_format(void) | |||
150 | { | 138 | { |
151 | DBG(debug("use_ssh2_packet_format")); | 139 | DBG(debug("use_ssh2_packet_format")); |
152 | use_ssh2_packet_format = 1; | 140 | use_ssh2_packet_format = 1; |
141 | newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL; | ||
153 | } | 142 | } |
154 | 143 | ||
155 | /* | 144 | /* |
@@ -522,6 +511,41 @@ packet_send1(void) | |||
522 | */ | 511 | */ |
523 | } | 512 | } |
524 | 513 | ||
514 | void | ||
515 | set_newkeys(int mode) | ||
516 | { | ||
517 | Enc *enc; | ||
518 | Mac *mac; | ||
519 | Comp *comp; | ||
520 | CipherContext *cc; | ||
521 | |||
522 | debug("newkeys: mode %d", mode); | ||
523 | |||
524 | cc = (mode == MODE_OUT) ? &send_context : &receive_context; | ||
525 | if (newkeys[mode] != NULL) { | ||
526 | debug("newkeys: rekeying"); | ||
527 | memset(cc, 0, sizeof(*cc)); | ||
528 | // free old keys, reset compression cipher-contexts; | ||
529 | } | ||
530 | newkeys[mode] = kex_get_newkeys(mode); | ||
531 | if (newkeys[mode] == NULL) | ||
532 | fatal("newkeys: no keys for mode %d", mode); | ||
533 | enc = &newkeys[mode]->enc; | ||
534 | mac = &newkeys[mode]->mac; | ||
535 | comp = &newkeys[mode]->comp; | ||
536 | if (mac->md != NULL) | ||
537 | mac->enabled = 1; | ||
538 | DBG(debug("cipher_init_context: %d", mode)); | ||
539 | cipher_init(cc, enc->cipher, enc->key, enc->cipher->key_len, | ||
540 | enc->iv, enc->cipher->block_size); | ||
541 | clear_enc_keys(enc, enc->cipher->key_len); | ||
542 | if (comp->type != 0 && comp->enabled == 0) { | ||
543 | comp->enabled = 1; | ||
544 | if (! packet_compression) | ||
545 | packet_start_compression(6); | ||
546 | } | ||
547 | } | ||
548 | |||
525 | /* | 549 | /* |
526 | * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) | 550 | * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) |
527 | */ | 551 | */ |
@@ -540,10 +564,10 @@ packet_send2(void) | |||
540 | Comp *comp = NULL; | 564 | Comp *comp = NULL; |
541 | int block_size; | 565 | int block_size; |
542 | 566 | ||
543 | if (kex != NULL) { | 567 | if (newkeys[MODE_OUT] != NULL) { |
544 | enc = &kex->enc[MODE_OUT]; | 568 | enc = &newkeys[MODE_OUT]->enc; |
545 | mac = &kex->mac[MODE_OUT]; | 569 | mac = &newkeys[MODE_OUT]->mac; |
546 | comp = &kex->comp[MODE_OUT]; | 570 | comp = &newkeys[MODE_OUT]->comp; |
547 | } | 571 | } |
548 | block_size = enc ? enc->cipher->block_size : 8; | 572 | block_size = enc ? enc->cipher->block_size : 8; |
549 | 573 | ||
@@ -622,22 +646,8 @@ packet_send2(void) | |||
622 | log("outgoing seqnr wraps around"); | 646 | log("outgoing seqnr wraps around"); |
623 | buffer_clear(&outgoing_packet); | 647 | buffer_clear(&outgoing_packet); |
624 | 648 | ||
625 | if (type == SSH2_MSG_NEWKEYS) { | 649 | if (type == SSH2_MSG_NEWKEYS) |
626 | if (kex==NULL || mac==NULL || enc==NULL || comp==NULL) | 650 | set_newkeys(MODE_OUT); |
627 | fatal("packet_send2: no KEX"); | ||
628 | if (mac->md != NULL) | ||
629 | mac->enabled = 1; | ||
630 | DBG(debug("cipher_init send_context")); | ||
631 | cipher_init(&send_context, enc->cipher, | ||
632 | enc->key, enc->cipher->key_len, | ||
633 | enc->iv, enc->cipher->block_size); | ||
634 | clear_enc_keys(enc, kex->we_need); | ||
635 | if (comp->type != 0 && comp->enabled == 0) { | ||
636 | comp->enabled = 1; | ||
637 | if (! packet_compression) | ||
638 | packet_start_compression(6); | ||
639 | } | ||
640 | } | ||
641 | } | 651 | } |
642 | 652 | ||
643 | void | 653 | void |
@@ -833,10 +843,10 @@ packet_read_poll2(int *payload_len_ptr) | |||
833 | Mac *mac = NULL; | 843 | Mac *mac = NULL; |
834 | Comp *comp = NULL; | 844 | Comp *comp = NULL; |
835 | 845 | ||
836 | if (kex != NULL) { | 846 | if (newkeys[MODE_IN] != NULL) { |
837 | enc = &kex->enc[MODE_IN]; | 847 | enc = &newkeys[MODE_IN]->enc; |
838 | mac = &kex->mac[MODE_IN]; | 848 | mac = &newkeys[MODE_IN]->mac; |
839 | comp = &kex->comp[MODE_IN]; | 849 | comp = &newkeys[MODE_IN]->comp; |
840 | } | 850 | } |
841 | maclen = mac && mac->enabled ? mac->mac_len : 0; | 851 | maclen = mac && mac->enabled ? mac->mac_len : 0; |
842 | block_size = enc ? enc->cipher->block_size : 8; | 852 | block_size = enc ? enc->cipher->block_size : 8; |
@@ -930,22 +940,8 @@ packet_read_poll2(int *payload_len_ptr) | |||
930 | /* extract packet type */ | 940 | /* extract packet type */ |
931 | type = (u_char)buf[0]; | 941 | type = (u_char)buf[0]; |
932 | 942 | ||
933 | if (type == SSH2_MSG_NEWKEYS) { | 943 | if (type == SSH2_MSG_NEWKEYS) |
934 | if (kex==NULL || mac==NULL || enc==NULL || comp==NULL) | 944 | set_newkeys(MODE_IN); |
935 | fatal("packet_read_poll2: no KEX"); | ||
936 | if (mac->md != NULL) | ||
937 | mac->enabled = 1; | ||
938 | DBG(debug("cipher_init receive_context")); | ||
939 | cipher_init(&receive_context, enc->cipher, | ||
940 | enc->key, enc->cipher->key_len, | ||
941 | enc->iv, enc->cipher->block_size); | ||
942 | clear_enc_keys(enc, kex->we_need); | ||
943 | if (comp->type != 0 && comp->enabled == 0) { | ||
944 | comp->enabled = 1; | ||
945 | if (! packet_compression) | ||
946 | packet_start_compression(6); | ||
947 | } | ||
948 | } | ||
949 | 945 | ||
950 | #ifdef PACKET_DEBUG | 946 | #ifdef PACKET_DEBUG |
951 | fprintf(stderr, "read/plain[%d]:\r\n", type); | 947 | fprintf(stderr, "read/plain[%d]:\r\n", type); |
@@ -1339,8 +1335,8 @@ packet_inject_ignore(int sumlen) | |||
1339 | 1335 | ||
1340 | have = buffer_len(&outgoing_packet); | 1336 | have = buffer_len(&outgoing_packet); |
1341 | debug2("packet_inject_ignore: current %d", have); | 1337 | debug2("packet_inject_ignore: current %d", have); |
1342 | if (kex != NULL) | 1338 | if (newkeys[MODE_OUT] != NULL) |
1343 | enc = &kex->enc[MODE_OUT]; | 1339 | enc = &newkeys[MODE_OUT]->enc; |
1344 | blocksize = enc ? enc->cipher->block_size : 8; | 1340 | blocksize = enc ? enc->cipher->block_size : 8; |
1345 | padlen = blocksize - (have % blocksize); | 1341 | padlen = blocksize - (have % blocksize); |
1346 | if (padlen < 4) | 1342 | if (padlen < 4) |