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