44 import sun.security.ssl.ClientHello.ClientHelloMessage; |
44 import sun.security.ssl.ClientHello.ClientHelloMessage; |
45 import sun.security.ssl.SSLCipher.SSLReadCipher; |
45 import sun.security.ssl.SSLCipher.SSLReadCipher; |
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 |
|
50 import static sun.security.ssl.SSLExtension.SH_SESSION_TICKET; |
49 |
51 |
50 /** |
52 /** |
51 * Pack of the ServerHello/HelloRetryRequest handshake message. |
53 * Pack of the ServerHello/HelloRetryRequest handshake message. |
52 */ |
54 */ |
53 final class ServerHello { |
55 final class ServerHello { |
335 } |
337 } |
336 } |
338 } |
337 shc.handshakeProducers.put(SSLHandshake.SERVER_HELLO_DONE.id, |
339 shc.handshakeProducers.put(SSLHandshake.SERVER_HELLO_DONE.id, |
338 SSLHandshake.SERVER_HELLO_DONE); |
340 SSLHandshake.SERVER_HELLO_DONE); |
339 } else { |
341 } else { |
|
342 // stateless and use the client session id (RFC 5077 3.4) |
|
343 if (shc.statelessResumption) { |
|
344 shc.resumingSession = new SSLSessionImpl(shc.resumingSession, |
|
345 (clientHello.sessionId.length() == 0) ? |
|
346 new SessionId(true, |
|
347 shc.sslContext.getSecureRandom()) : |
|
348 new SessionId(clientHello.sessionId.getId()) |
|
349 ); |
|
350 } |
340 shc.handshakeSession = shc.resumingSession; |
351 shc.handshakeSession = shc.resumingSession; |
341 shc.negotiatedProtocol = |
352 shc.negotiatedProtocol = |
342 shc.resumingSession.getProtocolVersion(); |
353 shc.resumingSession.getProtocolVersion(); |
343 shc.negotiatedCipherSuite = shc.resumingSession.getSuite(); |
354 shc.negotiatedCipherSuite = shc.resumingSession.getSuite(); |
344 shc.handshakeHash.determine( |
355 shc.handshakeHash.determine( |
489 HandshakeMessage message) throws IOException { |
500 HandshakeMessage message) throws IOException { |
490 // The producing happens in server side only. |
501 // The producing happens in server side only. |
491 ServerHandshakeContext shc = (ServerHandshakeContext)context; |
502 ServerHandshakeContext shc = (ServerHandshakeContext)context; |
492 ClientHelloMessage clientHello = (ClientHelloMessage)message; |
503 ClientHelloMessage clientHello = (ClientHelloMessage)message; |
493 |
504 |
|
505 SSLSessionContextImpl sessionCache = (SSLSessionContextImpl) |
|
506 shc.sslContext.engineGetServerSessionContext(); |
|
507 |
494 // If client hasn't specified a session we can resume, start a |
508 // If client hasn't specified a session we can resume, start a |
495 // new one and choose its cipher suite and compression options, |
509 // new one and choose its cipher suite and compression options, |
496 // unless new session creation is disabled for this connection! |
510 // unless new session creation is disabled for this connection! |
497 if (!shc.isResumption || shc.resumingSession == null) { |
511 if (!shc.isResumption || shc.resumingSession == null) { |
498 if (!shc.sslConfig.enableSessionCreation) { |
512 if (!shc.sslConfig.enableSessionCreation) { |
544 |
558 |
545 setUpPskKD(shc, |
559 setUpPskKD(shc, |
546 shc.resumingSession.consumePreSharedKey()); |
560 shc.resumingSession.consumePreSharedKey()); |
547 |
561 |
548 // The session can't be resumed again---remove it from cache |
562 // The session can't be resumed again---remove it from cache |
549 SSLSessionContextImpl sessionCache = (SSLSessionContextImpl) |
|
550 shc.sslContext.engineGetServerSessionContext(); |
|
551 sessionCache.remove(shc.resumingSession.getSessionId()); |
563 sessionCache.remove(shc.resumingSession.getSessionId()); |
552 } |
564 } |
553 |
565 |
554 // update the responders |
566 // update the responders |
555 shc.handshakeProducers.put(SSLHandshake.ENCRYPTED_EXTENSIONS.id, |
567 shc.handshakeProducers.put(SSLHandshake.ENCRYPTED_EXTENSIONS.id, |
677 writeCipher, (clientHello.sessionId.length() != 0)); |
689 writeCipher, (clientHello.sessionId.length() != 0)); |
678 |
690 |
679 // Update the context for master key derivation. |
691 // Update the context for master key derivation. |
680 shc.handshakeKeyDerivation = kd; |
692 shc.handshakeKeyDerivation = kd; |
681 |
693 |
|
694 // Check if the server supports stateless resumption |
|
695 if (sessionCache.statelessEnabled()) { |
|
696 shc.statelessResumption = true; |
|
697 } |
|
698 |
682 // The handshake message has been delivered. |
699 // The handshake message has been delivered. |
683 return null; |
700 return null; |
684 } |
701 } |
685 |
702 |
686 private static CipherSuite chooseCipherSuite( |
703 private static CipherSuite chooseCipherSuite( |
1096 |
1113 |
1097 if (!chc.sslConfig.enableSessionCreation) { |
1114 if (!chc.sslConfig.enableSessionCreation) { |
1098 throw chc.conContext.fatal(Alert.PROTOCOL_VERSION, |
1115 throw chc.conContext.fatal(Alert.PROTOCOL_VERSION, |
1099 "New session creation is disabled"); |
1116 "New session creation is disabled"); |
1100 } |
1117 } |
1101 chc.handshakeSession = new SSLSessionImpl(chc, |
1118 |
1102 chc.negotiatedCipherSuite, |
1119 if (serverHello.sessionId.length() == 0 && |
1103 serverHello.sessionId); |
1120 chc.statelessResumption) { |
|
1121 SessionId newId = new SessionId(true, |
|
1122 chc.sslContext.getSecureRandom()); |
|
1123 chc.handshakeSession = new SSLSessionImpl(chc, |
|
1124 chc.negotiatedCipherSuite, newId); |
|
1125 |
|
1126 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { |
|
1127 SSLLogger.fine("Locally assigned Session Id: " + |
|
1128 newId.toString()); |
|
1129 } |
|
1130 } else { |
|
1131 chc.handshakeSession = new SSLSessionImpl(chc, |
|
1132 chc.negotiatedCipherSuite, |
|
1133 serverHello.sessionId); |
|
1134 } |
1104 chc.handshakeSession.setMaximumPacketSize( |
1135 chc.handshakeSession.setMaximumPacketSize( |
1105 chc.sslConfig.maximumPacketSize); |
1136 chc.sslConfig.maximumPacketSize); |
1106 } |
1137 } |
1107 |
1138 |
1108 // |
1139 // |
1125 } |
1156 } |
1126 |
1157 |
1127 chc.conContext.consumers.putIfAbsent( |
1158 chc.conContext.consumers.putIfAbsent( |
1128 ContentType.CHANGE_CIPHER_SPEC.id, |
1159 ContentType.CHANGE_CIPHER_SPEC.id, |
1129 ChangeCipherSpec.t10Consumer); |
1160 ChangeCipherSpec.t10Consumer); |
|
1161 if (chc.statelessResumption) { |
|
1162 chc.handshakeConsumers.putIfAbsent( |
|
1163 SSLHandshake.NEW_SESSION_TICKET.id, |
|
1164 SSLHandshake.NEW_SESSION_TICKET); |
|
1165 } |
1130 chc.handshakeConsumers.put( |
1166 chc.handshakeConsumers.put( |
1131 SSLHandshake.FINISHED.id, |
1167 SSLHandshake.FINISHED.id, |
1132 SSLHandshake.FINISHED); |
1168 SSLHandshake.FINISHED); |
1133 } else { |
1169 } else { |
1134 SSLKeyExchange ke = SSLKeyExchange.valueOf( |
1170 SSLKeyExchange ke = SSLKeyExchange.valueOf( |