46 import sun.security.ssl.SSLCipher.SSLWriteCipher; |
46 import sun.security.ssl.SSLCipher.SSLWriteCipher; |
47 import sun.security.ssl.SSLHandshake.HandshakeMessage; |
47 import sun.security.ssl.SSLHandshake.HandshakeMessage; |
48 import sun.security.ssl.SupportedVersionsExtension.SHSupportedVersionsSpec; |
48 import sun.security.ssl.SupportedVersionsExtension.SHSupportedVersionsSpec; |
49 |
49 |
50 /** |
50 /** |
51 * Pack of the ServertHello/HelloRetryRequest handshake message. |
51 * Pack of the ServerHello/HelloRetryRequest handshake message. |
52 */ |
52 */ |
53 final class ServerHello { |
53 final class ServerHello { |
54 static final SSLConsumer handshakeConsumer = |
54 static final SSLConsumer handshakeConsumer = |
55 new ServerHelloConsumer(); |
55 new ServerHelloConsumer(); |
56 static final HandshakeProducer t12HandshakeProducer = |
56 static final HandshakeProducer t12HandshakeProducer = |
77 new T13HelloRetryRequestConsumer(); |
77 new T13HelloRetryRequestConsumer(); |
78 private static final HandshakeConsumer d13HrrHandshakeConsumer = |
78 private static final HandshakeConsumer d13HrrHandshakeConsumer = |
79 new T13HelloRetryRequestConsumer(); |
79 new T13HelloRetryRequestConsumer(); |
80 |
80 |
81 /** |
81 /** |
82 * The ServertHello handshake message. |
82 * The ServerHello handshake message. |
83 */ |
83 */ |
84 static final class ServerHelloMessage extends HandshakeMessage { |
84 static final class ServerHelloMessage extends HandshakeMessage { |
85 final ProtocolVersion serverVersion; // TLS 1.3 legacy |
85 final ProtocolVersion serverVersion; // TLS 1.3 legacy |
86 final RandomCookie serverRandom; |
86 final RandomCookie serverRandom; |
87 final SessionId sessionId; // TLS 1.3 legacy |
87 final SessionId sessionId; // TLS 1.3 legacy |
113 |
113 |
114 // Reserve the ClientHello message for cookie generation. |
114 // Reserve the ClientHello message for cookie generation. |
115 this.clientHello = clientHello; |
115 this.clientHello = clientHello; |
116 |
116 |
117 // The handshakeRecord field is used for HelloRetryRequest consumer |
117 // The handshakeRecord field is used for HelloRetryRequest consumer |
118 // only. It's fine to set it to null for gnerating side of the |
118 // only. It's fine to set it to null for generating side of the |
119 // ServerHello/HelloRetryRequest message. |
119 // ServerHello/HelloRetryRequest message. |
120 this.handshakeRecord = null; |
120 this.handshakeRecord = null; |
121 } |
121 } |
122 |
122 |
123 ServerHelloMessage(HandshakeContext context, |
123 ServerHelloMessage(HandshakeContext context, |
129 |
129 |
130 byte major = m.get(); |
130 byte major = m.get(); |
131 byte minor = m.get(); |
131 byte minor = m.get(); |
132 this.serverVersion = ProtocolVersion.valueOf(major, minor); |
132 this.serverVersion = ProtocolVersion.valueOf(major, minor); |
133 if (this.serverVersion == null) { |
133 if (this.serverVersion == null) { |
134 // The client should only request for known protovol versions. |
134 // The client should only request for known protocol versions. |
135 context.conContext.fatal(Alert.PROTOCOL_VERSION, |
135 context.conContext.fatal(Alert.PROTOCOL_VERSION, |
136 "Unsupported protocol version: " + |
136 "Unsupported protocol version: " + |
137 ProtocolVersion.nameOf(major, minor)); |
137 ProtocolVersion.nameOf(major, minor)); |
138 } |
138 } |
139 |
139 |
388 } |
388 } |
389 |
389 |
390 private static KeyExchangeProperties chooseCipherSuite( |
390 private static KeyExchangeProperties chooseCipherSuite( |
391 ServerHandshakeContext shc, |
391 ServerHandshakeContext shc, |
392 ClientHelloMessage clientHello) throws IOException { |
392 ClientHelloMessage clientHello) throws IOException { |
393 List<CipherSuite> prefered; |
393 List<CipherSuite> preferred; |
394 List<CipherSuite> proposed; |
394 List<CipherSuite> proposed; |
395 if (shc.sslConfig.preferLocalCipherSuites) { |
395 if (shc.sslConfig.preferLocalCipherSuites) { |
396 prefered = shc.activeCipherSuites; |
396 preferred = shc.activeCipherSuites; |
397 proposed = clientHello.cipherSuites; |
397 proposed = clientHello.cipherSuites; |
398 } else { |
398 } else { |
399 prefered = clientHello.cipherSuites; |
399 preferred = clientHello.cipherSuites; |
400 proposed = shc.activeCipherSuites; |
400 proposed = shc.activeCipherSuites; |
401 } |
401 } |
402 |
402 |
403 List<CipherSuite> legacySuites = new LinkedList<>(); |
403 List<CipherSuite> legacySuites = new LinkedList<>(); |
404 for (CipherSuite cs : prefered) { |
404 for (CipherSuite cs : preferred) { |
405 if (!HandshakeContext.isNegotiable( |
405 if (!HandshakeContext.isNegotiable( |
406 proposed, shc.negotiatedProtocol, cs)) { |
406 proposed, shc.negotiatedProtocol, cs)) { |
407 continue; |
407 continue; |
408 } |
408 } |
409 |
409 |
673 } |
673 } |
674 |
674 |
675 private static CipherSuite chooseCipherSuite( |
675 private static CipherSuite chooseCipherSuite( |
676 ServerHandshakeContext shc, |
676 ServerHandshakeContext shc, |
677 ClientHelloMessage clientHello) throws IOException { |
677 ClientHelloMessage clientHello) throws IOException { |
678 List<CipherSuite> prefered; |
678 List<CipherSuite> preferred; |
679 List<CipherSuite> proposed; |
679 List<CipherSuite> proposed; |
680 if (shc.sslConfig.preferLocalCipherSuites) { |
680 if (shc.sslConfig.preferLocalCipherSuites) { |
681 prefered = shc.activeCipherSuites; |
681 preferred = shc.activeCipherSuites; |
682 proposed = clientHello.cipherSuites; |
682 proposed = clientHello.cipherSuites; |
683 } else { |
683 } else { |
684 prefered = clientHello.cipherSuites; |
684 preferred = clientHello.cipherSuites; |
685 proposed = shc.activeCipherSuites; |
685 proposed = shc.activeCipherSuites; |
686 } |
686 } |
687 |
687 |
688 CipherSuite legacySuite = null; |
688 CipherSuite legacySuite = null; |
689 AlgorithmConstraints legacyConstraints = |
689 AlgorithmConstraints legacyConstraints = |
690 ServerHandshakeContext.legacyAlgorithmConstraints; |
690 ServerHandshakeContext.legacyAlgorithmConstraints; |
691 for (CipherSuite cs : prefered) { |
691 for (CipherSuite cs : preferred) { |
692 if (!HandshakeContext.isNegotiable( |
692 if (!HandshakeContext.isNegotiable( |
693 proposed, shc.negotiatedProtocol, cs)) { |
693 proposed, shc.negotiatedProtocol, cs)) { |
694 continue; |
694 continue; |
695 } |
695 } |
696 |
696 |
853 if (!chc.handshakeConsumers.isEmpty()) { |
853 if (!chc.handshakeConsumers.isEmpty()) { |
854 chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, |
854 chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, |
855 "No more message expected before ServerHello is processed"); |
855 "No more message expected before ServerHello is processed"); |
856 } |
856 } |
857 |
857 |
858 int startPos = message.position(); |
|
859 ServerHelloMessage shm = new ServerHelloMessage(chc, message); |
858 ServerHelloMessage shm = new ServerHelloMessage(chc, message); |
860 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { |
859 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { |
861 SSLLogger.fine("Consuming ServerHello handshake message", shm); |
860 SSLLogger.fine("Consuming ServerHello handshake message", shm); |
862 } |
861 } |
863 |
862 |
958 "Negotiated protocol version: " + serverVersion.name); |
957 "Negotiated protocol version: " + serverVersion.name); |
959 } |
958 } |
960 |
959 |
961 if (serverHello.serverRandom.isVersionDowngrade(chc)) { |
960 if (serverHello.serverRandom.isVersionDowngrade(chc)) { |
962 chc.conContext.fatal(Alert.ILLEGAL_PARAMETER, |
961 chc.conContext.fatal(Alert.ILLEGAL_PARAMETER, |
963 "A potential protocol versoin downgrade attack"); |
962 "A potential protocol version downgrade attack"); |
964 } |
963 } |
965 |
964 |
966 // Consume the handshake message for the specific protocol version. |
965 // Consume the handshake message for the specific protocol version. |
967 if (serverVersion.isDTLS) { |
966 if (serverVersion.isDTLS) { |
968 if (serverVersion.useTLS13PlusSpec()) { |
967 if (serverVersion.useTLS13PlusSpec()) { |