Motivation: This is a PR to solve the problem described here: https://github.com/netty/netty/issues/9767 Basically this PR is to add two more APIs in SslContextBuilder, for users to directly specify the KeyManager or TrustManager they want to use when building SslContext. This is very helpful when users want to pass in some customized implementation of KeyManager or TrustManager. Modification: This PR takes the first approach in here: https://github.com/netty/netty/issues/9767#issuecomment-551927994 (comment) which is to immediately convert the managers into factories and let factories continue to pass through Netty. 1. Add in SslContextBuilder the two APIs mentioned above 2. Create a KeyManagerFactoryWrapper and a TrustManagerFactoryWrapper, which take a KeyManager and a TrustManager respectively. These are two simple wrappers that do the conversion from XXXManager class to XXXManagerFactory class 3.Create a SimpleKeyManagerFactory class(and internally X509KeyManagerWrapper for compatibility), which hides the unnecessary details such as KeyManagerFactorySpi. This serves the similar functionalities with SimpleTrustManagerFactory, which was already inside Netty. Result: Easier usage.
This commit is contained in:
parent
e208e96f12
commit
6e3d784a2c
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.netty.handler.ssl;
|
||||||
|
|
||||||
|
import io.netty.handler.ssl.util.SimpleKeyManagerFactory;
|
||||||
|
import io.netty.util.internal.ObjectUtil;
|
||||||
|
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import javax.net.ssl.KeyManager;
|
||||||
|
import javax.net.ssl.ManagerFactoryParameters;
|
||||||
|
|
||||||
|
final class KeyManagerFactoryWrapper extends SimpleKeyManagerFactory {
|
||||||
|
private final KeyManager km;
|
||||||
|
|
||||||
|
KeyManagerFactoryWrapper(KeyManager km) {
|
||||||
|
this.km = ObjectUtil.checkNotNull(km, "km");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void engineInit(KeyStore keyStore, char[] var2) throws Exception { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void engineInit(ManagerFactoryParameters managerFactoryParameters)
|
||||||
|
throws Exception { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected KeyManager[] engineGetKeyManagers() {
|
||||||
|
return new KeyManager[] {km};
|
||||||
|
}
|
||||||
|
}
|
@ -18,9 +18,11 @@ package io.netty.handler.ssl;
|
|||||||
|
|
||||||
import io.netty.util.internal.UnstableApi;
|
import io.netty.util.internal.UnstableApi;
|
||||||
|
|
||||||
|
import javax.net.ssl.KeyManager;
|
||||||
import javax.net.ssl.KeyManagerFactory;
|
import javax.net.ssl.KeyManagerFactory;
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -160,6 +162,15 @@ public final class SslContextBuilder {
|
|||||||
return new SslContextBuilder(true).keyManager(keyManagerFactory);
|
return new SslContextBuilder(true).keyManager(keyManagerFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a builder for new server-side {@link SslContext} with {@link KeyManager}.
|
||||||
|
*
|
||||||
|
* @param KeyManager non-{@code null} KeyManager for server's private key
|
||||||
|
*/
|
||||||
|
public static SslContextBuilder forServer(KeyManager keyManager) {
|
||||||
|
return new SslContextBuilder(true).keyManager(keyManager);
|
||||||
|
}
|
||||||
|
|
||||||
private final boolean forServer;
|
private final boolean forServer;
|
||||||
private SslProvider provider;
|
private SslProvider provider;
|
||||||
private Provider sslContextProvider;
|
private Provider sslContextProvider;
|
||||||
@ -259,6 +270,19 @@ public final class SslContextBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A single trusted manager for verifying the remote endpoint's certificate.
|
||||||
|
* This is helpful when custom implementation of {@link TrustManager} is needed.
|
||||||
|
* Internally, a simple wrapper of {@link TrustManagerFactory} that only produces this
|
||||||
|
* specified {@link TrustManager} will be created, thus all the requirements specified in
|
||||||
|
* {@link #trustManager(TrustManagerFactory trustManagerFactory)} also apply here.
|
||||||
|
*/
|
||||||
|
public SslContextBuilder trustManager(TrustManager trustManager) {
|
||||||
|
this.trustManagerFactory = new TrustManagerFactoryWrapper(trustManager);
|
||||||
|
trustCertCollection = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifying certificate for this host. {@code keyCertChainFile} and {@code keyFile} may
|
* Identifying certificate for this host. {@code keyCertChainFile} and {@code keyFile} may
|
||||||
* be {@code null} for client contexts, which disables mutual authentication.
|
* be {@code null} for client contexts, which disables mutual authentication.
|
||||||
@ -423,6 +447,28 @@ public final class SslContextBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A single key manager managing the identity information of this host.
|
||||||
|
* This is helpful when custom implementation of {@link KeyManager} is needed.
|
||||||
|
* Internally, a wrapper of {@link KeyManagerFactory} that only produces this specified
|
||||||
|
* {@link KeyManager} will be created, thus all the requirements specified in
|
||||||
|
* {@link #keyManager(KeyManagerFactory keyManagerFactory)} also apply here.
|
||||||
|
*/
|
||||||
|
public SslContextBuilder keyManager(KeyManager keyManager) {
|
||||||
|
if (forServer) {
|
||||||
|
checkNotNull(keyManager, "keyManager required for servers");
|
||||||
|
}
|
||||||
|
if (keyManager != null) {
|
||||||
|
this.keyManagerFactory = new KeyManagerFactoryWrapper(keyManager);
|
||||||
|
} else {
|
||||||
|
this.keyManagerFactory = null;
|
||||||
|
}
|
||||||
|
keyCertChain = null;
|
||||||
|
key = null;
|
||||||
|
keyPassword = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The cipher suites to enable, in the order of preference. {@code null} to use default
|
* The cipher suites to enable, in the order of preference. {@code null} to use default
|
||||||
* cipher suites.
|
* cipher suites.
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.netty.handler.ssl;
|
||||||
|
|
||||||
|
import io.netty.handler.ssl.util.SimpleTrustManagerFactory;
|
||||||
|
import io.netty.util.internal.ObjectUtil;
|
||||||
|
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import javax.net.ssl.ManagerFactoryParameters;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
|
||||||
|
final class TrustManagerFactoryWrapper extends SimpleTrustManagerFactory {
|
||||||
|
private final TrustManager tm;
|
||||||
|
|
||||||
|
TrustManagerFactoryWrapper(TrustManager tm) {
|
||||||
|
this.tm = ObjectUtil.checkNotNull(tm, "tm");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void engineInit(KeyStore keyStore) throws Exception { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void engineInit(ManagerFactoryParameters managerFactoryParameters)
|
||||||
|
throws Exception { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TrustManager[] engineGetTrustManagers() {
|
||||||
|
return new TrustManager[] {tm};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.netty.handler.ssl.util;
|
||||||
|
|
||||||
|
import io.netty.util.concurrent.FastThreadLocal;
|
||||||
|
import io.netty.util.internal.ObjectUtil;
|
||||||
|
import io.netty.util.internal.PlatformDependent;
|
||||||
|
import io.netty.util.internal.StringUtil;
|
||||||
|
import io.netty.util.internal.SuppressJava6Requirement;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.security.KeyStoreException;
|
||||||
|
import java.security.Provider;
|
||||||
|
import javax.net.ssl.ManagerFactoryParameters;
|
||||||
|
import javax.net.ssl.KeyManager;
|
||||||
|
import javax.net.ssl.KeyManagerFactory;
|
||||||
|
import javax.net.ssl.KeyManagerFactorySpi;
|
||||||
|
import javax.net.ssl.X509ExtendedKeyManager;
|
||||||
|
import javax.net.ssl.X509KeyManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps to implement a custom {@link KeyManagerFactory}.
|
||||||
|
*/
|
||||||
|
public abstract class SimpleKeyManagerFactory extends KeyManagerFactory {
|
||||||
|
|
||||||
|
private static final Provider PROVIDER = new Provider("", 0.0, "") {
|
||||||
|
private static final long serialVersionUID = -2680540247105807895L;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SimpleKeyManagerFactorySpi} must have a reference to {@link SimpleKeyManagerFactory}
|
||||||
|
* to delegate its callbacks back to {@link SimpleKeyManagerFactory}. However, it is impossible to do so,
|
||||||
|
* because {@link KeyManagerFactory} requires {@link KeyManagerFactorySpi} at construction time and
|
||||||
|
* does not provide a way to access it later.
|
||||||
|
*
|
||||||
|
* To work around this issue, we use an ugly hack which uses a {@link FastThreadLocal }.
|
||||||
|
*/
|
||||||
|
private static final FastThreadLocal<SimpleKeyManagerFactorySpi> CURRENT_SPI =
|
||||||
|
new FastThreadLocal<SimpleKeyManagerFactorySpi>() {
|
||||||
|
@Override
|
||||||
|
protected SimpleKeyManagerFactorySpi initialValue() {
|
||||||
|
return new SimpleKeyManagerFactorySpi();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*/
|
||||||
|
protected SimpleKeyManagerFactory() {
|
||||||
|
this(StringUtil.EMPTY_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param name the name of this {@link KeyManagerFactory}
|
||||||
|
*/
|
||||||
|
protected SimpleKeyManagerFactory(String name) {
|
||||||
|
super(CURRENT_SPI.get(), PROVIDER, ObjectUtil.checkNotNull(name, "name"));
|
||||||
|
CURRENT_SPI.get().init(this);
|
||||||
|
CURRENT_SPI.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes this factory with a source of certificate authorities and related key material.
|
||||||
|
*
|
||||||
|
* @see KeyManagerFactorySpi#engineInit(KeyStore, char[])
|
||||||
|
*/
|
||||||
|
protected abstract void engineInit(KeyStore keyStore, char[] var2) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes this factory with a source of provider-specific key material.
|
||||||
|
*
|
||||||
|
* @see KeyManagerFactorySpi#engineInit(ManagerFactoryParameters)
|
||||||
|
*/
|
||||||
|
protected abstract void engineInit(ManagerFactoryParameters managerFactoryParameters) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns one key manager for each type of key material.
|
||||||
|
*
|
||||||
|
* @see KeyManagerFactorySpi#engineGetKeyManagers()
|
||||||
|
*/
|
||||||
|
protected abstract KeyManager[] engineGetKeyManagers();
|
||||||
|
|
||||||
|
private static final class SimpleKeyManagerFactorySpi extends KeyManagerFactorySpi {
|
||||||
|
|
||||||
|
private SimpleKeyManagerFactory parent;
|
||||||
|
private volatile KeyManager[] keyManagers;
|
||||||
|
|
||||||
|
void init(SimpleKeyManagerFactory parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void engineInit(KeyStore keyStore, char[] pwd) throws KeyStoreException {
|
||||||
|
try {
|
||||||
|
parent.engineInit(keyStore, pwd);
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new KeyStoreException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void engineInit(
|
||||||
|
ManagerFactoryParameters managerFactoryParameters) throws InvalidAlgorithmParameterException {
|
||||||
|
try {
|
||||||
|
parent.engineInit(managerFactoryParameters);
|
||||||
|
} catch (InvalidAlgorithmParameterException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InvalidAlgorithmParameterException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected KeyManager[] engineGetKeyManagers() {
|
||||||
|
KeyManager[] keyManagers = this.keyManagers;
|
||||||
|
if (keyManagers == null) {
|
||||||
|
keyManagers = parent.engineGetKeyManagers();
|
||||||
|
if (PlatformDependent.javaVersion() >= 7) {
|
||||||
|
wrapIfNeeded(keyManagers);
|
||||||
|
}
|
||||||
|
this.keyManagers = keyManagers;
|
||||||
|
}
|
||||||
|
return keyManagers.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressJava6Requirement(reason = "Usage guarded by java version check")
|
||||||
|
private static void wrapIfNeeded(KeyManager[] keyManagers) {
|
||||||
|
for (int i = 0; i < keyManagers.length; i++) {
|
||||||
|
final KeyManager tm = keyManagers[i];
|
||||||
|
if (tm instanceof X509KeyManager && !(tm instanceof X509ExtendedKeyManager)) {
|
||||||
|
keyManagers[i] = new X509KeyManagerWrapper((X509KeyManager) tm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.netty.handler.ssl.util;
|
||||||
|
|
||||||
|
import static io.netty.util.internal.ObjectUtil.checkNotNull;
|
||||||
|
|
||||||
|
import io.netty.util.internal.SuppressJava6Requirement;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.security.Principal;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import javax.net.ssl.SSLEngine;
|
||||||
|
import javax.net.ssl.X509ExtendedKeyManager;
|
||||||
|
import javax.net.ssl.X509KeyManager;
|
||||||
|
|
||||||
|
@SuppressJava6Requirement(reason = "Usage guarded by java version check")
|
||||||
|
final class X509KeyManagerWrapper extends X509ExtendedKeyManager {
|
||||||
|
|
||||||
|
private final X509KeyManager delegate;
|
||||||
|
|
||||||
|
X509KeyManagerWrapper(X509KeyManager delegate) {
|
||||||
|
this.delegate = checkNotNull(delegate, "delegate");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getClientAliases(String var1, Principal[] var2) {
|
||||||
|
return delegate.getClientAliases(var1, var2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String chooseClientAlias(String[] var1, Principal[] var2, Socket var3) {
|
||||||
|
return delegate.chooseClientAlias(var1, var2, var3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getServerAliases(String var1, Principal[] var2) {
|
||||||
|
return delegate.getServerAliases(var1, var2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String chooseServerAlias(String var1, Principal[] var2, Socket var3) {
|
||||||
|
return delegate.chooseServerAlias(var1, var2, var3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public X509Certificate[] getCertificateChain(String var1) {
|
||||||
|
return delegate.getCertificateChain(var1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PrivateKey getPrivateKey(String var1) {
|
||||||
|
return delegate.getPrivateKey(var1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine) {
|
||||||
|
return delegate.chooseClientAlias(keyType, issuers, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
|
||||||
|
return delegate.chooseServerAlias(keyType, issuers, null);
|
||||||
|
}
|
||||||
|
}
|
@ -21,9 +21,18 @@ import io.netty.util.CharsetUtil;
|
|||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.net.ssl.KeyManager;
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
import javax.net.ssl.X509ExtendedKeyManager;
|
||||||
|
import javax.net.ssl.X509ExtendedTrustManager;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.security.Principal;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
@ -85,6 +94,17 @@ public class SslContextBuilderTest {
|
|||||||
testServerContext(SslProvider.OPENSSL);
|
testServerContext(SslProvider.OPENSSL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContextFromManagersJdk() throws Exception {
|
||||||
|
testContextFromManagers(SslProvider.JDK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContextFromManagersOpenssl() throws Exception {
|
||||||
|
Assume.assumeTrue(OpenSsl.isAvailable());
|
||||||
|
testContextFromManagers(SslProvider.OPENSSL);
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = SSLException.class)
|
@Test(expected = SSLException.class)
|
||||||
public void testUnsupportedPrivateKeyFailsFastForServer() throws Exception {
|
public void testUnsupportedPrivateKeyFailsFastForServer() throws Exception {
|
||||||
Assume.assumeTrue(OpenSsl.isBoringSSL());
|
Assume.assumeTrue(OpenSsl.isBoringSSL());
|
||||||
@ -233,4 +253,104 @@ public class SslContextBuilderTest {
|
|||||||
engine.closeInbound();
|
engine.closeInbound();
|
||||||
engine.closeOutbound();
|
engine.closeOutbound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void testContextFromManagers(SslProvider provider) throws Exception {
|
||||||
|
final SelfSignedCertificate cert = new SelfSignedCertificate();
|
||||||
|
KeyManager customKeyManager = new X509ExtendedKeyManager() {
|
||||||
|
@Override
|
||||||
|
public String[] getClientAliases(String s,
|
||||||
|
Principal[] principals) {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String chooseClientAlias(String[] strings,
|
||||||
|
Principal[] principals,
|
||||||
|
Socket socket) {
|
||||||
|
return "cert_sent_to_server";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getServerAliases(String s,
|
||||||
|
Principal[] principals) {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String chooseServerAlias(String s,
|
||||||
|
Principal[] principals,
|
||||||
|
Socket socket) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public X509Certificate[] getCertificateChain(String s) {
|
||||||
|
X509Certificate[] certificates = new X509Certificate[1];
|
||||||
|
certificates[0] = cert.cert();
|
||||||
|
return new X509Certificate[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PrivateKey getPrivateKey(String s) {
|
||||||
|
return cert.key();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
TrustManager customTrustManager = new X509ExtendedTrustManager() {
|
||||||
|
@Override
|
||||||
|
public void checkClientTrusted(
|
||||||
|
X509Certificate[] x509Certificates, String s,
|
||||||
|
Socket socket) throws CertificateException { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkServerTrusted(
|
||||||
|
X509Certificate[] x509Certificates, String s,
|
||||||
|
Socket socket) throws CertificateException { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkClientTrusted(
|
||||||
|
X509Certificate[] x509Certificates, String s,
|
||||||
|
SSLEngine sslEngine) throws CertificateException { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkServerTrusted(
|
||||||
|
X509Certificate[] x509Certificates, String s,
|
||||||
|
SSLEngine sslEngine) throws CertificateException { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkClientTrusted(
|
||||||
|
X509Certificate[] x509Certificates, String s)
|
||||||
|
throws CertificateException { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkServerTrusted(
|
||||||
|
X509Certificate[] x509Certificates, String s)
|
||||||
|
throws CertificateException { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return new X509Certificate[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
SslContextBuilder client_builder = SslContextBuilder.forClient()
|
||||||
|
.sslProvider(provider)
|
||||||
|
.keyManager(customKeyManager)
|
||||||
|
.trustManager(customTrustManager)
|
||||||
|
.clientAuth(ClientAuth.OPTIONAL);
|
||||||
|
SslContext client_context = client_builder.build();
|
||||||
|
SSLEngine client_engine = client_context.newEngine(UnpooledByteBufAllocator.DEFAULT);
|
||||||
|
assertFalse(client_engine.getWantClientAuth());
|
||||||
|
assertFalse(client_engine.getNeedClientAuth());
|
||||||
|
client_engine.closeInbound();
|
||||||
|
client_engine.closeOutbound();
|
||||||
|
SslContextBuilder server_builder = SslContextBuilder.forServer(customKeyManager)
|
||||||
|
.sslProvider(provider)
|
||||||
|
.trustManager(customTrustManager)
|
||||||
|
.clientAuth(ClientAuth.REQUIRE);
|
||||||
|
SslContext server_context = server_builder.build();
|
||||||
|
SSLEngine server_engine = server_context.newEngine(UnpooledByteBufAllocator.DEFAULT);
|
||||||
|
assertFalse(server_engine.getWantClientAuth());
|
||||||
|
assertTrue(server_engine.getNeedClientAuth());
|
||||||
|
server_engine.closeInbound();
|
||||||
|
server_engine.closeOutbound();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user