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