annotate src/com/trilead/ssh2/transport/TransportConnection.java @ 319:776a220dbcc6 ganymed

add ecdsa key support everywhere
author Carl Byington <carl@five-ten-sg.com>
date Thu, 31 Jul 2014 08:20:47 -0700
parents 0ce5cc452d02
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
1
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
2 package com.trilead.ssh2.transport;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
3
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
4 import java.io.IOException;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
5 import java.io.InputStream;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
6 import java.io.OutputStream;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
7 import java.security.SecureRandom;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
8
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
9 import com.trilead.ssh2.compression.ICompressor;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
10 import com.trilead.ssh2.crypto.cipher.BlockCipher;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
11 import com.trilead.ssh2.crypto.cipher.CipherInputStream;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
12 import com.trilead.ssh2.crypto.cipher.CipherOutputStream;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
13 import com.trilead.ssh2.crypto.cipher.NullCipher;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
14 import com.trilead.ssh2.crypto.digest.MAC;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
15 import com.trilead.ssh2.log.Logger;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
16 import com.trilead.ssh2.packets.Packets;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
17
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
18
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
19 /**
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
20 * TransportConnection.
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
21 *
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
22 * @author Christian Plattner, plattner@trilead.com
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
23 * @version $Id: TransportConnection.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
24 */
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
25 public class TransportConnection {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
26 private static final Logger log = Logger.getLogger(TransportConnection.class);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
27
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
28 int send_seq_number = 0;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
29
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
30 int recv_seq_number = 0;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
31
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
32 CipherInputStream cis;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
33
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
34 CipherOutputStream cos;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
35
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
36 boolean useRandomPadding = false;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
37
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
38 /* Depends on current MAC and CIPHER */
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
39
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
40 MAC send_mac;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
41
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
42 byte[] send_mac_buffer;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
43
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
44 int send_padd_blocksize = 8;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
45
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
46 MAC recv_mac;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
47
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
48 byte[] recv_mac_buffer;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
49
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
50 byte[] recv_mac_buffer_cmp;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
51
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
52 int recv_padd_blocksize = 8;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
53
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
54 ICompressor recv_comp = null;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
55
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
56 ICompressor send_comp = null;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
57
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
58 boolean can_recv_compress = false;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
59
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
60 boolean can_send_compress = false;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
61
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
62 byte[] recv_comp_buffer;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
63
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
64 byte[] send_comp_buffer;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
65
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
66 /* won't change */
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
67
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
68 final byte[] send_padding_buffer = new byte[256];
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
69
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
70 final byte[] send_packet_header_buffer = new byte[5];
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
71
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
72 final byte[] recv_padding_buffer = new byte[256];
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
73
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
74 final byte[] recv_packet_header_buffer = new byte[5];
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
75
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
76 boolean recv_packet_header_present = false;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
77
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
78 ClientServerHello csh;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
79
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
80 final SecureRandom rnd;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
81
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
82 public TransportConnection(InputStream is, OutputStream os, SecureRandom rnd) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
83 this.cis = new CipherInputStream(new NullCipher(), is);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
84 this.cos = new CipherOutputStream(new NullCipher(), os);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
85 this.rnd = rnd;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
86 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
87
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
88 public void changeRecvCipher(BlockCipher bc, MAC mac) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
89 cis.changeCipher(bc);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
90 recv_mac = mac;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
91 recv_mac_buffer = (mac != null) ? new byte[mac.size()] : null;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
92 recv_mac_buffer_cmp = (mac != null) ? new byte[mac.size()] : null;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
93 recv_padd_blocksize = bc.getBlockSize();
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
94
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
95 if (recv_padd_blocksize < 8)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
96 recv_padd_blocksize = 8;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
97 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
98
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
99 public void changeSendCipher(BlockCipher bc, MAC mac) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
100 if ((bc instanceof NullCipher) == false) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
101 /* Only use zero byte padding for the first few packets */
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
102 useRandomPadding = true;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
103 /* Once we start encrypting, there is no way back */
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
104 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
105
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
106 cos.changeCipher(bc);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
107 send_mac = mac;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
108 send_mac_buffer = (mac != null) ? new byte[mac.size()] : null;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
109 send_padd_blocksize = bc.getBlockSize();
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
110
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
111 if (send_padd_blocksize < 8)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
112 send_padd_blocksize = 8;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
113 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
114
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
115 public void changeRecvCompression(ICompressor comp) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
116 recv_comp = comp;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
117
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
118 if (comp != null) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
119 recv_comp_buffer = new byte[comp.getBufferSize()];
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
120 can_recv_compress |= recv_comp.canCompressPreauth();
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
121 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
122 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
123
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
124 public void changeSendCompression(ICompressor comp) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
125 send_comp = comp;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
126
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
127 if (comp != null) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
128 send_comp_buffer = new byte[comp.getBufferSize()];
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
129 can_send_compress |= send_comp.canCompressPreauth();
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
130 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
131 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
132
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
133 public void sendMessage(byte[] message) throws IOException {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
134 sendMessage(message, 0, message.length, 0);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
135 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
136
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
137 public void sendMessage(byte[] message, int off, int len) throws IOException {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
138 sendMessage(message, off, len, 0);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
139 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
140
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
141 public int getPacketOverheadEstimate() {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
142 // return an estimate for the paket overhead (for send operations)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
143 return 5 + 4 + (send_padd_blocksize - 1) + send_mac_buffer.length;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
144 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
145
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
146 public void sendMessage(byte[] message, int off, int len, int padd) throws IOException {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
147 if (padd < 4)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
148 padd = 4;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
149 else if (padd > 64)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
150 padd = 64;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
151
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
152 if (send_comp != null && can_send_compress) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
153 if (send_comp_buffer.length < message.length + 1024)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
154 send_comp_buffer = new byte[message.length + 1024];
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
155
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
156 len = send_comp.compress(message, off, len, send_comp_buffer);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
157 message = send_comp_buffer;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
158 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
159
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
160 int packet_len = 5 + len + padd; /* Minimum allowed padding is 4 */
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
161 int slack = packet_len % send_padd_blocksize;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
162
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
163 if (slack != 0) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
164 packet_len += (send_padd_blocksize - slack);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
165 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
166
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
167 if (packet_len < 16)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
168 packet_len = 16;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
169
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
170 int padd_len = packet_len - (5 + len);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
171
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
172 if (useRandomPadding) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
173 for (int i = 0; i < padd_len; i = i + 4) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
174 /*
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
175 * don't waste calls to rnd.nextInt() (by using only 8bit of the
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
176 * output). just believe me: even though we may write here up to 3
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
177 * bytes which won't be used, there is no "buffer overflow" (i.e.,
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
178 * arrayindexoutofbounds). the padding buffer is big enough =) (256
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
179 * bytes, and that is bigger than any current cipher block size + 64).
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
180 */
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
181 int r = rnd.nextInt();
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
182 send_padding_buffer[i] = (byte) r;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
183 send_padding_buffer[i + 1] = (byte)(r >> 8);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
184 send_padding_buffer[i + 2] = (byte)(r >> 16);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
185 send_padding_buffer[i + 3] = (byte)(r >> 24);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
186 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
187 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
188 else {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
189 /* use zero padding for unencrypted traffic */
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
190 for (int i = 0; i < padd_len; i++)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
191 send_padding_buffer[i] = 0;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
192
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
193 /* Actually this code is paranoid: we never filled any
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
194 * bytes into the padding buffer so far, therefore it should
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
195 * consist of zeros only.
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
196 */
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
197 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
198
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
199 send_packet_header_buffer[0] = (byte)((packet_len - 4) >> 24);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
200 send_packet_header_buffer[1] = (byte)((packet_len - 4) >> 16);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
201 send_packet_header_buffer[2] = (byte)((packet_len - 4) >> 8);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
202 send_packet_header_buffer[3] = (byte)((packet_len - 4));
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
203 send_packet_header_buffer[4] = (byte) padd_len;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
204 cos.write(send_packet_header_buffer, 0, 5);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
205 cos.write(message, off, len);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
206 cos.write(send_padding_buffer, 0, padd_len);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
207
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
208 if (send_mac != null) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
209 send_mac.initMac(send_seq_number);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
210 send_mac.update(send_packet_header_buffer, 0, 5);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
211 send_mac.update(message, off, len);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
212 send_mac.update(send_padding_buffer, 0, padd_len);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
213 send_mac.getMac(send_mac_buffer, 0);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
214 cos.writePlain(send_mac_buffer, 0, send_mac_buffer.length);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
215 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
216
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
217 cos.flush();
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
218
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
219 if (log.isEnabled()) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
220 log.log(90, "Sent " + Packets.getMessageName(message[off] & 0xff) + " " + len + " bytes payload");
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
221 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
222
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
223 send_seq_number++;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
224 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
225
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
226 public int peekNextMessageLength() throws IOException {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
227 if (recv_packet_header_present == false) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
228 cis.read(recv_packet_header_buffer, 0, 5);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
229 recv_packet_header_present = true;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
230 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
231
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
232 int packet_length = ((recv_packet_header_buffer[0] & 0xff) << 24)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
233 | ((recv_packet_header_buffer[1] & 0xff) << 16) | ((recv_packet_header_buffer[2] & 0xff) << 8)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
234 | ((recv_packet_header_buffer[3] & 0xff));
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
235 int padding_length = recv_packet_header_buffer[4] & 0xff;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
236
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
237 if (packet_length > 35000 || packet_length < 12)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
238 throw new IOException("Illegal packet size! (" + packet_length + ")");
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
239
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
240 int payload_length = packet_length - padding_length - 1;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
241
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
242 if (payload_length < 0)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
243 throw new IOException("Illegal padding_length in packet from remote (" + padding_length + ")");
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
244
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
245 return payload_length;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
246 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
247
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
248 public int receiveMessage(byte buffer[], int off, int len) throws IOException {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
249 if (recv_packet_header_present == false) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
250 cis.read(recv_packet_header_buffer, 0, 5);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
251 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
252 else
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
253 recv_packet_header_present = false;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
254
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
255 int packet_length = ((recv_packet_header_buffer[0] & 0xff) << 24)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
256 | ((recv_packet_header_buffer[1] & 0xff) << 16) | ((recv_packet_header_buffer[2] & 0xff) << 8)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
257 | ((recv_packet_header_buffer[3] & 0xff));
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
258 int padding_length = recv_packet_header_buffer[4] & 0xff;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
259
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
260 if (packet_length > 35000 || packet_length < 12)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
261 throw new IOException("Illegal packet size! (" + packet_length + ")");
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
262
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
263 int payload_length = packet_length - padding_length - 1;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
264
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
265 if (payload_length < 0)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
266 throw new IOException("Illegal padding_length in packet from remote (" + padding_length + ")");
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
267
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
268 if (payload_length >= len)
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
269 throw new IOException("Receive buffer too small (" + len + ", need " + payload_length + ")");
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
270
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
271 cis.read(buffer, off, payload_length);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
272 cis.read(recv_padding_buffer, 0, padding_length);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
273
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
274 if (recv_mac != null) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
275 cis.readPlain(recv_mac_buffer, 0, recv_mac_buffer.length);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
276 recv_mac.initMac(recv_seq_number);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
277 recv_mac.update(recv_packet_header_buffer, 0, 5);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
278 recv_mac.update(buffer, off, payload_length);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
279 recv_mac.update(recv_padding_buffer, 0, padding_length);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
280 recv_mac.getMac(recv_mac_buffer_cmp, 0);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
281
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
282 for (int i = 0; i < recv_mac_buffer.length; i++) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
283 if (recv_mac_buffer[i] != recv_mac_buffer_cmp[i])
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
284 throw new IOException("Remote sent corrupt MAC.");
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
285 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
286 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
287
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
288 recv_seq_number++;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
289
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
290 if (log.isEnabled()) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
291 log.log(90, "Received " + Packets.getMessageName(buffer[off] & 0xff) + " " + payload_length
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
292 + " bytes payload");
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
293 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
294
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
295 if (recv_comp != null && can_recv_compress) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
296 int[] uncomp_len = new int[] { payload_length };
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
297 buffer = recv_comp.uncompress(buffer, off, uncomp_len);
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
298
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
299 if (buffer == null) {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
300 throw new IOException("Error while inflating remote data");
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
301 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
302 else {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
303 return uncomp_len[0];
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
304 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
305 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
306 else {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
307 return payload_length;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
308 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
309 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
310
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
311 /**
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
312 *
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
313 */
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
314 public void startCompression() {
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
315 can_recv_compress = true;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
316 can_send_compress = true;
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
317 }
0ce5cc452d02 initial version
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
318 }