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