1818import com .datastax .oss .driver .api .core .metadata .EndPoint ;
1919import com .datastax .oss .driver .api .core .session .SessionBuilder ;
2020import edu .umd .cs .findbugs .annotations .NonNull ;
21+ import edu .umd .cs .findbugs .annotations .Nullable ;
2122import java .net .InetSocketAddress ;
2223import java .net .SocketAddress ;
2324import javax .net .ssl .SSLContext ;
2425import javax .net .ssl .SSLEngine ;
26+ import javax .net .ssl .SSLParameters ;
2527
2628/**
2729 * An SSL engine factory that allows you to configure the driver programmatically, by passing your
2830 * own {@link SSLContext}.
2931 *
30- * <p>Unlike the configuration-based approach, this class does not allow you to customize cipher
31- * suites, or turn on host name validation. Also, note that it will create SSL engines with advisory
32- * peer information ({@link SSLContext#createSSLEngine(String, int)}) whenever possible.
32+ * <p>Note that this class will create SSL engines with advisory peer information ({@link
33+ * SSLContext#createSSLEngine(String, int)}) whenever possible.
3334 *
3435 * <p>If those defaults do not work for you, it should be pretty straightforward to write your own
3536 * implementation by extending or duplicating this class.
4041public class ProgrammaticSslEngineFactory implements SslEngineFactory {
4142
4243 protected final SSLContext sslContext ;
44+ protected final String [] cipherSuites ;
45+ protected final boolean requireHostnameValidation ;
4346
44- public ProgrammaticSslEngineFactory (SSLContext sslContext ) {
47+ /**
48+ * Creates an instance with the given {@link SSLContext}, default cipher suites and no host name
49+ * validation.
50+ *
51+ * @param sslContext the {@link SSLContext} to use.
52+ */
53+ public ProgrammaticSslEngineFactory (@ NonNull SSLContext sslContext ) {
54+ this (sslContext , null );
55+ }
56+
57+ /**
58+ * Creates an instance with the given {@link SSLContext} and cipher suites, and no host name
59+ * validation.
60+ *
61+ * @param sslContext the {@link SSLContext} to use.
62+ * @param cipherSuites the cipher suites to use, or null to use the default ones.
63+ */
64+ public ProgrammaticSslEngineFactory (
65+ @ NonNull SSLContext sslContext , @ Nullable String [] cipherSuites ) {
66+ this (sslContext , cipherSuites , false );
67+ }
68+
69+ /**
70+ * Creates an instance with the given {@link SSLContext}, cipher suites and host name validation.
71+ *
72+ * @param sslContext the {@link SSLContext} to use.
73+ * @param cipherSuites the cipher suites to use, or null to use the default ones.
74+ * @param requireHostnameValidation whether to enable host name validation. If enabled, host name
75+ * validation will be done using HTTPS algorithm.
76+ */
77+ public ProgrammaticSslEngineFactory (
78+ @ NonNull SSLContext sslContext ,
79+ @ Nullable String [] cipherSuites ,
80+ boolean requireHostnameValidation ) {
4581 this .sslContext = sslContext ;
82+ this .cipherSuites = cipherSuites ;
83+ this .requireHostnameValidation = requireHostnameValidation ;
4684 }
4785
4886 @ NonNull
@@ -57,6 +95,14 @@ public SSLEngine newSslEngine(@NonNull EndPoint remoteEndpoint) {
5795 engine = sslContext .createSSLEngine ();
5896 }
5997 engine .setUseClientMode (true );
98+ if (cipherSuites != null ) {
99+ engine .setEnabledCipherSuites (cipherSuites );
100+ }
101+ if (requireHostnameValidation ) {
102+ SSLParameters parameters = engine .getSSLParameters ();
103+ parameters .setEndpointIdentificationAlgorithm ("HTTPS" );
104+ engine .setSSLParameters (parameters );
105+ }
60106 return engine ;
61107 }
62108
0 commit comments