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 }