Upgrading to Conscrypt 1.0.0.RC9. (#7044)
Motivation: Starting with 1.0.0.RC9, conscrypt supports a buffer allocator. Modifications: - Updated the creation process for the engine to pass through the ByteBufAllocator. - Wrap a ByteBufAllocator with an adapter for conscrypt. - Added a property to optionally control whether conscrypt uses Netty's buffer allocator. Result: Netty+conscrypt will support using Netty's ByteBufAllocator.
This commit is contained in:
parent
52f384b37f
commit
4448b8f42f
@ -19,6 +19,8 @@ import static io.netty.handler.ssl.SslUtils.toSSLHandshakeException;
|
|||||||
import static io.netty.util.internal.ObjectUtil.checkNotNull;
|
import static io.netty.util.internal.ObjectUtil.checkNotNull;
|
||||||
import static java.lang.Math.min;
|
import static java.lang.Math.min;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelectionListener;
|
import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelectionListener;
|
||||||
import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelector;
|
import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelector;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@ -31,6 +33,9 @@ import javax.net.ssl.SSLEngineResult;
|
|||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
|
|
||||||
import io.netty.util.internal.PlatformDependent;
|
import io.netty.util.internal.PlatformDependent;
|
||||||
|
import io.netty.util.internal.SystemPropertyUtil;
|
||||||
|
import org.conscrypt.AllocatedBuffer;
|
||||||
|
import org.conscrypt.BufferAllocator;
|
||||||
import org.conscrypt.Conscrypt;
|
import org.conscrypt.Conscrypt;
|
||||||
import org.conscrypt.HandshakeListener;
|
import org.conscrypt.HandshakeListener;
|
||||||
|
|
||||||
@ -38,6 +43,8 @@ import org.conscrypt.HandshakeListener;
|
|||||||
* A {@link JdkSslEngine} that uses the Conscrypt provider or SSL with ALPN.
|
* A {@link JdkSslEngine} that uses the Conscrypt provider or SSL with ALPN.
|
||||||
*/
|
*/
|
||||||
abstract class ConscryptAlpnSslEngine extends JdkSslEngine {
|
abstract class ConscryptAlpnSslEngine extends JdkSslEngine {
|
||||||
|
private static final boolean USE_BUFFER_ALLOCATOR = SystemPropertyUtil.getBoolean(
|
||||||
|
"io.netty.handler.ssl.conscrypt.useBufferAllocator", true);
|
||||||
private static final Class<?> ENGINES_CLASS = getEnginesClass();
|
private static final Class<?> ENGINES_CLASS = getEnginesClass();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,19 +58,32 @@ abstract class ConscryptAlpnSslEngine extends JdkSslEngine {
|
|||||||
return isAvailable() && isConscryptEngine(engine, ENGINES_CLASS);
|
return isAvailable() && isConscryptEngine(engine, ENGINES_CLASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ConscryptAlpnSslEngine newClientEngine(SSLEngine engine,
|
static ConscryptAlpnSslEngine newClientEngine(SSLEngine engine, ByteBufAllocator alloc,
|
||||||
JdkApplicationProtocolNegotiator applicationNegotiator) {
|
JdkApplicationProtocolNegotiator applicationNegotiator) {
|
||||||
return new ClientEngine(engine, applicationNegotiator);
|
return new ClientEngine(engine, alloc, applicationNegotiator);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ConscryptAlpnSslEngine newServerEngine(SSLEngine engine,
|
static ConscryptAlpnSslEngine newServerEngine(SSLEngine engine, ByteBufAllocator alloc,
|
||||||
JdkApplicationProtocolNegotiator applicationNegotiator) {
|
JdkApplicationProtocolNegotiator applicationNegotiator) {
|
||||||
return new ServerEngine(engine, applicationNegotiator);
|
return new ServerEngine(engine, alloc, applicationNegotiator);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConscryptAlpnSslEngine(SSLEngine engine, List<String> protocols) {
|
private ConscryptAlpnSslEngine(SSLEngine engine, ByteBufAllocator alloc, List<String> protocols) {
|
||||||
super(engine);
|
super(engine);
|
||||||
|
|
||||||
|
// Configure the Conscrypt engine to use Netty's buffer allocator. This is a trade-off of memory vs
|
||||||
|
// performance.
|
||||||
|
//
|
||||||
|
// If no allocator is provided, the engine will internally allocate a direct buffer of max packet size in
|
||||||
|
// order to optimize JNI calls (this happens the first time it is provided a non-direct buffer from the
|
||||||
|
// application).
|
||||||
|
//
|
||||||
|
// Alternatively, if an allocator is provided, no internal buffer will be created and direct buffers will be
|
||||||
|
// retrieved from the allocator on-demand.
|
||||||
|
if (USE_BUFFER_ALLOCATOR) {
|
||||||
|
Conscrypt.Engines.setBufferAllocator(engine, new BufferAllocatorAdapter(alloc));
|
||||||
|
}
|
||||||
|
|
||||||
// Set the list of supported ALPN protocols on the engine.
|
// Set the list of supported ALPN protocols on the engine.
|
||||||
Conscrypt.Engines.setAlpnProtocols(engine, protocols.toArray(new String[protocols.size()]));
|
Conscrypt.Engines.setAlpnProtocols(engine, protocols.toArray(new String[protocols.size()]));
|
||||||
}
|
}
|
||||||
@ -90,9 +110,9 @@ abstract class ConscryptAlpnSslEngine extends JdkSslEngine {
|
|||||||
private static final class ClientEngine extends ConscryptAlpnSslEngine {
|
private static final class ClientEngine extends ConscryptAlpnSslEngine {
|
||||||
private final ProtocolSelectionListener protocolListener;
|
private final ProtocolSelectionListener protocolListener;
|
||||||
|
|
||||||
ClientEngine(SSLEngine engine,
|
ClientEngine(SSLEngine engine, ByteBufAllocator alloc,
|
||||||
JdkApplicationProtocolNegotiator applicationNegotiator) {
|
JdkApplicationProtocolNegotiator applicationNegotiator) {
|
||||||
super(engine, applicationNegotiator.protocols());
|
super(engine, alloc, applicationNegotiator.protocols());
|
||||||
// Register for completion of the handshake.
|
// Register for completion of the handshake.
|
||||||
Conscrypt.Engines.setHandshakeListener(engine, new HandshakeListener() {
|
Conscrypt.Engines.setHandshakeListener(engine, new HandshakeListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -119,8 +139,9 @@ abstract class ConscryptAlpnSslEngine extends JdkSslEngine {
|
|||||||
private static final class ServerEngine extends ConscryptAlpnSslEngine {
|
private static final class ServerEngine extends ConscryptAlpnSslEngine {
|
||||||
private final ProtocolSelector protocolSelector;
|
private final ProtocolSelector protocolSelector;
|
||||||
|
|
||||||
ServerEngine(SSLEngine engine, JdkApplicationProtocolNegotiator applicationNegotiator) {
|
ServerEngine(SSLEngine engine, ByteBufAllocator alloc,
|
||||||
super(engine, applicationNegotiator.protocols());
|
JdkApplicationProtocolNegotiator applicationNegotiator) {
|
||||||
|
super(engine, alloc, applicationNegotiator.protocols());
|
||||||
|
|
||||||
// Register for completion of the handshake.
|
// Register for completion of the handshake.
|
||||||
Conscrypt.Engines.setHandshakeListener(engine, new HandshakeListener() {
|
Conscrypt.Engines.setHandshakeListener(engine, new HandshakeListener() {
|
||||||
@ -173,4 +194,44 @@ abstract class ConscryptAlpnSslEngine extends JdkSslEngine {
|
|||||||
private static Method getIsConscryptMethod(Class<?> enginesClass) throws NoSuchMethodException {
|
private static Method getIsConscryptMethod(Class<?> enginesClass) throws NoSuchMethodException {
|
||||||
return enginesClass.getMethod("isConscrypt", SSLEngine.class);
|
return enginesClass.getMethod("isConscrypt", SSLEngine.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class BufferAllocatorAdapter extends BufferAllocator {
|
||||||
|
private final ByteBufAllocator alloc;
|
||||||
|
|
||||||
|
BufferAllocatorAdapter(ByteBufAllocator alloc) {
|
||||||
|
this.alloc = alloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AllocatedBuffer allocateDirectBuffer(int capacity) {
|
||||||
|
return new BufferAdapter(alloc.directBuffer(capacity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class BufferAdapter extends AllocatedBuffer {
|
||||||
|
private final ByteBuf nettyBuffer;
|
||||||
|
private final ByteBuffer buffer;
|
||||||
|
|
||||||
|
BufferAdapter(ByteBuf nettyBuffer) {
|
||||||
|
this.nettyBuffer = nettyBuffer;
|
||||||
|
this.buffer = nettyBuffer.nioBuffer(0, nettyBuffer.capacity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuffer nioBuffer() {
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AllocatedBuffer retain() {
|
||||||
|
nettyBuffer.retain();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AllocatedBuffer release() {
|
||||||
|
nettyBuffer.release();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.ssl;
|
package io.netty.handler.ssl;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,8 +109,8 @@ public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicati
|
|||||||
|
|
||||||
private static final class FailureWrapper implements SslEngineWrapperFactory {
|
private static final class FailureWrapper implements SslEngineWrapperFactory {
|
||||||
@Override
|
@Override
|
||||||
public SSLEngine wrapSslEngine(SSLEngine engine, JdkApplicationProtocolNegotiator applicationNegotiator,
|
public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc,
|
||||||
boolean isServer) {
|
JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) {
|
||||||
throw new RuntimeException("ALPN unsupported. Is your classpath configured correctly?"
|
throw new RuntimeException("ALPN unsupported. Is your classpath configured correctly?"
|
||||||
+ " For Conscrypt, add the appropriate Conscrypt JAR to classpath and set the security provider."
|
+ " For Conscrypt, add the appropriate Conscrypt JAR to classpath and set the security provider."
|
||||||
+ " For Jetty-ALPN, see "
|
+ " For Jetty-ALPN, see "
|
||||||
@ -119,11 +120,11 @@ public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicati
|
|||||||
|
|
||||||
private static final class AlpnWrapper implements SslEngineWrapperFactory {
|
private static final class AlpnWrapper implements SslEngineWrapperFactory {
|
||||||
@Override
|
@Override
|
||||||
public SSLEngine wrapSslEngine(SSLEngine engine, JdkApplicationProtocolNegotiator applicationNegotiator,
|
public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc,
|
||||||
boolean isServer) {
|
JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) {
|
||||||
if (ConscryptAlpnSslEngine.isEngineSupported(engine)) {
|
if (ConscryptAlpnSslEngine.isEngineSupported(engine)) {
|
||||||
return isServer ? ConscryptAlpnSslEngine.newServerEngine(engine, applicationNegotiator)
|
return isServer ? ConscryptAlpnSslEngine.newServerEngine(engine, alloc, applicationNegotiator)
|
||||||
: ConscryptAlpnSslEngine.newClientEngine(engine, applicationNegotiator);
|
: ConscryptAlpnSslEngine.newClientEngine(engine, alloc, applicationNegotiator);
|
||||||
}
|
}
|
||||||
if (JettyAlpnSslEngine.isAvailable()) {
|
if (JettyAlpnSslEngine.isAvailable()) {
|
||||||
return isServer ? JettyAlpnSslEngine.newServerEngine(engine, applicationNegotiator)
|
return isServer ? JettyAlpnSslEngine.newServerEngine(engine, applicationNegotiator)
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.ssl;
|
package io.netty.handler.ssl;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -31,6 +32,7 @@ public interface JdkApplicationProtocolNegotiator extends ApplicationProtocolNeg
|
|||||||
* Abstract factory pattern for wrapping an {@link SSLEngine} object. This is useful for NPN/APLN support.
|
* Abstract factory pattern for wrapping an {@link SSLEngine} object. This is useful for NPN/APLN support.
|
||||||
*
|
*
|
||||||
* @param engine The engine to wrap.
|
* @param engine The engine to wrap.
|
||||||
|
* @param alloc the buffer allocator.
|
||||||
* @param applicationNegotiator The application level protocol negotiator
|
* @param applicationNegotiator The application level protocol negotiator
|
||||||
* @param isServer <ul>
|
* @param isServer <ul>
|
||||||
* <li>{@code true} if the engine is for server side of connections</li>
|
* <li>{@code true} if the engine is for server side of connections</li>
|
||||||
@ -38,8 +40,8 @@ public interface JdkApplicationProtocolNegotiator extends ApplicationProtocolNeg
|
|||||||
* </ul>
|
* </ul>
|
||||||
* @return The resulting wrapped engine. This may just be {@code engine}.
|
* @return The resulting wrapped engine. This may just be {@code engine}.
|
||||||
*/
|
*/
|
||||||
SSLEngine wrapSslEngine(SSLEngine engine, JdkApplicationProtocolNegotiator applicationNegotiator,
|
SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc,
|
||||||
boolean isServer);
|
JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.ssl;
|
package io.netty.handler.ssl;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -29,8 +30,8 @@ final class JdkDefaultApplicationProtocolNegotiator implements JdkApplicationPro
|
|||||||
new JdkDefaultApplicationProtocolNegotiator();
|
new JdkDefaultApplicationProtocolNegotiator();
|
||||||
private static final SslEngineWrapperFactory DEFAULT_SSL_ENGINE_WRAPPER_FACTORY = new SslEngineWrapperFactory() {
|
private static final SslEngineWrapperFactory DEFAULT_SSL_ENGINE_WRAPPER_FACTORY = new SslEngineWrapperFactory() {
|
||||||
@Override
|
@Override
|
||||||
public SSLEngine wrapSslEngine(SSLEngine engine, JdkApplicationProtocolNegotiator applicationNegotiator,
|
public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc,
|
||||||
boolean isServer) {
|
JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) {
|
||||||
return engine;
|
return engine;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.ssl;
|
package io.netty.handler.ssl;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,8 +31,8 @@ public final class JdkNpnApplicationProtocolNegotiator extends JdkBaseApplicatio
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SSLEngine wrapSslEngine(SSLEngine engine, JdkApplicationProtocolNegotiator applicationNegotiator,
|
public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc,
|
||||||
boolean isServer) {
|
JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) {
|
||||||
return new JettyNpnSslEngine(engine, applicationNegotiator, isServer);
|
return new JettyNpnSslEngine(engine, applicationNegotiator, isServer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -210,15 +210,15 @@ public class JdkSslContext extends SslContext {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final SSLEngine newEngine(ByteBufAllocator alloc) {
|
public final SSLEngine newEngine(ByteBufAllocator alloc) {
|
||||||
return configureAndWrapEngine(context().createSSLEngine());
|
return configureAndWrapEngine(context().createSSLEngine(), alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final SSLEngine newEngine(ByteBufAllocator alloc, String peerHost, int peerPort) {
|
public final SSLEngine newEngine(ByteBufAllocator alloc, String peerHost, int peerPort) {
|
||||||
return configureAndWrapEngine(context().createSSLEngine(peerHost, peerPort));
|
return configureAndWrapEngine(context().createSSLEngine(peerHost, peerPort), alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SSLEngine configureAndWrapEngine(SSLEngine engine) {
|
private SSLEngine configureAndWrapEngine(SSLEngine engine, ByteBufAllocator alloc) {
|
||||||
engine.setEnabledCipherSuites(cipherSuites);
|
engine.setEnabledCipherSuites(cipherSuites);
|
||||||
engine.setEnabledProtocols(protocols);
|
engine.setEnabledProtocols(protocols);
|
||||||
engine.setUseClientMode(isClient());
|
engine.setUseClientMode(isClient());
|
||||||
@ -236,7 +236,7 @@ public class JdkSslContext extends SslContext {
|
|||||||
throw new Error("Unknown auth " + clientAuth);
|
throw new Error("Unknown auth " + clientAuth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return apn.wrapperFactory().wrapSslEngine(engine, apn, isServer());
|
return apn.wrapperFactory().wrapSslEngine(engine, alloc, apn, isServer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,4 +73,10 @@ public class ConscryptJdkSslEngineInteropTest extends SSLEngineTest {
|
|||||||
@Override
|
@Override
|
||||||
public void testMutualAuthValidClientCertChainTooLongFailRequireClientAuth() throws Exception {
|
public void testMutualAuthValidClientCertChainTooLongFailRequireClientAuth() throws Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean mySetupMutualAuthServerIsValidServerException(Throwable cause) {
|
||||||
|
// TODO(scott): work around for a JDK issue. The exception should be SSLHandshakeException.
|
||||||
|
return super.mySetupMutualAuthServerIsValidServerException(cause) || causedBySSLException(cause);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
2
pom.xml
2
pom.xml
@ -192,7 +192,7 @@
|
|||||||
<tcnative.classifier>${os.detected.classifier}</tcnative.classifier>
|
<tcnative.classifier>${os.detected.classifier}</tcnative.classifier>
|
||||||
<conscrypt.groupId>org.conscrypt</conscrypt.groupId>
|
<conscrypt.groupId>org.conscrypt</conscrypt.groupId>
|
||||||
<conscrypt.artifactId>conscrypt-openjdk-uber</conscrypt.artifactId>
|
<conscrypt.artifactId>conscrypt-openjdk-uber</conscrypt.artifactId>
|
||||||
<conscrypt.version>1.0.0.RC7</conscrypt.version>
|
<conscrypt.version>1.0.0.RC9</conscrypt.version>
|
||||||
<conscrypt.classifier />
|
<conscrypt.classifier />
|
||||||
<jni.classifier>${os.detected.name}-${os.detected.arch}</jni.classifier>
|
<jni.classifier>${os.detected.name}-${os.detected.arch}</jni.classifier>
|
||||||
<logging.config>${project.basedir}/../common/src/test/resources/logback-test.xml</logging.config>
|
<logging.config>${project.basedir}/../common/src/test/resources/logback-test.xml</logging.config>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user