< prev index next >

src/java.base/share/classes/sun/security/ssl/OutputRecord.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1996, 2019, 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 --- 1,7 ---- /* ! * Copyright (c) 1996, 2018, 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
*** 28,38 **** import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; - import java.util.concurrent.locks.ReentrantLock; import sun.security.ssl.SSLCipher.SSLWriteCipher; /** * {@code OutputRecord} takes care of the management of SSL/(D)TLS * output records, including buffering, encryption, handshake --- 28,37 ----
*** 67,78 **** int fragmentSize; // closed or not? volatile boolean isClosed; - final ReentrantLock recordLock = new ReentrantLock(); - /* * Mappings from V3 cipher suite encodings to their pure V2 equivalents. * This is taken from the SSL V3 specification, Appendix E. */ private static final int[] V3toV2CipherMap1 = --- 66,75 ----
*** 90,136 **** this.handshakeHash = handshakeHash; // Please set packetSize and protocolVersion in the implementation. } ! void setVersion(ProtocolVersion protocolVersion) { ! recordLock.lock(); ! try { ! this.protocolVersion = protocolVersion; ! } finally { ! recordLock.unlock(); ! } } /* * Updates helloVersion of this record. */ ! void setHelloVersion(ProtocolVersion helloVersion) { ! recordLock.lock(); ! try { ! this.helloVersion = helloVersion; ! } finally { ! recordLock.unlock(); ! } } /* * Return true iff the record is empty -- to avoid doing the work * of sending empty records over the network. */ boolean isEmpty() { return false; } ! boolean seqNumIsHuge() { ! recordLock.lock(); ! try { ! return (writeCipher.authenticator != null) && writeCipher.authenticator.seqNumIsHuge(); - } finally { - recordLock.unlock(); - } } // SSLEngine and SSLSocket abstract void encodeAlert(byte level, byte description) throws IOException; --- 87,118 ---- this.handshakeHash = handshakeHash; // Please set packetSize and protocolVersion in the implementation. } ! synchronized void setVersion(ProtocolVersion protocolVersion) { ! this.protocolVersion = protocolVersion; } /* * Updates helloVersion of this record. */ ! synchronized void setHelloVersion(ProtocolVersion helloVersion) { ! this.helloVersion = helloVersion; } /* * Return true iff the record is empty -- to avoid doing the work * of sending empty records over the network. */ boolean isEmpty() { return false; } ! synchronized boolean seqNumIsHuge() { ! return (writeCipher.authenticator != null) && writeCipher.authenticator.seqNumIsHuge(); } // SSLEngine and SSLSocket abstract void encodeAlert(byte level, byte description) throws IOException;
*** 164,260 **** void setDeliverStream(OutputStream outputStream) { throw new UnsupportedOperationException(); } // Change write ciphers, may use change_cipher_spec record. ! void changeWriteCiphers(SSLWriteCipher writeCipher, boolean useChangeCipherSpec) throws IOException { ! recordLock.lock(); ! try { ! if (isClosed()) { ! if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { ! SSLLogger.warning("outbound has closed, ignore outbound " + ! "change_cipher_spec message"); ! } ! return; ! } ! ! if (useChangeCipherSpec) { ! encodeChangeCipherSpec(); } ! /* ! * Dispose of any intermediate state in the underlying cipher. ! * For PKCS11 ciphers, this will release any attached sessions, ! * and thus make finalization faster. ! * ! * Since MAC's doFinal() is called for every SSL/TLS packet, it's ! * not necessary to do the same with MAC's. ! */ ! writeCipher.dispose(); ! ! this.writeCipher = writeCipher; ! this.isFirstAppOutputRecord = true; ! } finally { ! recordLock.unlock(); } } // Change write ciphers using key_update handshake message. ! void changeWriteCiphers(SSLWriteCipher writeCipher, byte keyUpdateRequest) throws IOException { ! recordLock.lock(); ! try { ! if (isClosed()) { ! if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { ! SSLLogger.warning("outbound has closed, ignore outbound " + ! "key_update handshake message"); ! } ! return; } ! ! // encode the handshake message, KeyUpdate ! byte[] hm = HANDSHAKE_MESSAGE_KEY_UPDATE.clone(); ! hm[hm.length - 1] = keyUpdateRequest; ! encodeHandshake(hm, 0, hm.length); ! flush(); ! ! // Dispose of any intermediate state in the underlying cipher. ! writeCipher.dispose(); ! ! this.writeCipher = writeCipher; ! this.isFirstAppOutputRecord = true; ! } finally { ! recordLock.unlock(); } } ! void changePacketSize(int packetSize) { ! recordLock.lock(); ! try { ! this.packetSize = packetSize; ! } finally { ! recordLock.unlock(); ! } } ! void changeFragmentSize(int fragmentSize) { ! recordLock.lock(); ! try { ! this.fragmentSize = fragmentSize; ! } finally { ! recordLock.unlock(); ! } } ! int getMaxPacketSize() { ! recordLock.lock(); ! try { ! return packetSize; ! } finally { ! recordLock.unlock(); ! } } // apply to DTLS SSLEngine void initHandshaker() { // blank --- 146,217 ---- void setDeliverStream(OutputStream outputStream) { throw new UnsupportedOperationException(); } // Change write ciphers, may use change_cipher_spec record. ! synchronized void changeWriteCiphers(SSLWriteCipher writeCipher, boolean useChangeCipherSpec) throws IOException { ! if (isClosed()) { ! if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { ! SSLLogger.warning("outbound has closed, ignore outbound " + ! "change_cipher_spec message"); } + return; + } ! if (useChangeCipherSpec) { ! encodeChangeCipherSpec(); } + + /* + * Dispose of any intermediate state in the underlying cipher. + * For PKCS11 ciphers, this will release any attached sessions, + * and thus make finalization faster. + * + * Since MAC's doFinal() is called for every SSL/TLS packet, it's + * not necessary to do the same with MAC's. + */ + writeCipher.dispose(); + + this.writeCipher = writeCipher; + this.isFirstAppOutputRecord = true; } // Change write ciphers using key_update handshake message. ! synchronized void changeWriteCiphers(SSLWriteCipher writeCipher, byte keyUpdateRequest) throws IOException { ! if (isClosed()) { ! if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { ! SSLLogger.warning("outbound has closed, ignore outbound " + ! "key_update handshake message"); } ! return; } + + // encode the handshake message, KeyUpdate + byte[] hm = HANDSHAKE_MESSAGE_KEY_UPDATE.clone(); + hm[hm.length - 1] = keyUpdateRequest; + encodeHandshake(hm, 0, hm.length); + flush(); + + // Dispose of any intermediate state in the underlying cipher. + writeCipher.dispose(); + + this.writeCipher = writeCipher; + this.isFirstAppOutputRecord = true; } ! synchronized void changePacketSize(int packetSize) { ! this.packetSize = packetSize; } ! synchronized void changeFragmentSize(int fragmentSize) { ! this.fragmentSize = fragmentSize; } ! synchronized int getMaxPacketSize() { ! return packetSize; } // apply to DTLS SSLEngine void initHandshaker() { // blank
*** 269,290 **** void launchRetransmission() { // blank } @Override ! public void close() throws IOException { ! recordLock.lock(); ! try { ! if (isClosed) { ! return; ! } ! ! isClosed = true; ! writeCipher.dispose(); ! } finally { ! recordLock.unlock(); } } boolean isClosed() { return isClosed; } --- 226,242 ---- void launchRetransmission() { // blank } @Override ! public synchronized void close() throws IOException { ! if (isClosed) { ! return; } + + isClosed = true; + writeCipher.dispose(); } boolean isClosed() { return isClosed; }
< prev index next >