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