1 /* 2 * Copyright (c) 1996, 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.EOFException; 29 import java.io.IOException; 30 import java.io.InputStream; 31 import java.io.InterruptedIOException; 32 import java.io.OutputStream; 33 import java.net.InetAddress; 34 import java.net.InetSocketAddress; 35 import java.net.Socket; 36 import java.net.SocketAddress; 37 import java.net.SocketException; 38 import java.net.UnknownHostException; 39 import java.nio.ByteBuffer; 40 import java.util.List; 41 import java.util.concurrent.locks.ReentrantLock; 42 import java.util.function.BiFunction; 43 import javax.net.ssl.HandshakeCompletedListener; 44 import javax.net.ssl.SSLException; 45 import javax.net.ssl.SSLHandshakeException; 46 import javax.net.ssl.SSLParameters; 47 import javax.net.ssl.SSLProtocolException; 48 import javax.net.ssl.SSLServerSocket; 49 import javax.net.ssl.SSLSession; 50 import javax.net.ssl.SSLSocket; 51 import jdk.internal.misc.JavaNetInetAddressAccess; 52 import jdk.internal.misc.SharedSecrets; 53 54 /** 55 * Implementation of an SSL socket. 56 * <P> 57 * This is a normal connection type socket, implementing SSL over some lower 58 * level socket, such as TCP. Because it is layered over some lower level 59 * socket, it MUST override all default socket methods. 60 * <P> 61 * This API offers a non-traditional option for establishing SSL 62 * connections. You may first establish the connection directly, then pass 63 * that connection to the SSL socket constructor with a flag saying which 64 * role should be taken in the handshake protocol. (The two ends of the 65 * connection must not choose the same role!) This allows setup of SSL 66 * proxying or tunneling, and also allows the kind of "role reversal" 67 * that is required for most FTP data transfers. 68 * 69 * @see javax.net.ssl.SSLSocket 70 * @see SSLServerSocket 71 * 72 * @author David Brownell 73 */ 74 public final class SSLSocketImpl 75 extends BaseSSLSocketImpl implements SSLTransport { 76 77 final SSLContextImpl sslContext; 78 final TransportContext conContext; 79 80 private final AppInputStream appInput = new AppInputStream(); 81 private final AppOutputStream appOutput = new AppOutputStream(); 82 83 private String peerHost; 84 private boolean autoClose; 85 private boolean isConnected = false; 86 private volatile boolean tlsIsClosed = false; 87 88 private final ReentrantLock socketLock = new ReentrantLock(); 89 private final ReentrantLock handshakeLock = new ReentrantLock(); 90 91 /* 92 * Is the local name service trustworthy? 93 * 94 * If the local name service is not trustworthy, reverse host name 95 * resolution should not be performed for endpoint identification. 96 */ 97 private static final boolean trustNameService = 98 Utilities.getBooleanProperty("jdk.tls.trustNameService", false); 99 100 /** 101 * Package-private constructor used to instantiate an unconnected 102 * socket. 103 * 104 * This instance is meant to set handshake state to use "client mode". 105 */ 106 SSLSocketImpl(SSLContextImpl sslContext) { 107 super(); 108 this.sslContext = sslContext; 109 HandshakeHash handshakeHash = new HandshakeHash(); 110 this.conContext = new TransportContext(sslContext, this, 111 new SSLSocketInputRecord(handshakeHash), 112 new SSLSocketOutputRecord(handshakeHash), true); 113 } 114 115 /** 116 * Package-private constructor used to instantiate a server socket. 117 * 118 * This instance is meant to set handshake state to use "server mode". 119 */ 120 SSLSocketImpl(SSLContextImpl sslContext, SSLConfiguration sslConfig) { 121 super(); 122 this.sslContext = sslContext; 123 HandshakeHash handshakeHash = new HandshakeHash(); 124 this.conContext = new TransportContext(sslContext, this, sslConfig, 125 new SSLSocketInputRecord(handshakeHash), 126 new SSLSocketOutputRecord(handshakeHash)); 127 } 128 129 /** 130 * Constructs an SSL connection to a named host at a specified 131 * port, using the authentication context provided. 132 * 133 * This endpoint acts as the client, and may rejoin an existing SSL session 134 * if appropriate. 135 */ 136 SSLSocketImpl(SSLContextImpl sslContext, String peerHost, 137 int peerPort) throws IOException, UnknownHostException { 138 super(); 139 this.sslContext = sslContext; 140 HandshakeHash handshakeHash = new HandshakeHash(); 141 this.conContext = new TransportContext(sslContext, this, 142 new SSLSocketInputRecord(handshakeHash), 143 new SSLSocketOutputRecord(handshakeHash), true); 144 this.peerHost = peerHost; 145 SocketAddress socketAddress = 146 peerHost != null ? new InetSocketAddress(peerHost, peerPort) : 147 new InetSocketAddress(InetAddress.getByName(null), peerPort); 148 connect(socketAddress, 0); 149 } 150 151 /** 152 * Constructs an SSL connection to a server at a specified 153 * address, and TCP port, using the authentication context 154 * provided. 155 * 156 * This endpoint acts as the client, and may rejoin an existing SSL 157 * session if appropriate. 158 */ 159 SSLSocketImpl(SSLContextImpl sslContext, 160 InetAddress address, int peerPort) throws IOException { 161 super(); 162 this.sslContext = sslContext; 163 HandshakeHash handshakeHash = new HandshakeHash(); 164 this.conContext = new TransportContext(sslContext, this, 165 new SSLSocketInputRecord(handshakeHash), 166 new SSLSocketOutputRecord(handshakeHash), true); 167 168 SocketAddress socketAddress = new InetSocketAddress(address, peerPort); 169 connect(socketAddress, 0); 170 } 171 172 /** 173 * Constructs an SSL connection to a named host at a specified 174 * port, using the authentication context provided. 175 * 176 * This endpoint acts as the client, and may rejoin an existing SSL 177 * session if appropriate. 178 */ 179 SSLSocketImpl(SSLContextImpl sslContext, 180 String peerHost, int peerPort, InetAddress localAddr, 181 int localPort) throws IOException, UnknownHostException { 182 super(); 183 this.sslContext = sslContext; 184 HandshakeHash handshakeHash = new HandshakeHash(); 185 this.conContext = new TransportContext(sslContext, this, 186 new SSLSocketInputRecord(handshakeHash), 187 new SSLSocketOutputRecord(handshakeHash), true); 188 this.peerHost = peerHost; 189 190 bind(new InetSocketAddress(localAddr, localPort)); 191 SocketAddress socketAddress = 192 peerHost != null ? new InetSocketAddress(peerHost, peerPort) : 193 new InetSocketAddress(InetAddress.getByName(null), peerPort); 194 connect(socketAddress, 0); 195 } 196 197 /** 198 * Constructs an SSL connection to a server at a specified 199 * address, and TCP port, using the authentication context 200 * provided. 201 * 202 * This endpoint acts as the client, and may rejoin an existing SSL 203 * session if appropriate. 204 */ 205 SSLSocketImpl(SSLContextImpl sslContext, 206 InetAddress peerAddr, int peerPort, 207 InetAddress localAddr, int localPort) throws IOException { 208 super(); 209 this.sslContext = sslContext; 210 HandshakeHash handshakeHash = new HandshakeHash(); 211 this.conContext = new TransportContext(sslContext, this, 212 new SSLSocketInputRecord(handshakeHash), 213 new SSLSocketOutputRecord(handshakeHash), true); 214 215 bind(new InetSocketAddress(localAddr, localPort)); 216 SocketAddress socketAddress = new InetSocketAddress(peerAddr, peerPort); 217 connect(socketAddress, 0); 218 } 219 220 /** 221 * Creates a server mode {@link Socket} layered over an 222 * existing connected socket, and is able to read data which has 223 * already been consumed/removed from the {@link Socket}'s 224 * underlying {@link InputStream}. 225 */ 226 SSLSocketImpl(SSLContextImpl sslContext, Socket sock, 227 InputStream consumed, boolean autoClose) throws IOException { 228 super(sock, consumed); 229 // We always layer over a connected socket 230 if (!sock.isConnected()) { 231 throw new SocketException("Underlying socket is not connected"); 232 } 233 234 this.sslContext = sslContext; 235 HandshakeHash handshakeHash = new HandshakeHash(); 236 this.conContext = new TransportContext(sslContext, this, 237 new SSLSocketInputRecord(handshakeHash), 238 new SSLSocketOutputRecord(handshakeHash), false); 239 this.autoClose = autoClose; 240 doneConnect(); 241 } 242 243 /** 244 * Layer SSL traffic over an existing connection, rather than 245 * creating a new connection. 246 * 247 * The existing connection may be used only for SSL traffic (using this 248 * SSLSocket) until the SSLSocket.close() call returns. However, if a 249 * protocol error is detected, that existing connection is automatically 250 * closed. 251 * <p> 252 * This particular constructor always uses the socket in the 253 * role of an SSL client. It may be useful in cases which start 254 * using SSL after some initial data transfers, for example in some 255 * SSL tunneling applications or as part of some kinds of application 256 * protocols which negotiate use of a SSL based security. 257 */ 258 SSLSocketImpl(SSLContextImpl sslContext, Socket sock, 259 String peerHost, int port, boolean autoClose) throws IOException { 260 super(sock); 261 // We always layer over a connected socket 262 if (!sock.isConnected()) { 263 throw new SocketException("Underlying socket is not connected"); 264 } 265 266 this.sslContext = sslContext; 267 HandshakeHash handshakeHash = new HandshakeHash(); 268 this.conContext = new TransportContext(sslContext, this, 269 new SSLSocketInputRecord(handshakeHash), 270 new SSLSocketOutputRecord(handshakeHash), true); 271 this.peerHost = peerHost; 272 this.autoClose = autoClose; 273 doneConnect(); 274 } 275 276 @Override 277 public void connect(SocketAddress endpoint, 278 int timeout) throws IOException { 279 280 if (isLayered()) { 281 throw new SocketException("Already connected"); 282 } 283 284 if (!(endpoint instanceof InetSocketAddress)) { 285 throw new SocketException( 286 "Cannot handle non-Inet socket addresses."); 287 } 288 289 super.connect(endpoint, timeout); 290 doneConnect(); 291 } 292 293 @Override 294 public String[] getSupportedCipherSuites() { 295 return CipherSuite.namesOf(sslContext.getSupportedCipherSuites()); 296 } 297 298 @Override 299 public String[] getEnabledCipherSuites() { 300 socketLock.lock(); 301 try { 302 return CipherSuite.namesOf( 303 conContext.sslConfig.enabledCipherSuites); 304 } finally { 305 socketLock.unlock(); 306 } 307 } 308 309 @Override 310 public void setEnabledCipherSuites(String[] suites) { 311 socketLock.lock(); 312 try { 313 conContext.sslConfig.enabledCipherSuites = 314 CipherSuite.validValuesOf(suites); 315 } finally { 316 socketLock.unlock(); 317 } 318 } 319 320 @Override 321 public String[] getSupportedProtocols() { 322 return ProtocolVersion.toStringArray( 323 sslContext.getSupportedProtocolVersions()); 324 } 325 326 @Override 327 public String[] getEnabledProtocols() { 328 socketLock.lock(); 329 try { 330 return ProtocolVersion.toStringArray( 331 conContext.sslConfig.enabledProtocols); 332 } finally { 333 socketLock.unlock(); 334 } 335 } 336 337 @Override 338 public void setEnabledProtocols(String[] protocols) { 339 if (protocols == null) { 340 throw new IllegalArgumentException("Protocols cannot be null"); 341 } 342 343 socketLock.lock(); 344 try { 345 conContext.sslConfig.enabledProtocols = 346 ProtocolVersion.namesOf(protocols); 347 } finally { 348 socketLock.unlock(); 349 } 350 } 351 352 @Override 353 public SSLSession getSession() { 354 try { 355 // start handshaking, if failed, the connection will be closed. 356 ensureNegotiated(); 357 } catch (IOException ioe) { 358 if (SSLLogger.isOn && SSLLogger.isOn("handshake")) { 359 SSLLogger.severe("handshake failed", ioe); 360 } 361 362 return SSLSessionImpl.nullSession; 363 } 364 365 return conContext.conSession; 366 } 367 368 @Override 369 public SSLSession getHandshakeSession() { 370 socketLock.lock(); 371 try { 372 return conContext.handshakeContext == null ? 373 null : conContext.handshakeContext.handshakeSession; 374 } finally { 375 socketLock.unlock(); 376 } 377 } 378 379 @Override 380 public void addHandshakeCompletedListener( 381 HandshakeCompletedListener listener) { 382 if (listener == null) { 383 throw new IllegalArgumentException("listener is null"); 384 } 385 386 socketLock.lock(); 387 try { 388 conContext.sslConfig.addHandshakeCompletedListener(listener); 389 } finally { 390 socketLock.unlock(); 391 } 392 } 393 394 @Override 395 public void removeHandshakeCompletedListener( 396 HandshakeCompletedListener listener) { 397 if (listener == null) { 398 throw new IllegalArgumentException("listener is null"); 399 } 400 401 socketLock.lock(); 402 try { 403 conContext.sslConfig.removeHandshakeCompletedListener(listener); 404 } finally { 405 socketLock.unlock(); 406 } 407 } 408 409 @Override 410 public void startHandshake() throws IOException { 411 if (!isConnected) { 412 throw new SocketException("Socket is not connected"); 413 } 414 415 if (conContext.isBroken || conContext.isInboundClosed() || 416 conContext.isOutboundClosed()) { 417 throw new SocketException("Socket has been closed or broken"); 418 } 419 420 handshakeLock.lock(); 421 try { 422 // double check the context status 423 if (conContext.isBroken || conContext.isInboundClosed() || 424 conContext.isOutboundClosed()) { 425 throw new SocketException("Socket has been closed or broken"); 426 } 427 428 try { 429 conContext.kickstart(); 430 431 // All initial handshaking goes through this operation until we 432 // have a valid SSL connection. 433 // 434 // Handle handshake messages only, need no application data. 435 if (!conContext.isNegotiated) { 436 readHandshakeRecord(); 437 } 438 } catch (IOException ioe) { 439 throw conContext.fatal(Alert.HANDSHAKE_FAILURE, 440 "Couldn't kickstart handshaking", ioe); 441 } catch (Exception oe) { // including RuntimeException 442 handleException(oe); 443 } 444 } finally { 445 handshakeLock.unlock(); 446 } 447 } 448 449 @Override 450 public void setUseClientMode(boolean mode) { 451 socketLock.lock(); 452 try { 453 conContext.setUseClientMode(mode); 454 } finally { 455 socketLock.unlock(); 456 } 457 } 458 459 @Override 460 public boolean getUseClientMode() { 461 socketLock.lock(); 462 try { 463 return conContext.sslConfig.isClientMode; 464 } finally { 465 socketLock.unlock(); 466 } 467 } 468 469 @Override 470 public void setNeedClientAuth(boolean need) { 471 socketLock.lock(); 472 try { 473 conContext.sslConfig.clientAuthType = 474 (need ? ClientAuthType.CLIENT_AUTH_REQUIRED : 475 ClientAuthType.CLIENT_AUTH_NONE); 476 } finally { 477 socketLock.unlock(); 478 } 479 } 480 481 @Override 482 public boolean getNeedClientAuth() { 483 socketLock.lock(); 484 try { 485 return (conContext.sslConfig.clientAuthType == 486 ClientAuthType.CLIENT_AUTH_REQUIRED); 487 } finally { 488 socketLock.unlock(); 489 } 490 } 491 492 @Override 493 public void setWantClientAuth(boolean want) { 494 socketLock.lock(); 495 try { 496 conContext.sslConfig.clientAuthType = 497 (want ? ClientAuthType.CLIENT_AUTH_REQUESTED : 498 ClientAuthType.CLIENT_AUTH_NONE); 499 } finally { 500 socketLock.unlock(); 501 } 502 } 503 504 @Override 505 public boolean getWantClientAuth() { 506 socketLock.lock(); 507 try { 508 return (conContext.sslConfig.clientAuthType == 509 ClientAuthType.CLIENT_AUTH_REQUESTED); 510 } finally { 511 socketLock.unlock(); 512 } 513 } 514 515 @Override 516 public void setEnableSessionCreation(boolean flag) { 517 socketLock.lock(); 518 try { 519 conContext.sslConfig.enableSessionCreation = flag; 520 } finally { 521 socketLock.unlock(); 522 } 523 } 524 525 @Override 526 public boolean getEnableSessionCreation() { 527 socketLock.lock(); 528 try { 529 return conContext.sslConfig.enableSessionCreation; 530 } finally { 531 socketLock.unlock(); 532 } 533 } 534 535 @Override 536 public boolean isClosed() { 537 return tlsIsClosed; 538 } 539 540 // Please don't synchronized this method. Otherwise, the read and close 541 // locks may be deadlocked. 542 @Override 543 public void close() throws IOException { 544 if (tlsIsClosed) { 545 return; 546 } 547 548 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 549 SSLLogger.fine("duplex close of SSLSocket"); 550 } 551 552 try { 553 // shutdown output bound, which may have been closed previously. 554 if (!isOutputShutdown()) { 555 duplexCloseOutput(); 556 } 557 558 // shutdown input bound, which may have been closed previously. 559 if (!isInputShutdown()) { 560 duplexCloseInput(); 561 } 562 563 if (!isClosed()) { 564 // close the connection directly 565 closeSocket(false); 566 } 567 } catch (IOException ioe) { 568 // ignore the exception 569 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 570 SSLLogger.warning("SSLSocket duplex close failed", ioe); 571 } 572 } finally { 573 tlsIsClosed = true; 574 } 575 } 576 577 /** 578 * Duplex close, start from closing outbound. 579 * 580 * For TLS 1.2 [RFC 5246], unless some other fatal alert has been 581 * transmitted, each party is required to send a close_notify alert 582 * before closing the write side of the connection. The other party 583 * MUST respond with a close_notify alert of its own and close down 584 * the connection immediately, discarding any pending writes. It is 585 * not required for the initiator of the close to wait for the responding 586 * close_notify alert before closing the read side of the connection. 587 * 588 * For TLS 1.3, Each party MUST send a close_notify alert before 589 * closing its write side of the connection, unless it has already sent 590 * some error alert. This does not have any effect on its read side of 591 * the connection. Both parties need not wait to receive a close_notify 592 * alert before closing their read side of the connection, though doing 593 * so would introduce the possibility of truncation. 594 * 595 * In order to support user initiated duplex-close for TLS 1.3 connections, 596 * the user_canceled alert is used together with the close_notify alert. 597 */ 598 private void duplexCloseOutput() throws IOException { 599 boolean useUserCanceled = false; 600 boolean hasCloseReceipt = false; 601 if (conContext.isNegotiated) { 602 if (!conContext.protocolVersion.useTLS13PlusSpec()) { 603 hasCloseReceipt = true; 604 } else { 605 // Use a user_canceled alert for TLS 1.3 duplex close. 606 useUserCanceled = true; 607 } 608 } else if (conContext.handshakeContext != null) { // initial handshake 609 // Use user_canceled alert regardless the protocol versions. 610 useUserCanceled = true; 611 612 // The protocol version may have been negotiated. 613 ProtocolVersion pv = conContext.handshakeContext.negotiatedProtocol; 614 if (pv == null || (!pv.useTLS13PlusSpec())) { 615 hasCloseReceipt = true; 616 } 617 } 618 619 // Need a lock here so that the user_canceled alert and the 620 // close_notify alert can be delivered together. 621 conContext.outputRecord.recordLock.lock(); 622 try { 623 try { 624 // send a user_canceled alert if needed. 625 if (useUserCanceled) { 626 conContext.warning(Alert.USER_CANCELED); 627 } 628 629 // send a close_notify alert 630 conContext.warning(Alert.CLOSE_NOTIFY); 631 } finally { 632 if (!conContext.isOutboundClosed()) { 633 conContext.outputRecord.close(); 634 } 635 636 if ((autoClose || !isLayered()) && !super.isOutputShutdown()) { 637 super.shutdownOutput(); 638 } 639 } 640 } finally { 641 conContext.outputRecord.recordLock.unlock(); 642 } 643 644 if (!isInputShutdown()) { 645 bruteForceCloseInput(hasCloseReceipt); 646 } 647 } 648 649 /** 650 * Duplex close, start from closing inbound. 651 * 652 * This method should only be called when the outbound has been closed, 653 * but the inbound is still open. 654 */ 655 private void duplexCloseInput() throws IOException { 656 boolean hasCloseReceipt = false; 657 if (conContext.isNegotiated && 658 !conContext.protocolVersion.useTLS13PlusSpec()) { 659 hasCloseReceipt = true; 660 } // No close receipt if handshake has no completed. 661 662 bruteForceCloseInput(hasCloseReceipt); 663 } 664 665 /** 666 * Brute force close the input bound. 667 * 668 * This method should only be called when the outbound has been closed, 669 * but the inbound is still open. 670 */ 671 private void bruteForceCloseInput( 672 boolean hasCloseReceipt) throws IOException { 673 if (hasCloseReceipt) { 674 // It is not required for the initiator of the close to wait for 675 // the responding close_notify alert before closing the read side 676 // of the connection. However, if the application protocol using 677 // TLS provides that any data may be carried over the underlying 678 // transport after the TLS connection is closed, the TLS 679 // implementation MUST receive a "close_notify" alert before 680 // indicating end-of-data to the application-layer. 681 try { 682 this.shutdown(); 683 } finally { 684 if (!isInputShutdown()) { 685 shutdownInput(false); 686 } 687 } 688 } else { 689 if (!conContext.isInboundClosed()) { 690 try (conContext.inputRecord) { 691 // Try the best to use up the input records and close the 692 // socket gracefully, without impact the performance too 693 // much. 694 appInput.deplete(); 695 } 696 } 697 698 if ((autoClose || !isLayered()) && !super.isInputShutdown()) { 699 super.shutdownInput(); 700 } 701 } 702 } 703 704 // Please don't synchronized this method. Otherwise, the read and close 705 // locks may be deadlocked. 706 @Override 707 public void shutdownInput() throws IOException { 708 shutdownInput(true); 709 } 710 711 // It is not required to check the close_notify receipt unless an 712 // application call shutdownInput() explicitly. 713 private void shutdownInput( 714 boolean checkCloseNotify) throws IOException { 715 if (isInputShutdown()) { 716 return; 717 } 718 719 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 720 SSLLogger.fine("close inbound of SSLSocket"); 721 } 722 723 // Is it ready to close inbound? 724 // 725 // No need to throw exception if the initial handshake is not started. 726 if (checkCloseNotify && !conContext.isInputCloseNotified && 727 (conContext.isNegotiated || conContext.handshakeContext != null)) { 728 729 throw conContext.fatal(Alert.INTERNAL_ERROR, 730 "closing inbound before receiving peer's close_notify"); 731 } 732 733 conContext.closeInbound(); 734 if ((autoClose || !isLayered()) && !super.isInputShutdown()) { 735 super.shutdownInput(); 736 } 737 } 738 739 @Override 740 public boolean isInputShutdown() { 741 return conContext.isInboundClosed() && 742 ((autoClose || !isLayered()) ? super.isInputShutdown(): true); 743 } 744 745 // Please don't synchronized this method. Otherwise, the read and close 746 // locks may be deadlocked. 747 @Override 748 public void shutdownOutput() throws IOException { 749 if (isOutputShutdown()) { 750 return; 751 } 752 753 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 754 SSLLogger.fine("close outbound of SSLSocket"); 755 } 756 conContext.closeOutbound(); 757 758 if ((autoClose || !isLayered()) && !super.isOutputShutdown()) { 759 super.shutdownOutput(); 760 } 761 } 762 763 @Override 764 public boolean isOutputShutdown() { 765 return conContext.isOutboundClosed() && 766 ((autoClose || !isLayered()) ? super.isOutputShutdown(): true); 767 } 768 769 @Override 770 public InputStream getInputStream() throws IOException { 771 socketLock.lock(); 772 try { 773 if (isClosed()) { 774 throw new SocketException("Socket is closed"); 775 } 776 777 if (!isConnected) { 778 throw new SocketException("Socket is not connected"); 779 } 780 781 if (conContext.isInboundClosed() || isInputShutdown()) { 782 throw new SocketException("Socket input is already shutdown"); 783 } 784 785 return appInput; 786 } finally { 787 socketLock.unlock(); 788 } 789 } 790 791 private void ensureNegotiated() throws IOException { 792 if (conContext.isNegotiated || conContext.isBroken || 793 conContext.isInboundClosed() || conContext.isOutboundClosed()) { 794 return; 795 } 796 797 handshakeLock.lock(); 798 try { 799 // double check the context status 800 if (conContext.isNegotiated || conContext.isBroken || 801 conContext.isInboundClosed() || 802 conContext.isOutboundClosed()) { 803 return; 804 } 805 806 startHandshake(); 807 } finally { 808 handshakeLock.unlock(); 809 } 810 } 811 812 /** 813 * InputStream for application data as returned by 814 * SSLSocket.getInputStream(). 815 */ 816 private class AppInputStream extends InputStream { 817 // One element array used to implement the single byte read() method 818 private final byte[] oneByte = new byte[1]; 819 820 // the temporary buffer used to read network 821 private ByteBuffer buffer; 822 823 // Is application data available in the stream? 824 private volatile boolean appDataIsAvailable; 825 826 // reading lock 827 private final ReentrantLock readLock = new ReentrantLock(); 828 829 AppInputStream() { 830 this.appDataIsAvailable = false; 831 this.buffer = ByteBuffer.allocate(4096); 832 } 833 834 /** 835 * Return the minimum number of bytes that can be read 836 * without blocking. 837 */ 838 @Override 839 public int available() throws IOException { 840 // Currently not synchronized. 841 if ((!appDataIsAvailable) || checkEOF()) { 842 return 0; 843 } 844 845 return buffer.remaining(); 846 } 847 848 /** 849 * Read a single byte, returning -1 on non-fault EOF status. 850 */ 851 @Override 852 public int read() throws IOException { 853 int n = read(oneByte, 0, 1); 854 if (n <= 0) { // EOF 855 return -1; 856 } 857 858 return oneByte[0] & 0xFF; 859 } 860 861 /** 862 * Reads up to {@code len} bytes of data from the input stream 863 * into an array of bytes. 864 * 865 * An attempt is made to read as many as {@code len} bytes, but a 866 * smaller number may be read. The number of bytes actually read 867 * is returned as an integer. 868 * 869 * If the layer above needs more data, it asks for more, so we 870 * are responsible only for blocking to fill at most one buffer, 871 * and returning "-1" on non-fault EOF status. 872 */ 873 @Override 874 public int read(byte[] b, int off, int len) 875 throws IOException { 876 if (b == null) { 877 throw new NullPointerException("the target buffer is null"); 878 } else if (off < 0 || len < 0 || len > b.length - off) { 879 throw new IndexOutOfBoundsException( 880 "buffer length: " + b.length + ", offset; " + off + 881 ", bytes to read:" + len); 882 } else if (len == 0) { 883 return 0; 884 } 885 886 if (checkEOF()) { 887 return -1; 888 } 889 890 // start handshaking if the connection has not been negotiated. 891 if (!conContext.isNegotiated && !conContext.isBroken && 892 !conContext.isInboundClosed() && 893 !conContext.isOutboundClosed()) { 894 ensureNegotiated(); 895 } 896 897 // Check if the Socket is invalid (error or closed). 898 if (!conContext.isNegotiated || 899 conContext.isBroken || conContext.isInboundClosed()) { 900 throw new SocketException("Connection or inbound has closed"); 901 } 902 903 // Read the available bytes at first. 904 // 905 // Note that the receiving and processing of post-handshake message 906 // are also synchronized with the read lock. 907 readLock.lock(); 908 try { 909 int remains = available(); 910 if (remains > 0) { 911 int howmany = Math.min(remains, len); 912 buffer.get(b, off, howmany); 913 914 return howmany; 915 } 916 917 appDataIsAvailable = false; 918 try { 919 ByteBuffer bb = readApplicationRecord(buffer); 920 if (bb == null) { // EOF 921 return -1; 922 } else { 923 // The buffer may be reallocated for bigger capacity. 924 buffer = bb; 925 } 926 927 bb.flip(); 928 int volume = Math.min(len, bb.remaining()); 929 buffer.get(b, off, volume); 930 appDataIsAvailable = true; 931 932 return volume; 933 } catch (Exception e) { // including RuntimeException 934 // shutdown and rethrow (wrapped) exception as appropriate 935 handleException(e); 936 937 // dummy for compiler 938 return -1; 939 } 940 } finally { 941 readLock.unlock(); 942 } 943 } 944 945 /** 946 * Skip n bytes. 947 * 948 * This implementation is somewhat less efficient than possible, but 949 * not badly so (redundant copy). We reuse the read() code to keep 950 * things simpler. 951 */ 952 @Override 953 public long skip(long n) throws IOException { 954 // dummy array used to implement skip() 955 byte[] skipArray = new byte[256]; 956 long skipped = 0; 957 958 readLock.lock(); 959 try { 960 while (n > 0) { 961 int len = (int)Math.min(n, skipArray.length); 962 int r = read(skipArray, 0, len); 963 if (r <= 0) { 964 break; 965 } 966 n -= r; 967 skipped += r; 968 } 969 } finally { 970 readLock.unlock(); 971 } 972 973 return skipped; 974 } 975 976 @Override 977 public void close() throws IOException { 978 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 979 SSLLogger.finest("Closing input stream"); 980 } 981 982 try { 983 SSLSocketImpl.this.close(); 984 } catch (IOException ioe) { 985 // ignore the exception 986 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 987 SSLLogger.warning("input stream close failed", ioe); 988 } 989 } 990 } 991 992 /** 993 * Return whether we have reached end-of-file. 994 * 995 * If the socket is not connected, has been shutdown because of an error 996 * or has been closed, throw an Exception. 997 */ 998 private boolean checkEOF() throws IOException { 999 if (conContext.isInboundClosed()) { 1000 return true; 1001 } else if (conContext.isInputCloseNotified || conContext.isBroken) { 1002 if (conContext.closeReason == null) { 1003 return true; 1004 } else { 1005 throw new SSLException( 1006 "Connection has closed: " + conContext.closeReason, 1007 conContext.closeReason); 1008 } 1009 } 1010 1011 return false; 1012 } 1013 1014 /** 1015 * Try the best to use up the input records so as to close the 1016 * socket gracefully, without impact the performance too much. 1017 */ 1018 private void deplete() { 1019 if (conContext.isInboundClosed()) { 1020 return; 1021 } 1022 1023 readLock.lock(); 1024 try { 1025 // double check 1026 if (conContext.isInboundClosed()) { 1027 return; 1028 } 1029 1030 if (!(conContext.inputRecord instanceof SSLSocketInputRecord)) { 1031 return; 1032 } 1033 1034 SSLSocketInputRecord socketInputRecord = 1035 (SSLSocketInputRecord)conContext.inputRecord; 1036 try { 1037 socketInputRecord.deplete( 1038 conContext.isNegotiated && (getSoTimeout() > 0)); 1039 } catch (IOException ioe) { 1040 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1041 SSLLogger.warning( 1042 "input stream close depletion failed", ioe); 1043 } 1044 } 1045 } finally { 1046 readLock.unlock(); 1047 } 1048 } 1049 } 1050 1051 @Override 1052 public OutputStream getOutputStream() throws IOException { 1053 socketLock.lock(); 1054 try { 1055 if (isClosed()) { 1056 throw new SocketException("Socket is closed"); 1057 } 1058 1059 if (!isConnected) { 1060 throw new SocketException("Socket is not connected"); 1061 } 1062 1063 if (conContext.isOutboundDone() || isOutputShutdown()) { 1064 throw new SocketException("Socket output is already shutdown"); 1065 } 1066 1067 return appOutput; 1068 } finally { 1069 socketLock.unlock(); 1070 } 1071 } 1072 1073 1074 /** 1075 * OutputStream for application data as returned by 1076 * SSLSocket.getOutputStream(). 1077 */ 1078 private class AppOutputStream extends OutputStream { 1079 // One element array used to implement the write(byte) method 1080 private final byte[] oneByte = new byte[1]; 1081 1082 @Override 1083 public void write(int i) throws IOException { 1084 oneByte[0] = (byte)i; 1085 write(oneByte, 0, 1); 1086 } 1087 1088 @Override 1089 public void write(byte[] b, 1090 int off, int len) throws IOException { 1091 if (b == null) { 1092 throw new NullPointerException("the source buffer is null"); 1093 } else if (off < 0 || len < 0 || len > b.length - off) { 1094 throw new IndexOutOfBoundsException( 1095 "buffer length: " + b.length + ", offset; " + off + 1096 ", bytes to read:" + len); 1097 } else if (len == 0) { 1098 // 1099 // Don't bother to really write empty records. We went this 1100 // far to drive the handshake machinery, for correctness; not 1101 // writing empty records improves performance by cutting CPU 1102 // time and network resource usage. However, some protocol 1103 // implementations are fragile and don't like to see empty 1104 // records, so this also increases robustness. 1105 // 1106 return; 1107 } 1108 1109 // Start handshaking if the connection has not been negotiated. 1110 if (!conContext.isNegotiated && !conContext.isBroken && 1111 !conContext.isInboundClosed() && 1112 !conContext.isOutboundClosed()) { 1113 ensureNegotiated(); 1114 } 1115 1116 // Check if the Socket is invalid (error or closed). 1117 if (!conContext.isNegotiated || 1118 conContext.isBroken || conContext.isOutboundClosed()) { 1119 throw new SocketException("Connection or outbound has closed"); 1120 } 1121 1122 // 1123 1124 // Delegate the writing to the underlying socket. 1125 try { 1126 conContext.outputRecord.deliver(b, off, len); 1127 } catch (SSLHandshakeException she) { 1128 // may be record sequence number overflow 1129 throw conContext.fatal(Alert.HANDSHAKE_FAILURE, she); 1130 } catch (IOException e) { 1131 throw conContext.fatal(Alert.UNEXPECTED_MESSAGE, e); 1132 } 1133 1134 // Is the sequence number is nearly overflow, or has the key usage 1135 // limit been reached? 1136 if (conContext.outputRecord.seqNumIsHuge() || 1137 conContext.outputRecord.writeCipher.atKeyLimit()) { 1138 tryKeyUpdate(); 1139 } 1140 } 1141 1142 @Override 1143 public void close() throws IOException { 1144 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1145 SSLLogger.finest("Closing output stream"); 1146 } 1147 1148 try { 1149 SSLSocketImpl.this.close(); 1150 } catch (IOException ioe) { 1151 // ignore the exception 1152 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1153 SSLLogger.warning("output stream close failed", ioe); 1154 } 1155 } 1156 } 1157 } 1158 1159 @Override 1160 public SSLParameters getSSLParameters() { 1161 socketLock.lock(); 1162 try { 1163 return conContext.sslConfig.getSSLParameters(); 1164 } finally { 1165 socketLock.unlock(); 1166 } 1167 } 1168 1169 @Override 1170 public void setSSLParameters(SSLParameters params) { 1171 socketLock.lock(); 1172 try { 1173 conContext.sslConfig.setSSLParameters(params); 1174 1175 if (conContext.sslConfig.maximumPacketSize != 0) { 1176 conContext.outputRecord.changePacketSize( 1177 conContext.sslConfig.maximumPacketSize); 1178 } 1179 } finally { 1180 socketLock.unlock(); 1181 } 1182 } 1183 1184 @Override 1185 public String getApplicationProtocol() { 1186 socketLock.lock(); 1187 try { 1188 return conContext.applicationProtocol; 1189 } finally { 1190 socketLock.unlock(); 1191 } 1192 } 1193 1194 @Override 1195 public String getHandshakeApplicationProtocol() { 1196 socketLock.lock(); 1197 try { 1198 if (conContext.handshakeContext != null) { 1199 return conContext.handshakeContext.applicationProtocol; 1200 } 1201 } finally { 1202 socketLock.unlock(); 1203 } 1204 1205 return null; 1206 } 1207 1208 @Override 1209 public void setHandshakeApplicationProtocolSelector( 1210 BiFunction<SSLSocket, List<String>, String> selector) { 1211 socketLock.lock(); 1212 try { 1213 conContext.sslConfig.socketAPSelector = selector; 1214 } finally { 1215 socketLock.unlock(); 1216 } 1217 } 1218 1219 @Override 1220 public BiFunction<SSLSocket, List<String>, String> 1221 getHandshakeApplicationProtocolSelector() { 1222 socketLock.lock(); 1223 try { 1224 return conContext.sslConfig.socketAPSelector; 1225 } finally { 1226 socketLock.unlock(); 1227 } 1228 } 1229 1230 /** 1231 * Read the initial handshake records. 1232 */ 1233 private int readHandshakeRecord() throws IOException { 1234 while (!conContext.isInboundClosed()) { 1235 try { 1236 Plaintext plainText = decode(null); 1237 if ((plainText.contentType == ContentType.HANDSHAKE.id) && 1238 conContext.isNegotiated) { 1239 return 0; 1240 } 1241 } catch (SSLException ssle) { 1242 throw ssle; 1243 } catch (IOException ioe) { 1244 if (!(ioe instanceof SSLException)) { 1245 throw new SSLException("readHandshakeRecord", ioe); 1246 } else { 1247 throw ioe; 1248 } 1249 } 1250 } 1251 1252 return -1; 1253 } 1254 1255 /** 1256 * Read application data record. Used by AppInputStream only, but defined 1257 * here so as to use the socket level synchronization. 1258 * 1259 * Note that the connection guarantees that handshake, alert, and change 1260 * cipher spec data streams are handled as they arrive, so we never see 1261 * them here. 1262 * 1263 * Note: Please be careful about the synchronization, and don't use this 1264 * method other than in the AppInputStream class! 1265 */ 1266 private ByteBuffer readApplicationRecord( 1267 ByteBuffer buffer) throws IOException { 1268 while (!conContext.isInboundClosed()) { 1269 /* 1270 * clean the buffer and check if it is too small, e.g. because 1271 * the AppInputStream did not have the chance to see the 1272 * current packet length but rather something like that of the 1273 * handshake before. In that case we return 0 at this point to 1274 * give the caller the chance to adjust the buffer. 1275 */ 1276 buffer.clear(); 1277 int inLen = conContext.inputRecord.bytesInCompletePacket(); 1278 if (inLen < 0) { // EOF 1279 handleEOF(null); 1280 1281 // if no exception thrown 1282 return null; 1283 } 1284 1285 // Is this packet bigger than SSL/TLS normally allows? 1286 if (inLen > SSLRecord.maxLargeRecordSize) { 1287 throw new SSLProtocolException( 1288 "Illegal packet size: " + inLen); 1289 } 1290 1291 if (inLen > buffer.remaining()) { 1292 buffer = ByteBuffer.allocate(inLen); 1293 } 1294 1295 try { 1296 Plaintext plainText; 1297 socketLock.lock(); 1298 try { 1299 plainText = decode(buffer); 1300 } finally { 1301 socketLock.unlock(); 1302 } 1303 if (plainText.contentType == ContentType.APPLICATION_DATA.id && 1304 buffer.position() > 0) { 1305 return buffer; 1306 } 1307 } catch (SSLException ssle) { 1308 throw ssle; 1309 } catch (IOException ioe) { 1310 if (!(ioe instanceof SSLException)) { 1311 throw new SSLException("readApplicationRecord", ioe); 1312 } else { 1313 throw ioe; 1314 } 1315 } 1316 } 1317 1318 // 1319 // couldn't read, due to some kind of error 1320 // 1321 return null; 1322 } 1323 1324 private Plaintext decode(ByteBuffer destination) throws IOException { 1325 Plaintext plainText; 1326 try { 1327 if (destination == null) { 1328 plainText = SSLTransport.decode(conContext, 1329 null, 0, 0, null, 0, 0); 1330 } else { 1331 plainText = SSLTransport.decode(conContext, 1332 null, 0, 0, new ByteBuffer[]{destination}, 0, 1); 1333 } 1334 } catch (EOFException eofe) { 1335 // EOFException is special as it is related to close_notify. 1336 plainText = handleEOF(eofe); 1337 } 1338 1339 // Is the sequence number is nearly overflow? 1340 if (plainText != Plaintext.PLAINTEXT_NULL && 1341 (conContext.inputRecord.seqNumIsHuge() || 1342 conContext.inputRecord.readCipher.atKeyLimit())) { 1343 tryKeyUpdate(); 1344 } 1345 1346 return plainText; 1347 } 1348 1349 /** 1350 * Try key update for sequence number wrap or key usage limit. 1351 * 1352 * Note that in order to maintain the handshake status properly, we check 1353 * the sequence number and key usage limit after the last record 1354 * reading/writing process. 1355 * 1356 * As we request renegotiation or close the connection for wrapped sequence 1357 * number when there is enough sequence number space left to handle a few 1358 * more records, so the sequence number of the last record cannot be 1359 * wrapped. 1360 */ 1361 private void tryKeyUpdate() throws IOException { 1362 // Don't bother to kickstart if handshaking is in progress, or if the 1363 // connection is not duplex-open. 1364 if ((conContext.handshakeContext == null) && 1365 !conContext.isOutboundClosed() && 1366 !conContext.isInboundClosed() && 1367 !conContext.isBroken) { 1368 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1369 SSLLogger.finest("trigger key update"); 1370 } 1371 startHandshake(); 1372 } 1373 } 1374 1375 /** 1376 * Initialize the handshaker and socket streams. 1377 * 1378 * Called by connect, the layered constructor, and SSLServerSocket. 1379 */ 1380 void doneConnect() throws IOException { 1381 socketLock.lock(); 1382 try { 1383 // In server mode, it is not necessary to set host and serverNames. 1384 // Otherwise, would require a reverse DNS lookup to get 1385 // the hostname. 1386 if (peerHost == null || peerHost.isEmpty()) { 1387 boolean useNameService = 1388 trustNameService && conContext.sslConfig.isClientMode; 1389 useImplicitHost(useNameService); 1390 } else { 1391 conContext.sslConfig.serverNames = 1392 Utilities.addToSNIServerNameList( 1393 conContext.sslConfig.serverNames, peerHost); 1394 } 1395 1396 InputStream sockInput = super.getInputStream(); 1397 conContext.inputRecord.setReceiverStream(sockInput); 1398 1399 OutputStream sockOutput = super.getOutputStream(); 1400 conContext.inputRecord.setDeliverStream(sockOutput); 1401 conContext.outputRecord.setDeliverStream(sockOutput); 1402 1403 this.isConnected = true; 1404 } finally { 1405 socketLock.unlock(); 1406 } 1407 } 1408 1409 private void useImplicitHost(boolean useNameService) { 1410 // Note: If the local name service is not trustworthy, reverse 1411 // host name resolution should not be performed for endpoint 1412 // identification. Use the application original specified 1413 // hostname or IP address instead. 1414 1415 // Get the original hostname via jdk.internal.misc.SharedSecrets 1416 InetAddress inetAddress = getInetAddress(); 1417 if (inetAddress == null) { // not connected 1418 return; 1419 } 1420 1421 JavaNetInetAddressAccess jna = 1422 SharedSecrets.getJavaNetInetAddressAccess(); 1423 String originalHostname = jna.getOriginalHostName(inetAddress); 1424 if (originalHostname != null && !originalHostname.isEmpty()) { 1425 1426 this.peerHost = originalHostname; 1427 if (conContext.sslConfig.serverNames.isEmpty() && 1428 !conContext.sslConfig.noSniExtension) { 1429 conContext.sslConfig.serverNames = 1430 Utilities.addToSNIServerNameList( 1431 conContext.sslConfig.serverNames, peerHost); 1432 } 1433 1434 return; 1435 } 1436 1437 // No explicitly specified hostname, no server name indication. 1438 if (!useNameService) { 1439 // The local name service is not trustworthy, use IP address. 1440 this.peerHost = inetAddress.getHostAddress(); 1441 } else { 1442 // Use the underlying reverse host name resolution service. 1443 this.peerHost = getInetAddress().getHostName(); 1444 } 1445 } 1446 1447 // ONLY used by HttpsClient to setup the URI specified hostname 1448 // 1449 // Please NOTE that this method MUST be called before calling to 1450 // SSLSocket.setSSLParameters(). Otherwise, the {@code host} parameter 1451 // may override SNIHostName in the customized server name indication. 1452 public void setHost(String host) { 1453 socketLock.lock(); 1454 try { 1455 this.peerHost = host; 1456 this.conContext.sslConfig.serverNames = 1457 Utilities.addToSNIServerNameList( 1458 conContext.sslConfig.serverNames, host); 1459 } finally { 1460 socketLock.unlock(); 1461 } 1462 } 1463 1464 /** 1465 * Handle an exception. 1466 * 1467 * This method is called by top level exception handlers (in read(), 1468 * write()) to make sure we always shutdown the connection correctly 1469 * and do not pass runtime exception to the application. 1470 * 1471 * This method never returns normally, it always throws an IOException. 1472 */ 1473 private void handleException(Exception cause) throws IOException { 1474 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1475 SSLLogger.warning("handling exception", cause); 1476 } 1477 1478 // Don't close the Socket in case of timeouts or interrupts. 1479 if (cause instanceof InterruptedIOException) { 1480 throw (IOException)cause; 1481 } 1482 1483 // need to perform error shutdown 1484 boolean isSSLException = (cause instanceof SSLException); 1485 Alert alert; 1486 if (isSSLException) { 1487 if (cause instanceof SSLHandshakeException) { 1488 alert = Alert.HANDSHAKE_FAILURE; 1489 } else { 1490 alert = Alert.UNEXPECTED_MESSAGE; 1491 } 1492 } else { 1493 if (cause instanceof IOException) { 1494 alert = Alert.UNEXPECTED_MESSAGE; 1495 } else { 1496 // RuntimeException 1497 alert = Alert.INTERNAL_ERROR; 1498 } 1499 } 1500 1501 throw conContext.fatal(alert, cause); 1502 } 1503 1504 private Plaintext handleEOF(EOFException eofe) throws IOException { 1505 if (requireCloseNotify || conContext.handshakeContext != null) { 1506 SSLException ssle; 1507 if (conContext.handshakeContext != null) { 1508 ssle = new SSLHandshakeException( 1509 "Remote host terminated the handshake"); 1510 } else { 1511 ssle = new SSLProtocolException( 1512 "Remote host terminated the connection"); 1513 } 1514 1515 if (eofe != null) { 1516 ssle.initCause(eofe); 1517 } 1518 throw ssle; 1519 } else { 1520 // treat as if we had received a close_notify 1521 conContext.isInputCloseNotified = true; 1522 shutdownInput(); 1523 1524 return Plaintext.PLAINTEXT_NULL; 1525 } 1526 } 1527 1528 1529 @Override 1530 public String getPeerHost() { 1531 return peerHost; 1532 } 1533 1534 @Override 1535 public int getPeerPort() { 1536 return getPort(); 1537 } 1538 1539 @Override 1540 public boolean useDelegatedTask() { 1541 return false; 1542 } 1543 1544 @Override 1545 public void shutdown() throws IOException { 1546 if (!isClosed()) { 1547 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1548 SSLLogger.fine("close the underlying socket"); 1549 } 1550 1551 try { 1552 if (conContext.isInputCloseNotified) { 1553 // Close the connection, no wait for more peer response. 1554 closeSocket(false); 1555 } else { 1556 // Close the connection, may wait for peer close_notify. 1557 closeSocket(true); 1558 } 1559 } finally { 1560 tlsIsClosed = true; 1561 } 1562 } 1563 } 1564 1565 private void closeSocket(boolean selfInitiated) throws IOException { 1566 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1567 SSLLogger.fine("close the SSL connection " + 1568 (selfInitiated ? "(initiative)" : "(passive)")); 1569 } 1570 1571 if (autoClose || !isLayered()) { 1572 super.close(); 1573 } else if (selfInitiated) { 1574 if (!conContext.isInboundClosed() && !isInputShutdown()) { 1575 // wait for close_notify alert to clear input stream. 1576 waitForClose(); 1577 } 1578 } 1579 } 1580 1581 /** 1582 * Wait for close_notify alert for a graceful closure. 1583 * 1584 * [RFC 5246] If the application protocol using TLS provides that any 1585 * data may be carried over the underlying transport after the TLS 1586 * connection is closed, the TLS implementation must receive the responding 1587 * close_notify alert before indicating to the application layer that 1588 * the TLS connection has ended. If the application protocol will not 1589 * transfer any additional data, but will only close the underlying 1590 * transport connection, then the implementation MAY choose to close the 1591 * transport without waiting for the responding close_notify. 1592 */ 1593 private void waitForClose() throws IOException { 1594 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1595 SSLLogger.fine("wait for close_notify or alert"); 1596 } 1597 1598 while (!conContext.isInboundClosed()) { 1599 try { 1600 Plaintext plainText = decode(null); 1601 // discard and continue 1602 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1603 SSLLogger.finest( 1604 "discard plaintext while waiting for close", plainText); 1605 } 1606 } catch (Exception e) { // including RuntimeException 1607 handleException(e); 1608 } 1609 } 1610 } 1611 }