version 1.56, 2001/03/03 21:41:07 |
version 1.57, 2001/04/03 23:32:12 |
|
|
int use_ssh2_packet_format = 0; |
int use_ssh2_packet_format = 0; |
|
|
/* Session key information for Encryption and MAC */ |
/* Session key information for Encryption and MAC */ |
Kex *kex = NULL; |
Newkeys *newkeys[MODE_MAX]; |
|
|
void |
void |
packet_set_kex(Kex *k) |
|
{ |
|
if( k->mac[MODE_IN ].key == NULL || |
|
k->enc[MODE_IN ].key == NULL || |
|
k->enc[MODE_IN ].iv == NULL || |
|
k->mac[MODE_OUT].key == NULL || |
|
k->enc[MODE_OUT].key == NULL || |
|
k->enc[MODE_OUT].iv == NULL) |
|
fatal("bad KEX"); |
|
kex = k; |
|
} |
|
void |
|
clear_enc_keys(Enc *enc, int len) |
clear_enc_keys(Enc *enc, int len) |
{ |
{ |
memset(enc->iv, 0, len); |
memset(enc->iv, 0, len); |
|
|
{ |
{ |
DBG(debug("use_ssh2_packet_format")); |
DBG(debug("use_ssh2_packet_format")); |
use_ssh2_packet_format = 1; |
use_ssh2_packet_format = 1; |
|
newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL; |
} |
} |
|
|
/* |
/* |
|
|
*/ |
*/ |
} |
} |
|
|
|
void |
|
set_newkeys(int mode) |
|
{ |
|
Enc *enc; |
|
Mac *mac; |
|
Comp *comp; |
|
CipherContext *cc; |
|
|
|
debug("newkeys: mode %d", mode); |
|
|
|
cc = (mode == MODE_OUT) ? &send_context : &receive_context; |
|
if (newkeys[mode] != NULL) { |
|
debug("newkeys: rekeying"); |
|
memset(cc, 0, sizeof(*cc)); |
|
// free old keys, reset compression cipher-contexts; |
|
} |
|
newkeys[mode] = kex_get_newkeys(mode); |
|
if (newkeys[mode] == NULL) |
|
fatal("newkeys: no keys for mode %d", mode); |
|
enc = &newkeys[mode]->enc; |
|
mac = &newkeys[mode]->mac; |
|
comp = &newkeys[mode]->comp; |
|
if (mac->md != NULL) |
|
mac->enabled = 1; |
|
DBG(debug("cipher_init_context: %d", mode)); |
|
cipher_init(cc, enc->cipher, enc->key, enc->cipher->key_len, |
|
enc->iv, enc->cipher->block_size); |
|
clear_enc_keys(enc, enc->cipher->key_len); |
|
if (comp->type != 0 && comp->enabled == 0) { |
|
comp->enabled = 1; |
|
if (! packet_compression) |
|
packet_start_compression(6); |
|
} |
|
} |
|
|
/* |
/* |
* Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) |
* Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) |
*/ |
*/ |
|
|
Comp *comp = NULL; |
Comp *comp = NULL; |
int block_size; |
int block_size; |
|
|
if (kex != NULL) { |
if (newkeys[MODE_OUT] != NULL) { |
enc = &kex->enc[MODE_OUT]; |
enc = &newkeys[MODE_OUT]->enc; |
mac = &kex->mac[MODE_OUT]; |
mac = &newkeys[MODE_OUT]->mac; |
comp = &kex->comp[MODE_OUT]; |
comp = &newkeys[MODE_OUT]->comp; |
} |
} |
block_size = enc ? enc->cipher->block_size : 8; |
block_size = enc ? enc->cipher->block_size : 8; |
|
|
|
|
log("outgoing seqnr wraps around"); |
log("outgoing seqnr wraps around"); |
buffer_clear(&outgoing_packet); |
buffer_clear(&outgoing_packet); |
|
|
if (type == SSH2_MSG_NEWKEYS) { |
if (type == SSH2_MSG_NEWKEYS) |
if (kex==NULL || mac==NULL || enc==NULL || comp==NULL) |
set_newkeys(MODE_OUT); |
fatal("packet_send2: no KEX"); |
|
if (mac->md != NULL) |
|
mac->enabled = 1; |
|
DBG(debug("cipher_init send_context")); |
|
cipher_init(&send_context, enc->cipher, |
|
enc->key, enc->cipher->key_len, |
|
enc->iv, enc->cipher->block_size); |
|
clear_enc_keys(enc, kex->we_need); |
|
if (comp->type != 0 && comp->enabled == 0) { |
|
comp->enabled = 1; |
|
if (! packet_compression) |
|
packet_start_compression(6); |
|
} |
|
} |
|
} |
} |
|
|
void |
void |
|
|
Mac *mac = NULL; |
Mac *mac = NULL; |
Comp *comp = NULL; |
Comp *comp = NULL; |
|
|
if (kex != NULL) { |
if (newkeys[MODE_IN] != NULL) { |
enc = &kex->enc[MODE_IN]; |
enc = &newkeys[MODE_IN]->enc; |
mac = &kex->mac[MODE_IN]; |
mac = &newkeys[MODE_IN]->mac; |
comp = &kex->comp[MODE_IN]; |
comp = &newkeys[MODE_IN]->comp; |
} |
} |
maclen = mac && mac->enabled ? mac->mac_len : 0; |
maclen = mac && mac->enabled ? mac->mac_len : 0; |
block_size = enc ? enc->cipher->block_size : 8; |
block_size = enc ? enc->cipher->block_size : 8; |
|
|
/* extract packet type */ |
/* extract packet type */ |
type = (u_char)buf[0]; |
type = (u_char)buf[0]; |
|
|
if (type == SSH2_MSG_NEWKEYS) { |
if (type == SSH2_MSG_NEWKEYS) |
if (kex==NULL || mac==NULL || enc==NULL || comp==NULL) |
set_newkeys(MODE_IN); |
fatal("packet_read_poll2: no KEX"); |
|
if (mac->md != NULL) |
|
mac->enabled = 1; |
|
DBG(debug("cipher_init receive_context")); |
|
cipher_init(&receive_context, enc->cipher, |
|
enc->key, enc->cipher->key_len, |
|
enc->iv, enc->cipher->block_size); |
|
clear_enc_keys(enc, kex->we_need); |
|
if (comp->type != 0 && comp->enabled == 0) { |
|
comp->enabled = 1; |
|
if (! packet_compression) |
|
packet_start_compression(6); |
|
} |
|
} |
|
|
|
#ifdef PACKET_DEBUG |
#ifdef PACKET_DEBUG |
fprintf(stderr, "read/plain[%d]:\r\n", type); |
fprintf(stderr, "read/plain[%d]:\r\n", type); |
|
|
|
|
have = buffer_len(&outgoing_packet); |
have = buffer_len(&outgoing_packet); |
debug2("packet_inject_ignore: current %d", have); |
debug2("packet_inject_ignore: current %d", have); |
if (kex != NULL) |
if (newkeys[MODE_OUT] != NULL) |
enc = &kex->enc[MODE_OUT]; |
enc = &newkeys[MODE_OUT]->enc; |
blocksize = enc ? enc->cipher->block_size : 8; |
blocksize = enc ? enc->cipher->block_size : 8; |
padlen = blocksize - (have % blocksize); |
padlen = blocksize - (have % blocksize); |
if (padlen < 4) |
if (padlen < 4) |