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