1 /*
   2  * Copyright (c) 2015, 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.security.SecureRandom;
  31 import java.security.cert.X509Certificate;
  32 import java.text.MessageFormat;
  33 import java.util.Arrays;
  34 import java.util.Collections;
  35 import java.util.LinkedList;
  36 import java.util.List;
  37 import java.util.Locale;
  38 import java.util.Objects;
  39 import javax.net.ssl.SSLException;
  40 import javax.net.ssl.SSLHandshakeException;
  41 import javax.net.ssl.SSLPeerUnverifiedException;
  42 import javax.net.ssl.SSLProtocolException;
  43 import static sun.security.ssl.ClientAuthType.CLIENT_AUTH_REQUIRED;
  44 import sun.security.ssl.SSLHandshake.HandshakeMessage;
  45 import sun.security.ssl.SupportedVersionsExtension.CHSupportedVersionsSpec;
  46 
  47 /**
  48  * Pack of the ClientHello handshake message.
  49  */
  50 final class ClientHello {
  51     static final SSLProducer kickstartProducer =
  52         new ClientHelloKickstartProducer();
  53     static final SSLConsumer handshakeConsumer =
  54         new ClientHelloConsumer();
  55     static final HandshakeProducer handshakeProducer =
  56         new ClientHelloProducer();
  57 
  58     private static final HandshakeConsumer t12HandshakeConsumer =
  59             new T12ClientHelloConsumer();
  60     private static final HandshakeConsumer t13HandshakeConsumer =
  61             new T13ClientHelloConsumer();
  62     private static final HandshakeConsumer d12HandshakeConsumer =
  63             new D12ClientHelloConsumer();
  64     private static final HandshakeConsumer d13HandshakeConsumer =
  65             new D13ClientHelloConsumer();
  66 
  67     /**
  68      * The ClientHello handshake message.
  69      *
  70      * See RFC 5264/4346/2246/6347 for the specifications.
  71      */
  72     static final class ClientHelloMessage extends HandshakeMessage {
  73         private final boolean       isDTLS;
  74 
  75         final int                   clientVersion;
  76         final RandomCookie          clientRandom;
  77         final SessionId             sessionId;
  78         private byte[]              cookie;         // DTLS only
  79         final int[]                 cipherSuiteIds;
  80         final List<CipherSuite>     cipherSuites;   // known cipher suites only
  81         final byte[]                compressionMethod;
  82         final SSLExtensions         extensions;
  83 
  84         private static final byte[]  NULL_COMPRESSION = new byte[] {0};
  85 
  86         ClientHelloMessage(HandshakeContext handshakeContext,
  87                 int clientVersion, SessionId sessionId,
  88                 List<CipherSuite> cipherSuites, SecureRandom generator) {
  89             super(handshakeContext);
  90             this.isDTLS = handshakeContext.sslContext.isDTLS();
  91 
  92             this.clientVersion = clientVersion;
  93             this.clientRandom = new RandomCookie(generator);
  94             this.sessionId = sessionId;
  95             if (isDTLS) {
  96                 this.cookie = new byte[0];
  97             } else {
  98                 this.cookie = null;
  99             }
 100 
 101             this.cipherSuites = cipherSuites;
 102             this.cipherSuiteIds = getCipherSuiteIds(cipherSuites);
 103             this.extensions = new SSLExtensions(this);
 104 
 105             // Don't support compression.
 106             this.compressionMethod = NULL_COMPRESSION;
 107         }
 108 
 109         /* Read up to the binders in the PSK extension. After this method
 110          * returns, the ByteBuffer position will be at end of the message
 111          * fragment that should be hashed to produce the PSK binder values.
 112          * The client of this method can use this position to determine the
 113          * message fragment and produce the binder values.
 114          */
 115         static void readPartial(TransportContext tc,
 116                 ByteBuffer m) throws IOException {
 117             boolean isDTLS = tc.sslContext.isDTLS();
 118 
 119             // version
 120             Record.getInt16(m);
 121 
 122             new RandomCookie(m);
 123 
 124             // session ID
 125             Record.getBytes8(m);
 126 
 127             // DTLS cookie
 128             if (isDTLS) {
 129                 Record.getBytes8(m);
 130             }
 131 
 132             // cipher suite IDs
 133             Record.getBytes16(m);
 134             // compression method
 135             Record.getBytes8(m);
 136             // read extensions, if present
 137             if (m.remaining() >= 2) {
 138                 int remaining = Record.getInt16(m);
 139                 while (remaining > 0) {
 140                     int id = Record.getInt16(m);
 141                     int extLen = Record.getInt16(m);
 142                     remaining -= extLen + 4;
 143 
 144                     if (id == SSLExtension.CH_PRE_SHARED_KEY.id) {
 145                         // ensure pre_shared_key is the last extension
 146                         if (remaining > 0) {
 147                             tc.fatal(Alert.ILLEGAL_PARAMETER,
 148                             "pre_shared_key extension is not last");
 149                         }
 150                         // read only up to the IDs
 151                         Record.getBytes16(m);
 152                         return;
 153                     } else {
 154                         m.position(m.position() + extLen);
 155 
 156                     }
 157                 }
 158             }   // Otherwise, ignore the remaining bytes.
 159         }
 160 
 161         ClientHelloMessage(HandshakeContext handshakeContext, ByteBuffer m,
 162                 SSLExtension[] supportedExtensions) throws IOException {
 163             super(handshakeContext);
 164             this.isDTLS = handshakeContext.sslContext.isDTLS();
 165 
 166             this.clientVersion = ((m.get() & 0xFF) << 8) | (m.get() & 0xFF);
 167             this.clientRandom = new RandomCookie(m);
 168             this.sessionId = new SessionId(Record.getBytes8(m));
 169             try {
 170                 sessionId.checkLength(clientVersion);
 171             } catch (SSLProtocolException ex) {
 172                 handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, ex);
 173             }
 174             if (isDTLS) {
 175                 this.cookie = Record.getBytes8(m);
 176             } else {
 177                 this.cookie = null;
 178             }
 179 
 180             byte[] encodedIds = Record.getBytes16(m);
 181             if (encodedIds.length == 0 || (encodedIds.length & 0x01) != 0) {
 182                 handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
 183                     "Invalid ClientHello message");
 184             }
 185 
 186             this.cipherSuiteIds = new int[encodedIds.length >> 1];
 187             for (int i = 0, j = 0; i < encodedIds.length; i++, j++) {
 188                 cipherSuiteIds[j] =
 189                     ((encodedIds[i++] & 0xFF) << 8) | (encodedIds[i] & 0xFF);
 190             }
 191             this.cipherSuites = getCipherSuites(cipherSuiteIds);
 192 
 193             this.compressionMethod = Record.getBytes8(m);
 194             // In TLS 1.3, use of certain extensions is mandatory.
 195             if (m.hasRemaining()) {
 196                 this.extensions =
 197                         new SSLExtensions(this, m, supportedExtensions);
 198             } else {
 199                 this.extensions = new SSLExtensions(this);
 200             }
 201         }
 202 
 203         void setHelloCookie(byte[] cookie) {
 204             this.cookie = cookie;
 205         }
 206 
 207         // DTLS 1.0/1.2, for cookie generation.
 208         byte[] getHelloCookieBytes() {
 209             HandshakeOutStream hos = new HandshakeOutStream(null);
 210             try {
 211                 // copied from send() method
 212                 hos.putInt8((byte)((clientVersion >>> 8) & 0xFF));
 213                 hos.putInt8((byte)(clientVersion & 0xFF));
 214                 hos.write(clientRandom.randomBytes, 0, 32);
 215                 hos.putBytes8(sessionId.getId());
 216                 // ignore cookie
 217                 hos.putBytes16(getEncodedCipherSuites());
 218                 hos.putBytes8(compressionMethod);
 219                 extensions.send(hos);       // In TLS 1.3, use of certain
 220                                             // extensions is mandatory.
 221             } catch (IOException ioe) {
 222                 // unlikely
 223             }
 224 
 225             return hos.toByteArray();
 226         }
 227 
 228         // (D)TLS 1.3, for cookie generation.
 229         byte[] getHeaderBytes() {
 230             HandshakeOutStream hos = new HandshakeOutStream(null);
 231             try {
 232                 // copied from send() method
 233                 hos.putInt8((byte)((clientVersion >>> 8) & 0xFF));
 234                 hos.putInt8((byte)(clientVersion & 0xFF));
 235                 hos.write(clientRandom.randomBytes, 0, 32);
 236                 hos.putBytes8(sessionId.getId());
 237                 hos.putBytes16(getEncodedCipherSuites());
 238                 hos.putBytes8(compressionMethod);
 239             } catch (IOException ioe) {
 240                 // unlikely
 241             }
 242 
 243             return hos.toByteArray();
 244         }
 245 
 246         private static int[] getCipherSuiteIds(
 247                 List<CipherSuite> cipherSuites) {
 248             if (cipherSuites != null) {
 249                 int[] ids = new int[cipherSuites.size()];
 250                 int i = 0;
 251                 for (CipherSuite cipherSuite : cipherSuites) {
 252                     ids[i++] = cipherSuite.id;
 253                 }
 254 
 255                 return ids;
 256             }
 257 
 258             return new int[0];
 259         }
 260 
 261         private static List<CipherSuite> getCipherSuites(int[] ids) {
 262             List<CipherSuite> cipherSuites = new LinkedList<>();
 263             for (int id : ids) {
 264                 CipherSuite cipherSuite = CipherSuite.valueOf(id);
 265                 if (cipherSuite != null) {
 266                     cipherSuites.add(cipherSuite);
 267                 }
 268             }
 269 
 270             return Collections.unmodifiableList(cipherSuites);
 271         }
 272 
 273         private List<String> getCipherSuiteNames() {
 274             List<String> names = new LinkedList<>();
 275             for (int id : cipherSuiteIds) {
 276                 names.add(CipherSuite.nameOf(id) +
 277                         "(" + Utilities.byte16HexString(id) + ")");            }
 278 
 279             return names;
 280         }
 281 
 282         private byte[] getEncodedCipherSuites() {
 283             byte[] encoded = new byte[cipherSuiteIds.length << 1];
 284             int i = 0;
 285             for (int id : cipherSuiteIds) {
 286                 encoded[i++] = (byte)(id >> 8);
 287                 encoded[i++] = (byte)id;
 288             }
 289             return encoded;
 290         }
 291 
 292         @Override
 293         public SSLHandshake handshakeType() {
 294             return SSLHandshake.CLIENT_HELLO;
 295         }
 296 
 297         @Override
 298         public int messageLength() {
 299             /*
 300              * Add fixed size parts of each field...
 301              * version + random + session + cipher + compress
 302              */
 303             return (2 + 32 + 1 + 2 + 1
 304                 + sessionId.length()        /* ... + variable parts */
 305                 + (isDTLS ? (1 + cookie.length) : 0)
 306                 + (cipherSuiteIds.length * 2)
 307                 + compressionMethod.length)
 308                 + extensions.length();      // In TLS 1.3, use of certain
 309                                             // extensions is mandatory.
 310         }
 311 
 312         @Override
 313         public void send(HandshakeOutStream hos) throws IOException {
 314             sendCore(hos);
 315             extensions.send(hos);       // In TLS 1.3, use of certain
 316                                         // extensions is mandatory.
 317         }
 318 
 319         void sendCore(HandshakeOutStream hos) throws IOException {
 320             hos.putInt8((byte) (clientVersion >>> 8));
 321             hos.putInt8((byte) clientVersion);
 322             hos.write(clientRandom.randomBytes, 0, 32);
 323             hos.putBytes8(sessionId.getId());
 324             if (isDTLS) {
 325                 hos.putBytes8(cookie);
 326             }
 327             hos.putBytes16(getEncodedCipherSuites());
 328             hos.putBytes8(compressionMethod);
 329         }
 330 
 331         @Override
 332         public String toString() {
 333             if (isDTLS) {
 334                 MessageFormat messageFormat = new MessageFormat(
 335                     "\"ClientHello\": '{'\n" +
 336                     "  \"client version\"      : \"{0}\",\n" +
 337                     "  \"random\"              : \"{1}\",\n" +
 338                     "  \"session id\"          : \"{2}\",\n" +
 339                     "  \"cookie\"              : \"{3}\",\n" +
 340                     "  \"cipher suites\"       : \"{4}\",\n" +
 341                     "  \"compression methods\" : \"{5}\",\n" +
 342                     "  \"extensions\"          : [\n" +
 343                     "{6}\n" +
 344                     "  ]\n" +
 345                     "'}'",
 346                     Locale.ENGLISH);
 347                 Object[] messageFields = {
 348                     ProtocolVersion.nameOf(clientVersion),
 349                     Utilities.toHexString(clientRandom.randomBytes),
 350                     sessionId.toString(),
 351                     Utilities.toHexString(cookie),
 352                     getCipherSuiteNames().toString(),
 353                     Utilities.toHexString(compressionMethod),
 354                     Utilities.indent(Utilities.indent(extensions.toString()))
 355                 };
 356 
 357                 return messageFormat.format(messageFields);
 358             } else {
 359                 MessageFormat messageFormat = new MessageFormat(
 360                     "\"ClientHello\": '{'\n" +
 361                     "  \"client version\"      : \"{0}\",\n" +
 362                     "  \"random\"              : \"{1}\",\n" +
 363                     "  \"session id\"          : \"{2}\",\n" +
 364                     "  \"cipher suites\"       : \"{3}\",\n" +
 365                     "  \"compression methods\" : \"{4}\",\n" +
 366                     "  \"extensions\"          : [\n" +
 367                     "{5}\n" +
 368                     "  ]\n" +
 369                     "'}'",
 370                     Locale.ENGLISH);
 371                 Object[] messageFields = {
 372                     ProtocolVersion.nameOf(clientVersion),
 373                     Utilities.toHexString(clientRandom.randomBytes),
 374                     sessionId.toString(),
 375                     getCipherSuiteNames().toString(),
 376                     Utilities.toHexString(compressionMethod),
 377                     Utilities.indent(Utilities.indent(extensions.toString()))
 378                 };
 379 
 380                 return messageFormat.format(messageFields);
 381             }
 382         }
 383     }
 384 
 385     /**
 386      * The "ClientHello" handshake message kick start producer.
 387      */
 388     private static final
 389             class ClientHelloKickstartProducer implements SSLProducer {
 390         // Prevent instantiation of this class.
 391         private ClientHelloKickstartProducer() {
 392             // blank
 393         }
 394 
 395         // Produce kickstart handshake message.
 396         @Override
 397         public byte[] produce(ConnectionContext context) throws IOException {
 398             // The producing happens in client side only.
 399             ClientHandshakeContext chc = (ClientHandshakeContext)context;
 400 
 401             // clean up this producer
 402             chc.handshakeProducers.remove(SSLHandshake.CLIENT_HELLO.id);
 403 
 404             // the max protocol version this client is supporting.
 405             ProtocolVersion maxProtocolVersion = chc.maximumActiveProtocol;
 406 
 407             // session ID of the ClientHello message
 408             SessionId sessionId = SSLSessionImpl.nullSession.getSessionId();
 409 
 410             // a list of cipher suites sent by the client
 411             List<CipherSuite> cipherSuites = chc.activeCipherSuites;
 412 
 413             //
 414             // Try to resume an existing session.
 415             //
 416             SSLSessionContextImpl ssci = (SSLSessionContextImpl)
 417                     chc.sslContext.engineGetClientSessionContext();
 418             SSLSessionImpl session = ssci.get(
 419                     chc.conContext.transport.getPeerHost(),
 420                     chc.conContext.transport.getPeerPort());
 421             if (session != null) {
 422                 // If unsafe server certificate change is not allowed, reserve
 423                 // current server certificates if the previous handshake is a
 424                 // session-resumption abbreviated initial handshake.
 425                 if (!ClientHandshakeContext.allowUnsafeServerCertChange &&
 426                         session.isSessionResumption()) {
 427                     try {
 428                         // If existing, peer certificate chain cannot be null.
 429                         chc.reservedServerCerts =
 430                             (X509Certificate[])session.getPeerCertificates();
 431                     } catch (SSLPeerUnverifiedException puve) {
 432                         // Maybe not certificate-based, ignore the exception.
 433                     }
 434                 }
 435 
 436                 if (!session.isRejoinable()) {
 437                     session = null;
 438                     if (SSLLogger.isOn &&
 439                             SSLLogger.isOn("ssl,handshake,verbose")) {
 440                         SSLLogger.finest(
 441                             "Can't resume, the session is not rejoinable");
 442                     }
 443                 }
 444             }
 445 
 446             CipherSuite sessionSuite = null;
 447             if (session != null) {
 448                 sessionSuite = session.getSuite();
 449                 if (!chc.isNegotiable(sessionSuite)) {
 450                     session = null;
 451                     if (SSLLogger.isOn &&
 452                             SSLLogger.isOn("ssl,handshake,verbose")) {
 453                         SSLLogger.finest(
 454                             "Can't resume, unavailable session cipher suite");
 455                     }
 456                 }
 457             }
 458 
 459             ProtocolVersion sessionVersion = null;
 460             if (session != null) {
 461                 sessionVersion = session.getProtocolVersion();
 462                 if (!chc.isNegotiable(sessionVersion)) {
 463                     session = null;
 464                     if (SSLLogger.isOn &&
 465                             SSLLogger.isOn("ssl,handshake,verbose")) {
 466                         SSLLogger.finest(
 467                             "Can't resume, unavailable protocol version");
 468                     }
 469                 }
 470             }
 471 
 472             if (session != null &&
 473                 !sessionVersion.useTLS13PlusSpec() &&
 474                 SSLConfiguration.useExtendedMasterSecret) {
 475 
 476                 boolean isEmsAvailable = chc.sslConfig.isAvailable(
 477                     SSLExtension.CH_EXTENDED_MASTER_SECRET, sessionVersion);
 478                 if (isEmsAvailable && !session.useExtendedMasterSecret &&
 479                         !SSLConfiguration.allowLegacyResumption) {
 480                     // perform full handshake instead
 481                     //
 482                     // The client SHOULD NOT offer an abbreviated handshake
 483                     // to resume a session that does not use an extended
 484                     // master secret.  Instead, it SHOULD offer a full
 485                     // handshake.
 486                      session = null;
 487                 }
 488 
 489                 if ((session != null) &&
 490                         !ClientHandshakeContext.allowUnsafeServerCertChange) {
 491                     // It is fine to move on with abbreviate handshake if
 492                     // endpoint identification is enabled.
 493                     String identityAlg = chc.sslConfig.identificationProtocol;
 494                     if ((identityAlg == null || identityAlg.length() == 0)) {
 495                         if (isEmsAvailable) {
 496                             if (!session.useExtendedMasterSecret) {
 497                                 // perform full handshake instead
 498                                 session = null;
 499                             }   // Otherwise, use extended master secret.
 500                         } else {
 501                             // The extended master secret extension does not
 502                             // apply to SSL 3.0.  Perform a full handshake
 503                             // instead.
 504                             //
 505                             // Note that the useExtendedMasterSecret is
 506                             // extended to protect SSL 3.0 connections,
 507                             // by discarding abbreviate handshake.
 508                             session = null;
 509                         }
 510                     }
 511                 }
 512             }
 513 
 514             // ensure that the endpoint identification algorithm matches the
 515             // one in the session
 516             String identityAlg = chc.sslConfig.identificationProtocol;
 517             if (session != null && identityAlg != null) {
 518                 String sessionIdentityAlg =
 519                     session.getIdentificationProtocol();
 520                 if (!Objects.equals(identityAlg, sessionIdentityAlg)) {
 521                     if (SSLLogger.isOn &&
 522                     SSLLogger.isOn("ssl,handshake,verbose")) {
 523                         SSLLogger.finest("Can't resume, endpoint id" +
 524                             " algorithm does not match, requested: " +
 525                             identityAlg + ", cached: " + sessionIdentityAlg);
 526                     }
 527                     session = null;
 528                 }
 529             }
 530 
 531             if (session != null) {
 532                 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake,verbose")) {
 533                     SSLLogger.finest("Try resuming session", session);
 534                 }
 535 
 536                 // only set session id if session is 1.2 or earlier
 537                 if (!session.getProtocolVersion().useTLS13PlusSpec()) {
 538                     sessionId = session.getSessionId();
 539                 }
 540                 if (!maxProtocolVersion.equals(sessionVersion)) {
 541                     maxProtocolVersion = sessionVersion;
 542 
 543                     // Update protocol version number in underlying socket and
 544                     // handshake output stream, so that the output records
 545                     // (at the record layer) have the correct version
 546                     chc.setVersion(sessionVersion);
 547                 }
 548 
 549                 // If no new session is allowed, force use of the previous
 550                 // session ciphersuite, and add the renegotiation SCSV if
 551                 // necessary.
 552                 if (!chc.sslConfig.enableSessionCreation) {
 553                     if (!chc.conContext.isNegotiated &&
 554                         !sessionVersion.useTLS13PlusSpec() &&
 555                         cipherSuites.contains(
 556                             CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) {
 557                         cipherSuites = Arrays.asList(sessionSuite,
 558                             CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
 559                     } else {    // otherwise, use renegotiation_info extension
 560                         cipherSuites = Arrays.asList(sessionSuite);
 561                     }
 562 
 563                     if (SSLLogger.isOn &&
 564                             SSLLogger.isOn("ssl,handshake,verbose")) {
 565                         SSLLogger.finest(
 566                             "No new session is allowed, so try to resume " +
 567                             "the session cipher suite only", sessionSuite);
 568                     }
 569                 }
 570 
 571                 chc.isResumption = true;
 572                 chc.resumingSession = session;
 573             }
 574 
 575             if (session == null) {
 576                 if (!chc.sslConfig.enableSessionCreation) {
 577                     throw new SSLHandshakeException(
 578                             "No new session is allowed and " +
 579                             "no existing session can be resumed");
 580                 }
 581 
 582                 if (maxProtocolVersion.useTLS13PlusSpec() &&
 583                         SSLConfiguration.useCompatibilityMode) {
 584                     // In compatibility mode, the TLS 1.3 legacy_session_id
 585                     // field MUST be non-empty, so a client not offering a
 586                     // pre-TLS 1.3 session MUST generate a new 32-byte value.
 587                     sessionId =
 588                         new SessionId(true, chc.sslContext.getSecureRandom());
 589                 }
 590             }
 591 
 592             ProtocolVersion minimumVersion = ProtocolVersion.NONE;
 593             for (ProtocolVersion pv : chc.activeProtocols) {
 594                 if (minimumVersion == ProtocolVersion.NONE ||
 595                         pv.compare(minimumVersion) < 0) {
 596                     minimumVersion = pv;
 597                 }
 598             }
 599 
 600             // exclude SCSV for secure renegotiation
 601             if (!minimumVersion.useTLS13PlusSpec()) {
 602                 if (chc.conContext.secureRenegotiation &&
 603                         cipherSuites.contains(
 604                             CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) {
 605                     // The cipherSuites may be unmodifiable
 606                     cipherSuites = new LinkedList<>(cipherSuites);
 607                     cipherSuites.remove(
 608                             CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
 609                 }
 610             }
 611 
 612             // make sure there is a negotiable cipher suite.
 613             boolean negotiable = false;
 614             for (CipherSuite suite : cipherSuites) {
 615                 if (chc.isNegotiable(suite)) {
 616                     negotiable = true;
 617                     break;
 618                 }
 619             }
 620             if (!negotiable) {
 621                 throw new SSLHandshakeException("No negotiable cipher suite");
 622             }
 623 
 624             // Create the handshake message.
 625             ProtocolVersion clientHelloVersion = maxProtocolVersion;
 626             if (clientHelloVersion.useTLS13PlusSpec()) {
 627                 // In (D)TLS 1.3, the client indicates its version preferences
 628                 // in the "supported_versions" extension and the client_version
 629                 // (legacy_version) field MUST be set to (D)TLS 1.2.
 630                 if (clientHelloVersion.isDTLS) {
 631                     clientHelloVersion = ProtocolVersion.DTLS12;
 632                 } else {
 633                     clientHelloVersion = ProtocolVersion.TLS12;
 634                 }
 635             }
 636 
 637             ClientHelloMessage chm = new ClientHelloMessage(chc,
 638                     clientHelloVersion.id, sessionId, cipherSuites,
 639                     chc.sslContext.getSecureRandom());
 640 
 641             // cache the client random number for further using
 642             chc.clientHelloRandom = chm.clientRandom;
 643             chc.clientHelloVersion = clientHelloVersion.id;
 644 
 645             // Produce extensions for ClientHello handshake message.
 646             SSLExtension[] extTypes = chc.sslConfig.getEnabledExtensions(
 647                     SSLHandshake.CLIENT_HELLO, chc.activeProtocols);
 648             chm.extensions.produce(chc, extTypes);
 649 
 650             if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 651                 SSLLogger.fine("Produced ClientHello handshake message", chm);
 652             }
 653 
 654             // Output the handshake message.
 655             chm.write(chc.handshakeOutput);
 656             chc.handshakeOutput.flush();
 657 
 658             // Reserve the initial ClientHello message for the follow on
 659             // cookie exchange if needed.
 660             chc.initialClientHelloMsg = chm;
 661 
 662             // What's the expected response?
 663             chc.handshakeConsumers.put(
 664                     SSLHandshake.SERVER_HELLO.id, SSLHandshake.SERVER_HELLO);
 665             if (chc.sslContext.isDTLS() &&
 666                     !minimumVersion.useTLS13PlusSpec()) {
 667                 chc.handshakeConsumers.put(
 668                         SSLHandshake.HELLO_VERIFY_REQUEST.id,
 669                         SSLHandshake.HELLO_VERIFY_REQUEST);
 670             }
 671 
 672             // The handshake message has been delivered.
 673             return null;
 674         }
 675     }
 676 
 677     private static final
 678             class ClientHelloProducer implements HandshakeProducer {
 679         // Prevent instantiation of this class.
 680         private ClientHelloProducer() {
 681             // blank
 682         }
 683 
 684         // Response to one of the following handshake message:
 685         //     HelloRequest                     (SSL 3.0/TLS 1.0/1.1/1.2)
 686         //     ServerHello(HelloRetryRequest)   (TLS 1.3)
 687         //     HelloVerifyRequest               (DTLS 1.0/1.2)
 688         @Override
 689         public byte[] produce(ConnectionContext context,
 690                 HandshakeMessage message) throws IOException {
 691             // The producing happens in client side only.
 692             ClientHandshakeContext chc = (ClientHandshakeContext)context;
 693 
 694             SSLHandshake ht = message.handshakeType();
 695             if (ht == null) {
 696                 throw new UnsupportedOperationException("Not supported yet.");
 697             }
 698 
 699             switch (ht) {
 700                 case HELLO_REQUEST:
 701                     // SSL 3.0/TLS 1.0/1.1/1.2
 702                     try {
 703                         chc.kickstart();
 704                     } catch (IOException ioe) {
 705                         chc.conContext.fatal(Alert.HANDSHAKE_FAILURE, ioe);
 706                     }
 707 
 708                     // The handshake message has been delivered.
 709                     return null;
 710                 case HELLO_VERIFY_REQUEST:
 711                     // DTLS 1.0/1.2
 712                     //
 713                     // The HelloVerifyRequest consumer should have updated the
 714                     // ClientHello handshake message with cookie.
 715                     if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 716                         SSLLogger.fine(
 717                             "Produced ClientHello(cookie) handshake message",
 718                             chc.initialClientHelloMsg);
 719                     }
 720 
 721                     // Output the handshake message.
 722                     chc.initialClientHelloMsg.write(chc.handshakeOutput);
 723                     chc.handshakeOutput.flush();
 724 
 725                     // What's the expected response?
 726                     chc.handshakeConsumers.put(SSLHandshake.SERVER_HELLO.id,
 727                             SSLHandshake.SERVER_HELLO);
 728 
 729                     ProtocolVersion minimumVersion = ProtocolVersion.NONE;
 730                     for (ProtocolVersion pv : chc.activeProtocols) {
 731                         if (minimumVersion == ProtocolVersion.NONE ||
 732                                 pv.compare(minimumVersion) < 0) {
 733                             minimumVersion = pv;
 734                         }
 735                     }
 736                     if (chc.sslContext.isDTLS() &&
 737                             !minimumVersion.useTLS13PlusSpec()) {
 738                         chc.handshakeConsumers.put(
 739                                 SSLHandshake.HELLO_VERIFY_REQUEST.id,
 740                                 SSLHandshake.HELLO_VERIFY_REQUEST);
 741                     }
 742 
 743                     // The handshake message has been delivered.
 744                     return null;
 745                 case HELLO_RETRY_REQUEST:
 746                     // TLS 1.3
 747                     // The HelloRetryRequest consumer should have updated the
 748                     // ClientHello handshake message with cookie.
 749                     if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 750                         SSLLogger.fine(
 751                             "Produced ClientHello(HRR) handshake message",
 752                             chc.initialClientHelloMsg);
 753                     }
 754 
 755                     // Output the handshake message.
 756                     chc.initialClientHelloMsg.write(chc.handshakeOutput);
 757                     chc.handshakeOutput.flush();
 758 
 759                     // What's the expected response?
 760                     chc.conContext.consumers.putIfAbsent(
 761                             ContentType.CHANGE_CIPHER_SPEC.id,
 762                             ChangeCipherSpec.t13Consumer);
 763                     chc.handshakeConsumers.put(SSLHandshake.SERVER_HELLO.id,
 764                             SSLHandshake.SERVER_HELLO);
 765 
 766                     // The handshake message has been delivered.
 767                     return null;
 768                 default:
 769                     throw new UnsupportedOperationException(
 770                             "Not supported yet.");
 771             }
 772         }
 773     }
 774 
 775     /**
 776      * The "ClientHello" handshake message consumer.
 777      */
 778     private static final class ClientHelloConsumer implements SSLConsumer {
 779         // Prevent instantiation of this class.
 780         private ClientHelloConsumer() {
 781             // blank
 782         }
 783 
 784         @Override
 785         public void consume(ConnectionContext context,
 786                 ByteBuffer message) throws IOException {
 787             // The consuming happens in server side only.
 788             ServerHandshakeContext shc = (ServerHandshakeContext)context;
 789 
 790             // clean up this consumer
 791             shc.handshakeConsumers.remove(SSLHandshake.CLIENT_HELLO.id);
 792             if (!shc.handshakeConsumers.isEmpty()) {
 793                 shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 794                         "No more handshake message allowed " +
 795                         "in a ClientHello flight");
 796             }
 797 
 798             // Get enabled extension types in ClientHello handshake message.
 799             SSLExtension[] enabledExtensions =
 800                     shc.sslConfig.getEnabledExtensions(
 801                             SSLHandshake.CLIENT_HELLO);
 802 
 803             ClientHelloMessage chm =
 804                     new ClientHelloMessage(shc, message, enabledExtensions);
 805             if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 806                 SSLLogger.fine("Consuming ClientHello handshake message", chm);
 807             }
 808 
 809             shc.clientHelloVersion = chm.clientVersion;
 810             onClientHello(shc, chm);
 811         }
 812 
 813         private void onClientHello(ServerHandshakeContext context,
 814                 ClientHelloMessage clientHello) throws IOException {
 815             // Negotiate protocol version.
 816             //
 817             // Check and launch SupportedVersions.
 818             SSLExtension[] extTypes = new SSLExtension[] {
 819                     SSLExtension.CH_SUPPORTED_VERSIONS
 820                 };
 821             clientHello.extensions.consumeOnLoad(context, extTypes);
 822 
 823             ProtocolVersion negotiatedProtocol;
 824             CHSupportedVersionsSpec svs =
 825                     (CHSupportedVersionsSpec)context.handshakeExtensions.get(
 826                             SSLExtension.CH_SUPPORTED_VERSIONS);
 827             if (svs != null) {
 828                 negotiatedProtocol =
 829                         negotiateProtocol(context, svs.requestedProtocols);
 830             } else {
 831                 negotiatedProtocol =
 832                         negotiateProtocol(context, clientHello.clientVersion);
 833             }
 834             context.negotiatedProtocol = negotiatedProtocol;
 835             if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 836                 SSLLogger.fine(
 837                     "Negotiated protocol version: " + negotiatedProtocol.name);
 838             }
 839 
 840             // Consume the handshake message for the specific protocol version.
 841             if (negotiatedProtocol.isDTLS) {
 842                 if (negotiatedProtocol.useTLS13PlusSpec()) {
 843                     d13HandshakeConsumer.consume(context, clientHello);
 844                 } else {
 845                     d12HandshakeConsumer.consume(context, clientHello);
 846                 }
 847             } else {
 848                 if (negotiatedProtocol.useTLS13PlusSpec()) {
 849                     t13HandshakeConsumer.consume(context, clientHello);
 850                 } else {
 851                     t12HandshakeConsumer.consume(context, clientHello);
 852                 }
 853             }
 854         }
 855 
 856         // Select a protocol version according to the
 857         // ClientHello.client_version.
 858         private ProtocolVersion negotiateProtocol(
 859                 ServerHandshakeContext context,
 860                 int clientHelloVersion) throws SSLException {
 861 
 862             // Per TLS 1.3 specification, server MUST negotiate TLS 1.2 or prior
 863             // even if ClientHello.client_version is 0x0304 or later.
 864             int chv = clientHelloVersion;
 865             if (context.sslContext.isDTLS()) {
 866                 if (chv < ProtocolVersion.DTLS12.id) {
 867                     chv = ProtocolVersion.DTLS12.id;
 868                 }
 869             } else {
 870                 if (chv > ProtocolVersion.TLS12.id) {
 871                     chv = ProtocolVersion.TLS12.id;
 872                 }
 873             }
 874 
 875             // Select a protocol version from the activated protocols.
 876             ProtocolVersion pv = ProtocolVersion.selectedFrom(
 877                     context.activeProtocols, chv);
 878             if (pv == null || pv == ProtocolVersion.NONE ||
 879                     pv == ProtocolVersion.SSL20Hello) {
 880                 context.conContext.fatal(Alert.PROTOCOL_VERSION,
 881                     "Client requested protocol " +
 882                     ProtocolVersion.nameOf(clientHelloVersion) +
 883                     " is not enabled or supported in server context");
 884             }
 885 
 886             return pv;
 887         }
 888 
 889         // Select a protocol version according to the
 890         // supported_versions extension.
 891         private ProtocolVersion negotiateProtocol(
 892                 ServerHandshakeContext context,
 893                 int[] clientSupportedVersions) throws SSLException {
 894 
 895             // The client supported protocol versions are present in client
 896             // preference order.  This implementation chooses to use the server
 897             // preference of protocol versions instead.
 898             for (ProtocolVersion spv : context.activeProtocols) {
 899                 if (spv == ProtocolVersion.SSL20Hello) {
 900                     continue;
 901                 }
 902                 for (int cpv : clientSupportedVersions) {
 903                     if (cpv == ProtocolVersion.SSL20Hello.id) {
 904                         continue;
 905                     }
 906                     if (spv.id == cpv) {
 907                         return spv;
 908                     }
 909                 }
 910             }
 911 
 912             // No protocol version can be negotiated.
 913             context.conContext.fatal(Alert.PROTOCOL_VERSION,
 914                 "The client supported protocol versions " + Arrays.toString(
 915                     ProtocolVersion.toStringArray(clientSupportedVersions)) +
 916                 " are not accepted by server preferences " +
 917                 context.activeProtocols);
 918 
 919             return null;        // make the compiler happy
 920         }
 921     }
 922 
 923     /**
 924      * The "ClientHello" handshake message consumer for TLS 1.2 and
 925      * prior SSL/TLS protocol versions.
 926      */
 927     private static final
 928             class T12ClientHelloConsumer implements HandshakeConsumer {
 929         // Prevent instantiation of this class.
 930         private T12ClientHelloConsumer() {
 931             // blank
 932         }
 933 
 934         @Override
 935         public void consume(ConnectionContext context,
 936                 HandshakeMessage message) throws IOException {
 937             // The consuming happens in server side only.
 938             ServerHandshakeContext shc = (ServerHandshakeContext)context;
 939             ClientHelloMessage clientHello = (ClientHelloMessage)message;
 940 
 941             //
 942             // validate
 943             //
 944 
 945             // Reject client initiated renegotiation?
 946             //
 947             // If server side should reject client-initiated renegotiation,
 948             // send an Alert.HANDSHAKE_FAILURE fatal alert, not a
 949             // no_renegotiation warning alert (no_renegotiation must be a
 950             // warning: RFC 2246).  no_renegotiation might seem more
 951             // natural at first, but warnings are not appropriate because
 952             // the sending party does not know how the receiving party
 953             // will behave.  This state must be treated as a fatal server
 954             // condition.
 955             //
 956             // This will not have any impact on server initiated renegotiation.
 957             if (shc.conContext.isNegotiated) {
 958                 if (!shc.conContext.secureRenegotiation &&
 959                         !HandshakeContext.allowUnsafeRenegotiation) {
 960                     shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
 961                             "Unsafe renegotiation is not allowed");
 962                 }
 963 
 964                 if (ServerHandshakeContext.rejectClientInitiatedRenego &&
 965                         !shc.kickstartMessageDelivered) {
 966                     shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
 967                             "Client initiated renegotiation is not allowed");
 968                 }
 969             }
 970 
 971             // Is it an abbreviated handshake?
 972             if (clientHello.sessionId.length() != 0) {
 973                 SSLSessionImpl previous = ((SSLSessionContextImpl)shc.sslContext
 974                             .engineGetServerSessionContext())
 975                             .get(clientHello.sessionId.getId());
 976 
 977                 boolean resumingSession =
 978                         (previous != null) && previous.isRejoinable();
 979                 if (!resumingSession) {
 980                     if (SSLLogger.isOn &&
 981                             SSLLogger.isOn("ssl,handshake,verbose")) {
 982                         SSLLogger.finest(
 983                                 "Can't resume, " +
 984                                 "the existing session is not rejoinable");
 985                     }
 986                 }
 987                 // Validate the negotiated protocol version.
 988                 if (resumingSession) {
 989                     ProtocolVersion sessionProtocol =
 990                             previous.getProtocolVersion();
 991                     if (sessionProtocol != shc.negotiatedProtocol) {
 992                         resumingSession = false;
 993                         if (SSLLogger.isOn &&
 994                                 SSLLogger.isOn("ssl,handshake,verbose")) {
 995                             SSLLogger.finest(
 996                                 "Can't resume, not the same protocol version");
 997                         }
 998                     }
 999                 }
1000 
1001                 // Validate the required client authentication.
1002                 if (resumingSession &&
1003                     (shc.sslConfig.clientAuthType == CLIENT_AUTH_REQUIRED)) {
1004                     try {
1005                         previous.getPeerPrincipal();
1006                     } catch (SSLPeerUnverifiedException e) {
1007                         resumingSession = false;
1008                         if (SSLLogger.isOn &&
1009                                 SSLLogger.isOn("ssl,handshake,verbose")) {
1010                             SSLLogger.finest(
1011                                 "Can't resume, " +
1012                                 "client authentication is required");
1013                         }
1014                     }
1015                 }
1016 
1017                 // Validate that the cached cipher suite.
1018                 if (resumingSession) {
1019                     CipherSuite suite = previous.getSuite();
1020                     if ((!shc.isNegotiable(suite)) ||
1021                             (!clientHello.cipherSuites.contains(suite))) {
1022                         resumingSession = false;
1023                         if (SSLLogger.isOn &&
1024                                 SSLLogger.isOn("ssl,handshake,verbose")) {
1025                             SSLLogger.finest(
1026                                 "Can't resume, " +
1027                                 "the session cipher suite is absent");
1028                         }
1029                     }
1030                 }
1031 
1032                 // ensure that the endpoint identification algorithm matches the
1033                 // one in the session
1034                 String identityAlg = shc.sslConfig.identificationProtocol;
1035                 if (resumingSession && identityAlg != null) {
1036                     String sessionIdentityAlg =
1037                         previous.getIdentificationProtocol();
1038                     if (!Objects.equals(identityAlg, sessionIdentityAlg)) {
1039                         if (SSLLogger.isOn &&
1040                         SSLLogger.isOn("ssl,handshake,verbose")) {
1041                             SSLLogger.finest("Can't resume, endpoint id" +
1042                             " algorithm does not match, requested: " +
1043                             identityAlg + ", cached: " + sessionIdentityAlg);
1044                         }
1045                         resumingSession = false;
1046                     }
1047                 }
1048 
1049                 // So far so good.  Note that the handshake extensions may reset
1050                 // the resuming options later.
1051                 shc.isResumption = resumingSession;
1052                 shc.resumingSession = resumingSession ? previous : null;
1053             }
1054 
1055             // cache the client random number for further using
1056             shc.clientHelloRandom = clientHello.clientRandom;
1057 
1058             // Check and launch ClientHello extensions.
1059             SSLExtension[] extTypes = shc.sslConfig.getEnabledExtensions(
1060                     SSLHandshake.CLIENT_HELLO);
1061             clientHello.extensions.consumeOnLoad(shc, extTypes);
1062 
1063             //
1064             // update
1065             //
1066             if (!shc.conContext.isNegotiated) {
1067                 shc.conContext.protocolVersion = shc.negotiatedProtocol;
1068                 shc.conContext.outputRecord.setVersion(shc.negotiatedProtocol);
1069             }
1070 
1071             // update the responders
1072             //
1073             // Only need to ServerHello, which may add more responders later.
1074             // Note that ServerHello and HelloRetryRequest share the same
1075             // handshake type/id.  The ServerHello producer may be replaced
1076             // by HelloRetryRequest producer if needed.
1077             shc.handshakeProducers.put(SSLHandshake.SERVER_HELLO.id,
1078                     SSLHandshake.SERVER_HELLO);
1079 
1080             //
1081             // produce
1082             //
1083             SSLHandshake[] probableHandshakeMessages = new SSLHandshake[] {
1084                 SSLHandshake.SERVER_HELLO,
1085 
1086                 // full handshake messages
1087                 SSLHandshake.CERTIFICATE,
1088                 SSLHandshake.CERTIFICATE_STATUS,
1089                 SSLHandshake.SERVER_KEY_EXCHANGE,
1090                 SSLHandshake.CERTIFICATE_REQUEST,
1091                 SSLHandshake.SERVER_HELLO_DONE,
1092 
1093                 // abbreviated handshake messages
1094                 SSLHandshake.FINISHED
1095             };
1096 
1097             for (SSLHandshake hs : probableHandshakeMessages) {
1098                 HandshakeProducer handshakeProducer =
1099                         shc.handshakeProducers.remove(hs.id);
1100                 if (handshakeProducer != null) {
1101                     handshakeProducer.produce(context, clientHello);
1102                 }
1103             }
1104         }
1105     }
1106 
1107     /**
1108      * The "ClientHello" handshake message consumer for TLS 1.3.
1109      */
1110     private static final
1111             class T13ClientHelloConsumer implements HandshakeConsumer {
1112         // Prevent instantiation of this class.
1113         private T13ClientHelloConsumer() {
1114             // blank
1115         }
1116 
1117         @Override
1118         public void consume(ConnectionContext context,
1119                 HandshakeMessage message) throws IOException {
1120             // The consuming happens in server side only.
1121             ServerHandshakeContext shc = (ServerHandshakeContext)context;
1122             ClientHelloMessage clientHello = (ClientHelloMessage)message;
1123 
1124             // The client may send a dummy change_cipher_spec record
1125             // immediately after the first ClientHello.
1126             shc.conContext.consumers.putIfAbsent(
1127                     ContentType.CHANGE_CIPHER_SPEC.id,
1128                     ChangeCipherSpec.t13Consumer);
1129 
1130             // Is it a resumption?
1131             //
1132             // Check and launch the "psk_key_exchange_modes" and
1133             // "pre_shared_key" extensions first, which will reset the
1134             // resuming session, no matter the extensions present or not.
1135             shc.isResumption = true;
1136             SSLExtension[] extTypes = new SSLExtension[] {
1137                     SSLExtension.PSK_KEY_EXCHANGE_MODES,
1138                     SSLExtension.CH_PRE_SHARED_KEY
1139                 };
1140             clientHello.extensions.consumeOnLoad(shc, extTypes);
1141 
1142             // Check and launch ClientHello extensions other than
1143             // "psk_key_exchange_modes", "pre_shared_key", "protocol_version"
1144             // and "key_share" extensions.
1145             //
1146             // These extensions may discard session resumption, or ask for
1147             // hello retry.
1148             extTypes = shc.sslConfig.getExclusiveExtensions(
1149                     SSLHandshake.CLIENT_HELLO,
1150                     Arrays.asList(
1151                             SSLExtension.PSK_KEY_EXCHANGE_MODES,
1152                             SSLExtension.CH_PRE_SHARED_KEY,
1153                             SSLExtension.CH_SUPPORTED_VERSIONS));
1154             clientHello.extensions.consumeOnLoad(shc, extTypes);
1155 
1156             if (!shc.handshakeProducers.isEmpty()) {
1157                 // Should be HelloRetryRequest producer.
1158                 goHelloRetryRequest(shc, clientHello);
1159             } else {
1160                 goServerHello(shc, clientHello);
1161             }
1162         }
1163 
1164         private void goHelloRetryRequest(ServerHandshakeContext shc,
1165                 ClientHelloMessage clientHello) throws IOException {
1166             HandshakeProducer handshakeProducer =
1167                     shc.handshakeProducers.remove(
1168                             SSLHandshake.HELLO_RETRY_REQUEST.id);
1169             if (handshakeProducer != null) {
1170                     handshakeProducer.produce(shc, clientHello);
1171             } else {
1172                 // unlikely
1173                 shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
1174                     "No HelloRetryRequest producer: " + shc.handshakeProducers);
1175             }
1176 
1177             if (!shc.handshakeProducers.isEmpty()) {
1178                 // unlikely, but please double check.
1179                 shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
1180                     "unknown handshake producers: " + shc.handshakeProducers);
1181             }
1182         }
1183 
1184         private void goServerHello(ServerHandshakeContext shc,
1185                 ClientHelloMessage clientHello) throws IOException {
1186             //
1187             // validate
1188             //
1189             shc.clientHelloRandom = clientHello.clientRandom;
1190 
1191             //
1192             // update
1193             //
1194             if (!shc.conContext.isNegotiated) {
1195                 shc.conContext.protocolVersion = shc.negotiatedProtocol;
1196                 shc.conContext.outputRecord.setVersion(shc.negotiatedProtocol);
1197             }
1198 
1199             // update the responders
1200             //
1201             // Only ServerHello/HelloRetryRequest producer, which adds
1202             // more responders later.
1203             shc.handshakeProducers.put(SSLHandshake.SERVER_HELLO.id,
1204                 SSLHandshake.SERVER_HELLO);
1205 
1206             SSLHandshake[] probableHandshakeMessages = new SSLHandshake[] {
1207                 SSLHandshake.SERVER_HELLO,
1208 
1209                 // full handshake messages
1210                 SSLHandshake.ENCRYPTED_EXTENSIONS,
1211                 SSLHandshake.CERTIFICATE_REQUEST,
1212                 SSLHandshake.CERTIFICATE,
1213                 SSLHandshake.CERTIFICATE_VERIFY,
1214                 SSLHandshake.FINISHED
1215             };
1216 
1217             //
1218             // produce
1219             //
1220             for (SSLHandshake hs : probableHandshakeMessages) {
1221                 HandshakeProducer handshakeProducer =
1222                         shc.handshakeProducers.remove(hs.id);
1223                 if (handshakeProducer != null) {
1224                     handshakeProducer.produce(shc, clientHello);
1225                 }
1226             }
1227         }
1228     }
1229 
1230     /**
1231      * The "ClientHello" handshake message consumer for DTLS 1.2 and
1232      * previous DTLS protocol versions.
1233      */
1234     private static final
1235             class D12ClientHelloConsumer implements HandshakeConsumer {
1236         // Prevent instantiation of this class.
1237         private D12ClientHelloConsumer() {
1238             // blank
1239         }
1240 
1241         @Override
1242         public void consume(ConnectionContext context,
1243                 HandshakeMessage message) throws IOException {
1244             // The consuming happens in server side only.
1245             ServerHandshakeContext shc = (ServerHandshakeContext)context;
1246             ClientHelloMessage clientHello = (ClientHelloMessage)message;
1247 
1248             //
1249             // validate
1250             //
1251 
1252             // Reject client initiated renegotiation?
1253             //
1254             // If server side should reject client-initiated renegotiation,
1255             // send an Alert.HANDSHAKE_FAILURE fatal alert, not a
1256             // no_renegotiation warning alert (no_renegotiation must be a
1257             // warning: RFC 2246).  no_renegotiation might seem more
1258             // natural at first, but warnings are not appropriate because
1259             // the sending party does not know how the receiving party
1260             // will behave.  This state must be treated as a fatal server
1261             // condition.
1262             //
1263             // This will not have any impact on server initiated renegotiation.
1264             if (shc.conContext.isNegotiated) {
1265                 if (!shc.conContext.secureRenegotiation &&
1266                         !HandshakeContext.allowUnsafeRenegotiation) {
1267                     shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
1268                             "Unsafe renegotiation is not allowed");
1269                 }
1270 
1271                 if (ServerHandshakeContext.rejectClientInitiatedRenego &&
1272                         !shc.kickstartMessageDelivered) {
1273                     shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
1274                             "Client initiated renegotiation is not allowed");
1275                 }
1276             }
1277 
1278             // Is it an abbreviated handshake?
1279             if (clientHello.sessionId.length() != 0) {
1280                 SSLSessionImpl previous = ((SSLSessionContextImpl)shc.sslContext
1281                             .engineGetServerSessionContext())
1282                             .get(clientHello.sessionId.getId());
1283 
1284                 boolean resumingSession =
1285                         (previous != null) && previous.isRejoinable();
1286                 if (!resumingSession) {
1287                     if (SSLLogger.isOn &&
1288                             SSLLogger.isOn("ssl,handshake,verbose")) {
1289                         SSLLogger.finest(
1290                             "Can't resume, " +
1291                             "the existing session is not rejoinable");
1292                     }
1293                 }
1294                 // Validate the negotiated protocol version.
1295                 if (resumingSession) {
1296                     ProtocolVersion sessionProtocol =
1297                             previous.getProtocolVersion();
1298                     if (sessionProtocol != shc.negotiatedProtocol) {
1299                         resumingSession = false;
1300                         if (SSLLogger.isOn &&
1301                                 SSLLogger.isOn("ssl,handshake,verbose")) {
1302                             SSLLogger.finest(
1303                                 "Can't resume, not the same protocol version");
1304                         }
1305                     }
1306                 }
1307 
1308                 // Validate the required client authentication.
1309                 if (resumingSession &&
1310                     (shc.sslConfig.clientAuthType == CLIENT_AUTH_REQUIRED)) {
1311 
1312                     try {
1313                         previous.getPeerPrincipal();
1314                     } catch (SSLPeerUnverifiedException e) {
1315                         resumingSession = false;
1316                         if (SSLLogger.isOn &&
1317                                 SSLLogger.isOn("ssl,handshake,verbose")) {
1318                             SSLLogger.finest(
1319                                 "Can't resume, " +
1320                                 "client authentication is required");
1321                         }
1322                     }
1323                 }
1324 
1325                 // Validate that the cached cipher suite.
1326                 if (resumingSession) {
1327                     CipherSuite suite = previous.getSuite();
1328                     if ((!shc.isNegotiable(suite)) ||
1329                             (!clientHello.cipherSuites.contains(suite))) {
1330                         resumingSession = false;
1331                         if (SSLLogger.isOn &&
1332                                 SSLLogger.isOn("ssl,handshake,verbose")) {
1333                             SSLLogger.finest(
1334                                 "Can't resume, " +
1335                                 "the session cipher suite is absent");
1336                         }
1337                     }
1338                 }
1339 
1340                 // So far so good.  Note that the handshake extensions may reset
1341                 // the resuming options later.
1342                 shc.isResumption = resumingSession;
1343                 shc.resumingSession = resumingSession ? previous : null;
1344             }
1345 
1346             HelloCookieManager hcm =
1347                 shc.sslContext.getHelloCookieManager(ProtocolVersion.DTLS10);
1348             if (!shc.isResumption &&
1349                 !hcm.isCookieValid(shc, clientHello, clientHello.cookie)) {
1350                 //
1351                 // Perform cookie exchange for DTLS handshaking if no cookie
1352                 // or the cookie is invalid in the ClientHello message.
1353                 //
1354                 // update the responders
1355                 shc.handshakeProducers.put(
1356                         SSLHandshake.HELLO_VERIFY_REQUEST.id,
1357                         SSLHandshake.HELLO_VERIFY_REQUEST);
1358 
1359                 //
1360                 // produce response handshake message
1361                 //
1362                 SSLHandshake.HELLO_VERIFY_REQUEST.produce(context, clientHello);
1363 
1364                 return;
1365             }
1366 
1367             // cache the client random number for further using
1368             shc.clientHelloRandom = clientHello.clientRandom;
1369 
1370             // Check and launch ClientHello extensions.
1371             SSLExtension[] extTypes = shc.sslConfig.getEnabledExtensions(
1372                     SSLHandshake.CLIENT_HELLO);
1373             clientHello.extensions.consumeOnLoad(shc, extTypes);
1374 
1375             //
1376             // update
1377             //
1378             if (!shc.conContext.isNegotiated) {
1379                 shc.conContext.protocolVersion = shc.negotiatedProtocol;
1380                 shc.conContext.outputRecord.setVersion(shc.negotiatedProtocol);
1381             }
1382 
1383             // update the responders
1384             //
1385             // Only need to ServerHello, which may add more responders later.
1386             shc.handshakeProducers.put(SSLHandshake.SERVER_HELLO.id,
1387                     SSLHandshake.SERVER_HELLO);
1388 
1389             //
1390             // produce
1391             //
1392             SSLHandshake[] probableHandshakeMessages = new SSLHandshake[] {
1393                 SSLHandshake.SERVER_HELLO,
1394 
1395                 // full handshake messages
1396                 SSLHandshake.CERTIFICATE,
1397                 SSLHandshake.CERTIFICATE_STATUS,
1398                 SSLHandshake.SERVER_KEY_EXCHANGE,
1399                 SSLHandshake.CERTIFICATE_REQUEST,
1400                 SSLHandshake.SERVER_HELLO_DONE,
1401 
1402                 // abbreviated handshake messages
1403                 SSLHandshake.FINISHED
1404             };
1405 
1406             for (SSLHandshake hs : probableHandshakeMessages) {
1407                 HandshakeProducer handshakeProducer =
1408                         shc.handshakeProducers.remove(hs.id);
1409                 if (handshakeProducer != null) {
1410                     handshakeProducer.produce(context, clientHello);
1411                 }
1412             }
1413         }
1414     }
1415 
1416     /**
1417      * The "ClientHello" handshake message consumer for DTLS 1.3.
1418      */
1419     private static final
1420             class D13ClientHelloConsumer implements HandshakeConsumer {
1421         // Prevent instantiation of this class.
1422         private D13ClientHelloConsumer() {
1423             // blank
1424         }
1425 
1426         @Override
1427         public void consume(ConnectionContext context,
1428                 HandshakeMessage message) throws IOException {
1429             throw new UnsupportedOperationException("Not supported yet.");
1430         }
1431     }
1432 }