1 /* 2 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.ssl; 27 28 import java.io.IOException; 29 import java.nio.ByteBuffer; 30 import java.nio.ReadOnlyBufferException; 31 import java.security.AccessController; 32 import java.security.PrivilegedActionException; 33 import java.security.PrivilegedExceptionAction; 34 import java.util.List; 35 import java.util.Map; 36 import java.util.function.BiFunction; 37 import javax.net.ssl.SSLEngine; 38 import javax.net.ssl.SSLEngineResult; 39 import javax.net.ssl.SSLEngineResult.HandshakeStatus; 40 import javax.net.ssl.SSLEngineResult.Status; 41 import javax.net.ssl.SSLException; 42 import javax.net.ssl.SSLHandshakeException; 43 import javax.net.ssl.SSLKeyException; 44 import javax.net.ssl.SSLParameters; 45 import javax.net.ssl.SSLPeerUnverifiedException; 46 import javax.net.ssl.SSLProtocolException; 47 import javax.net.ssl.SSLSession; 48 49 /** 50 * Implementation of an non-blocking SSLEngine. 51 * 52 * @author Brad Wetmore 53 */ 54 final class SSLEngineImpl extends SSLEngine implements SSLTransport { 55 private final SSLContextImpl sslContext; 56 final TransportContext conContext; 57 58 /** 59 * Constructor for an SSLEngine from SSLContext, without 60 * host/port hints. 61 * 62 * This Engine will not be able to cache sessions, but must renegotiate 63 * everything by hand. 64 */ 65 SSLEngineImpl(SSLContextImpl sslContext) { 66 this(sslContext, null, -1); 67 } 68 69 /** 70 * Constructor for an SSLEngine from SSLContext. 71 */ 72 SSLEngineImpl(SSLContextImpl sslContext, 73 String host, int port) { 74 super(host, port); 75 this.sslContext = sslContext; 76 HandshakeHash handshakeHash = new HandshakeHash(); 77 if (sslContext.isDTLS()) { 78 this.conContext = new TransportContext(sslContext, this, 79 new DTLSInputRecord(handshakeHash), 80 new DTLSOutputRecord(handshakeHash)); 81 } else { 82 this.conContext = new TransportContext(sslContext, this, 83 new SSLEngineInputRecord(handshakeHash), 84 new SSLEngineOutputRecord(handshakeHash)); 85 } 86 87 // Server name indication is a connection scope extension. 88 if (host != null) { 89 this.conContext.sslConfig.serverNames = 90 Utilities.addToSNIServerNameList( 91 conContext.sslConfig.serverNames, host); 92 } 93 } 94 95 @Override 96 public synchronized void beginHandshake() throws SSLException { 97 if (conContext.isUnsureMode) { 98 throw new IllegalStateException( 99 "Client/Server mode has not yet been set."); 100 } 101 102 try { 103 conContext.kickstart(); 104 } catch (IOException ioe) { 105 throw conContext.fatal(Alert.HANDSHAKE_FAILURE, 106 "Couldn't kickstart handshaking", ioe); 107 } catch (Exception ex) { // including RuntimeException 108 throw conContext.fatal(Alert.INTERNAL_ERROR, 109 "Fail to begin handshake", ex); 110 } 111 } 112 113 @Override 114 public synchronized SSLEngineResult wrap(ByteBuffer[] appData, 115 int offset, int length, ByteBuffer netData) throws SSLException { 116 return wrap(appData, offset, length, new ByteBuffer[]{ netData }, 0, 1); 117 } 118 119 // @Override 120 public synchronized SSLEngineResult wrap( 121 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 122 ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws SSLException { 123 124 if (conContext.isUnsureMode) { 125 throw new IllegalStateException( 126 "Client/Server mode has not yet been set."); 127 } 128 129 // See if the handshaker needs to report back some SSLException. 130 checkTaskThrown(); 131 132 // check parameters 133 checkParams(srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength); 134 135 try { 136 return writeRecord( 137 srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength); 138 } catch (SSLProtocolException spe) { 139 // may be an unexpected handshake message 140 throw conContext.fatal(Alert.UNEXPECTED_MESSAGE, spe); 141 } catch (IOException ioe) { 142 throw conContext.fatal(Alert.INTERNAL_ERROR, 143 "problem wrapping app data", ioe); 144 } catch (Exception ex) { // including RuntimeException 145 throw conContext.fatal(Alert.INTERNAL_ERROR, 146 "Fail to wrap application data", ex); 147 } 148 } 149 150 private SSLEngineResult writeRecord( 151 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 152 ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException { 153 154 // May need to deliver cached records. 155 if (isOutboundDone()) { 156 return new SSLEngineResult( 157 Status.CLOSED, getHandshakeStatus(), 0, 0); 158 } 159 160 HandshakeContext hc = conContext.handshakeContext; 161 HandshakeStatus hsStatus = null; 162 if (!conContext.isNegotiated && !conContext.isBroken && 163 !conContext.isInboundClosed() && 164 !conContext.isOutboundClosed()) { 165 conContext.kickstart(); 166 167 hsStatus = getHandshakeStatus(); 168 if (hsStatus == HandshakeStatus.NEED_UNWRAP) { 169 /* 170 * For DTLS, if the handshake state is 171 * HandshakeStatus.NEED_UNWRAP, a call to SSLEngine.wrap() 172 * means that the previous handshake packets (if delivered) 173 * get lost, and need retransmit the handshake messages. 174 */ 175 if (!sslContext.isDTLS() || hc == null || 176 !hc.sslConfig.enableRetransmissions || 177 conContext.outputRecord.firstMessage) { 178 179 return new SSLEngineResult(Status.OK, hsStatus, 0, 0); 180 } // otherwise, need retransmission 181 } 182 } 183 184 if (hsStatus == null) { 185 hsStatus = getHandshakeStatus(); 186 } 187 188 /* 189 * If we have a task outstanding, this *MUST* be done before 190 * doing any more wrapping, because we could be in the middle 191 * of receiving a handshake message, for example, a finished 192 * message which would change the ciphers. 193 */ 194 if (hsStatus == HandshakeStatus.NEED_TASK) { 195 return new SSLEngineResult(Status.OK, hsStatus, 0, 0); 196 } 197 198 int dstsRemains = 0; 199 for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) { 200 dstsRemains += dsts[i].remaining(); 201 } 202 203 // Check destination buffer size. 204 // 205 // We can be smarter about using smaller buffer sizes later. For 206 // now, force it to be large enough to handle any valid record. 207 if (dstsRemains < conContext.conSession.getPacketBufferSize()) { 208 return new SSLEngineResult( 209 Status.BUFFER_OVERFLOW, getHandshakeStatus(), 0, 0); 210 } 211 212 int srcsRemains = 0; 213 for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) { 214 srcsRemains += srcs[i].remaining(); 215 } 216 217 Ciphertext ciphertext = null; 218 try { 219 // Acquire the buffered to-be-delivered records or retransmissions. 220 // 221 // May have buffered records, or need retransmission if handshaking. 222 if (!conContext.outputRecord.isEmpty() || (hc != null && 223 hc.sslConfig.enableRetransmissions && 224 hc.sslContext.isDTLS() && 225 hsStatus == HandshakeStatus.NEED_UNWRAP)) { 226 ciphertext = encode(null, 0, 0, 227 dsts, dstsOffset, dstsLength); 228 } 229 230 if (ciphertext == null && srcsRemains != 0) { 231 ciphertext = encode(srcs, srcsOffset, srcsLength, 232 dsts, dstsOffset, dstsLength); 233 } 234 } catch (IOException ioe) { 235 if (ioe instanceof SSLException) { 236 throw ioe; 237 } else { 238 throw new SSLException("Write problems", ioe); 239 } 240 } 241 242 /* 243 * Check for status. 244 */ 245 Status status = (isOutboundDone() ? Status.CLOSED : Status.OK); 246 if (ciphertext != null && ciphertext.handshakeStatus != null) { 247 hsStatus = ciphertext.handshakeStatus; 248 } else { 249 hsStatus = getHandshakeStatus(); 250 } 251 252 int deltaSrcs = srcsRemains; 253 for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) { 254 deltaSrcs -= srcs[i].remaining(); 255 } 256 257 int deltaDsts = dstsRemains; 258 for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) { 259 deltaDsts -= dsts[i].remaining(); 260 } 261 262 return new SSLEngineResult(status, hsStatus, deltaSrcs, deltaDsts, 263 ciphertext != null ? ciphertext.recordSN : -1L); 264 } 265 266 private Ciphertext encode( 267 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 268 ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException { 269 270 Ciphertext ciphertext = null; 271 try { 272 ciphertext = conContext.outputRecord.encode( 273 srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength); 274 } catch (SSLHandshakeException she) { 275 // may be record sequence number overflow 276 throw conContext.fatal(Alert.HANDSHAKE_FAILURE, she); 277 } catch (IOException e) { 278 throw conContext.fatal(Alert.UNEXPECTED_MESSAGE, e); 279 } 280 281 if (ciphertext == null) { 282 return Ciphertext.CIPHERTEXT_NULL; 283 } 284 285 // Is the handshake completed? 286 boolean needRetransmission = 287 conContext.sslContext.isDTLS() && 288 conContext.handshakeContext != null && 289 conContext.handshakeContext.sslConfig.enableRetransmissions; 290 HandshakeStatus hsStatus = 291 tryToFinishHandshake(ciphertext.contentType); 292 if (needRetransmission && 293 hsStatus == HandshakeStatus.FINISHED && 294 conContext.sslContext.isDTLS() && 295 ciphertext.handshakeType == SSLHandshake.FINISHED.id) { 296 // Retransmit the last flight for DTLS. 297 // 298 // The application data transactions may begin immediately 299 // after the last flight. If the last flight get lost, the 300 // application data may be discarded accordingly. As could 301 // be an issue for some applications. This impact can be 302 // mitigated by sending the last fligth twice. 303 if (SSLLogger.isOn && SSLLogger.isOn("ssl,verbose")) { 304 SSLLogger.finest("retransmit the last flight messages"); 305 } 306 307 conContext.outputRecord.launchRetransmission(); 308 hsStatus = HandshakeStatus.NEED_WRAP; 309 } 310 311 if (hsStatus == null) { 312 hsStatus = conContext.getHandshakeStatus(); 313 } 314 315 // Is the sequence number is nearly overflow? 316 if (conContext.outputRecord.seqNumIsHuge() || 317 conContext.outputRecord.writeCipher.atKeyLimit()) { 318 hsStatus = tryKeyUpdate(hsStatus); 319 } 320 321 // update context status 322 ciphertext.handshakeStatus = hsStatus; 323 324 return ciphertext; 325 } 326 327 private HandshakeStatus tryToFinishHandshake(byte contentType) { 328 HandshakeStatus hsStatus = null; 329 if ((contentType == ContentType.HANDSHAKE.id) && 330 conContext.outputRecord.isEmpty()) { 331 if (conContext.handshakeContext == null) { 332 hsStatus = HandshakeStatus.FINISHED; 333 } else if (conContext.isPostHandshakeContext()) { 334 // unlikely, but just in case. 335 hsStatus = conContext.finishPostHandshake(); 336 } else if (conContext.handshakeContext.handshakeFinished) { 337 hsStatus = conContext.finishHandshake(); 338 } 339 } // Otherwise, the followed call to getHSStatus() will help. 340 341 return hsStatus; 342 } 343 344 /** 345 * Try key update for sequence number wrap or key usage limit. 346 * 347 * Note that in order to maintain the handshake status properly, we check 348 * the sequence number and key usage limit after the last record 349 * reading/writing process. 350 * 351 * As we request renegotiation or close the connection for wrapped sequence 352 * number when there is enough sequence number space left to handle a few 353 * more records, so the sequence number of the last record cannot be 354 * wrapped. 355 */ 356 private HandshakeStatus tryKeyUpdate( 357 HandshakeStatus currentHandshakeStatus) throws IOException { 358 // Don't bother to kickstart if handshaking is in progress, or if the 359 // connection is not duplex-open. 360 if ((conContext.handshakeContext == null) && 361 !conContext.isOutboundClosed() && 362 !conContext.isInboundClosed() && 363 !conContext.isBroken) { 364 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 365 SSLLogger.finest("trigger key update"); 366 } 367 beginHandshake(); 368 return conContext.getHandshakeStatus(); 369 } 370 371 return currentHandshakeStatus; 372 } 373 374 private static void checkParams( 375 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 376 ByteBuffer[] dsts, int dstsOffset, int dstsLength) { 377 378 if ((srcs == null) || (dsts == null)) { 379 throw new IllegalArgumentException( 380 "source or destination buffer is null"); 381 } 382 383 if ((dstsOffset < 0) || (dstsLength < 0) || 384 (dstsOffset > dsts.length - dstsLength)) { 385 throw new IndexOutOfBoundsException( 386 "index out of bound of the destination buffers"); 387 } 388 389 if ((srcsOffset < 0) || (srcsLength < 0) || 390 (srcsOffset > srcs.length - srcsLength)) { 391 throw new IndexOutOfBoundsException( 392 "index out of bound of the source buffers"); 393 } 394 395 for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) { 396 if (dsts[i] == null) { 397 throw new IllegalArgumentException( 398 "destination buffer[" + i + "] == null"); 399 } 400 401 /* 402 * Make sure the destination bufffers are writable. 403 */ 404 if (dsts[i].isReadOnly()) { 405 throw new ReadOnlyBufferException(); 406 } 407 } 408 409 for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) { 410 if (srcs[i] == null) { 411 throw new IllegalArgumentException( 412 "source buffer[" + i + "] == null"); 413 } 414 } 415 } 416 417 @Override 418 public synchronized SSLEngineResult unwrap(ByteBuffer src, 419 ByteBuffer[] dsts, int offset, int length) throws SSLException { 420 return unwrap( 421 new ByteBuffer[]{src}, 0, 1, dsts, offset, length); 422 } 423 424 // @Override 425 public synchronized SSLEngineResult unwrap( 426 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 427 ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws SSLException { 428 429 if (conContext.isUnsureMode) { 430 throw new IllegalStateException( 431 "Client/Server mode has not yet been set."); 432 } 433 434 // See if the handshaker needs to report back some SSLException. 435 checkTaskThrown(); 436 437 // check parameters 438 checkParams(srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength); 439 440 try { 441 return readRecord( 442 srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength); 443 } catch (SSLProtocolException spe) { 444 // may be an unexpected handshake message 445 throw conContext.fatal(Alert.UNEXPECTED_MESSAGE, 446 spe.getMessage(), spe); 447 } catch (IOException ioe) { 448 /* 449 * Don't reset position so it looks like we didn't 450 * consume anything. We did consume something, and it 451 * got us into this situation, so report that much back. 452 * Our days of consuming are now over anyway. 453 */ 454 throw conContext.fatal(Alert.INTERNAL_ERROR, 455 "problem unwrapping net record", ioe); 456 } catch (Exception ex) { // including RuntimeException 457 throw conContext.fatal(Alert.INTERNAL_ERROR, 458 "Fail to unwrap network record", ex); 459 } 460 } 461 462 private SSLEngineResult readRecord( 463 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 464 ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException { 465 466 /* 467 * Check if we are closing/closed. 468 */ 469 if (isInboundDone()) { 470 return new SSLEngineResult( 471 Status.CLOSED, getHandshakeStatus(), 0, 0); 472 } 473 474 HandshakeStatus hsStatus = null; 475 if (!conContext.isNegotiated && !conContext.isBroken && 476 !conContext.isInboundClosed() && 477 !conContext.isOutboundClosed()) { 478 conContext.kickstart(); 479 480 /* 481 * If there's still outbound data to flush, we 482 * can return without trying to unwrap anything. 483 */ 484 hsStatus = getHandshakeStatus(); 485 if (hsStatus == HandshakeStatus.NEED_WRAP) { 486 return new SSLEngineResult(Status.OK, hsStatus, 0, 0); 487 } 488 } 489 490 if (hsStatus == null) { 491 hsStatus = getHandshakeStatus(); 492 } 493 494 /* 495 * If we have a task outstanding, this *MUST* be done before 496 * doing any more unwrapping, because we could be in the middle 497 * of receiving a handshake message, for example, a finished 498 * message which would change the ciphers. 499 */ 500 if (hsStatus == HandshakeStatus.NEED_TASK) { 501 return new SSLEngineResult(Status.OK, hsStatus, 0, 0); 502 } 503 504 if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_UNWRAP_AGAIN) { 505 Plaintext plainText = null; 506 try { 507 plainText = decode(null, 0, 0, 508 dsts, dstsOffset, dstsLength); 509 } catch (IOException ioe) { 510 if (ioe instanceof SSLException) { 511 throw ioe; 512 } else { 513 throw new SSLException("readRecord", ioe); 514 } 515 } 516 517 Status status = (isInboundDone() ? Status.CLOSED : Status.OK); 518 if (plainText.handshakeStatus != null) { 519 hsStatus = plainText.handshakeStatus; 520 } else { 521 hsStatus = getHandshakeStatus(); 522 } 523 524 return new SSLEngineResult( 525 status, hsStatus, 0, 0, plainText.recordSN); 526 } 527 528 int srcsRemains = 0; 529 for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) { 530 srcsRemains += srcs[i].remaining(); 531 } 532 533 if (srcsRemains == 0) { 534 return new SSLEngineResult( 535 Status.BUFFER_UNDERFLOW, hsStatus, 0, 0); 536 } 537 538 /* 539 * Check the packet to make sure enough is here. 540 * This will also indirectly check for 0 len packets. 541 */ 542 int packetLen = 0; 543 try { 544 packetLen = conContext.inputRecord.bytesInCompletePacket( 545 srcs, srcsOffset, srcsLength); 546 } catch (SSLException ssle) { 547 // Need to discard invalid records for DTLS protocols. 548 if (sslContext.isDTLS()) { 549 if (SSLLogger.isOn && SSLLogger.isOn("ssl,verbose")) { 550 SSLLogger.finest("Discard invalid DTLS records", ssle); 551 } 552 553 // invalid, discard the entire data [section 4.1.2.7, RFC 6347] 554 int deltaNet = 0; 555 // int deltaNet = netData.remaining(); 556 // netData.position(netData.limit()); 557 558 Status status = (isInboundDone() ? Status.CLOSED : Status.OK); 559 if (hsStatus == null) { 560 hsStatus = getHandshakeStatus(); 561 } 562 563 return new SSLEngineResult(status, hsStatus, deltaNet, 0, -1L); 564 } else { 565 throw ssle; 566 } 567 } 568 569 // Is this packet bigger than SSL/TLS normally allows? 570 if (packetLen > conContext.conSession.getPacketBufferSize()) { 571 int largestRecordSize = sslContext.isDTLS() ? 572 DTLSRecord.maxRecordSize : SSLRecord.maxLargeRecordSize; 573 if ((packetLen <= largestRecordSize) && !sslContext.isDTLS()) { 574 // Expand the expected maximum packet/application buffer 575 // sizes. 576 // 577 // Only apply to SSL/TLS protocols. 578 579 // Old behavior: shall we honor the System Property 580 // "jsse.SSLEngine.acceptLargeFragments" if it is "false"? 581 conContext.conSession.expandBufferSizes(); 582 } 583 584 // check the packet again 585 largestRecordSize = conContext.conSession.getPacketBufferSize(); 586 if (packetLen > largestRecordSize) { 587 throw new SSLProtocolException( 588 "Input record too big: max = " + 589 largestRecordSize + " len = " + packetLen); 590 } 591 } 592 593 /* 594 * Check for OVERFLOW. 595 * 596 * Delay enforcing the application buffer free space requirement 597 * until after the initial handshaking. 598 */ 599 int dstsRemains = 0; 600 for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) { 601 dstsRemains += dsts[i].remaining(); 602 } 603 604 if (conContext.isNegotiated) { 605 int FragLen = 606 conContext.inputRecord.estimateFragmentSize(packetLen); 607 if (FragLen > dstsRemains) { 608 return new SSLEngineResult( 609 Status.BUFFER_OVERFLOW, hsStatus, 0, 0); 610 } 611 } 612 613 // check for UNDERFLOW. 614 if ((packetLen == -1) || (srcsRemains < packetLen)) { 615 return new SSLEngineResult(Status.BUFFER_UNDERFLOW, hsStatus, 0, 0); 616 } 617 618 /* 619 * We're now ready to actually do the read. 620 */ 621 Plaintext plainText = null; 622 try { 623 plainText = decode(srcs, srcsOffset, srcsLength, 624 dsts, dstsOffset, dstsLength); 625 } catch (IOException ioe) { 626 if (ioe instanceof SSLException) { 627 throw ioe; 628 } else { 629 throw new SSLException("readRecord", ioe); 630 } 631 } 632 633 /* 634 * Check the various condition that we could be reporting. 635 * 636 * It's *possible* something might have happened between the 637 * above and now, but it was better to minimally lock "this" 638 * during the read process. We'll return the current 639 * status, which is more representative of the current state. 640 * 641 * status above should cover: FINISHED, NEED_TASK 642 */ 643 Status status = (isInboundDone() ? Status.CLOSED : Status.OK); 644 if (plainText.handshakeStatus != null) { 645 hsStatus = plainText.handshakeStatus; 646 } else { 647 hsStatus = getHandshakeStatus(); 648 } 649 650 int deltaNet = srcsRemains; 651 for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) { 652 deltaNet -= srcs[i].remaining(); 653 } 654 655 int deltaApp = dstsRemains; 656 for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) { 657 deltaApp -= dsts[i].remaining(); 658 } 659 660 return new SSLEngineResult( 661 status, hsStatus, deltaNet, deltaApp, plainText.recordSN); 662 } 663 664 private Plaintext decode( 665 ByteBuffer[] srcs, int srcsOffset, int srcsLength, 666 ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException { 667 668 Plaintext pt = SSLTransport.decode(conContext, 669 srcs, srcsOffset, srcsLength, 670 dsts, dstsOffset, dstsLength); 671 672 // Is the handshake completed? 673 if (pt != Plaintext.PLAINTEXT_NULL) { 674 HandshakeStatus hsStatus = tryToFinishHandshake(pt.contentType); 675 if (hsStatus == null) { 676 pt.handshakeStatus = conContext.getHandshakeStatus(); 677 } else { 678 pt.handshakeStatus = hsStatus; 679 } 680 681 // Is the sequence number is nearly overflow? 682 if (conContext.inputRecord.seqNumIsHuge() || 683 conContext.inputRecord.readCipher.atKeyLimit()) { 684 pt.handshakeStatus = 685 tryKeyUpdate(pt.handshakeStatus); 686 } 687 } 688 689 return pt; 690 } 691 692 @Override 693 public synchronized Runnable getDelegatedTask() { 694 if (conContext.handshakeContext != null && // PRE or POST handshake 695 !conContext.handshakeContext.taskDelegated && 696 !conContext.handshakeContext.delegatedActions.isEmpty()) { 697 conContext.handshakeContext.taskDelegated = true; 698 return new DelegatedTask(this); 699 } 700 701 return null; 702 } 703 704 @Override 705 public synchronized void closeInbound() throws SSLException { 706 if (isInboundDone()) { 707 return; 708 } 709 710 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 711 SSLLogger.finest("Closing inbound of SSLEngine"); 712 } 713 714 // Is it ready to close inbound? 715 // 716 // No need to throw exception if the initial handshake is not started. 717 if (!conContext.isInputCloseNotified && 718 (conContext.isNegotiated || conContext.handshakeContext != null)) { 719 720 throw conContext.fatal(Alert.INTERNAL_ERROR, 721 "closing inbound before receiving peer's close_notify"); 722 } 723 724 conContext.closeInbound(); 725 } 726 727 @Override 728 public synchronized boolean isInboundDone() { 729 return conContext.isInboundClosed(); 730 } 731 732 @Override 733 public synchronized void closeOutbound() { 734 if (conContext.isOutboundClosed()) { 735 return; 736 } 737 738 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 739 SSLLogger.finest("Closing outbound of SSLEngine"); 740 } 741 742 conContext.closeOutbound(); 743 } 744 745 @Override 746 public synchronized boolean isOutboundDone() { 747 return conContext.isOutboundDone(); 748 } 749 750 @Override 751 public String[] getSupportedCipherSuites() { 752 return CipherSuite.namesOf(sslContext.getSupportedCipherSuites()); 753 } 754 755 @Override 756 public synchronized String[] getEnabledCipherSuites() { 757 return CipherSuite.namesOf(conContext.sslConfig.enabledCipherSuites); 758 } 759 760 @Override 761 public synchronized void setEnabledCipherSuites(String[] suites) { 762 conContext.sslConfig.enabledCipherSuites = 763 CipherSuite.validValuesOf(suites); 764 } 765 766 @Override 767 public String[] getSupportedProtocols() { 768 return ProtocolVersion.toStringArray( 769 sslContext.getSupportedProtocolVersions()); 770 } 771 772 @Override 773 public synchronized String[] getEnabledProtocols() { 774 return ProtocolVersion.toStringArray( 775 conContext.sslConfig.enabledProtocols); 776 } 777 778 @Override 779 public synchronized void setEnabledProtocols(String[] protocols) { 780 if (protocols == null) { 781 throw new IllegalArgumentException("Protocols cannot be null"); 782 } 783 784 conContext.sslConfig.enabledProtocols = 785 ProtocolVersion.namesOf(protocols); 786 } 787 788 @Override 789 public synchronized SSLSession getSession() { 790 return conContext.conSession; 791 } 792 793 @Override 794 public synchronized SSLSession getHandshakeSession() { 795 return conContext.handshakeContext == null ? 796 null : conContext.handshakeContext.handshakeSession; 797 } 798 799 @Override 800 public synchronized SSLEngineResult.HandshakeStatus getHandshakeStatus() { 801 return conContext.getHandshakeStatus(); 802 } 803 804 @Override 805 public synchronized void setUseClientMode(boolean mode) { 806 conContext.setUseClientMode(mode); 807 } 808 809 @Override 810 public synchronized boolean getUseClientMode() { 811 return conContext.sslConfig.isClientMode; 812 } 813 814 @Override 815 public synchronized void setNeedClientAuth(boolean need) { 816 conContext.sslConfig.clientAuthType = 817 (need ? ClientAuthType.CLIENT_AUTH_REQUIRED : 818 ClientAuthType.CLIENT_AUTH_NONE); 819 } 820 821 @Override 822 public synchronized boolean getNeedClientAuth() { 823 return (conContext.sslConfig.clientAuthType == 824 ClientAuthType.CLIENT_AUTH_REQUIRED); 825 } 826 827 @Override 828 public synchronized void setWantClientAuth(boolean want) { 829 conContext.sslConfig.clientAuthType = 830 (want ? ClientAuthType.CLIENT_AUTH_REQUESTED : 831 ClientAuthType.CLIENT_AUTH_NONE); 832 } 833 834 @Override 835 public synchronized boolean getWantClientAuth() { 836 return (conContext.sslConfig.clientAuthType == 837 ClientAuthType.CLIENT_AUTH_REQUESTED); 838 } 839 840 @Override 841 public synchronized void setEnableSessionCreation(boolean flag) { 842 conContext.sslConfig.enableSessionCreation = flag; 843 } 844 845 @Override 846 public synchronized boolean getEnableSessionCreation() { 847 return conContext.sslConfig.enableSessionCreation; 848 } 849 850 @Override 851 public synchronized SSLParameters getSSLParameters() { 852 return conContext.sslConfig.getSSLParameters(); 853 } 854 855 @Override 856 public synchronized void setSSLParameters(SSLParameters params) { 857 conContext.sslConfig.setSSLParameters(params); 858 859 if (conContext.sslConfig.maximumPacketSize != 0) { 860 conContext.outputRecord.changePacketSize( 861 conContext.sslConfig.maximumPacketSize); 862 } 863 } 864 865 @Override 866 public synchronized String getApplicationProtocol() { 867 return conContext.applicationProtocol; 868 } 869 870 @Override 871 public synchronized String getHandshakeApplicationProtocol() { 872 return conContext.handshakeContext == null ? 873 null : conContext.handshakeContext.applicationProtocol; 874 } 875 876 @Override 877 public synchronized void setHandshakeApplicationProtocolSelector( 878 BiFunction<SSLEngine, List<String>, String> selector) { 879 conContext.sslConfig.engineAPSelector = selector; 880 } 881 882 @Override 883 public synchronized BiFunction<SSLEngine, List<String>, String> 884 getHandshakeApplicationProtocolSelector() { 885 return conContext.sslConfig.engineAPSelector; 886 } 887 888 @Override 889 public boolean useDelegatedTask() { 890 return true; 891 } 892 893 /* 894 * Depending on whether the error was just a warning and the 895 * handshaker wasn't closed, or fatal and the handshaker is now 896 * null, report back the Exception that happened in the delegated 897 * task(s). 898 */ 899 private synchronized void checkTaskThrown() throws SSLException { 900 901 Exception exc = null; 902 903 // First check the handshake context. 904 HandshakeContext hc = conContext.handshakeContext; 905 if ((hc != null) && (hc.delegatedThrown != null)) { 906 exc = hc.delegatedThrown; 907 hc.delegatedThrown = null; 908 } 909 910 /* 911 * hc.delegatedThrown and conContext.delegatedThrown are most likely 912 * the same, but it's possible we could have had a non-fatal 913 * exception and thus the new HandshakeContext is still valid 914 * (alert warning). If so, then we may have a secondary exception 915 * waiting to be reported from the TransportContext, so we will 916 * need to clear that on a successive call. Otherwise, clear it now. 917 */ 918 if (conContext.delegatedThrown != null) { 919 if (exc != null) { 920 // hc object comparison 921 if (conContext.delegatedThrown == exc) { 922 // clear if/only if both are the same 923 conContext.delegatedThrown = null; 924 } // otherwise report the hc delegatedThrown 925 } else { 926 // Nothing waiting in HandshakeContext, but one is in the 927 // TransportContext. 928 exc = conContext.delegatedThrown; 929 conContext.delegatedThrown = null; 930 } 931 } 932 933 // Anything to report? 934 if (exc == null) { 935 return; 936 } 937 938 // If it wasn't a RuntimeException/SSLException, need to wrap it. 939 if (exc instanceof SSLException) { 940 throw (SSLException)exc; 941 } else if (exc instanceof RuntimeException) { 942 throw (RuntimeException)exc; 943 } else { 944 throw getTaskThrown(exc); 945 } 946 } 947 948 private static SSLException getTaskThrown(Exception taskThrown) { 949 String msg = taskThrown.getMessage(); 950 951 if (msg == null) { 952 msg = "Delegated task threw Exception or Error"; 953 } 954 955 if (taskThrown instanceof RuntimeException) { 956 throw new RuntimeException(msg, taskThrown); 957 } else if (taskThrown instanceof SSLHandshakeException) { 958 return (SSLHandshakeException) 959 new SSLHandshakeException(msg).initCause(taskThrown); 960 } else if (taskThrown instanceof SSLKeyException) { 961 return (SSLKeyException) 962 new SSLKeyException(msg).initCause(taskThrown); 963 } else if (taskThrown instanceof SSLPeerUnverifiedException) { 964 return (SSLPeerUnverifiedException) 965 new SSLPeerUnverifiedException(msg).initCause(taskThrown); 966 } else if (taskThrown instanceof SSLProtocolException) { 967 return (SSLProtocolException) 968 new SSLProtocolException(msg).initCause(taskThrown); 969 } else if (taskThrown instanceof SSLException) { 970 return (SSLException)taskThrown; 971 } else { 972 return new SSLException(msg, taskThrown); 973 } 974 } 975 976 /** 977 * Implement a simple task delegator. 978 */ 979 private static class DelegatedTask implements Runnable { 980 private final SSLEngineImpl engine; 981 982 DelegatedTask(SSLEngineImpl engineInstance) { 983 this.engine = engineInstance; 984 } 985 986 @Override 987 public void run() { 988 synchronized (engine) { 989 HandshakeContext hc = engine.conContext.handshakeContext; 990 if (hc == null || hc.delegatedActions.isEmpty()) { 991 return; 992 } 993 994 try { 995 AccessController.doPrivileged( 996 new DelegatedAction(hc), engine.conContext.acc); 997 } catch (PrivilegedActionException pae) { 998 // Get the handshake context again in case the 999 // handshaking has completed. 1000 Exception reportedException = pae.getException(); 1001 1002 // Report to both the TransportContext... 1003 if (engine.conContext.delegatedThrown == null) { 1004 engine.conContext.delegatedThrown = reportedException; 1005 } 1006 1007 // ...and the HandshakeContext in case condition 1008 // wasn't fatal and the handshakeContext is still 1009 // around. 1010 hc = engine.conContext.handshakeContext; 1011 if (hc != null) { 1012 hc.delegatedThrown = reportedException; 1013 } else if (engine.conContext.closeReason != null) { 1014 // Update the reason in case there was a previous. 1015 engine.conContext.closeReason = 1016 getTaskThrown(reportedException); 1017 } 1018 } catch (RuntimeException rte) { 1019 // Get the handshake context again in case the 1020 // handshaking has completed. 1021 1022 // Report to both the TransportContext... 1023 if (engine.conContext.delegatedThrown == null) { 1024 engine.conContext.delegatedThrown = rte; 1025 } 1026 1027 // ...and the HandshakeContext in case condition 1028 // wasn't fatal and the handshakeContext is still 1029 // around. 1030 hc = engine.conContext.handshakeContext; 1031 if (hc != null) { 1032 hc.delegatedThrown = rte; 1033 } else if (engine.conContext.closeReason != null) { 1034 // Update the reason in case there was a previous. 1035 engine.conContext.closeReason = rte; 1036 } 1037 } 1038 1039 // Get the handshake context again in case the 1040 // handshaking has completed. 1041 hc = engine.conContext.handshakeContext; 1042 if (hc != null) { 1043 hc.taskDelegated = false; 1044 } 1045 } 1046 } 1047 1048 private static class DelegatedAction 1049 implements PrivilegedExceptionAction<Void> { 1050 final HandshakeContext context; 1051 DelegatedAction(HandshakeContext context) { 1052 this.context = context; 1053 } 1054 1055 @Override 1056 public Void run() throws Exception { 1057 while (!context.delegatedActions.isEmpty()) { 1058 Map.Entry<Byte, ByteBuffer> me = 1059 context.delegatedActions.poll(); 1060 if (me != null) { 1061 context.dispatch(me.getKey(), me.getValue()); 1062 } 1063 } 1064 return null; 1065 } 1066 } 1067 } 1068 }