1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.ssl;
  27 
  28 import java.util.Collections;
  29 import java.util.List;
  30 import java.util.LinkedList;
  31 import java.util.HashMap;
  32 import javax.net.ssl.SSLProtocolException;
  33 
  34 import static sun.security.ssl.CipherSuite.KeyExchange;
  35 import static sun.security.ssl.CipherSuite.KeyExchange.*;
  36 import static sun.security.ssl.HandshakeStateManager.HandshakeState.*;
  37 import static sun.security.ssl.HandshakeMessage.*;
  38 
  39 /*
  40  * Handshake state manager.
  41  *
  42  * Messages flow for a full handshake:
  43  *
  44  *      -                                                         -
  45  *      |          HelloRequest       (No.0, RFC 5246) [*]        |
  46  *      |     <--------------------------------------------       |
  47  *      |                                                         |
  48  *      |          ClientHello        (No.1, RFC 5246)            |
  49  *      |     -------------------------------------------->       |
  50  *      |                                                         |
  51  *      |   -      HelloVerifyRequest (No.3, RFC 6347)      -     |
  52  *      | D | <-------------------------------------------- | D   |
  53  *      | T |                                               | T   |
  54  *      | L |      ClientHello        (No.1, RFC 5246)      | L   |
  55  *      | S | --------------------------------------------> | S   |
  56  *      |   -                                               -     |
  57  *      |                                                         |
  58  *   C  |          ServerHello        (No.2, RFC 5246)            |  S
  59  *   L  |          SupplementalData   (No.23, RFC4680) [*]        |  E
  60  *   I  |          Certificate        (No.11, RFC 5246) [*]       |  R
  61  *   E  |          CertificateStatus  (No.22, RFC 6066) [*]       |  V
  62  *   N  |          ServerKeyExchange  (No.12, RFC 5246) [*]       |  E
  63  *   T  |          CertificateRequest (No.13, RFC 5246) [*]       |  R
  64  *      |          ServerHelloDone    (No.14, RFC 5246)           |
  65  *      |     <--------------------------------------------       |
  66  *      |                                                         |
  67  *      |          SupplementalData   (No.23, RFC4680) [*]        |
  68  *      |          Certificate        (No.11, RFC 5246) [*] Or    |
  69  *      |              CertificateURL (No.21, RFC6066) [*]        |
  70  *      |          ClientKeyExchange  (No.16, RFC 5246)           |
  71  *      |          CertificateVerify  (No.15, RFC 5246) [*]       |
  72  *      |          [ChangeCipherSpec] (RFC 5246)                  |
  73  *      |          Finished           (No.20, RFC 5246)           |
  74  *      |     -------------------------------------------->       |
  75  *      |                                                         |
  76  *      |          NewSessionTicket   (No.4, RFC4507) [*]         |
  77  *      |          [ChangeCipherSpec] (RFC 5246)                  |
  78  *      |          Finished           (No.20, RFC 5246)           |
  79  *      |     <--------------------------------------------       |
  80  *      -                                                         -
  81  * [*] Indicates optional or situation-dependent messages that are not
  82  * always sent.
  83  *
  84  * Message flow for an abbreviated handshake:
  85  *      -                                                         -
  86  *      |          ClientHello        (No.1, RFC 5246)            |
  87  *      |     -------------------------------------------->       |
  88  *      |                                                         |
  89  *   C  |          ServerHello        (No.2, RFC 5246)            |  S
  90  *   L  |          NewSessionTicket   (No.4, RFC4507) [*]         |  E
  91  *   I  |          [ChangeCipherSpec] (RFC 5246)                  |  R
  92  *   E  |          Finished           (No.20, RFC 5246)           |  V
  93  *   N  |     <--------------------------------------------       |  E
  94  *   T  |                                                         |  R
  95  *      |          [ChangeCipherSpec] (RFC 5246)                  |
  96  *      |          Finished           (No.20, RFC 5246)           |
  97  *      |     -------------------------------------------->       |
  98  *      -                                                         -
  99  *
 100  *
 101  * State machine of handshake states:
 102  *
 103  *                   +--------------+
 104  *      START -----> | HelloRequest |
 105  *        |          +--------------+
 106  *        |               |
 107  *        v               v
 108  *     +---------------------+   -->  +---------------------+
 109  *     |    ClientHello      |        | HelloVerifyRequest  |
 110  *     +---------------------+   <--  +---------------------+
 111  *               |
 112  *               |
 113  * =========================================================================
 114  *               |
 115  *               v
 116  *     +---------------------+
 117  *     |    ServerHello      |  ----------------------------------+------+
 118  *     +---------------------+  -->  +-------------------------+  |      |
 119  *                    |              | Server SupplementalData |  |      |
 120  *                    |              +-------------------------+  |      |
 121  *                    |                |                          |      |
 122  *                    v                v                          |      |
 123  *                +---------------------+                         |      |
 124  *         +----  | Server Certificate  |                         |      |
 125  *         |      +---------------------+                         |      |
 126  *         |          |                                           |      |
 127  *         |          |   +--------------------+                  |      |
 128  *         |          +-> | CertificateStatus  |                  |      |
 129  *         |          |   +--------------------+                  v      |
 130  *         |          |      |          |     +--------------------+     |
 131  *         |          v      v          +-->  | ServerKeyExchange  |     |
 132  *         |  +---------------------+   |     +--------------------+     |
 133  *         |  | CertificateRequest  |   |         |                      |
 134  *         |  +---------------------+ <-+---------+                      |
 135  *         |            |               |         |                      |
 136  *         v            v               |         |                      |
 137  *     +---------------------+  <-------+         |                      |
 138  *     |  ServerHelloDone    |  <-----------------+                      |
 139  *     +---------------------+                                           |
 140  *       |         |                                                     |
 141  *       |         |                                                     |
 142  *       |         |                                                     |
 143  * =========================================================================
 144  *       |         |                                                     |
 145  *       |         v                                                     |
 146  *       |   +-------------------------+                                 |
 147  *       |   | Client SupplementalData | --------------+                 |
 148  *       |   +-------------------------+               |                 |
 149  *       |             |                               |                 |
 150  *       |             v                               |                 |
 151  *       |   +--------------------+                    |                 |
 152  *       +-> | Client Certificate | ALT.               |                 |
 153  *       |   +--------------------+----------------+   |                 |
 154  *       |                        | CertificateURL |   |                 |
 155  *       |                        +----------------+   |                 |
 156  *       v                                             |                 |
 157  *     +-------------------+  <------------------------+                 |
 158  *     | ClientKeyExchange |                                             |
 159  *     +-------------------+                                             |
 160  *          |           |                                                |
 161  *          |           v                                                |
 162  *          |      +-------------------+                                 |
 163  *          |      | CertificateVerify |                                 |
 164  *          |      +-------------------+                                 |
 165  *          |          |                                                 |
 166  *          v          v                                                 |
 167  *     +-------------------------+                                       |
 168  *     | Client ChangeCipherSpec |  <---------------+                    |
 169  *     +-------------------------+                  |                    |
 170  *               |                                  |                    |
 171  *               v                                  |                    |
 172  *     +-----------------+  (abbreviated)           |                    |
 173  *     | Client Finished |  -------------> END      |                    |
 174  *     +-----------------+  (Abbreviated handshake) |                    |
 175  *                      |                           |                    |
 176  *                      | (full)                    |                    |
 177  *                      |                           |                    |
 178  * ================================                 |                    |
 179  *                      |                           |                    |
 180  *                      |                   ================================
 181  *                      |                           |                    |
 182  *                      v                           |                    |
 183  *                 +------------------+             |    (abbreviated)   |
 184  *                 | NewSessionTicket | <--------------------------------+
 185  *                 +------------------+             |                    |
 186  *                      |                           |                    |
 187  *                      v                           |                    |
 188  *     +-------------------------+                  |    (abbreviated)   |
 189  *     | Server ChangeCipherSpec | <-------------------------------------+
 190  *     +-------------------------+                  |
 191  *               |                                  |
 192  *               v                                  |
 193  *     +-----------------+    (abbreviated)         |
 194  *     | Server Finished | -------------------------+
 195  *     +-----------------+
 196  *            | (full)
 197  *            v
 198  *        END (Full handshake)
 199  *
 200  *
 201  * The scenarios of the use of this class:
 202  * 1. Create an instance of HandshakeStateManager during the initializtion
 203  *    handshake.
 204  * 2. If receiving a handshake message, call HandshakeStateManager.check()
 205  *    to make sure that the message is of the expected handshake type.  And
 206  *    then call HandshakeStateManager.update() in case handshake states may
 207  *    be impacted by this new incoming handshake message.
 208  * 3. On delivering a handshake message, call HandshakeStateManager.update()
 209  *    in case handshake states may by thie new outgoing handshake message.
 210  * 4. On receiving and delivering ChangeCipherSpec message, call
 211  *    HandshakeStateManager.changeCipherSpec() to check the present sequence
 212  *    of this message, and update the states if necessary.
 213  */
 214 final class HandshakeStateManager {
 215     // upcoming handshake states.
 216     private LinkedList<HandshakeState> upcomingStates;
 217     private LinkedList<HandshakeState> alternatives;
 218 
 219     private boolean isDTLS;
 220 
 221     private static final boolean debugIsOn;
 222 
 223     private static final HashMap<Byte, String> handshakeTypes;
 224 
 225     static {
 226         debugIsOn = (Handshaker.debug != null) &&
 227                 Debug.isOn("handshake") && Debug.isOn("verbose");
 228         handshakeTypes = new HashMap<>(15);
 229 
 230         handshakeTypes.put(ht_hello_request,            "hello_request");
 231         handshakeTypes.put(ht_client_hello,             "client_hello");
 232         handshakeTypes.put(ht_server_hello,             "server_hello");
 233         handshakeTypes.put(ht_hello_verify_request,     "hello_verify_request");
 234         handshakeTypes.put(ht_new_session_ticket,       "session_ticket");
 235         handshakeTypes.put(ht_certificate,              "certificate");
 236         handshakeTypes.put(ht_server_key_exchange,      "server_key_exchange");
 237         handshakeTypes.put(ht_certificate_request,      "certificate_request");
 238         handshakeTypes.put(ht_server_hello_done,        "server_hello_done");
 239         handshakeTypes.put(ht_certificate_verify,       "certificate_verify");
 240         handshakeTypes.put(ht_client_key_exchange,      "client_key_exchange");
 241         handshakeTypes.put(ht_finished,                 "finished");
 242         handshakeTypes.put(ht_certificate_url,          "certificate_url");
 243         handshakeTypes.put(ht_certificate_status,       "certificate_status");
 244         handshakeTypes.put(ht_supplemental_data,        "supplemental_data");
 245     }
 246 
 247     HandshakeStateManager(boolean isDTLS) {
 248         this.upcomingStates = new LinkedList<>();
 249         this.alternatives = new LinkedList<>();
 250         this.isDTLS = isDTLS;
 251     }
 252 
 253     //
 254     // enumation of handshake type
 255     //
 256     static enum HandshakeState {
 257         HS_HELLO_REQUEST(
 258                 "hello_request",
 259                 HandshakeMessage.ht_hello_request),
 260         HS_CLIENT_HELLO(
 261                 "client_hello",
 262                 HandshakeMessage.ht_client_hello),
 263         HS_HELLO_VERIFY_REQUEST(
 264                 "hello_verify_request",
 265                 HandshakeMessage.ht_hello_verify_request),
 266         HS_SERVER_HELLO(
 267                 "server_hello",
 268                 HandshakeMessage.ht_server_hello),
 269         HS_SERVER_SUPPLEMENTAL_DATA(
 270                 "server supplemental_data",
 271                 HandshakeMessage.ht_supplemental_data, true),
 272         HS_SERVER_CERTIFICATE(
 273                 "server certificate",
 274                 HandshakeMessage.ht_certificate),
 275         HS_CERTIFICATE_STATUS(
 276                 "certificate_status",
 277                 HandshakeMessage.ht_certificate_status, true),
 278         HS_SERVER_KEY_EXCHANGE(
 279                 "server_key_exchange",
 280                 HandshakeMessage.ht_server_key_exchange, true),
 281         HS_CERTIFICATE_REQUEST(
 282                 "certificate_request",
 283                 HandshakeMessage.ht_certificate_request, true),
 284         HS_SERVER_HELLO_DONE(
 285                 "server_hello_done",
 286                 HandshakeMessage.ht_server_hello_done),
 287         HS_CLIENT_SUPPLEMENTAL_DATA(
 288                 "client supplemental_data",
 289                 HandshakeMessage.ht_supplemental_data, true),
 290         HS_CLIENT_CERTIFICATE(
 291                 "client certificate",
 292                 HandshakeMessage.ht_certificate, true),
 293         HS_CERTIFICATE_URL(
 294                 "certificate_url",
 295                 HandshakeMessage.ht_certificate_url, true),
 296         HS_CLIENT_KEY_EXCHANGE(
 297                 "client_key_exchange",
 298                 HandshakeMessage.ht_client_key_exchange),
 299         HS_CERTIFICATE_VERIFY(
 300                 "certificate_verify",
 301                 HandshakeMessage.ht_certificate_verify, true),
 302         HS_CLIENT_CHANGE_CIPHER_SPEC(
 303                 "client change_cipher_spec",
 304                 HandshakeMessage.ht_not_applicable),
 305         HS_CLEINT_FINISHED(
 306                 "client finished",
 307                 HandshakeMessage.ht_finished),
 308         HS_NEW_SESSION_TICKET(
 309                 "session_ticket",
 310                 HandshakeMessage.ht_new_session_ticket),
 311         HS_SERVER_CHANGE_CIPHER_SPEC(
 312                 "server change_cipher_spec",
 313                 HandshakeMessage.ht_not_applicable),
 314         HS_SERVER_FINISHED(
 315                 "server finished",
 316                 HandshakeMessage.ht_finished);
 317 
 318         final String description;
 319         final byte handshakeType;
 320         final boolean isOptional;
 321 
 322         HandshakeState(String description, byte handshakeType) {
 323             this.description = description;
 324             this.handshakeType = handshakeType;
 325             this.isOptional = false;
 326         }
 327 
 328         HandshakeState(String description,
 329                 byte handshakeType, boolean isOptional) {
 330 
 331             this.description = description;
 332             this.handshakeType = handshakeType;
 333             this.isOptional = isOptional;
 334         }
 335 
 336         public String toString() {
 337             return description + "[" + handshakeType + "]" +
 338                     (isOptional ? "(optional)" : "");
 339         }
 340     }
 341 
 342     boolean isEmpty() {
 343         return upcomingStates.isEmpty();
 344     }
 345 
 346     List<Byte> check(byte handshakeType) throws SSLProtocolException {
 347         List<Byte> ignoredOptional = new LinkedList<>();
 348         String exceptionMsg =
 349                  "Handshake message sequence violation, " + handshakeType;
 350 
 351         if (debugIsOn) {
 352             System.out.println(
 353                     "check handshake state: " + toString(handshakeType));
 354         }
 355 
 356         if (upcomingStates.isEmpty()) {
 357             // Is it a kickstart message?
 358             if ((handshakeType != HandshakeMessage.ht_hello_request) &&
 359                 (handshakeType != HandshakeMessage.ht_client_hello)) {
 360 
 361                 throw new SSLProtocolException(
 362                     "Handshake message sequence violation, " + handshakeType);
 363             }
 364 
 365             // It is a kickstart message.
 366             return Collections.emptyList();
 367         }
 368 
 369         // Ignore the checking for HelloRequest messages as they
 370         // may be sent by the server at any time.
 371         if (handshakeType == HandshakeMessage.ht_hello_request) {
 372             return Collections.emptyList();
 373         }
 374 
 375         for (HandshakeState handshakeState : upcomingStates) {
 376             if (handshakeState.handshakeType == handshakeType) {
 377                 // It's the expected next handshake type.
 378                 return ignoredOptional;
 379             }
 380 
 381             if (handshakeState.isOptional) {
 382                 ignoredOptional.add(handshakeState.handshakeType);
 383                 continue;
 384             } else {
 385                 for (HandshakeState alternative : alternatives) {
 386                     if (alternative.handshakeType == handshakeType) {
 387                         return ignoredOptional;
 388                     }
 389 
 390                     if (alternative.isOptional) {
 391                         continue;
 392                     } else {
 393                         throw new SSLProtocolException(exceptionMsg);
 394                     }
 395                 }
 396             }
 397 
 398             throw new SSLProtocolException(exceptionMsg);
 399         }
 400 
 401         // Not an expected Handshake message.
 402         throw new SSLProtocolException(
 403                 "Handshake message sequence violation, " + handshakeType);
 404     }
 405 
 406     void update(HandshakeMessage handshakeMessage,
 407             boolean isAbbreviated) throws SSLProtocolException {
 408 
 409         byte handshakeType = (byte)handshakeMessage.messageType();
 410         String exceptionMsg =
 411                  "Handshake message sequence violation, " + handshakeType;
 412 
 413         if (debugIsOn) {
 414             System.out.println(
 415                     "update handshake state: " + toString(handshakeType));
 416         }
 417 
 418         boolean hasPresentState = false;
 419         switch (handshakeType) {
 420         case HandshakeMessage.ht_hello_request:
 421             //
 422             // State machine:
 423             //     PRESENT: START
 424             //        TO  : ClientHello
 425             //
 426 
 427             // No old state to update.
 428 
 429             // Add the upcoming states.
 430             if (!upcomingStates.isEmpty()) {
 431                 // A ClientHello message should be followed.
 432                 upcomingStates.add(HS_CLIENT_HELLO);
 433 
 434             }   // Otherwise, ignore this HelloRequest message.
 435 
 436             break;
 437 
 438         case HandshakeMessage.ht_client_hello:
 439             //
 440             // State machine:
 441             //     PRESENT: START
 442             //              HS_CLIENT_HELLO
 443             //        TO  : HS_HELLO_VERIFY_REQUEST (DTLS)
 444             //              HS_SERVER_HELLO
 445             //
 446 
 447             // Check and update the present state.
 448             if (!upcomingStates.isEmpty()) {
 449                 // The current state should be HS_CLIENT_HELLO.
 450                 HandshakeState handshakeState = upcomingStates.pop();
 451                 if (handshakeState != HS_CLIENT_HELLO) {
 452                     throw new SSLProtocolException(exceptionMsg);
 453                 }
 454             }
 455 
 456             // Add the upcoming states.
 457             ClientHello clientHello = (ClientHello)handshakeMessage;
 458             if (isDTLS) {
 459                 // Is it an initial ClientHello message?
 460                 if (clientHello.cookie == null ||
 461                         clientHello.cookie.length == 0) {
 462                     // Is it an abbreviated handshake?
 463                     if (clientHello.sessionId.length() != 0) {
 464                         // A HelloVerifyRequest message or a ServerHello
 465                         // message may follow the abbreviated session
 466                         // resuming handshake request.
 467                         upcomingStates.add(HS_HELLO_VERIFY_REQUEST);
 468                         alternatives.add(HS_SERVER_HELLO);
 469                     } else {
 470                         // A HelloVerifyRequest message should follow
 471                         // the initial ClientHello message.
 472                         upcomingStates.add(HS_HELLO_VERIFY_REQUEST);
 473                     }
 474                 } else {
 475                     // A HelloVerifyRequest may be followed if the cookie
 476                     // cannot be verified.
 477                     upcomingStates.add(HS_SERVER_HELLO);
 478                     alternatives.add(HS_HELLO_VERIFY_REQUEST);
 479                 }
 480             } else {
 481                 upcomingStates.add(HS_SERVER_HELLO);
 482             }
 483 
 484             break;
 485 
 486         case HandshakeMessage.ht_hello_verify_request:
 487             //
 488             // State machine:
 489             //     PRESENT: HS_HELLO_VERIFY_REQUEST
 490             //        TO  : HS_CLIENT_HELLO
 491             //
 492             // Note that this state may have an alternative option.
 493 
 494             // Check and update the present state.
 495             if (!upcomingStates.isEmpty()) {
 496                 // The current state should be HS_HELLO_VERIFY_REQUEST.
 497                 HandshakeState handshakeState = upcomingStates.pop();
 498                 HandshakeState alternative = null;
 499                 if (!alternatives.isEmpty()) {
 500                     alternative = alternatives.pop();
 501                 }
 502 
 503                 if ((handshakeState != HS_HELLO_VERIFY_REQUEST) &&
 504                         (alternative != HS_HELLO_VERIFY_REQUEST)) {
 505 
 506                     throw new SSLProtocolException(exceptionMsg);
 507                 }
 508             } else {
 509                 // No present state.
 510                 throw new SSLProtocolException(exceptionMsg);
 511             }
 512 
 513             // Add the upcoming states.
 514             upcomingStates.add(HS_CLIENT_HELLO);
 515 
 516             break;
 517 
 518         case HandshakeMessage.ht_server_hello:
 519             //
 520             // State machine:
 521             //     PRESENT: HS_SERVER_HELLO
 522             //        TO  :
 523             //          Full handshake state stacks
 524             //              (ServerHello Flight)
 525             //              HS_SERVER_SUPPLEMENTAL_DATA [optional]
 526             //          --> HS_SERVER_CERTIFICATE [optional]
 527             //          --> HS_CERTIFICATE_STATUS [optional]
 528             //          --> HS_SERVER_KEY_EXCHANGE [optional]
 529             //          --> HS_CERTIFICATE_REQUEST [optional]
 530             //          --> HS_SERVER_HELLO_DONE
 531             //              (Client ClientKeyExchange Flight)
 532             //          --> HS_CLIENT_SUPPLEMENTAL_DATA [optional]
 533             //          --> HS_CLIENT_CERTIFICATE or
 534             //              HS_CERTIFICATE_URL
 535             //          --> HS_CLIENT_KEY_EXCHANGE
 536             //          --> HS_CERTIFICATE_VERIFY [optional]
 537             //          --> HS_CLIENT_CHANGE_CIPHER_SPEC
 538             //          --> HS_CLEINT_FINISHED
 539             //              (Server Finished Flight)
 540             //          --> HS_CLIENT_SUPPLEMENTAL_DATA [optional]
 541             //
 542             //          Abbreviated handshake state stacks
 543             //              (Server Finished Flight)
 544             //              HS_NEW_SESSION_TICKET
 545             //          --> HS_SERVER_CHANGE_CIPHER_SPEC
 546             //          --> HS_SERVER_FINISHED
 547             //              (Client Finished Flight)
 548             //          --> HS_CLIENT_CHANGE_CIPHER_SPEC
 549             //          --> HS_CLEINT_FINISHED
 550             //
 551             // Note that this state may have an alternative option.
 552 
 553             // Check and update the present state.
 554             if (!upcomingStates.isEmpty()) {
 555                 // The current state should be HS_SERVER_HELLO
 556                 HandshakeState handshakeState = upcomingStates.pop();
 557                 HandshakeState alternative = null;
 558                 if (!alternatives.isEmpty()) {
 559                     alternative = alternatives.pop();
 560                 }
 561 
 562                 if ((handshakeState != HS_SERVER_HELLO) &&
 563                         (alternative != HS_SERVER_HELLO)) {
 564 
 565                     throw new SSLProtocolException(exceptionMsg);
 566                 }
 567             } else {
 568                 // No present state.
 569                 throw new SSLProtocolException(exceptionMsg);
 570             }
 571 
 572             // Add the upcoming states.
 573             ServerHello serverHello = (ServerHello)handshakeMessage;
 574             HelloExtensions hes = serverHello.extensions;
 575 
 576 
 577             // Not support SessionTicket extension yet.
 578             //
 579             // boolean hasSessionTicketExt =
 580             //     (hes.get(HandshakeMessage.ht_new_session_ticket) != null);
 581 
 582             if (isAbbreviated) {
 583                 // Not support SessionTicket extension yet.
 584                 //
 585                 // // Mandatory NewSessionTicket message
 586                 // if (hasSessionTicketExt) {
 587                 //     upcomingStates.add(HS_NEW_SESSION_TICKET);
 588                 // }
 589 
 590                 // Mandatory server ChangeCipherSpec and Finished messages
 591                 upcomingStates.add(HS_SERVER_CHANGE_CIPHER_SPEC);
 592                 upcomingStates.add(HS_SERVER_FINISHED);
 593 
 594                 // Mandatory client ChangeCipherSpec and Finished messages
 595                 upcomingStates.add(HS_CLIENT_CHANGE_CIPHER_SPEC);
 596                 upcomingStates.add(HS_CLEINT_FINISHED);
 597             } else {
 598                 // Not support SupplementalData extension yet.
 599                 //
 600                 // boolean hasSupplementalDataExt =
 601                 //     (hes.get(HandshakeMessage.ht_supplemental_data) != null);
 602 
 603                 // Not support CertificateURL extension yet.
 604                 //
 605                 // boolean hasCertificateUrlExt =
 606                 //     (hes.get(ExtensionType EXT_CLIENT_CERTIFICATE_URL)
 607                 //          != null);
 608 
 609                 // Not support SupplementalData extension yet.
 610                 //
 611                 // // Optional SupplementalData message
 612                 // if (hasSupplementalDataExt) {
 613                 //     upcomingStates.add(HS_SERVER_SUPPLEMENTAL_DATA);
 614                 // }
 615 
 616                 // Need server Certificate message or not?
 617                 KeyExchange keyExchange = serverHello.cipherSuite.keyExchange;
 618                 if ((keyExchange != K_KRB5) &&
 619                         (keyExchange != K_KRB5_EXPORT) &&
 620                         (keyExchange != K_DH_ANON) &&
 621                         (keyExchange != K_ECDH_ANON)) {
 622                     // Mandatory Certificate message
 623                     upcomingStates.add(HS_SERVER_CERTIFICATE);
 624                 }
 625 
 626                 // Optional CertificateStatus message
 627                 if (hes.get(ExtensionType.EXT_STATUS_REQUEST) != null ||
 628                         hes.get(ExtensionType.EXT_STATUS_REQUEST_V2) != null) {
 629                     upcomingStates.add(HS_CERTIFICATE_STATUS);
 630                 }
 631 
 632                 // Need ServerKeyExchange message or not?
 633                 if ((keyExchange == K_RSA_EXPORT) ||
 634                         (keyExchange == K_DHE_RSA) ||
 635                         (keyExchange == K_DHE_DSS) ||
 636                         (keyExchange == K_DH_ANON) ||
 637                         (keyExchange == K_ECDHE_RSA) ||
 638                         (keyExchange == K_ECDHE_ECDSA) ||
 639                         (keyExchange == K_ECDH_ANON)) {
 640                     // Optional ServerKeyExchange message
 641                     upcomingStates.add(HS_SERVER_KEY_EXCHANGE);
 642                 }
 643 
 644                 // Optional CertificateRequest message
 645                 upcomingStates.add(HS_CERTIFICATE_REQUEST);
 646 
 647                 // Mandatory ServerHelloDone message
 648                 upcomingStates.add(HS_SERVER_HELLO_DONE);
 649 
 650                 // Not support SupplementalData extension yet.
 651                 //
 652                 // // Optional SupplementalData message
 653                 // if (hasSupplementalDataExt) {
 654                 //     upcomingStates.add(HS_CLIENT_SUPPLEMENTAL_DATA);
 655                 // }
 656 
 657                 // Optional client Certificate message
 658                 upcomingStates.add(HS_CLIENT_CERTIFICATE);
 659 
 660                 // Not support CertificateURL extension yet.
 661                 //
 662                 // // Alternative CertificateURL message, optional too.
 663                 // //
 664                 // // Please put CertificateURL rather than Certificate
 665                 // // message in the alternatives list.  So that we can
 666                 // // simplify the process of this alternative pair later.
 667                 // if (hasCertificateUrlExt) {
 668                 //     alternatives.add(HS_CERTIFICATE_URL);
 669                 // }
 670 
 671                 // Mandatory ClientKeyExchange message
 672                 upcomingStates.add(HS_CLIENT_KEY_EXCHANGE);
 673 
 674                 // Optional CertificateVerify message
 675                 upcomingStates.add(HS_CERTIFICATE_VERIFY);
 676 
 677                 // Mandatory client ChangeCipherSpec and Finished messages
 678                 upcomingStates.add(HS_CLIENT_CHANGE_CIPHER_SPEC);
 679                 upcomingStates.add(HS_CLEINT_FINISHED);
 680 
 681                 // Not support SessionTicket extension yet.
 682                 //
 683                 // // Mandatory NewSessionTicket message
 684                 // if (hasSessionTicketExt) {
 685                 //     upcomingStates.add(HS_NEW_SESSION_TICKET);
 686                 // }
 687 
 688                 // Mandatory server ChangeCipherSpec and Finished messages
 689                 upcomingStates.add(HS_SERVER_CHANGE_CIPHER_SPEC);
 690                 upcomingStates.add(HS_SERVER_FINISHED);
 691             }
 692 
 693             break;
 694 
 695         case HandshakeMessage.ht_certificate:
 696             //
 697             // State machine:
 698             //     PRESENT: HS_CERTIFICATE_URL or
 699             //              HS_CLIENT_CERTIFICATE
 700             //        TO  : HS_CLIENT_KEY_EXCHANGE
 701             //
 702             //     Or
 703             //
 704             //     PRESENT: HS_SERVER_CERTIFICATE
 705             //        TO  : HS_CERTIFICATE_STATUS [optional]
 706             //              HS_SERVER_KEY_EXCHANGE [optional]
 707             //              HS_CERTIFICATE_REQUEST [optional]
 708             //              HS_SERVER_HELLO_DONE
 709             //
 710             // Note that this state may have an alternative option.
 711 
 712             // Check and update the present state.
 713             while (!upcomingStates.isEmpty()) {
 714                 HandshakeState handshakeState = upcomingStates.pop();
 715                 if (handshakeState.handshakeType == handshakeType) {
 716                     hasPresentState = true;
 717 
 718                     // The current state should be HS_CLIENT_CERTIFICATE or
 719                     // HS_SERVER_CERTIFICATE.
 720                     //
 721                     // Note that we won't put HS_CLIENT_CERTIFICATE into
 722                     // the alternative list.
 723                     if ((handshakeState != HS_CLIENT_CERTIFICATE) &&
 724                             (handshakeState != HS_SERVER_CERTIFICATE)) {
 725                         throw new SSLProtocolException(exceptionMsg);
 726                     }
 727 
 728                     // Is it an expected client Certificate message?
 729                     boolean isClientMessage = false;
 730                     if (!upcomingStates.isEmpty()) {
 731                         // If the next expected message is ClientKeyExchange,
 732                         // this one should be an expected client Certificate
 733                         // message.
 734                         HandshakeState nextState = upcomingStates.getFirst();
 735                         if (nextState == HS_CLIENT_KEY_EXCHANGE) {
 736                             isClientMessage = true;
 737                         }
 738                     }
 739 
 740                     if (isClientMessage) {
 741                         if (handshakeState != HS_CLIENT_CERTIFICATE) {
 742                             throw new SSLProtocolException(exceptionMsg);
 743                         }
 744 
 745                         // Not support CertificateURL extension yet.
 746                         /*******************************************
 747                         // clear up the alternatives list
 748                         if (!alternatives.isEmpty()) {
 749                             HandshakeState alternative = alternatives.pop();
 750 
 751                             if (alternative != HS_CERTIFICATE_URL) {
 752                                 throw new SSLProtocolException(exceptionMsg);
 753                             }
 754                         }
 755                         ********************************************/
 756                     } else {
 757                         if ((handshakeState != HS_SERVER_CERTIFICATE)) {
 758                             throw new SSLProtocolException(exceptionMsg);
 759                         }
 760                     }
 761 
 762                     break;
 763                 } else if (!handshakeState.isOptional) {
 764                     throw new SSLProtocolException(exceptionMsg);
 765                 }   // Otherwise, looking for next state track.
 766             }
 767 
 768             // No present state.
 769             if (!hasPresentState) {
 770                 throw new SSLProtocolException(exceptionMsg);
 771             }
 772 
 773             // no new upcoming states.
 774 
 775             break;
 776 
 777         // Not support CertificateURL extension yet.
 778         /*************************************************/
 779         case HandshakeMessage.ht_certificate_url:
 780             //
 781             // State machine:
 782             //     PRESENT: HS_CERTIFICATE_URL or
 783             //              HS_CLIENT_CERTIFICATE
 784             //        TO  : HS_CLIENT_KEY_EXCHANGE
 785             //
 786             // Note that this state may have an alternative option.
 787 
 788             // Check and update the present state.
 789             while (!upcomingStates.isEmpty()) {
 790                 // The current state should be HS_CLIENT_CERTIFICATE.
 791                 //
 792                 // Note that we won't put HS_CLIENT_CERTIFICATE into
 793                 // the alternative list.
 794                 HandshakeState handshakeState = upcomingStates.pop();
 795                 if (handshakeState.handshakeType ==
 796                         HS_CLIENT_CERTIFICATE.handshakeType) {
 797                     hasPresentState = true;
 798 
 799                     // Look for HS_CERTIFICATE_URL state track.
 800                     if (!alternatives.isEmpty()) {
 801                         HandshakeState alternative = alternatives.pop();
 802 
 803                         if (alternative != HS_CERTIFICATE_URL) {
 804                             throw new SSLProtocolException(exceptionMsg);
 805                         }
 806                     } else {
 807                         // No alternative CertificateUR state track.
 808                         throw new SSLProtocolException(exceptionMsg);
 809                     }
 810 
 811                     if ((handshakeState != HS_CLIENT_CERTIFICATE)) {
 812                         throw new SSLProtocolException(exceptionMsg);
 813                     }
 814 
 815                     break;
 816                 } else if (!handshakeState.isOptional) {
 817                     throw new SSLProtocolException(exceptionMsg);
 818                 }   // Otherwise, looking for next state track.
 819 
 820             }
 821 
 822             // No present state.
 823             if (!hasPresentState) {
 824                 // No present state.
 825                 throw new SSLProtocolException(exceptionMsg);
 826             }
 827 
 828             // no new upcoming states.
 829 
 830             break;
 831         /*************************************************/
 832 
 833         default:
 834             // Check and update the present state.
 835             while (!upcomingStates.isEmpty()) {
 836                 HandshakeState handshakeState = upcomingStates.pop();
 837                 if (handshakeState.handshakeType == handshakeType) {
 838                     hasPresentState = true;
 839                     break;
 840                 } else if (!handshakeState.isOptional) {
 841                     throw new SSLProtocolException(exceptionMsg);
 842                 }   // Otherwise, looking for next state track.
 843             }
 844 
 845             // No present state.
 846             if (!hasPresentState) {
 847                 throw new SSLProtocolException(exceptionMsg);
 848             }
 849 
 850             // no new upcoming states.
 851         }
 852 
 853         if (debugIsOn) {
 854             for (HandshakeState handshakeState : upcomingStates) {
 855                 System.out.println(
 856                     "upcoming handshake states: " + handshakeState);
 857             }
 858             for (HandshakeState handshakeState : alternatives) {
 859                 System.out.println(
 860                     "upcoming handshake alternative state: " + handshakeState);
 861             }
 862         }
 863     }
 864 
 865     void changeCipherSpec(boolean isInput,
 866             boolean isClient) throws SSLProtocolException {
 867 
 868         if (debugIsOn) {
 869             System.out.println(
 870                     "update handshake state: change_cipher_spec");
 871         }
 872 
 873         String exceptionMsg = "ChangeCipherSpec message sequence violation";
 874 
 875         HandshakeState expectedState;
 876         if ((isClient && isInput) || (!isClient && !isInput)) {
 877             expectedState = HS_SERVER_CHANGE_CIPHER_SPEC;
 878         } else {
 879             expectedState = HS_CLIENT_CHANGE_CIPHER_SPEC;
 880         }
 881 
 882         boolean hasPresentState = false;
 883 
 884         // Check and update the present state.
 885         while (!upcomingStates.isEmpty()) {
 886             HandshakeState handshakeState = upcomingStates.pop();
 887             if (handshakeState == expectedState) {
 888                 hasPresentState = true;
 889                 break;
 890             } else if (!handshakeState.isOptional) {
 891                 throw new SSLProtocolException(exceptionMsg);
 892             }   // Otherwise, looking for next state track.
 893         }
 894 
 895         // No present state.
 896         if (!hasPresentState) {
 897             throw new SSLProtocolException(exceptionMsg);
 898         }
 899 
 900         // no new upcoming states.
 901 
 902         if (debugIsOn) {
 903             for (HandshakeState handshakeState : upcomingStates) {
 904                 System.out.println(
 905                     "upcoming handshake states: " + handshakeState);
 906             }
 907             for (HandshakeState handshakeState : alternatives) {
 908                 System.out.println(
 909                     "upcoming handshake alternative state: " + handshakeState);
 910             }
 911         }
 912     }
 913 
 914     private static String toString(byte handshakeType) {
 915         String s = handshakeTypes.get(handshakeType);
 916         if (s == null) {
 917             s = "unknown";
 918         }
 919         return (s + "[" + handshakeType + "]");
 920     }
 921 }
 922