use of sun.security.ssl.CipherSuite.KeyExchange in project jdk8u_jdk by JetBrains.
the class ServerHandshaker method trySetCipherSuite.
/**
* Set the given CipherSuite, if possible. Return the result.
* The call succeeds if the CipherSuite is available and we have
* the necessary certificates to complete the handshake. We don't
* check if the CipherSuite is actually enabled.
*
* If successful, this method also generates ephemeral keys if
* required for this ciphersuite. This may take some time, so this
* method should only be called if you really want to use the
* CipherSuite.
*
* This method is called from chooseCipherSuite() in this class.
*/
boolean trySetCipherSuite(CipherSuite suite) {
/*
* If we're resuming a session we know we can
* support this key exchange algorithm and in fact
* have already cached the result of it in
* the session state.
*/
if (resumingSession) {
return true;
}
if (suite.isNegotiable() == false) {
return false;
}
// must not negotiate the obsoleted weak cipher suites.
if (protocolVersion.v >= suite.obsoleted) {
return false;
}
// must not negotiate unsupported cipher suites.
if (protocolVersion.v < suite.supported) {
return false;
}
KeyExchange keyExchange = suite.keyExchange;
// null out any existing references
privateKey = null;
certs = null;
dh = null;
tempPrivateKey = null;
tempPublicKey = null;
Collection<SignatureAndHashAlgorithm> supportedSignAlgs = null;
if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
if (peerSupportedSignAlgs != null) {
supportedSignAlgs = peerSupportedSignAlgs;
} else {
SignatureAndHashAlgorithm algorithm = null;
// we may optimize the performance
switch(keyExchange) {
// behave as if client had sent the value {sha1,rsa}.
case K_RSA:
case K_DHE_RSA:
case K_DH_RSA:
// case K_RSA_PSK:
case K_ECDH_RSA:
case K_ECDHE_RSA:
algorithm = SignatureAndHashAlgorithm.valueOf(HashAlgorithm.SHA1.value, SignatureAlgorithm.RSA.value, 0);
break;
// sent the value {sha1,dsa}.
case K_DHE_DSS:
case K_DH_DSS:
algorithm = SignatureAndHashAlgorithm.valueOf(HashAlgorithm.SHA1.value, SignatureAlgorithm.DSA.value, 0);
break;
// had sent value {sha1,ecdsa}.
case K_ECDH_ECDSA:
case K_ECDHE_ECDSA:
algorithm = SignatureAndHashAlgorithm.valueOf(HashAlgorithm.SHA1.value, SignatureAlgorithm.ECDSA.value, 0);
break;
default:
}
if (algorithm == null) {
supportedSignAlgs = Collections.<SignatureAndHashAlgorithm>emptySet();
} else {
supportedSignAlgs = new ArrayList<SignatureAndHashAlgorithm>(1);
supportedSignAlgs.add(algorithm);
supportedSignAlgs = SignatureAndHashAlgorithm.getSupportedAlgorithms(algorithmConstraints, supportedSignAlgs);
// May be no default activated signature algorithm, but
// let the following process make the final decision.
}
// Sets the peer supported signature algorithm to use in KM
// temporarily.
session.setPeerSupportedSignatureAlgorithms(supportedSignAlgs);
}
}
switch(keyExchange) {
case K_RSA:
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
break;
case K_RSA_EXPORT:
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
try {
if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
if (!setupEphemeralRSAKeys(suite.exportable)) {
return false;
}
}
} catch (RuntimeException e) {
// could not determine keylength, ignore key
return false;
}
break;
case K_DHE_RSA:
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm(supportedSignAlgs, "RSA", privateKey);
if (preferableSignatureAlgorithm == null) {
if ((debug != null) && Debug.isOn("handshake")) {
System.out.println("No signature and hash algorithm for cipher " + suite);
}
return false;
}
}
setupEphemeralDHKeys(suite.exportable, privateKey);
break;
case K_ECDHE_RSA:
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm(supportedSignAlgs, "RSA", privateKey);
if (preferableSignatureAlgorithm == null) {
if ((debug != null) && Debug.isOn("handshake")) {
System.out.println("No signature and hash algorithm for cipher " + suite);
}
return false;
}
}
if (setupEphemeralECDHKeys() == false) {
return false;
}
break;
case K_DHE_DSS:
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm(supportedSignAlgs, "DSA");
if (preferableSignatureAlgorithm == null) {
if ((debug != null) && Debug.isOn("handshake")) {
System.out.println("No signature and hash algorithm for cipher " + suite);
}
return false;
}
}
// need DSS certs for authentication
if (setupPrivateKeyAndChain("DSA") == false) {
return false;
}
setupEphemeralDHKeys(suite.exportable, privateKey);
break;
case K_ECDHE_ECDSA:
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm(supportedSignAlgs, "ECDSA");
if (preferableSignatureAlgorithm == null) {
if ((debug != null) && Debug.isOn("handshake")) {
System.out.println("No signature and hash algorithm for cipher " + suite);
}
return false;
}
}
// need EC cert
if (setupPrivateKeyAndChain("EC") == false) {
return false;
}
if (setupEphemeralECDHKeys() == false) {
return false;
}
break;
case K_ECDH_RSA:
// need EC cert
if (setupPrivateKeyAndChain("EC") == false) {
return false;
}
setupStaticECDHKeys();
break;
case K_ECDH_ECDSA:
// need EC cert
if (setupPrivateKeyAndChain("EC") == false) {
return false;
}
setupStaticECDHKeys();
break;
case K_KRB5:
case K_KRB5_EXPORT:
// need Kerberos Key
if (!setupKerberosKeys()) {
return false;
}
break;
case K_DH_ANON:
// no certs needed for anonymous
setupEphemeralDHKeys(suite.exportable, null);
break;
case K_ECDH_ANON:
// no certs needed for anonymous
if (setupEphemeralECDHKeys() == false) {
return false;
}
break;
default:
// internal error, unknown key exchange
throw new RuntimeException("Unrecognized cipherSuite: " + suite);
}
setCipherSuite(suite);
// set the peer implicit supported signature algorithms
if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
if (peerSupportedSignAlgs == null) {
setPeerSupportedSignAlgs(supportedSignAlgs);
// we had alreay update the session
}
}
return true;
}
use of sun.security.ssl.CipherSuite.KeyExchange in project Bytecoder by mirkosertic.
the class ServerHandshaker method trySetCipherSuite.
/**
* Set the given CipherSuite, if possible. Return the result.
* The call succeeds if the CipherSuite is available and we have
* the necessary certificates to complete the handshake. We don't
* check if the CipherSuite is actually enabled.
*
* If successful, this method also generates ephemeral keys if
* required for this ciphersuite. This may take some time, so this
* method should only be called if you really want to use the
* CipherSuite.
*
* This method is called from chooseCipherSuite() in this class.
*/
boolean trySetCipherSuite(CipherSuite suite) {
/*
* If we're resuming a session we know we can
* support this key exchange algorithm and in fact
* have already cached the result of it in
* the session state.
*/
if (resumingSession) {
return true;
}
if (suite.isNegotiable() == false) {
return false;
}
// must not negotiate the obsoleted weak cipher suites.
if (protocolVersion.obsoletes(suite)) {
return false;
}
// must not negotiate unsupported cipher suites.
if (!protocolVersion.supports(suite)) {
return false;
}
KeyExchange keyExchange = suite.keyExchange;
// null out any existing references
privateKey = null;
certs = null;
dh = null;
tempPrivateKey = null;
tempPublicKey = null;
Collection<SignatureAndHashAlgorithm> supportedSignAlgs = null;
if (protocolVersion.useTLS12PlusSpec()) {
if (peerSupportedSignAlgs != null) {
supportedSignAlgs = peerSupportedSignAlgs;
} else {
SignatureAndHashAlgorithm algorithm = null;
// we may optimize the performance
switch(keyExchange) {
// behave as if client had sent the value {sha1,rsa}.
case K_RSA:
case K_DHE_RSA:
case K_DH_RSA:
// case K_RSA_PSK:
case K_ECDH_RSA:
case K_ECDHE_RSA:
algorithm = SignatureAndHashAlgorithm.valueOf(HashAlgorithm.SHA1.value, SignatureAlgorithm.RSA.value, 0);
break;
// sent the value {sha1,dsa}.
case K_DHE_DSS:
case K_DH_DSS:
algorithm = SignatureAndHashAlgorithm.valueOf(HashAlgorithm.SHA1.value, SignatureAlgorithm.DSA.value, 0);
break;
// had sent value {sha1,ecdsa}.
case K_ECDH_ECDSA:
case K_ECDHE_ECDSA:
algorithm = SignatureAndHashAlgorithm.valueOf(HashAlgorithm.SHA1.value, SignatureAlgorithm.ECDSA.value, 0);
break;
default:
}
if (algorithm == null) {
supportedSignAlgs = Collections.<SignatureAndHashAlgorithm>emptySet();
} else {
supportedSignAlgs = new ArrayList<SignatureAndHashAlgorithm>(1);
supportedSignAlgs.add(algorithm);
supportedSignAlgs = SignatureAndHashAlgorithm.getSupportedAlgorithms(algorithmConstraints, supportedSignAlgs);
// May be no default activated signature algorithm, but
// let the following process make the final decision.
}
// Sets the peer supported signature algorithm to use in KM
// temporarily.
session.setPeerSupportedSignatureAlgorithms(supportedSignAlgs);
}
}
// The named group used for ECDHE and FFDHE.
NamedGroup namedGroup = null;
switch(keyExchange) {
case K_RSA:
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
break;
case K_RSA_EXPORT:
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
try {
if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
if (!setupEphemeralRSAKeys(suite.exportable)) {
return false;
}
}
} catch (RuntimeException e) {
// could not determine keylength, ignore key
return false;
}
break;
case K_DHE_RSA:
// FFDHE extension will not be used.
if ((!useLegacyEphemeralDHKeys) && (!suite.exportable) && (requestedGroups != null) && requestedGroups.hasFFDHEGroup()) {
namedGroup = requestedGroups.getPreferredGroup(algorithmConstraints, NamedGroupType.NAMED_GROUP_FFDHE);
if (namedGroup == null) {
// no match found, cannot use this cipher suite.
return false;
}
}
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.useTLS12PlusSpec()) {
preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm(supportedSignAlgs, "RSA", privateKey);
if (preferableSignatureAlgorithm == null) {
if ((debug != null) && Debug.isOn("handshake")) {
System.out.println("No signature and hash algorithm for cipher " + suite);
}
return false;
}
}
setupEphemeralDHKeys(namedGroup, suite.exportable, privateKey);
break;
case K_ECDHE_RSA:
// Is ECDHE cipher suite usable for the connection?
namedGroup = (requestedGroups != null) ? requestedGroups.getPreferredGroup(algorithmConstraints, NamedGroupType.NAMED_GROUP_ECDHE) : SupportedGroupsExtension.getPreferredECGroup(algorithmConstraints);
if (namedGroup == null) {
// no match found, cannot use this ciphersuite
return false;
}
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.useTLS12PlusSpec()) {
preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm(supportedSignAlgs, "RSA", privateKey);
if (preferableSignatureAlgorithm == null) {
if ((debug != null) && Debug.isOn("handshake")) {
System.out.println("No signature and hash algorithm for cipher " + suite);
}
return false;
}
}
setupEphemeralECDHKeys(namedGroup);
break;
case K_DHE_DSS:
// See comment in K_DHE_RSA case.
if ((!useLegacyEphemeralDHKeys) && (!suite.exportable) && (requestedGroups != null) && requestedGroups.hasFFDHEGroup()) {
namedGroup = requestedGroups.getPreferredGroup(algorithmConstraints, NamedGroupType.NAMED_GROUP_FFDHE);
if (namedGroup == null) {
// no match found, cannot use this cipher suite.
return false;
}
}
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.useTLS12PlusSpec()) {
preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm(supportedSignAlgs, "DSA");
if (preferableSignatureAlgorithm == null) {
if ((debug != null) && Debug.isOn("handshake")) {
System.out.println("No signature and hash algorithm for cipher " + suite);
}
return false;
}
}
// need DSS certs for authentication
if (setupPrivateKeyAndChain("DSA") == false) {
return false;
}
setupEphemeralDHKeys(namedGroup, suite.exportable, privateKey);
break;
case K_ECDHE_ECDSA:
// Is ECDHE cipher suite usable for the connection?
namedGroup = (requestedGroups != null) ? requestedGroups.getPreferredGroup(algorithmConstraints, NamedGroupType.NAMED_GROUP_ECDHE) : SupportedGroupsExtension.getPreferredECGroup(algorithmConstraints);
if (namedGroup == null) {
// no match found, cannot use this ciphersuite
return false;
}
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.useTLS12PlusSpec()) {
preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm(supportedSignAlgs, "ECDSA");
if (preferableSignatureAlgorithm == null) {
if ((debug != null) && Debug.isOn("handshake")) {
System.out.println("No signature and hash algorithm for cipher " + suite);
}
return false;
}
}
// need EC cert
if (setupPrivateKeyAndChain("EC") == false) {
return false;
}
setupEphemeralECDHKeys(namedGroup);
break;
case K_ECDH_RSA:
// need EC cert
if (setupPrivateKeyAndChain("EC") == false) {
return false;
}
setupStaticECDHKeys();
break;
case K_ECDH_ECDSA:
// need EC cert
if (setupPrivateKeyAndChain("EC") == false) {
return false;
}
setupStaticECDHKeys();
break;
case K_DH_ANON:
// See comment in K_DHE_RSA case.
if ((!useLegacyEphemeralDHKeys) && (!suite.exportable) && (requestedGroups != null) && requestedGroups.hasFFDHEGroup()) {
namedGroup = requestedGroups.getPreferredGroup(algorithmConstraints, NamedGroupType.NAMED_GROUP_FFDHE);
if (namedGroup == null) {
// no match found, cannot use this cipher suite.
return false;
}
}
// no certs needed for anonymous
setupEphemeralDHKeys(namedGroup, suite.exportable, null);
break;
case K_ECDH_ANON:
// Is ECDHE cipher suite usable for the connection?
namedGroup = (requestedGroups != null) ? requestedGroups.getPreferredGroup(algorithmConstraints, NamedGroupType.NAMED_GROUP_ECDHE) : SupportedGroupsExtension.getPreferredECGroup(algorithmConstraints);
if (namedGroup == null) {
// no match found, cannot use this ciphersuite
return false;
}
// no certs needed for anonymous
setupEphemeralECDHKeys(namedGroup);
break;
default:
ClientKeyExchangeService p = ClientKeyExchangeService.find(keyExchange.name);
if (p == null) {
// internal error, unknown key exchange
throw new RuntimeException("Unrecognized cipherSuite: " + suite);
}
// need service creds
if (serviceCreds == null) {
AccessControlContext acc = getAccSE();
serviceCreds = p.getServiceCreds(acc);
if (serviceCreds != null) {
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Using serviceCreds");
}
}
if (serviceCreds == null) {
return false;
}
}
break;
}
setCipherSuite(suite);
// set the peer implicit supported signature algorithms
if (protocolVersion.useTLS12PlusSpec()) {
if (peerSupportedSignAlgs == null) {
setPeerSupportedSignAlgs(supportedSignAlgs);
// we had alreay update the session
}
}
return true;
}
use of sun.security.ssl.CipherSuite.KeyExchange in project Bytecoder by mirkosertic.
the class HandshakeStateManager method update.
void update(HandshakeMessage handshakeMessage, boolean isAbbreviated) throws SSLProtocolException {
byte handshakeType = (byte) handshakeMessage.messageType();
String exceptionMsg = "Handshake message sequence violation, " + handshakeType;
if (debugIsOn) {
System.out.println("update handshake state: " + toString(handshakeType));
}
boolean hasPresentState = false;
switch(handshakeType) {
case HandshakeMessage.ht_hello_request:
// Add the upcoming states.
if (!upcomingStates.isEmpty()) {
// A ClientHello message should be followed.
upcomingStates.add(HS_CLIENT_HELLO);
}
break;
case HandshakeMessage.ht_client_hello:
// Check and update the present state.
if (!upcomingStates.isEmpty()) {
// The current state should be HS_CLIENT_HELLO.
HandshakeState handshakeState = upcomingStates.pop();
if (handshakeState != HS_CLIENT_HELLO) {
throw new SSLProtocolException(exceptionMsg);
}
}
// Add the upcoming states.
ClientHello clientHello = (ClientHello) handshakeMessage;
if (isDTLS) {
// Is it an initial ClientHello message?
if (clientHello.cookie == null || clientHello.cookie.length == 0) {
// Is it an abbreviated handshake?
if (clientHello.sessionId.length() != 0) {
// A HelloVerifyRequest message or a ServerHello
// message may follow the abbreviated session
// resuming handshake request.
upcomingStates.add(HS_HELLO_VERIFY_REQUEST);
alternatives.add(HS_SERVER_HELLO);
} else {
// A HelloVerifyRequest message should follow
// the initial ClientHello message.
upcomingStates.add(HS_HELLO_VERIFY_REQUEST);
}
} else {
// A HelloVerifyRequest may be followed if the cookie
// cannot be verified.
upcomingStates.add(HS_SERVER_HELLO);
alternatives.add(HS_HELLO_VERIFY_REQUEST);
}
} else {
upcomingStates.add(HS_SERVER_HELLO);
}
break;
case HandshakeMessage.ht_hello_verify_request:
// Check and update the present state.
if (!upcomingStates.isEmpty()) {
// The current state should be HS_HELLO_VERIFY_REQUEST.
HandshakeState handshakeState = upcomingStates.pop();
HandshakeState alternative = null;
if (!alternatives.isEmpty()) {
alternative = alternatives.pop();
}
if ((handshakeState != HS_HELLO_VERIFY_REQUEST) && (alternative != HS_HELLO_VERIFY_REQUEST)) {
throw new SSLProtocolException(exceptionMsg);
}
} else {
// No present state.
throw new SSLProtocolException(exceptionMsg);
}
// Add the upcoming states.
upcomingStates.add(HS_CLIENT_HELLO);
break;
case HandshakeMessage.ht_server_hello:
// Check and update the present state.
if (!upcomingStates.isEmpty()) {
// The current state should be HS_SERVER_HELLO
HandshakeState handshakeState = upcomingStates.pop();
HandshakeState alternative = null;
if (!alternatives.isEmpty()) {
alternative = alternatives.pop();
}
if ((handshakeState != HS_SERVER_HELLO) && (alternative != HS_SERVER_HELLO)) {
throw new SSLProtocolException(exceptionMsg);
}
} else {
// No present state.
throw new SSLProtocolException(exceptionMsg);
}
// Add the upcoming states.
ServerHello serverHello = (ServerHello) handshakeMessage;
HelloExtensions hes = serverHello.extensions;
if (isAbbreviated) {
// Not support SessionTicket extension yet.
//
// // Mandatory NewSessionTicket message
// if (hasSessionTicketExt) {
// upcomingStates.add(HS_NEW_SESSION_TICKET);
// }
// Mandatory server ChangeCipherSpec and Finished messages
upcomingStates.add(HS_SERVER_CHANGE_CIPHER_SPEC);
upcomingStates.add(HS_SERVER_FINISHED);
// Mandatory client ChangeCipherSpec and Finished messages
upcomingStates.add(HS_CLIENT_CHANGE_CIPHER_SPEC);
upcomingStates.add(HS_CLEINT_FINISHED);
} else {
// Not support SupplementalData extension yet.
//
// boolean hasSupplementalDataExt =
// (hes.get(HandshakeMessage.ht_supplemental_data) != null);
// Not support CertificateURL extension yet.
//
// boolean hasCertificateUrlExt =
// (hes.get(ExtensionType EXT_CLIENT_CERTIFICATE_URL)
// != null);
// Not support SupplementalData extension yet.
//
// // Optional SupplementalData message
// if (hasSupplementalDataExt) {
// upcomingStates.add(HS_SERVER_SUPPLEMENTAL_DATA);
// }
// Need server Certificate message or not?
KeyExchange keyExchange = serverHello.cipherSuite.keyExchange;
if ((keyExchange != K_KRB5) && (keyExchange != K_KRB5_EXPORT) && (keyExchange != K_DH_ANON) && (keyExchange != K_ECDH_ANON)) {
// Mandatory Certificate message
upcomingStates.add(HS_SERVER_CERTIFICATE);
}
// Optional CertificateStatus message
if (hes.get(ExtensionType.EXT_STATUS_REQUEST) != null || hes.get(ExtensionType.EXT_STATUS_REQUEST_V2) != null) {
upcomingStates.add(HS_CERTIFICATE_STATUS);
}
// Need ServerKeyExchange message or not?
if ((keyExchange == K_RSA_EXPORT) || (keyExchange == K_DHE_RSA) || (keyExchange == K_DHE_DSS) || (keyExchange == K_DH_ANON) || (keyExchange == K_ECDHE_RSA) || (keyExchange == K_ECDHE_ECDSA) || (keyExchange == K_ECDH_ANON)) {
// Optional ServerKeyExchange message
upcomingStates.add(HS_SERVER_KEY_EXCHANGE);
}
// Optional CertificateRequest message
upcomingStates.add(HS_CERTIFICATE_REQUEST);
// Mandatory ServerHelloDone message
upcomingStates.add(HS_SERVER_HELLO_DONE);
// Not support SupplementalData extension yet.
//
// // Optional SupplementalData message
// if (hasSupplementalDataExt) {
// upcomingStates.add(HS_CLIENT_SUPPLEMENTAL_DATA);
// }
// Optional client Certificate message
upcomingStates.add(HS_CLIENT_CERTIFICATE);
// Not support CertificateURL extension yet.
//
// // Alternative CertificateURL message, optional too.
// //
// // Please put CertificateURL rather than Certificate
// // message in the alternatives list. So that we can
// // simplify the process of this alternative pair later.
// if (hasCertificateUrlExt) {
// alternatives.add(HS_CERTIFICATE_URL);
// }
// Mandatory ClientKeyExchange message
upcomingStates.add(HS_CLIENT_KEY_EXCHANGE);
// Optional CertificateVerify message
upcomingStates.add(HS_CERTIFICATE_VERIFY);
// Mandatory client ChangeCipherSpec and Finished messages
upcomingStates.add(HS_CLIENT_CHANGE_CIPHER_SPEC);
upcomingStates.add(HS_CLEINT_FINISHED);
// Not support SessionTicket extension yet.
//
// // Mandatory NewSessionTicket message
// if (hasSessionTicketExt) {
// upcomingStates.add(HS_NEW_SESSION_TICKET);
// }
// Mandatory server ChangeCipherSpec and Finished messages
upcomingStates.add(HS_SERVER_CHANGE_CIPHER_SPEC);
upcomingStates.add(HS_SERVER_FINISHED);
}
break;
case HandshakeMessage.ht_certificate:
// Check and update the present state.
while (!upcomingStates.isEmpty()) {
HandshakeState handshakeState = upcomingStates.pop();
if (handshakeState.handshakeType == handshakeType) {
hasPresentState = true;
// the alternative list.
if ((handshakeState != HS_CLIENT_CERTIFICATE) && (handshakeState != HS_SERVER_CERTIFICATE)) {
throw new SSLProtocolException(exceptionMsg);
}
// Is it an expected client Certificate message?
boolean isClientMessage = false;
if (!upcomingStates.isEmpty()) {
// If the next expected message is ClientKeyExchange,
// this one should be an expected client Certificate
// message.
HandshakeState nextState = upcomingStates.getFirst();
if (nextState == HS_CLIENT_KEY_EXCHANGE) {
isClientMessage = true;
}
}
if (isClientMessage) {
if (handshakeState != HS_CLIENT_CERTIFICATE) {
throw new SSLProtocolException(exceptionMsg);
}
// Not support CertificateURL extension yet.
/**
*****************************************
* // clear up the alternatives list
* if (!alternatives.isEmpty()) {
* HandshakeState alternative = alternatives.pop();
*
* if (alternative != HS_CERTIFICATE_URL) {
* throw new SSLProtocolException(exceptionMsg);
* }
* }
*******************************************
*/
} else {
if ((handshakeState != HS_SERVER_CERTIFICATE)) {
throw new SSLProtocolException(exceptionMsg);
}
}
break;
} else if (!handshakeState.isOptional) {
throw new SSLProtocolException(exceptionMsg);
}
// Otherwise, looking for next state track.
}
// No present state.
if (!hasPresentState) {
throw new SSLProtocolException(exceptionMsg);
}
break;
/**
**********************************************
*/
case HandshakeMessage.ht_certificate_url:
// Check and update the present state.
while (!upcomingStates.isEmpty()) {
// The current state should be HS_CLIENT_CERTIFICATE.
//
// Note that we won't put HS_CLIENT_CERTIFICATE into
// the alternative list.
HandshakeState handshakeState = upcomingStates.pop();
if (handshakeState.handshakeType == HS_CLIENT_CERTIFICATE.handshakeType) {
hasPresentState = true;
// Look for HS_CERTIFICATE_URL state track.
if (!alternatives.isEmpty()) {
HandshakeState alternative = alternatives.pop();
if (alternative != HS_CERTIFICATE_URL) {
throw new SSLProtocolException(exceptionMsg);
}
} else {
// No alternative CertificateUR state track.
throw new SSLProtocolException(exceptionMsg);
}
if ((handshakeState != HS_CLIENT_CERTIFICATE)) {
throw new SSLProtocolException(exceptionMsg);
}
break;
} else if (!handshakeState.isOptional) {
throw new SSLProtocolException(exceptionMsg);
}
// Otherwise, looking for next state track.
}
// No present state.
if (!hasPresentState) {
// No present state.
throw new SSLProtocolException(exceptionMsg);
}
break;
default:
// Check and update the present state.
while (!upcomingStates.isEmpty()) {
HandshakeState handshakeState = upcomingStates.pop();
if (handshakeState.handshakeType == handshakeType) {
hasPresentState = true;
break;
} else if (!handshakeState.isOptional) {
throw new SSLProtocolException(exceptionMsg);
}
// Otherwise, looking for next state track.
}
// No present state.
if (!hasPresentState) {
throw new SSLProtocolException(exceptionMsg);
}
}
if (debugIsOn) {
for (HandshakeState handshakeState : upcomingStates) {
System.out.println("upcoming handshake states: " + handshakeState);
}
for (HandshakeState handshakeState : alternatives) {
System.out.println("upcoming handshake alternative state: " + handshakeState);
}
}
}
Aggregations