Allow to specify KeyStore type in SslContext (#9003)
Motivation: As brought up in https://github.com/netty/netty/issues/8998, JKS can be substantially faster than pkcs12, JDK's new default. Without an option to set the KeyStore type you must change the configuration of the entire JVM which is impractical. Modification: - Allow to specify KeyStore type - Add test case Result: Fixes https://github.com/netty/netty/issues/8998.
This commit is contained in:
parent
df20a125aa
commit
5a27f2f78b
@ -54,7 +54,7 @@ import io.netty.util.CharsetUtil;
|
||||
|
||||
/**
|
||||
* ATTENTION: This is an incomplete example! In order to provide a fully functional
|
||||
* end-to-end example we'd need a X.509 certificate and the matching PrivateKey.
|
||||
* end-to-end example we'd need an X.509 certificate and the matching PrivateKey.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class OcspServerExample {
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package io.netty.handler.ssl;
|
||||
|
||||
import java.security.KeyStore;
|
||||
import java.security.Provider;
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
@ -169,12 +170,12 @@ public final class JdkSslClientContext extends JdkSslContext {
|
||||
}
|
||||
|
||||
JdkSslClientContext(Provider provider,
|
||||
File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
|
||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||
File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
|
||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||
super(newSSLContext(provider, toX509CertificatesInternal(trustCertCollectionFile),
|
||||
trustManagerFactory, null, null,
|
||||
null, null, sessionCacheSize, sessionTimeout), true,
|
||||
null, null, sessionCacheSize, sessionTimeout, KeyStore.getDefaultType()), true,
|
||||
ciphers, cipherFilter, apn, ClientAuth.NONE, null, false);
|
||||
}
|
||||
|
||||
@ -257,7 +258,7 @@ public final class JdkSslClientContext extends JdkSslContext {
|
||||
super(newSSLContext(null, toX509CertificatesInternal(
|
||||
trustCertCollectionFile), trustManagerFactory,
|
||||
toX509CertificatesInternal(keyCertChainFile), toPrivateKeyInternal(keyFile, keyPassword),
|
||||
keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout), true,
|
||||
keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout, KeyStore.getDefaultType()), true,
|
||||
ciphers, cipherFilter, apn, ClientAuth.NONE, null, false);
|
||||
}
|
||||
|
||||
@ -265,10 +266,12 @@ public final class JdkSslClientContext extends JdkSslContext {
|
||||
X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
|
||||
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword,
|
||||
KeyManagerFactory keyManagerFactory, Iterable<String> ciphers, CipherSuiteFilter cipherFilter,
|
||||
ApplicationProtocolConfig apn, String[] protocols, long sessionCacheSize, long sessionTimeout)
|
||||
ApplicationProtocolConfig apn, String[] protocols, long sessionCacheSize, long sessionTimeout,
|
||||
String keyStoreType)
|
||||
throws SSLException {
|
||||
super(newSSLContext(sslContextProvider, trustCertCollection, trustManagerFactory,
|
||||
keyCertChain, key, keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout),
|
||||
keyCertChain, key, keyPassword, keyManagerFactory, sessionCacheSize,
|
||||
sessionTimeout, keyStoreType),
|
||||
true, ciphers, cipherFilter, toNegotiator(apn, false), ClientAuth.NONE, protocols, false);
|
||||
}
|
||||
|
||||
@ -276,13 +279,14 @@ public final class JdkSslClientContext extends JdkSslContext {
|
||||
X509Certificate[] trustCertCollection,
|
||||
TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain,
|
||||
PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||
long sessionCacheSize, long sessionTimeout,
|
||||
String keyStore) throws SSLException {
|
||||
try {
|
||||
if (trustCertCollection != null) {
|
||||
trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory);
|
||||
trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory, keyStore);
|
||||
}
|
||||
if (keyCertChain != null) {
|
||||
keyManagerFactory = buildKeyManagerFactory(keyCertChain, key, keyPassword, keyManagerFactory);
|
||||
keyManagerFactory = buildKeyManagerFactory(keyCertChain, key, keyPassword, keyManagerFactory, null);
|
||||
}
|
||||
SSLContext ctx = sslContextProvider == null ? SSLContext.getInstance(PROTOCOL)
|
||||
: SSLContext.getInstance(PROTOCOL, sslContextProvider);
|
||||
|
@ -25,6 +25,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.KeyException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
@ -435,7 +436,29 @@ public class JdkSslContext extends SslContext {
|
||||
|
||||
/**
|
||||
* Build a {@link KeyManagerFactory} based upon a key file, key file password, and a certificate chain.
|
||||
* @param certChainFile a X.509 certificate chain file in PEM format
|
||||
* @param certChainFile an X.509 certificate chain file in PEM format
|
||||
* @param keyFile a PKCS#8 private key file in PEM format
|
||||
* @param keyPassword the password of the {@code keyFile}.
|
||||
* {@code null} if it's not password-protected.
|
||||
* @param kmf The existing {@link KeyManagerFactory} that will be used if not {@code null}
|
||||
* @param keyStore the {@link KeyStore} that should be used in the {@link KeyManagerFactory}
|
||||
* @return A {@link KeyManagerFactory} based upon a key file, key file password, and a certificate chain.
|
||||
*/
|
||||
static KeyManagerFactory buildKeyManagerFactory(File certChainFile, File keyFile, String keyPassword,
|
||||
KeyManagerFactory kmf, String keyStore)
|
||||
throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException,
|
||||
NoSuchPaddingException, InvalidKeySpecException, InvalidAlgorithmParameterException,
|
||||
CertificateException, KeyException, IOException {
|
||||
String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm");
|
||||
if (algorithm == null) {
|
||||
algorithm = "SunX509";
|
||||
}
|
||||
return buildKeyManagerFactory(certChainFile, algorithm, keyFile, keyPassword, kmf, keyStore);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link KeyManagerFactory} based upon a key file, key file password, and a certificate chain.
|
||||
* @param certChainFile an X.509 certificate chain file in PEM format
|
||||
* @param keyFile a PKCS#8 private key file in PEM format
|
||||
* @param keyPassword the password of the {@code keyFile}.
|
||||
* {@code null} if it's not password-protected.
|
||||
@ -445,23 +468,43 @@ public class JdkSslContext extends SslContext {
|
||||
*/
|
||||
@Deprecated
|
||||
protected static KeyManagerFactory buildKeyManagerFactory(File certChainFile, File keyFile, String keyPassword,
|
||||
KeyManagerFactory kmf)
|
||||
throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException,
|
||||
NoSuchPaddingException, InvalidKeySpecException, InvalidAlgorithmParameterException,
|
||||
CertificateException, KeyException, IOException {
|
||||
String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm");
|
||||
if (algorithm == null) {
|
||||
algorithm = "SunX509";
|
||||
}
|
||||
return buildKeyManagerFactory(certChainFile, algorithm, keyFile, keyPassword, kmf);
|
||||
KeyManagerFactory kmf)
|
||||
throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException,
|
||||
NoSuchPaddingException, InvalidKeySpecException, InvalidAlgorithmParameterException,
|
||||
CertificateException, KeyException, IOException {
|
||||
return buildKeyManagerFactory(certChainFile, keyFile, keyPassword, kmf, KeyStore.getDefaultType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link KeyManagerFactory} based upon a key algorithm, key file, key file password,
|
||||
* and a certificate chain.
|
||||
* @param certChainFile a X.509 certificate chain file in PEM format
|
||||
* @param certChainFile an X.509 certificate chain file in PEM format
|
||||
* @param keyAlgorithm the standard name of the requested algorithm. See the Java Secure Socket Extension
|
||||
* Reference Guide for information about standard algorithm names.
|
||||
* Reference Guide for information about standard algorithm names.
|
||||
* @param keyFile a PKCS#8 private key file in PEM format
|
||||
* @param keyPassword the password of the {@code keyFile}.
|
||||
* {@code null} if it's not password-protected.
|
||||
* @param kmf The existing {@link KeyManagerFactory} that will be used if not {@code null}
|
||||
* @param keyStore the {@link KeyStore} that should be used in the {@link KeyManagerFactory}
|
||||
* @return A {@link KeyManagerFactory} based upon a key algorithm, key file, key file password,
|
||||
* and a certificate chain.
|
||||
*/
|
||||
static KeyManagerFactory buildKeyManagerFactory(File certChainFile,
|
||||
String keyAlgorithm, File keyFile, String keyPassword, KeyManagerFactory kmf,
|
||||
String keyStore)
|
||||
throws KeyStoreException, NoSuchAlgorithmException, NoSuchPaddingException,
|
||||
InvalidKeySpecException, InvalidAlgorithmParameterException, IOException,
|
||||
CertificateException, KeyException, UnrecoverableKeyException {
|
||||
return buildKeyManagerFactory(toX509Certificates(certChainFile), keyAlgorithm,
|
||||
toPrivateKey(keyFile, keyPassword), keyPassword, kmf, keyStore);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link KeyManagerFactory} based upon a key algorithm, key file, key file password,
|
||||
* and a certificate chain.
|
||||
* @param certChainFile an buildKeyManagerFactory X.509 certificate chain file in PEM format
|
||||
* @param keyAlgorithm the standard name of the requested algorithm. See the Java Secure Socket Extension
|
||||
* Reference Guide for information about standard algorithm names.
|
||||
* @param keyFile a PKCS#8 private key file in PEM format
|
||||
* @param keyPassword the password of the {@code keyFile}.
|
||||
* {@code null} if it's not password-protected.
|
||||
@ -472,11 +515,12 @@ public class JdkSslContext extends SslContext {
|
||||
*/
|
||||
@Deprecated
|
||||
protected static KeyManagerFactory buildKeyManagerFactory(File certChainFile,
|
||||
String keyAlgorithm, File keyFile, String keyPassword, KeyManagerFactory kmf)
|
||||
throws KeyStoreException, NoSuchAlgorithmException, NoSuchPaddingException,
|
||||
InvalidKeySpecException, InvalidAlgorithmParameterException, IOException,
|
||||
CertificateException, KeyException, UnrecoverableKeyException {
|
||||
String keyAlgorithm, File keyFile,
|
||||
String keyPassword, KeyManagerFactory kmf)
|
||||
throws KeyStoreException, NoSuchAlgorithmException, NoSuchPaddingException,
|
||||
InvalidKeySpecException, InvalidAlgorithmParameterException, IOException,
|
||||
CertificateException, KeyException, UnrecoverableKeyException {
|
||||
return buildKeyManagerFactory(toX509Certificates(certChainFile), keyAlgorithm,
|
||||
toPrivateKey(keyFile, keyPassword), keyPassword, kmf);
|
||||
toPrivateKey(keyFile, keyPassword), keyPassword, kmf, KeyStore.getDefaultType());
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package io.netty.handler.ssl;
|
||||
|
||||
import java.security.KeyStore;
|
||||
import java.security.Provider;
|
||||
import javax.net.ssl.KeyManager;
|
||||
|
||||
@ -47,7 +48,8 @@ public final class JdkSslServerContext extends JdkSslContext {
|
||||
*/
|
||||
@Deprecated
|
||||
public JdkSslServerContext(File certChainFile, File keyFile) throws SSLException {
|
||||
this(certChainFile, keyFile, null);
|
||||
this(null, certChainFile, keyFile, null, null, IdentityCipherSuiteFilter.INSTANCE,
|
||||
JdkDefaultApplicationProtocolNegotiator.INSTANCE, 0, 0, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,8 +89,9 @@ public final class JdkSslServerContext extends JdkSslContext {
|
||||
File certChainFile, File keyFile, String keyPassword,
|
||||
Iterable<String> ciphers, Iterable<String> nextProtocols,
|
||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||
this(certChainFile, keyFile, keyPassword, ciphers, IdentityCipherSuiteFilter.INSTANCE,
|
||||
toNegotiator(toApplicationProtocolConfig(nextProtocols), true), sessionCacheSize, sessionTimeout);
|
||||
this(null, certChainFile, keyFile, keyPassword, ciphers, IdentityCipherSuiteFilter.INSTANCE,
|
||||
toNegotiator(toApplicationProtocolConfig(nextProtocols), true), sessionCacheSize,
|
||||
sessionTimeout, KeyStore.getDefaultType());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,8 +116,8 @@ public final class JdkSslServerContext extends JdkSslContext {
|
||||
File certChainFile, File keyFile, String keyPassword,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
|
||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||
this(certChainFile, keyFile, keyPassword, ciphers, cipherFilter,
|
||||
toNegotiator(apn, true), sessionCacheSize, sessionTimeout);
|
||||
this(null, certChainFile, keyFile, keyPassword, ciphers, cipherFilter,
|
||||
toNegotiator(apn, true), sessionCacheSize, sessionTimeout, KeyStore.getDefaultType());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,17 +142,18 @@ public final class JdkSslServerContext extends JdkSslContext {
|
||||
File certChainFile, File keyFile, String keyPassword,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
|
||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||
this(null, certChainFile, keyFile, keyPassword, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
|
||||
this(null, certChainFile, keyFile, keyPassword, ciphers, cipherFilter, apn,
|
||||
sessionCacheSize, sessionTimeout, KeyStore.getDefaultType());
|
||||
}
|
||||
|
||||
JdkSslServerContext(Provider provider,
|
||||
File certChainFile, File keyFile, String keyPassword,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
|
||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||
File certChainFile, File keyFile, String keyPassword,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
|
||||
long sessionCacheSize, long sessionTimeout, String keyStore) throws SSLException {
|
||||
super(newSSLContext(provider, null, null,
|
||||
toX509CertificatesInternal(certChainFile), toPrivateKeyInternal(keyFile, keyPassword),
|
||||
keyPassword, null, sessionCacheSize, sessionTimeout), false,
|
||||
ciphers, cipherFilter, apn, ClientAuth.NONE, null, false);
|
||||
toX509CertificatesInternal(certChainFile), toPrivateKeyInternal(keyFile, keyPassword),
|
||||
keyPassword, null, sessionCacheSize, sessionTimeout, keyStore), false,
|
||||
ciphers, cipherFilter, apn, ClientAuth.NONE, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -182,11 +186,14 @@ public final class JdkSslServerContext extends JdkSslContext {
|
||||
*/
|
||||
@Deprecated
|
||||
public JdkSslServerContext(File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
|
||||
File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
|
||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||
this(trustCertCollectionFile, trustManagerFactory, keyCertChainFile, keyFile, keyPassword, keyManagerFactory,
|
||||
ciphers, cipherFilter, toNegotiator(apn, true), sessionCacheSize, sessionTimeout);
|
||||
File keyCertChainFile, File keyFile, String keyPassword,
|
||||
KeyManagerFactory keyManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
|
||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||
super(newSSLContext(null, toX509CertificatesInternal(trustCertCollectionFile), trustManagerFactory,
|
||||
toX509CertificatesInternal(keyCertChainFile), toPrivateKeyInternal(keyFile, keyPassword),
|
||||
keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout, null), false,
|
||||
ciphers, cipherFilter, apn, ClientAuth.NONE, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -214,17 +221,19 @@ public final class JdkSslServerContext extends JdkSslContext {
|
||||
* @param sessionCacheSize the size of the cache used for storing SSL session objects.
|
||||
* {@code 0} to use the default value.
|
||||
* @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
|
||||
* {@code 0} to use the default value.
|
||||
* {@code 0} to use the default value
|
||||
* @deprecated use {@link SslContextBuilder}
|
||||
*/
|
||||
@Deprecated
|
||||
public JdkSslServerContext(File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
|
||||
File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
|
||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||
File keyCertChainFile, File keyFile, String keyPassword,
|
||||
KeyManagerFactory keyManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter,
|
||||
JdkApplicationProtocolNegotiator apn,
|
||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||
super(newSSLContext(null, toX509CertificatesInternal(trustCertCollectionFile), trustManagerFactory,
|
||||
toX509CertificatesInternal(keyCertChainFile), toPrivateKeyInternal(keyFile, keyPassword),
|
||||
keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout), false,
|
||||
keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout, KeyStore.getDefaultType()), false,
|
||||
ciphers, cipherFilter, apn, ClientAuth.NONE, null, false);
|
||||
}
|
||||
|
||||
@ -233,16 +242,17 @@ public final class JdkSslServerContext extends JdkSslContext {
|
||||
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword,
|
||||
KeyManagerFactory keyManagerFactory, Iterable<String> ciphers, CipherSuiteFilter cipherFilter,
|
||||
ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout,
|
||||
ClientAuth clientAuth, String[] protocols, boolean startTls) throws SSLException {
|
||||
ClientAuth clientAuth, String[] protocols, boolean startTls,
|
||||
String keyStore) throws SSLException {
|
||||
super(newSSLContext(provider, trustCertCollection, trustManagerFactory, keyCertChain, key,
|
||||
keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout), false,
|
||||
keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout, keyStore), false,
|
||||
ciphers, cipherFilter, toNegotiator(apn, true), clientAuth, protocols, startTls);
|
||||
}
|
||||
|
||||
private static SSLContext newSSLContext(Provider sslContextProvider, X509Certificate[] trustCertCollection,
|
||||
TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain,
|
||||
PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
long sessionCacheSize, long sessionTimeout)
|
||||
long sessionCacheSize, long sessionTimeout, String keyStore)
|
||||
throws SSLException {
|
||||
if (key == null && keyManagerFactory == null) {
|
||||
throw new NullPointerException("key, keyManagerFactory");
|
||||
@ -250,10 +260,10 @@ public final class JdkSslServerContext extends JdkSslContext {
|
||||
|
||||
try {
|
||||
if (trustCertCollection != null) {
|
||||
trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory);
|
||||
trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory, keyStore);
|
||||
}
|
||||
if (key != null) {
|
||||
keyManagerFactory = buildKeyManagerFactory(keyCertChain, key, keyPassword, keyManagerFactory);
|
||||
keyManagerFactory = buildKeyManagerFactory(keyCertChain, key, keyPassword, keyManagerFactory, null);
|
||||
}
|
||||
|
||||
// Initialize the SSLContext to work with our key managers.
|
||||
|
@ -18,6 +18,7 @@ package io.netty.handler.ssl;
|
||||
import io.netty.internal.tcnative.SSL;
|
||||
|
||||
import java.io.File;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
@ -42,7 +43,7 @@ public final class OpenSslClientContext extends OpenSslContext {
|
||||
*/
|
||||
@Deprecated
|
||||
public OpenSslClientContext() throws SSLException {
|
||||
this((File) null, null, null, null, null, null, null, IdentityCipherSuiteFilter.INSTANCE, null, 0, 0);
|
||||
this(null, null, null, null, null, null, null, IdentityCipherSuiteFilter.INSTANCE, null, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -176,14 +177,14 @@ public final class OpenSslClientContext extends OpenSslContext {
|
||||
this(toX509CertificatesInternal(trustCertCollectionFile), trustManagerFactory,
|
||||
toX509CertificatesInternal(keyCertChainFile), toPrivateKeyInternal(keyFile, keyPassword),
|
||||
keyPassword, keyManagerFactory, ciphers, cipherFilter, apn, null, sessionCacheSize,
|
||||
sessionTimeout, false);
|
||||
sessionTimeout, false, KeyStore.getDefaultType());
|
||||
}
|
||||
|
||||
OpenSslClientContext(X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
|
||||
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword,
|
||||
KeyManagerFactory keyManagerFactory, Iterable<String> ciphers,
|
||||
CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols,
|
||||
long sessionCacheSize, long sessionTimeout, boolean enableOcsp)
|
||||
long sessionCacheSize, long sessionTimeout, boolean enableOcsp, String keyStore)
|
||||
throws SSLException {
|
||||
super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_CLIENT, keyCertChain,
|
||||
ClientAuth.NONE, protocols, false, enableOcsp);
|
||||
@ -191,7 +192,7 @@ public final class OpenSslClientContext extends OpenSslContext {
|
||||
try {
|
||||
OpenSslKeyMaterialProvider.validateKeyMaterialSupported(keyCertChain, key, keyPassword);
|
||||
sessionContext = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory,
|
||||
keyCertChain, key, keyPassword, keyManagerFactory);
|
||||
keyCertChain, key, keyPassword, keyManagerFactory, keyStore);
|
||||
success = true;
|
||||
} finally {
|
||||
if (!success) {
|
||||
|
@ -18,6 +18,7 @@ package io.netty.handler.ssl;
|
||||
import io.netty.internal.tcnative.SSL;
|
||||
|
||||
import java.io.File;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
@ -321,7 +322,7 @@ public final class OpenSslServerContext extends OpenSslContext {
|
||||
this(toX509CertificatesInternal(trustCertCollectionFile), trustManagerFactory,
|
||||
toX509CertificatesInternal(keyCertChainFile), toPrivateKeyInternal(keyFile, keyPassword),
|
||||
keyPassword, keyManagerFactory, ciphers, cipherFilter,
|
||||
apn, sessionCacheSize, sessionTimeout, ClientAuth.NONE, null, false, false);
|
||||
apn, sessionCacheSize, sessionTimeout, ClientAuth.NONE, null, false, false, KeyStore.getDefaultType());
|
||||
}
|
||||
|
||||
OpenSslServerContext(
|
||||
@ -329,10 +330,10 @@ public final class OpenSslServerContext extends OpenSslContext {
|
||||
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
|
||||
long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls,
|
||||
boolean enableOcsp) throws SSLException {
|
||||
boolean enableOcsp, String keyStore) throws SSLException {
|
||||
this(trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, keyManagerFactory, ciphers,
|
||||
cipherFilter, toNegotiator(apn), sessionCacheSize, sessionTimeout, clientAuth, protocols, startTls,
|
||||
enableOcsp);
|
||||
enableOcsp, keyStore);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@ -341,7 +342,7 @@ public final class OpenSslServerContext extends OpenSslContext {
|
||||
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, OpenSslApplicationProtocolNegotiator apn,
|
||||
long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls,
|
||||
boolean enableOcsp) throws SSLException {
|
||||
boolean enableOcsp, String keyStore) throws SSLException {
|
||||
super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_SERVER, keyCertChain,
|
||||
clientAuth, protocols, startTls, enableOcsp);
|
||||
|
||||
@ -350,7 +351,7 @@ public final class OpenSslServerContext extends OpenSslContext {
|
||||
try {
|
||||
OpenSslKeyMaterialProvider.validateKeyMaterialSupported(keyCertChain, key, keyPassword);
|
||||
sessionContext = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory,
|
||||
keyCertChain, key, keyPassword, keyManagerFactory);
|
||||
keyCertChain, key, keyPassword, keyManagerFactory, keyStore);
|
||||
success = true;
|
||||
} finally {
|
||||
if (!success) {
|
||||
|
@ -52,6 +52,8 @@ import java.util.Map;
|
||||
* Special {@link KeyManagerFactory} that pre-compute the keymaterial used when {@link SslProvider#OPENSSL} or
|
||||
* {@link SslProvider#OPENSSL_REFCNT} is used and so will improve handshake times and its performance.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Because the keymaterial is pre-computed any modification to the {@link KeyStore} is ignored after
|
||||
* {@link #init(KeyStore, char[])} is called.
|
||||
*
|
||||
|
@ -62,13 +62,13 @@ public final class ReferenceCountedOpenSslClientContext extends ReferenceCounted
|
||||
KeyManagerFactory keyManagerFactory, Iterable<String> ciphers,
|
||||
CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
|
||||
String[] protocols, long sessionCacheSize, long sessionTimeout,
|
||||
boolean enableOcsp) throws SSLException {
|
||||
boolean enableOcsp, String keyStore) throws SSLException {
|
||||
super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_CLIENT, keyCertChain,
|
||||
ClientAuth.NONE, protocols, false, enableOcsp, true);
|
||||
boolean success = false;
|
||||
try {
|
||||
sessionContext = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory,
|
||||
keyCertChain, key, keyPassword, keyManagerFactory);
|
||||
keyCertChain, key, keyPassword, keyManagerFactory, keyStore);
|
||||
success = true;
|
||||
} finally {
|
||||
if (!success) {
|
||||
@ -86,8 +86,9 @@ public final class ReferenceCountedOpenSslClientContext extends ReferenceCounted
|
||||
OpenSslEngineMap engineMap,
|
||||
X509Certificate[] trustCertCollection,
|
||||
TrustManagerFactory trustManagerFactory,
|
||||
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword,
|
||||
KeyManagerFactory keyManagerFactory) throws SSLException {
|
||||
X509Certificate[] keyCertChain, PrivateKey key,
|
||||
String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
String keyStore) throws SSLException {
|
||||
if (key == null && keyCertChain != null || key != null && keyCertChain == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Either both keyCertChain and key needs to be null or none of them");
|
||||
@ -107,7 +108,7 @@ public final class ReferenceCountedOpenSslClientContext extends ReferenceCounted
|
||||
// javadocs state that keyManagerFactory has precedent over keyCertChain
|
||||
if (keyManagerFactory == null && keyCertChain != null) {
|
||||
char[] keyPasswordChars = keyStorePassword(keyPassword);
|
||||
KeyStore ks = buildKeyStore(keyCertChain, key, keyPasswordChars);
|
||||
KeyStore ks = buildKeyStore(keyCertChain, key, keyPasswordChars, keyStore);
|
||||
if (ks.aliases().hasMoreElements()) {
|
||||
keyManagerFactory = new OpenSslX509KeyManagerFactory();
|
||||
} else {
|
||||
@ -140,7 +141,7 @@ public final class ReferenceCountedOpenSslClientContext extends ReferenceCounted
|
||||
|
||||
try {
|
||||
if (trustCertCollection != null) {
|
||||
trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory);
|
||||
trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory, keyStore);
|
||||
} else if (trustManagerFactory == null) {
|
||||
trustManagerFactory = TrustManagerFactory.getInstance(
|
||||
TrustManagerFactory.getDefaultAlgorithm());
|
||||
|
@ -55,25 +55,25 @@ public final class ReferenceCountedOpenSslServerContext extends ReferenceCounted
|
||||
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
|
||||
long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls,
|
||||
boolean enableOcsp) throws SSLException {
|
||||
boolean enableOcsp, String keyStore) throws SSLException {
|
||||
this(trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, keyManagerFactory, ciphers,
|
||||
cipherFilter, toNegotiator(apn), sessionCacheSize, sessionTimeout, clientAuth, protocols, startTls,
|
||||
enableOcsp);
|
||||
enableOcsp, keyStore);
|
||||
}
|
||||
|
||||
private ReferenceCountedOpenSslServerContext(
|
||||
ReferenceCountedOpenSslServerContext(
|
||||
X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
|
||||
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, OpenSslApplicationProtocolNegotiator apn,
|
||||
long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls,
|
||||
boolean enableOcsp) throws SSLException {
|
||||
boolean enableOcsp, String keyStore) throws SSLException {
|
||||
super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_SERVER, keyCertChain,
|
||||
clientAuth, protocols, startTls, enableOcsp, true);
|
||||
// Create a new SSL_CTX and configure it.
|
||||
boolean success = false;
|
||||
try {
|
||||
sessionContext = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory,
|
||||
keyCertChain, key, keyPassword, keyManagerFactory);
|
||||
keyCertChain, key, keyPassword, keyManagerFactory, keyStore);
|
||||
success = true;
|
||||
} finally {
|
||||
if (!success) {
|
||||
@ -92,7 +92,8 @@ public final class ReferenceCountedOpenSslServerContext extends ReferenceCounted
|
||||
X509Certificate[] trustCertCollection,
|
||||
TrustManagerFactory trustManagerFactory,
|
||||
X509Certificate[] keyCertChain, PrivateKey key,
|
||||
String keyPassword, KeyManagerFactory keyManagerFactory)
|
||||
String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
String keyStore)
|
||||
throws SSLException {
|
||||
OpenSslKeyMaterialProvider keyMaterialProvider = null;
|
||||
try {
|
||||
@ -111,7 +112,7 @@ public final class ReferenceCountedOpenSslServerContext extends ReferenceCounted
|
||||
// keyManagerFactory for the server so build one if it is not specified.
|
||||
if (keyManagerFactory == null) {
|
||||
char[] keyPasswordChars = keyStorePassword(keyPassword);
|
||||
KeyStore ks = buildKeyStore(keyCertChain, key, keyPasswordChars);
|
||||
KeyStore ks = buildKeyStore(keyCertChain, key, keyPasswordChars, keyStore);
|
||||
if (ks.aliases().hasMoreElements()) {
|
||||
keyManagerFactory = new OpenSslX509KeyManagerFactory();
|
||||
} else {
|
||||
@ -130,7 +131,7 @@ public final class ReferenceCountedOpenSslServerContext extends ReferenceCounted
|
||||
}
|
||||
try {
|
||||
if (trustCertCollection != null) {
|
||||
trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory);
|
||||
trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory, keyStore);
|
||||
} else if (trustManagerFactory == null) {
|
||||
// Mimic the way SSLContext.getInstance(KeyManager[], null, null) works
|
||||
trustManagerFactory = TrustManagerFactory.getInstance(
|
||||
|
@ -339,7 +339,7 @@ public abstract class SslContext {
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
|
||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||
return newServerContext(provider, null, null, certChainFile, keyFile, keyPassword, null,
|
||||
ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
|
||||
ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, KeyStore.getDefaultType());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -382,12 +382,57 @@ public abstract class SslContext {
|
||||
File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
|
||||
long sessionCacheSize, long sessionTimeout) throws SSLException {
|
||||
return newServerContext(provider, trustCertCollectionFile, trustManagerFactory, keyCertChainFile,
|
||||
keyFile, keyPassword, keyManagerFactory, ciphers, cipherFilter, apn,
|
||||
sessionCacheSize, sessionTimeout, KeyStore.getDefaultType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new server-side {@link SslContext}.
|
||||
* @param provider the {@link SslContext} implementation to use.
|
||||
* {@code null} to use the current default one.
|
||||
* @param trustCertCollectionFile an X.509 certificate collection file in PEM format.
|
||||
* This provides the certificate collection used for mutual authentication.
|
||||
* {@code null} to use the system default
|
||||
* @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
|
||||
* that verifies the certificates sent from clients.
|
||||
* {@code null} to use the default or the results of parsing
|
||||
* {@code trustCertCollectionFile}.
|
||||
* This parameter is ignored if {@code provider} is not {@link SslProvider#JDK}.
|
||||
* @param keyCertChainFile an X.509 certificate chain file in PEM format
|
||||
* @param keyFile a PKCS#8 private key file in PEM format
|
||||
* @param keyPassword the password of the {@code keyFile}.
|
||||
* {@code null} if it's not password-protected.
|
||||
* @param keyManagerFactory the {@link KeyManagerFactory} that provides the {@link KeyManager}s
|
||||
* that is used to encrypt data being sent to clients.
|
||||
* {@code null} to use the default or the results of parsing
|
||||
* {@code keyCertChainFile} and {@code keyFile}.
|
||||
* This parameter is ignored if {@code provider} is not {@link SslProvider#JDK}.
|
||||
* @param ciphers the cipher suites to enable, in the order of preference.
|
||||
* {@code null} to use the default cipher suites.
|
||||
* @param cipherFilter a filter to apply over the supplied list of ciphers
|
||||
* Only required if {@code provider} is {@link SslProvider#JDK}
|
||||
* @param apn Provides a means to configure parameters related to application protocol negotiation.
|
||||
* @param sessionCacheSize the size of the cache used for storing SSL session objects.
|
||||
* {@code 0} to use the default value.
|
||||
* @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
|
||||
* {@code 0} to use the default value.
|
||||
* @param keyStore the keystore type that should be used
|
||||
* @return a new server-side {@link SslContext}
|
||||
*/
|
||||
static SslContext newServerContext(
|
||||
SslProvider provider,
|
||||
File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
|
||||
File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
|
||||
long sessionCacheSize, long sessionTimeout, String keyStore) throws SSLException {
|
||||
try {
|
||||
return newServerContextInternal(provider, null, toX509Certificates(trustCertCollectionFile),
|
||||
trustManagerFactory, toX509Certificates(keyCertChainFile),
|
||||
toPrivateKey(keyFile, keyPassword),
|
||||
keyPassword, keyManagerFactory, ciphers, cipherFilter, apn,
|
||||
sessionCacheSize, sessionTimeout, ClientAuth.NONE, null, false, false);
|
||||
sessionCacheSize, sessionTimeout, ClientAuth.NONE, null,
|
||||
false, false, keyStore);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof SSLException) {
|
||||
throw (SSLException) e;
|
||||
@ -403,7 +448,7 @@ public abstract class SslContext {
|
||||
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
|
||||
long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls,
|
||||
boolean enableOcsp) throws SSLException {
|
||||
boolean enableOcsp, String keyStoreType) throws SSLException {
|
||||
|
||||
if (provider == null) {
|
||||
provider = defaultServerProvider();
|
||||
@ -417,19 +462,19 @@ public abstract class SslContext {
|
||||
return new JdkSslServerContext(sslContextProvider,
|
||||
trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword,
|
||||
keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout,
|
||||
clientAuth, protocols, startTls);
|
||||
clientAuth, protocols, startTls, keyStoreType);
|
||||
case OPENSSL:
|
||||
verifyNullSslContextProvider(provider, sslContextProvider);
|
||||
return new OpenSslServerContext(
|
||||
trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword,
|
||||
keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout,
|
||||
clientAuth, protocols, startTls, enableOcsp);
|
||||
clientAuth, protocols, startTls, enableOcsp, keyStoreType);
|
||||
case OPENSSL_REFCNT:
|
||||
verifyNullSslContextProvider(provider, sslContextProvider);
|
||||
return new ReferenceCountedOpenSslServerContext(
|
||||
trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword,
|
||||
keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout,
|
||||
clientAuth, protocols, startTls, enableOcsp);
|
||||
clientAuth, protocols, startTls, enableOcsp, keyStoreType);
|
||||
default:
|
||||
throw new Error(provider.toString());
|
||||
}
|
||||
@ -745,7 +790,8 @@ public abstract class SslContext {
|
||||
toX509Certificates(trustCertCollectionFile), trustManagerFactory,
|
||||
toX509Certificates(keyCertChainFile), toPrivateKey(keyFile, keyPassword),
|
||||
keyPassword, keyManagerFactory, ciphers, cipherFilter,
|
||||
apn, null, sessionCacheSize, sessionTimeout, false);
|
||||
apn, null, sessionCacheSize, sessionTimeout, false,
|
||||
KeyStore.getDefaultType());
|
||||
} catch (Exception e) {
|
||||
if (e instanceof SSLException) {
|
||||
throw (SSLException) e;
|
||||
@ -760,7 +806,7 @@ public abstract class SslContext {
|
||||
X509Certificate[] trustCert, TrustManagerFactory trustManagerFactory,
|
||||
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
|
||||
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols,
|
||||
long sessionCacheSize, long sessionTimeout, boolean enableOcsp) throws SSLException {
|
||||
long sessionCacheSize, long sessionTimeout, boolean enableOcsp, String keyStoreType) throws SSLException {
|
||||
if (provider == null) {
|
||||
provider = defaultClientProvider();
|
||||
}
|
||||
@ -771,19 +817,20 @@ public abstract class SslContext {
|
||||
}
|
||||
return new JdkSslClientContext(sslContextProvider,
|
||||
trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
|
||||
keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, sessionTimeout);
|
||||
keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize,
|
||||
sessionTimeout, keyStoreType);
|
||||
case OPENSSL:
|
||||
verifyNullSslContextProvider(provider, sslContextProvider);
|
||||
return new OpenSslClientContext(
|
||||
trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
|
||||
keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, sessionTimeout,
|
||||
enableOcsp);
|
||||
enableOcsp, keyStoreType);
|
||||
case OPENSSL_REFCNT:
|
||||
verifyNullSslContextProvider(provider, sslContextProvider);
|
||||
return new ReferenceCountedOpenSslClientContext(
|
||||
trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
|
||||
keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, sessionTimeout,
|
||||
enableOcsp);
|
||||
enableOcsp, keyStoreType);
|
||||
default:
|
||||
throw new Error(provider.toString());
|
||||
}
|
||||
@ -1026,16 +1073,21 @@ public abstract class SslContext {
|
||||
/**
|
||||
* Generates a new {@link KeyStore}.
|
||||
*
|
||||
* @param certChain a X.509 certificate chain
|
||||
* @param certChain an X.509 certificate chain
|
||||
* @param key a PKCS#8 private key
|
||||
* @param keyPasswordChars the password of the {@code keyFile}.
|
||||
* {@code null} if it's not password-protected.
|
||||
* @param keyStoreType The KeyStore Type you want to use
|
||||
* @return generated {@link KeyStore}.
|
||||
*/
|
||||
static KeyStore buildKeyStore(X509Certificate[] certChain, PrivateKey key, char[] keyPasswordChars)
|
||||
static KeyStore buildKeyStore(X509Certificate[] certChain, PrivateKey key,
|
||||
char[] keyPasswordChars, String keyStoreType)
|
||||
throws KeyStoreException, NoSuchAlgorithmException,
|
||||
CertificateException, IOException {
|
||||
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
if (keyStoreType == null) {
|
||||
keyStoreType = KeyStore.getDefaultType();
|
||||
}
|
||||
KeyStore ks = KeyStore.getInstance(keyStoreType);
|
||||
ks.load(null, null);
|
||||
ks.setKeyEntry(ALIAS, key, keyPasswordChars, certChain);
|
||||
return ks;
|
||||
@ -1095,9 +1147,22 @@ public abstract class SslContext {
|
||||
protected static TrustManagerFactory buildTrustManagerFactory(
|
||||
File certChainFile, TrustManagerFactory trustManagerFactory)
|
||||
throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
|
||||
return buildTrustManagerFactory(certChainFile, trustManagerFactory, KeyStore.getDefaultType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link TrustManagerFactory} from a certificate chain file.
|
||||
* @param certChainFile The certificate file to build from.
|
||||
* @param trustManagerFactory The existing {@link TrustManagerFactory} that will be used if not {@code null}.
|
||||
* @param keyType The KeyStore Type you want to use
|
||||
* @return A {@link TrustManagerFactory} which contains the certificates in {@code certChainFile}
|
||||
*/
|
||||
static TrustManagerFactory buildTrustManagerFactory(
|
||||
File certChainFile, TrustManagerFactory trustManagerFactory, String keyType)
|
||||
throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
|
||||
X509Certificate[] x509Certs = toX509Certificates(certChainFile);
|
||||
|
||||
return buildTrustManagerFactory(x509Certs, trustManagerFactory);
|
||||
return buildTrustManagerFactory(x509Certs, trustManagerFactory, keyType);
|
||||
}
|
||||
|
||||
static X509Certificate[] toX509Certificates(File file) throws CertificateException {
|
||||
@ -1141,9 +1206,12 @@ public abstract class SslContext {
|
||||
}
|
||||
|
||||
static TrustManagerFactory buildTrustManagerFactory(
|
||||
X509Certificate[] certCollection, TrustManagerFactory trustManagerFactory)
|
||||
X509Certificate[] certCollection, TrustManagerFactory trustManagerFactory, String keyStoreType)
|
||||
throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
|
||||
final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
if (keyStoreType == null) {
|
||||
keyStoreType = KeyStore.getDefaultType();
|
||||
}
|
||||
final KeyStore ks = KeyStore.getInstance(keyStoreType);
|
||||
ks.load(null, null);
|
||||
|
||||
int i = 1;
|
||||
@ -1179,10 +1247,22 @@ public abstract class SslContext {
|
||||
}
|
||||
|
||||
static KeyManagerFactory buildKeyManagerFactory(X509Certificate[] certChain, PrivateKey key, String keyPassword,
|
||||
KeyManagerFactory kmf)
|
||||
KeyManagerFactory kmf, String keyStoreType)
|
||||
throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException,
|
||||
CertificateException, IOException {
|
||||
return buildKeyManagerFactory(certChain, KeyManagerFactory.getDefaultAlgorithm(), key, keyPassword, kmf);
|
||||
return buildKeyManagerFactory(certChain, KeyManagerFactory.getDefaultAlgorithm(), key,
|
||||
keyPassword, kmf, keyStoreType);
|
||||
}
|
||||
|
||||
static KeyManagerFactory buildKeyManagerFactory(X509Certificate[] certChainFile,
|
||||
String keyAlgorithm, PrivateKey key,
|
||||
String keyPassword, KeyManagerFactory kmf,
|
||||
String keyStore)
|
||||
throws KeyStoreException, NoSuchAlgorithmException, IOException,
|
||||
CertificateException, UnrecoverableKeyException {
|
||||
char[] keyPasswordChars = keyStorePassword(keyPassword);
|
||||
KeyStore ks = buildKeyStore(certChainFile, key, keyPasswordChars, keyStore);
|
||||
return buildKeyManagerFactory(ks, keyAlgorithm, keyPasswordChars, kmf);
|
||||
}
|
||||
|
||||
static KeyManagerFactory buildKeyManagerFactory(X509Certificate[] certChainFile,
|
||||
@ -1191,7 +1271,7 @@ public abstract class SslContext {
|
||||
throws KeyStoreException, NoSuchAlgorithmException, IOException,
|
||||
CertificateException, UnrecoverableKeyException {
|
||||
char[] keyPasswordChars = keyStorePassword(keyPassword);
|
||||
KeyStore ks = buildKeyStore(certChainFile, key, keyPasswordChars);
|
||||
KeyStore ks = buildKeyStore(certChainFile, key, keyPasswordChars, KeyStore.getDefaultType());
|
||||
return buildKeyManagerFactory(ks, keyAlgorithm, keyPasswordChars, kmf);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ import static io.netty.util.internal.ObjectUtil.checkNotNull;
|
||||
|
||||
import io.netty.util.internal.UnstableApi;
|
||||
|
||||
import java.security.KeyStore;
|
||||
import java.security.Provider;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLException;
|
||||
@ -149,6 +150,7 @@ public final class SslContextBuilder {
|
||||
private String[] protocols;
|
||||
private boolean startTls;
|
||||
private boolean enableOcsp;
|
||||
private String keyStoreType = KeyStore.getDefaultType();
|
||||
|
||||
private SslContextBuilder(boolean forServer) {
|
||||
this.forServer = forServer;
|
||||
@ -162,6 +164,14 @@ public final class SslContextBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link KeyStore} type that should be used. {@code null} uses the default one.
|
||||
*/
|
||||
public SslContextBuilder keyStoreType(String keyStoreType) {
|
||||
this.keyStoreType = keyStoreType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The SSLContext {@link Provider} to use. {@code null} uses the default one. This is only
|
||||
* used with {@link SslProvider#JDK}.
|
||||
@ -447,11 +457,11 @@ public final class SslContextBuilder {
|
||||
return SslContext.newServerContextInternal(provider, sslContextProvider, trustCertCollection,
|
||||
trustManagerFactory, keyCertChain, key, keyPassword, keyManagerFactory,
|
||||
ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, clientAuth, protocols, startTls,
|
||||
enableOcsp);
|
||||
enableOcsp, keyStoreType);
|
||||
} else {
|
||||
return SslContext.newClientContextInternal(provider, sslContextProvider, trustCertCollection,
|
||||
trustManagerFactory, keyCertChain, key, keyPassword, keyManagerFactory,
|
||||
ciphers, cipherFilter, apn, protocols, sessionCacheSize, sessionTimeout, enableOcsp);
|
||||
ciphers, cipherFilter, apn, protocols, sessionCacheSize, sessionTimeout, enableOcsp, keyStoreType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ import java.util.Date;
|
||||
* It is purely for testing purposes, and thus it is very insecure.
|
||||
* It even uses an insecure pseudo-random generator for faster generation internally.
|
||||
* </p><p>
|
||||
* A X.509 certificate file and a RSA private key file are generated in a system's temporary directory using
|
||||
* An X.509 certificate file and a RSA private key file are generated in a system's temporary directory using
|
||||
* {@link java.io.File#createTempFile(String, String)}, and they are deleted when the JVM exits using
|
||||
* {@link java.io.File#deleteOnExit()}.
|
||||
* </p><p>
|
||||
|
@ -238,7 +238,7 @@ public class JdkSslEngineTest extends SSLEngineTest {
|
||||
|
||||
SslContext serverSslCtx = new JdkSslServerContext(providerType.provider(),
|
||||
ssc.certificate(), ssc.privateKey(), null, null,
|
||||
IdentityCipherSuiteFilter.INSTANCE, serverApn, 0, 0);
|
||||
IdentityCipherSuiteFilter.INSTANCE, serverApn, 0, 0, null);
|
||||
SslContext clientSslCtx = new JdkSslClientContext(providerType.provider(), null,
|
||||
InsecureTrustManagerFactory.INSTANCE, null,
|
||||
IdentityCipherSuiteFilter.INSTANCE, clientApn, 0, 0);
|
||||
|
@ -2903,7 +2903,7 @@ public abstract class SSLEngineTest {
|
||||
SelfSignedCertificate ssc = new SelfSignedCertificate();
|
||||
KeyManagerFactory kmf = useKeyManagerFactory ?
|
||||
SslContext.buildKeyManagerFactory(
|
||||
new java.security.cert.X509Certificate[] { ssc.cert()}, ssc.key(), null, null) : null;
|
||||
new java.security.cert.X509Certificate[] { ssc.cert()}, ssc.key(), null, null, null) : null;
|
||||
|
||||
SslContextBuilder clientContextBuilder = SslContextBuilder.forClient();
|
||||
if (mutualAuth) {
|
||||
@ -3249,7 +3249,7 @@ public abstract class SSLEngineTest {
|
||||
throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException,
|
||||
CertificateException, IOException {
|
||||
return SslContext.buildKeyManagerFactory(
|
||||
new java.security.cert.X509Certificate[] { ssc.cert() }, ssc.key(), null, null);
|
||||
new java.security.cert.X509Certificate[] { ssc.cert() }, ssc.key(), null, null, null);
|
||||
}
|
||||
|
||||
private final class TestTrustManagerFactory extends X509ExtendedTrustManager {
|
||||
|
@ -260,7 +260,7 @@ final class SniClientJava8TestUtil {
|
||||
IOException, CertificateException {
|
||||
return new SniX509KeyManagerFactory(
|
||||
new SNIHostName(hostname), SslContext.buildKeyManagerFactory(
|
||||
new X509Certificate[] { cert.cert() }, cert.key(), null, null));
|
||||
new X509Certificate[] { cert.cert() }, cert.key(), null, null, null));
|
||||
}
|
||||
|
||||
private static final class SniX509KeyManagerFactory extends KeyManagerFactory {
|
||||
|
@ -114,7 +114,7 @@ public class SniClientTest {
|
||||
KeyManagerFactory kmf = PlatformDependent.javaVersion() >= 8 ?
|
||||
SniClientJava8TestUtil.newSniX509KeyManagerFactory(cert, sniHostName) :
|
||||
SslContext.buildKeyManagerFactory(
|
||||
new X509Certificate[] { cert.cert() }, cert.key(), null, null);
|
||||
new X509Certificate[] { cert.cert() }, cert.key(), null, null, null);
|
||||
|
||||
sslServerContext = SslContextBuilder.forServer(kmf)
|
||||
.sslProvider(sslServerProvider)
|
||||
|
@ -52,6 +52,17 @@ public class SslContextBuilderTest {
|
||||
testClientContext(SslProvider.OPENSSL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyStoreTypeJdk() throws Exception {
|
||||
testKeyStoreType(SslProvider.JDK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyStoreTypeOpenssl() throws Exception {
|
||||
Assume.assumeTrue(OpenSsl.isAvailable());
|
||||
testKeyStoreType(SslProvider.OPENSSL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerContextFromFileJdk() throws Exception {
|
||||
testServerContextFromFile(SslProvider.JDK);
|
||||
@ -141,6 +152,17 @@ public class SslContextBuilderTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static void testKeyStoreType(SslProvider provider) throws Exception {
|
||||
SelfSignedCertificate cert = new SelfSignedCertificate();
|
||||
SslContextBuilder builder = SslContextBuilder.forServer(cert.certificate(), cert.privateKey())
|
||||
.sslProvider(provider)
|
||||
.keyStoreType("PKCS12");
|
||||
SslContext context = builder.build();
|
||||
SSLEngine engine = context.newEngine(UnpooledByteBufAllocator.DEFAULT);
|
||||
engine.closeInbound();
|
||||
engine.closeOutbound();
|
||||
}
|
||||
|
||||
private static void testInvalidCipher(SslProvider provider) throws Exception {
|
||||
SelfSignedCertificate cert = new SelfSignedCertificate();
|
||||
SslContextBuilder builder = SslContextBuilder.forClient()
|
||||
|
@ -110,7 +110,7 @@ public class SslContextTrustManagerTest {
|
||||
throws Exception {
|
||||
X509Certificate[] certCollection = loadCertCollection(resourceNames);
|
||||
TrustManagerFactory tmf = SslContext.buildTrustManagerFactory(
|
||||
certCollection, null);
|
||||
certCollection, null, null);
|
||||
|
||||
for (TrustManager tm : tmf.getTrustManagers()) {
|
||||
if (tm instanceof X509TrustManager) {
|
||||
|
Loading…
Reference in New Issue
Block a user