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 private void bruteForceCloseInput( 585 boolean hasCloseReceipt) throws IOException { 586 if (hasCloseReceipt) { 587 // It is not required for the initiator of the close to wait for 588 // the responding close_notify alert before closing the read side 589 // of the connection. However, if the application protocol using 590 // TLS provides that any data may be carried over the underlying 591 // transport after the TLS connection is closed, the TLS 592 // implementation MUST receive a "close_notify" alert before 593 // indicating end-of-data to the application-layer. 594 try { 595 this.shutdown(); 596 } finally { 597 if (!isInputShutdown()) { 598 shutdownInput(false); 599 } 600 } 601 } else { 602 if (!conContext.isInboundClosed()) { 603 conContext.inputRecord.close(); 604 } 605 606 if ((autoClose || !isLayered()) && !super.isInputShutdown()) { 607 super.shutdownInput(); 608 } 609 } 610 } 611 612 // Please don't synchronized this method. Otherwise, the read and close 613 // locks may be deadlocked. 614 @Override 615 public void shutdownInput() throws IOException { 616 shutdownInput(true); 617 } 618 619 // It is not required to check the close_notify receipt unless an 620 // application call shutdownInput() explicitly. 621 private void shutdownInput( 622 boolean checkCloseNotify) throws IOException { 623 if (isInputShutdown()) { 624 return; 625 } 626 627 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 628 SSLLogger.fine("close inbound of SSLSocket"); 629 } 630 631 // Is it ready to close inbound? 632 // 633 // No need to throw exception if the initial handshake is not started. 634 if (checkCloseNotify && !conContext.isInputCloseNotified && 635 (conContext.isNegotiated || conContext.handshakeContext != null)) { 636 637 throw conContext.fatal(Alert.INTERNAL_ERROR, 638 "closing inbound before receiving peer's close_notify"); 639 } 640 641 conContext.closeInbound(); 642 if ((autoClose || !isLayered()) && !super.isInputShutdown()) { 643 super.shutdownInput(); 644 } 645 } 646 647 @Override 648 public boolean isInputShutdown() { 649 return conContext.isInboundClosed() && 650 ((autoClose || !isLayered()) ? super.isInputShutdown(): true); 651 } 652 653 // Please don't synchronized this method. Otherwise, the read and close 654 // locks may be deadlocked. 655 @Override 656 public void shutdownOutput() throws IOException { 657 if (isOutputShutdown()) { 658 return; 659 } 660 661 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 662 SSLLogger.fine("close outbound of SSLSocket"); 663 } 664 conContext.closeOutbound(); 665 666 if ((autoClose || !isLayered()) && !super.isOutputShutdown()) { 667 super.shutdownOutput(); 668 } 669 } 670 671 @Override 672 public boolean isOutputShutdown() { 673 return conContext.isOutboundClosed() && 674 ((autoClose || !isLayered()) ? super.isOutputShutdown(): true); 675 } 676 677 @Override 678 public synchronized InputStream getInputStream() throws IOException { 679 if (isClosed()) { 680 throw new SocketException("Socket is closed"); 681 } 682 683 if (!isConnected) { 684 throw new SocketException("Socket is not connected"); 685 } 686 687 if (conContext.isInboundClosed() || isInputShutdown()) { 688 throw new SocketException("Socket input is already shutdown"); 689 } 690 691 return appInput; 692 } 693 694 private void ensureNegotiated() throws IOException { 695 if (conContext.isNegotiated || conContext.isBroken || 696 conContext.isInboundClosed() || conContext.isOutboundClosed()) { 697 return; 698 } 699 700 synchronized (conContext) { // handshake lock 701 // double check the context status 702 if (conContext.isNegotiated || conContext.isBroken || 703 conContext.isInboundClosed() || 704 conContext.isOutboundClosed()) { 705 return; 706 } 707 708 startHandshake(); 709 } 710 } 711 712 /** 713 * InputStream for application data as returned by 714 * SSLSocket.getInputStream(). 715 */ 716 private class AppInputStream extends InputStream { 717 // One element array used to implement the single byte read() method 718 private final byte[] oneByte = new byte[1]; 719 720 // the temporary buffer used to read network 721 private ByteBuffer buffer; 722 723 // Is application data available in the stream? 724 private volatile boolean appDataIsAvailable; 725 726 AppInputStream() { 727 this.appDataIsAvailable = false; 728 this.buffer = ByteBuffer.allocate(4096); 729 } 730 731 /** 732 * Return the minimum number of bytes that can be read 733 * without blocking. 734 */ 735 @Override 736 public int available() throws IOException { 737 // Currently not synchronized. 738 if ((!appDataIsAvailable) || checkEOF()) { 739 return 0; 740 } 741 742 return buffer.remaining(); 743 } 744 745 /** 746 * Read a single byte, returning -1 on non-fault EOF status. 747 */ 748 @Override 749 public int read() throws IOException { 750 int n = read(oneByte, 0, 1); 751 if (n <= 0) { // EOF 752 return -1; 753 } 754 755 return oneByte[0] & 0xFF; 756 } 757 758 /** 759 * Reads up to {@code len} bytes of data from the input stream 760 * into an array of bytes. 761 * 762 * An attempt is made to read as many as {@code len} bytes, but a 763 * smaller number may be read. The number of bytes actually read 764 * is returned as an integer. 765 * 766 * If the layer above needs more data, it asks for more, so we 767 * are responsible only for blocking to fill at most one buffer, 768 * and returning "-1" on non-fault EOF status. 769 */ 770 @Override 771 public int read(byte[] b, int off, int len) 772 throws IOException { 773 if (b == null) { 774 throw new NullPointerException("the target buffer is null"); 775 } else if (off < 0 || len < 0 || len > b.length - off) { 776 throw new IndexOutOfBoundsException( 777 "buffer length: " + b.length + ", offset; " + off + 778 ", bytes to read:" + len); 779 } else if (len == 0) { 780 return 0; 781 } 782 783 if (checkEOF()) { 784 return -1; 785 } 786 787 // start handshaking if the connection has not been negotiated. 788 if (!conContext.isNegotiated && !conContext.isBroken && 789 !conContext.isInboundClosed() && 790 !conContext.isOutboundClosed()) { 791 ensureNegotiated(); 792 } 793 794 // Check if the Socket is invalid (error or closed). 795 if (!conContext.isNegotiated || 796 conContext.isBroken || conContext.isInboundClosed()) { 797 throw new SocketException("Connection or inbound has closed"); 798 } 799 800 // Read the available bytes at first. 801 // 802 // Note that the receiving and processing of post-handshake message 803 // are also synchronized with the read lock. 804 synchronized (this) { 805 int remains = available(); 806 if (remains > 0) { 807 int howmany = Math.min(remains, len); 808 buffer.get(b, off, howmany); 809 810 return howmany; 811 } 812 813 appDataIsAvailable = false; 814 try { 815 ByteBuffer bb = readApplicationRecord(buffer); 816 if (bb == null) { // EOF 817 return -1; 818 } else { 819 // The buffer may be reallocated for bigger capacity. 820 buffer = bb; 821 } 822 823 bb.flip(); 824 int volume = Math.min(len, bb.remaining()); 825 buffer.get(b, off, volume); 826 appDataIsAvailable = true; 827 828 return volume; 829 } catch (Exception e) { // including RuntimeException 830 // shutdown and rethrow (wrapped) exception as appropriate 831 handleException(e); 832 833 // dummy for compiler 834 return -1; 835 } 836 } 837 } 838 839 /** 840 * Skip n bytes. 841 * 842 * This implementation is somewhat less efficient than possible, but 843 * not badly so (redundant copy). We reuse the read() code to keep 844 * things simpler. 845 */ 846 @Override 847 public synchronized long skip(long n) throws IOException { 848 // dummy array used to implement skip() 849 byte[] skipArray = new byte[256]; 850 851 long skipped = 0; 852 while (n > 0) { 853 int len = (int)Math.min(n, skipArray.length); 854 int r = read(skipArray, 0, len); 855 if (r <= 0) { 856 break; 857 } 858 n -= r; 859 skipped += r; 860 } 861 862 return skipped; 863 } 864 865 @Override 866 public void close() throws IOException { 867 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 868 SSLLogger.finest("Closing input stream"); 869 } 870 871 try { 872 SSLSocketImpl.this.close(); 873 } catch (IOException ioe) { 874 // ignore the exception 875 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 876 SSLLogger.warning("input stream close failed", ioe); 877 } 878 } 879 } 880 881 /** 882 * Return whether we have reached end-of-file. 883 * 884 * If the socket is not connected, has been shutdown because of an error 885 * or has been closed, throw an Exception. 886 */ 887 private boolean checkEOF() throws IOException { 888 if (conContext.isInboundClosed()) { 889 return true; 890 } else if (conContext.isInputCloseNotified || conContext.isBroken) { 891 if (conContext.closeReason == null) { 892 return true; 893 } else { 894 throw new SSLException( 895 "Connection has closed: " + conContext.closeReason, 896 conContext.closeReason); 897 } 898 } 899 900 return false; 901 } 902 } 903 904 @Override 905 public synchronized OutputStream getOutputStream() throws IOException { 906 if (isClosed()) { 907 throw new SocketException("Socket is closed"); 908 } 909 910 if (!isConnected) { 911 throw new SocketException("Socket is not connected"); 912 } 913 914 if (conContext.isOutboundDone() || isOutputShutdown()) { 915 throw new SocketException("Socket output is already shutdown"); 916 } 917 918 return appOutput; 919 } 920 921 922 /** 923 * OutputStream for application data as returned by 924 * SSLSocket.getOutputStream(). 925 */ 926 private class AppOutputStream extends OutputStream { 927 // One element array used to implement the write(byte) method 928 private final byte[] oneByte = new byte[1]; 929 930 @Override 931 public void write(int i) throws IOException { 932 oneByte[0] = (byte)i; 933 write(oneByte, 0, 1); 934 } 935 936 @Override 937 public void write(byte[] b, 938 int off, int len) throws IOException { 939 if (b == null) { 940 throw new NullPointerException("the source buffer is null"); 941 } else if (off < 0 || len < 0 || len > b.length - off) { 942 throw new IndexOutOfBoundsException( 943 "buffer length: " + b.length + ", offset; " + off + 944 ", bytes to read:" + len); 945 } else if (len == 0) { 946 // 947 // Don't bother to really write empty records. We went this 948 // far to drive the handshake machinery, for correctness; not 949 // writing empty records improves performance by cutting CPU 950 // time and network resource usage. However, some protocol 951 // implementations are fragile and don't like to see empty 952 // records, so this also increases robustness. 953 // 954 return; 955 } 956 957 // Start handshaking if the connection has not been negotiated. 958 if (!conContext.isNegotiated && !conContext.isBroken && 959 !conContext.isInboundClosed() && 960 !conContext.isOutboundClosed()) { 961 ensureNegotiated(); 962 } 963 964 // Check if the Socket is invalid (error or closed). 965 if (!conContext.isNegotiated || 966 conContext.isBroken || conContext.isOutboundClosed()) { 967 throw new SocketException("Connection or outbound has closed"); 968 } 969 970 // 971 972 // Delegate the writing to the underlying socket. 973 try { 974 conContext.outputRecord.deliver(b, off, len); 975 } catch (SSLHandshakeException she) { 976 // may be record sequence number overflow 977 throw conContext.fatal(Alert.HANDSHAKE_FAILURE, she); 978 } catch (IOException e) { 979 throw conContext.fatal(Alert.UNEXPECTED_MESSAGE, e); 980 } 981 982 // Is the sequence number is nearly overflow, or has the key usage 983 // limit been reached? 984 if (conContext.outputRecord.seqNumIsHuge() || 985 conContext.outputRecord.writeCipher.atKeyLimit()) { 986 tryKeyUpdate(); 987 } 988 } 989 990 @Override 991 public void close() throws IOException { 992 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 993 SSLLogger.finest("Closing output stream"); 994 } 995 996 try { 997 SSLSocketImpl.this.close(); 998 } catch (IOException ioe) { 999 // ignore the exception 1000 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1001 SSLLogger.warning("output stream close failed", ioe); 1002 } 1003 } 1004 } 1005 } 1006 1007 @Override 1008 public synchronized SSLParameters getSSLParameters() { 1009 return conContext.sslConfig.getSSLParameters(); 1010 } 1011 1012 @Override 1013 public synchronized void setSSLParameters(SSLParameters params) { 1014 conContext.sslConfig.setSSLParameters(params); 1015 1016 if (conContext.sslConfig.maximumPacketSize != 0) { 1017 conContext.outputRecord.changePacketSize( 1018 conContext.sslConfig.maximumPacketSize); 1019 } 1020 } 1021 1022 @Override 1023 public synchronized String getApplicationProtocol() { 1024 return conContext.applicationProtocol; 1025 } 1026 1027 @Override 1028 public synchronized String getHandshakeApplicationProtocol() { 1029 if (conContext.handshakeContext != null) { 1030 return conContext.handshakeContext.applicationProtocol; 1031 } 1032 1033 return null; 1034 } 1035 1036 @Override 1037 public synchronized void setHandshakeApplicationProtocolSelector( 1038 BiFunction<SSLSocket, List<String>, String> selector) { 1039 conContext.sslConfig.socketAPSelector = selector; 1040 } 1041 1042 @Override 1043 public synchronized BiFunction<SSLSocket, List<String>, String> 1044 getHandshakeApplicationProtocolSelector() { 1045 return conContext.sslConfig.socketAPSelector; 1046 } 1047 1048 /** 1049 * Read the initial handshake records. 1050 */ 1051 private int readHandshakeRecord() throws IOException { 1052 while (!conContext.isInboundClosed()) { 1053 try { 1054 Plaintext plainText = decode(null); 1055 if ((plainText.contentType == ContentType.HANDSHAKE.id) && 1056 conContext.isNegotiated) { 1057 return 0; 1058 } 1059 } catch (SSLException ssle) { 1060 throw ssle; 1061 } catch (IOException ioe) { 1062 if (!(ioe instanceof SSLException)) { 1063 throw new SSLException("readHandshakeRecord", ioe); 1064 } else { 1065 throw ioe; 1066 } 1067 } 1068 } 1069 1070 return -1; 1071 } 1072 1073 /** 1074 * Read application data record. Used by AppInputStream only, but defined 1075 * here so as to use the socket level synchronization. 1076 * 1077 * Note that the connection guarantees that handshake, alert, and change 1078 * cipher spec data streams are handled as they arrive, so we never see 1079 * them here. 1080 * 1081 * Note: Please be careful about the synchronization, and don't use this 1082 * method other than in the AppInputStream class! 1083 */ 1084 private ByteBuffer readApplicationRecord( 1085 ByteBuffer buffer) throws IOException { 1086 while (!conContext.isInboundClosed()) { 1087 /* 1088 * clean the buffer and check if it is too small, e.g. because 1089 * the AppInputStream did not have the chance to see the 1090 * current packet length but rather something like that of the 1091 * handshake before. In that case we return 0 at this point to 1092 * give the caller the chance to adjust the buffer. 1093 */ 1094 buffer.clear(); 1095 int inLen = conContext.inputRecord.bytesInCompletePacket(); 1096 if (inLen < 0) { // EOF 1097 handleEOF(null); 1098 1099 // if no exception thrown 1100 return null; 1101 } 1102 1103 // Is this packet bigger than SSL/TLS normally allows? 1104 if (inLen > SSLRecord.maxLargeRecordSize) { 1105 throw new SSLProtocolException( 1106 "Illegal packet size: " + inLen); 1107 } 1108 1109 if (inLen > buffer.remaining()) { 1110 buffer = ByteBuffer.allocate(inLen); 1111 } 1112 1113 try { 1114 Plaintext plainText; 1115 synchronized (this) { 1116 plainText = decode(buffer); 1117 } 1118 if (plainText.contentType == ContentType.APPLICATION_DATA.id && 1119 buffer.position() > 0) { 1120 return buffer; 1121 } 1122 } catch (SSLException ssle) { 1123 throw ssle; 1124 } catch (IOException ioe) { 1125 if (!(ioe instanceof SSLException)) { 1126 throw new SSLException("readApplicationRecord", ioe); 1127 } else { 1128 throw ioe; 1129 } 1130 } 1131 } 1132 1133 // 1134 // couldn't read, due to some kind of error 1135 // 1136 return null; 1137 } 1138 1139 private Plaintext decode(ByteBuffer destination) throws IOException { 1140 Plaintext plainText; 1141 try { 1142 if (destination == null) { 1143 plainText = SSLTransport.decode(conContext, 1144 null, 0, 0, null, 0, 0); 1145 } else { 1146 plainText = SSLTransport.decode(conContext, 1147 null, 0, 0, new ByteBuffer[]{destination}, 0, 1); 1148 } 1149 } catch (EOFException eofe) { 1150 // EOFException is special as it is related to close_notify. 1151 plainText = handleEOF(eofe); 1152 } 1153 1154 // Is the sequence number is nearly overflow? 1155 if (plainText != Plaintext.PLAINTEXT_NULL && 1156 (conContext.inputRecord.seqNumIsHuge() || 1157 conContext.inputRecord.readCipher.atKeyLimit())) { 1158 tryKeyUpdate(); 1159 } 1160 1161 return plainText; 1162 } 1163 1164 /** 1165 * Try key update for sequence number wrap or key usage limit. 1166 * 1167 * Note that in order to maintain the handshake status properly, we check 1168 * the sequence number and key usage limit after the last record 1169 * reading/writing process. 1170 * 1171 * As we request renegotiation or close the connection for wrapped sequence 1172 * number when there is enough sequence number space left to handle a few 1173 * more records, so the sequence number of the last record cannot be 1174 * wrapped. 1175 */ 1176 private void tryKeyUpdate() throws IOException { 1177 // Don't bother to kickstart if handshaking is in progress, or if the 1178 // connection is not duplex-open. 1179 if ((conContext.handshakeContext == null) && 1180 !conContext.isOutboundClosed() && 1181 !conContext.isInboundClosed() && 1182 !conContext.isBroken) { 1183 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1184 SSLLogger.finest("trigger key update"); 1185 } 1186 startHandshake(); 1187 } 1188 } 1189 1190 /** 1191 * Initialize the handshaker and socket streams. 1192 * 1193 * Called by connect, the layered constructor, and SSLServerSocket. 1194 */ 1195 synchronized void doneConnect() throws IOException { 1196 // In server mode, it is not necessary to set host and serverNames. 1197 // Otherwise, would require a reverse DNS lookup to get the hostname. 1198 if (peerHost == null || peerHost.isEmpty()) { 1199 boolean useNameService = 1200 trustNameService && conContext.sslConfig.isClientMode; 1201 useImplicitHost(useNameService); 1202 } else { 1203 conContext.sslConfig.serverNames = 1204 Utilities.addToSNIServerNameList( 1205 conContext.sslConfig.serverNames, peerHost); 1206 } 1207 1208 InputStream sockInput = super.getInputStream(); 1209 conContext.inputRecord.setReceiverStream(sockInput); 1210 1211 OutputStream sockOutput = super.getOutputStream(); 1212 conContext.inputRecord.setDeliverStream(sockOutput); 1213 conContext.outputRecord.setDeliverStream(sockOutput); 1214 1215 this.isConnected = true; 1216 } 1217 1218 private void useImplicitHost(boolean useNameService) { 1219 // Note: If the local name service is not trustworthy, reverse 1220 // host name resolution should not be performed for endpoint 1221 // identification. Use the application original specified 1222 // hostname or IP address instead. 1223 1224 // Get the original hostname via jdk.internal.misc.SharedSecrets 1225 InetAddress inetAddress = getInetAddress(); 1226 if (inetAddress == null) { // not connected 1227 return; 1228 } 1229 1230 String originalHostname = SharedSecrets.getJavaNetAccess().getOriginalHostName(inetAddress); 1231 if (originalHostname != null && !originalHostname.isEmpty()) { 1232 1233 this.peerHost = originalHostname; 1234 if (conContext.sslConfig.serverNames.isEmpty() && 1235 !conContext.sslConfig.noSniExtension) { 1236 conContext.sslConfig.serverNames = 1237 Utilities.addToSNIServerNameList( 1238 conContext.sslConfig.serverNames, peerHost); 1239 } 1240 1241 return; 1242 } 1243 1244 // No explicitly specified hostname, no server name indication. 1245 if (!useNameService) { 1246 // The local name service is not trustworthy, use IP address. 1247 this.peerHost = inetAddress.getHostAddress(); 1248 } else { 1249 // Use the underlying reverse host name resolution service. 1250 this.peerHost = getInetAddress().getHostName(); 1251 } 1252 } 1253 1254 // ONLY used by HttpsClient to setup the URI specified hostname 1255 // 1256 // Please NOTE that this method MUST be called before calling to 1257 // SSLSocket.setSSLParameters(). Otherwise, the {@code host} parameter 1258 // may override SNIHostName in the customized server name indication. 1259 public synchronized void setHost(String host) { 1260 this.peerHost = host; 1261 this.conContext.sslConfig.serverNames = 1262 Utilities.addToSNIServerNameList( 1263 conContext.sslConfig.serverNames, host); 1264 } 1265 1266 /** 1267 * Handle an exception. 1268 * 1269 * This method is called by top level exception handlers (in read(), 1270 * write()) to make sure we always shutdown the connection correctly 1271 * and do not pass runtime exception to the application. 1272 * 1273 * This method never returns normally, it always throws an IOException. 1274 */ 1275 private void handleException(Exception cause) throws IOException { 1276 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1277 SSLLogger.warning("handling exception", cause); 1278 } 1279 1280 // Don't close the Socket in case of timeouts or interrupts. 1281 if (cause instanceof InterruptedIOException) { 1282 throw (IOException)cause; 1283 } 1284 1285 // need to perform error shutdown 1286 boolean isSSLException = (cause instanceof SSLException); 1287 Alert alert; 1288 if (isSSLException) { 1289 if (cause instanceof SSLHandshakeException) { 1290 alert = Alert.HANDSHAKE_FAILURE; 1291 } else { 1292 alert = Alert.UNEXPECTED_MESSAGE; 1293 } 1294 } else { 1295 if (cause instanceof IOException) { 1296 alert = Alert.UNEXPECTED_MESSAGE; 1297 } else { 1298 // RuntimeException 1299 alert = Alert.INTERNAL_ERROR; 1300 } 1301 } 1302 1303 throw conContext.fatal(alert, cause); 1304 } 1305 1306 private Plaintext handleEOF(EOFException eofe) throws IOException { 1307 if (requireCloseNotify || conContext.handshakeContext != null) { 1308 SSLException ssle; 1309 if (conContext.handshakeContext != null) { 1310 ssle = new SSLHandshakeException( 1311 "Remote host terminated the handshake"); 1312 } else { 1313 ssle = new SSLProtocolException( 1314 "Remote host terminated the connection"); 1315 } 1316 1317 if (eofe != null) { 1318 ssle.initCause(eofe); 1319 } 1320 throw ssle; 1321 } else { 1322 // treat as if we had received a close_notify 1323 conContext.isInputCloseNotified = true; 1324 shutdownInput(); 1325 1326 return Plaintext.PLAINTEXT_NULL; 1327 } 1328 } 1329 1330 1331 @Override 1332 public String getPeerHost() { 1333 return peerHost; 1334 } 1335 1336 @Override 1337 public int getPeerPort() { 1338 return getPort(); 1339 } 1340 1341 @Override 1342 public boolean useDelegatedTask() { 1343 return false; 1344 } 1345 1346 @Override 1347 public void shutdown() throws IOException { 1348 if (!isClosed()) { 1349 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1350 SSLLogger.fine("close the underlying socket"); 1351 } 1352 1353 try { 1354 if (conContext.isInputCloseNotified) { 1355 // Close the connection, no wait for more peer response. 1356 closeSocket(false); 1357 } else { 1358 // Close the connection, may wait for peer close_notify. 1359 closeSocket(true); 1360 } 1361 } finally { 1362 tlsIsClosed = true; 1363 } 1364 } 1365 } 1366 1367 private void closeSocket(boolean selfInitiated) throws IOException { 1368 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1369 SSLLogger.fine("close the SSL connection " + 1370 (selfInitiated ? "(initiative)" : "(passive)")); 1371 } 1372 1373 if (autoClose || !isLayered()) { 1374 super.close(); 1375 } else if (selfInitiated) { 1376 if (!conContext.isInboundClosed() && !isInputShutdown()) { 1377 // wait for close_notify alert to clear input stream. 1378 waitForClose(); 1379 } 1380 } 1381 } 1382 1383 /** 1384 * Wait for close_notify alert for a graceful closure. 1385 * 1386 * [RFC 5246] If the application protocol using TLS provides that any 1387 * data may be carried over the underlying transport after the TLS 1388 * connection is closed, the TLS implementation must receive the responding 1389 * close_notify alert before indicating to the application layer that 1390 * the TLS connection has ended. If the application protocol will not 1391 * transfer any additional data, but will only close the underlying 1392 * transport connection, then the implementation MAY choose to close the 1393 * transport without waiting for the responding close_notify. 1394 */ 1395 private void waitForClose() throws IOException { 1396 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1397 SSLLogger.fine("wait for close_notify or alert"); 1398 } 1399 1400 while (!conContext.isInboundClosed()) { 1401 try { 1402 Plaintext plainText = decode(null); 1403 // discard and continue 1404 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1405 SSLLogger.finest( 1406 "discard plaintext while waiting for close", plainText); 1407 } 1408 } catch (Exception e) { // including RuntimeException 1409 handleException(e); 1410 } 1411 } 1412 } 1413 }