src/java.base/share/classes/sun/security/ssl/OutputRecord.java
Print this page
8167680 DTLS implementation bugs
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -192,10 +192,15 @@
// apply to DTLS SSLEngine
void initHandshaker() {
// blank
}
+ // apply to DTLS SSLEngine
+ void launchRetransmission() {
+ // blank
+ }
+
@Override
public synchronized void close() throws IOException {
if (!isClosed) {
isClosed = true;
writeCipher.dispose();
@@ -222,10 +227,13 @@
// Acquire the current sequence number before using.
if (isDTLS) {
sequenceNumber = authenticator.sequenceNumber();
}
+ // The sequence number may be shared for different purpose.
+ boolean sharedSequenceNumber = false;
+
// "flip" but skip over header again, add MAC & encrypt
if (authenticator instanceof MAC) {
MAC signer = (MAC)authenticator;
if (signer.MAClen() != 0) {
byte[] hash = signer.compute(contentType, destination, false);
@@ -241,12 +249,17 @@
destination.put(hash);
// reset the position and limit
destination.limit(destination.position());
destination.position(dstContent);
+
+ // The signer has used and increased the sequence number.
+ if (isDTLS) {
+ sharedSequenceNumber = true;
}
}
+ }
if (!encCipher.isNullCipher()) {
if (protocolVersion.useTLS11PlusSpec() &&
(encCipher.isCBCMode() || encCipher.isAEADMode())) {
byte[] nonce = encCipher.createExplicitNonce(
@@ -259,10 +272,15 @@
destination.position(headerOffset + headerSize);
} // Otherwise, DON'T encrypt the nonce_explicit for AEAD mode
// Encrypt may pad, so again the limit may be changed.
encCipher.encrypt(destination, dstLim);
+
+ // The cipher has used and increased the sequence number.
+ if (isDTLS && encCipher.isAEADMode()) {
+ sharedSequenceNumber = true;
+ }
} else {
destination.position(destination.limit());
}
// Finish out the record header.
@@ -288,13 +306,15 @@
// fragment length
destination.put(headerOffset + 11, (byte)(fragLen >> 8));
destination.put(headerOffset + 12, (byte)fragLen);
- // Increase the sequence number for next use.
+ // Increase the sequence number for next use if it is not shared.
+ if (!sharedSequenceNumber) {
authenticator.increaseSequenceNumber();
}
+ }
// Update destination position to reflect the amount of data produced.
destination.position(destination.limit());
return Authenticator.toLong(sequenceNumber);