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