23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package sun.security.ssl; |
26 package sun.security.ssl; |
27 |
27 |
|
28 import java.io.IOException; |
|
29 import java.nio.ByteBuffer; |
|
30 import javax.net.ssl.SSLException; |
|
31 |
28 /** |
32 /** |
29 * SSL/TLS/DTLS records, as pulled off (and put onto) a TCP stream. This is |
33 * SSL/(D)TLS record. |
30 * the base interface, which defines common information and interfaces |
34 * |
|
35 * This is the base interface, which defines common information and interfaces |
31 * used by both Input and Output records. |
36 * used by both Input and Output records. |
32 * |
37 * |
33 * @author David Brownell |
38 * @author David Brownell |
34 */ |
39 */ |
35 interface Record { |
40 interface Record { |
36 |
|
37 /* |
|
38 * There are four record types, which are part of the interface |
|
39 * to this level (along with the maximum record size). |
|
40 * |
|
41 * enum { change_cipher_spec(20), alert(21), handshake(22), |
|
42 * application_data(23), (255) } ContentType; |
|
43 */ |
|
44 static final byte ct_change_cipher_spec = 20; |
|
45 static final byte ct_alert = 21; |
|
46 static final byte ct_handshake = 22; |
|
47 static final byte ct_application_data = 23; |
|
48 |
|
49 static final int maxMacSize = 48; // the max supported MAC or |
41 static final int maxMacSize = 48; // the max supported MAC or |
50 // AEAD tag size |
42 // AEAD tag size |
51 static final int maxDataSize = 16384; // 2^14 bytes of data |
43 static final int maxDataSize = 16384; // 2^14 bytes of data |
52 static final int maxPadding = 256; // block cipher padding |
44 static final int maxPadding = 256; // block cipher padding |
53 static final int maxIVLength = 16; // the max supported IV length |
45 static final int maxIVLength = 16; // the max supported IV length |
57 |
49 |
58 /* |
50 /* |
59 * System property to enable/disable CBC protection in SSL3/TLS1. |
51 * System property to enable/disable CBC protection in SSL3/TLS1. |
60 */ |
52 */ |
61 static final boolean enableCBCProtection = |
53 static final boolean enableCBCProtection = |
62 Debug.getBooleanProperty("jsse.enableCBCProtection", true); |
54 Utilities.getBooleanProperty("jsse.enableCBCProtection", true); |
63 |
55 |
64 /* |
56 /* |
65 * The overflow values of integers of 8, 16 and 24 bits. |
57 * The overflow values of integers of 8, 16 and 24 bits. |
66 */ |
58 */ |
67 static final int OVERFLOW_OF_INT08 = (1 << 8); |
59 static final int OVERFLOW_OF_INT08 = (0x01 << 8); |
68 static final int OVERFLOW_OF_INT16 = (1 << 16); |
60 static final int OVERFLOW_OF_INT16 = (0x01 << 16); |
69 static final int OVERFLOW_OF_INT24 = (1 << 24); |
61 static final int OVERFLOW_OF_INT24 = (0x01 << 24); |
70 |
62 |
71 /** |
63 /* |
72 * Return a description for the given content type. |
64 * Read 8, 16, 24, and 32 bit integer data types, encoded |
|
65 * in standard big-endian form. |
73 */ |
66 */ |
74 static String contentName(byte contentType) { |
67 static int getInt8(ByteBuffer m) throws IOException { |
75 switch (contentType) { |
68 verifyLength(m, 1); |
76 case ct_change_cipher_spec: |
69 return (m.get() & 0xFF); |
77 return "Change Cipher Spec"; |
70 } |
78 case ct_alert: |
71 |
79 return "Alert"; |
72 static int getInt16(ByteBuffer m) throws IOException { |
80 case ct_handshake: |
73 verifyLength(m, 2); |
81 return "Handshake"; |
74 return ((m.get() & 0xFF) << 8) | |
82 case ct_application_data: |
75 (m.get() & 0xFF); |
83 return "Application Data"; |
76 } |
84 default: |
77 |
85 return "contentType = " + contentType; |
78 static int getInt24(ByteBuffer m) throws IOException { |
|
79 verifyLength(m, 3); |
|
80 return ((m.get() & 0xFF) << 16) | |
|
81 ((m.get() & 0xFF) << 8) | |
|
82 (m.get() & 0xFF); |
|
83 } |
|
84 |
|
85 static int getInt32(ByteBuffer m) throws IOException { |
|
86 verifyLength(m, 4); |
|
87 return ((m.get() & 0xFF) << 24) | |
|
88 ((m.get() & 0xFF) << 16) | |
|
89 ((m.get() & 0xFF) << 8) | |
|
90 (m.get() & 0xFF); |
|
91 } |
|
92 |
|
93 /* |
|
94 * Read byte vectors with 8, 16, and 24 bit length encodings. |
|
95 */ |
|
96 static byte[] getBytes8(ByteBuffer m) throws IOException { |
|
97 int len = Record.getInt8(m); |
|
98 verifyLength(m, len); |
|
99 byte[] b = new byte[len]; |
|
100 |
|
101 m.get(b); |
|
102 return b; |
|
103 } |
|
104 |
|
105 static byte[] getBytes16(ByteBuffer m) throws IOException { |
|
106 int len = Record.getInt16(m); |
|
107 verifyLength(m, len); |
|
108 byte[] b = new byte[len]; |
|
109 |
|
110 m.get(b); |
|
111 return b; |
|
112 } |
|
113 |
|
114 static byte[] getBytes24(ByteBuffer m) throws IOException { |
|
115 int len = Record.getInt24(m); |
|
116 verifyLength(m, len); |
|
117 byte[] b = new byte[len]; |
|
118 |
|
119 m.get(b); |
|
120 return b; |
|
121 } |
|
122 |
|
123 /* |
|
124 * Write 8, 16, 24, and 32 bit integer data types, encoded |
|
125 * in standard big-endian form. |
|
126 */ |
|
127 static void putInt8(ByteBuffer m, int i) throws IOException { |
|
128 verifyLength(m, 1); |
|
129 m.put((byte)(i & 0xFF)); |
|
130 } |
|
131 |
|
132 static void putInt16(ByteBuffer m, int i) throws IOException { |
|
133 verifyLength(m, 2); |
|
134 m.put((byte)((i >> 8) & 0xFF)); |
|
135 m.put((byte)(i & 0xFF)); |
|
136 } |
|
137 |
|
138 static void putInt24(ByteBuffer m, int i) throws IOException { |
|
139 verifyLength(m, 3); |
|
140 m.put((byte)((i >> 16) & 0xFF)); |
|
141 m.put((byte)((i >> 8) & 0xFF)); |
|
142 m.put((byte)(i & 0xFF)); |
|
143 } |
|
144 |
|
145 static void putInt32(ByteBuffer m, int i) throws IOException { |
|
146 m.put((byte)((i >> 24) & 0xFF)); |
|
147 m.put((byte)((i >> 16) & 0xFF)); |
|
148 m.put((byte)((i >> 8) & 0xFF)); |
|
149 m.put((byte)(i & 0xFF)); |
|
150 } |
|
151 |
|
152 /* |
|
153 * Write byte vectors with 8, 16, and 24 bit length encodings. |
|
154 */ |
|
155 static void putBytes8(ByteBuffer m, byte[] s) throws IOException { |
|
156 if (s == null || s.length == 0) { |
|
157 verifyLength(m, 1); |
|
158 putInt8(m, 0); |
|
159 } else { |
|
160 verifyLength(m, 1 + s.length); |
|
161 putInt8(m, s.length); |
|
162 m.put(s); |
86 } |
163 } |
87 } |
164 } |
88 |
165 |
89 static boolean isValidContentType(byte contentType) { |
166 static void putBytes16(ByteBuffer m, byte[] s) throws IOException { |
90 return (contentType == 20) || (contentType == 21) || |
167 if (s == null || s.length == 0) { |
91 (contentType == 22) || (contentType == 23); |
168 verifyLength(m, 2); |
|
169 putInt16(m, 0); |
|
170 } else { |
|
171 verifyLength(m, 2 + s.length); |
|
172 putInt16(m, s.length); |
|
173 m.put(s); |
|
174 } |
|
175 } |
|
176 |
|
177 static void putBytes24(ByteBuffer m, byte[] s) throws IOException { |
|
178 if (s == null || s.length == 0) { |
|
179 verifyLength(m, 3); |
|
180 putInt24(m, 0); |
|
181 } else { |
|
182 verifyLength(m, 3 + s.length); |
|
183 putInt24(m, s.length); |
|
184 m.put(s); |
|
185 } |
|
186 } |
|
187 |
|
188 // Verify that the buffer has sufficient remaining. |
|
189 static void verifyLength( |
|
190 ByteBuffer m, int len) throws SSLException { |
|
191 if (len > m.remaining()) { |
|
192 throw new SSLException("Insufficient space in the buffer, " + |
|
193 "may be cause by an unexpected end of handshake data."); |
|
194 } |
92 } |
195 } |
93 } |
196 } |