1 /*
2 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
177 this.isFirstAppOutputRecord = true;
178 }
179
180 void changePacketSize(int packetSize) {
181 this.packetSize = packetSize;
182 }
183
184 void changeFragmentSize(int fragmentSize) {
185 this.fragmentSize = fragmentSize;
186 }
187
188 int getMaxPacketSize() {
189 return packetSize;
190 }
191
192 // apply to DTLS SSLEngine
193 void initHandshaker() {
194 // blank
195 }
196
197 @Override
198 public synchronized void close() throws IOException {
199 if (!isClosed) {
200 isClosed = true;
201 writeCipher.dispose();
202 }
203 }
204
205 //
206 // shared helpers
207 //
208
209 // Encrypt a fragment and wrap up a record.
210 //
211 // To be consistent with the spec of SSLEngine.wrap() methods, the
212 // destination ByteBuffer's position is updated to reflect the amount
213 // of data produced. The limit remains the same.
214 static long encrypt(Authenticator authenticator,
215 CipherBox encCipher, byte contentType, ByteBuffer destination,
216 int headerOffset, int dstLim, int headerSize,
217 ProtocolVersion protocolVersion, boolean isDTLS) {
218
219 byte[] sequenceNumber = null;
220 int dstContent = destination.position();
221
222 // Acquire the current sequence number before using.
223 if (isDTLS) {
224 sequenceNumber = authenticator.sequenceNumber();
225 }
226
227 // "flip" but skip over header again, add MAC & encrypt
228 if (authenticator instanceof MAC) {
229 MAC signer = (MAC)authenticator;
230 if (signer.MAClen() != 0) {
231 byte[] hash = signer.compute(contentType, destination, false);
232
233 /*
234 * position was advanced to limit in MAC compute above.
235 *
236 * Mark next area as writable (above layers should have
237 * established that we have plenty of room), then write
238 * out the hash.
239 */
240 destination.limit(destination.limit() + hash.length);
241 destination.put(hash);
242
243 // reset the position and limit
244 destination.limit(destination.position());
245 destination.position(dstContent);
246 }
247 }
248
249 if (!encCipher.isNullCipher()) {
250 if (protocolVersion.useTLS11PlusSpec() &&
251 (encCipher.isCBCMode() || encCipher.isAEADMode())) {
252 byte[] nonce = encCipher.createExplicitNonce(
253 authenticator, contentType, destination.remaining());
254 destination.position(headerOffset + headerSize);
255 destination.put(nonce);
256 }
257 if (!encCipher.isAEADMode()) {
258 // The explicit IV in TLS 1.1 and later can be encrypted.
259 destination.position(headerOffset + headerSize);
260 } // Otherwise, DON'T encrypt the nonce_explicit for AEAD mode
261
262 // Encrypt may pad, so again the limit may be changed.
263 encCipher.encrypt(destination, dstLim);
264 } else {
265 destination.position(destination.limit());
266 }
267
268 // Finish out the record header.
269 int fragLen = destination.limit() - headerOffset - headerSize;
270
271 destination.put(headerOffset, contentType); // content type
272 destination.put(headerOffset + 1, protocolVersion.major);
273 destination.put(headerOffset + 2, protocolVersion.minor);
274 if (!isDTLS) {
275 // fragment length
276 destination.put(headerOffset + 3, (byte)(fragLen >> 8));
277 destination.put(headerOffset + 4, (byte)fragLen);
278 } else {
279 // epoch and sequence_number
280 destination.put(headerOffset + 3, sequenceNumber[0]);
281 destination.put(headerOffset + 4, sequenceNumber[1]);
282 destination.put(headerOffset + 5, sequenceNumber[2]);
283 destination.put(headerOffset + 6, sequenceNumber[3]);
284 destination.put(headerOffset + 7, sequenceNumber[4]);
285 destination.put(headerOffset + 8, sequenceNumber[5]);
286 destination.put(headerOffset + 9, sequenceNumber[6]);
287 destination.put(headerOffset + 10, sequenceNumber[7]);
288
289 // fragment length
290 destination.put(headerOffset + 11, (byte)(fragLen >> 8));
291 destination.put(headerOffset + 12, (byte)fragLen);
292
293 // Increase the sequence number for next use.
294 authenticator.increaseSequenceNumber();
295 }
296
297 // Update destination position to reflect the amount of data produced.
298 destination.position(destination.limit());
299
300 return Authenticator.toLong(sequenceNumber);
301 }
302
303 // Encrypt a fragment and wrap up a record.
304 //
305 // Uses the internal expandable buf variable and the current
306 // protocolVersion variable.
307 void encrypt(Authenticator authenticator,
308 CipherBox encCipher, byte contentType, int headerSize) {
309
310 int position = headerSize + writeCipher.getExplicitNonceSize();
311
312 // "flip" but skip over header again, add MAC & encrypt
313 int macLen = 0;
314 if (authenticator instanceof MAC) {
315 MAC signer = (MAC)authenticator;
|
1 /*
2 * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
177 this.isFirstAppOutputRecord = true;
178 }
179
180 void changePacketSize(int packetSize) {
181 this.packetSize = packetSize;
182 }
183
184 void changeFragmentSize(int fragmentSize) {
185 this.fragmentSize = fragmentSize;
186 }
187
188 int getMaxPacketSize() {
189 return packetSize;
190 }
191
192 // apply to DTLS SSLEngine
193 void initHandshaker() {
194 // blank
195 }
196
197 // apply to DTLS SSLEngine
198 void launchRetransmission() {
199 // blank
200 }
201
202 @Override
203 public synchronized void close() throws IOException {
204 if (!isClosed) {
205 isClosed = true;
206 writeCipher.dispose();
207 }
208 }
209
210 //
211 // shared helpers
212 //
213
214 // Encrypt a fragment and wrap up a record.
215 //
216 // To be consistent with the spec of SSLEngine.wrap() methods, the
217 // destination ByteBuffer's position is updated to reflect the amount
218 // of data produced. The limit remains the same.
219 static long encrypt(Authenticator authenticator,
220 CipherBox encCipher, byte contentType, ByteBuffer destination,
221 int headerOffset, int dstLim, int headerSize,
222 ProtocolVersion protocolVersion, boolean isDTLS) {
223
224 byte[] sequenceNumber = null;
225 int dstContent = destination.position();
226
227 // Acquire the current sequence number before using.
228 if (isDTLS) {
229 sequenceNumber = authenticator.sequenceNumber();
230 }
231
232 // The sequence number may be shared for different purpose.
233 boolean sharedSequenceNumber = false;
234
235 // "flip" but skip over header again, add MAC & encrypt
236 if (authenticator instanceof MAC) {
237 MAC signer = (MAC)authenticator;
238 if (signer.MAClen() != 0) {
239 byte[] hash = signer.compute(contentType, destination, false);
240
241 /*
242 * position was advanced to limit in MAC compute above.
243 *
244 * Mark next area as writable (above layers should have
245 * established that we have plenty of room), then write
246 * out the hash.
247 */
248 destination.limit(destination.limit() + hash.length);
249 destination.put(hash);
250
251 // reset the position and limit
252 destination.limit(destination.position());
253 destination.position(dstContent);
254
255 // The signer has used and increased the sequence number.
256 if (isDTLS) {
257 sharedSequenceNumber = true;
258 }
259 }
260 }
261
262 if (!encCipher.isNullCipher()) {
263 if (protocolVersion.useTLS11PlusSpec() &&
264 (encCipher.isCBCMode() || encCipher.isAEADMode())) {
265 byte[] nonce = encCipher.createExplicitNonce(
266 authenticator, contentType, destination.remaining());
267 destination.position(headerOffset + headerSize);
268 destination.put(nonce);
269 }
270 if (!encCipher.isAEADMode()) {
271 // The explicit IV in TLS 1.1 and later can be encrypted.
272 destination.position(headerOffset + headerSize);
273 } // Otherwise, DON'T encrypt the nonce_explicit for AEAD mode
274
275 // Encrypt may pad, so again the limit may be changed.
276 encCipher.encrypt(destination, dstLim);
277
278 // The cipher has used and increased the sequence number.
279 if (isDTLS && encCipher.isAEADMode()) {
280 sharedSequenceNumber = true;
281 }
282 } else {
283 destination.position(destination.limit());
284 }
285
286 // Finish out the record header.
287 int fragLen = destination.limit() - headerOffset - headerSize;
288
289 destination.put(headerOffset, contentType); // content type
290 destination.put(headerOffset + 1, protocolVersion.major);
291 destination.put(headerOffset + 2, protocolVersion.minor);
292 if (!isDTLS) {
293 // fragment length
294 destination.put(headerOffset + 3, (byte)(fragLen >> 8));
295 destination.put(headerOffset + 4, (byte)fragLen);
296 } else {
297 // epoch and sequence_number
298 destination.put(headerOffset + 3, sequenceNumber[0]);
299 destination.put(headerOffset + 4, sequenceNumber[1]);
300 destination.put(headerOffset + 5, sequenceNumber[2]);
301 destination.put(headerOffset + 6, sequenceNumber[3]);
302 destination.put(headerOffset + 7, sequenceNumber[4]);
303 destination.put(headerOffset + 8, sequenceNumber[5]);
304 destination.put(headerOffset + 9, sequenceNumber[6]);
305 destination.put(headerOffset + 10, sequenceNumber[7]);
306
307 // fragment length
308 destination.put(headerOffset + 11, (byte)(fragLen >> 8));
309 destination.put(headerOffset + 12, (byte)fragLen);
310
311 // Increase the sequence number for next use if it is not shared.
312 if (!sharedSequenceNumber) {
313 authenticator.increaseSequenceNumber();
314 }
315 }
316
317 // Update destination position to reflect the amount of data produced.
318 destination.position(destination.limit());
319
320 return Authenticator.toLong(sequenceNumber);
321 }
322
323 // Encrypt a fragment and wrap up a record.
324 //
325 // Uses the internal expandable buf variable and the current
326 // protocolVersion variable.
327 void encrypt(Authenticator authenticator,
328 CipherBox encCipher, byte contentType, int headerSize) {
329
330 int position = headerSize + writeCipher.getExplicitNonceSize();
331
332 // "flip" but skip over header again, add MAC & encrypt
333 int macLen = 0;
334 if (authenticator instanceof MAC) {
335 MAC signer = (MAC)authenticator;
|