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