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