--- old/src/java.base/share/classes/sun/security/ssl/HandshakeStateManager.java 2018-05-11 15:11:30.502841500 -0700 +++ /dev/null 2018-05-11 10:42:23.849000000 -0700 @@ -1,922 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.security.ssl; - -import java.util.Collections; -import java.util.List; -import java.util.LinkedList; -import java.util.HashMap; -import javax.net.ssl.SSLProtocolException; - -import static sun.security.ssl.CipherSuite.KeyExchange; -import static sun.security.ssl.CipherSuite.KeyExchange.*; -import static sun.security.ssl.HandshakeStateManager.HandshakeState.*; -import static sun.security.ssl.HandshakeMessage.*; - -/* - * Handshake state manager. - * - * Messages flow for a full handshake: - * - * - - - * | HelloRequest (No.0, RFC 5246) [*] | - * | <-------------------------------------------- | - * | | - * | ClientHello (No.1, RFC 5246) | - * | --------------------------------------------> | - * | | - * | - HelloVerifyRequest (No.3, RFC 6347) - | - * | D | <-------------------------------------------- | D | - * | T | | T | - * | L | ClientHello (No.1, RFC 5246) | L | - * | S | --------------------------------------------> | S | - * | - - | - * | | - * C | ServerHello (No.2, RFC 5246) | S - * L | SupplementalData (No.23, RFC4680) [*] | E - * I | Certificate (No.11, RFC 5246) [*] | R - * E | CertificateStatus (No.22, RFC 6066) [*] | V - * N | ServerKeyExchange (No.12, RFC 5246) [*] | E - * T | CertificateRequest (No.13, RFC 5246) [*] | R - * | ServerHelloDone (No.14, RFC 5246) | - * | <-------------------------------------------- | - * | | - * | SupplementalData (No.23, RFC4680) [*] | - * | Certificate (No.11, RFC 5246) [*] Or | - * | CertificateURL (No.21, RFC6066) [*] | - * | ClientKeyExchange (No.16, RFC 5246) | - * | CertificateVerify (No.15, RFC 5246) [*] | - * | [ChangeCipherSpec] (RFC 5246) | - * | Finished (No.20, RFC 5246) | - * | --------------------------------------------> | - * | | - * | NewSessionTicket (No.4, RFC4507) [*] | - * | [ChangeCipherSpec] (RFC 5246) | - * | Finished (No.20, RFC 5246) | - * | <-------------------------------------------- | - * - - - * [*] Indicates optional or situation-dependent messages that are not - * always sent. - * - * Message flow for an abbreviated handshake: - * - - - * | ClientHello (No.1, RFC 5246) | - * | --------------------------------------------> | - * | | - * C | ServerHello (No.2, RFC 5246) | S - * L | NewSessionTicket (No.4, RFC4507) [*] | E - * I | [ChangeCipherSpec] (RFC 5246) | R - * E | Finished (No.20, RFC 5246) | V - * N | <-------------------------------------------- | E - * T | | R - * | [ChangeCipherSpec] (RFC 5246) | - * | Finished (No.20, RFC 5246) | - * | --------------------------------------------> | - * - - - * - * - * State machine of handshake states: - * - * +--------------+ - * START -----> | HelloRequest | - * | +--------------+ - * | | - * v v - * +---------------------+ --> +---------------------+ - * | ClientHello | | HelloVerifyRequest | - * +---------------------+ <-- +---------------------+ - * | - * | - * ========================================================================= - * | - * v - * +---------------------+ - * | ServerHello | ----------------------------------+------+ - * +---------------------+ --> +-------------------------+ | | - * | | Server SupplementalData | | | - * | +-------------------------+ | | - * | | | | - * v v | | - * +---------------------+ | | - * +---- | Server Certificate | | | - * | +---------------------+ | | - * | | | | - * | | +--------------------+ | | - * | +-> | CertificateStatus | | | - * | | +--------------------+ v | - * | | | | +--------------------+ | - * | v v +--> | ServerKeyExchange | | - * | +---------------------+ | +--------------------+ | - * | | CertificateRequest | | | | - * | +---------------------+ <-+---------+ | - * | | | | | - * v v | | | - * +---------------------+ <-------+ | | - * | ServerHelloDone | <-----------------+ | - * +---------------------+ | - * | | | - * | | | - * | | | - * ========================================================================= - * | | | - * | v | - * | +-------------------------+ | - * | | Client SupplementalData | --------------+ | - * | +-------------------------+ | | - * | | | | - * | v | | - * | +--------------------+ | | - * +-> | Client Certificate | ALT. | | - * | +--------------------+----------------+ | | - * | | CertificateURL | | | - * | +----------------+ | | - * v | | - * +-------------------+ <------------------------+ | - * | ClientKeyExchange | | - * +-------------------+ | - * | | | - * | v | - * | +-------------------+ | - * | | CertificateVerify | | - * | +-------------------+ | - * | | | - * v v | - * +-------------------------+ | - * | Client ChangeCipherSpec | <---------------+ | - * +-------------------------+ | | - * | | | - * v | | - * +-----------------+ (abbreviated) | | - * | Client Finished | -------------> END | | - * +-----------------+ (Abbreviated handshake) | | - * | | | - * | (full) | | - * | | | - * ================================ | | - * | | | - * | ================================ - * | | | - * v | | - * +------------------+ | (abbreviated) | - * | NewSessionTicket | <--------------------------------+ - * +------------------+ | | - * | | | - * v | | - * +-------------------------+ | (abbreviated) | - * | Server ChangeCipherSpec | <-------------------------------------+ - * +-------------------------+ | - * | | - * v | - * +-----------------+ (abbreviated) | - * | Server Finished | -------------------------+ - * +-----------------+ - * | (full) - * v - * END (Full handshake) - * - * - * The scenarios of the use of this class: - * 1. Create an instance of HandshakeStateManager during the initializtion - * handshake. - * 2. If receiving a handshake message, call HandshakeStateManager.check() - * to make sure that the message is of the expected handshake type. And - * then call HandshakeStateManager.update() in case handshake states may - * be impacted by this new incoming handshake message. - * 3. On delivering a handshake message, call HandshakeStateManager.update() - * in case handshake states may by thie new outgoing handshake message. - * 4. On receiving and delivering ChangeCipherSpec message, call - * HandshakeStateManager.changeCipherSpec() to check the present sequence - * of this message, and update the states if necessary. - */ -final class HandshakeStateManager { - // upcoming handshake states. - private LinkedList upcomingStates; - private LinkedList alternatives; - - private boolean isDTLS; - - private static final boolean debugIsOn; - - private static final HashMap handshakeTypes; - - static { - debugIsOn = (Handshaker.debug != null) && - Debug.isOn("handshake") && Debug.isOn("verbose"); - handshakeTypes = new HashMap<>(15); - - handshakeTypes.put(ht_hello_request, "hello_request"); - handshakeTypes.put(ht_client_hello, "client_hello"); - handshakeTypes.put(ht_server_hello, "server_hello"); - handshakeTypes.put(ht_hello_verify_request, "hello_verify_request"); - handshakeTypes.put(ht_new_session_ticket, "session_ticket"); - handshakeTypes.put(ht_certificate, "certificate"); - handshakeTypes.put(ht_server_key_exchange, "server_key_exchange"); - handshakeTypes.put(ht_certificate_request, "certificate_request"); - handshakeTypes.put(ht_server_hello_done, "server_hello_done"); - handshakeTypes.put(ht_certificate_verify, "certificate_verify"); - handshakeTypes.put(ht_client_key_exchange, "client_key_exchange"); - handshakeTypes.put(ht_finished, "finished"); - handshakeTypes.put(ht_certificate_url, "certificate_url"); - handshakeTypes.put(ht_certificate_status, "certificate_status"); - handshakeTypes.put(ht_supplemental_data, "supplemental_data"); - } - - HandshakeStateManager(boolean isDTLS) { - this.upcomingStates = new LinkedList<>(); - this.alternatives = new LinkedList<>(); - this.isDTLS = isDTLS; - } - - // - // enumation of handshake type - // - static enum HandshakeState { - HS_HELLO_REQUEST( - "hello_request", - HandshakeMessage.ht_hello_request), - HS_CLIENT_HELLO( - "client_hello", - HandshakeMessage.ht_client_hello), - HS_HELLO_VERIFY_REQUEST( - "hello_verify_request", - HandshakeMessage.ht_hello_verify_request), - HS_SERVER_HELLO( - "server_hello", - HandshakeMessage.ht_server_hello), - HS_SERVER_SUPPLEMENTAL_DATA( - "server supplemental_data", - HandshakeMessage.ht_supplemental_data, true), - HS_SERVER_CERTIFICATE( - "server certificate", - HandshakeMessage.ht_certificate), - HS_CERTIFICATE_STATUS( - "certificate_status", - HandshakeMessage.ht_certificate_status, true), - HS_SERVER_KEY_EXCHANGE( - "server_key_exchange", - HandshakeMessage.ht_server_key_exchange, true), - HS_CERTIFICATE_REQUEST( - "certificate_request", - HandshakeMessage.ht_certificate_request, true), - HS_SERVER_HELLO_DONE( - "server_hello_done", - HandshakeMessage.ht_server_hello_done), - HS_CLIENT_SUPPLEMENTAL_DATA( - "client supplemental_data", - HandshakeMessage.ht_supplemental_data, true), - HS_CLIENT_CERTIFICATE( - "client certificate", - HandshakeMessage.ht_certificate, true), - HS_CERTIFICATE_URL( - "certificate_url", - HandshakeMessage.ht_certificate_url, true), - HS_CLIENT_KEY_EXCHANGE( - "client_key_exchange", - HandshakeMessage.ht_client_key_exchange), - HS_CERTIFICATE_VERIFY( - "certificate_verify", - HandshakeMessage.ht_certificate_verify, true), - HS_CLIENT_CHANGE_CIPHER_SPEC( - "client change_cipher_spec", - HandshakeMessage.ht_not_applicable), - HS_CLEINT_FINISHED( - "client finished", - HandshakeMessage.ht_finished), - HS_NEW_SESSION_TICKET( - "session_ticket", - HandshakeMessage.ht_new_session_ticket), - HS_SERVER_CHANGE_CIPHER_SPEC( - "server change_cipher_spec", - HandshakeMessage.ht_not_applicable), - HS_SERVER_FINISHED( - "server finished", - HandshakeMessage.ht_finished); - - final String description; - final byte handshakeType; - final boolean isOptional; - - HandshakeState(String description, byte handshakeType) { - this.description = description; - this.handshakeType = handshakeType; - this.isOptional = false; - } - - HandshakeState(String description, - byte handshakeType, boolean isOptional) { - - this.description = description; - this.handshakeType = handshakeType; - this.isOptional = isOptional; - } - - public String toString() { - return description + "[" + handshakeType + "]" + - (isOptional ? "(optional)" : ""); - } - } - - boolean isEmpty() { - return upcomingStates.isEmpty(); - } - - List check(byte handshakeType) throws SSLProtocolException { - List ignoredOptional = new LinkedList<>(); - String exceptionMsg = - "Handshake message sequence violation, " + handshakeType; - - if (debugIsOn) { - System.out.println( - "check handshake state: " + toString(handshakeType)); - } - - if (upcomingStates.isEmpty()) { - // Is it a kickstart message? - if ((handshakeType != HandshakeMessage.ht_hello_request) && - (handshakeType != HandshakeMessage.ht_client_hello)) { - - throw new SSLProtocolException( - "Handshake message sequence violation, " + handshakeType); - } - - // It is a kickstart message. - return Collections.emptyList(); - } - - // Ignore the checking for HelloRequest messages as they - // may be sent by the server at any time. - if (handshakeType == HandshakeMessage.ht_hello_request) { - return Collections.emptyList(); - } - - for (HandshakeState handshakeState : upcomingStates) { - if (handshakeState.handshakeType == handshakeType) { - // It's the expected next handshake type. - return ignoredOptional; - } - - if (handshakeState.isOptional) { - ignoredOptional.add(handshakeState.handshakeType); - continue; - } else { - for (HandshakeState alternative : alternatives) { - if (alternative.handshakeType == handshakeType) { - return ignoredOptional; - } - - if (alternative.isOptional) { - continue; - } else { - throw new SSLProtocolException(exceptionMsg); - } - } - } - - throw new SSLProtocolException(exceptionMsg); - } - - // Not an expected Handshake message. - throw new SSLProtocolException( - "Handshake message sequence violation, " + handshakeType); - } - - 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: - // - // State machine: - // PRESENT: START - // TO : ClientHello - // - - // No old state to update. - - // Add the upcoming states. - if (!upcomingStates.isEmpty()) { - // A ClientHello message should be followed. - upcomingStates.add(HS_CLIENT_HELLO); - - } // Otherwise, ignore this HelloRequest message. - - break; - - case HandshakeMessage.ht_client_hello: - // - // State machine: - // PRESENT: START - // HS_CLIENT_HELLO - // TO : HS_HELLO_VERIFY_REQUEST (DTLS) - // HS_SERVER_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: - // - // State machine: - // PRESENT: HS_HELLO_VERIFY_REQUEST - // TO : HS_CLIENT_HELLO - // - // Note that this state may have an alternative option. - - // 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: - // - // State machine: - // PRESENT: HS_SERVER_HELLO - // TO : - // Full handshake state stacks - // (ServerHello Flight) - // HS_SERVER_SUPPLEMENTAL_DATA [optional] - // --> HS_SERVER_CERTIFICATE [optional] - // --> HS_CERTIFICATE_STATUS [optional] - // --> HS_SERVER_KEY_EXCHANGE [optional] - // --> HS_CERTIFICATE_REQUEST [optional] - // --> HS_SERVER_HELLO_DONE - // (Client ClientKeyExchange Flight) - // --> HS_CLIENT_SUPPLEMENTAL_DATA [optional] - // --> HS_CLIENT_CERTIFICATE or - // HS_CERTIFICATE_URL - // --> HS_CLIENT_KEY_EXCHANGE - // --> HS_CERTIFICATE_VERIFY [optional] - // --> HS_CLIENT_CHANGE_CIPHER_SPEC - // --> HS_CLEINT_FINISHED - // (Server Finished Flight) - // --> HS_CLIENT_SUPPLEMENTAL_DATA [optional] - // - // Abbreviated handshake state stacks - // (Server Finished Flight) - // HS_NEW_SESSION_TICKET - // --> HS_SERVER_CHANGE_CIPHER_SPEC - // --> HS_SERVER_FINISHED - // (Client Finished Flight) - // --> HS_CLIENT_CHANGE_CIPHER_SPEC - // --> HS_CLEINT_FINISHED - // - // Note that this state may have an alternative option. - - // 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; - - - // Not support SessionTicket extension yet. - // - // boolean hasSessionTicketExt = - // (hes.get(HandshakeMessage.ht_new_session_ticket) != null); - - 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: - // - // State machine: - // PRESENT: HS_CERTIFICATE_URL or - // HS_CLIENT_CERTIFICATE - // TO : HS_CLIENT_KEY_EXCHANGE - // - // Or - // - // PRESENT: HS_SERVER_CERTIFICATE - // TO : HS_CERTIFICATE_STATUS [optional] - // HS_SERVER_KEY_EXCHANGE [optional] - // HS_CERTIFICATE_REQUEST [optional] - // HS_SERVER_HELLO_DONE - // - // Note that this state may have an alternative option. - - // Check and update the present state. - while (!upcomingStates.isEmpty()) { - HandshakeState handshakeState = upcomingStates.pop(); - if (handshakeState.handshakeType == handshakeType) { - hasPresentState = true; - - // The current state should be HS_CLIENT_CERTIFICATE or - // HS_SERVER_CERTIFICATE. - // - // Note that we won't put HS_CLIENT_CERTIFICATE into - // 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); - } - - // no new upcoming states. - - break; - - // Not support CertificateURL extension yet. - /*************************************************/ - case HandshakeMessage.ht_certificate_url: - // - // State machine: - // PRESENT: HS_CERTIFICATE_URL or - // HS_CLIENT_CERTIFICATE - // TO : HS_CLIENT_KEY_EXCHANGE - // - // Note that this state may have an alternative option. - - // 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); - } - - // no new upcoming states. - - 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); - } - - // no new upcoming states. - } - - 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); - } - } - } - - void changeCipherSpec(boolean isInput, - boolean isClient) throws SSLProtocolException { - - if (debugIsOn) { - System.out.println( - "update handshake state: change_cipher_spec"); - } - - String exceptionMsg = "ChangeCipherSpec message sequence violation"; - - HandshakeState expectedState; - if ((isClient && isInput) || (!isClient && !isInput)) { - expectedState = HS_SERVER_CHANGE_CIPHER_SPEC; - } else { - expectedState = HS_CLIENT_CHANGE_CIPHER_SPEC; - } - - boolean hasPresentState = false; - - // Check and update the present state. - while (!upcomingStates.isEmpty()) { - HandshakeState handshakeState = upcomingStates.pop(); - if (handshakeState == expectedState) { - 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); - } - - // no new upcoming states. - - 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); - } - } - } - - private static String toString(byte handshakeType) { - String s = handshakeTypes.get(handshakeType); - if (s == null) { - s = "unknown"; - } - return (s + "[" + handshakeType + "]"); - } -} -