diff options
Diffstat (limited to 'crypto/openssh/packet.c')
-rw-r--r-- | crypto/openssh/packet.c | 145 |
1 files changed, 129 insertions, 16 deletions
diff --git a/crypto/openssh/packet.c b/crypto/openssh/packet.c index b3e6d84..759361b 100644 --- a/crypto/openssh/packet.c +++ b/crypto/openssh/packet.c @@ -37,7 +37,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: packet.c,v 1.90 2002/02/27 21:23:13 stevesk Exp $"); +RCSID("$OpenBSD: packet.c,v 1.95 2002/06/19 18:01:00 markus Exp $"); #include "xmalloc.h" #include "buffer.h" @@ -60,6 +60,7 @@ RCSID("$OpenBSD: packet.c,v 1.90 2002/02/27 21:23:13 stevesk Exp $"); #include "log.h" #include "canohost.h" #include "misc.h" +#include "ssh.h" #ifdef PACKET_DEBUG #define DBG(x) x @@ -86,10 +87,10 @@ static CipherContext receive_context; static CipherContext send_context; /* Buffer for raw input data from the socket. */ -static Buffer input; +Buffer input; /* Buffer for raw output data going to the socket. */ -static Buffer output; +Buffer output; /* Buffer for the partial outgoing packet being constructed. */ static Buffer outgoing_packet; @@ -115,6 +116,12 @@ static int interactive_mode = 0; /* Session key information for Encryption and MAC */ Newkeys *newkeys[MODE_MAX]; +static u_int32_t read_seqnr = 0; +static u_int32_t send_seqnr = 0; + +/* Session key for protocol v1 */ +static u_char ssh1_key[SSH_SESSION_KEY_LENGTH]; +static u_int ssh1_keylen; /* roundup current message to extra_pad bytes */ static u_char extra_pad = 0; @@ -171,6 +178,99 @@ packet_connection_is_on_socket(void) return 1; } +/* + * Exports an IV from the CipherContext required to export the key + * state back from the unprivileged child to the privileged parent + * process. + */ + +void +packet_get_keyiv(int mode, u_char *iv, u_int len) +{ + CipherContext *cc; + + if (mode == MODE_OUT) + cc = &send_context; + else + cc = &receive_context; + + cipher_get_keyiv(cc, iv, len); +} + +int +packet_get_keycontext(int mode, u_char *dat) +{ + CipherContext *cc; + + if (mode == MODE_OUT) + cc = &send_context; + else + cc = &receive_context; + + return (cipher_get_keycontext(cc, dat)); +} + +void +packet_set_keycontext(int mode, u_char *dat) +{ + CipherContext *cc; + + if (mode == MODE_OUT) + cc = &send_context; + else + cc = &receive_context; + + cipher_set_keycontext(cc, dat); +} + +int +packet_get_keyiv_len(int mode) +{ + CipherContext *cc; + + if (mode == MODE_OUT) + cc = &send_context; + else + cc = &receive_context; + + return (cipher_get_keyiv_len(cc)); +} +void +packet_set_iv(int mode, u_char *dat) +{ + CipherContext *cc; + + if (mode == MODE_OUT) + cc = &send_context; + else + cc = &receive_context; + + cipher_set_keyiv(cc, dat); +} +int +packet_get_ssh1_cipher() +{ + return (cipher_get_number(receive_context.cipher)); +} + + +u_int32_t +packet_get_seqnr(int mode) +{ + return (mode == MODE_IN ? read_seqnr : send_seqnr); +} + +void +packet_set_seqnr(int mode, u_int32_t seqnr) +{ + if (mode == MODE_IN) + read_seqnr = seqnr; + else if (mode == MODE_OUT) + send_seqnr = seqnr; + else + fatal("packet_set_seqnr: bad mode %d", mode); +} + /* returns 1 if connection is via ipv4 */ int @@ -291,6 +391,7 @@ packet_start_compression(int level) * key is used for both sending and reception. However, both directions are * encrypted independently of each other. */ + void packet_set_encryption_key(const u_char *key, u_int keylen, int number) @@ -300,10 +401,23 @@ packet_set_encryption_key(const u_char *key, u_int keylen, fatal("packet_set_encryption_key: unknown cipher number %d", number); if (keylen < 20) fatal("packet_set_encryption_key: keylen too small: %d", keylen); + if (keylen > SSH_SESSION_KEY_LENGTH) + fatal("packet_set_encryption_key: keylen too big: %d", keylen); + memcpy(ssh1_key, key, keylen); + ssh1_keylen = keylen; cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT); cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT); } +u_int +packet_get_encryption_key(u_char *key) +{ + if (key == NULL) + return (ssh1_keylen); + memcpy(key, ssh1_key, ssh1_keylen); + return (ssh1_keylen); +} + /* Start constructing a packet to send. */ void packet_start(u_char type) @@ -433,7 +547,7 @@ packet_send1(void) */ } -static void +void set_newkeys(int mode) { Enc *enc; @@ -477,8 +591,9 @@ set_newkeys(int mode) DBG(debug("cipher_init_context: %d", mode)); cipher_init(cc, enc->cipher, enc->key, enc->key_len, enc->iv, enc->block_size, encrypt); - memset(enc->iv, 0, enc->block_size); - memset(enc->key, 0, enc->key_len); + /* Deleting the keys does not gain extra security */ + /* memset(enc->iv, 0, enc->block_size); + memset(enc->key, 0, enc->key_len); */ if (comp->type != 0 && comp->enabled == 0) { packet_init_compression(); if (mode == MODE_OUT) @@ -495,7 +610,6 @@ set_newkeys(int mode) static void packet_send2(void) { - static u_int32_t seqnr = 0; u_char type, *cp, *macbuf = NULL; u_char padlen, pad; u_int packet_length = 0; @@ -549,7 +663,7 @@ packet_send2(void) /* will wrap if extra_pad+padlen > 255 */ extra_pad = roundup(extra_pad, block_size); pad = extra_pad - ((len + padlen) % extra_pad); - debug("packet_send2: adding %d (len %d padlen %d extra_pad %d)", + debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)", pad, len, padlen, extra_pad); padlen += pad; extra_pad = 0; @@ -576,10 +690,10 @@ packet_send2(void) /* compute MAC over seqnr and packet(length fields, payload, padding) */ if (mac && mac->enabled) { - macbuf = mac_compute(mac, seqnr, + macbuf = mac_compute(mac, send_seqnr, buffer_ptr(&outgoing_packet), buffer_len(&outgoing_packet)); - DBG(debug("done calc MAC out #%d", seqnr)); + DBG(debug("done calc MAC out #%d", send_seqnr)); } /* encrypt packet and append to output buffer. */ cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); @@ -593,7 +707,7 @@ packet_send2(void) buffer_dump(&output); #endif /* increment sequence number for outgoing packets */ - if (++seqnr == 0) + if (++send_seqnr == 0) log("outgoing seqnr wraps around"); buffer_clear(&outgoing_packet); @@ -783,7 +897,6 @@ packet_read_poll1(void) static int packet_read_poll2(u_int32_t *seqnr_p) { - static u_int32_t seqnr = 0; static u_int packet_length = 0; u_int padlen, need; u_char *macbuf, *cp, type; @@ -845,17 +958,17 @@ packet_read_poll2(u_int32_t *seqnr_p) * increment sequence number for incoming packet */ if (mac && mac->enabled) { - macbuf = mac_compute(mac, seqnr, + macbuf = mac_compute(mac, read_seqnr, buffer_ptr(&incoming_packet), buffer_len(&incoming_packet)); if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) packet_disconnect("Corrupted MAC on input."); - DBG(debug("MAC #%d ok", seqnr)); + DBG(debug("MAC #%d ok", read_seqnr)); buffer_consume(&input, mac->mac_len); } if (seqnr_p != NULL) - *seqnr_p = seqnr; - if (++seqnr == 0) + *seqnr_p = read_seqnr; + if (++read_seqnr == 0) log("incoming seqnr wraps around"); /* get padlen */ |