1/* 2 * Copyright 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/* 18 * Copyright 2016 The Netty Project 19 * 20 * The Netty Project licenses this file to you under the Apache License, 21 * version 2.0 (the "License"); you may not use this file except in compliance 22 * with the License. You may obtain a copy of the License at: 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 28 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 29 * License for the specific language governing permissions and limitations 30 * under the License. 31 */ 32 33package org.conscrypt; 34 35import static javax.net.ssl.SSLEngineResult.HandshakeStatus.FINISHED; 36import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_UNWRAP; 37import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_WRAP; 38import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING; 39import static javax.net.ssl.SSLEngineResult.Status.BUFFER_OVERFLOW; 40import static javax.net.ssl.SSLEngineResult.Status.BUFFER_UNDERFLOW; 41import static javax.net.ssl.SSLEngineResult.Status.CLOSED; 42import static javax.net.ssl.SSLEngineResult.Status.OK; 43import static org.conscrypt.NativeConstants.SSL3_RT_HEADER_LENGTH; 44import static org.conscrypt.NativeConstants.SSL3_RT_MAX_PACKET_SIZE; 45import static org.conscrypt.NativeConstants.SSL3_RT_MAX_PLAIN_LENGTH; 46import static org.conscrypt.NativeConstants.SSL_CB_HANDSHAKE_DONE; 47import static org.conscrypt.NativeConstants.SSL_CB_HANDSHAKE_START; 48import static org.conscrypt.NativeConstants.SSL_ERROR_NONE; 49import static org.conscrypt.NativeConstants.SSL_ERROR_WANT_READ; 50import static org.conscrypt.NativeConstants.SSL_ERROR_WANT_WRITE; 51import static org.conscrypt.NativeConstants.SSL_ERROR_ZERO_RETURN; 52import static org.conscrypt.NativeConstants.SSL_RECEIVED_SHUTDOWN; 53import static org.conscrypt.NativeConstants.SSL_SENT_SHUTDOWN; 54import static org.conscrypt.SSLUtils.calculateOutNetBufSize; 55import static org.conscrypt.SSLUtils.toSSLHandshakeException; 56 57import java.io.IOException; 58import java.nio.ByteBuffer; 59import java.nio.ReadOnlyBufferException; 60import java.security.InvalidKeyException; 61import java.security.PrivateKey; 62import java.security.cert.CertificateEncodingException; 63import java.security.cert.CertificateException; 64import java.security.interfaces.ECKey; 65import java.security.spec.ECParameterSpec; 66import javax.crypto.SecretKey; 67import javax.net.ssl.SSLEngine; 68import javax.net.ssl.SSLEngineResult; 69import javax.net.ssl.SSLEngineResult.HandshakeStatus; 70import javax.net.ssl.SSLEngineResult.Status; 71import javax.net.ssl.SSLException; 72import javax.net.ssl.SSLHandshakeException; 73import javax.net.ssl.SSLParameters; 74import javax.net.ssl.SSLSession; 75import javax.net.ssl.X509ExtendedKeyManager; 76import javax.net.ssl.X509KeyManager; 77import javax.net.ssl.X509TrustManager; 78import javax.security.auth.x500.X500Principal; 79 80/** 81 * Implements the {@link SSLEngine} API using OpenSSL's non-blocking interfaces. 82 * 83 * @hide 84 */ 85final class OpenSSLEngineImpl extends SSLEngine implements NativeCrypto.SSLHandshakeCallbacks, 86 SSLParametersImpl.AliasChooser, 87 SSLParametersImpl.PSKCallbacks { 88 private static final SSLEngineResult NEED_UNWRAP_OK = 89 new SSLEngineResult(OK, NEED_UNWRAP, 0, 0); 90 private static final SSLEngineResult NEED_UNWRAP_CLOSED = 91 new SSLEngineResult(CLOSED, NEED_UNWRAP, 0, 0); 92 private static final SSLEngineResult NEED_WRAP_OK = new SSLEngineResult(OK, NEED_WRAP, 0, 0); 93 private static final SSLEngineResult NEED_WRAP_CLOSED = 94 new SSLEngineResult(CLOSED, NEED_WRAP, 0, 0); 95 private static final SSLEngineResult CLOSED_NOT_HANDSHAKING = 96 new SSLEngineResult(CLOSED, NOT_HANDSHAKING, 0, 0); 97 private static final ByteBuffer EMPTY = ByteBuffer.allocateDirect(0); 98 private static final long EMPTY_ADDR = NativeCrypto.getDirectBufferAddress(EMPTY); 99 100 /** 101 * Hostname used with the TLS extension SNI hostname. {@link #getPeerHost()} is used if this is 102 * not set. 103 */ 104 private String sniHostname; 105 106 private final SSLParametersImpl sslParameters; 107 108 /** 109 * Protects {@link #engineState} and {@link #handshakeFinished}. 110 */ 111 private final Object stateLock = new Object(); 112 113 private enum EngineState { 114 /** 115 * The {@link OpenSSLSocketImpl} object is constructed, but {@link #beginHandshake()} has 116 * not yet been called. 117 */ 118 NEW, 119 /** 120 * {@link #setUseClientMode(boolean)} has been called at least once. 121 */ 122 MODE_SET, 123 /** 124 * Handshake task has been started. 125 */ 126 HANDSHAKE_STARTED, 127 /** 128 * Handshake has been completed, but {@link #beginHandshake()} hasn't returned yet. 129 */ 130 HANDSHAKE_COMPLETED, 131 /** 132 * {@link #beginHandshake()} has completed but the task hasn't been called. This is expected 133 * behaviour in cut-through mode, where SSL_do_handshake returns before the handshake is 134 * complete. We can now start writing data to the socket. 135 */ 136 READY_HANDSHAKE_CUT_THROUGH, 137 /** 138 * {@link #beginHandshake()} has completed and socket is ready to go. 139 */ 140 READY, 141 CLOSED_INBOUND, 142 CLOSED_OUTBOUND, 143 /** 144 * Inbound and outbound has been called. 145 */ 146 CLOSED, 147 } 148 149 // @GuardedBy("stateLock"); 150 private EngineState engineState = EngineState.NEW; 151 private boolean handshakeFinished; 152 153 /** 154 * Protected by synchronizing on stateLock. Starts as 0, set by startHandshake, reset to 0 on 155 * close. 156 */ 157 // @GuardedBy("stateLock"); 158 private long sslNativePointer; 159 160 /** 161 * Protected by synchronizing on stateLock. Starts as 0, set by startHandshake, reset to 0 on 162 * close. 163 */ 164 // @GuardedBy("stateLock"); 165 private long networkBio; 166 167 /** 168 * Set during startHandshake. 169 */ 170 private AbstractOpenSSLSession sslSession; 171 172 /** 173 * Used during handshake callbacks. 174 */ 175 private AbstractOpenSSLSession handshakeSession; 176 177 /** 178 * Private key for the TLS Channel ID extension. This field is client-side only. Set during 179 * startHandshake. 180 */ 181 private OpenSSLKey channelIdPrivateKey; 182 183 private int maxSealOverhead; 184 185 private HandshakeListener handshakeListener; 186 187 private final ByteBuffer[] singleSrcBuffer = new ByteBuffer[1]; 188 private final ByteBuffer[] singleDstBuffer = new ByteBuffer[1]; 189 190 OpenSSLEngineImpl(SSLParametersImpl sslParameters) { 191 this.sslParameters = sslParameters; 192 } 193 194 OpenSSLEngineImpl(String host, int port, SSLParametersImpl sslParameters) { 195 super(host, port); 196 this.sslParameters = sslParameters; 197 } 198 199 /** 200 * Returns the maximum overhead, in bytes, of sealing a record with SSL. 201 */ 202 int maxSealOverhead() { 203 return maxSealOverhead; 204 } 205 206 /** 207 * Enables/disables TLS Channel ID for this server engine. 208 * 209 * <p>This method needs to be invoked before the handshake starts. 210 * 211 * @throws IllegalStateException if this is a client engine or if the handshake has already 212 * started. 213 */ 214 void setChannelIdEnabled(boolean enabled) { 215 synchronized (stateLock) { 216 if (getUseClientMode()) { 217 throw new IllegalStateException("Not allowed in client mode"); 218 } 219 if (isHandshakeStarted()) { 220 throw new IllegalStateException( 221 "Could not enable/disable Channel ID after the initial handshake has begun."); 222 } 223 sslParameters.channelIdEnabled = enabled; 224 } 225 } 226 227 /** 228 * Gets the TLS Channel ID for this server engine. Channel ID is only available once the 229 * handshake completes. 230 * 231 * @return channel ID or {@code null} if not available. 232 * 233 * @throws IllegalStateException if this is a client engine or if the handshake has not yet 234 * completed. 235 * @throws SSLException if channel ID is available but could not be obtained. 236 */ 237 byte[] getChannelId() throws SSLException { 238 synchronized (stateLock) { 239 if (getUseClientMode()) { 240 throw new IllegalStateException("Not allowed in client mode"); 241 } 242 243 if (isHandshakeStarted()) { 244 throw new IllegalStateException( 245 "Channel ID is only available after handshake completes"); 246 } 247 return NativeCrypto.SSL_get_tls_channel_id(sslNativePointer); 248 } 249 } 250 251 /** 252 * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client engine. 253 * 254 * <p>This method needs to be invoked before the handshake starts. 255 * 256 * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key (disables 257 * TLS Channel ID). The private key must be an Elliptic Curve (EC) key based on the NIST 258 * P-256 curve (aka SECG secp256r1 or ANSI X9.62 prime256v1). 259 * 260 * @throws IllegalStateException if this is a server engine or if the handshake has already 261 * started. 262 */ 263 void setChannelIdPrivateKey(PrivateKey privateKey) { 264 if (!getUseClientMode()) { 265 throw new IllegalStateException("Not allowed in server mode"); 266 } 267 268 synchronized (stateLock) { 269 if (isHandshakeStarted()) { 270 throw new IllegalStateException("Could not change Channel ID private key " 271 + "after the initial handshake has begun."); 272 } 273 274 if (privateKey == null) { 275 sslParameters.channelIdEnabled = false; 276 channelIdPrivateKey = null; 277 return; 278 } 279 280 sslParameters.channelIdEnabled = true; 281 try { 282 ECParameterSpec ecParams = null; 283 if (privateKey instanceof ECKey) { 284 ecParams = ((ECKey) privateKey).getParams(); 285 } 286 if (ecParams == null) { 287 // Assume this is a P-256 key, as specified in the contract of this method. 288 ecParams = 289 OpenSSLECGroupContext.getCurveByName("prime256v1").getECParameterSpec(); 290 } 291 channelIdPrivateKey = 292 OpenSSLKey.fromECPrivateKeyForTLSStackOnly(privateKey, ecParams); 293 } catch (InvalidKeyException e) { 294 // Will have error in startHandshake 295 } 296 } 297 } 298 299 /** 300 * Sets the listener for the completion of the TLS handshake. 301 */ 302 void setHandshakeListener(HandshakeListener handshakeListener) { 303 synchronized (stateLock) { 304 if (isHandshakeStarted()) { 305 throw new IllegalStateException( 306 "Handshake listener must be set before starting the handshake."); 307 } 308 this.handshakeListener = handshakeListener; 309 } 310 } 311 312 private boolean isHandshakeStarted() { 313 switch (engineState) { 314 case NEW: 315 case MODE_SET: 316 return false; 317 default: 318 return true; 319 } 320 } 321 322 @Override 323 public void beginHandshake() throws SSLException { 324 synchronized (stateLock) { 325 beginHandshakeInternal(); 326 } 327 } 328 329 private void beginHandshakeInternal() throws SSLException { 330 switch (engineState) { 331 case MODE_SET: 332 // This is the only allowed state. 333 break; 334 case HANDSHAKE_STARTED: 335 throw new IllegalStateException("Handshake has already been started"); 336 case CLOSED_INBOUND: 337 case CLOSED_OUTBOUND: 338 case CLOSED: 339 throw new IllegalStateException("Engine has already been closed"); 340 default: 341 throw new IllegalStateException("Client/server mode must be set before handshake"); 342 } 343 344 engineState = EngineState.HANDSHAKE_STARTED; 345 346 boolean releaseResources = true; 347 try { 348 final AbstractSessionContext sessionContext = sslParameters.getSessionContext(); 349 sslNativePointer = NativeCrypto.SSL_new(sessionContext.sslCtxNativePointer); 350 networkBio = NativeCrypto.SSL_BIO_new(sslNativePointer); 351 sslSession = sslParameters.getSessionToReuse( 352 sslNativePointer, getSniHostname(), getPeerPort()); 353 sslParameters.setSSLParameters(sslNativePointer, this, this, getSniHostname()); 354 sslParameters.setCertificateValidation(sslNativePointer); 355 sslParameters.setTlsChannelId(sslNativePointer, channelIdPrivateKey); 356 if (getUseClientMode()) { 357 NativeCrypto.SSL_set_connect_state(sslNativePointer); 358 } else { 359 NativeCrypto.SSL_set_accept_state(sslNativePointer); 360 } 361 maxSealOverhead = NativeCrypto.SSL_max_seal_overhead(sslNativePointer); 362 handshake(); 363 releaseResources = false; 364 } catch (IOException e) { 365 // Write CCS errors to EventLog 366 String message = e.getMessage(); 367 // Must match error reason string of SSL_R_UNEXPECTED_CCS (in ssl/ssl_err.c) 368 if (message.contains("unexpected CCS")) { 369 String logMessage = String.format("ssl_unexpected_ccs: host=%s", getSniHostname()); 370 Platform.logEvent(logMessage); 371 } 372 throw new SSLException(e); 373 } finally { 374 if (releaseResources) { 375 engineState = EngineState.CLOSED; 376 shutdownAndFreeSslNative(); 377 } 378 } 379 } 380 381 @Override 382 public void closeInbound() throws SSLException { 383 synchronized (stateLock) { 384 if (engineState == EngineState.CLOSED) { 385 return; 386 } 387 if (engineState == EngineState.CLOSED_OUTBOUND) { 388 engineState = EngineState.CLOSED; 389 } else { 390 engineState = EngineState.CLOSED_INBOUND; 391 } 392 } 393 // TODO anything else to notify OpenSSL layer? 394 } 395 396 @Override 397 public void closeOutbound() { 398 synchronized (stateLock) { 399 if (engineState == EngineState.CLOSED || engineState == EngineState.CLOSED_OUTBOUND) { 400 return; 401 } 402 if (engineState != EngineState.MODE_SET && engineState != EngineState.NEW) { 403 shutdownAndFreeSslNative(); 404 } 405 if (engineState == EngineState.CLOSED_INBOUND) { 406 engineState = EngineState.CLOSED; 407 } else { 408 engineState = EngineState.CLOSED_OUTBOUND; 409 } 410 } 411 shutdown(); 412 } 413 414 @Override 415 public Runnable getDelegatedTask() { 416 // This implementation doesn't use any delegated tasks. 417 return null; 418 } 419 420 @Override 421 public String[] getEnabledCipherSuites() { 422 return sslParameters.getEnabledCipherSuites(); 423 } 424 425 @Override 426 public String[] getEnabledProtocols() { 427 return sslParameters.getEnabledProtocols(); 428 } 429 430 @Override 431 public boolean getEnableSessionCreation() { 432 return sslParameters.getEnableSessionCreation(); 433 } 434 435 @Override 436 public SSLParameters getSSLParameters() { 437 SSLParameters params = super.getSSLParameters(); 438 Platform.getSSLParameters(params, sslParameters, this); 439 return params; 440 } 441 442 public void setSniHostname(String sniHostname) { 443 this.sniHostname = sniHostname; 444 } 445 446 public String getSniHostname() { 447 return sniHostname != null ? sniHostname : getPeerHost(); 448 } 449 450 @Override 451 public void setSSLParameters(SSLParameters p) { 452 super.setSSLParameters(p); 453 Platform.setSSLParameters(p, sslParameters, this); 454 } 455 456 @Override 457 public HandshakeStatus getHandshakeStatus() { 458 synchronized (stateLock) { 459 return getHandshakeStatusInternal(); 460 } 461 } 462 463 private HandshakeStatus getHandshakeStatusInternal() { 464 if (handshakeFinished) { 465 return HandshakeStatus.NOT_HANDSHAKING; 466 } 467 switch (engineState) { 468 case HANDSHAKE_STARTED: 469 return pendingStatus(pendingOutboundEncryptedBytes()); 470 case HANDSHAKE_COMPLETED: 471 return HandshakeStatus.NEED_WRAP; 472 case NEW: 473 case MODE_SET: 474 case CLOSED: 475 case CLOSED_INBOUND: 476 case CLOSED_OUTBOUND: 477 case READY: 478 case READY_HANDSHAKE_CUT_THROUGH: 479 return HandshakeStatus.NOT_HANDSHAKING; 480 default: 481 break; 482 } 483 throw new IllegalStateException("Unexpected engine state: " + engineState); 484 } 485 486 private int pendingOutboundEncryptedBytes() { 487 return NativeCrypto.SSL_pending_written_bytes_in_BIO(networkBio); 488 } 489 490 private int pendingInboundCleartextBytes() { 491 return NativeCrypto.SSL_pending_readable_bytes(sslNativePointer); 492 } 493 494 private static SSLEngineResult.HandshakeStatus pendingStatus(int pendingOutboundBytes) { 495 // Depending on if there is something left in the BIO we need to WRAP or UNWRAP 496 return pendingOutboundBytes > 0 ? NEED_WRAP : NEED_UNWRAP; 497 } 498 499 @Override 500 public boolean getNeedClientAuth() { 501 return sslParameters.getNeedClientAuth(); 502 } 503 504 @Override 505 public SSLSession getSession() { 506 if (sslSession == null) { 507 return handshakeSession != null ? Platform.wrapSSLSession(handshakeSession) 508 : SSLNullSession.getNullSession(); 509 } 510 return Platform.wrapSSLSession(sslSession); 511 } 512 513 @Override 514 public String[] getSupportedCipherSuites() { 515 return NativeCrypto.getSupportedCipherSuites(); 516 } 517 518 @Override 519 public String[] getSupportedProtocols() { 520 return NativeCrypto.getSupportedProtocols(); 521 } 522 523 @Override 524 public boolean getUseClientMode() { 525 return sslParameters.getUseClientMode(); 526 } 527 528 @Override 529 public boolean getWantClientAuth() { 530 return sslParameters.getWantClientAuth(); 531 } 532 533 @Override 534 public boolean isInboundDone() { 535 if (sslNativePointer == 0) { 536 synchronized (stateLock) { 537 return engineState == EngineState.CLOSED 538 || engineState == EngineState.CLOSED_INBOUND; 539 } 540 } 541 return (NativeCrypto.SSL_get_shutdown(sslNativePointer) & SSL_RECEIVED_SHUTDOWN) != 0; 542 } 543 544 @Override 545 public boolean isOutboundDone() { 546 if (sslNativePointer == 0) { 547 synchronized (stateLock) { 548 return engineState == EngineState.CLOSED 549 || engineState == EngineState.CLOSED_OUTBOUND; 550 } 551 } 552 return (NativeCrypto.SSL_get_shutdown(sslNativePointer) & SSL_SENT_SHUTDOWN) != 0; 553 } 554 555 @Override 556 public void setEnabledCipherSuites(String[] suites) { 557 sslParameters.setEnabledCipherSuites(suites); 558 } 559 560 @Override 561 public void setEnabledProtocols(String[] protocols) { 562 sslParameters.setEnabledProtocols(protocols); 563 } 564 565 @Override 566 public void setEnableSessionCreation(boolean flag) { 567 sslParameters.setEnableSessionCreation(flag); 568 } 569 570 @Override 571 public void setNeedClientAuth(boolean need) { 572 sslParameters.setNeedClientAuth(need); 573 } 574 575 @Override 576 public void setUseClientMode(boolean mode) { 577 synchronized (stateLock) { 578 if (engineState != EngineState.MODE_SET && engineState != EngineState.NEW) { 579 throw new IllegalArgumentException( 580 "Can not change mode after handshake: engineState == " + engineState); 581 } 582 engineState = EngineState.MODE_SET; 583 } 584 sslParameters.setUseClientMode(mode); 585 } 586 587 @Override 588 public void setWantClientAuth(boolean want) { 589 sslParameters.setWantClientAuth(want); 590 } 591 592 @Override 593 public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst) throws SSLException { 594 synchronized (stateLock) { 595 try { 596 return unwrap(singleSrcBuffer(src), singleDstBuffer(dst)); 597 } finally { 598 resetSingleSrcBuffer(); 599 resetSingleDstBuffer(); 600 } 601 } 602 } 603 604 @Override 605 public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts) throws SSLException { 606 synchronized (stateLock) { 607 try { 608 return unwrap(singleSrcBuffer(src), dsts); 609 } finally { 610 resetSingleSrcBuffer(); 611 } 612 } 613 } 614 615 @Override 616 public SSLEngineResult unwrap(final ByteBuffer src, final ByteBuffer[] dsts, final int offset, 617 final int length) throws SSLException { 618 synchronized (stateLock) { 619 try { 620 return unwrap(singleSrcBuffer(src), 0, 1, dsts, offset, length); 621 } finally { 622 resetSingleSrcBuffer(); 623 } 624 } 625 } 626 627 SSLEngineResult unwrap(final ByteBuffer[] srcs, final ByteBuffer[] dsts) throws SSLException { 628 checkNotNull(srcs, "srcs"); 629 checkNotNull(dsts, "dsts"); 630 return unwrap(srcs, 0, srcs.length, dsts, 0, dsts.length); 631 } 632 633 SSLEngineResult unwrap(final ByteBuffer[] srcs, int srcsOffset, final int srcsLength, 634 final ByteBuffer[] dsts, final int dstsOffset, final int dstsLength) 635 throws SSLException { 636 checkNotNull(srcs, "srcs"); 637 checkNotNull(dsts, "dsts"); 638 639 checkIndex(srcs.length, srcsOffset, srcsLength, "srcs"); 640 checkIndex(dsts.length, dstsOffset, dstsLength, "dsts"); 641 642 // Determine the output capacity. 643 final int dstLength = calcDstsLength(dsts, dstsOffset, dstsLength); 644 final int endOffset = dstsOffset + dstsLength; 645 646 final int srcsEndOffset = srcsOffset + srcsLength; 647 final long srcLength = calcSrcsLength(srcs, srcsOffset, srcsEndOffset); 648 649 synchronized (stateLock) { 650 switch (engineState) { 651 case MODE_SET: 652 // Begin the handshake implicitly. 653 beginHandshakeInternal(); 654 break; 655 case CLOSED_INBOUND: 656 case CLOSED: 657 // If the inbound direction is closed. we can't send anymore. 658 return new SSLEngineResult(Status.CLOSED, getHandshakeStatusInternal(), 0, 0); 659 case NEW: 660 throw new IllegalStateException( 661 "Client/server mode must be set before calling unwrap"); 662 default: 663 break; 664 } 665 666 HandshakeStatus handshakeStatus = HandshakeStatus.NOT_HANDSHAKING; 667 if (!handshakeFinished) { 668 handshakeStatus = handshake(); 669 if (handshakeStatus == NEED_WRAP) { 670 return NEED_WRAP_OK; 671 } 672 if (engineState == EngineState.CLOSED) { 673 return NEED_WRAP_CLOSED; 674 } 675 // NEED_UNWRAP - just fall through to perform the unwrap. 676 } 677 678 // Consume any source data. Skip this if there are unread cleartext data. 679 boolean noCleartextDataAvailable = pendingInboundCleartextBytes() <= 0; 680 int lenRemaining = 0; 681 if (srcLength > 0 && noCleartextDataAvailable) { 682 if (srcLength < SSL3_RT_HEADER_LENGTH) { 683 // Need to be able to read a full TLS header. 684 return new SSLEngineResult(BUFFER_UNDERFLOW, getHandshakeStatus(), 0, 0); 685 } 686 687 int packetLength = SSLUtils.getEncryptedPacketLength(srcs, srcsOffset); 688 if (packetLength < 0) { 689 throw new SSLException("Unable to parse TLS packet header"); 690 } 691 692 if (srcLength < packetLength) { 693 // We either have not enough data to read the packet header or not enough for 694 // reading the whole packet. 695 return new SSLEngineResult(BUFFER_UNDERFLOW, getHandshakeStatus(), 0, 0); 696 } 697 698 // Limit the amount of data to be read to a single packet. 699 lenRemaining = packetLength; 700 } else if (noCleartextDataAvailable) { 701 // No pending data and nothing provided as input. Need more data. 702 return new SSLEngineResult(BUFFER_UNDERFLOW, getHandshakeStatus(), 0, 0); 703 } 704 705 // Write all of the encrypted source data to the networkBio 706 int bytesConsumed = 0; 707 if (lenRemaining > 0 && srcsOffset < srcsEndOffset) { 708 do { 709 ByteBuffer src = srcs[srcsOffset]; 710 int remaining = src.remaining(); 711 if (remaining == 0) { 712 // We must skip empty buffers as BIO_write will return 0 if asked to 713 // write something with length 0. 714 srcsOffset++; 715 continue; 716 } 717 // Write the source encrypted data to the networkBio. 718 int written = writeEncryptedData(src, Math.min(lenRemaining, remaining)); 719 if (written > 0) { 720 bytesConsumed += written; 721 lenRemaining -= written; 722 if (lenRemaining == 0) { 723 // A whole packet has been consumed. 724 break; 725 } 726 727 if (written == remaining) { 728 srcsOffset++; 729 } else { 730 // We were not able to write everything into the BIO so break the 731 // write loop as otherwise we will produce an error on the next 732 // write attempt, which will trigger a SSL.clearError() later. 733 break; 734 } 735 } else { 736 // BIO_write returned a negative or zero number, this means we could not 737 // complete the write operation and should retry later. 738 // We ignore BIO_* errors here as we use in memory BIO anyway and will 739 // do another SSL_* call later on in which we will produce an exception 740 // in case of an error 741 NativeCrypto.SSL_clear_error(); 742 break; 743 } 744 } while (srcsOffset < srcsEndOffset); 745 } 746 747 // Now read any available plaintext data. 748 int bytesProduced = 0; 749 if (dstLength > 0) { 750 // Write decrypted data to dsts buffers 751 for (int idx = dstsOffset; idx < endOffset; ++idx) { 752 ByteBuffer dst = dsts[idx]; 753 if (!dst.hasRemaining()) { 754 continue; 755 } 756 757 int bytesRead = readPlaintextData(dst); 758 if (bytesRead > 0) { 759 bytesProduced += bytesRead; 760 if (dst.hasRemaining()) { 761 // We haven't filled this buffer fully, break out of the loop 762 // and determine the correct response status below. 763 break; 764 } 765 } else { 766 // Return an appropriate result based on the error code. 767 int sslError = NativeCrypto.SSL_get_error(sslNativePointer, bytesRead); 768 switch (sslError) { 769 case SSL_ERROR_ZERO_RETURN: 770 // This means the connection was shutdown correctly, close inbound 771 // and outbound 772 closeAll(); 773 return newResult(bytesConsumed, bytesProduced, handshakeStatus); 774 case SSL_ERROR_WANT_READ: 775 case SSL_ERROR_WANT_WRITE: 776 return newResult(bytesConsumed, bytesProduced, handshakeStatus); 777 default: 778 return sslReadErrorResult(NativeCrypto.SSL_get_last_error_number(), 779 bytesConsumed, bytesProduced); 780 } 781 } 782 } 783 } else { 784 // If the capacity of all destination buffers is 0 we need to trigger a SSL_read 785 // anyway to ensure everything is flushed in the BIO pair and so we can detect it 786 // in the pendingInboundCleartextBytes() call. 787 try { 788 if (NativeCrypto.ENGINE_SSL_read_direct(sslNativePointer, EMPTY_ADDR, 0, this) 789 <= 0) { 790 // We do not check SSL_get_error as we are not interested in any error that 791 // is not fatal. 792 int err = NativeCrypto.SSL_get_last_error_number(); 793 if (err != SSL_ERROR_NONE) { 794 return sslReadErrorResult(err, bytesConsumed, bytesProduced); 795 } 796 } 797 } catch (IOException e) { 798 throw new SSLException(e); 799 } 800 } 801 802 // There won't be any application data until we're done handshaking. 803 // We first check handshakeFinished to eliminate the overhead of extra JNI call if 804 // possible. 805 int pendingCleartextBytes = handshakeFinished ? pendingInboundCleartextBytes() : 0; 806 if (pendingCleartextBytes > 0) { 807 // We filled all buffers but there is still some data pending in the BIO buffer, 808 // return BUFFER_OVERFLOW. 809 return new SSLEngineResult(BUFFER_OVERFLOW, 810 mayFinishHandshake(handshakeStatus == FINISHED 811 ? handshakeStatus 812 : getHandshakeStatusInternal()), 813 bytesConsumed, bytesProduced); 814 } 815 816 return newResult(bytesConsumed, bytesProduced, handshakeStatus); 817 } 818 } 819 820 private static int calcDstsLength(ByteBuffer[] dsts, int dstsOffset, int dstsLength) { 821 int capacity = 0; 822 for (int i = 0; i < dsts.length; i++) { 823 ByteBuffer dst = dsts[i]; 824 checkNotNull(dst, "one of the dst"); 825 if (dst.isReadOnly()) { 826 throw new ReadOnlyBufferException(); 827 } 828 if (i >= dstsOffset && i < dstsOffset + dstsLength) { 829 capacity += dst.remaining(); 830 } 831 } 832 return capacity; 833 } 834 835 private static long calcSrcsLength(ByteBuffer[] srcs, int srcsOffset, int srcsEndOffset) { 836 long len = 0; 837 for (int i = srcsOffset; i < srcsEndOffset; i++) { 838 ByteBuffer src = srcs[i]; 839 if (src == null) { 840 throw new IllegalArgumentException("srcs[" + i + "] is null"); 841 } 842 len += src.remaining(); 843 } 844 return len; 845 } 846 847 private SSLEngineResult.HandshakeStatus handshake() throws SSLException { 848 long sslSessionCtx = 0L; 849 try { 850 // Only actually perform the handshake if we haven't already just completed it 851 // via BIO operations. 852 int code = NativeCrypto.ENGINE_SSL_do_handshake(sslNativePointer, this); 853 if (code <= 0) { 854 int sslError = NativeCrypto.SSL_get_error(sslNativePointer, code); 855 switch (sslError) { 856 case SSL_ERROR_WANT_READ: 857 case SSL_ERROR_WANT_WRITE: 858 return pendingStatus(pendingOutboundEncryptedBytes()); 859 default: 860 // Everything else is considered as error 861 throw shutdownWithError("SSL_do_handshake"); 862 } 863 } 864 865 // Handshake is finished! 866 sslSessionCtx = NativeCrypto.SSL_get1_session(sslNativePointer); 867 if (sslSessionCtx == 0) { 868 // TODO(nathanmittler): Should we throw here? 869 // return pendingStatus(pendingOutboundBytes()); 870 throw shutdownWithError("Failed to obtain session after handshake completed"); 871 } 872 sslSession = sslParameters.setupSession(sslSessionCtx, sslNativePointer, sslSession, 873 getSniHostname(), getPeerPort(), true); 874 if (sslSession != null && engineState == EngineState.HANDSHAKE_STARTED) { 875 engineState = EngineState.READY_HANDSHAKE_CUT_THROUGH; 876 } else { 877 engineState = EngineState.READY; 878 } 879 finishHandshake(); 880 return FINISHED; 881 } catch (Exception e) { 882 throw toSSLHandshakeException(e); 883 } finally { 884 if (sslSession == null && sslSessionCtx != 0) { 885 NativeCrypto.SSL_SESSION_free(sslSessionCtx); 886 } 887 } 888 } 889 890 private void finishHandshake() throws SSLException { 891 handshakeFinished = true; 892 // Notify the listener, if provided. 893 if (handshakeListener != null) { 894 handshakeListener.onHandshakeFinished(); 895 } 896 } 897 /** 898 * Write plaintext data to the OpenSSL internal BIO 899 * 900 * Calling this function with src.remaining == 0 is undefined. 901 */ 902 private int writePlaintextData(final ByteBuffer src, int len) throws SSLException { 903 try { 904 final int pos = src.position(); 905 final int sslWrote; 906 907 if (src.isDirect()) { 908 long addr = NativeCrypto.getDirectBufferAddress(src) + pos; 909 sslWrote = NativeCrypto.ENGINE_SSL_write_direct(sslNativePointer, addr, len, this); 910 } else { 911 ByteBuffer heapSrc = toHeapBuffer(src, len); 912 sslWrote = NativeCrypto.ENGINE_SSL_write_heap(sslNativePointer, heapSrc.array(), 913 heapSrc.arrayOffset() + heapSrc.position(), len, this); 914 } 915 if (sslWrote > 0) { 916 src.position(pos + sslWrote); 917 } 918 return sslWrote; 919 } catch (Exception e) { 920 throw convertException(e); 921 } 922 } 923 924 /** 925 * Read plaintext data from the OpenSSL internal BIO 926 */ 927 private int readPlaintextData(final ByteBuffer dst) throws SSLException { 928 try { 929 final int sslRead; 930 final int pos = dst.position(); 931 final int limit = dst.limit(); 932 final int len = Math.min(SSL3_RT_MAX_PACKET_SIZE, limit - pos); 933 if (dst.isDirect()) { 934 long addr = NativeCrypto.getDirectBufferAddress(dst) + pos; 935 sslRead = NativeCrypto.ENGINE_SSL_read_direct(sslNativePointer, addr, len, this); 936 if (sslRead > 0) { 937 dst.position(pos + sslRead); 938 } 939 } else if (dst.hasArray()) { 940 sslRead = NativeCrypto.ENGINE_SSL_read_heap( 941 sslNativePointer, dst.array(), dst.arrayOffset() + pos, len, this); 942 if (sslRead > 0) { 943 dst.position(pos + sslRead); 944 } 945 } else { 946 byte[] data = new byte[len]; 947 sslRead = NativeCrypto.ENGINE_SSL_read_heap(sslNativePointer, data, 0, len, this); 948 if (sslRead > 0) { 949 dst.put(data, 0, sslRead); 950 } 951 } 952 return sslRead; 953 } catch (Exception e) { 954 throw convertException(e); 955 } 956 } 957 958 private SSLException convertException(Throwable e) { 959 if (e instanceof SSLHandshakeException || !handshakeFinished) { 960 return SSLUtils.toSSLHandshakeException(e); 961 } 962 return SSLUtils.toSSLException(e); 963 } 964 965 /** 966 * Write encrypted data to the OpenSSL network BIO. 967 */ 968 private int writeEncryptedData(final ByteBuffer src, int len) throws SSLException { 969 try { 970 final int pos = src.position(); 971 final int netWrote; 972 if (src.isDirect()) { 973 long addr = NativeCrypto.getDirectBufferAddress(src) + pos; 974 netWrote = NativeCrypto.ENGINE_SSL_write_BIO_direct( 975 sslNativePointer, networkBio, addr, len, this); 976 } else { 977 ByteBuffer heapSrc = toHeapBuffer(src, len); 978 netWrote = NativeCrypto.ENGINE_SSL_write_BIO_heap(sslNativePointer, networkBio, 979 heapSrc.array(), heapSrc.arrayOffset() + heapSrc.position(), len, this); 980 } 981 982 if (netWrote >= 0) { 983 src.position(pos + netWrote); 984 } 985 986 return netWrote; 987 } catch (IOException e) { 988 throw new SSLException(e); 989 } 990 } 991 992 private SSLEngineResult readPendingBytesFromBIO(ByteBuffer dst, int bytesConsumed, 993 int bytesProduced, SSLEngineResult.HandshakeStatus status) throws SSLException { 994 try { 995 // Check to see if the engine wrote data into the network BIO 996 int pendingNet = pendingOutboundEncryptedBytes(); 997 if (pendingNet > 0) { 998 // Do we have enough room in dst to write encrypted data? 999 int capacity = dst.remaining(); 1000 if (capacity < pendingNet) { 1001 return new SSLEngineResult(BUFFER_OVERFLOW, 1002 mayFinishHandshake( 1003 status == FINISHED ? status : getHandshakeStatus(pendingNet)), 1004 bytesConsumed, bytesProduced); 1005 } 1006 1007 // Write the pending data from the network BIO into the dst buffer 1008 int produced = readEncryptedData(dst, pendingNet); 1009 1010 if (produced <= 0) { 1011 // We ignore BIO_* errors here as we use in memory BIO anyway and will do 1012 // another SSL_* call later on in which we will produce an exception in 1013 // case of an error 1014 NativeCrypto.SSL_clear_error(); 1015 } else { 1016 bytesProduced += produced; 1017 pendingNet -= produced; 1018 } 1019 1020 return new SSLEngineResult(getEngineStatus(), 1021 mayFinishHandshake( 1022 status == FINISHED ? status : getHandshakeStatus(pendingNet)), 1023 bytesConsumed, bytesProduced); 1024 } 1025 return null; 1026 } catch (Exception e) { 1027 throw convertException(e); 1028 } 1029 } 1030 1031 /** 1032 * Read encrypted data from the OpenSSL network BIO 1033 */ 1034 private int readEncryptedData(final ByteBuffer dst, final int pending) throws SSLException { 1035 try { 1036 int bioRead = 0; 1037 if (dst.remaining() >= pending) { 1038 final int pos = dst.position(); 1039 final int limit = dst.limit(); 1040 final int len = Math.min(pending, limit - pos); 1041 if (dst.isDirect()) { 1042 long addr = NativeCrypto.getDirectBufferAddress(dst) + pos; 1043 bioRead = NativeCrypto.ENGINE_SSL_read_BIO_direct( 1044 sslNativePointer, networkBio, addr, len, this); 1045 if (bioRead > 0) { 1046 dst.position(pos + bioRead); 1047 return bioRead; 1048 } 1049 } else if (dst.hasArray()) { 1050 bioRead = NativeCrypto.ENGINE_SSL_read_BIO_heap(sslNativePointer, networkBio, 1051 dst.array(), dst.arrayOffset() + pos, pending, this); 1052 if (bioRead > 0) { 1053 dst.position(pos + bioRead); 1054 return bioRead; 1055 } 1056 } else { 1057 byte[] data = new byte[len]; 1058 bioRead = NativeCrypto.ENGINE_SSL_read_BIO_heap( 1059 sslNativePointer, networkBio, data, 0, pending, this); 1060 if (bioRead > 0) { 1061 dst.put(data, 0, bioRead); 1062 return bioRead; 1063 } 1064 } 1065 } 1066 return bioRead; 1067 } catch (Exception e) { 1068 throw convertException(e); 1069 } 1070 } 1071 1072 private SSLEngineResult.HandshakeStatus mayFinishHandshake( 1073 SSLEngineResult.HandshakeStatus status) throws SSLException { 1074 if (!handshakeFinished 1075 && status 1076 == NOT_HANDSHAKING /*|| engineState == EngineState.HANDSHAKE_COMPLETED)*/) { 1077 // If the status was NOT_HANDSHAKING and we not finished the handshake we need to call 1078 // SSL_do_handshake() again 1079 return handshake(); 1080 } 1081 return status; 1082 } 1083 1084 private SSLEngineResult.HandshakeStatus getHandshakeStatus(int pending) { 1085 // Check if we are in the initial handshake phase or shutdown phase 1086 return !handshakeFinished ? pendingStatus(pending) : NOT_HANDSHAKING; 1087 } 1088 1089 private SSLEngineResult.Status getEngineStatus() { 1090 switch (engineState) { 1091 case CLOSED_INBOUND: 1092 case CLOSED_OUTBOUND: 1093 case CLOSED: 1094 return CLOSED; 1095 default: 1096 return OK; 1097 } 1098 } 1099 1100 private void closeAll() throws SSLException { 1101 closeOutbound(); 1102 closeInbound(); 1103 } 1104 1105 private SSLEngineResult sslReadErrorResult(int err, int bytesConsumed, int bytesProduced) 1106 throws SSLException { 1107 if (!handshakeFinished && pendingOutboundEncryptedBytes() > 0) { 1108 return new SSLEngineResult(OK, NEED_WRAP, bytesConsumed, bytesProduced); 1109 } 1110 throw shutdownWithError(NativeCrypto.SSL_get_error_string(err)); 1111 } 1112 1113 private SSLException shutdownWithError(String err) { 1114 // There was an internal error -- shutdown 1115 shutdown(); 1116 if (getHandshakeStatusInternal() == HandshakeStatus.FINISHED) { 1117 return new SSLException(err); 1118 } 1119 return new SSLHandshakeException(err); 1120 } 1121 1122 private SSLEngineResult newResult(int bytesConsumed, int bytesProduced, 1123 SSLEngineResult.HandshakeStatus status) throws SSLException { 1124 return new SSLEngineResult(getEngineStatus(), 1125 mayFinishHandshake(status == FINISHED ? status : getHandshakeStatusInternal()), 1126 bytesConsumed, bytesProduced); 1127 } 1128 1129 @Override 1130 public final SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException { 1131 synchronized (stateLock) { 1132 try { 1133 return wrap(singleSrcBuffer(src), dst); 1134 } finally { 1135 resetSingleSrcBuffer(); 1136 } 1137 } 1138 } 1139 1140 @Override 1141 public SSLEngineResult wrap(ByteBuffer[] srcs, int offset, int length, ByteBuffer dst) 1142 throws SSLException { 1143 checkNotNull(srcs, "srcs"); 1144 checkNotNull(dst, "dst"); 1145 checkIndex(srcs.length, offset, length, "srcs"); 1146 if (dst.isReadOnly()) { 1147 throw new ReadOnlyBufferException(); 1148 } 1149 1150 synchronized (stateLock) { 1151 switch (engineState) { 1152 case MODE_SET: 1153 // Begin the handshake implicitly. 1154 beginHandshakeInternal(); 1155 break; 1156 case CLOSED_OUTBOUND: 1157 case CLOSED: 1158 return new SSLEngineResult(Status.CLOSED, getHandshakeStatusInternal(), 0, 0); 1159 case NEW: 1160 throw new IllegalStateException( 1161 "Client/server mode must be set before calling wrap"); 1162 default: 1163 break; 1164 } 1165 1166 // If we haven't completed the handshake yet, just let the caller know. 1167 HandshakeStatus handshakeStatus = HandshakeStatus.NOT_HANDSHAKING; 1168 // Prepare OpenSSL to work in server mode and receive handshake 1169 if (!handshakeFinished) { 1170 handshakeStatus = handshake(); 1171 if (handshakeStatus == NEED_UNWRAP) { 1172 return NEED_UNWRAP_OK; 1173 } 1174 1175 if (engineState == EngineState.CLOSED) { 1176 return NEED_UNWRAP_CLOSED; 1177 } 1178 // NEED_WRAP - just fall through to perform the wrap. 1179 } 1180 1181 int srcsLen = 0; 1182 final int endOffset = offset + length; 1183 for (int i = offset; i < endOffset; ++i) { 1184 final ByteBuffer src = srcs[i]; 1185 if (src == null) { 1186 throw new IllegalArgumentException("srcs[" + i + "] is null"); 1187 } 1188 if (srcsLen == SSL3_RT_MAX_PLAIN_LENGTH) { 1189 continue; 1190 } 1191 1192 srcsLen += src.remaining(); 1193 if (srcsLen > SSL3_RT_MAX_PLAIN_LENGTH || srcsLen < 0) { 1194 // If srcLen > MAX_PLAINTEXT_LENGTH or secLen < 0 just set it to 1195 // MAX_PLAINTEXT_LENGTH. 1196 // This also help us to guard against overflow. 1197 // We not break out here as we still need to check for null entries in srcs[]. 1198 srcsLen = SSL3_RT_MAX_PLAIN_LENGTH; 1199 } 1200 } 1201 1202 if (dst.remaining() < calculateOutNetBufSize(srcsLen)) { 1203 return new SSLEngineResult( 1204 Status.BUFFER_OVERFLOW, getHandshakeStatusInternal(), 0, 0); 1205 } 1206 1207 int bytesProduced = 0; 1208 int bytesConsumed = 0; 1209 loop: 1210 for (int i = offset; i < endOffset; ++i) { 1211 final ByteBuffer src = srcs[i]; 1212 checkNotNull(src, "srcs[%d] is null", i); 1213 while (src.hasRemaining()) { 1214 final SSLEngineResult pendingNetResult; 1215 // Write plaintext application data to the SSL engine 1216 int result = writePlaintextData(src, 1217 Math.min(src.remaining(), SSL3_RT_MAX_PLAIN_LENGTH - bytesConsumed)); 1218 if (result > 0) { 1219 bytesConsumed += result; 1220 1221 pendingNetResult = readPendingBytesFromBIO( 1222 dst, bytesConsumed, bytesProduced, handshakeStatus); 1223 if (pendingNetResult != null) { 1224 if (pendingNetResult.getStatus() != OK) { 1225 return pendingNetResult; 1226 } 1227 bytesProduced = pendingNetResult.bytesProduced(); 1228 } 1229 if (bytesConsumed == SSL3_RT_MAX_PLAIN_LENGTH) { 1230 // If we consumed the maximum amount of bytes for the plaintext length 1231 // break out of the loop and start to fill the dst buffer. 1232 break loop; 1233 } 1234 } else { 1235 int sslError = NativeCrypto.SSL_get_error(sslNativePointer, result); 1236 switch (sslError) { 1237 case SSL_ERROR_ZERO_RETURN: 1238 // This means the connection was shutdown correctly, close inbound 1239 // and outbound 1240 closeAll(); 1241 pendingNetResult = readPendingBytesFromBIO( 1242 dst, bytesConsumed, bytesProduced, handshakeStatus); 1243 return pendingNetResult != null ? pendingNetResult 1244 : CLOSED_NOT_HANDSHAKING; 1245 case SSL_ERROR_WANT_READ: 1246 // If there is no pending data to read from BIO we should go back to 1247 // event loop and try 1248 // to read more data [1]. It is also possible that event loop will 1249 // detect the socket 1250 // has been closed. [1] 1251 // https://www.openssl.org/docs/manmaster/ssl/SSL_write.html 1252 pendingNetResult = readPendingBytesFromBIO( 1253 dst, bytesConsumed, bytesProduced, handshakeStatus); 1254 return pendingNetResult != null 1255 ? pendingNetResult 1256 : new SSLEngineResult(getEngineStatus(), NEED_UNWRAP, 1257 bytesConsumed, bytesProduced); 1258 case SSL_ERROR_WANT_WRITE: 1259 // SSL_ERROR_WANT_WRITE typically means that the underlying 1260 // transport is not writable 1261 // and we should set the "want write" flag on the selector and try 1262 // again when the 1263 // underlying transport is writable [1]. However we are not directly 1264 // writing to the 1265 // underlying transport and instead writing to a BIO buffer. The 1266 // OpenSsl documentation 1267 // says we should do the following [1]: 1268 // 1269 // "When using a buffering BIO, like a BIO pair, data must be 1270 // written into or retrieved 1271 // out of the BIO before being able to continue." 1272 // 1273 // So we attempt to drain the BIO buffer below, but if there is no 1274 // data this condition 1275 // is undefined and we assume their is a fatal error with the 1276 // openssl engine and close. 1277 // [1] https://www.openssl.org/docs/manmaster/ssl/SSL_write.html 1278 pendingNetResult = readPendingBytesFromBIO( 1279 dst, bytesConsumed, bytesProduced, handshakeStatus); 1280 return pendingNetResult != null ? pendingNetResult 1281 : NEED_WRAP_CLOSED; 1282 default: 1283 // Everything else is considered as error 1284 throw shutdownWithError("SSL_write"); 1285 } 1286 } 1287 } 1288 } 1289 // We need to check if pendingWrittenBytesInBIO was checked yet, as we may not checked 1290 // if the srcs was 1291 // empty, or only contained empty buffers. 1292 if (bytesConsumed == 0) { 1293 SSLEngineResult pendingNetResult = 1294 readPendingBytesFromBIO(dst, 0, bytesProduced, handshakeStatus); 1295 if (pendingNetResult != null) { 1296 return pendingNetResult; 1297 } 1298 } 1299 1300 // return new SSLEngineResult(OK, getHandshakeStatusInternal(), bytesConsumed, 1301 // bytesProduced); 1302 return newResult(bytesConsumed, bytesProduced, handshakeStatus); 1303 } 1304 } 1305 1306 @Override 1307 public int clientPSKKeyRequested(String identityHint, byte[] identity, byte[] key) { 1308 return sslParameters.clientPSKKeyRequested(identityHint, identity, key, this); 1309 } 1310 1311 @Override 1312 public int serverPSKKeyRequested(String identityHint, String identity, byte[] key) { 1313 return sslParameters.serverPSKKeyRequested(identityHint, identity, key, this); 1314 } 1315 1316 @Override 1317 public void onSSLStateChange(int type, int val) { 1318 synchronized (stateLock) { 1319 switch (type) { 1320 case SSL_CB_HANDSHAKE_DONE: 1321 if (engineState != EngineState.HANDSHAKE_STARTED 1322 && engineState != EngineState.READY_HANDSHAKE_CUT_THROUGH) { 1323 throw new IllegalStateException( 1324 "Completed handshake while in mode " + engineState); 1325 } 1326 engineState = EngineState.HANDSHAKE_COMPLETED; 1327 break; 1328 case SSL_CB_HANDSHAKE_START: 1329 // For clients, this will allow the NEED_UNWRAP status to be 1330 // returned. 1331 engineState = EngineState.HANDSHAKE_STARTED; 1332 break; 1333 } 1334 } 1335 } 1336 1337 @Override 1338 public void verifyCertificateChain(long[] certRefs, String authMethod) 1339 throws CertificateException { 1340 try { 1341 X509TrustManager x509tm = sslParameters.getX509TrustManager(); 1342 if (x509tm == null) { 1343 throw new CertificateException("No X.509 TrustManager"); 1344 } 1345 if (certRefs == null || certRefs.length == 0) { 1346 throw new SSLException("Peer sent no certificate"); 1347 } 1348 OpenSSLX509Certificate[] peerCertChain = 1349 OpenSSLX509Certificate.createCertChain(certRefs); 1350 1351 byte[] ocspData = NativeCrypto.SSL_get_ocsp_response(sslNativePointer); 1352 byte[] tlsSctData = NativeCrypto.SSL_get_signed_cert_timestamp_list(sslNativePointer); 1353 1354 // Used for verifyCertificateChain callback 1355 handshakeSession = new OpenSSLSessionImpl( 1356 NativeCrypto.SSL_get1_session(sslNativePointer), null, peerCertChain, ocspData, 1357 tlsSctData, getSniHostname(), getPeerPort(), null); 1358 1359 boolean client = sslParameters.getUseClientMode(); 1360 if (client) { 1361 Platform.checkServerTrusted(x509tm, peerCertChain, authMethod, this); 1362 } else { 1363 String authType = peerCertChain[0].getPublicKey().getAlgorithm(); 1364 Platform.checkClientTrusted(x509tm, peerCertChain, authType, this); 1365 } 1366 } catch (CertificateException e) { 1367 throw e; 1368 } catch (Exception e) { 1369 throw new CertificateException(e); 1370 } finally { 1371 handshakeSession = null; 1372 } 1373 } 1374 1375 @Override 1376 public void clientCertificateRequested(byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals) 1377 throws CertificateEncodingException, SSLException { 1378 sslParameters.chooseClientCertificate( 1379 keyTypeBytes, asn1DerEncodedPrincipals, sslNativePointer, this); 1380 } 1381 1382 private void shutdown() { 1383 try { 1384 NativeCrypto.ENGINE_SSL_shutdown(sslNativePointer, this); 1385 } catch (IOException ignored) { 1386 // TODO: The RI ignores close failures in SSLSocket, but need to 1387 // investigate whether it does for SSLEngine. 1388 } 1389 } 1390 1391 private void shutdownAndFreeSslNative() { 1392 try { 1393 shutdown(); 1394 } finally { 1395 free(); 1396 } 1397 } 1398 1399 private void free() { 1400 if (sslNativePointer == 0) { 1401 return; 1402 } 1403 NativeCrypto.SSL_free(sslNativePointer); 1404 NativeCrypto.BIO_free_all(networkBio); 1405 sslNativePointer = 0; 1406 networkBio = 0; 1407 } 1408 1409 @Override 1410 protected void finalize() throws Throwable { 1411 try { 1412 free(); 1413 } finally { 1414 super.finalize(); 1415 } 1416 } 1417 1418 /* @Override */ 1419 @SuppressWarnings("MissingOverride") // For compilation with Java 6. 1420 public SSLSession getHandshakeSession() { 1421 return handshakeSession; 1422 } 1423 1424 @Override 1425 public String chooseServerAlias(X509KeyManager keyManager, String keyType) { 1426 if (keyManager instanceof X509ExtendedKeyManager) { 1427 X509ExtendedKeyManager ekm = (X509ExtendedKeyManager) keyManager; 1428 return ekm.chooseEngineServerAlias(keyType, null, this); 1429 } else { 1430 return keyManager.chooseServerAlias(keyType, null, null); 1431 } 1432 } 1433 1434 @Override 1435 public String chooseClientAlias( 1436 X509KeyManager keyManager, X500Principal[] issuers, String[] keyTypes) { 1437 if (keyManager instanceof X509ExtendedKeyManager) { 1438 X509ExtendedKeyManager ekm = (X509ExtendedKeyManager) keyManager; 1439 return ekm.chooseEngineClientAlias(keyTypes, issuers, this); 1440 } else { 1441 return keyManager.chooseClientAlias(keyTypes, issuers, null); 1442 } 1443 } 1444 1445 @Override 1446 @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package 1447 public String chooseServerPSKIdentityHint(PSKKeyManager keyManager) { 1448 return keyManager.chooseServerKeyIdentityHint(this); 1449 } 1450 1451 @Override 1452 @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package 1453 public String chooseClientPSKIdentity(PSKKeyManager keyManager, String identityHint) { 1454 return keyManager.chooseClientKeyIdentity(identityHint, this); 1455 } 1456 1457 @Override 1458 @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package 1459 public SecretKey getPSKKey(PSKKeyManager keyManager, String identityHint, String identity) { 1460 return keyManager.getKey(identityHint, identity, this); 1461 } 1462 1463 /** 1464 * This method enables session ticket support. 1465 * 1466 * @param useSessionTickets True to enable session tickets 1467 */ 1468 void setUseSessionTickets(boolean useSessionTickets) { 1469 sslParameters.setUseSessionTickets(useSessionTickets); 1470 } 1471 1472 /** 1473 * Sets the list of ALPN protocols. 1474 * 1475 * @param alpnProtocols the list of ALPN protocols 1476 */ 1477 void setAlpnProtocols(String[] alpnProtocols) { 1478 sslParameters.setAlpnProtocols(alpnProtocols); 1479 } 1480 1481 /** 1482 * Returns the protocol agreed upon by client and server, or {@code null} if no protocol was 1483 * agreed upon. 1484 */ 1485 byte[] getAlpnSelectedProtocol() { 1486 return NativeCrypto.SSL_get0_alpn_selected(sslNativePointer); 1487 } 1488 1489 private ByteBuffer toHeapBuffer(ByteBuffer buffer, int len) { 1490 if (buffer.hasArray()) { 1491 return buffer; 1492 } 1493 1494 // Need to copy to a heap buffer. 1495 final ByteBuffer heapBuffer = ByteBuffer.allocate(len); 1496 final int pos = buffer.position(); 1497 final int limit = buffer.limit(); 1498 buffer.limit(pos + len); 1499 try { 1500 heapBuffer.put(buffer); 1501 heapBuffer.flip(); 1502 return heapBuffer; 1503 } finally { 1504 buffer.limit(limit); 1505 buffer.position(pos); 1506 } 1507 } 1508 1509 private ByteBuffer[] singleSrcBuffer(ByteBuffer src) { 1510 singleSrcBuffer[0] = src; 1511 return singleSrcBuffer; 1512 } 1513 1514 private void resetSingleSrcBuffer() { 1515 singleSrcBuffer[0] = null; 1516 } 1517 1518 private ByteBuffer[] singleDstBuffer(ByteBuffer src) { 1519 singleDstBuffer[0] = src; 1520 return singleDstBuffer; 1521 } 1522 1523 private void resetSingleDstBuffer() { 1524 singleDstBuffer[0] = null; 1525 } 1526 1527 private static void checkIndex(int arrayLength, int offset, int length, String arrayName) { 1528 if ((offset | length) < 0 || offset + length > arrayLength) { 1529 throw new IndexOutOfBoundsException("offset: " + offset + ", length: " + length 1530 + " (expected: offset <= offset + length <= " + arrayName + ".length (" 1531 + arrayLength + "))"); 1532 } 1533 } 1534 1535 private static <T> T checkNotNull(T obj, String fmt, Object... args) { 1536 if (obj == null) { 1537 throw new IllegalArgumentException(String.format(fmt, args)); 1538 } 1539 return obj; 1540 } 1541} 1542