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