Mark some methods as protected to make it easier to write own SslContext implementations (#10953)

Motivation:

We should expose some methods as protected to make it easier to write custom SslContext implementations.
This will be reused by the code for https://github.com/netty/netty-incubator-codec-quic/issues/97

Modifications:

- Add protected to some static methods which are useful for sub-classes
- Remove some unused methods
- Move *Wrapper classes to util package and make these public

Result:

Easier to write custom SslContext implementations
This commit is contained in:
Norman Maurer 2021-01-21 10:41:33 +01:00
parent b19b8c39cb
commit 6ae8cd6e44
9 changed files with 34 additions and 46 deletions

View File

@ -80,7 +80,8 @@ final class JdkSslClientContext extends JdkSslContext {
trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory, keyStore); trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory, keyStore);
} }
if (keyCertChain != null) { if (keyCertChain != null) {
keyManagerFactory = buildKeyManagerFactory(keyCertChain, key, keyPassword, keyManagerFactory, keyStore); keyManagerFactory = buildKeyManagerFactory(keyCertChain, null,
key, keyPassword, keyManagerFactory, keyStore);
} }
SSLContext ctx = sslContextProvider == null ? SSLContext.getInstance(PROTOCOL) SSLContext ctx = sslContextProvider == null ? SSLContext.getInstance(PROTOCOL)
: SSLContext.getInstance(PROTOCOL, sslContextProvider); : SSLContext.getInstance(PROTOCOL, sslContextProvider);

View File

@ -86,7 +86,8 @@ final class JdkSslServerContext extends JdkSslContext {
trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory, keyStore); trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory, keyStore);
} }
if (key != null) { if (key != null) {
keyManagerFactory = buildKeyManagerFactory(keyCertChain, key, keyPassword, keyManagerFactory, null); keyManagerFactory = buildKeyManagerFactory(keyCertChain, null,
key, keyPassword, keyManagerFactory, null);
} }
// Initialize the SSLContext to work with our key managers. // Initialize the SSLContext to work with our key managers.

View File

