提交 aec6f2de 编写于 作者: W wetmore

8046656: Update protocol support

Reviewed-by: xuelei, wetmore, igerasim, mullan, asmotrak
Contributed-by: jamil.nimeh@oracle.com
上级 0bbca228
...@@ -66,27 +66,27 @@ abstract class Handshaker { ...@@ -66,27 +66,27 @@ abstract class Handshaker {
ProtocolVersion protocolVersion; ProtocolVersion protocolVersion;
// the currently active protocol version during a renegotiation // the currently active protocol version during a renegotiation
ProtocolVersion activeProtocolVersion; ProtocolVersion activeProtocolVersion;
// security parameters for secure renegotiation. // security parameters for secure renegotiation.
boolean secureRenegotiation; boolean secureRenegotiation;
byte[] clientVerifyData; byte[] clientVerifyData;
byte[] serverVerifyData; byte[] serverVerifyData;
// Is it an initial negotiation or a renegotiation? // Is it an initial negotiation or a renegotiation?
boolean isInitialHandshake; boolean isInitialHandshake;
// List of enabled protocols // List of enabled protocols
private ProtocolList enabledProtocols; private ProtocolList enabledProtocols;
// List of enabled CipherSuites // List of enabled CipherSuites
private CipherSuiteList enabledCipherSuites; private CipherSuiteList enabledCipherSuites;
// The endpoint identification protocol // The endpoint identification protocol
String identificationProtocol; String identificationProtocol;
// The cryptographic algorithm constraints // The cryptographic algorithm constraints
private AlgorithmConstraints algorithmConstraints = null; private AlgorithmConstraints algorithmConstraints = null;
// Local supported signature and algorithms // Local supported signature and algorithms
Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs; Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs;
...@@ -94,8 +94,6 @@ abstract class Handshaker { ...@@ -94,8 +94,6 @@ abstract class Handshaker {
// Peer supported signature and algorithms // Peer supported signature and algorithms
Collection<SignatureAndHashAlgorithm> peerSupportedSignAlgs; Collection<SignatureAndHashAlgorithm> peerSupportedSignAlgs;
/*
/* /*
* List of active protocols * List of active protocols
* *
...@@ -103,7 +101,7 @@ abstract class Handshaker { ...@@ -103,7 +101,7 @@ abstract class Handshaker {
* contain only those protocols that have vaild cipher suites * contain only those protocols that have vaild cipher suites
* enabled. * enabled.
*/ */
private ProtocolList activeProtocols; private ProtocolList activeProtocols;
/* /*
* List of active cipher suites * List of active cipher suites
...@@ -111,39 +109,41 @@ abstract class Handshaker { ...@@ -111,39 +109,41 @@ abstract class Handshaker {
* Active cipher suites is a subset of enabled cipher suites, and will * Active cipher suites is a subset of enabled cipher suites, and will
* contain only those cipher suites available for the active protocols. * contain only those cipher suites available for the active protocols.
*/ */
private CipherSuiteList activeCipherSuites; private CipherSuiteList activeCipherSuites;
// The server name indication and matchers // The server name indication and matchers
List<SNIServerName> serverNames = List<SNIServerName> serverNames = Collections.<SNIServerName>emptyList();
Collections.<SNIServerName>emptyList(); Collection<SNIMatcher> sniMatchers = Collections.<SNIMatcher>emptyList();
Collection<SNIMatcher> sniMatchers =
Collections.<SNIMatcher>emptyList();
private boolean isClient; private boolean isClient;
private boolean needCertVerify; private boolean needCertVerify;
SSLSocketImpl conn = null; SSLSocketImpl conn = null;
SSLEngineImpl engine = null; SSLEngineImpl engine = null;
HandshakeHash handshakeHash; HandshakeHash handshakeHash;
HandshakeInStream input; HandshakeInStream input;
HandshakeOutStream output; HandshakeOutStream output;
int state; int state;
SSLContextImpl sslContext; SSLContextImpl sslContext;
RandomCookie clnt_random, svr_random; RandomCookie clnt_random, svr_random;
SSLSessionImpl session; SSLSessionImpl session;
// current CipherSuite. Never null, initially SSL_NULL_WITH_NULL_NULL // current CipherSuite. Never null, initially SSL_NULL_WITH_NULL_NULL
CipherSuite cipherSuite; CipherSuite cipherSuite;
// current key exchange. Never null, initially K_NULL // current key exchange. Never null, initially K_NULL
KeyExchange keyExchange; KeyExchange keyExchange;
/* True if this session is being resumed (fast handshake) */ // True if this session is being resumed (fast handshake)
boolean resumingSession; boolean resumingSession;
/* True if it's OK to start a new SSL session */ // True if it's OK to start a new SSL session
boolean enableNewSession; boolean enableNewSession;
// True if session keys have been calculated and the caller may receive
// and process a ChangeCipherSpec message
private boolean sessKeysCalculated;
// Whether local cipher suites preference should be honored during // Whether local cipher suites preference should be honored during
// handshaking? // handshaking?
...@@ -176,7 +176,7 @@ abstract class Handshaker { ...@@ -176,7 +176,7 @@ abstract class Handshaker {
// here instead of using this lock. Consider changing. // here instead of using this lock. Consider changing.
private Object thrownLock = new Object(); private Object thrownLock = new Object();
/* Class and subclass dynamic debugging support */ // Class and subclass dynamic debugging support
static final Debug debug = Debug.getInstance("ssl"); static final Debug debug = Debug.getInstance("ssl");
// By default, disable the unsafe legacy session renegotiation // By default, disable the unsafe legacy session renegotiation
...@@ -253,6 +253,7 @@ abstract class Handshaker { ...@@ -253,6 +253,7 @@ abstract class Handshaker {
this.serverVerifyData = serverVerifyData; this.serverVerifyData = serverVerifyData;
enableNewSession = true; enableNewSession = true;
invalidated = false; invalidated = false;
sessKeysCalculated = false;
setCipherSuite(CipherSuite.C_NULL); setCipherSuite(CipherSuite.C_NULL);
setEnabledProtocols(enabledProtocols); setEnabledProtocols(enabledProtocols);
...@@ -1212,6 +1213,10 @@ abstract class Handshaker { ...@@ -1212,6 +1213,10 @@ abstract class Handshaker {
throw new ProviderException(e); throw new ProviderException(e);
} }
// Mark a flag that allows outside entities (like SSLSocket/SSLEngine)
// determine if a ChangeCipherSpec message could be processed.
sessKeysCalculated = true;
// //
// Dump the connection keys as they're generated. // Dump the connection keys as they're generated.
// //
...@@ -1266,6 +1271,15 @@ abstract class Handshaker { ...@@ -1266,6 +1271,15 @@ abstract class Handshaker {
} }
} }
/**
* Return whether or not the Handshaker has derived session keys for
* this handshake. This is used for determining readiness to process
* an incoming ChangeCipherSpec message.
*/
boolean sessionKeysCalculated() {
return sessKeysCalculated;
}
private static void printHex(HexDumpEncoder dump, byte[] bytes) { private static void printHex(HexDumpEncoder dump, byte[] bytes) {
if (bytes == null) { if (bytes == null) {
System.out.println("(key bytes not available)"); System.out.println("(key bytes not available)");
......
/* /*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -211,6 +211,11 @@ final public class SSLEngineImpl extends SSLEngine { ...@@ -211,6 +211,11 @@ final public class SSLEngineImpl extends SSLEngine {
static final byte clauth_requested = 1; static final byte clauth_requested = 1;
static final byte clauth_required = 2; static final byte clauth_required = 2;
/*
* Flag indicating that the engine has received a ChangeCipherSpec message.
*/
private boolean receivedCCS;
/* /*
* Flag indicating if the next record we receive MUST be a Finished * Flag indicating if the next record we receive MUST be a Finished
* message. Temporarily set during the handshake to ensure that * message. Temporarily set during the handshake to ensure that
...@@ -372,6 +377,7 @@ final public class SSLEngineImpl extends SSLEngine { ...@@ -372,6 +377,7 @@ final public class SSLEngineImpl extends SSLEngine {
*/ */
roleIsServer = true; roleIsServer = true;
connectionState = cs_START; connectionState = cs_START;
receivedCCS = false;
// default server name indication // default server name indication
serverNames = serverNames =
...@@ -1021,6 +1027,7 @@ final public class SSLEngineImpl extends SSLEngine { ...@@ -1021,6 +1027,7 @@ final public class SSLEngineImpl extends SSLEngine {
if (handshaker.invalidated) { if (handshaker.invalidated) {
handshaker = null; handshaker = null;
receivedCCS = false;
// if state is cs_RENEGOTIATE, revert it to cs_DATA // if state is cs_RENEGOTIATE, revert it to cs_DATA
if (connectionState == cs_RENEGOTIATE) { if (connectionState == cs_RENEGOTIATE) {
connectionState = cs_DATA; connectionState = cs_DATA;
...@@ -1039,6 +1046,7 @@ final public class SSLEngineImpl extends SSLEngine { ...@@ -1039,6 +1046,7 @@ final public class SSLEngineImpl extends SSLEngine {
} }
handshaker = null; handshaker = null;
connectionState = cs_DATA; connectionState = cs_DATA;
receivedCCS = false;
// No handshakeListeners here. That's a // No handshakeListeners here. That's a
// SSLSocket thing. // SSLSocket thing.
...@@ -1078,13 +1086,25 @@ final public class SSLEngineImpl extends SSLEngine { ...@@ -1078,13 +1086,25 @@ final public class SSLEngineImpl extends SSLEngine {
case Record.ct_change_cipher_spec: case Record.ct_change_cipher_spec:
if ((connectionState != cs_HANDSHAKE if ((connectionState != cs_HANDSHAKE
&& connectionState != cs_RENEGOTIATE) && connectionState != cs_RENEGOTIATE)
|| inputRecord.available() != 1 || !handshaker.sessionKeysCalculated()
|| receivedCCS) {
// For the CCS message arriving in the wrong state
fatal(Alerts.alert_unexpected_message,
"illegal change cipher spec msg, conn state = "
+ connectionState + ", handshake state = "
+ handshaker.state);
} else if (inputRecord.available() != 1
|| inputRecord.read() != 1) { || inputRecord.read() != 1) {
// For structural/content issues with the CCS
fatal(Alerts.alert_unexpected_message, fatal(Alerts.alert_unexpected_message,
"illegal change cipher spec msg, state = " "Malformed change cipher spec msg");
+ connectionState);
} }
// Once we've received CCS, update the flag.
// If the remote endpoint sends it again in this handshake
// we won't process it.
receivedCCS = true;
// //
// The first message after a change_cipher_spec // The first message after a change_cipher_spec
// record MUST be a "Finished" handshake record, // record MUST be a "Finished" handshake record,
......
/* /*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -171,6 +171,12 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { ...@@ -171,6 +171,12 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
*/ */
private volatile int connectionState; private volatile int connectionState;
/*
* Flag indicating that the engine's handshaker has done the necessary
* steps so the engine may process a ChangeCipherSpec message.
*/
private boolean receivedCCS;
/* /*
* Flag indicating if the next record we receive MUST be a Finished * Flag indicating if the next record we receive MUST be a Finished
* message. Temporarily set during the handshake to ensure that * message. Temporarily set during the handshake to ensure that
...@@ -587,6 +593,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { ...@@ -587,6 +593,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
*/ */
roleIsServer = isServer; roleIsServer = isServer;
connectionState = cs_START; connectionState = cs_START;
receivedCCS = false;
/* /*
* default read and write side cipher and MAC support * default read and write side cipher and MAC support
...@@ -1045,6 +1052,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { ...@@ -1045,6 +1052,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
if (handshaker.invalidated) { if (handshaker.invalidated) {
handshaker = null; handshaker = null;
receivedCCS = false;
// if state is cs_RENEGOTIATE, revert it to cs_DATA // if state is cs_RENEGOTIATE, revert it to cs_DATA
if (connectionState == cs_RENEGOTIATE) { if (connectionState == cs_RENEGOTIATE) {
connectionState = cs_DATA; connectionState = cs_DATA;
...@@ -1060,6 +1068,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { ...@@ -1060,6 +1068,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
handshakeSession = null; handshakeSession = null;
handshaker = null; handshaker = null;
connectionState = cs_DATA; connectionState = cs_DATA;
receivedCCS = false;
// //
// Tell folk about handshake completion, but do // Tell folk about handshake completion, but do
...@@ -1107,13 +1116,24 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { ...@@ -1107,13 +1116,24 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
case Record.ct_change_cipher_spec: case Record.ct_change_cipher_spec:
if ((connectionState != cs_HANDSHAKE if ((connectionState != cs_HANDSHAKE
&& connectionState != cs_RENEGOTIATE) && connectionState != cs_RENEGOTIATE)
|| r.available() != 1 || !handshaker.sessionKeysCalculated()
|| r.read() != 1) { || receivedCCS) {
// For the CCS message arriving in the wrong state
fatal(Alerts.alert_unexpected_message, fatal(Alerts.alert_unexpected_message,
"illegal change cipher spec msg, state = " "illegal change cipher spec msg, conn state = "
+ connectionState); + connectionState + ", handshake state = "
+ handshaker.state);
} else if (r.available() != 1 || r.read() != 1) {
// For structural/content issues with the CCS
fatal(Alerts.alert_unexpected_message,
"Malformed change cipher spec msg");
} }
// Once we've received CCS, update the flag.
// If the remote endpoint sends it again in this handshake
// we won't process it.
receivedCCS = true;
// //
// The first message after a change_cipher_spec // The first message after a change_cipher_spec
// record MUST be a "Finished" handshake record, // record MUST be a "Finished" handshake record,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册