src/java.base/share/classes/sun/security/ssl/HandshakeStateManager.java
branchJDK-8145252-TLS13-branch
changeset 56542 56aaa6cb3693
parent 56541 92cbbfc996f3
child 56543 2352538d2f6e
equal deleted inserted replaced
56541:92cbbfc996f3 56542:56aaa6cb3693
     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