@ -16,8 +16,6 @@
package io.netty.handler.ssl; package io.netty.handler.ssl;
import io.netty.util.internal.SystemPropertyUtil; import io.netty.util.internal.SystemPropertyUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import io.netty.internal.tcnative.CertificateCallback; import io.netty.internal.tcnative.CertificateCallback;
import io.netty.internal.tcnative.SSL; import io.netty.internal.tcnative.SSL;
import io.netty.internal.tcnative.SSLContext; import io.netty.internal.tcnative.SSLContext;
@ -48,8 +46,7 @@ import javax.security.auth.x500.X500Principal;
* {@link ReferenceCountedOpenSslEngine} is called which uses this class's JNI resources the JVM may crash. * {@link ReferenceCountedOpenSslEngine} is called which uses this class's JNI resources the JVM may crash.
*/ */
public final class ReferenceCountedOpenSslClientContext extends ReferenceCountedOpenSslContext { public final class ReferenceCountedOpenSslClientContext extends ReferenceCountedOpenSslContext {
private static final InternalLogger logger =
InternalLoggerFactory.getInstance(ReferenceCountedOpenSslClientContext.class);
private static final Set<String> SUPPORTED_KEY_TYPES = Collections.unmodifiableSet(new LinkedHashSet<>( private static final Set<String> SUPPORTED_KEY_TYPES = Collections.unmodifiableSet(new LinkedHashSet<>(
Arrays.asList(OpenSslKeyMaterialManager.KEY_TYPE_RSA, Arrays.asList(OpenSslKeyMaterialManager.KEY_TYPE_RSA,
OpenSslKeyMaterialManager.KEY_TYPE_DH_RSA, OpenSslKeyMaterialManager.KEY_TYPE_DH_RSA,

View File

@ -1061,6 +1061,7 @@ public abstract class SslContext {
* {@code key} * {@code key}
* @throws InvalidAlgorithmParameterException if decryption algorithm parameters are somehow faulty * @throws InvalidAlgorithmParameterException if decryption algorithm parameters are somehow faulty
*/ */
@Deprecated
protected static PKCS8EncodedKeySpec generateKeySpec(char[] password, byte[] key) protected static PKCS8EncodedKeySpec generateKeySpec(char[] password, byte[] key)
throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException,
InvalidKeyException, InvalidAlgorithmParameterException { InvalidKeyException, InvalidAlgorithmParameterException {
@ -1090,7 +1091,7 @@ public abstract class SslContext {
* @param keyStoreType The KeyStore Type you want to use * @param keyStoreType The KeyStore Type you want to use
* @return generated {@link KeyStore}. * @return generated {@link KeyStore}.
*/ */
static KeyStore buildKeyStore(X509Certificate[] certChain, PrivateKey key, protected static KeyStore buildKeyStore(X509Certificate[] certChain, PrivateKey key,
char[] keyPasswordChars, String keyStoreType) char[] keyPasswordChars, String keyStoreType)
throws KeyStoreException, NoSuchAlgorithmException, throws KeyStoreException, NoSuchAlgorithmException,
CertificateException, IOException { CertificateException, IOException {
@ -1103,7 +1104,7 @@ public abstract class SslContext {
return ks; return ks;
} }
static PrivateKey toPrivateKey(File keyFile, String keyPassword) throws NoSuchAlgorithmException, protected static PrivateKey toPrivateKey(File keyFile, String keyPassword) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeySpecException,
InvalidAlgorithmParameterException, InvalidAlgorithmParameterException,
KeyException, IOException { KeyException, IOException {
@ -1113,7 +1114,8 @@ public abstract class SslContext {
return getPrivateKeyFromByteBuffer(PemReader.readPrivateKey(keyFile), keyPassword); return getPrivateKeyFromByteBuffer(PemReader.readPrivateKey(keyFile), keyPassword);
} }
static PrivateKey toPrivateKey(InputStream keyInputStream, String keyPassword) throws NoSuchAlgorithmException, protected static PrivateKey toPrivateKey(InputStream keyInputStream, String keyPassword)
throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeySpecException,
InvalidAlgorithmParameterException, InvalidAlgorithmParameterException,
KeyException, IOException { KeyException, IOException {
@ -1157,7 +1159,7 @@ public abstract class SslContext {
protected static TrustManagerFactory buildTrustManagerFactory( protected static TrustManagerFactory buildTrustManagerFactory(
File certChainFile, TrustManagerFactory trustManagerFactory) File certChainFile, TrustManagerFactory trustManagerFactory)
throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException { throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
return buildTrustManagerFactory(certChainFile, trustManagerFactory, KeyStore.getDefaultType()); return buildTrustManagerFactory(certChainFile, trustManagerFactory, null);
} }
/** /**
@ -1167,7 +1169,7 @@ public abstract class SslContext {
* @param keyType The KeyStore Type you want to use * @param keyType The KeyStore Type you want to use
* @return A {@link TrustManagerFactory} which contains the certificates in {@code certChainFile} * @return A {@link TrustManagerFactory} which contains the certificates in {@code certChainFile}
*/ */
static TrustManagerFactory buildTrustManagerFactory( protected static TrustManagerFactory buildTrustManagerFactory(
File certChainFile, TrustManagerFactory trustManagerFactory, String keyType) File certChainFile, TrustManagerFactory trustManagerFactory, String keyType)
throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException { throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
X509Certificate[] x509Certs = toX509Certificates(certChainFile); X509Certificate[] x509Certs = toX509Certificates(certChainFile);
@ -1175,14 +1177,14 @@ public abstract class SslContext {
return buildTrustManagerFactory(x509Certs, trustManagerFactory, keyType); return buildTrustManagerFactory(x509Certs, trustManagerFactory, keyType);
} }
static X509Certificate[] toX509Certificates(File file) throws CertificateException { protected static X509Certificate[] toX509Certificates(File file) throws CertificateException {
if (file == null) { if (file == null) {
return null; return null;
} }
return getCertificatesFromBuffers(PemReader.readCertificates(file)); return getCertificatesFromBuffers(PemReader.readCertificates(file));
} }
static X509Certificate[] toX509Certificates(InputStream in) throws CertificateException { protected static X509Certificate[] toX509Certificates(InputStream in) throws CertificateException {
if (in == null) { if (in == null) {
return null; return null;
} }
@ -1215,7 +1217,7 @@ public abstract class SslContext {
return x509Certs; return x509Certs;
} }
static TrustManagerFactory buildTrustManagerFactory( protected static TrustManagerFactory buildTrustManagerFactory(
X509Certificate[] certCollection, TrustManagerFactory trustManagerFactory, String keyStoreType) X509Certificate[] certCollection, TrustManagerFactory trustManagerFactory, String keyStoreType)
throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException { throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
if (keyStoreType == null) { if (keyStoreType == null) {
@ -1256,41 +1258,29 @@ public abstract class SslContext {
} }
} }
static KeyManagerFactory buildKeyManagerFactory(X509Certificate[] certChain, PrivateKey key, String keyPassword, protected static KeyManagerFactory buildKeyManagerFactory(X509Certificate[] certChainFile,
KeyManagerFactory kmf, String keyStoreType)
throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException,
CertificateException, IOException {
return buildKeyManagerFactory(certChain, KeyManagerFactory.getDefaultAlgorithm(), key,
keyPassword, kmf, keyStoreType);
}
static KeyManagerFactory buildKeyManagerFactory(X509Certificate[] certChainFile,
String keyAlgorithm, PrivateKey key, String keyAlgorithm, PrivateKey key,
String keyPassword, KeyManagerFactory kmf, String keyPassword, KeyManagerFactory kmf,
String keyStore) String keyStore)
throws KeyStoreException, NoSuchAlgorithmException, IOException, throws KeyStoreException, NoSuchAlgorithmException, IOException,
CertificateException, UnrecoverableKeyException { CertificateException, UnrecoverableKeyException {
if (keyAlgorithm == null) {
keyAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
}
char[] keyPasswordChars = keyStorePassword(keyPassword); char[] keyPasswordChars = keyStorePassword(keyPassword);
KeyStore ks = buildKeyStore(certChainFile, key, keyPasswordChars, keyStore); KeyStore ks = buildKeyStore(certChainFile, key, keyPasswordChars, keyStore);
return buildKeyManagerFactory(ks, keyAlgorithm, keyPasswordChars, kmf); return buildKeyManagerFactory(ks, keyAlgorithm, keyPasswordChars, kmf);
} }
static KeyManagerFactory buildKeyManagerFactory(X509Certificate[] certChainFile,
String keyAlgorithm, PrivateKey key,
String keyPassword, KeyManagerFactory kmf)
throws KeyStoreException, NoSuchAlgorithmException, IOException,
CertificateException, UnrecoverableKeyException {
char[] keyPasswordChars = keyStorePassword(keyPassword);
KeyStore ks = buildKeyStore(certChainFile, key, keyPasswordChars, KeyStore.getDefaultType());
return buildKeyManagerFactory(ks, keyAlgorithm, keyPasswordChars, kmf);
}
static KeyManagerFactory buildKeyManagerFactory(KeyStore ks, static KeyManagerFactory buildKeyManagerFactory(KeyStore ks,
String keyAlgorithm, String keyAlgorithm,
char[] keyPasswordChars, KeyManagerFactory kmf) char[] keyPasswordChars, KeyManagerFactory kmf)
throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
// Set up key manager factory to use our key store // Set up key manager factory to use our key store
if (kmf == null) { if (kmf == null) {
if (keyAlgorithm == null) {
keyAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
}
kmf = KeyManagerFactory.getInstance(keyAlgorithm); kmf = KeyManagerFactory.getInstance(keyAlgorithm);
} }
kmf.init(ks, keyPasswordChars); kmf.init(ks, keyPasswordChars);

View File

@ -16,6 +16,8 @@
package io.netty.handler.ssl; package io.netty.handler.ssl;
import io.netty.handler.ssl.util.KeyManagerFactoryWrapper;
import io.netty.handler.ssl.util.TrustManagerFactoryWrapper;
import io.netty.util.internal.UnstableApi; import io.netty.util.internal.UnstableApi;
import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManager;

View File

@ -14,19 +14,17 @@
* under the License. * under the License.
*/ */
package io.netty.handler.ssl; package io.netty.handler.ssl.util;
import io.netty.handler.ssl.util.SimpleKeyManagerFactory;
import java.security.KeyStore; import java.security.KeyStore;
import java.util.Objects; import java.util.Objects;
import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManager;
import javax.net.ssl.ManagerFactoryParameters; import javax.net.ssl.ManagerFactoryParameters;
final class KeyManagerFactoryWrapper extends SimpleKeyManagerFactory { public final class KeyManagerFactoryWrapper extends SimpleKeyManagerFactory {
private final KeyManager km; private final KeyManager km;
KeyManagerFactoryWrapper(KeyManager km) { public KeyManagerFactoryWrapper(KeyManager km) {
this.km = Objects.requireNonNull(km, "km"); this.km = Objects.requireNonNull(km, "km");
} }

View File

@ -14,19 +14,17 @@
* under the License. * under the License.
*/ */
package io.netty.handler.ssl; package io.netty.handler.ssl.util;
import io.netty.handler.ssl.util.SimpleTrustManagerFactory;
import java.security.KeyStore; import java.security.KeyStore;
import java.util.Objects; import java.util.Objects;
import javax.net.ssl.ManagerFactoryParameters; import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
final class TrustManagerFactoryWrapper extends SimpleTrustManagerFactory { public final class TrustManagerFactoryWrapper extends SimpleTrustManagerFactory {
private final TrustManager tm; private final TrustManager tm;
TrustManagerFactoryWrapper(TrustManager tm) { public TrustManagerFactoryWrapper(TrustManager tm) {
this.tm = Objects.requireNonNull(tm, "tm"); this.tm = Objects.requireNonNull(tm, "tm");
} }

View File

@ -2959,7 +2959,8 @@ public abstract class SSLEngineTest {
SelfSignedCertificate ssc = new SelfSignedCertificate(); SelfSignedCertificate ssc = new SelfSignedCertificate();
KeyManagerFactory kmf = useKeyManagerFactory ? KeyManagerFactory kmf = useKeyManagerFactory ?
SslContext.buildKeyManagerFactory( SslContext.buildKeyManagerFactory(
new java.security.cert.X509Certificate[] { ssc.cert()}, ssc.key(), null, null, null) : null; new java.security.cert.X509Certificate[] { ssc.cert()}, null,
ssc.key(), null, null, null) : null;
SslContextBuilder clientContextBuilder = SslContextBuilder.forClient(); SslContextBuilder clientContextBuilder = SslContextBuilder.forClient();
if (mutualAuth) { if (mutualAuth) {
@ -3522,7 +3523,7 @@ public abstract class SSLEngineTest {
throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException,
CertificateException, IOException { CertificateException, IOException {
return SslContext.buildKeyManagerFactory( return SslContext.buildKeyManagerFactory(
new java.security.cert.X509Certificate[] { ssc.cert() }, ssc.key(), null, null, null); new java.security.cert.X509Certificate[] { ssc.cert() }, null, ssc.key(), null, null, null);
} }
private final class TestTrustManagerFactory extends X509ExtendedTrustManager { private final class TestTrustManagerFactory extends X509ExtendedTrustManager {

View File

@ -264,7 +264,7 @@ final class SniClientJava8TestUtil {
IOException, CertificateException { IOException, CertificateException {
return new SniX509KeyManagerFactory( return new SniX509KeyManagerFactory(
new SNIHostName(hostname), SslContext.buildKeyManagerFactory( new SNIHostName(hostname), SslContext.buildKeyManagerFactory(
new X509Certificate[] { cert.cert() }, cert.key(), null, null, null)); new X509Certificate[] { cert.cert() }, null, cert.key(), null, null, null));
} }
private static final class SniX509KeyManagerFactory extends KeyManagerFactory { private static final class SniX509KeyManagerFactory extends KeyManagerFactory {