jdk/src/java.base/share/classes/sun/security/ssl/HandshakeStateManager.java
changeset 30904 ec0224270f90
child 32032 22badc53802f
equal deleted inserted replaced
30903:0c7d705209c6 30904:ec0224270f90
       
     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.LinkedList;
       
    29 import java.util.HashMap;
       
    30 import javax.net.ssl.SSLProtocolException;
       
    31 
       
    32 import sun.security.ssl.HandshakeMessage.*;
       
    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 final static boolean debugIsOn;
       
   222 
       
   223     private final static 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_FINISHDE(
       
   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     void check(byte handshakeType) throws SSLProtocolException {
       
   347         String exceptionMsg =
       
   348                  "Handshake message sequence violation, " + handshakeType;
       
   349 
       
   350         if (debugIsOn) {
       
   351             System.out.println(
       
   352                     "check handshake state: " + toString(handshakeType));
       
   353         }
       
   354 
       
   355         if (upcomingStates.isEmpty()) {
       
   356             // Is it a kickstart message?
       
   357             if ((handshakeType != HandshakeMessage.ht_hello_request) &&
       
   358                 (handshakeType != HandshakeMessage.ht_client_hello)) {
       
   359 
       
   360                 throw new SSLProtocolException(
       
   361                     "Handshake message sequence violation, " + handshakeType);
       
   362             }
       
   363 
       
   364             // It is a kickstart message.
       
   365             return;
       
   366         }
       
   367 
       
   368         // Ignore the checking for HelloRequest messages as they are
       
   369         // may be sent by the server at any time.
       
   370         if (handshakeType == HandshakeMessage.ht_hello_request) {
       
   371             return;
       
   372         }
       
   373 
       
   374         for (HandshakeState handshakeState : upcomingStates) {
       
   375             if (handshakeState.handshakeType == handshakeType) {
       
   376                 // It's the expected next handshake type.
       
   377                 return;
       
   378             }
       
   379 
       
   380             if (handshakeState.isOptional) {
       
   381                 continue;
       
   382             } else {
       
   383                 for (HandshakeState alternative : alternatives) {
       
   384                     if (alternative.handshakeType == handshakeType) {
       
   385                         return;
       
   386                     }
       
   387 
       
   388                     if (alternative.isOptional) {
       
   389                         continue;
       
   390                     } else {
       
   391                         throw new SSLProtocolException(exceptionMsg);
       
   392                     }
       
   393                 }
       
   394             }
       
   395 
       
   396             throw new SSLProtocolException(exceptionMsg);
       
   397         }
       
   398 
       
   399         // Not an expected Handshake message.
       
   400         throw new SSLProtocolException(
       
   401                 "Handshake message sequence violation, " + handshakeType);
       
   402     }
       
   403 
       
   404     void update(HandshakeMessage handshakeMessage,
       
   405             boolean isAbbreviated) throws SSLProtocolException {
       
   406 
       
   407         byte handshakeType = (byte)handshakeMessage.messageType();
       
   408         String exceptionMsg =
       
   409                  "Handshake message sequence violation, " + handshakeType;
       
   410 
       
   411         if (debugIsOn) {
       
   412             System.out.println(
       
   413                     "update handshake state: " + toString(handshakeType));
       
   414         }
       
   415 
       
   416         boolean hasPresentState = false;
       
   417         switch (handshakeType) {
       
   418         case HandshakeMessage.ht_hello_request:
       
   419             //
       
   420             // State machine:
       
   421             //     PRESENT: START
       
   422             //        TO  : ClientHello
       
   423             //
       
   424 
       
   425             // No old state to update.
       
   426 
       
   427             // Add the upcoming states.
       
   428             if (!upcomingStates.isEmpty()) {
       
   429                 // A ClientHello message should be followed.
       
   430                 upcomingStates.add(HS_CLIENT_HELLO);
       
   431 
       
   432             }   // Otherwise, ignore this HelloRequest message.
       
   433 
       
   434             break;
       
   435 
       
   436         case HandshakeMessage.ht_client_hello:
       
   437             //
       
   438             // State machine:
       
   439             //     PRESENT: START
       
   440             //              HS_CLIENT_HELLO
       
   441             //        TO  : HS_HELLO_VERIFY_REQUEST (DTLS)
       
   442             //              HS_SERVER_HELLO
       
   443             //
       
   444 
       
   445             // Check and update the present state.
       
   446             if (!upcomingStates.isEmpty()) {
       
   447                 // The current state should be HS_CLIENT_HELLO.
       
   448                 HandshakeState handshakeState = upcomingStates.pop();
       
   449                 if (handshakeState != HS_CLIENT_HELLO) {
       
   450                     throw new SSLProtocolException(exceptionMsg);
       
   451                 }
       
   452             }
       
   453 
       
   454             // Add the upcoming states.
       
   455             ClientHello clientHello = (ClientHello)handshakeMessage;
       
   456             if (isDTLS) {
       
   457                 // Is it an initial ClientHello message?
       
   458                 if (clientHello.cookie == null ||
       
   459                         clientHello.cookie.length == 0) {
       
   460                     // Is it an abbreviated handshake?
       
   461                     if (clientHello.sessionId.length() != 0) {
       
   462                         // A HelloVerifyRequest message or a ServerHello
       
   463                         // message may follow the abbreviated session
       
   464                         // resuming handshake request.
       
   465                         upcomingStates.add(HS_HELLO_VERIFY_REQUEST);
       
   466                         alternatives.add(HS_SERVER_HELLO);
       
   467                     } else {
       
   468                         // A HelloVerifyRequest message should follow
       
   469                         // the initial ClientHello message.
       
   470                         upcomingStates.add(HS_HELLO_VERIFY_REQUEST);
       
   471                     }
       
   472                 } else {
       
   473                     // A HelloVerifyRequest may be followed if the cookie
       
   474                     // cannot be verified.
       
   475                     upcomingStates.add(HS_SERVER_HELLO);
       
   476                     alternatives.add(HS_HELLO_VERIFY_REQUEST);
       
   477                 }
       
   478             } else {
       
   479                 upcomingStates.add(HS_SERVER_HELLO);
       
   480             }
       
   481 
       
   482             break;
       
   483 
       
   484         case HandshakeMessage.ht_hello_verify_request:
       
   485             //
       
   486             // State machine:
       
   487             //     PRESENT: HS_HELLO_VERIFY_REQUEST
       
   488             //        TO  : HS_CLIENT_HELLO
       
   489             //
       
   490             // Note that this state may have an alternative option.
       
   491 
       
   492             // Check and update the present state.
       
   493             if (!upcomingStates.isEmpty()) {
       
   494                 // The current state should be HS_HELLO_VERIFY_REQUEST.
       
   495                 HandshakeState handshakeState = upcomingStates.pop();
       
   496                 HandshakeState alternative = null;
       
   497                 if (!alternatives.isEmpty()) {
       
   498                     alternative = alternatives.pop();
       
   499                 }
       
   500 
       
   501                 if ((handshakeState != HS_HELLO_VERIFY_REQUEST) &&
       
   502                         (alternative != HS_HELLO_VERIFY_REQUEST)) {
       
   503 
       
   504                     throw new SSLProtocolException(exceptionMsg);
       
   505                 }
       
   506             } else {
       
   507                 // No present state.
       
   508                 throw new SSLProtocolException(exceptionMsg);
       
   509             }
       
   510 
       
   511             // Add the upcoming states.
       
   512             upcomingStates.add(HS_CLIENT_HELLO);
       
   513 
       
   514             break;
       
   515 
       
   516         case HandshakeMessage.ht_server_hello:
       
   517             //
       
   518             // State machine:
       
   519             //     PRESENT: HS_SERVER_HELLO
       
   520             //        TO  :
       
   521             //          Full handshake state stacks
       
   522             //              (ServerHello Flight)
       
   523             //              HS_SERVER_SUPPLEMENTAL_DATA [optional]
       
   524             //          --> HS_SERVER_CERTIFICATE [optional]
       
   525             //          --> HS_CERTIFICATE_STATUS [optional]
       
   526             //          --> HS_SERVER_KEY_EXCHANGE [optional]
       
   527             //          --> HS_CERTIFICATE_REQUEST [optional]
       
   528             //          --> HS_SERVER_HELLO_DONE
       
   529             //              (Client ClientKeyExchange Flight)
       
   530             //          --> HS_CLIENT_SUPPLEMENTAL_DATA [optional]
       
   531             //          --> HS_CLIENT_CERTIFICATE or
       
   532             //              HS_CERTIFICATE_URL
       
   533             //          --> HS_CLIENT_KEY_EXCHANGE
       
   534             //          --> HS_CERTIFICATE_VERIFY [optional]
       
   535             //          --> HS_CLIENT_CHANGE_CIPHER_SPEC
       
   536             //          --> HS_CLEINT_FINISHED
       
   537             //              (Server Finished Flight)
       
   538             //          --> HS_CLIENT_SUPPLEMENTAL_DATA [optional]
       
   539             //
       
   540             //          Abbreviated handshake state stacks
       
   541             //              (Server Finished Flight)
       
   542             //              HS_NEW_SESSION_TICKET
       
   543             //          --> HS_SERVER_CHANGE_CIPHER_SPEC
       
   544             //          --> HS_SERVER_FINISHDE
       
   545             //              (Client Finished Flight)
       
   546             //          --> HS_CLIENT_CHANGE_CIPHER_SPEC
       
   547             //          --> HS_CLEINT_FINISHED
       
   548             //
       
   549             // Note that this state may have an alternative option.
       
   550 
       
   551             // Check and update the present state.
       
   552             if (!upcomingStates.isEmpty()) {
       
   553                 // The current state should be HS_SERVER_HELLO
       
   554                 HandshakeState handshakeState = upcomingStates.pop();
       
   555                 HandshakeState alternative = null;
       
   556                 if (!alternatives.isEmpty()) {
       
   557                     alternative = alternatives.pop();
       
   558                 }
       
   559 
       
   560                 if ((handshakeState != HS_SERVER_HELLO) &&
       
   561                         (alternative != HS_SERVER_HELLO)) {
       
   562 
       
   563                     throw new SSLProtocolException(exceptionMsg);
       
   564                 }
       
   565             } else {
       
   566                 // No present state.
       
   567                 throw new SSLProtocolException(exceptionMsg);
       
   568             }
       
   569 
       
   570             // Add the upcoming states.
       
   571             ServerHello serverHello = (ServerHello)handshakeMessage;
       
   572             HelloExtensions hes = serverHello.extensions;
       
   573 
       
   574 
       
   575             // Not support SessionTicket extension yet.
       
   576             //
       
   577             // boolean hasSessionTicketExt =
       
   578             //     (hes.get(HandshakeMessage.ht_new_session_ticket) != null);
       
   579 
       
   580             if (isAbbreviated) {
       
   581                 // Not support SessionTicket extension yet.
       
   582                 //
       
   583                 // // Mandatory NewSessionTicket message
       
   584                 // if (hasSessionTicketExt) {
       
   585                 //     upcomingStates.add(HS_NEW_SESSION_TICKET);
       
   586                 // }
       
   587 
       
   588                 // Mandatory server ChangeCipherSpec and Finished messages
       
   589                 upcomingStates.add(HS_SERVER_CHANGE_CIPHER_SPEC);
       
   590                 upcomingStates.add(HS_SERVER_FINISHDE);
       
   591 
       
   592                 // Mandatory client ChangeCipherSpec and Finished messages
       
   593                 upcomingStates.add(HS_CLIENT_CHANGE_CIPHER_SPEC);
       
   594                 upcomingStates.add(HS_CLEINT_FINISHED);
       
   595             } else {
       
   596                 // Not support SupplementalData extension yet.
       
   597                 //
       
   598                 // boolean hasSupplementalDataExt =
       
   599                 //     (hes.get(HandshakeMessage.ht_supplemental_data) != null);
       
   600 
       
   601                 // Not support CertificateStatus extension yet.
       
   602                 //
       
   603                 // boolean hasCertificateStatusExt =
       
   604                 //    (hes.get(HandshakeMessage.ht_certificate_status) != null);
       
   605 
       
   606                 // Not support CertificateURL extension yet.
       
   607                 //
       
   608                 // boolean hasCertificateUrlExt =
       
   609                 //     (hes.get(HandshakeMessage.ht_certificate_url) != null);
       
   610 
       
   611                 // Not support SupplementalData extension yet.
       
   612                 //
       
   613                 // // Optional SupplementalData message
       
   614                 // if (hasSupplementalDataExt) {
       
   615                 //     upcomingStates.add(HS_SERVER_SUPPLEMENTAL_DATA);
       
   616                 // }
       
   617 
       
   618                 // Need server Certificate message or not?
       
   619                 KeyExchange keyExchange = serverHello.cipherSuite.keyExchange;
       
   620                 if ((keyExchange != K_KRB5) &&
       
   621                         (keyExchange != K_KRB5_EXPORT) &&
       
   622                         (keyExchange != K_DH_ANON) &&
       
   623                         (keyExchange != K_ECDH_ANON)) {
       
   624                     // Mandatory Certificate message
       
   625                     upcomingStates.add(HS_SERVER_CERTIFICATE);
       
   626                 }
       
   627 
       
   628                 // Not support CertificateStatus extension yet.
       
   629                 //
       
   630                 // // Optional CertificateStatus message
       
   631                 // if (hasCertificateStatusExt) {
       
   632                 //     upcomingStates.add(HS_CERTIFICATE_STATUS);
       
   633                 // }
       
   634 
       
   635                 // Need ServerKeyExchange message or not?
       
   636                 if ((keyExchange == K_RSA_EXPORT) ||
       
   637                         (keyExchange == K_DHE_RSA) ||
       
   638                         (keyExchange == K_DHE_DSS) ||
       
   639                         (keyExchange == K_DH_ANON) ||
       
   640                         (keyExchange == K_ECDHE_RSA) ||
       
   641                         (keyExchange == K_ECDHE_ECDSA) ||
       
   642                         (keyExchange == K_ECDH_ANON)) {
       
   643                     // Optional ServerKeyExchange message
       
   644                     upcomingStates.add(HS_SERVER_KEY_EXCHANGE);
       
   645                 }
       
   646 
       
   647                 // Optional CertificateRequest message
       
   648                 upcomingStates.add(HS_CERTIFICATE_REQUEST);
       
   649 
       
   650                 // Mandatory ServerHelloDone message
       
   651                 upcomingStates.add(HS_SERVER_HELLO_DONE);
       
   652 
       
   653                 // Not support SupplementalData extension yet.
       
   654                 //
       
   655                 // // Optional SupplementalData message
       
   656                 // if (hasSupplementalDataExt) {
       
   657                 //     upcomingStates.add(HS_CLIENT_SUPPLEMENTAL_DATA);
       
   658                 // }
       
   659 
       
   660                 // Optional client Certificate message
       
   661                 upcomingStates.add(HS_CLIENT_CERTIFICATE);
       
   662 
       
   663                 // Not support CertificateURL extension yet.
       
   664                 //
       
   665                 // // Alternative CertificateURL message, optional too.
       
   666                 // //
       
   667                 // // Please put CertificateURL rather than Certificate
       
   668                 // // message in the alternatives list.  So that we can
       
   669                 // // simplify the process of this alternative pair later.
       
   670                 // if (hasCertificateUrlExt) {
       
   671                 //     alternatives.add(HS_CERTIFICATE_URL);
       
   672                 // }
       
   673 
       
   674                 // Mandatory ClientKeyExchange message
       
   675                 upcomingStates.add(HS_CLIENT_KEY_EXCHANGE);
       
   676 
       
   677                 // Optional CertificateVerify message
       
   678                 upcomingStates.add(HS_CERTIFICATE_VERIFY);
       
   679 
       
   680                 // Mandatory client ChangeCipherSpec and Finished messages
       
   681                 upcomingStates.add(HS_CLIENT_CHANGE_CIPHER_SPEC);
       
   682                 upcomingStates.add(HS_CLEINT_FINISHED);
       
   683 
       
   684                 // Not support SessionTicket extension yet.
       
   685                 //
       
   686                 // // Mandatory NewSessionTicket message
       
   687                 // if (hasSessionTicketExt) {
       
   688                 //     upcomingStates.add(HS_NEW_SESSION_TICKET);
       
   689                 // }
       
   690 
       
   691                 // Mandatory server ChangeCipherSpec and Finished messages
       
   692                 upcomingStates.add(HS_SERVER_CHANGE_CIPHER_SPEC);
       
   693                 upcomingStates.add(HS_SERVER_FINISHDE);
       
   694             }
       
   695 
       
   696             break;
       
   697 
       
   698         case HandshakeMessage.ht_certificate:
       
   699             //
       
   700             // State machine:
       
   701             //     PRESENT: HS_CERTIFICATE_URL or
       
   702             //              HS_CLIENT_CERTIFICATE
       
   703             //        TO  : HS_CLIENT_KEY_EXCHANGE
       
   704             //
       
   705             //     Or
       
   706             //
       
   707             //     PRESENT: HS_SERVER_CERTIFICATE
       
   708             //        TO  : HS_CERTIFICATE_STATUS [optional]
       
   709             //              HS_SERVER_KEY_EXCHANGE [optional]
       
   710             //              HS_CERTIFICATE_REQUEST [optional]
       
   711             //              HS_SERVER_HELLO_DONE
       
   712             //
       
   713             // Note that this state may have an alternative option.
       
   714 
       
   715             // Check and update the present state.
       
   716             while (!upcomingStates.isEmpty()) {
       
   717                 HandshakeState handshakeState = upcomingStates.pop();
       
   718                 if (handshakeState.handshakeType == handshakeType) {
       
   719                     hasPresentState = true;
       
   720 
       
   721                     // The current state should be HS_CLIENT_CERTIFICATE or
       
   722                     // HS_SERVER_CERTIFICATE.
       
   723                     //
       
   724                     // Note that we won't put HS_CLIENT_CERTIFICATE into
       
   725                     // the alternative list.
       
   726                     if ((handshakeState != HS_CLIENT_CERTIFICATE) &&
       
   727                             (handshakeState != HS_SERVER_CERTIFICATE)) {
       
   728                         throw new SSLProtocolException(exceptionMsg);
       
   729                     }
       
   730 
       
   731                     // Is it an expected client Certificate message?
       
   732                     boolean isClientMessage = false;
       
   733                     if (!upcomingStates.isEmpty()) {
       
   734                         // If the next expected message is ClientKeyExchange,
       
   735                         // this one should be an expected client Certificate
       
   736                         // message.
       
   737                         HandshakeState nextState = upcomingStates.getFirst();
       
   738                         if (nextState == HS_CLIENT_KEY_EXCHANGE) {
       
   739                             isClientMessage = true;
       
   740                         }
       
   741                     }
       
   742 
       
   743                     if (isClientMessage) {
       
   744                         if (handshakeState != HS_CLIENT_CERTIFICATE) {
       
   745                             throw new SSLProtocolException(exceptionMsg);
       
   746                         }
       
   747 
       
   748                         // Not support CertificateURL extension yet.
       
   749                         /*******************************************
       
   750                         // clear up the alternatives list
       
   751                         if (!alternatives.isEmpty()) {
       
   752                             HandshakeState alternative = alternatives.pop();
       
   753 
       
   754                             if (alternative != HS_CERTIFICATE_URL) {
       
   755                                 throw new SSLProtocolException(exceptionMsg);
       
   756                             }
       
   757                         }
       
   758                         ********************************************/
       
   759                     } else {
       
   760                         if ((handshakeState != HS_SERVER_CERTIFICATE)) {
       
   761                             throw new SSLProtocolException(exceptionMsg);
       
   762                         }
       
   763                     }
       
   764 
       
   765                     break;
       
   766                 } else if (!handshakeState.isOptional) {
       
   767                     throw new SSLProtocolException(exceptionMsg);
       
   768                 }   // Otherwise, looking for next state track.
       
   769             }
       
   770 
       
   771             // No present state.
       
   772             if (!hasPresentState) {
       
   773                 throw new SSLProtocolException(exceptionMsg);
       
   774             }
       
   775 
       
   776             // no new upcoming states.
       
   777 
       
   778             break;
       
   779 
       
   780         // Not support CertificateURL extension yet.
       
   781         /*************************************************/
       
   782         case HandshakeMessage.ht_certificate_url:
       
   783             //
       
   784             // State machine:
       
   785             //     PRESENT: HS_CERTIFICATE_URL or
       
   786             //              HS_CLIENT_CERTIFICATE
       
   787             //        TO  : HS_CLIENT_KEY_EXCHANGE
       
   788             //
       
   789             // Note that this state may have an alternative option.
       
   790 
       
   791             // Check and update the present state.
       
   792             while (!upcomingStates.isEmpty()) {
       
   793                 // The current state should be HS_CLIENT_CERTIFICATE.
       
   794                 //
       
   795                 // Note that we won't put HS_CLIENT_CERTIFICATE into
       
   796                 // the alternative list.
       
   797                 HandshakeState handshakeState = upcomingStates.pop();
       
   798                 if (handshakeState.handshakeType ==
       
   799                         HS_CLIENT_CERTIFICATE.handshakeType) {
       
   800                     hasPresentState = true;
       
   801 
       
   802                     // Look for HS_CERTIFICATE_URL state track.
       
   803                     if (!alternatives.isEmpty()) {
       
   804                         HandshakeState alternative = alternatives.pop();
       
   805 
       
   806                         if (alternative != HS_CERTIFICATE_URL) {
       
   807                             throw new SSLProtocolException(exceptionMsg);
       
   808                         }
       
   809                     } else {
       
   810                         // No alternative CertificateUR state track.
       
   811                         throw new SSLProtocolException(exceptionMsg);
       
   812                     }
       
   813 
       
   814                     if ((handshakeState != HS_CLIENT_CERTIFICATE)) {
       
   815                         throw new SSLProtocolException(exceptionMsg);
       
   816                     }
       
   817 
       
   818                     break;
       
   819                 } else if (!handshakeState.isOptional) {
       
   820                     throw new SSLProtocolException(exceptionMsg);
       
   821                 }   // Otherwise, looking for next state track.
       
   822 
       
   823             }
       
   824 
       
   825             // No present state.
       
   826             if (!hasPresentState) {
       
   827                 // No present state.
       
   828                 throw new SSLProtocolException(exceptionMsg);
       
   829             }
       
   830 
       
   831             // no new upcoming states.
       
   832 
       
   833             break;
       
   834         /*************************************************/
       
   835 
       
   836         default:
       
   837             // Check and update the present state.
       
   838             while (!upcomingStates.isEmpty()) {
       
   839                 HandshakeState handshakeState = upcomingStates.pop();
       
   840                 if (handshakeState.handshakeType == handshakeType) {
       
   841                     hasPresentState = true;
       
   842                     break;
       
   843                 } else if (!handshakeState.isOptional) {
       
   844                     throw new SSLProtocolException(exceptionMsg);
       
   845                 }   // Otherwise, looking for next state track.
       
   846             }
       
   847 
       
   848             // No present state.
       
   849             if (!hasPresentState) {
       
   850                 throw new SSLProtocolException(exceptionMsg);
       
   851             }
       
   852 
       
   853             // no new upcoming states.
       
   854         }
       
   855 
       
   856         if (debugIsOn) {
       
   857             for (HandshakeState handshakeState : upcomingStates) {
       
   858                 System.out.println(
       
   859                     "upcoming handshake states: " + handshakeState);
       
   860             }
       
   861             for (HandshakeState handshakeState : alternatives) {
       
   862                 System.out.println(
       
   863                     "upcoming handshake alternative state: " + handshakeState);
       
   864             }
       
   865         }
       
   866     }
       
   867 
       
   868     void changeCipherSpec(boolean isInput,
       
   869             boolean isClient) throws SSLProtocolException {
       
   870 
       
   871         if (debugIsOn) {
       
   872             System.out.println(
       
   873                     "update handshake state: change_cipher_spec");
       
   874         }
       
   875 
       
   876         String exceptionMsg = "ChangeCipherSpec message sequence violation";
       
   877 
       
   878         HandshakeState expectedState;
       
   879         if ((isClient && isInput) || (!isClient && !isInput)) {
       
   880             expectedState = HS_SERVER_CHANGE_CIPHER_SPEC;
       
   881         } else {
       
   882             expectedState = HS_CLIENT_CHANGE_CIPHER_SPEC;
       
   883         }
       
   884 
       
   885         boolean hasPresentState = false;
       
   886 
       
   887         // Check and update the present state.
       
   888         while (!upcomingStates.isEmpty()) {
       
   889             HandshakeState handshakeState = upcomingStates.pop();
       
   890             if (handshakeState == expectedState) {
       
   891                 hasPresentState = true;
       
   892                 break;
       
   893             } else if (!handshakeState.isOptional) {
       
   894                 throw new SSLProtocolException(exceptionMsg);
       
   895             }   // Otherwise, looking for next state track.
       
   896         }
       
   897 
       
   898         // No present state.
       
   899         if (!hasPresentState) {
       
   900             throw new SSLProtocolException(exceptionMsg);
       
   901         }
       
   902 
       
   903         // no new upcoming states.
       
   904 
       
   905         if (debugIsOn) {
       
   906             for (HandshakeState handshakeState : upcomingStates) {
       
   907                 System.out.println(
       
   908                     "upcoming handshake states: " + handshakeState);
       
   909             }
       
   910             for (HandshakeState handshakeState : alternatives) {
       
   911                 System.out.println(
       
   912                     "upcoming handshake alternative state: " + handshakeState);
       
   913             }
       
   914         }
       
   915     }
       
   916 
       
   917     private static String toString(byte handshakeType) {
       
   918         String s = handshakeTypes.get(handshakeType);
       
   919         if (s == null) {
       
   920             s = "unknown";
       
   921         }
       
   922         return (s + "[" + handshakeType + "]");
       
   923     }
       
   924 }
       
   925