1 /* 2 * Copyright (c) 2003, 2016, 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.*; 29 import java.nio.*; 30 import java.security.*; 31 import java.util.*; 32 import java.util.function.BiFunction; 33 34 import javax.crypto.BadPaddingException; 35 36 import javax.net.ssl.*; 37 import javax.net.ssl.SSLEngineResult.*; 38 39 /** 40 * Implementation of an non-blocking SSLEngine. 41 * 42 * *Currently*, the SSLEngine code exists in parallel with the current 43 * SSLSocket. As such, the current implementation is using legacy code 44 * with many of the same abstractions. However, it varies in many 45 * areas, most dramatically in the IO handling. 46 * 47 * There are three main I/O threads that can be existing in parallel: 48 * wrap(), unwrap(), and beginHandshake(). We are encouraging users to 49 * not call multiple instances of wrap or unwrap, because the data could 50 * appear to flow out of the SSLEngine in a non-sequential order. We 51 * take all steps we can to at least make sure the ordering remains 52 * consistent, but once the calls returns, anything can happen. For 53 * example, thread1 and thread2 both call wrap, thread1 gets the first 54 * packet, thread2 gets the second packet, but thread2 gets control back 55 * before thread1, and sends the data. The receiving side would see an 56 * out-of-order error. 57 * 58 * @author Brad Wetmore 59 */ 60 public final class SSLEngineImpl extends SSLEngine { 61 62 // 63 // Fields and global comments 64 // 65 66 /* 67 * There's a state machine associated with each connection, which 68 * among other roles serves to negotiate session changes. 69 * 70 * - START with constructor, until the TCP connection's around. 71 * - HANDSHAKE picks session parameters before allowing traffic. 72 * There are many substates due to sequencing requirements 73 * for handshake messages. 74 * - DATA may be transmitted. 75 * - RENEGOTIATE state allows concurrent data and handshaking 76 * traffic ("same" substates as HANDSHAKE), and terminates 77 * in selection of new session (and connection) parameters 78 * - ERROR state immediately precedes abortive disconnect. 79 * - CLOSED when one side closes down, used to start the shutdown 80 * process. SSL connection objects are not reused. 81 * 82 * State affects what SSL record types may legally be sent: 83 * 84 * - Handshake ... only in HANDSHAKE and RENEGOTIATE states 85 * - App Data ... only in DATA and RENEGOTIATE states 86 * - Alert ... in HANDSHAKE, DATA, RENEGOTIATE 87 * 88 * Re what may be received: same as what may be sent, except that 89 * HandshakeRequest handshaking messages can come from servers even 90 * in the application data state, to request entry to RENEGOTIATE. 91 * 92 * The state machine within HANDSHAKE and RENEGOTIATE states controls 93 * the pending session, not the connection state, until the change 94 * cipher spec and "Finished" handshake messages are processed and 95 * make the "new" session become the current one. 96 * 97 * NOTE: details of the SMs always need to be nailed down better. 98 * The text above illustrates the core ideas. 99 * 100 * +---->-------+------>--------->-------+ 101 * | | | 102 * <-----< ^ ^ <-----< | 103 *START>----->HANDSHAKE>----->DATA>----->RENEGOTIATE | 104 * v v v | 105 * | | | | 106 * +------------+---------------+ | 107 * | | 108 * v | 109 * ERROR>------>----->CLOSED<--------<----+ 110 * 111 * ALSO, note that the purpose of handshaking (renegotiation is 112 * included) is to assign a different, and perhaps new, session to 113 * the connection. The SSLv3 spec is a bit confusing on that new 114 * protocol feature. 115 */ 116 private int connectionState; 117 118 private static final int cs_START = 0; 119 private static final int cs_HANDSHAKE = 1; 120 private static final int cs_DATA = 2; 121 private static final int cs_RENEGOTIATE = 3; 122 private static final int cs_ERROR = 4; 123 private static final int cs_CLOSED = 6; 124 125 /* 126 * Once we're in state cs_CLOSED, we can continue to 127 * wrap/unwrap until we finish sending/receiving the messages 128 * for close_notify. 129 */ 130 private boolean inboundDone = false; 131 private boolean outboundDone = false; 132 133 /* 134 * The authentication context holds all information used to establish 135 * who this end of the connection is (certificate chains, private keys, 136 * etc) and who is trusted (e.g. as CAs or websites). 137 */ 138 private SSLContextImpl sslContext; 139 140 /* 141 * This connection is one of (potentially) many associated with 142 * any given session. The output of the handshake protocol is a 143 * new session ... although all the protocol description talks 144 * about changing the cipher spec (and it does change), in fact 145 * that's incidental since it's done by changing everything that 146 * is associated with a session at the same time. (TLS/IETF may 147 * change that to add client authentication w/o new key exchg.) 148 */ 149 private Handshaker handshaker; 150 private SSLSessionImpl sess; 151 private volatile SSLSessionImpl handshakeSession; 152 153 /* 154 * Flag indicating if the next record we receive MUST be a Finished 155 * message. Temporarily set during the handshake to ensure that 156 * a change cipher spec message is followed by a finished message. 157 */ 158 private boolean expectingFinished; 159 160 161 /* 162 * If someone tries to closeInbound() (say at End-Of-Stream) 163 * our engine having received a close_notify, we need to 164 * notify the app that we may have a truncation attack underway. 165 */ 166 private boolean recvCN; 167 168 /* 169 * For improved diagnostics, we detail connection closure 170 * If the engine is closed (connectionState >= cs_ERROR), 171 * closeReason != null indicates if the engine was closed 172 * because of an error or because or normal shutdown. 173 */ 174 private SSLException closeReason; 175 176 /* 177 * Per-connection private state that doesn't change when the 178 * session is changed. 179 */ 180 private ClientAuthType doClientAuth = 181 ClientAuthType.CLIENT_AUTH_NONE; 182 private boolean enableSessionCreation = true; 183 InputRecord inputRecord; 184 OutputRecord outputRecord; 185 private AccessControlContext acc; 186 187 // The cipher suites enabled for use on this connection. 188 private CipherSuiteList enabledCipherSuites; 189 190 // the endpoint identification protocol 191 private String identificationProtocol = null; 192 193 // The cryptographic algorithm constraints 194 private AlgorithmConstraints algorithmConstraints = null; 195 196 // The server name indication and matchers 197 List<SNIServerName> serverNames = 198 Collections.<SNIServerName>emptyList(); 199 Collection<SNIMatcher> sniMatchers = 200 Collections.<SNIMatcher>emptyList(); 201 202 // Configured application protocol values 203 String[] applicationProtocols = new String[0]; 204 205 // Negotiated application protocol value. 206 // 207 // The value under negotiation will be obtained from handshaker. 208 String applicationProtocol = null; 209 210 // Callback function that selects the application protocol value during 211 // the SSL/TLS handshake. 212 BiFunction<SSLEngine, List<String>, String> applicationProtocolSelector; 213 214 // Have we been told whether we're client or server? 215 private boolean serverModeSet = false; 216 private boolean roleIsServer; 217 218 /* 219 * The protocol versions enabled for use on this connection. 220 * 221 * Note: we support a pseudo protocol called SSLv2Hello which when 222 * set will result in an SSL v2 Hello being sent with SSL (version 3.0) 223 * or TLS (version 3.1, 3.2, etc.) version info. 224 */ 225 private ProtocolList enabledProtocols; 226 227 /* 228 * The SSL version associated with this connection. 229 */ 230 private ProtocolVersion protocolVersion; 231 232 /* 233 * security parameters for secure renegotiation. 234 */ 235 private boolean secureRenegotiation; 236 private byte[] clientVerifyData; 237 private byte[] serverVerifyData; 238 239 /* 240 * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME * 241 * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES. 242 * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME * 243 * 244 * There are several locks here. 245 * 246 * The primary lock is the per-instance lock used by 247 * synchronized(this) and the synchronized methods. It controls all 248 * access to things such as the connection state and variables which 249 * affect handshaking. If we are inside a synchronized method, we 250 * can access the state directly, otherwise, we must use the 251 * synchronized equivalents. 252 * 253 * Note that we must never acquire the <code>this</code> lock after 254 * <code>writeLock</code> or run the risk of deadlock. 255 * 256 * Grab some coffee, and be careful with any code changes. 257 */ 258 private Object wrapLock; 259 private Object unwrapLock; 260 Object writeLock; 261 262 /* 263 * Whether local cipher suites preference in server side should be 264 * honored during handshaking? 265 */ 266 private boolean preferLocalCipherSuites = false; 267 268 /* 269 * whether DTLS handshake retransmissions should be enabled? 270 */ 271 private boolean enableRetransmissions = false; 272 273 /* 274 * The maximum expected network packet size for SSL/TLS/DTLS records. 275 */ 276 private int maximumPacketSize = 0; 277 278 /* 279 * Is this an instance for Datagram Transport Layer Security (DTLS)? 280 */ 281 private final boolean isDTLS; 282 283 /* 284 * Class and subclass dynamic debugging support 285 */ 286 private static final Debug debug = Debug.getInstance("ssl"); 287 288 // 289 // Initialization/Constructors 290 // 291 292 /** 293 * Constructor for an SSLEngine from SSLContext, without 294 * host/port hints. This Engine will not be able to cache 295 * sessions, but must renegotiate everything by hand. 296 */ 297 SSLEngineImpl(SSLContextImpl ctx, boolean isDTLS) { 298 super(); 299 this.isDTLS = isDTLS; 300 init(ctx, isDTLS); 301 } 302 303 /** 304 * Constructor for an SSLEngine from SSLContext. 305 */ 306 SSLEngineImpl(SSLContextImpl ctx, String host, int port, boolean isDTLS) { 307 super(host, port); 308 this.isDTLS = isDTLS; 309 init(ctx, isDTLS); 310 } 311 312 /** 313 * Initializes the Engine 314 */ 315 private void init(SSLContextImpl ctx, boolean isDTLS) { 316 if (debug != null && Debug.isOn("ssl")) { 317 System.out.println("Using SSLEngineImpl."); 318 } 319 320 sslContext = ctx; 321 sess = SSLSessionImpl.nullSession; 322 handshakeSession = null; 323 protocolVersion = isDTLS ? 324 ProtocolVersion.DEFAULT_DTLS : ProtocolVersion.DEFAULT_TLS; 325 326 /* 327 * State is cs_START until we initialize the handshaker. 328 * 329 * Apps using SSLEngine are probably going to be server. 330 * Somewhat arbitrary choice. 331 */ 332 roleIsServer = true; 333 connectionState = cs_START; 334 335 // default server name indication 336 serverNames = 337 Utilities.addToSNIServerNameList(serverNames, getPeerHost()); 338 339 // default security parameters for secure renegotiation 340 secureRenegotiation = false; 341 clientVerifyData = new byte[0]; 342 serverVerifyData = new byte[0]; 343 344 enabledCipherSuites = 345 sslContext.getDefaultCipherSuiteList(roleIsServer); 346 enabledProtocols = 347 sslContext.getDefaultProtocolList(roleIsServer); 348 349 wrapLock = new Object(); 350 unwrapLock = new Object(); 351 writeLock = new Object(); 352 353 /* 354 * Save the Access Control Context. This will be used later 355 * for a couple of things, including providing a context to 356 * run tasks in, and for determining which credentials 357 * to use for Subject based (JAAS) decisions 358 */ 359 acc = AccessController.getContext(); 360 361 /* 362 * All outbound application data goes through this OutputRecord, 363 * other data goes through their respective records created 364 * elsewhere. All inbound data goes through this one 365 * input record. 366 */ 367 if (isDTLS) { 368 enableRetransmissions = true; 369 370 // SSLEngine needs no record local buffer 371 outputRecord = new DTLSOutputRecord(); 372 inputRecord = new DTLSInputRecord(); 373 374 } else { 375 outputRecord = new SSLEngineOutputRecord(); 376 inputRecord = new SSLEngineInputRecord(); 377 } 378 379 maximumPacketSize = outputRecord.getMaxPacketSize(); 380 } 381 382 /** 383 * Initialize the handshaker object. This means: 384 * 385 * . if a handshake is already in progress (state is cs_HANDSHAKE 386 * or cs_RENEGOTIATE), do nothing and return 387 * 388 * . if the engine is already closed, throw an Exception (internal error) 389 * 390 * . otherwise (cs_START or cs_DATA), create the appropriate handshaker 391 * object and advance the connection state (to cs_HANDSHAKE or 392 * cs_RENEGOTIATE, respectively). 393 * 394 * This method is called right after a new engine is created, when 395 * starting renegotiation, or when changing client/server mode of the 396 * engine. 397 */ 398 private void initHandshaker() { 399 switch (connectionState) { 400 401 // 402 // Starting a new handshake. 403 // 404 case cs_START: 405 case cs_DATA: 406 break; 407 408 // 409 // We're already in the middle of a handshake. 410 // 411 case cs_HANDSHAKE: 412 case cs_RENEGOTIATE: 413 return; 414 415 // 416 // Anyone allowed to call this routine is required to 417 // do so ONLY if the connection state is reasonable... 418 // 419 default: 420 throw new IllegalStateException("Internal error"); 421 } 422 423 // state is either cs_START or cs_DATA 424 if (connectionState == cs_START) { 425 connectionState = cs_HANDSHAKE; 426 } else { // cs_DATA 427 connectionState = cs_RENEGOTIATE; 428 } 429 430 if (roleIsServer) { 431 handshaker = new ServerHandshaker(this, sslContext, 432 enabledProtocols, doClientAuth, 433 protocolVersion, connectionState == cs_HANDSHAKE, 434 secureRenegotiation, clientVerifyData, serverVerifyData, 435 isDTLS); 436 handshaker.setSNIMatchers(sniMatchers); 437 handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites); 438 } else { 439 handshaker = new ClientHandshaker(this, sslContext, 440 enabledProtocols, 441 protocolVersion, connectionState == cs_HANDSHAKE, 442 secureRenegotiation, clientVerifyData, serverVerifyData, 443 isDTLS); 444 handshaker.setSNIServerNames(serverNames); 445 } 446 handshaker.setMaximumPacketSize(maximumPacketSize); 447 handshaker.setEnabledCipherSuites(enabledCipherSuites); 448 handshaker.setEnableSessionCreation(enableSessionCreation); 449 handshaker.setApplicationProtocols(applicationProtocols); 450 handshaker.setApplicationProtocolSelectorSSLEngine( 451 applicationProtocolSelector); 452 453 outputRecord.initHandshaker(); 454 } 455 456 /* 457 * Report the current status of the Handshaker 458 */ 459 private HandshakeStatus getHSStatus(HandshakeStatus hss) { 460 461 if (hss != null) { 462 return hss; 463 } 464 465 synchronized (this) { 466 if (!outputRecord.isEmpty()) { 467 // If no handshaking, special case to wrap alters. 468 return HandshakeStatus.NEED_WRAP; 469 } else if (handshaker != null) { 470 if (handshaker.taskOutstanding()) { 471 return HandshakeStatus.NEED_TASK; 472 } else if (isDTLS && !inputRecord.isEmpty()) { 473 return HandshakeStatus.NEED_UNWRAP_AGAIN; 474 } else { 475 return HandshakeStatus.NEED_UNWRAP; 476 } 477 } else if (connectionState == cs_CLOSED) { 478 /* 479 * Special case where we're closing, but 480 * still need the close_notify before we 481 * can officially be closed. 482 * 483 * Note isOutboundDone is taken care of by 484 * hasOutboundData() above. 485 */ 486 if (!isInboundDone()) { 487 return HandshakeStatus.NEED_UNWRAP; 488 } // else not handshaking 489 } 490 491 return HandshakeStatus.NOT_HANDSHAKING; 492 } 493 } 494 495 private synchronized void checkTaskThrown() throws SSLException { 496 if (handshaker != null) { 497 handshaker.checkThrown(); 498 } 499 } 500 501 // 502 // Handshaking and connection state code 503 // 504 505 /* 506 * Provides "this" synchronization for connection state. 507 * Otherwise, you can access it directly. 508 */ 509 private synchronized int getConnectionState() { 510 return connectionState; 511 } 512 513 private synchronized void setConnectionState(int state) { 514 connectionState = state; 515 } 516 517 /* 518 * Get the Access Control Context. 519 * 520 * Used for a known context to 521 * run tasks in, and for determining which credentials 522 * to use for Subject-based (JAAS) decisions. 523 */ 524 AccessControlContext getAcc() { 525 return acc; 526 } 527 528 /* 529 * Is a handshake currently underway? 530 */ 531 @Override 532 public SSLEngineResult.HandshakeStatus getHandshakeStatus() { 533 return getHSStatus(null); 534 } 535 536 /* 537 * used by Handshaker to change the active write cipher, follows 538 * the output of the CCS message. 539 * 540 * Also synchronized on "this" from readRecord/delegatedTask. 541 */ 542 void changeWriteCiphers() throws IOException { 543 544 Authenticator writeAuthenticator; 545 CipherBox writeCipher; 546 try { 547 writeCipher = handshaker.newWriteCipher(); 548 writeAuthenticator = handshaker.newWriteAuthenticator(); 549 } catch (GeneralSecurityException e) { 550 // "can't happen" 551 throw new SSLException("Algorithm missing: ", e); 552 } 553 554 outputRecord.changeWriteCiphers(writeAuthenticator, writeCipher); 555 } 556 557 /* 558 * Updates the SSL version associated with this connection. 559 * Called from Handshaker once it has determined the negotiated version. 560 */ 561 synchronized void setVersion(ProtocolVersion protocolVersion) { 562 this.protocolVersion = protocolVersion; 563 outputRecord.setVersion(protocolVersion); 564 } 565 566 567 /** 568 * Kickstart the handshake if it is not already in progress. 569 * This means: 570 * 571 * . if handshaking is already underway, do nothing and return 572 * 573 * . if the engine is not connected or already closed, throw an 574 * Exception. 575 * 576 * . otherwise, call initHandshake() to initialize the handshaker 577 * object and progress the state. Then, send the initial 578 * handshaking message if appropriate (always on clients and 579 * on servers when renegotiating). 580 */ 581 private synchronized void kickstartHandshake() throws IOException { 582 switch (connectionState) { 583 584 case cs_START: 585 if (!serverModeSet) { 586 throw new IllegalStateException( 587 "Client/Server mode not yet set."); 588 } 589 initHandshaker(); 590 break; 591 592 case cs_HANDSHAKE: 593 // handshaker already setup, proceed 594 break; 595 596 case cs_DATA: 597 if (!secureRenegotiation && !Handshaker.allowUnsafeRenegotiation) { 598 throw new SSLHandshakeException( 599 "Insecure renegotiation is not allowed"); 600 } 601 602 if (!secureRenegotiation) { 603 if (debug != null && Debug.isOn("handshake")) { 604 System.out.println( 605 "Warning: Using insecure renegotiation"); 606 } 607 } 608 609 // initialize the handshaker, move to cs_RENEGOTIATE 610 initHandshaker(); 611 break; 612 613 case cs_RENEGOTIATE: 614 // handshaking already in progress, return 615 return; 616 617 default: 618 // cs_ERROR/cs_CLOSED 619 throw new SSLException("SSLEngine is closing/closed"); 620 } 621 622 // 623 // Kickstart handshake state machine if we need to ... 624 // 625 if (!handshaker.activated()) { 626 // prior to handshaking, activate the handshake 627 if (connectionState == cs_RENEGOTIATE) { 628 // don't use SSLv2Hello when renegotiating 629 handshaker.activate(protocolVersion); 630 } else { 631 handshaker.activate(null); 632 } 633 634 if (handshaker instanceof ClientHandshaker) { 635 // send client hello 636 handshaker.kickstart(); 637 } else { // instanceof ServerHandshaker 638 if (connectionState == cs_HANDSHAKE) { 639 // initial handshake, no kickstart message to send 640 } else { 641 // we want to renegotiate, send hello request 642 handshaker.kickstart(); 643 } 644 } 645 } 646 } 647 648 /* 649 * Start a SSLEngine handshake 650 */ 651 @Override 652 public void beginHandshake() throws SSLException { 653 try { 654 kickstartHandshake(); 655 } catch (Exception e) { 656 fatal(Alerts.alert_handshake_failure, 657 "Couldn't kickstart handshaking", e); 658 } 659 } 660 661 662 // 663 // Read/unwrap side 664 // 665 666 667 /** 668 * Unwraps a buffer. Does a variety of checks before grabbing 669 * the unwrapLock, which blocks multiple unwraps from occurring. 670 */ 671 @Override 672 public SSLEngineResult unwrap(ByteBuffer netData, ByteBuffer[] appData, 673 int offset, int length) throws SSLException { 674 675 // check engine parameters 676 checkEngineParas(netData, appData, offset, length, false); 677 678 try { 679 synchronized (unwrapLock) { 680 return readNetRecord(netData, appData, offset, length); 681 } 682 } catch (SSLProtocolException spe) { 683 // may be an unexpected handshake message 684 fatal(Alerts.alert_unexpected_message, spe.getMessage(), spe); 685 return null; // make compiler happy 686 } catch (Exception e) { 687 /* 688 * Don't reset position so it looks like we didn't 689 * consume anything. We did consume something, and it 690 * got us into this situation, so report that much back. 691 * Our days of consuming are now over anyway. 692 */ 693 fatal(Alerts.alert_internal_error, 694 "problem unwrapping net record", e); 695 return null; // make compiler happy 696 } 697 } 698 699 private static void checkEngineParas(ByteBuffer netData, 700 ByteBuffer[] appData, int offset, int len, boolean isForWrap) { 701 702 if ((netData == null) || (appData == null)) { 703 throw new IllegalArgumentException("src/dst is null"); 704 } 705 706 if ((offset < 0) || (len < 0) || (offset > appData.length - len)) { 707 throw new IndexOutOfBoundsException(); 708 } 709 710 /* 711 * If wrapping, make sure the destination bufffer is writable. 712 */ 713 if (isForWrap && netData.isReadOnly()) { 714 throw new ReadOnlyBufferException(); 715 } 716 717 for (int i = offset; i < offset + len; i++) { 718 if (appData[i] == null) { 719 throw new IllegalArgumentException( 720 "appData[" + i + "] == null"); 721 } 722 723 /* 724 * If unwrapping, make sure the destination bufffers are writable. 725 */ 726 if (!isForWrap && appData[i].isReadOnly()) { 727 throw new ReadOnlyBufferException(); 728 } 729 } 730 } 731 732 /* 733 * Makes additional checks for unwrap, but this time more 734 * specific to this packet and the current state of the machine. 735 */ 736 private SSLEngineResult readNetRecord(ByteBuffer netData, 737 ByteBuffer[] appData, int offset, int length) throws IOException { 738 739 Status status = null; 740 HandshakeStatus hsStatus = null; 741 742 /* 743 * See if the handshaker needs to report back some SSLException. 744 */ 745 checkTaskThrown(); 746 747 /* 748 * Check if we are closing/closed. 749 */ 750 if (isInboundDone()) { 751 return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0); 752 } 753 754 /* 755 * If we're still in cs_HANDSHAKE, make sure it's been 756 * started. 757 */ 758 synchronized (this) { 759 if ((connectionState == cs_HANDSHAKE) || 760 (connectionState == cs_START)) { 761 kickstartHandshake(); 762 763 /* 764 * If there's still outbound data to flush, we 765 * can return without trying to unwrap anything. 766 */ 767 hsStatus = getHSStatus(null); 768 769 if (hsStatus == HandshakeStatus.NEED_WRAP) { 770 return new SSLEngineResult(Status.OK, hsStatus, 0, 0); 771 } 772 } 773 } 774 775 /* 776 * Grab a copy of this if it doesn't already exist, 777 * and we can use it several places before anything major 778 * happens on this side. Races aren't critical 779 * here. 780 */ 781 if (hsStatus == null) { 782 hsStatus = getHSStatus(null); 783 } 784 785 /* 786 * If we have a task outstanding, this *MUST* be done before 787 * doing any more unwrapping, because we could be in the middle 788 * of receiving a handshake message, for example, a finished 789 * message which would change the ciphers. 790 */ 791 if (hsStatus == HandshakeStatus.NEED_TASK) { 792 return new SSLEngineResult(Status.OK, hsStatus, 0, 0); 793 } 794 795 if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_UNWRAP_AGAIN) { 796 Plaintext plainText = null; 797 try { 798 plainText = readRecord(null, null, 0, 0); 799 } catch (SSLException e) { 800 throw e; 801 } catch (IOException e) { 802 throw new SSLException("readRecord", e); 803 } 804 805 status = (isInboundDone() ? Status.CLOSED : Status.OK); 806 hsStatus = getHSStatus(plainText.handshakeStatus); 807 808 return new SSLEngineResult( 809 status, hsStatus, 0, 0, plainText.recordSN); 810 } 811 812 /* 813 * Check the packet to make sure enough is here. 814 * This will also indirectly check for 0 len packets. 815 */ 816 int packetLen = 0; 817 try { 818 packetLen = inputRecord.bytesInCompletePacket(netData); 819 } catch (SSLException ssle) { 820 // Need to discard invalid records for DTLS protocols. 821 if (isDTLS) { 822 if (debug != null && Debug.isOn("ssl")) { 823 System.out.println( 824 Thread.currentThread().getName() + 825 " discard invalid record: " + ssle); 826 } 827 828 // invalid, discard the entire data [section 4.1.2.7, RFC 6347] 829 int deltaNet = netData.remaining(); 830 netData.position(netData.limit()); 831 832 status = (isInboundDone() ? Status.CLOSED : Status.OK); 833 hsStatus = getHSStatus(hsStatus); 834 835 return new SSLEngineResult(status, hsStatus, deltaNet, 0, -1L); 836 } else { 837 throw ssle; 838 } 839 } 840 841 // Is this packet bigger than SSL/TLS normally allows? 842 if (packetLen > sess.getPacketBufferSize()) { 843 int largestRecordSize = isDTLS ? 844 DTLSRecord.maxRecordSize : SSLRecord.maxLargeRecordSize; 845 if ((packetLen <= largestRecordSize) && !isDTLS) { 846 // Expand the expected maximum packet/application buffer 847 // sizes. 848 // 849 // Only apply to SSL/TLS protocols. 850 851 // Old behavior: shall we honor the System Property 852 // "jsse.SSLEngine.acceptLargeFragments" if it is "false"? 853 sess.expandBufferSizes(); 854 } 855 856 // check the packet again 857 largestRecordSize = sess.getPacketBufferSize(); 858 if (packetLen > largestRecordSize) { 859 throw new SSLProtocolException( 860 "Input record too big: max = " + 861 largestRecordSize + " len = " + packetLen); 862 } 863 } 864 865 int netPos = netData.position(); 866 int appRemains = 0; 867 for (int i = offset; i < offset + length; i++) { 868 if (appData[i] == null) { 869 throw new IllegalArgumentException( 870 "appData[" + i + "] == null"); 871 } 872 appRemains += appData[i].remaining(); 873 } 874 875 /* 876 * Check for OVERFLOW. 877 * 878 * Delay enforcing the application buffer free space requirement 879 * until after the initial handshaking. 880 */ 881 // synchronize connectionState? 882 if ((connectionState == cs_DATA) || 883 (connectionState == cs_RENEGOTIATE)) { 884 885 int FragLen = inputRecord.estimateFragmentSize(packetLen); 886 if (FragLen > appRemains) { 887 return new SSLEngineResult( 888 Status.BUFFER_OVERFLOW, hsStatus, 0, 0); 889 } 890 } 891 892 // check for UNDERFLOW. 893 if ((packetLen == -1) || (netData.remaining() < packetLen)) { 894 return new SSLEngineResult(Status.BUFFER_UNDERFLOW, hsStatus, 0, 0); 895 } 896 897 /* 898 * We're now ready to actually do the read. 899 */ 900 Plaintext plainText = null; 901 try { 902 plainText = readRecord(netData, appData, offset, length); 903 } catch (SSLException e) { 904 throw e; 905 } catch (IOException e) { 906 throw new SSLException("readRecord", e); 907 } 908 909 /* 910 * Check the various condition that we could be reporting. 911 * 912 * It's *possible* something might have happened between the 913 * above and now, but it was better to minimally lock "this" 914 * during the read process. We'll return the current 915 * status, which is more representative of the current state. 916 * 917 * status above should cover: FINISHED, NEED_TASK 918 */ 919 status = (isInboundDone() ? Status.CLOSED : Status.OK); 920 hsStatus = getHSStatus(plainText.handshakeStatus); 921 922 int deltaNet = netData.position() - netPos; 923 int deltaApp = appRemains; 924 for (int i = offset; i < offset + length; i++) { 925 deltaApp -= appData[i].remaining(); 926 } 927 928 return new SSLEngineResult( 929 status, hsStatus, deltaNet, deltaApp, plainText.recordSN); 930 } 931 932 // the caller have synchronized readLock 933 void expectingFinishFlight() { 934 inputRecord.expectingFinishFlight(); 935 } 936 937 /* 938 * Actually do the read record processing. 939 * 940 * Returns a Status if it can make specific determinations 941 * of the engine state. In particular, we need to signal 942 * that a handshake just completed. 943 * 944 * It would be nice to be symmetrical with the write side and move 945 * the majority of this to SSLInputRecord, but there's too much 946 * SSLEngine state to do that cleanly. It must still live here. 947 */ 948 private Plaintext readRecord(ByteBuffer netData, 949 ByteBuffer[] appData, int offset, int length) throws IOException { 950 951 /* 952 * The various operations will return new sliced BB's, 953 * this will avoid having to worry about positions and 954 * limits in the netBB. 955 */ 956 Plaintext plainText = null; 957 958 if (getConnectionState() == cs_ERROR) { 959 return Plaintext.PLAINTEXT_NULL; 960 } 961 962 /* 963 * Read a record ... maybe emitting an alert if we get a 964 * comprehensible but unsupported "hello" message during 965 * format checking (e.g. V2). 966 */ 967 try { 968 if (isDTLS) { 969 // Don't process the incoming record until all of the 970 // buffered records get handled. 971 plainText = inputRecord.acquirePlaintext(); 972 } 973 974 if ((!isDTLS || plainText == null) && netData != null) { 975 plainText = inputRecord.decode(netData); 976 } 977 } catch (UnsupportedOperationException unsoe) { // SSLv2Hello 978 // Hack code to deliver SSLv2 error message for SSL/TLS connections. 979 if (!isDTLS) { 980 outputRecord.encodeV2NoCipher(); 981 } 982 983 fatal(Alerts.alert_unexpected_message, unsoe); 984 } catch (BadPaddingException e) { 985 /* 986 * The basic SSLv3 record protection involves (optional) 987 * encryption for privacy, and an integrity check ensuring 988 * data origin authentication. We do them both here, and 989 * throw a fatal alert if the integrity check fails. 990 */ 991 byte alertType = (connectionState != cs_DATA) ? 992 Alerts.alert_handshake_failure : 993 Alerts.alert_bad_record_mac; 994 fatal(alertType, e.getMessage(), e); 995 } catch (SSLHandshakeException she) { 996 // may be record sequence number overflow 997 fatal(Alerts.alert_handshake_failure, she); 998 } catch (IOException ioe) { 999 fatal(Alerts.alert_unexpected_message, ioe); 1000 } 1001 1002 // plainText should never be null for TLS protocols 1003 HandshakeStatus hsStatus = null; 1004 if (plainText == Plaintext.PLAINTEXT_NULL) { 1005 // Only happens for DTLS protocols. 1006 // 1007 // Received a retransmitted flight, and need to retransmit the 1008 // previous delivered handshake flight messages. 1009 if (enableRetransmissions) { 1010 if (debug != null && Debug.isOn("verbose")) { 1011 Debug.log( 1012 "Retransmit the previous handshake flight messages."); 1013 } 1014 1015 synchronized (this) { 1016 outputRecord.launchRetransmission(); 1017 } 1018 } // Otherwise, discard the retransmitted flight. 1019 } else if (!isDTLS || plainText != null) { 1020 hsStatus = processInputRecord(plainText, appData, offset, length); 1021 } 1022 1023 if (hsStatus == null) { 1024 hsStatus = getHSStatus(null); 1025 } 1026 1027 if (plainText == null) { 1028 plainText = Plaintext.PLAINTEXT_NULL; 1029 } 1030 plainText.handshakeStatus = hsStatus; 1031 1032 return plainText; 1033 } 1034 1035 /* 1036 * Process the record. 1037 */ 1038 private synchronized HandshakeStatus processInputRecord( 1039 Plaintext plainText, 1040 ByteBuffer[] appData, int offset, int length) throws IOException { 1041 1042 HandshakeStatus hsStatus = null; 1043 switch (plainText.contentType) { 1044 case Record.ct_handshake: 1045 /* 1046 * Handshake messages always go to a pending session 1047 * handshaker ... if there isn't one, create one. This 1048 * must work asynchronously, for renegotiation. 1049 * 1050 * NOTE that handshaking will either resume a session 1051 * which was in the cache (and which might have other 1052 * connections in it already), or else will start a new 1053 * session (new keys exchanged) with just this connection 1054 * in it. 1055 */ 1056 initHandshaker(); 1057 if (!handshaker.activated()) { 1058 // prior to handshaking, activate the handshake 1059 if (connectionState == cs_RENEGOTIATE) { 1060 // don't use SSLv2Hello when renegotiating 1061 handshaker.activate(protocolVersion); 1062 } else { 1063 handshaker.activate(null); 1064 } 1065 } 1066 1067 /* 1068 * process the handshake record ... may contain just 1069 * a partial handshake message or multiple messages. 1070 * 1071 * The handshaker state machine will ensure that it's 1072 * a finished message. 1073 */ 1074 handshaker.processRecord(plainText.fragment, expectingFinished); 1075 expectingFinished = false; 1076 1077 if (handshaker.invalidated) { 1078 finishHandshake(); 1079 1080 // if state is cs_RENEGOTIATE, revert it to cs_DATA 1081 if (connectionState == cs_RENEGOTIATE) { 1082 connectionState = cs_DATA; 1083 } 1084 } else if (handshaker.isDone()) { 1085 // reset the parameters for secure renegotiation. 1086 secureRenegotiation = 1087 handshaker.isSecureRenegotiation(); 1088 clientVerifyData = handshaker.getClientVerifyData(); 1089 serverVerifyData = handshaker.getServerVerifyData(); 1090 // set connection ALPN value 1091 applicationProtocol = 1092 handshaker.getHandshakeApplicationProtocol(); 1093 1094 sess = handshaker.getSession(); 1095 handshakeSession = null; 1096 if (outputRecord.isEmpty()) { 1097 hsStatus = finishHandshake(); 1098 connectionState = cs_DATA; 1099 } 1100 1101 // No handshakeListeners here. That's a 1102 // SSLSocket thing. 1103 } else if (handshaker.taskOutstanding()) { 1104 hsStatus = HandshakeStatus.NEED_TASK; 1105 } 1106 break; 1107 1108 case Record.ct_application_data: 1109 // Pass this right back up to the application. 1110 if ((connectionState != cs_DATA) 1111 && (connectionState != cs_RENEGOTIATE) 1112 && (connectionState != cs_CLOSED)) { 1113 throw new SSLProtocolException( 1114 "Data received in non-data state: " + 1115 connectionState); 1116 } 1117 1118 if (expectingFinished) { 1119 throw new SSLProtocolException 1120 ("Expecting finished message, received data"); 1121 } 1122 1123 if (!inboundDone) { 1124 ByteBuffer fragment = plainText.fragment; 1125 int remains = fragment.remaining(); 1126 1127 // Should have enough room in appData. 1128 for (int i = offset; 1129 ((i < (offset + length)) && (remains > 0)); i++) { 1130 int amount = Math.min(appData[i].remaining(), remains); 1131 fragment.limit(fragment.position() + amount); 1132 appData[i].put(fragment); 1133 remains -= amount; 1134 } 1135 } 1136 1137 break; 1138 1139 case Record.ct_alert: 1140 recvAlert(plainText.fragment); 1141 break; 1142 1143 case Record.ct_change_cipher_spec: 1144 if ((connectionState != cs_HANDSHAKE 1145 && connectionState != cs_RENEGOTIATE)) { 1146 // For the CCS message arriving in the wrong state 1147 fatal(Alerts.alert_unexpected_message, 1148 "illegal change cipher spec msg, conn state = " 1149 + connectionState); 1150 } else if (plainText.fragment.remaining() != 1 1151 || plainText.fragment.get() != 1) { 1152 // For structural/content issues with the CCS 1153 fatal(Alerts.alert_unexpected_message, 1154 "Malformed change cipher spec msg"); 1155 } 1156 1157 // 1158 // The first message after a change_cipher_spec 1159 // record MUST be a "Finished" handshake record, 1160 // else it's a protocol violation. We force this 1161 // to be checked by a minor tweak to the state 1162 // machine. 1163 // 1164 handshaker.receiveChangeCipherSpec(); 1165 1166 CipherBox readCipher; 1167 Authenticator readAuthenticator; 1168 try { 1169 readCipher = handshaker.newReadCipher(); 1170 readAuthenticator = handshaker.newReadAuthenticator(); 1171 } catch (GeneralSecurityException e) { 1172 // can't happen 1173 throw new SSLException("Algorithm missing: ", e); 1174 } 1175 inputRecord.changeReadCiphers(readAuthenticator, readCipher); 1176 1177 // next message MUST be a finished message 1178 expectingFinished = true; 1179 break; 1180 1181 default: 1182 // 1183 // TLS requires that unrecognized records be ignored. 1184 // 1185 if (debug != null && Debug.isOn("ssl")) { 1186 System.out.println(Thread.currentThread().getName() + 1187 ", Received record type: " + plainText.contentType); 1188 } 1189 break; 1190 } // switch 1191 1192 /* 1193 * We only need to check the sequence number state for 1194 * non-handshaking record. 1195 * 1196 * Note that in order to maintain the handshake status 1197 * properly, we check the sequence number after the last 1198 * record reading process. As we request renegotiation 1199 * or close the connection for wrapped sequence number 1200 * when there is enough sequence number space left to 1201 * handle a few more records, so the sequence number 1202 * of the last record cannot be wrapped. 1203 */ 1204 hsStatus = getHSStatus(hsStatus); 1205 if (connectionState < cs_ERROR && !isInboundDone() && 1206 (hsStatus == HandshakeStatus.NOT_HANDSHAKING) && 1207 (inputRecord.seqNumIsHuge())) { 1208 /* 1209 * Ask for renegotiation when need to renew sequence number. 1210 * 1211 * Don't bother to kickstart the renegotiation when the local is 1212 * asking for it. 1213 */ 1214 if (debug != null && Debug.isOn("ssl")) { 1215 System.out.println(Thread.currentThread().getName() + 1216 ", request renegotiation " + 1217 "to avoid sequence number overflow"); 1218 } 1219 1220 beginHandshake(); 1221 1222 hsStatus = getHSStatus(null); 1223 } 1224 1225 return hsStatus; 1226 } 1227 1228 1229 // 1230 // write/wrap side 1231 // 1232 1233 1234 /** 1235 * Wraps a buffer. Does a variety of checks before grabbing 1236 * the wrapLock, which blocks multiple wraps from occurring. 1237 */ 1238 @Override 1239 public SSLEngineResult wrap(ByteBuffer[] appData, 1240 int offset, int length, ByteBuffer netData) throws SSLException { 1241 1242 // check engine parameters 1243 checkEngineParas(netData, appData, offset, length, true); 1244 1245 /* 1246 * We can be smarter about using smaller buffer sizes later. 1247 * For now, force it to be large enough to handle any valid record. 1248 */ 1249 if (netData.remaining() < sess.getPacketBufferSize()) { 1250 return new SSLEngineResult( 1251 Status.BUFFER_OVERFLOW, getHSStatus(null), 0, 0); 1252 } 1253 1254 try { 1255 synchronized (wrapLock) { 1256 return writeAppRecord(appData, offset, length, netData); 1257 } 1258 } catch (SSLProtocolException spe) { 1259 // may be an unexpected handshake message 1260 fatal(Alerts.alert_unexpected_message, spe.getMessage(), spe); 1261 return null; // make compiler happy 1262 } catch (Exception e) { 1263 fatal(Alerts.alert_internal_error, 1264 "problem wrapping app data", e); 1265 return null; // make compiler happy 1266 } 1267 } 1268 1269 /* 1270 * Makes additional checks for unwrap, but this time more 1271 * specific to this packet and the current state of the machine. 1272 */ 1273 private SSLEngineResult writeAppRecord(ByteBuffer[] appData, 1274 int offset, int length, ByteBuffer netData) throws IOException { 1275 1276 Status status = null; 1277 HandshakeStatus hsStatus = null; 1278 1279 /* 1280 * See if the handshaker needs to report back some SSLException. 1281 */ 1282 checkTaskThrown(); 1283 1284 /* 1285 * short circuit if we're closed/closing. 1286 */ 1287 if (isOutboundDone()) { 1288 return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0); 1289 } 1290 1291 /* 1292 * If we're still in cs_HANDSHAKE, make sure it's been 1293 * started. 1294 */ 1295 synchronized (this) { 1296 if ((connectionState == cs_HANDSHAKE) || 1297 (connectionState == cs_START)) { 1298 1299 kickstartHandshake(); 1300 1301 /* 1302 * If there's no HS data available to write, we can return 1303 * without trying to wrap anything. 1304 */ 1305 hsStatus = getHSStatus(null); 1306 if (hsStatus == HandshakeStatus.NEED_UNWRAP) { 1307 /* 1308 * For DTLS, if the handshake state is 1309 * HandshakeStatus.NEED_UNWRAP, a call to SSLEngine.wrap() 1310 * means that the previous handshake packets (if delivered) 1311 * get lost, and need retransmit the handshake messages. 1312 */ 1313 if (!isDTLS || !enableRetransmissions || 1314 (handshaker == null) || outputRecord.firstMessage) { 1315 1316 return new SSLEngineResult(Status.OK, hsStatus, 0, 0); 1317 } // otherwise, need retransmission 1318 } 1319 } 1320 } 1321 1322 /* 1323 * Grab a copy of this if it doesn't already exist, 1324 * and we can use it several places before anything major 1325 * happens on this side. Races aren't critical 1326 * here. 1327 */ 1328 if (hsStatus == null) { 1329 hsStatus = getHSStatus(null); 1330 } 1331 1332 /* 1333 * If we have a task outstanding, this *MUST* be done before 1334 * doing any more wrapping, because we could be in the middle 1335 * of receiving a handshake message, for example, a finished 1336 * message which would change the ciphers. 1337 */ 1338 if (hsStatus == HandshakeStatus.NEED_TASK) { 1339 return new SSLEngineResult(Status.OK, hsStatus, 0, 0); 1340 } 1341 1342 /* 1343 * This will obtain any waiting outbound data, or will 1344 * process the outbound appData. 1345 */ 1346 int netPos = netData.position(); 1347 int appRemains = 0; 1348 for (int i = offset; i < offset + length; i++) { 1349 if (appData[i] == null) { 1350 throw new IllegalArgumentException( 1351 "appData[" + i + "] == null"); 1352 } 1353 appRemains += appData[i].remaining(); 1354 } 1355 1356 Ciphertext ciphertext = null; 1357 try { 1358 if (appRemains != 0) { 1359 synchronized (writeLock) { 1360 ciphertext = writeRecord(appData, offset, length, netData); 1361 } 1362 } else { 1363 synchronized (writeLock) { 1364 ciphertext = writeRecord(null, 0, 0, netData); 1365 } 1366 } 1367 } catch (SSLException e) { 1368 throw e; 1369 } catch (IOException e) { 1370 throw new SSLException("Write problems", e); 1371 } 1372 1373 /* 1374 * writeRecord might have reported some status. 1375 * Now check for the remaining cases. 1376 * 1377 * status above should cover: NEED_WRAP/FINISHED 1378 */ 1379 status = (isOutboundDone() ? Status.CLOSED : Status.OK); 1380 hsStatus = getHSStatus(ciphertext.handshakeStatus); 1381 1382 int deltaNet = netData.position() - netPos; 1383 int deltaApp = appRemains; 1384 for (int i = offset; i < offset + length; i++) { 1385 deltaApp -= appData[i].remaining(); 1386 } 1387 1388 return new SSLEngineResult( 1389 status, hsStatus, deltaApp, deltaNet, ciphertext.recordSN); 1390 } 1391 1392 /* 1393 * Central point to write/get all of the outgoing data. 1394 */ 1395 private Ciphertext writeRecord(ByteBuffer[] appData, 1396 int offset, int length, ByteBuffer netData) throws IOException { 1397 1398 Ciphertext ciphertext = null; 1399 try { 1400 // Acquire the buffered to-be-delivered records or retransmissions. 1401 // 1402 // May have buffered records, or need retransmission if handshaking. 1403 if (!outputRecord.isEmpty() || 1404 (enableRetransmissions && handshaker != null)) { 1405 ciphertext = outputRecord.acquireCiphertext(netData); 1406 } 1407 1408 if ((ciphertext == null) && (appData != null)) { 1409 ciphertext = outputRecord.encode( 1410 appData, offset, length, netData); 1411 } 1412 } catch (SSLHandshakeException she) { 1413 // may be record sequence number overflow 1414 fatal(Alerts.alert_handshake_failure, she); 1415 1416 return Ciphertext.CIPHERTEXT_NULL; // make the complier happy 1417 } catch (IOException e) { 1418 fatal(Alerts.alert_unexpected_message, e); 1419 1420 return Ciphertext.CIPHERTEXT_NULL; // make the complier happy 1421 } 1422 1423 if (ciphertext == null) { 1424 return Ciphertext.CIPHERTEXT_NULL; 1425 } 1426 1427 HandshakeStatus hsStatus = null; 1428 Ciphertext.RecordType recordType = ciphertext.recordType; 1429 if ((recordType.contentType == Record.ct_handshake) && 1430 (recordType.handshakeType == HandshakeMessage.ht_finished) && 1431 outputRecord.isEmpty()) { 1432 1433 if (handshaker == null) { 1434 hsStatus = HandshakeStatus.FINISHED; 1435 } else if (handshaker.isDone()) { 1436 hsStatus = finishHandshake(); 1437 connectionState = cs_DATA; 1438 1439 // Retransmit the last flight twice. 1440 // 1441 // The application data transactions may begin immediately 1442 // after the last flight. If the last flight get lost, the 1443 // application data may be discarded accordingly. As could 1444 // be an issue for some applications. This impact can be 1445 // mitigated by sending the last fligth twice. 1446 if (isDTLS && enableRetransmissions) { 1447 if (debug != null && Debug.isOn("verbose")) { 1448 Debug.log( 1449 "Retransmit the last flight messages."); 1450 } 1451 1452 synchronized (this) { 1453 outputRecord.launchRetransmission(); 1454 } 1455 1456 hsStatus = HandshakeStatus.NEED_WRAP; 1457 } 1458 } 1459 } // Otherwise, the followed call to getHSStatus() will help. 1460 1461 /* 1462 * We only need to check the sequence number state for 1463 * non-handshaking record. 1464 * 1465 * Note that in order to maintain the handshake status 1466 * properly, we check the sequence number after the last 1467 * record writing process. As we request renegotiation 1468 * or close the connection for wrapped sequence number 1469 * when there is enough sequence number space left to 1470 * handle a few more records, so the sequence number 1471 * of the last record cannot be wrapped. 1472 */ 1473 hsStatus = getHSStatus(hsStatus); 1474 if (connectionState < cs_ERROR && !isOutboundDone() && 1475 (hsStatus == HandshakeStatus.NOT_HANDSHAKING) && 1476 (outputRecord.seqNumIsHuge())) { 1477 /* 1478 * Ask for renegotiation when need to renew sequence number. 1479 * 1480 * Don't bother to kickstart the renegotiation when the local is 1481 * asking for it. 1482 */ 1483 if (debug != null && Debug.isOn("ssl")) { 1484 System.out.println(Thread.currentThread().getName() + 1485 ", request renegotiation " + 1486 "to avoid sequence number overflow"); 1487 } 1488 1489 beginHandshake(); 1490 1491 hsStatus = getHSStatus(null); 1492 } 1493 ciphertext.handshakeStatus = hsStatus; 1494 1495 return ciphertext; 1496 } 1497 1498 private HandshakeStatus finishHandshake() { 1499 handshaker = null; 1500 inputRecord.setHandshakeHash(null); 1501 outputRecord.setHandshakeHash(null); 1502 connectionState = cs_DATA; 1503 1504 return HandshakeStatus.FINISHED; 1505 } 1506 1507 // 1508 // Close code 1509 // 1510 1511 /** 1512 * Signals that no more outbound application data will be sent 1513 * on this <code>SSLEngine</code>. 1514 */ 1515 private void closeOutboundInternal() { 1516 1517 if ((debug != null) && Debug.isOn("ssl")) { 1518 System.out.println(Thread.currentThread().getName() + 1519 ", closeOutboundInternal()"); 1520 } 1521 1522 /* 1523 * Already closed, ignore 1524 */ 1525 if (outboundDone) { 1526 return; 1527 } 1528 1529 switch (connectionState) { 1530 1531 /* 1532 * If we haven't even started yet, don't bother reading inbound. 1533 */ 1534 case cs_START: 1535 try { 1536 outputRecord.close(); 1537 } catch (IOException ioe) { 1538 // ignore 1539 } 1540 outboundDone = true; 1541 1542 try { 1543 inputRecord.close(); 1544 } catch (IOException ioe) { 1545 // ignore 1546 } 1547 inboundDone = true; 1548 break; 1549 1550 case cs_ERROR: 1551 case cs_CLOSED: 1552 break; 1553 1554 /* 1555 * Otherwise we indicate clean termination. 1556 */ 1557 // case cs_HANDSHAKE: 1558 // case cs_DATA: 1559 // case cs_RENEGOTIATE: 1560 default: 1561 warning(Alerts.alert_close_notify); 1562 try { 1563 outputRecord.close(); 1564 } catch (IOException ioe) { 1565 // ignore 1566 } 1567 outboundDone = true; 1568 break; 1569 } 1570 1571 connectionState = cs_CLOSED; 1572 } 1573 1574 @Override 1575 public synchronized void closeOutbound() { 1576 /* 1577 * Dump out a close_notify to the remote side 1578 */ 1579 if ((debug != null) && Debug.isOn("ssl")) { 1580 System.out.println(Thread.currentThread().getName() + 1581 ", called closeOutbound()"); 1582 } 1583 1584 closeOutboundInternal(); 1585 } 1586 1587 /** 1588 * Returns the outbound application data closure state 1589 */ 1590 @Override 1591 public boolean isOutboundDone() { 1592 return outboundDone && outputRecord.isEmpty(); 1593 } 1594 1595 /** 1596 * Signals that no more inbound network data will be sent 1597 * to this <code>SSLEngine</code>. 1598 */ 1599 private void closeInboundInternal() { 1600 1601 if ((debug != null) && Debug.isOn("ssl")) { 1602 System.out.println(Thread.currentThread().getName() + 1603 ", closeInboundInternal()"); 1604 } 1605 1606 /* 1607 * Already closed, ignore 1608 */ 1609 if (inboundDone) { 1610 return; 1611 } 1612 1613 closeOutboundInternal(); 1614 1615 try { 1616 inputRecord.close(); 1617 } catch (IOException ioe) { 1618 // ignore 1619 } 1620 inboundDone = true; 1621 1622 connectionState = cs_CLOSED; 1623 } 1624 1625 /* 1626 * Close the inbound side of the connection. We grab the 1627 * lock here, and do the real work in the internal verison. 1628 * We do check for truncation attacks. 1629 */ 1630 @Override 1631 public synchronized void closeInbound() throws SSLException { 1632 /* 1633 * Currently closes the outbound side as well. The IETF TLS 1634 * working group has expressed the opinion that 1/2 open 1635 * connections are not allowed by the spec. May change 1636 * someday in the future. 1637 */ 1638 if ((debug != null) && Debug.isOn("ssl")) { 1639 System.out.println(Thread.currentThread().getName() + 1640 ", called closeInbound()"); 1641 } 1642 1643 /* 1644 * No need to throw an Exception if we haven't even started yet. 1645 */ 1646 if ((connectionState != cs_START) && !recvCN) { 1647 recvCN = true; // Only receive the Exception once 1648 fatal(Alerts.alert_internal_error, 1649 "Inbound closed before receiving peer's close_notify: " + 1650 "possible truncation attack?"); 1651 } else { 1652 /* 1653 * Currently, this is a no-op, but in case we change 1654 * the close inbound code later. 1655 */ 1656 closeInboundInternal(); 1657 } 1658 } 1659 1660 /** 1661 * Returns the network inbound data closure state 1662 */ 1663 @Override 1664 public synchronized boolean isInboundDone() { 1665 return inboundDone; 1666 } 1667 1668 1669 // 1670 // Misc stuff 1671 // 1672 1673 1674 /** 1675 * Returns the current <code>SSLSession</code> for this 1676 * <code>SSLEngine</code> 1677 * <P> 1678 * These can be long lived, and frequently correspond to an 1679 * entire login session for some user. 1680 */ 1681 @Override 1682 public synchronized SSLSession getSession() { 1683 return sess; 1684 } 1685 1686 @Override 1687 public synchronized SSLSession getHandshakeSession() { 1688 return handshakeSession; 1689 } 1690 1691 synchronized void setHandshakeSession(SSLSessionImpl session) { 1692 // update the fragment size, which may be negotiated during handshaking 1693 inputRecord.changeFragmentSize(session.getNegotiatedMaxFragSize()); 1694 outputRecord.changeFragmentSize(session.getNegotiatedMaxFragSize()); 1695 1696 handshakeSession = session; 1697 } 1698 1699 /** 1700 * Returns a delegated <code>Runnable</code> task for 1701 * this <code>SSLEngine</code>. 1702 */ 1703 @Override 1704 public synchronized Runnable getDelegatedTask() { 1705 if (handshaker != null) { 1706 return handshaker.getTask(); 1707 } 1708 return null; 1709 } 1710 1711 1712 // 1713 // EXCEPTION AND ALERT HANDLING 1714 // 1715 1716 /* 1717 * Send a warning alert. 1718 */ 1719 void warning(byte description) { 1720 sendAlert(Alerts.alert_warning, description); 1721 } 1722 1723 synchronized void fatal(byte description, String diagnostic) 1724 throws SSLException { 1725 fatal(description, diagnostic, null, false); 1726 } 1727 1728 synchronized void fatal(byte description, Throwable cause) 1729 throws SSLException { 1730 fatal(description, null, cause, false); 1731 } 1732 1733 synchronized void fatal(byte description, String diagnostic, 1734 Throwable cause) throws SSLException { 1735 fatal(description, diagnostic, cause, false); 1736 } 1737 1738 /* 1739 * We've got a fatal error here, so start the shutdown process. 1740 * 1741 * Because of the way the code was written, we have some code 1742 * calling fatal directly when the "description" is known 1743 * and some throwing Exceptions which are then caught by higher 1744 * levels which then call here. This code needs to determine 1745 * if one of the lower levels has already started the process. 1746 * 1747 * We won't worry about Errors, if we have one of those, 1748 * we're in worse trouble. Note: the networking code doesn't 1749 * deal with Errors either. 1750 */ 1751 synchronized void fatal(byte description, String diagnostic, 1752 Throwable cause, boolean recvFatalAlert) throws SSLException { 1753 1754 /* 1755 * If we have no further information, make a general-purpose 1756 * message for folks to see. We generally have one or the other. 1757 */ 1758 if (diagnostic == null) { 1759 diagnostic = "General SSLEngine problem"; 1760 } 1761 if (cause == null) { 1762 cause = Alerts.getSSLException(description, cause, diagnostic); 1763 } 1764 1765 /* 1766 * If we've already shutdown because of an error, 1767 * there is nothing we can do except rethrow the exception. 1768 * 1769 * Most exceptions seen here will be SSLExceptions. 1770 * We may find the occasional Exception which hasn't been 1771 * converted to a SSLException, so we'll do it here. 1772 */ 1773 if (closeReason != null) { 1774 if ((debug != null) && Debug.isOn("ssl")) { 1775 System.out.println(Thread.currentThread().getName() + 1776 ", fatal: engine already closed. Rethrowing " + 1777 cause.toString()); 1778 } 1779 if (cause instanceof RuntimeException) { 1780 throw (RuntimeException)cause; 1781 } else if (cause instanceof SSLException) { 1782 throw (SSLException)cause; 1783 } else if (cause instanceof Exception) { 1784 throw new SSLException("fatal SSLEngine condition", cause); 1785 } 1786 } 1787 1788 if ((debug != null) && Debug.isOn("ssl")) { 1789 System.out.println(Thread.currentThread().getName() 1790 + ", fatal error: " + description + 1791 ": " + diagnostic + "\n" + cause.toString()); 1792 } 1793 1794 /* 1795 * Ok, this engine's going down. 1796 */ 1797 int oldState = connectionState; 1798 connectionState = cs_ERROR; 1799 1800 try { 1801 inputRecord.close(); 1802 } catch (IOException ioe) { 1803 // ignore 1804 } 1805 inboundDone = true; 1806 1807 sess.invalidate(); 1808 if (handshakeSession != null) { 1809 handshakeSession.invalidate(); 1810 } 1811 1812 /* 1813 * If we haven't even started handshaking yet, or we are the 1814 * recipient of a fatal alert, no need to generate a fatal close 1815 * alert. 1816 */ 1817 if (oldState != cs_START && !recvFatalAlert) { 1818 sendAlert(Alerts.alert_fatal, description); 1819 } 1820 1821 if (cause instanceof SSLException) { // only true if != null 1822 closeReason = (SSLException)cause; 1823 } else { 1824 /* 1825 * Including RuntimeExceptions, but we'll throw those 1826 * down below. The closeReason isn't used again, 1827 * except for null checks. 1828 */ 1829 closeReason = 1830 Alerts.getSSLException(description, cause, diagnostic); 1831 } 1832 1833 try { 1834 outputRecord.close(); 1835 } catch (IOException ioe) { 1836 // ignore 1837 } 1838 outboundDone = true; 1839 1840 connectionState = cs_CLOSED; 1841 1842 if (cause instanceof RuntimeException) { 1843 throw (RuntimeException)cause; 1844 } else { 1845 throw closeReason; 1846 } 1847 } 1848 1849 /* 1850 * Process an incoming alert ... caller must already have synchronized 1851 * access to "this". 1852 */ 1853 private void recvAlert(ByteBuffer fragment) throws IOException { 1854 byte level = fragment.get(); 1855 byte description = fragment.get(); 1856 1857 if (debug != null && (Debug.isOn("record") || 1858 Debug.isOn("handshake"))) { 1859 synchronized (System.out) { 1860 System.out.print(Thread.currentThread().getName()); 1861 System.out.print(", RECV " + protocolVersion + " ALERT: "); 1862 if (level == Alerts.alert_fatal) { 1863 System.out.print("fatal, "); 1864 } else if (level == Alerts.alert_warning) { 1865 System.out.print("warning, "); 1866 } else { 1867 System.out.print("<level " + (0x0ff & level) + ">, "); 1868 } 1869 System.out.println(Alerts.alertDescription(description)); 1870 } 1871 } 1872 1873 if (level == Alerts.alert_warning) { 1874 if (description == -1) { // check for short message 1875 fatal(Alerts.alert_illegal_parameter, "Short alert message"); 1876 } else if (description == Alerts.alert_close_notify) { 1877 if (connectionState == cs_HANDSHAKE) { 1878 fatal(Alerts.alert_unexpected_message, 1879 "Received close_notify during handshake"); 1880 } else { 1881 recvCN = true; 1882 closeInboundInternal(); // reply to close 1883 } 1884 } else { 1885 1886 // 1887 // The other legal warnings relate to certificates, 1888 // e.g. no_certificate, bad_certificate, etc; these 1889 // are important to the handshaking code, which can 1890 // also handle illegal protocol alerts if needed. 1891 // 1892 if (handshaker != null) { 1893 handshaker.handshakeAlert(description); 1894 } 1895 } 1896 } else { // fatal or unknown level 1897 String reason = "Received fatal alert: " 1898 + Alerts.alertDescription(description); 1899 1900 // The inbound and outbound queues will be closed as part of 1901 // the call to fatal. The handhaker to needs to be set to null 1902 // so subsequent calls to getHandshakeStatus will return 1903 // NOT_HANDSHAKING. 1904 handshaker = null; 1905 Throwable cause = Alerts.getSSLException(description, reason); 1906 fatal(description, null, cause, true); 1907 } 1908 } 1909 1910 1911 /* 1912 * Emit alerts. Caller must have synchronized with "this". 1913 */ 1914 private void sendAlert(byte level, byte description) { 1915 // the connectionState cannot be cs_START 1916 if (connectionState >= cs_CLOSED) { 1917 return; 1918 } 1919 1920 // For initial handshaking, don't send alert message to peer if 1921 // handshaker has not started. 1922 // 1923 // Shall we send an fatal alter to terminate the connection gracefully? 1924 if (connectionState <= cs_HANDSHAKE && 1925 (handshaker == null || !handshaker.started() || 1926 !handshaker.activated())) { 1927 return; 1928 } 1929 1930 try { 1931 outputRecord.encodeAlert(level, description); 1932 } catch (IOException ioe) { 1933 // ignore 1934 } 1935 } 1936 1937 1938 // 1939 // VARIOUS OTHER METHODS (COMMON TO SSLSocket) 1940 // 1941 1942 1943 /** 1944 * Controls whether new connections may cause creation of new SSL 1945 * sessions. 1946 * 1947 * As long as handshaking has not started, we can change 1948 * whether we enable session creations. Otherwise, 1949 * we will need to wait for the next handshake. 1950 */ 1951 @Override 1952 public synchronized void setEnableSessionCreation(boolean flag) { 1953 enableSessionCreation = flag; 1954 1955 if ((handshaker != null) && !handshaker.activated()) { 1956 handshaker.setEnableSessionCreation(enableSessionCreation); 1957 } 1958 } 1959 1960 /** 1961 * Returns true if new connections may cause creation of new SSL 1962 * sessions. 1963 */ 1964 @Override 1965 public synchronized boolean getEnableSessionCreation() { 1966 return enableSessionCreation; 1967 } 1968 1969 1970 /** 1971 * Sets the flag controlling whether a server mode engine 1972 * *REQUIRES* SSL client authentication. 1973 * 1974 * As long as handshaking has not started, we can change 1975 * whether client authentication is needed. Otherwise, 1976 * we will need to wait for the next handshake. 1977 */ 1978 @Override 1979 public synchronized void setNeedClientAuth(boolean flag) { 1980 doClientAuth = (flag ? 1981 ClientAuthType.CLIENT_AUTH_REQUIRED : 1982 ClientAuthType.CLIENT_AUTH_NONE); 1983 1984 if ((handshaker != null) && 1985 (handshaker instanceof ServerHandshaker) && 1986 !handshaker.activated()) { 1987 ((ServerHandshaker) handshaker).setClientAuth(doClientAuth); 1988 } 1989 } 1990 1991 @Override 1992 public synchronized boolean getNeedClientAuth() { 1993 return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUIRED); 1994 } 1995 1996 /** 1997 * Sets the flag controlling whether a server mode engine 1998 * *REQUESTS* SSL client authentication. 1999 * 2000 * As long as handshaking has not started, we can change 2001 * whether client authentication is requested. Otherwise, 2002 * we will need to wait for the next handshake. 2003 */ 2004 @Override 2005 public synchronized void setWantClientAuth(boolean flag) { 2006 doClientAuth = (flag ? 2007 ClientAuthType.CLIENT_AUTH_REQUESTED : 2008 ClientAuthType.CLIENT_AUTH_NONE); 2009 2010 if ((handshaker != null) && 2011 (handshaker instanceof ServerHandshaker) && 2012 !handshaker.activated()) { 2013 ((ServerHandshaker) handshaker).setClientAuth(doClientAuth); 2014 } 2015 } 2016 2017 @Override 2018 public synchronized boolean getWantClientAuth() { 2019 return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUESTED); 2020 } 2021 2022 2023 /** 2024 * Sets the flag controlling whether the engine is in SSL 2025 * client or server mode. Must be called before any SSL 2026 * traffic has started. 2027 */ 2028 @Override 2029 @SuppressWarnings("fallthrough") 2030 public synchronized void setUseClientMode(boolean flag) { 2031 switch (connectionState) { 2032 2033 case cs_START: 2034 /* 2035 * If we need to change the socket mode and the enabled 2036 * protocols and cipher suites haven't specifically been 2037 * set by the user, change them to the corresponding 2038 * default ones. 2039 */ 2040 if (roleIsServer != (!flag)) { 2041 if (sslContext.isDefaultProtocolList(enabledProtocols)) { 2042 enabledProtocols = 2043 sslContext.getDefaultProtocolList(!flag); 2044 } 2045 2046 if (sslContext.isDefaultCipherSuiteList(enabledCipherSuites)) { 2047 enabledCipherSuites = 2048 sslContext.getDefaultCipherSuiteList(!flag); 2049 } 2050 } 2051 2052 roleIsServer = !flag; 2053 serverModeSet = true; 2054 break; 2055 2056 case cs_HANDSHAKE: 2057 /* 2058 * If we have a handshaker, but haven't started 2059 * SSL traffic, we can throw away our current 2060 * handshaker, and start from scratch. Don't 2061 * need to call doneConnect() again, we already 2062 * have the streams. 2063 */ 2064 assert(handshaker != null); 2065 if (!handshaker.activated()) { 2066 /* 2067 * If we need to change the socket mode and the enabled 2068 * protocols and cipher suites haven't specifically been 2069 * set by the user, change them to the corresponding 2070 * default ones. 2071 */ 2072 if (roleIsServer != (!flag)) { 2073 if (sslContext.isDefaultProtocolList(enabledProtocols)) { 2074 enabledProtocols = 2075 sslContext.getDefaultProtocolList(!flag); 2076 } 2077 2078 if (sslContext.isDefaultCipherSuiteList( 2079 enabledCipherSuites)) { 2080 enabledCipherSuites = 2081 sslContext.getDefaultCipherSuiteList(!flag); 2082 } 2083 } 2084 2085 roleIsServer = !flag; 2086 connectionState = cs_START; 2087 initHandshaker(); 2088 break; 2089 } 2090 2091 // If handshake has started, that's an error. Fall through... 2092 2093 default: 2094 if (debug != null && Debug.isOn("ssl")) { 2095 System.out.println(Thread.currentThread().getName() + 2096 ", setUseClientMode() invoked in state = " + 2097 connectionState); 2098 } 2099 2100 /* 2101 * We can let them continue if they catch this correctly, 2102 * we don't need to shut this down. 2103 */ 2104 throw new IllegalArgumentException( 2105 "Cannot change mode after SSL traffic has started"); 2106 } 2107 } 2108 2109 @Override 2110 public synchronized boolean getUseClientMode() { 2111 return !roleIsServer; 2112 } 2113 2114 2115 /** 2116 * Returns the names of the cipher suites which could be enabled for use 2117 * on an SSL connection. Normally, only a subset of these will actually 2118 * be enabled by default, since this list may include cipher suites which 2119 * do not support the mutual authentication of servers and clients, or 2120 * which do not protect data confidentiality. Servers may also need 2121 * certain kinds of certificates to use certain cipher suites. 2122 * 2123 * @return an array of cipher suite names 2124 */ 2125 @Override 2126 public String[] getSupportedCipherSuites() { 2127 return sslContext.getSupportedCipherSuiteList().toStringArray(); 2128 } 2129 2130 /** 2131 * Controls which particular cipher suites are enabled for use on 2132 * this connection. The cipher suites must have been listed by 2133 * getCipherSuites() as being supported. Even if a suite has been 2134 * enabled, it might never be used if no peer supports it or the 2135 * requisite certificates (and private keys) are not available. 2136 * 2137 * @param suites Names of all the cipher suites to enable. 2138 */ 2139 @Override 2140 public synchronized void setEnabledCipherSuites(String[] suites) { 2141 enabledCipherSuites = new CipherSuiteList(suites); 2142 if ((handshaker != null) && !handshaker.activated()) { 2143 handshaker.setEnabledCipherSuites(enabledCipherSuites); 2144 } 2145 } 2146 2147 /** 2148 * Returns the names of the SSL cipher suites which are currently enabled 2149 * for use on this connection. When an SSL engine is first created, 2150 * all enabled cipher suites <em>(a)</em> protect data confidentiality, 2151 * by traffic encryption, and <em>(b)</em> can mutually authenticate 2152 * both clients and servers. Thus, in some environments, this value 2153 * might be empty. 2154 * 2155 * @return an array of cipher suite names 2156 */ 2157 @Override 2158 public synchronized String[] getEnabledCipherSuites() { 2159 return enabledCipherSuites.toStringArray(); 2160 } 2161 2162 2163 /** 2164 * Returns the protocols that are supported by this implementation. 2165 * A subset of the supported protocols may be enabled for this connection 2166 * @return an array of protocol names. 2167 */ 2168 @Override 2169 public String[] getSupportedProtocols() { 2170 return sslContext.getSuportedProtocolList().toStringArray(); 2171 } 2172 2173 /** 2174 * Controls which protocols are enabled for use on 2175 * this connection. The protocols must have been listed by 2176 * getSupportedProtocols() as being supported. 2177 * 2178 * @param protocols protocols to enable. 2179 * @exception IllegalArgumentException when one of the protocols 2180 * named by the parameter is not supported. 2181 */ 2182 @Override 2183 public synchronized void setEnabledProtocols(String[] protocols) { 2184 enabledProtocols = new ProtocolList(protocols); 2185 if ((handshaker != null) && !handshaker.activated()) { 2186 handshaker.setEnabledProtocols(enabledProtocols); 2187 } 2188 } 2189 2190 @Override 2191 public synchronized String[] getEnabledProtocols() { 2192 return enabledProtocols.toStringArray(); 2193 } 2194 2195 /** 2196 * Returns the SSLParameters in effect for this SSLEngine. 2197 */ 2198 @Override 2199 public synchronized SSLParameters getSSLParameters() { 2200 SSLParameters params = super.getSSLParameters(); 2201 2202 // the super implementation does not handle the following parameters 2203 params.setEndpointIdentificationAlgorithm(identificationProtocol); 2204 params.setAlgorithmConstraints(algorithmConstraints); 2205 params.setSNIMatchers(sniMatchers); 2206 params.setServerNames(serverNames); 2207 params.setUseCipherSuitesOrder(preferLocalCipherSuites); 2208 params.setEnableRetransmissions(enableRetransmissions); 2209 params.setMaximumPacketSize(maximumPacketSize); 2210 params.setApplicationProtocols(applicationProtocols); 2211 2212 return params; 2213 } 2214 2215 /** 2216 * Applies SSLParameters to this engine. 2217 */ 2218 @Override 2219 public synchronized void setSSLParameters(SSLParameters params) { 2220 super.setSSLParameters(params); 2221 2222 // the super implementation does not handle the following parameters 2223 identificationProtocol = params.getEndpointIdentificationAlgorithm(); 2224 algorithmConstraints = params.getAlgorithmConstraints(); 2225 preferLocalCipherSuites = params.getUseCipherSuitesOrder(); 2226 enableRetransmissions = params.getEnableRetransmissions(); 2227 maximumPacketSize = params.getMaximumPacketSize(); 2228 2229 if (maximumPacketSize != 0) { 2230 outputRecord.changePacketSize(maximumPacketSize); 2231 } else { 2232 // use the implicit maximum packet size. 2233 maximumPacketSize = outputRecord.getMaxPacketSize(); 2234 } 2235 2236 List<SNIServerName> sniNames = params.getServerNames(); 2237 if (sniNames != null) { 2238 serverNames = sniNames; 2239 } 2240 2241 Collection<SNIMatcher> matchers = params.getSNIMatchers(); 2242 if (matchers != null) { 2243 sniMatchers = matchers; 2244 } 2245 applicationProtocols = params.getApplicationProtocols(); 2246 2247 if ((handshaker != null) && !handshaker.activated()) { 2248 handshaker.setIdentificationProtocol(identificationProtocol); 2249 handshaker.setAlgorithmConstraints(algorithmConstraints); 2250 handshaker.setMaximumPacketSize(maximumPacketSize); 2251 handshaker.setApplicationProtocols(applicationProtocols); 2252 if (roleIsServer) { 2253 handshaker.setSNIMatchers(sniMatchers); 2254 handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites); 2255 } else { 2256 handshaker.setSNIServerNames(serverNames); 2257 } 2258 } 2259 } 2260 2261 @Override 2262 public synchronized String getApplicationProtocol() { 2263 return applicationProtocol; 2264 } 2265 2266 @Override 2267 public synchronized String getHandshakeApplicationProtocol() { 2268 if ((handshaker != null) && handshaker.started()) { 2269 return handshaker.getHandshakeApplicationProtocol(); 2270 } 2271 return null; 2272 } 2273 2274 @Override 2275 public synchronized void setHandshakeApplicationProtocolSelector( 2276 BiFunction<SSLEngine, List<String>, String> selector) { 2277 applicationProtocolSelector = selector; 2278 if ((handshaker != null) && !handshaker.activated()) { 2279 handshaker.setApplicationProtocolSelectorSSLEngine(selector); 2280 } 2281 } 2282 2283 @Override 2284 public synchronized BiFunction<SSLEngine, List<String>, String> 2285 getHandshakeApplicationProtocolSelector() { 2286 return this.applicationProtocolSelector; 2287 } 2288 2289 /** 2290 * Returns a printable representation of this end of the connection. 2291 */ 2292 @Override 2293 public String toString() { 2294 StringBuilder retval = new StringBuilder(80); 2295 2296 retval.append(Integer.toHexString(hashCode())); 2297 retval.append("["); 2298 retval.append("SSLEngine[hostname="); 2299 String host = getPeerHost(); 2300 retval.append((host == null) ? "null" : host); 2301 retval.append(" port="); 2302 retval.append(Integer.toString(getPeerPort())); 2303 retval.append(" role=" + (roleIsServer ? "Server" : "Client")); 2304 retval.append("] "); 2305 retval.append(getSession().getCipherSuite()); 2306 retval.append("]"); 2307 2308 return retval.toString(); 2309 } 2310 } | 1 /* 2 * Copyright (c) 2003, 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.IOException; 29 import java.nio.ByteBuffer; 30 import java.nio.ReadOnlyBufferException; 31 import java.security.AccessController; 32 import java.security.PrivilegedActionException; 33 import java.security.PrivilegedExceptionAction; 34 import java.util.List; 35 import java.util.Map; 36 import java.util.function.BiFunction; 37 import javax.net.ssl.SSLEngine; 38 import javax.net.ssl.SSLEngineResult; 39 import javax.net.ssl.SSLEngineResult.HandshakeStatus; 40 import javax.net.ssl.SSLEngineResult.Status; 41 import javax.net.ssl.SSLException; 42 import javax.net.ssl.SSLHandshakeException; 43 import javax.net.ssl.SSLKeyException; 44 import javax.net.ssl.SSLParameters; 45 import javax.net.ssl.SSLPeerUnverifiedException; 46 import javax.net.ssl.SSLProtocolException; 47 import javax.net.ssl.SSLSession; 48 49 /** 50 * Implementation of an non-blocking SSLEngine. 51 * 52 * @author Brad Wetmore 53 */ 54 final class SSLEngineImpl extends SSLEngine implements SSLTransport { 55 private final SSLContextImpl sslContext; 56 final TransportContext conContext; 57 58 /** 59 * Constructor for an SSLEngine from SSLContext, without 60 * host/port hints. 61 * 62 * This Engine will not be able to cache sessions, but must renegotiate 63 * everything by hand. 64 */ 65 SSLEngineImpl(SSLContextImpl sslContext) { 66 this(sslContext, null, -1); 67 } 68 69 /** 70 * Constructor for an SSLEngine from SSLContext. 71 */ 72 SSLEngineImpl(SSLContextImpl sslContext, 73 String host, int port) { 74 super(host, port); 75 this.sslContext = sslContext; 76 HandshakeHash handshakeHash = new HandshakeHash(); 77 if (sslContext.isDTLS()) { 78 this.conContext = new TransportContext(sslContext, this, 79 new DTLSInputRecord(handshakeHash), 80 new DTLSOutputRecord(handshakeHash)); 81 } else { 82 this.conContext = new TransportContext(sslContext, this, 83 new SSLEngineInputRecord(handshakeHash), 84 new SSLEngineOutputRecord(handshakeHash)); 85 } 86 87 // Server name indication is a connection scope extension. 88 if (host != null) { 89 this.conContext.sslConfig.serverNames = 90 Utilities.addToSNIServerNameList( 91 conContext.sslConfig.serverNames, host); 92 } 93 } 94 95 @Override 96 public synchronized void beginHandshake() throws SSLException { 97 if (conContext.isUnsureMode) { 98 throw new IllegalStateException( 99 "Client/Server mode has not yet been set."); 100 } 101 102 try { 103 conContext.kickstart(); 104 } catch (IOException ioe) { 105 conContext.fatal(Alert.HANDSHAKE_FAILURE, 106 "Couldn't kickstart handshaking", ioe); 107 } catch (Exception ex) { // including RuntimeException 108 conContext.fatal(Alert.INTERNAL_ERROR, 109 "Fail to begin handshake", ex); 110 } 111 } 112 113 @Override 114 public synchronized SSLEngineResult wrap(ByteBuffer[] appData, 115 int offset, int length, ByteBuffer netData) throws SSLException { 116 return wrap( 117 appData, offset, length, new ByteBuffer[]{ netData }, 0, 1); 118 } 119 120 // @Override 121 public synchronized SSLEngineResult wrap( 122 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 123 ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws SSLException { 124 125 if (conContext.isUnsureMode) { 126 throw new IllegalStateException( 127 "Client/Server mode has not yet been set."); 128 } 129 130 // See if the handshaker needs to report back some SSLException. 131 if (conContext.outputRecord.isEmpty()) { 132 checkTaskThrown(); 133 } // Otherwise, deliver cached records before throwing task exception. 134 135 // check parameters 136 checkParams(srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength); 137 138 try { 139 return writeRecord( 140 srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength); 141 } catch (SSLProtocolException spe) { 142 // may be an unexpected handshake message 143 conContext.fatal(Alert.UNEXPECTED_MESSAGE, spe); 144 } catch (IOException ioe) { 145 conContext.fatal(Alert.INTERNAL_ERROR, 146 "problem wrapping app data", ioe); 147 } catch (Exception ex) { // including RuntimeException 148 conContext.fatal(Alert.INTERNAL_ERROR, 149 "Fail to wrap application data", ex); 150 } 151 152 return null; // make compiler happy 153 } 154 155 private SSLEngineResult writeRecord( 156 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 157 ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException { 158 159 if (isOutboundDone()) { 160 return new SSLEngineResult( 161 Status.CLOSED, getHandshakeStatus(), 0, 0); 162 } 163 164 HandshakeContext hc = conContext.handshakeContext; 165 HandshakeStatus hsStatus = null; 166 if (!conContext.isNegotiated) { 167 conContext.kickstart(); 168 169 hsStatus = getHandshakeStatus(); 170 if (hsStatus == HandshakeStatus.NEED_UNWRAP) { 171 /* 172 * For DTLS, if the handshake state is 173 * HandshakeStatus.NEED_UNWRAP, a call to SSLEngine.wrap() 174 * means that the previous handshake packets (if delivered) 175 * get lost, and need retransmit the handshake messages. 176 */ 177 if (!sslContext.isDTLS() || hc == null || 178 !hc.sslConfig.enableRetransmissions || 179 conContext.outputRecord.firstMessage) { 180 181 return new SSLEngineResult(Status.OK, hsStatus, 0, 0); 182 } // otherwise, need retransmission 183 } 184 } 185 186 if (hsStatus == null) { 187 hsStatus = getHandshakeStatus(); 188 } 189 190 /* 191 * If we have a task outstanding, this *MUST* be done before 192 * doing any more wrapping, because we could be in the middle 193 * of receiving a handshake message, for example, a finished 194 * message which would change the ciphers. 195 */ 196 if (hsStatus == HandshakeStatus.NEED_TASK) { 197 return new SSLEngineResult(Status.OK, hsStatus, 0, 0); 198 } 199 200 int dstsRemains = 0; 201 for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) { 202 dstsRemains += dsts[i].remaining(); 203 } 204 205 // Check destination buffer size. 206 // 207 // We can be smarter about using smaller buffer sizes later. For 208 // now, force it to be large enough to handle any valid record. 209 if (dstsRemains < conContext.conSession.getPacketBufferSize()) { 210 return new SSLEngineResult( 211 Status.BUFFER_OVERFLOW, getHandshakeStatus(), 0, 0); 212 } 213 214 int srcsRemains = 0; 215 for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) { 216 srcsRemains += srcs[i].remaining(); 217 } 218 219 Ciphertext ciphertext = null; 220 try { 221 // Acquire the buffered to-be-delivered records or retransmissions. 222 // 223 // May have buffered records, or need retransmission if handshaking. 224 if (!conContext.outputRecord.isEmpty() || (hc != null && 225 hc.sslConfig.enableRetransmissions && 226 hc.sslContext.isDTLS() && 227 hsStatus == HandshakeStatus.NEED_UNWRAP)) { 228 ciphertext = encode(null, 0, 0, 229 dsts, dstsOffset, dstsLength); 230 } 231 232 if (ciphertext == null && srcsRemains != 0) { 233 ciphertext = encode(srcs, srcsOffset, srcsLength, 234 dsts, dstsOffset, dstsLength); 235 } 236 } catch (IOException ioe) { 237 if (ioe instanceof SSLException) { 238 throw ioe; 239 } else { 240 throw new SSLException("Write problems", ioe); 241 } 242 } 243 244 /* 245 * Check for status. 246 */ 247 Status status = (isOutboundDone() ? Status.CLOSED : Status.OK); 248 if (ciphertext != null && ciphertext.handshakeStatus != null) { 249 hsStatus = ciphertext.handshakeStatus; 250 } else { 251 hsStatus = getHandshakeStatus(); 252 } 253 254 int deltaSrcs = srcsRemains; 255 for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) { 256 deltaSrcs -= srcs[i].remaining(); 257 } 258 259 int deltaDsts = dstsRemains; 260 for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) { 261 deltaDsts -= dsts[i].remaining(); 262 } 263 264 return new SSLEngineResult(status, hsStatus, deltaSrcs, deltaDsts, 265 ciphertext != null ? ciphertext.recordSN : -1L); 266 } 267 268 private Ciphertext encode( 269 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 270 ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException { 271 272 Ciphertext ciphertext = null; 273 try { 274 ciphertext = conContext.outputRecord.encode( 275 srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength); 276 } catch (SSLHandshakeException she) { 277 // may be record sequence number overflow 278 conContext.fatal(Alert.HANDSHAKE_FAILURE, she); 279 } catch (IOException e) { 280 conContext.fatal(Alert.UNEXPECTED_MESSAGE, e); 281 } 282 283 if (ciphertext == null) { 284 return Ciphertext.CIPHERTEXT_NULL; 285 } 286 287 // Is the handshake completed? 288 boolean needRetransmission = 289 conContext.sslContext.isDTLS() && 290 conContext.handshakeContext != null && 291 conContext.handshakeContext.sslConfig.enableRetransmissions; 292 HandshakeStatus hsStatus = 293 tryToFinishHandshake(ciphertext.contentType); 294 if (needRetransmission && 295 hsStatus == HandshakeStatus.FINISHED && 296 conContext.sslContext.isDTLS() && 297 ciphertext.handshakeType == SSLHandshake.FINISHED.id) { 298 // Retransmit the last flight for DTLS. 299 // 300 // The application data transactions may begin immediately 301 // after the last flight. If the last flight get lost, the 302 // application data may be discarded accordingly. As could 303 // be an issue for some applications. This impact can be 304 // mitigated by sending the last fligth twice. 305 if (SSLLogger.isOn && SSLLogger.isOn("ssl,verbose")) { 306 SSLLogger.finest("retransmit the last flight messages"); 307 } 308 309 conContext.outputRecord.launchRetransmission(); 310 hsStatus = HandshakeStatus.NEED_WRAP; 311 } 312 313 if (hsStatus == null) { 314 hsStatus = conContext.getHandshakeStatus(); 315 } 316 317 // Is the sequence number is nearly overflow? 318 if (conContext.outputRecord.seqNumIsHuge()) { 319 hsStatus = tryKeyUpdate(hsStatus); 320 } 321 322 // update context status 323 ciphertext.handshakeStatus = hsStatus; 324 325 return ciphertext; 326 } 327 328 private HandshakeStatus tryToFinishHandshake(byte contentType) { 329 HandshakeStatus hsStatus = null; 330 if ((contentType == ContentType.HANDSHAKE.id) && 331 conContext.outputRecord.isEmpty()) { 332 if (conContext.handshakeContext == null) { 333 hsStatus = HandshakeStatus.FINISHED; 334 } else if (conContext.handshakeContext.handshakeFinished) { 335 hsStatus = conContext.finishHandshake(); 336 } 337 } // Otherwise, the followed call to getHSStatus() will help. 338 339 return hsStatus; 340 } 341 342 /** 343 * Try renegotiation or key update for sequence number wrap. 344 * 345 * Note that in order to maintain the handshake status properly, we check 346 * the sequence number after the last record reading/writing process. As 347 * we request renegotiation or close the connection for wrapped sequence 348 * number when there is enough sequence number space left to handle a few 349 * more records, so the sequence number of the last record cannot be 350 * wrapped. 351 */ 352 private HandshakeStatus tryKeyUpdate( 353 HandshakeStatus currentHandshakeStatus) throws IOException { 354 // Don't bother to kickstart the renegotiation or key update when the 355 // local is asking for it. 356 if ((conContext.handshakeContext == null) && 357 !conContext.isClosed() && !conContext.isBroken) { 358 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 359 SSLLogger.finest("key update to wrap sequence number"); 360 } 361 conContext.keyUpdate(); 362 return conContext.getHandshakeStatus(); 363 } 364 365 return currentHandshakeStatus; 366 } 367 368 private static void checkParams( 369 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 370 ByteBuffer[] dsts, int dstsOffset, int dstsLength) { 371 372 if ((srcs == null) || (dsts == null)) { 373 throw new IllegalArgumentException( 374 "source or destination buffer is null"); 375 } 376 377 if ((srcsOffset < 0) || (srcsLength < 0) || 378 (srcsOffset > srcs.length - srcsLength)) { 379 throw new IndexOutOfBoundsException( 380 "index out of bound of the source buffers"); 381 } 382 383 if ((dstsOffset < 0) || (dstsLength < 0) || 384 (dstsOffset > dsts.length - dstsLength)) { 385 throw new IndexOutOfBoundsException( 386 "index out of bound of the destination buffers"); 387 } 388 389 for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) { 390 if (srcs[i] == null) { 391 throw new IllegalArgumentException( 392 "source buffer[" + i + "] == null"); 393 } 394 } 395 396 for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) { 397 if (dsts[i] == null) { 398 throw new IllegalArgumentException( 399 "destination buffer[" + i + "] == null"); 400 } 401 402 /* 403 * Make sure the destination bufffers are writable. 404 */ 405 if (dsts[i].isReadOnly()) { 406 throw new ReadOnlyBufferException(); 407 } 408 } 409 } 410 411 @Override 412 public synchronized SSLEngineResult unwrap(ByteBuffer src, 413 ByteBuffer[] dsts, int offset, int length) throws SSLException { 414 return unwrap( 415 new ByteBuffer[]{src}, 0, 1, dsts, offset, length); 416 } 417 418 // @Override 419 public synchronized SSLEngineResult unwrap( 420 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 421 ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws SSLException { 422 423 if (conContext.isUnsureMode) { 424 throw new IllegalStateException( 425 "Client/Server mode has not yet been set."); 426 } 427 428 // See if the handshaker needs to report back some SSLException. 429 checkTaskThrown(); 430 431 // check parameters 432 checkParams(srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength); 433 434 try { 435 return readRecord( 436 srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength); 437 } catch (SSLProtocolException spe) { 438 // may be an unexpected handshake message 439 conContext.fatal(Alert.UNEXPECTED_MESSAGE, 440 spe.getMessage(), spe); 441 } catch (IOException ioe) { 442 /* 443 * Don't reset position so it looks like we didn't 444 * consume anything. We did consume something, and it 445 * got us into this situation, so report that much back. 446 * Our days of consuming are now over anyway. 447 */ 448 conContext.fatal(Alert.INTERNAL_ERROR, 449 "problem unwrapping net record", ioe); 450 } catch (Exception ex) { // including RuntimeException 451 conContext.fatal(Alert.INTERNAL_ERROR, 452 "Fail to unwrap network record", ex); 453 } 454 455 return null; // make compiler happy 456 } 457 458 private SSLEngineResult readRecord( 459 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 460 ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException { 461 462 /* 463 * Check if we are closing/closed. 464 */ 465 if (isInboundDone()) { 466 return new SSLEngineResult( 467 Status.CLOSED, getHandshakeStatus(), 0, 0); 468 } 469 470 HandshakeStatus hsStatus = null; 471 if (!conContext.isNegotiated) { 472 conContext.kickstart(); 473 474 /* 475 * If there's still outbound data to flush, we 476 * can return without trying to unwrap anything. 477 */ 478 hsStatus = getHandshakeStatus(); 479 if (hsStatus == HandshakeStatus.NEED_WRAP) { 480 return new SSLEngineResult(Status.OK, hsStatus, 0, 0); 481 } 482 } 483 484 if (hsStatus == null) { 485 hsStatus = getHandshakeStatus(); 486 } 487 488 /* 489 * If we have a task outstanding, this *MUST* be done before 490 * doing any more unwrapping, because we could be in the middle 491 * of receiving a handshake message, for example, a finished 492 * message which would change the ciphers. 493 */ 494 if (hsStatus == HandshakeStatus.NEED_TASK) { 495 return new SSLEngineResult(Status.OK, hsStatus, 0, 0); 496 } 497 498 if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_UNWRAP_AGAIN) { 499 Plaintext plainText = null; 500 try { 501 plainText = decode(null, 0, 0, 502 dsts, dstsOffset, dstsLength); 503 } catch (IOException ioe) { 504 if (ioe instanceof SSLException) { 505 throw ioe; 506 } else { 507 throw new SSLException("readRecord", ioe); 508 } 509 } 510 511 Status status = (isInboundDone() ? Status.CLOSED : Status.OK); 512 if (plainText.handshakeStatus != null) { 513 hsStatus = plainText.handshakeStatus; 514 } else { 515 hsStatus = getHandshakeStatus(); 516 } 517 518 return new SSLEngineResult( 519 status, hsStatus, 0, 0, plainText.recordSN); 520 } 521 522 int srcsRemains = 0; 523 for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) { 524 srcsRemains += srcs[i].remaining(); 525 } 526 527 if (srcsRemains == 0) { 528 return new SSLEngineResult(Status.OK, getHandshakeStatus(), 0, 0); 529 } 530 531 /* 532 * Check the packet to make sure enough is here. 533 * This will also indirectly check for 0 len packets. 534 */ 535 int packetLen = 0; 536 try { 537 packetLen = conContext.inputRecord.bytesInCompletePacket( 538 srcs, srcsOffset, srcsLength); 539 } catch (SSLException ssle) { 540 // Need to discard invalid records for DTLS protocols. 541 if (sslContext.isDTLS()) { 542 if (SSLLogger.isOn && SSLLogger.isOn("ssl,verbose")) { 543 SSLLogger.finest("Discard invalid DTLS records", ssle); 544 } 545 546 // invalid, discard the entire data [section 4.1.2.7, RFC 6347] 547 // TODO 548 int deltaNet = 0; 549 // int deltaNet = netData.remaining(); 550 // netData.position(netData.limit()); 551 552 Status status = (isInboundDone() ? Status.CLOSED : Status.OK); 553 if (hsStatus == null) { 554 hsStatus = getHandshakeStatus(); 555 } 556 557 return new SSLEngineResult(status, hsStatus, deltaNet, 0, -1L); 558 } else { 559 throw ssle; 560 } 561 } 562 563 // Is this packet bigger than SSL/TLS normally allows? 564 if (packetLen > conContext.conSession.getPacketBufferSize()) { 565 int largestRecordSize = sslContext.isDTLS() ? 566 DTLSRecord.maxRecordSize : SSLRecord.maxLargeRecordSize; 567 if ((packetLen <= largestRecordSize) && !sslContext.isDTLS()) { 568 // Expand the expected maximum packet/application buffer 569 // sizes. 570 // 571 // Only apply to SSL/TLS protocols. 572 573 // Old behavior: shall we honor the System Property 574 // "jsse.SSLEngine.acceptLargeFragments" if it is "false"? 575 conContext.conSession.expandBufferSizes(); 576 } 577 578 // check the packet again 579 largestRecordSize = conContext.conSession.getPacketBufferSize(); 580 if (packetLen > largestRecordSize) { 581 throw new SSLProtocolException( 582 "Input record too big: max = " + 583 largestRecordSize + " len = " + packetLen); 584 } 585 } 586 587 /* 588 * Check for OVERFLOW. 589 * 590 * Delay enforcing the application buffer free space requirement 591 * until after the initial handshaking. 592 */ 593 int dstsRemains = 0; 594 for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) { 595 dstsRemains += dsts[i].remaining(); 596 } 597 598 if (conContext.isNegotiated) { 599 int FragLen = 600 conContext.inputRecord.estimateFragmentSize(packetLen); 601 if (FragLen > dstsRemains) { 602 return new SSLEngineResult( 603 Status.BUFFER_OVERFLOW, hsStatus, 0, 0); 604 } 605 } 606 607 // check for UNDERFLOW. 608 if ((packetLen == -1) || (srcsRemains < packetLen)) { 609 return new SSLEngineResult(Status.BUFFER_UNDERFLOW, hsStatus, 0, 0); 610 } 611 612 /* 613 * We're now ready to actually do the read. 614 */ 615 Plaintext plainText = null; 616 try { 617 plainText = decode(srcs, srcsOffset, srcsLength, 618 dsts, dstsOffset, dstsLength); 619 } catch (IOException ioe) { 620 if (ioe instanceof SSLException) { 621 throw ioe; 622 } else { 623 throw new SSLException("readRecord", ioe); 624 } 625 } 626 627 /* 628 * Check the various condition that we could be reporting. 629 * 630 * It's *possible* something might have happened between the 631 * above and now, but it was better to minimally lock "this" 632 * during the read process. We'll return the current 633 * status, which is more representative of the current state. 634 * 635 * status above should cover: FINISHED, NEED_TASK 636 */ 637 Status status = (isInboundDone() ? Status.CLOSED : Status.OK); 638 if (plainText.handshakeStatus != null) { 639 hsStatus = plainText.handshakeStatus; 640 } else { 641 hsStatus = getHandshakeStatus(); 642 } 643 644 int deltaNet = srcsRemains; 645 for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) { 646 deltaNet -= srcs[i].remaining(); 647 } 648 649 int deltaApp = dstsRemains; 650 for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) { 651 deltaApp -= dsts[i].remaining(); 652 } 653 654 return new SSLEngineResult( 655 status, hsStatus, deltaNet, deltaApp, plainText.recordSN); 656 } 657 658 private Plaintext decode( 659 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 660 ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException { 661 662 Plaintext pt = SSLTransport.decode(conContext, 663 srcs, srcsOffset, srcsLength, 664 dsts, dstsOffset, dstsLength); 665 666 // Is the handshake completed? 667 if (pt != Plaintext.PLAINTEXT_NULL) { 668 HandshakeStatus hsStatus = tryToFinishHandshake(pt.contentType); 669 if (hsStatus == null) { 670 pt.handshakeStatus = conContext.getHandshakeStatus(); 671 } else { 672 pt.handshakeStatus = hsStatus; 673 } 674 675 // Is the sequence number is nearly overflow? 676 if (conContext.inputRecord.seqNumIsHuge()) { 677 pt.handshakeStatus = 678 tryKeyUpdate(pt.handshakeStatus); 679 } 680 } 681 682 return pt; 683 } 684 685 @Override 686 public synchronized Runnable getDelegatedTask() { 687 if (conContext.handshakeContext != null && 688 !conContext.handshakeContext.taskDelegated && 689 !conContext.handshakeContext.delegatedActions.isEmpty()) { 690 conContext.handshakeContext.taskDelegated = true; 691 return new DelegatedTask(this); 692 } 693 694 return null; 695 } 696 697 @Override 698 public synchronized void closeInbound() throws SSLException { 699 conContext.closeInbound(); 700 } 701 702 @Override 703 public synchronized boolean isInboundDone() { 704 return conContext.isInboundDone(); 705 } 706 707 @Override 708 public synchronized void closeOutbound() { 709 conContext.closeOutbound(); 710 } 711 712 @Override 713 public synchronized boolean isOutboundDone() { 714 return conContext.isOutboundDone(); 715 } 716 717 @Override 718 public String[] getSupportedCipherSuites() { 719 return CipherSuite.namesOf(sslContext.getSupportedCipherSuites()); 720 } 721 722 @Override 723 public synchronized String[] getEnabledCipherSuites() { 724 return CipherSuite.namesOf(conContext.sslConfig.enabledCipherSuites); 725 } 726 727 @Override 728 public synchronized void setEnabledCipherSuites(String[] suites) { 729 if (suites == null) { 730 throw new IllegalArgumentException("CipherSuites cannot be null"); 731 } 732 733 conContext.sslConfig.enabledCipherSuites = 734 CipherSuite.validValuesOf(suites); 735 } 736 737 @Override 738 public String[] getSupportedProtocols() { 739 return ProtocolVersion.toStringArray( 740 sslContext.getSuportedProtocolVersions()); 741 } 742 743 @Override 744 public synchronized String[] getEnabledProtocols() { 745 return ProtocolVersion.toStringArray( 746 conContext.sslConfig.enabledProtocols); 747 } 748 749 @Override 750 public synchronized void setEnabledProtocols(String[] protocols) { 751 if (protocols == null) { 752 throw new IllegalArgumentException("Protocols cannot be null"); 753 } 754 755 conContext.sslConfig.enabledProtocols = 756 ProtocolVersion.namesOf(protocols); 757 } 758 759 @Override 760 public synchronized SSLSession getSession() { 761 return conContext.conSession; 762 } 763 764 @Override 765 public synchronized SSLSession getHandshakeSession() { 766 return conContext.handshakeContext == null ? 767 null : conContext.handshakeContext.handshakeSession; 768 } 769 770 @Override 771 public synchronized SSLEngineResult.HandshakeStatus getHandshakeStatus() { 772 return conContext.getHandshakeStatus(); 773 } 774 775 @Override 776 public synchronized void setUseClientMode(boolean mode) { 777 conContext.setUseClientMode(mode); 778 } 779 780 @Override 781 public synchronized boolean getUseClientMode() { 782 return conContext.sslConfig.isClientMode; 783 } 784 785 @Override 786 public synchronized void setNeedClientAuth(boolean need) { 787 conContext.sslConfig.clientAuthType = 788 (need ? ClientAuthType.CLIENT_AUTH_REQUIRED : 789 ClientAuthType.CLIENT_AUTH_NONE); 790 } 791 792 @Override 793 public synchronized boolean getNeedClientAuth() { 794 return (conContext.sslConfig.clientAuthType == 795 ClientAuthType.CLIENT_AUTH_REQUIRED); 796 } 797 798 @Override 799 public synchronized void setWantClientAuth(boolean want) { 800 conContext.sslConfig.clientAuthType = 801 (want ? ClientAuthType.CLIENT_AUTH_REQUESTED : 802 ClientAuthType.CLIENT_AUTH_NONE); 803 } 804 805 @Override 806 public synchronized boolean getWantClientAuth() { 807 return (conContext.sslConfig.clientAuthType == 808 ClientAuthType.CLIENT_AUTH_REQUESTED); 809 } 810 811 @Override 812 public synchronized void setEnableSessionCreation(boolean flag) { 813 conContext.sslConfig.enableSessionCreation = flag; 814 } 815 816 @Override 817 public synchronized boolean getEnableSessionCreation() { 818 return conContext.sslConfig.enableSessionCreation; 819 } 820 821 @Override 822 public synchronized SSLParameters getSSLParameters() { 823 return conContext.sslConfig.getSSLParameters(); 824 } 825 826 @Override 827 public synchronized void setSSLParameters(SSLParameters params) { 828 conContext.sslConfig.setSSLParameters(params); 829 830 if (conContext.sslConfig.maximumPacketSize != 0) { 831 conContext.outputRecord.changePacketSize( 832 conContext.sslConfig.maximumPacketSize); 833 } 834 } 835 836 @Override 837 public synchronized String getApplicationProtocol() { 838 return conContext.applicationProtocol; 839 } 840 841 @Override 842 public synchronized String getHandshakeApplicationProtocol() { 843 return conContext.handshakeContext == null ? 844 null : conContext.handshakeContext.applicationProtocol; 845 } 846 847 @Override 848 public synchronized void setHandshakeApplicationProtocolSelector( 849 BiFunction<SSLEngine, List<String>, String> selector) { 850 conContext.sslConfig.engineAPSelector = selector; 851 } 852 853 @Override 854 public synchronized BiFunction<SSLEngine, List<String>, String> 855 getHandshakeApplicationProtocolSelector() { 856 return conContext.sslConfig.engineAPSelector; 857 } 858 859 @Override 860 public boolean useDelegatedTask() { 861 return true; 862 } 863 864 private synchronized void checkTaskThrown() throws SSLException { 865 HandshakeContext hc = conContext.handshakeContext; 866 if (hc != null && hc.delegatedThrown != null) { 867 try { 868 throw getTaskThrown(hc.delegatedThrown); 869 } finally { 870 hc.delegatedThrown = null; 871 } 872 } 873 874 if (conContext.isBroken && conContext.closeReason != null) { 875 throw getTaskThrown(conContext.closeReason); 876 } 877 } 878 879 private static SSLException getTaskThrown(Exception taskThrown) { 880 String msg = taskThrown.getMessage(); 881 882 if (msg == null) { 883 msg = "Delegated task threw Exception or Error"; 884 } 885 886 if (taskThrown instanceof RuntimeException) { 887 throw new RuntimeException(msg, taskThrown); 888 } else if (taskThrown instanceof SSLHandshakeException) { 889 return (SSLHandshakeException) 890 new SSLHandshakeException(msg).initCause(taskThrown); 891 } else if (taskThrown instanceof SSLKeyException) { 892 return (SSLKeyException) 893 new SSLKeyException(msg).initCause(taskThrown); 894 } else if (taskThrown instanceof SSLPeerUnverifiedException) { 895 return (SSLPeerUnverifiedException) 896 new SSLPeerUnverifiedException(msg).initCause(taskThrown); 897 } else if (taskThrown instanceof SSLProtocolException) { 898 return (SSLProtocolException) 899 new SSLProtocolException(msg).initCause(taskThrown); 900 } else if (taskThrown instanceof SSLException) { 901 return (SSLException)taskThrown; 902 } else { 903 return new SSLException(msg, taskThrown); 904 } 905 } 906 907 /** 908 * Implement a simple task delegator. 909 */ 910 private static class DelegatedTask implements Runnable { 911 private final SSLEngineImpl engine; 912 913 DelegatedTask(SSLEngineImpl engineInstance) { 914 this.engine = engineInstance; 915 } 916 917 @Override 918 public void run() { 919 synchronized (engine) { 920 HandshakeContext hc = engine.conContext.handshakeContext; 921 if (hc == null || hc.delegatedActions.isEmpty()) { 922 return; 923 } 924 925 try { 926 AccessController.doPrivileged( 927 new DelegatedAction(hc), engine.conContext.acc); 928 } catch (PrivilegedActionException pae) { 929 // Get the handshake context again in case the 930 // handshaking has completed. 931 hc = engine.conContext.handshakeContext; 932 if (hc != null) { 933 hc.delegatedThrown = pae.getException(); 934 } else if (engine.conContext.closeReason != null) { 935 engine.conContext.closeReason = 936 getTaskThrown(pae.getException()); 937 } 938 } catch (RuntimeException rte) { 939 // Get the handshake context again in case the 940 // handshaking has completed. 941 hc = engine.conContext.handshakeContext; 942 if (hc != null) { 943 hc.delegatedThrown = rte; 944 } else if (engine.conContext.closeReason != null) { 945 engine.conContext.closeReason = rte; 946 } 947 } 948 949 // Get the handshake context again in case the 950 // handshaking has completed. 951 hc = engine.conContext.handshakeContext; 952 if (hc != null) { 953 hc.taskDelegated = false; 954 } 955 } 956 } 957 958 private static class DelegatedAction 959 implements PrivilegedExceptionAction<Void> { 960 final HandshakeContext context; 961 DelegatedAction(HandshakeContext context) { 962 this.context = context; 963 } 964 965 @Override 966 public Void run() throws Exception { 967 while (!context.delegatedActions.isEmpty()) { 968 // Report back the task SSLException 969 if (context.delegatedThrown != null) { 970 Exception delegatedThrown = context.delegatedThrown; 971 context.delegatedThrown = null; 972 throw getTaskThrown(delegatedThrown); 973 } 974 975 Map.Entry<Byte, ByteBuffer> me = 976 context.delegatedActions.poll(); 977 if (me != null) { 978 context.dispatch(me.getKey(), me.getValue()); 979 } 980 } 981 return null; 982 } 983 } 984 } 985 } |