src/java.base/share/classes/sun/security/ssl/SSLHandshake.java
branchJDK-8145252-TLS13-branch
changeset 56542 56aaa6cb3693
parent 48225 718669e6b375
child 56704 c3ee22c3a0f6
equal deleted inserted replaced
56541:92cbbfc996f3 56542:56aaa6cb3693
       
     1 /*
       
     2  * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package sun.security.ssl;
       
    27 
       
    28 import java.io.IOException;
       
    29 import java.nio.ByteBuffer;
       
    30 import java.util.AbstractMap.SimpleImmutableEntry;
       
    31 import java.util.Map;
       
    32 import javax.net.ssl.SSLException;
       
    33 
       
    34 enum SSLHandshake implements SSLConsumer, HandshakeProducer {
       
    35     @SuppressWarnings({"unchecked", "rawtypes"})
       
    36     HELLO_REQUEST ((byte)0x00, "hello_request",
       
    37         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
    38             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
    39                 HelloRequest.handshakeConsumer,
       
    40                 ProtocolVersion.PROTOCOLS_TO_12
       
    41             )
       
    42         }),
       
    43         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
    44             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
    45                 HelloRequest.handshakeProducer,
       
    46                 ProtocolVersion.PROTOCOLS_TO_12
       
    47             )
       
    48         })),
       
    49 
       
    50     @SuppressWarnings({"unchecked", "rawtypes"})
       
    51     CLIENT_HELLO ((byte)0x01, "client_hello",
       
    52         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
    53             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
    54                 ClientHello.handshakeConsumer,
       
    55                 ProtocolVersion.PROTOCOLS_TO_13
       
    56             )
       
    57         }),
       
    58         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
    59             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
    60                 ClientHello.handshakeProducer,
       
    61                 ProtocolVersion.PROTOCOLS_TO_13
       
    62             )
       
    63         })),
       
    64 
       
    65     @SuppressWarnings({"unchecked", "rawtypes"})
       
    66     SERVER_HELLO ((byte)0x02, "server_hello",
       
    67         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
    68             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
    69                 ServerHello.handshakeConsumer,
       
    70                 ProtocolVersion.PROTOCOLS_TO_13
       
    71             )
       
    72         }),
       
    73         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
    74             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
    75                 ServerHello.t12HandshakeProducer,
       
    76                 ProtocolVersion.PROTOCOLS_TO_12
       
    77             ),
       
    78             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
    79                 ServerHello.t13HandshakeProducer,
       
    80                 ProtocolVersion.PROTOCOLS_OF_13
       
    81             )
       
    82         })),
       
    83 
       
    84     @SuppressWarnings({"unchecked", "rawtypes"})
       
    85     HELLO_RETRY_REQUEST ((byte)0x02, "hello_retry_request",
       
    86         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
    87             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
    88                 ServerHello.handshakeConsumer,      // Use ServerHello consumer
       
    89                 ProtocolVersion.PROTOCOLS_TO_13
       
    90             )
       
    91         }),
       
    92         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
    93             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
    94                 ServerHello.hrrHandshakeProducer,
       
    95                 ProtocolVersion.PROTOCOLS_OF_13
       
    96             )
       
    97         })),
       
    98 
       
    99     @SuppressWarnings({"unchecked", "rawtypes"})
       
   100     HELLO_VERIFY_REQUEST        ((byte)0x03, "hello_verify_request",
       
   101         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   102             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   103                 HelloVerifyRequest.handshakeConsumer,
       
   104                 ProtocolVersion.PROTOCOLS_TO_12
       
   105             )
       
   106         }),
       
   107         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   108             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   109                 HelloVerifyRequest.handshakeProducer,
       
   110                 ProtocolVersion.PROTOCOLS_TO_12
       
   111             )
       
   112         })),
       
   113 
       
   114     @SuppressWarnings({"unchecked", "rawtypes"})
       
   115     NEW_SESSION_TICKET          ((byte)0x04, "new_session_ticket",
       
   116         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   117             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   118                 NewSessionTicket.handshakeConsumer,
       
   119                 ProtocolVersion.PROTOCOLS_OF_13
       
   120         )
       
   121         }),
       
   122         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   123             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   124                 NewSessionTicket.handshakeProducer,
       
   125                 ProtocolVersion.PROTOCOLS_OF_13
       
   126         )
       
   127         })),
       
   128     END_OF_EARLY_DATA           ((byte)0x05, "end_of_early_data"),
       
   129 
       
   130     @SuppressWarnings({"unchecked", "rawtypes"})
       
   131     ENCRYPTED_EXTENSIONS        ((byte)0x08, "encrypted_extensions",
       
   132         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   133             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   134                 EncryptedExtensions.handshakeConsumer,
       
   135                 ProtocolVersion.PROTOCOLS_OF_13
       
   136             )
       
   137         }),
       
   138         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   139             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   140                 EncryptedExtensions.handshakeProducer,
       
   141                 ProtocolVersion.PROTOCOLS_OF_13
       
   142             )
       
   143         })),
       
   144 
       
   145     @SuppressWarnings({"unchecked", "rawtypes"})
       
   146     CERTIFICATE                 ((byte)0x0B, "certificate",
       
   147         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   148             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   149                 CertificateMessage.t12HandshakeConsumer,
       
   150                 ProtocolVersion.PROTOCOLS_TO_12
       
   151             ),
       
   152             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   153                 CertificateMessage.t13HandshakeConsumer,
       
   154                 ProtocolVersion.PROTOCOLS_OF_13
       
   155             )
       
   156         }),
       
   157         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   158             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   159                 CertificateMessage.t12HandshakeProducer,
       
   160                 ProtocolVersion.PROTOCOLS_TO_12
       
   161             ),
       
   162             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   163                 CertificateMessage.t13HandshakeProducer,
       
   164                 ProtocolVersion.PROTOCOLS_OF_13
       
   165             )
       
   166         })),
       
   167 
       
   168     @SuppressWarnings({"unchecked", "rawtypes"})
       
   169     SERVER_KEY_EXCHANGE         ((byte)0x0C, "server_key_exchange",
       
   170         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   171             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   172                 ServerKeyExchange.handshakeConsumer,
       
   173                 ProtocolVersion.PROTOCOLS_TO_12
       
   174             )
       
   175         }),
       
   176         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   177             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   178                 ServerKeyExchange.handshakeProducer,
       
   179                 ProtocolVersion.PROTOCOLS_TO_12
       
   180             )
       
   181         })),
       
   182 
       
   183     @SuppressWarnings({"unchecked", "rawtypes"})
       
   184     CERTIFICATE_REQUEST         ((byte)0x0D, "certificate_request",
       
   185         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   186             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   187                 CertificateRequest.t10HandshakeConsumer,
       
   188                 ProtocolVersion.PROTOCOLS_TO_11
       
   189             ),
       
   190             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   191                 CertificateRequest.t12HandshakeConsumer,
       
   192                 ProtocolVersion.PROTOCOLS_OF_12
       
   193             ),
       
   194             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   195                 CertificateRequest.t13HandshakeConsumer,
       
   196                 ProtocolVersion.PROTOCOLS_OF_13
       
   197             )
       
   198         }),
       
   199         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   200             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   201                 CertificateRequest.t10HandshakeProducer,
       
   202                 ProtocolVersion.PROTOCOLS_TO_11
       
   203             ),
       
   204             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   205                 CertificateRequest.t12HandshakeProducer,
       
   206                 ProtocolVersion.PROTOCOLS_OF_12
       
   207             ),
       
   208             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   209                 CertificateRequest.t13HandshakeProducer,
       
   210                 ProtocolVersion.PROTOCOLS_OF_13
       
   211             )
       
   212         })),
       
   213 
       
   214     @SuppressWarnings({"unchecked", "rawtypes"})
       
   215     SERVER_HELLO_DONE           ((byte)0x0E, "server_hello_done",
       
   216         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   217             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   218                 ServerHelloDone.handshakeConsumer,
       
   219                 ProtocolVersion.PROTOCOLS_TO_12
       
   220             )
       
   221         }),
       
   222         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   223             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   224                 ServerHelloDone.handshakeProducer,
       
   225                 ProtocolVersion.PROTOCOLS_TO_12
       
   226             )
       
   227         })),
       
   228 
       
   229     @SuppressWarnings({"unchecked", "rawtypes"})
       
   230     CERTIFICATE_VERIFY          ((byte)0x0F, "certificate_verify",
       
   231         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   232             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   233                 CertificateVerify.s30HandshakeConsumer,
       
   234                 ProtocolVersion.PROTOCOLS_OF_30
       
   235             ),
       
   236             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   237                 CertificateVerify.t10HandshakeConsumer,
       
   238                 ProtocolVersion.PROTOCOLS_10_11
       
   239             ),
       
   240             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   241                 CertificateVerify.t12HandshakeConsumer,
       
   242                 ProtocolVersion.PROTOCOLS_OF_12
       
   243             ),
       
   244             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   245                 CertificateVerify.t13HandshakeConsumer,
       
   246                 ProtocolVersion.PROTOCOLS_OF_13
       
   247             )
       
   248         }),
       
   249         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   250             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   251                 CertificateVerify.s30HandshakeProducer,
       
   252                 ProtocolVersion.PROTOCOLS_OF_30
       
   253             ),
       
   254             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   255                 CertificateVerify.t10HandshakeProducer,
       
   256                 ProtocolVersion.PROTOCOLS_10_11
       
   257             ),
       
   258             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   259                 CertificateVerify.t12HandshakeProducer,
       
   260                 ProtocolVersion.PROTOCOLS_OF_12
       
   261             ),
       
   262             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   263                 CertificateVerify.t13HandshakeProducer,
       
   264                 ProtocolVersion.PROTOCOLS_OF_13
       
   265             )
       
   266         })),
       
   267 
       
   268     @SuppressWarnings({"unchecked", "rawtypes"})
       
   269     CLIENT_KEY_EXCHANGE         ((byte)0x10, "client_key_exchange",
       
   270         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   271             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   272                 ClientKeyExchange.handshakeConsumer,
       
   273                 ProtocolVersion.PROTOCOLS_TO_12
       
   274             )
       
   275         }),
       
   276         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   277             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   278                 ClientKeyExchange.handshakeProducer,
       
   279                 ProtocolVersion.PROTOCOLS_TO_12
       
   280             )
       
   281         })),
       
   282 
       
   283     @SuppressWarnings({"unchecked", "rawtypes"})
       
   284     FINISHED                    ((byte)0x14, "finished",
       
   285         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   286             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   287                 Finished.t12HandshakeConsumer,
       
   288                 ProtocolVersion.PROTOCOLS_TO_12
       
   289             ),
       
   290             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   291                 Finished.t13HandshakeConsumer,
       
   292                 ProtocolVersion.PROTOCOLS_OF_13
       
   293             )
       
   294         }),
       
   295         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   296             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   297                 Finished.t12HandshakeProducer,
       
   298                 ProtocolVersion.PROTOCOLS_TO_12
       
   299             ),
       
   300             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   301                 Finished.t13HandshakeProducer,
       
   302                 ProtocolVersion.PROTOCOLS_OF_13
       
   303             )
       
   304         })),
       
   305 
       
   306     CERTIFICATE_URL             ((byte)0x15, "certificate_url"),
       
   307 
       
   308     @SuppressWarnings({"unchecked", "rawtypes"})
       
   309     CERTIFICATE_STATUS          ((byte)0x16, "certificate_status",
       
   310         (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   311             new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   312                 CertificateStatus.handshakeConsumer,
       
   313                 ProtocolVersion.PROTOCOLS_TO_12
       
   314             )
       
   315         }),
       
   316         (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   317             new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   318                 CertificateStatus.handshakeProducer,
       
   319                 ProtocolVersion.PROTOCOLS_TO_12
       
   320             )
       
   321         }),
       
   322         (Map.Entry<HandshakeAbsence, ProtocolVersion[]>[])(new Map.Entry[] {
       
   323             new SimpleImmutableEntry<HandshakeAbsence, ProtocolVersion[]>(
       
   324                 CertificateStatus.handshakeAbsence,
       
   325                 ProtocolVersion.PROTOCOLS_TO_12
       
   326             )
       
   327         })),
       
   328 
       
   329     SUPPLEMENTAL_DATA           ((byte)0x17, "supplemental_data"),
       
   330 
       
   331     @SuppressWarnings({"unchecked", "rawtypes"})
       
   332     KEY_UPDATE                  ((byte)0x18, "key_update",
       
   333             (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   334                     new SimpleImmutableEntry<SSLConsumer, ProtocolVersion[]>(
       
   335                             KeyUpdate.handshakeConsumer,
       
   336                             ProtocolVersion.PROTOCOLS_OF_13
       
   337                     )
       
   338             }),
       
   339             (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(new Map.Entry[] {
       
   340                     new SimpleImmutableEntry<HandshakeProducer, ProtocolVersion[]>(
       
   341                             KeyUpdate.handshakeProducer,
       
   342                             ProtocolVersion.PROTOCOLS_OF_13
       
   343                     )
       
   344             })),
       
   345     MESSAGE_HASH                ((byte)0xFE, "message_hash"),
       
   346     NOT_APPLICABLE              ((byte)0xFF, "not_applicable");
       
   347 
       
   348     final byte id;
       
   349     final String name;
       
   350     final Map.Entry<SSLConsumer, ProtocolVersion[]>[] handshakeConsumers;
       
   351     final Map.Entry<HandshakeProducer, ProtocolVersion[]>[] handshakeProducers;
       
   352     final Map.Entry<HandshakeAbsence, ProtocolVersion[]>[] handshakeAbsences;
       
   353 
       
   354     @SuppressWarnings({"unchecked", "rawtypes"})
       
   355     SSLHandshake(byte id, String name) {
       
   356         this(id, name,
       
   357                 (Map.Entry<SSLConsumer, ProtocolVersion[]>[])(
       
   358                         new Map.Entry[0]),
       
   359                 (Map.Entry<HandshakeProducer, ProtocolVersion[]>[])(
       
   360                         new Map.Entry[0]),
       
   361                 (Map.Entry<HandshakeAbsence, ProtocolVersion[]>[])(
       
   362                         new Map.Entry[0]));
       
   363     }
       
   364 
       
   365     @SuppressWarnings({"unchecked", "rawtypes"})
       
   366     SSLHandshake(byte id, String name,
       
   367         Map.Entry<SSLConsumer, ProtocolVersion[]>[] handshakeConsumers,
       
   368         Map.Entry<HandshakeProducer, ProtocolVersion[]>[] handshakeProducers) {
       
   369         this(id, name, handshakeConsumers, handshakeProducers,
       
   370                 (Map.Entry<HandshakeAbsence, ProtocolVersion[]>[])(
       
   371                         new Map.Entry[0]));
       
   372     }
       
   373 
       
   374     SSLHandshake(byte id, String name,
       
   375         Map.Entry<SSLConsumer, ProtocolVersion[]>[] handshakeConsumers,
       
   376         Map.Entry<HandshakeProducer, ProtocolVersion[]>[] handshakeProducers,
       
   377         Map.Entry<HandshakeAbsence, ProtocolVersion[]>[] handshakeAbsence) {
       
   378         this.id = id;
       
   379         this.name = name;
       
   380         this.handshakeConsumers = handshakeConsumers;
       
   381         this.handshakeProducers = handshakeProducers;
       
   382         this.handshakeAbsences = handshakeAbsence;
       
   383     }
       
   384 
       
   385     @Override
       
   386     public void consume(ConnectionContext context,
       
   387             ByteBuffer message) throws IOException {
       
   388         SSLConsumer hc = getHandshakeConsumer(context);
       
   389         if (hc != null) {
       
   390             hc.consume(context, message);
       
   391         } else {
       
   392             throw new UnsupportedOperationException(
       
   393                     "Unsupported handshake consumer: " + this.name);
       
   394         }
       
   395     }
       
   396 
       
   397     private SSLConsumer getHandshakeConsumer(ConnectionContext context) {
       
   398         if (handshakeConsumers.length == 0) {
       
   399             return null;
       
   400         }
       
   401 
       
   402         // The comsuming happens in handshake context only.
       
   403         HandshakeContext hc = (HandshakeContext)context;
       
   404         ProtocolVersion protocolVersion;
       
   405         if ((hc.negotiatedProtocol == null) ||
       
   406                 (hc.negotiatedProtocol == ProtocolVersion.NONE)) {
       
   407             protocolVersion = hc.maximumActiveProtocol;
       
   408         } else {
       
   409             protocolVersion = hc.negotiatedProtocol;
       
   410         }
       
   411 
       
   412         for (Map.Entry<SSLConsumer,
       
   413                 ProtocolVersion[]> phe : handshakeConsumers) {
       
   414             for (ProtocolVersion pv : phe.getValue()) {
       
   415                 if (protocolVersion == pv) {
       
   416                     return phe.getKey();
       
   417                 }
       
   418             }
       
   419         }
       
   420 
       
   421         return null;
       
   422     }
       
   423 
       
   424     @Override
       
   425     public byte[] produce(ConnectionContext context,
       
   426             HandshakeMessage message) throws IOException {
       
   427         HandshakeProducer hp = getHandshakeProducer(context);
       
   428         if (hp != null) {
       
   429             return hp.produce(context, message);
       
   430         } else {
       
   431             throw new UnsupportedOperationException(
       
   432                     "Unsupported handshake producer: " + this.name);
       
   433         }
       
   434     }
       
   435 
       
   436     private HandshakeProducer getHandshakeProducer(
       
   437             ConnectionContext context) {
       
   438         if (handshakeConsumers.length == 0) {
       
   439             return null;
       
   440         }
       
   441 
       
   442         // The comsuming happens in handshake context only.
       
   443         HandshakeContext hc = (HandshakeContext)context;
       
   444         ProtocolVersion protocolVersion;
       
   445         if ((hc.negotiatedProtocol == null) ||
       
   446                 (hc.negotiatedProtocol == ProtocolVersion.NONE)) {
       
   447             protocolVersion = hc.maximumActiveProtocol;
       
   448         } else {
       
   449             protocolVersion = hc.negotiatedProtocol;
       
   450         }
       
   451 
       
   452         for (Map.Entry<HandshakeProducer,
       
   453                 ProtocolVersion[]> phe : handshakeProducers) {
       
   454             for (ProtocolVersion pv : phe.getValue()) {
       
   455                 if (protocolVersion == pv) {
       
   456                     return phe.getKey();
       
   457                 }
       
   458             }
       
   459         }
       
   460 
       
   461         return null;
       
   462     }
       
   463 
       
   464     @Override
       
   465     public String toString() {
       
   466         return name;
       
   467     }
       
   468 
       
   469     /*
       
   470     static SSLHandshake valueOf(byte id) {
       
   471         for (SSLHandshake hs : SSLHandshake.values()) {
       
   472             if (hs.id == id) {
       
   473                 return hs;
       
   474             }
       
   475         }
       
   476 
       
   477         return null;
       
   478     }
       
   479     */
       
   480 
       
   481     static String nameOf(byte id) {
       
   482         // If two handshake message share the same handshake type, returns
       
   483         // the first handshake message name.
       
   484         //
       
   485         // It is not a big issue at present as only ServerHello and
       
   486         // HellRetryRequest share a handshake type.
       
   487         for (SSLHandshake hs : SSLHandshake.values()) {
       
   488             if (hs.id == id) {
       
   489                 return hs.name;
       
   490             }
       
   491         }
       
   492 
       
   493         return "UNKNOWN-HANDSHAKE-MESSAGE(" + id + ")";
       
   494     }
       
   495 
       
   496     static final void kickstart(HandshakeContext context) throws IOException {
       
   497         if (context instanceof ClientHandshakeContext) {
       
   498             // For initial handshaking, including session resumption,
       
   499             // ClientHello message is used as the kickstart message.
       
   500             //
       
   501             // (D)TLS 1.2 and older protocols support renegotiation on existing
       
   502             // connections.  A ClientHello messages is used to kickstart the
       
   503             // renegotiation.
       
   504             //
       
   505             // (D)TLS 1.3 forbids renegotiation.  The post-handshake KeyUpdate
       
   506             // message is used to update the sending cryptographic keys.
       
   507             if (context.conContext.isNegotiated &&
       
   508                     context.conContext.protocolVersion.useTLS13PlusSpec()) {
       
   509                 // Use KeyUpdate message for renegotiation.
       
   510                 KeyUpdate.kickstartProducer.produce(context);
       
   511             } else {
       
   512                 // Using ClientHello message for the initial handshaking
       
   513                 // (including session resumption) or renegotiation.
       
   514                 // SSLHandshake.CLIENT_HELLO.produce(context);
       
   515                 ClientHello.kickstartProducer.produce(context);
       
   516             }
       
   517         } else {
       
   518             // The server side can delivering kickstart message after the
       
   519             // connection has established.
       
   520             //
       
   521             // (D)TLS 1.2 and older protocols use HelloRequest to begin a
       
   522             // negotiation process anew.
       
   523             //
       
   524             // While (D)TLS 1.3 uses the post-handshake KeyUpdate message
       
   525             // to update the sending cryptographic keys.
       
   526             if (context.conContext.protocolVersion.useTLS13PlusSpec()) {
       
   527                 // Use KeyUpdate message for renegotiation.
       
   528                 KeyUpdate.kickstartProducer.produce(context);
       
   529             } else {
       
   530                 // SSLHandshake.HELLO_REQUEST.produce(context);
       
   531                 HelloRequest.kickstartProducer.produce(context);
       
   532             }
       
   533         }
       
   534     }
       
   535 
       
   536     /**
       
   537      * A (transparent) specification of handshake message.
       
   538      */
       
   539     static abstract class HandshakeMessage {
       
   540         final HandshakeContext      handshakeContext;
       
   541 
       
   542         HandshakeMessage(HandshakeContext handshakeContext) {
       
   543             this.handshakeContext = handshakeContext;
       
   544         }
       
   545 
       
   546         abstract SSLHandshake handshakeType();
       
   547         abstract int messageLength();
       
   548         abstract void send(HandshakeOutStream hos) throws IOException;
       
   549 
       
   550         void write(HandshakeOutStream hos) throws IOException {
       
   551             int len = messageLength();
       
   552             if (len >= Record.OVERFLOW_OF_INT24) {
       
   553                 throw new SSLException("Handshake message is overflow"
       
   554                         + ", type = " + handshakeType() + ", len = " + len);
       
   555             }
       
   556             hos.write(handshakeType().id);
       
   557             hos.putInt24(len);
       
   558             send(hos);
       
   559             hos.complete();
       
   560         }
       
   561     }
       
   562 }