src/java.base/share/classes/sun/security/ssl/TransportContext.java
branchJDK-8145252-TLS13-branch
changeset 56715 b152d06ed6a9
parent 56660 66c803c3ce32
child 56718 da9979451b7a
equal deleted inserted replaced
56714:2d7e08d730b6 56715:b152d06ed6a9
    33 import java.util.HashMap;
    33 import java.util.HashMap;
    34 import java.util.HashSet;
    34 import java.util.HashSet;
    35 import java.util.List;
    35 import java.util.List;
    36 import java.util.Map;
    36 import java.util.Map;
    37 import java.util.Set;
    37 import java.util.Set;
    38 import javax.crypto.SecretKey;
       
    39 import javax.net.ssl.HandshakeCompletedEvent;
    38 import javax.net.ssl.HandshakeCompletedEvent;
    40 import javax.net.ssl.HandshakeCompletedListener;
    39 import javax.net.ssl.HandshakeCompletedListener;
    41 import javax.net.ssl.SSLEngineResult.HandshakeStatus;
    40 import javax.net.ssl.SSLEngineResult.HandshakeStatus;
    42 import javax.net.ssl.SSLException;
    41 import javax.net.ssl.SSLException;
    43 import javax.net.ssl.SSLSocket;
    42 import javax.net.ssl.SSLSocket;
    58     final InputRecord               inputRecord;
    57     final InputRecord               inputRecord;
    59     final OutputRecord              outputRecord;
    58     final OutputRecord              outputRecord;
    60 
    59 
    61     // connection status
    60     // connection status
    62     boolean                         isUnsureMode;
    61     boolean                         isUnsureMode;
    63     boolean                         isNegotiated;
    62     boolean                         isNegotiated = false;
    64     boolean                         isBroken;
    63     boolean                         isBroken = false;
    65     boolean                         isInputCloseNotified;
    64     boolean                         isInputCloseNotified = false;
    66     boolean                         isOutputCloseNotified;
    65     boolean                         isOutputCloseNotified = false;
    67     Exception                       closeReason;
    66     Exception                       closeReason = null;
    68 
    67 
    69     // negotiated security parameters
    68     // negotiated security parameters
    70     SSLSessionImpl                  conSession;
    69     SSLSessionImpl                  conSession;
    71     ProtocolVersion                 protocolVersion;
    70     ProtocolVersion                 protocolVersion;
    72     String                          applicationProtocol;
    71     String                          applicationProtocol= null;
    73 
    72 
    74     // handshake context
    73     // handshake context
    75     HandshakeContext                handshakeContext;
    74     HandshakeContext                handshakeContext = null;
    76 
    75 
    77     // connection reserved status for handshake.
    76     // connection reserved status for handshake.
    78     boolean                         secureRenegotiation;
    77     boolean                         secureRenegotiation = false;
    79     byte[]                          clientVerifyData;
    78     byte[]                          clientVerifyData;
    80     byte[]                          serverVerifyData;
    79     byte[]                          serverVerifyData;
    81 
    80 
    82     // connection sensitive configuration
    81     // connection sensitive configuration
    83     List<NamedGroup>                serverRequestedNamedGroups;
    82     List<NamedGroup>                serverRequestedNamedGroups;
    84 
    83 
    85     SecretKey baseWriteSecret, baseReadSecret;
       
    86     CipherSuite cipherSuite;
    84     CipherSuite cipherSuite;
       
    85     private static final byte[] emptyByteArray = new byte[0];
    87 
    86 
    88     // Please never use the transport parameter other than storing a
    87     // Please never use the transport parameter other than storing a
    89     // reference to this object.
    88     // reference to this object.
       
    89     // Called by SSLEngineImpl
    90     TransportContext(SSLContextImpl sslContext, SSLTransport transport,
    90     TransportContext(SSLContextImpl sslContext, SSLTransport transport,
    91             InputRecord inputRecord, OutputRecord outputRecord) {
    91             InputRecord inputRecord, OutputRecord outputRecord) {
       
    92         this(sslContext, transport, new SSLConfiguration(sslContext, true),
       
    93                 inputRecord, outputRecord, true);
       
    94     }
       
    95 
       
    96     // Please never use the transport parameter other than storing a
       
    97     // reference to this object.
       
    98     // Called by SSLSocketImpl
       
    99     TransportContext(SSLContextImpl sslContext, SSLTransport transport,
       
   100             InputRecord inputRecord, OutputRecord outputRecord,
       
   101             boolean isClientMode) {
       
   102         this(sslContext, transport,
       
   103                 new SSLConfiguration(sslContext, isClientMode),
       
   104                 inputRecord, outputRecord,false);
       
   105     }
       
   106 
       
   107     // Please never use the transport parameter other than storing a
       
   108     // reference to this object.
       
   109     // Called by SSLSocketImpl with an existing SSLConfig
       
   110     TransportContext(SSLContextImpl sslContext, SSLTransport transport,
       
   111             SSLConfiguration sslConfig,
       
   112             InputRecord inputRecord, OutputRecord outputRecord) {
       
   113         this(sslContext, transport, (SSLConfiguration)sslConfig.clone(),
       
   114                 inputRecord, outputRecord, false);
       
   115     }
       
   116 
       
   117     private TransportContext(SSLContextImpl sslContext, SSLTransport transport,
       
   118             SSLConfiguration sslConfig, InputRecord inputRecord,
       
   119             OutputRecord outputRecord, boolean isUnsureMode) {
    92         this.transport = transport;
   120         this.transport = transport;
    93         this.sslContext = sslContext;
   121         this.sslContext = sslContext;
    94         this.inputRecord = inputRecord;
   122         this.inputRecord = inputRecord;
    95         this.outputRecord = outputRecord;
   123         this.outputRecord = outputRecord;
    96         this.sslConfig = new SSLConfiguration(sslContext, true);
   124         this.sslConfig = sslConfig;
    97         this.sslConfig.maximumPacketSize = outputRecord.getMaxPacketSize();
       
    98         this.isUnsureMode = true;
       
    99 
       
   100         initialize();
       
   101 
       
   102         this.acc = AccessController.getContext();
       
   103         this.consumers = new HashMap<>();
       
   104     }
       
   105 
       
   106     // Please never use the transport parameter other than storing a
       
   107     // reference to this object.
       
   108     TransportContext(SSLContextImpl sslContext, SSLTransport transport,
       
   109             InputRecord inputRecord, OutputRecord outputRecord,
       
   110             boolean isClientMode) {
       
   111         this.transport = transport;
       
   112         this.sslContext = sslContext;
       
   113         this.inputRecord = inputRecord;
       
   114         this.outputRecord = outputRecord;
       
   115         this.sslConfig = new SSLConfiguration(sslContext, isClientMode);
       
   116         this.sslConfig.maximumPacketSize = outputRecord.getMaxPacketSize();
       
   117         this.isUnsureMode = false;
       
   118 
       
   119         initialize();
       
   120 
       
   121         this.acc = AccessController.getContext();
       
   122         this.consumers = new HashMap<>();
       
   123     }
       
   124 
       
   125     // Please never use the transport parameter other than storing a
       
   126     // reference to this object.
       
   127     TransportContext(SSLContextImpl sslContext, SSLTransport transport,
       
   128             SSLConfiguration sslConfig,
       
   129             InputRecord inputRecord, OutputRecord outputRecord) {
       
   130         this.transport = transport;
       
   131         this.sslContext = sslContext;
       
   132         this.inputRecord = inputRecord;
       
   133         this.outputRecord = outputRecord;
       
   134         this.sslConfig = (SSLConfiguration)sslConfig.clone();
       
   135         if (this.sslConfig.maximumPacketSize == 0) {
   125         if (this.sslConfig.maximumPacketSize == 0) {
   136             this.sslConfig.maximumPacketSize = outputRecord.getMaxPacketSize();
   126             this.sslConfig.maximumPacketSize = outputRecord.getMaxPacketSize();
   137         }
   127         }
   138         this.isUnsureMode = false;
   128         this.isUnsureMode = isUnsureMode;
   139 
   129 
   140         initialize();
       
   141 
       
   142         this.acc = AccessController.getContext();
       
   143         this.consumers = new HashMap<>();
       
   144     }
       
   145 
       
   146     // Initialize the non-final class variables.
       
   147     private void initialize() {
       
   148         // initial security parameters
   130         // initial security parameters
   149         this.conSession = SSLSessionImpl.nullSession;
   131         this.conSession = SSLSessionImpl.nullSession;
   150         this.protocolVersion = this.sslConfig.maximumProtocolVersion;
   132         this.protocolVersion = this.sslConfig.maximumProtocolVersion;
   151         this.applicationProtocol = null;
   133         this.clientVerifyData = emptyByteArray;
   152 
   134         this.serverVerifyData = emptyByteArray;
   153         // initial handshake context
   135 
   154         this.handshakeContext = null;
   136         this.acc = AccessController.getContext();
   155 
   137         this.consumers = new HashMap<>();
   156         // initial security parameters for secure renegotiation
       
   157         this.secureRenegotiation = false;
       
   158         this.clientVerifyData = new byte[0];
       
   159         this.serverVerifyData = new byte[0];
       
   160 
       
   161         this.isNegotiated = false;
       
   162         this.isBroken = false;
       
   163         this.isInputCloseNotified = false;
       
   164         this.isOutputCloseNotified = false;
       
   165         this.closeReason = null;
       
   166     }
   138     }
   167 
   139 
   168     // Dispatch plaintext to a specific consumer.
   140     // Dispatch plaintext to a specific consumer.
   169     void dispatch(Plaintext plaintext) throws IOException {
   141     void dispatch(Plaintext plaintext) throws IOException {
   170         if (plaintext == null) {
   142         if (plaintext == null) {
   315             if (cause instanceof SSLException) {
   287             if (cause instanceof SSLException) {
   316                 throw (SSLException)cause;
   288                 throw (SSLException)cause;
   317             } else {    // unlikely, but just in case.
   289             } else {    // unlikely, but just in case.
   318                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
   290                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
   319                     SSLLogger.warning(
   291                     SSLLogger.warning(
   320                             "Closed transport, rethrowing (unexpected)", cause);
   292                             "Closed transport, unexpected rethrowing", cause);
   321                 }
   293                 }
   322                 throw alert.createSSLException("Unexpected rethrowing", cause);
   294                 throw alert.createSSLException("Unexpected rethrowing", cause);
   323             }
   295             }
   324         }
   296         }
   325 
   297 
   388         // close outbound
   360         // close outbound
   389         try {
   361         try {
   390             outputRecord.close();
   362             outputRecord.close();
   391         } catch (IOException ioe) {
   363         } catch (IOException ioe) {
   392             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
   364             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
   393                 SSLLogger.warning("Fatal: ouput record closure failed", ioe);
   365                 SSLLogger.warning("Fatal: output record closure failed", ioe);
   394             }
   366             }
   395         }
   367         }
   396 
   368 
   397         // terminal handshake context
   369         // terminal handshake context
   398         if (handshakeContext != null) {
   370         if (handshakeContext != null) {
   471         if (!isInboundDone()) {
   443         if (!isInboundDone()) {
   472             closeInbound();
   444             closeInbound();
   473         }
   445         }
   474     }
   446     }
   475 
   447 
   476     void closeInbound() throws SSLException {
   448     void closeInbound() {
   477         if (isInboundDone()) {
   449         if (isInboundDone()) {
   478             return;
   450             return;
   479         }
   451         }
   480 
   452 
   481         try {
   453         try {
   509     // receiving a close_notify alert or reaching end_of_file of the socket.
   481     // receiving a close_notify alert or reaching end_of_file of the socket.
   510     private void passiveInboundClose() throws IOException {
   482     private void passiveInboundClose() throws IOException {
   511         if (!isInboundDone()) {
   483         if (!isInboundDone()) {
   512             inputRecord.close();
   484             inputRecord.close();
   513         }
   485         }
   514 
       
   515         // For TLS 1.3, output closure is independent from input closure.
       
   516 //      if (isNegotiated && protocolVersion.useTLS13PlusSpec()) {
       
   517 //          return;
       
   518 //      }
       
   519 
   486 
   520         // For TLS 1.2 and prior version, it is required to respond with
   487         // For TLS 1.2 and prior version, it is required to respond with
   521         // a close_notify alert of its own and close down the connection
   488         // a close_notify alert of its own and close down the connection
   522         // immediately, discarding any pending writes.
   489         // immediately, discarding any pending writes.
   523         if (!isOutboundDone() && !isOutputCloseNotified) {
   490         if (!isOutboundDone() && !isOutputCloseNotified) {
   576                 // any data received after a closure alert is ignored.
   543                 // any data received after a closure alert is ignored.
   577                 isOutputCloseNotified = true;
   544                 isOutputCloseNotified = true;
   578                 outputRecord.close();
   545                 outputRecord.close();
   579             }
   546             }
   580         }
   547         }
   581 
       
   582         // For TLS 1.3, output closure is independent from input closure.
       
   583 //
       
   584 //      if (isNegotiated && protocolVersion.useTLS13PlusSpec()) {
       
   585 //          return;
       
   586 //      }
       
   587 //
       
   588 
   548 
   589         // It is not required for the initiator of the close to wait for the
   549         // It is not required for the initiator of the close to wait for the
   590         // responding close_notify alert before closing the read side of the
   550         // responding close_notify alert before closing the read side of the
   591         // connection.  However, if the application protocol using TLS
   551         // connection.  However, if the application protocol using TLS
   592         // provides that any data may be carried over the underlying transport
   552         // provides that any data may be carried over the underlying transport
   639             inputRecord.readCipher.baseSecret = handshakeContext.baseReadSecret;
   599             inputRecord.readCipher.baseSecret = handshakeContext.baseReadSecret;
   640             outputRecord.writeCipher.baseSecret = handshakeContext.baseWriteSecret;
   600             outputRecord.writeCipher.baseSecret = handshakeContext.baseWriteSecret;
   641         }
   601         }
   642 
   602 
   643         handshakeContext = null;
   603         handshakeContext = null;
   644         // inputRecord and outputRecord shares the same handshakeHash
       
   645         // inputRecord.handshakeHash.finish();
       
   646         outputRecord.handshakeHash.finish();
   604         outputRecord.handshakeHash.finish();
   647         inputRecord.finishHandshake();
   605         inputRecord.finishHandshake();
   648         outputRecord.finishHandshake();
   606         outputRecord.finishHandshake();
   649         isNegotiated = true;
   607         isNegotiated = true;
   650 
   608 
   668 
   626 
   669     HandshakeStatus finishPostHandshake() {
   627     HandshakeStatus finishPostHandshake() {
   670         handshakeContext = null;
   628         handshakeContext = null;
   671 
   629 
   672         // Note: May need trigger handshake completion even for post-handshake
   630         // Note: May need trigger handshake completion even for post-handshake
   673         // authenticiation in the future.
   631         // authentication in the future.
   674 
   632 
   675         return HandshakeStatus.FINISHED;
   633         return HandshakeStatus.FINISHED;
   676     }
   634     }
   677 
   635 
   678     // A separate thread is allocated to deliver handshake completion
   636     // A separate thread is allocated to deliver handshake completion