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