diff --git a/jdk/src/share/classes/sun/security/ssl/InputRecord.java b/jdk/src/share/classes/sun/security/ssl/InputRecord.java index 377c50e8260..8d32a7f1bd7 100644 --- a/jdk/src/share/classes/sun/security/ssl/InputRecord.java +++ b/jdk/src/share/classes/sun/security/ssl/InputRecord.java @@ -100,7 +100,7 @@ void changeReadCiphers(SSLReadCipher readCipher) { * Since MAC's doFinal() is called for every SSL/TLS packet, it's * not necessary to do the same with MAC's. */ - readCipher.dispose(); + this.readCipher.dispose(); this.readCipher = readCipher; } diff --git a/jdk/src/share/classes/sun/security/ssl/OutputRecord.java b/jdk/src/share/classes/sun/security/ssl/OutputRecord.java index 6bd5baeafaa..b1a11a7a2bf 100644 --- a/jdk/src/share/classes/sun/security/ssl/OutputRecord.java +++ b/jdk/src/share/classes/sun/security/ssl/OutputRecord.java @@ -123,6 +123,11 @@ abstract void encodeHandshake(byte[] buffer, // SSLEngine and SSLSocket abstract void encodeChangeCipherSpec() throws IOException; + // SSLEngine and SSLSocket + void disposeWriteCipher() { + throw new UnsupportedOperationException(); + } + // apply to SSLEngine only Ciphertext encode( ByteBuffer[] srcs, int srcsOffset, int srcsLength, @@ -170,7 +175,7 @@ synchronized void changeWriteCiphers(SSLWriteCipher writeCipher, * Since MAC's doFinal() is called for every SSL/TLS packet, it's * not necessary to do the same with MAC's. */ - writeCipher.dispose(); + disposeWriteCipher(); this.writeCipher = writeCipher; this.isFirstAppOutputRecord = true; @@ -194,7 +199,7 @@ synchronized void changeWriteCiphers(SSLWriteCipher writeCipher, flush(); // Dispose of any intermediate state in the underlying cipher. - writeCipher.dispose(); + disposeWriteCipher(); this.writeCipher = writeCipher; this.isFirstAppOutputRecord = true; diff --git a/jdk/src/share/classes/sun/security/ssl/SSLEngineOutputRecord.java b/jdk/src/share/classes/sun/security/ssl/SSLEngineOutputRecord.java index ee82d2743a3..6c2fb43c64b 100644 --- a/jdk/src/share/classes/sun/security/ssl/SSLEngineOutputRecord.java +++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineOutputRecord.java @@ -146,6 +146,15 @@ void encodeChangeCipherSpec() throws IOException { fragmenter.queueUpChangeCipherSpec(); } + @Override + void disposeWriteCipher() { + if (fragmenter == null) { + writeCipher.dispose(); + } else { + fragmenter.queueUpCipherDispose(); + } + } + @Override void encodeV2NoCipher() throws IOException { isTalkingToV2 = true; @@ -356,6 +365,7 @@ private static class RecordMemo { byte majorVersion; byte minorVersion; SSLWriteCipher encodeCipher; + boolean disposeCipher; byte[] fragment; } @@ -416,6 +426,15 @@ void queueUpAlert(byte level, byte description) { handshakeMemos.add(memo); } + void queueUpCipherDispose() { + RecordMemo lastMemo = handshakeMemos.peekLast(); + if (lastMemo != null) { + lastMemo.disposeCipher = true; + } else { + writeCipher.dispose(); + } + } + Ciphertext acquireCiphertext(ByteBuffer dstBuf) throws IOException { if (isEmpty()) { return null; @@ -515,6 +534,9 @@ Ciphertext acquireCiphertext(ByteBuffer dstBuf) throws IOException { dstPos, dstLim, headerSize, ProtocolVersion.valueOf(memo.majorVersion, memo.minorVersion)); + if (memo.disposeCipher) { + memo.encodeCipher.dispose(); + } if (SSLLogger.isOn && SSLLogger.isOn("packet")) { ByteBuffer temporary = dstBuf.duplicate(); diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSocketOutputRecord.java b/jdk/src/share/classes/sun/security/ssl/SSLSocketOutputRecord.java index 23205061e5f..0dbb6f3de77 100644 --- a/jdk/src/share/classes/sun/security/ssl/SSLSocketOutputRecord.java +++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketOutputRecord.java @@ -230,6 +230,11 @@ synchronized void encodeChangeCipherSpec() throws IOException { count = 0; } + @Override + void disposeWriteCipher() { + writeCipher.dispose(); + } + @Override public synchronized void flush() throws IOException { int position = headerSize + writeCipher.getExplicitNonceSize();