Allow to create a JdkSslContext from an existing JDK SSLContext. Related to [#5095] and [#4929]

Motivation:

Sometimes a user only has access to a preconfigured SSLContext but still would like to use our ssl sub-system. For this situations it would be very useful if the user could create a JdkSslContext instance from an existing SSLContext.

Modifications:

- Create new public constructors in JdkSslContext which allow to wrap an existing SSLContext and make the class non-abstract
- Mark JdkSslServerContext and JdkSslClientContext as deprecated as the user should not directly use these.

Result:

It's now possible to create an JdkSslContext from an existing SSLContext.
This commit is contained in:
Norman Maurer 2016-04-07 17:44:45 +02:00
parent 8617df7f2d
commit bfdfb50df6
4 changed files with 84 additions and 56 deletions

View File

@ -29,11 +29,13 @@ import java.security.cert.X509Certificate;
/**
* A client-side {@link SslContext} which uses JDK's SSL/TLS implementation.
*
* @deprecated Use {@link SslContextBuilder} to create {@link JdkSslContext} instances and only
* use {@link JdkSslContext} in your code.
*/
@Deprecated
public final class JdkSslClientContext extends JdkSslContext {
private final SSLContext ctx;
/**
* Creates a new instance.
*
@ -245,26 +247,20 @@ public final class JdkSslClientContext extends JdkSslContext {
File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
long sessionCacheSize, long sessionTimeout) throws SSLException {
super(ciphers, cipherFilter, apn, ClientAuth.NONE);
try {
ctx = newSSLContext(toX509Certificates(trustCertCollectionFile), trustManagerFactory,
toX509Certificates(keyCertChainFile), toPrivateKey(keyFile, keyPassword),
keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout);
} catch (Exception e) {
if (e instanceof SSLException) {
throw (SSLException) e;
}
throw new SSLException("failed to initialize the client-side SSL context", e);
}
super(newSSLContext(toX509CertificatesInternal(
trustCertCollectionFile), trustManagerFactory,
toX509CertificatesInternal(keyCertChainFile), toPrivateKeyInternal(keyFile, keyPassword),
keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout), true,
ciphers, cipherFilter, apn, ClientAuth.NONE);
}
JdkSslClientContext(X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword,
KeyManagerFactory keyManagerFactory, Iterable<String> ciphers, CipherSuiteFilter cipherFilter,
ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout) throws SSLException {
super(ciphers, cipherFilter, toNegotiator(apn, false), ClientAuth.NONE);
ctx = newSSLContext(trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword,
keyManagerFactory, sessionCacheSize, sessionTimeout);
super(newSSLContext(trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword,
keyManagerFactory, sessionCacheSize, sessionTimeout), true,
ciphers, cipherFilter, toNegotiator(apn, false), ClientAuth.NONE);
}
private static SSLContext newSSLContext(X509Certificate[] trustCertCollection,
@ -298,14 +294,4 @@ public final class JdkSslClientContext extends JdkSslContext {
throw new SSLException("failed to initialize the client-side SSL context", e);
}
}
@Override
public boolean isClient() {
return true;
}
@Override
public SSLContext context() {
return ctx;
}
}

View File

@ -51,7 +51,7 @@ import static io.netty.util.internal.ObjectUtil.*;
/**
* An {@link SslContext} which uses JDK's SSL/TLS implementation.
*/
public abstract class JdkSslContext extends SslContext {
public class JdkSslContext extends SslContext {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(JdkSslContext.class);
@ -140,20 +140,60 @@ public abstract class JdkSslContext extends SslContext {
private final List<String> unmodifiableCipherSuites;
private final JdkApplicationProtocolNegotiator apn;
private final ClientAuth clientAuth;
private final SSLContext sslContext;
private final boolean isClient;
JdkSslContext(Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
ClientAuth clientAuth) {
/**
* Creates a new {@link JdkSslContext} from a pre-configured {@link SSLContext}.
*
* @param sslContext the {@link SSLContext} to use.
* @param isClient {@code true} if this context should create {@link SSLEngine}s for client-side usage.
* @param clientAuth the {@link ClientAuth} to use. This will only be used when {@param isClient} is {@code false}.
*/
public JdkSslContext(SSLContext sslContext, boolean isClient,
ClientAuth clientAuth) {
this(sslContext, isClient, null, IdentityCipherSuiteFilter.INSTANCE,
JdkDefaultApplicationProtocolNegotiator.INSTANCE, clientAuth);
}
/**
* Creates a new {@link JdkSslContext} from a pre-configured {@link SSLContext}.
*
* @param sslContext the {@link SSLContext} to use.
* @param isClient {@code true} if this context should create {@link SSLEngine}s for client-side usage.
* @param ciphers the ciphers to use or {@code null} if the standart should be used.
* @param cipherFilter the filter to use.
* @param apn the {@link ApplicationProtocolConfig} to use.
* @param clientAuth the {@link ClientAuth} to use. This will only be used when {@param isClient} is {@code false}.
*/
public JdkSslContext(SSLContext sslContext, boolean isClient, Iterable<String> ciphers,
CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
ClientAuth clientAuth) {
this(sslContext, isClient, ciphers, cipherFilter, toNegotiator(apn, !isClient), clientAuth);
}
JdkSslContext(SSLContext sslContext, boolean isClient, Iterable<String> ciphers, CipherSuiteFilter cipherFilter,
JdkApplicationProtocolNegotiator apn, ClientAuth clientAuth) {
this.apn = checkNotNull(apn, "apn");
this.clientAuth = checkNotNull(clientAuth, "clientAuth");
cipherSuites = checkNotNull(cipherFilter, "cipherFilter").filterCipherSuites(
ciphers, DEFAULT_CIPHERS, SUPPORTED_CIPHERS);
unmodifiableCipherSuites = Collections.unmodifiableList(Arrays.asList(cipherSuites));
this.sslContext = checkNotNull(sslContext, "sslContext");
this.isClient = isClient;
}
/**
* Returns the JDK {@link SSLContext} object held by this context.
*/
public abstract SSLContext context();
public final SSLContext context() {
return sslContext;
}
@Override
public final boolean isClient() {
return isClient;
}
/**
* Returns the JDK {@link SSLSessionContext} object held by this context.
@ -210,7 +250,7 @@ public abstract class JdkSslContext extends SslContext {
}
@Override
public JdkApplicationProtocolNegotiator applicationProtocolNegotiator() {
public final JdkApplicationProtocolNegotiator applicationProtocolNegotiator() {
return apn;
}

View File

@ -30,11 +30,13 @@ import java.security.cert.X509Certificate;
/**
* A server-side {@link SslContext} which uses JDK's SSL/TLS implementation.
*
* @deprecated Use {@link SslContextBuilder} to create {@link JdkSslContext} instances and only
* use {@link JdkSslContext} in your code.
*/
@Deprecated
public final class JdkSslServerContext extends JdkSslContext {
private final SSLContext ctx;
/**
* Creates a new instance.
*
@ -210,17 +212,10 @@ public final class JdkSslServerContext extends JdkSslContext {
File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
long sessionCacheSize, long sessionTimeout) throws SSLException {
super(ciphers, cipherFilter, apn, ClientAuth.NONE);
try {
ctx = newSSLContext(toX509Certificates(trustCertCollectionFile), trustManagerFactory,
toX509Certificates(keyCertChainFile), toPrivateKey(keyFile, keyPassword),
keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout);
} catch (Exception e) {
if (e instanceof SSLException) {
throw (SSLException) e;
}
throw new SSLException("failed to initialize the server-side SSL context", e);
}
super(newSSLContext(toX509CertificatesInternal(trustCertCollectionFile), trustManagerFactory,
toX509CertificatesInternal(keyCertChainFile), toPrivateKeyInternal(keyFile, keyPassword),
keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout), false,
ciphers, cipherFilter, apn, ClientAuth.NONE);
}
JdkSslServerContext(X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
@ -228,9 +223,9 @@ public final class JdkSslServerContext extends JdkSslContext {
KeyManagerFactory keyManagerFactory, Iterable<String> ciphers, CipherSuiteFilter cipherFilter,
ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout,
ClientAuth clientAuth) throws SSLException {
super(ciphers, cipherFilter, toNegotiator(apn, true), clientAuth);
ctx = newSSLContext(trustCertCollection, trustManagerFactory, keyCertChain, key,
keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout);
super(newSSLContext(trustCertCollection, trustManagerFactory, keyCertChain, key,
keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout), false,
ciphers, cipherFilter, toNegotiator(apn, true), clientAuth);
}
private static SSLContext newSSLContext(X509Certificate[] trustCertCollection,
@ -272,13 +267,4 @@ public final class JdkSslServerContext extends JdkSslContext {
}
}
@Override
public boolean isClient() {
return false;
}
@Override
public SSLContext context() {
return ctx;
}
}

View File

@ -1015,4 +1015,20 @@ public abstract class SslContext {
return trustManagerFactory;
}
static PrivateKey toPrivateKeyInternal(File keyFile, String keyPassword) throws SSLException {
try {
return toPrivateKey(keyFile, keyPassword);
} catch (Exception e) {
throw new SSLException(e);
}
}
static X509Certificate[] toX509CertificatesInternal(File file) throws SSLException {
try {
return toX509Certificates(file);
} catch (CertificateException e) {
throw new SSLException(e);
}
}
}