6262import javax .security .auth .login .AppConfigurationEntry .LoginModuleControlFlag ;
6363import java .io .IOException ;
6464import java .net .InetSocketAddress ;
65- import java .net .UnknownHostException ;
6665import java .security .KeyStore ;
6766
6867import java .util .ArrayList ;
6968import java .util .Arrays ;
7069import java .util .HashMap ;
7170import java .util .List ;
7271import java .util .Map ;
72+ import java .util .Set ;
73+ import java .util .stream .Collectors ;
7374
7475public class SecurityUtils {
7576 private static final Logger LOG = LoggerFactory .getLogger (SecurityUtils .class );
@@ -278,17 +279,32 @@ public static TServerSocket getServerSocket(String hiveHost, int portNum) throws
278279 return new TServerSocket (serverAddress );
279280 }
280281
282+ private static TSSLTransportFactory .TSSLTransportParameters getSSLTransportParameters (boolean isKeyStore ,
283+ String storePath , String storePassword , String storeAlgorithm , String storeType , String [] cipherSuites ) {
284+ TSSLTransportFactory .TSSLTransportParameters params ;
285+ if (cipherSuites .length > 0 ) {
286+ params = new TSSLTransportFactory .TSSLTransportParameters ("TLS" , cipherSuites );
287+ } else {
288+ params = new TSSLTransportFactory .TSSLTransportParameters ();
289+ }
290+ if (isKeyStore ) {
291+ params .setKeyStore (storePath , storePassword , storeAlgorithm , storeType );
292+ } else {
293+ params .setTrustStore (storePath , storePassword , storeAlgorithm , storeType );
294+ params .requireClientAuth (true );
295+ }
296+ return params ;
297+ }
298+
281299 public static TServerSocket getServerSSLSocket (String hiveHost , int portNum , String keyStorePath ,
282- String keyStorePassWord , String keyStoreType , String keyStoreAlgorithm , List <String > sslVersionBlacklist )
283- throws TTransportException , UnknownHostException {
284- TSSLTransportFactory .TSSLTransportParameters params =
285- new TSSLTransportFactory .TSSLTransportParameters ();
286- String kStoreType = keyStoreType .isEmpty ()? KeyStore .getDefaultType () : keyStoreType ;
287- String kStoreAlgorithm = keyStoreAlgorithm .isEmpty ()?
288- KeyManagerFactory .getDefaultAlgorithm () : keyStoreAlgorithm ;
289- params .setKeyStore (keyStorePath , keyStorePassWord , kStoreAlgorithm , kStoreType );
300+ String keyStorePassWord , String keyStoreType , String keyStoreAlgorithm , List <String > sslVersionBlacklist ,
301+ String [] includeProtocols , String [] cipherSuites ) throws TTransportException {
302+ TSSLTransportFactory .TSSLTransportParameters params = getSSLTransportParameters (true ,
303+ keyStorePath , keyStorePassWord ,
304+ keyStoreAlgorithm .isEmpty () ? KeyManagerFactory .getDefaultAlgorithm () : keyStoreAlgorithm ,
305+ keyStoreType .isEmpty () ? KeyStore .getDefaultType () : keyStoreType , cipherSuites );
290306 InetSocketAddress serverAddress ;
291- if (hiveHost == null || hiveHost .isEmpty ()) {
307+ if (StringUtils .isEmpty (hiveHost )) {
292308 // Wildcard bind
293309 serverAddress = new InetSocketAddress (portNum );
294310 } else {
@@ -303,14 +319,20 @@ public static TServerSocket getServerSSLSocket(String hiveHost, int portNum, Str
303319 }
304320 SSLServerSocket sslServerSocket = (SSLServerSocket ) thriftServerSocket .getServerSocket ();
305321 List <String > enabledProtocols = new ArrayList <>();
306- for (String protocol : sslServerSocket .getEnabledProtocols ()) {
322+ for (String protocol : sslServerSocket .getSupportedProtocols ()) {
307323 if (sslVersionBlacklistLocal .contains (protocol .toLowerCase ())) {
308324 LOG .debug ("Disabling SSL Protocol: " + protocol );
309325 } else {
310326 enabledProtocols .add (protocol );
311327 }
312328 }
313- sslServerSocket .setEnabledProtocols (enabledProtocols .toArray (new String [0 ]));
329+ if (includeProtocols .length > 0 ) {
330+ Set <String > includeProtocolsLowerCase = Arrays .stream (includeProtocols ).map (String ::toLowerCase )
331+ .collect (Collectors .toSet ());
332+ enabledProtocols = enabledProtocols .stream ()
333+ .filter (protocol -> includeProtocolsLowerCase .contains (protocol .toLowerCase ())).toList ();
334+ }
335+ sslServerSocket .setEnabledProtocols (enabledProtocols .toArray (String []::new ));
314336 LOG .info ("SSL Server Socket Enabled Protocols: "
315337 + Arrays .toString (sslServerSocket .getEnabledProtocols ()));
316338 }
@@ -319,18 +341,23 @@ public static TServerSocket getServerSSLSocket(String hiveHost, int portNum, Str
319341
320342 public static TTransport getSSLSocket (String host , int port , int socketTimeout , int connectionTimeout ,
321343 String trustStorePath , String trustStorePassWord , String trustStoreType ,
322- String trustStoreAlgorithm ) throws TTransportException {
323- TSSLTransportFactory .TSSLTransportParameters params =
324- new TSSLTransportFactory .TSSLTransportParameters ();
325- String tStoreType = trustStoreType .isEmpty ()? KeyStore .getDefaultType () : trustStoreType ;
326- String tStoreAlgorithm = trustStoreAlgorithm .isEmpty ()?
327- TrustManagerFactory .getDefaultAlgorithm () : trustStoreAlgorithm ;
328- params .setTrustStore (trustStorePath , trustStorePassWord ,
329- tStoreAlgorithm , tStoreType );
330- params .requireClientAuth (true );
344+ String trustStoreAlgorithm , String [] includeProtocols , String [] cipherSuites ) throws TTransportException {
345+ TSSLTransportFactory .TSSLTransportParameters params = getSSLTransportParameters (false ,
346+ trustStorePath , trustStorePassWord ,
347+ trustStoreAlgorithm .isEmpty () ? TrustManagerFactory .getDefaultAlgorithm () : trustStoreAlgorithm ,
348+ trustStoreType .isEmpty () ? KeyStore .getDefaultType () : trustStoreType ,
349+ cipherSuites );
331350 // The underlying SSLSocket object is bound to host:port with the given SO_TIMEOUT and
332351 // connection timeout and SSLContext created with the given params
333352 TSocket tSSLSocket = TSSLTransportFactory .getClientSocket (host , port , socketTimeout , params );
353+ if (includeProtocols .length > 0 ) {
354+ SSLSocket sslSocket = (SSLSocket ) (tSSLSocket .getSocket ());
355+ Set <String > includeProtocolsLowerCase = Arrays .stream (includeProtocols ).map (String ::toLowerCase )
356+ .collect (Collectors .toSet ());
357+ String [] enabledProtocols = Arrays .stream (sslSocket .getSupportedProtocols ())
358+ .filter (protocol -> includeProtocolsLowerCase .contains (protocol .toLowerCase ())).toArray (String []::new );
359+ sslSocket .setEnabledProtocols (enabledProtocols );
360+ }
334361 tSSLSocket .setConnectTimeout (connectionTimeout );
335362 return getSSLSocketWithHttps (tSSLSocket );
336363 }
@@ -341,13 +368,17 @@ public static TTransport getSSLSocket(String host, int port, int socketTimeout,
341368 */
342369 public static THttpClient getThriftHttpsClient (String httpsUrl , String trustStorePath ,
343370 String trustStorePasswd , String trustStoreAlgorithm , String trustStoreType ,
371+ String [] includeProtocols , String [] cipherSuites ,
344372 HttpClientBuilder underlyingHttpClientBuilder ) throws TTransportException , IOException ,
345373 KeyStoreException , NoSuchAlgorithmException , CertificateException ,
346374 KeyManagementException {
347375 Preconditions .checkNotNull (underlyingHttpClientBuilder , "httpClientBuilder should not be null" );
348376 if (trustStoreType == null || trustStoreType .isEmpty ()) {
349377 trustStoreType = KeyStore .getDefaultType ();
350378 }
379+ if (trustStoreAlgorithm .isEmpty ()) {
380+ trustStoreAlgorithm = TrustManagerFactory .getDefaultAlgorithm ();
381+ }
351382 KeyStore sslTrustStore = KeyStore .getInstance (trustStoreType );
352383 try (FileInputStream fis = new FileInputStream (trustStorePath )) {
353384 sslTrustStore .load (fis , trustStorePasswd .toCharArray ());
@@ -356,8 +387,16 @@ public static THttpClient getThriftHttpsClient(String httpsUrl, String trustStor
356387 SSLContext sslContext =
357388 SSLContexts .custom ().setTrustManagerFactoryAlgorithm (trustStoreAlgorithm ).
358389 loadTrustMaterial (sslTrustStore , null ).build ();
390+ String [] protocols = null ;
391+ String [] ciphers = null ;
392+ if (includeProtocols .length > 0 ) {
393+ protocols = includeProtocols ;
394+ }
395+ if (cipherSuites .length > 0 ) {
396+ ciphers = cipherSuites ;
397+ }
359398 SSLConnectionSocketFactory socketFactory =
360- new SSLConnectionSocketFactory (sslContext , new DefaultHostnameVerifier (null ));
399+ new SSLConnectionSocketFactory (sslContext , protocols , ciphers , new DefaultHostnameVerifier (null ));
361400 final Registry <ConnectionSocketFactory > registry =
362401 RegistryBuilder .<ConnectionSocketFactory > create ().register ("https" , socketFactory )
363402 .build ();
0 commit comments