1818
1919import static com .google .cloud .bigquery .storage .v1 .stub .BigQueryReadStubSettings .defaultGrpcTransportProviderBuilder ;
2020
21- import com .google .api .client .googleapis .GoogleUtils ;
2221import com .google .api .client .http .HttpTransport ;
2322import com .google .api .client .http .apache .v5 .Apache5HttpTransport ;
2423import com .google .api .client .http .javanet .NetHttpTransport ;
3736import java .net .SocketAddress ;
3837import java .security .GeneralSecurityException ;
3938import java .security .KeyStore ;
40- import java .security .cert .CertificateException ;
41- import java .security .cert .X509Certificate ;
4239import java .util .HashMap ;
4340import java .util .Map ;
4441import java .util .regex .Pattern ;
4542import javax .net .ssl .SSLContext ;
46- import javax .net .ssl .TrustManager ;
4743import javax .net .ssl .TrustManagerFactory ;
48- import javax .net .ssl .X509TrustManager ;
4944import org .apache .hc .client5 .http .auth .AuthScope ;
5045import org .apache .hc .client5 .http .auth .UsernamePasswordCredentials ;
5146import org .apache .hc .client5 .http .impl .DefaultAuthenticationStrategy ;
@@ -149,20 +144,10 @@ static HttpTransportOptions getHttpTransportOptions(
149144 getHttpTransportFactory (
150145 proxyProperties , sslTrustStorePath , sslTrustStorePassword , callerClassName ));
151146 } else {
152- // Default to NetHttpTransport configured with a MergedTrustManager that trusts
153- // both the JVM's default trust store and Google's bundled certificate store .
147+ // Default to NetHttpTransport which automatically respects the JVM's default trust store
148+ // (cacerts or javax.net.ssl.trustStore) .
154149 httpTransportOptionsBuilder .setHttpTransportFactory (
155- () -> {
156- try {
157- SSLContext sslContext = createMergedSslContext ();
158- return new NetHttpTransport .Builder ()
159- .setSslSocketFactory (sslContext .getSocketFactory ())
160- .build ();
161- } catch (GeneralSecurityException | IOException e ) {
162- throw new BigQueryJdbcRuntimeException (
163- "Failed to configure SSL for HTTP transport" , e );
164- }
165- });
150+ () -> new NetHttpTransport .Builder ().build ());
166151 }
167152
168153 if (connectTimeout != null ) {
@@ -193,10 +178,8 @@ private static HttpTransportFactory getHttpTransportFactory(
193178 proxyProperties .get (BigQueryJdbcUrlUtility .PROXY_PORT_PROPERTY_NAME )));
194179 HttpRoutePlanner httpRoutePlanner = new DefaultProxyRoutePlanner (proxyHostDetails );
195180 httpClientBuilder .setRoutePlanner (httpRoutePlanner );
196- addAuthToProxyIfPresent (proxyProperties , httpClientBuilder , callerClassName );
197- } else {
198- httpClientBuilder .useSystemProperties ();
199181 }
182+ httpClientBuilder .useSystemProperties ();
200183
201184 if (sslTrustStorePath != null ) {
202185 try (FileInputStream trustStoreStream = new FileInputStream (sslTrustStorePath )) {
@@ -212,19 +195,15 @@ private static HttpTransportFactory getHttpTransportFactory(
212195 SSLContext sslContext = SSLContext .getInstance ("TLS" );
213196 sslContext .init (null , trustManagerFactory .getTrustManagers (), null );
214197
215- setSslSocketFactory (httpClientBuilder , sslContext );
198+ SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory (sslContext );
199+ httpClientBuilder .setConnectionManager (
200+ PoolingHttpClientConnectionManagerBuilder .create ()
201+ .setSSLSocketFactory (sslSocketFactory )
202+ .build ());
216203 } catch (IOException | GeneralSecurityException e ) {
217204 throw new BigQueryJdbcRuntimeException (
218205 "Failed to configure SSL TrustStore for HTTP transport" , e );
219206 }
220- } else {
221- // Default to MergedTrustManager when no custom SSLTrustStore is specified, ensuring standard
222- // JVM properties (like javax.net.ssl.trustStore) and google.p12 fallback are respected.
223- try {
224- setSslSocketFactory (httpClientBuilder , createMergedSslContext ());
225- } catch (IOException | GeneralSecurityException e ) {
226- throw new BigQueryJdbcRuntimeException ("Failed to configure SSL for HTTP transport" , e );
227- }
228207 }
229208 addAuthToProxyIfPresent (proxyProperties , httpClientBuilder , callerClassName );
230209
@@ -338,91 +317,4 @@ private static HttpConnectProxiedSocketAddress getHttpConnectProxiedSocketAddres
338317 }
339318 return builder .build ();
340319 }
341-
342- private static SSLContext createMergedSslContext () throws GeneralSecurityException , IOException {
343- SSLContext sslContext = SSLContext .getInstance ("TLS" );
344- sslContext .init (null , new TrustManager [] {createMergedTrustManager ()}, null );
345- return sslContext ;
346- }
347-
348- private static void setSslSocketFactory (
349- HttpClientBuilder httpClientBuilder , SSLContext sslContext ) {
350- SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory (sslContext );
351- httpClientBuilder .setConnectionManager (
352- PoolingHttpClientConnectionManagerBuilder .create ()
353- .setSSLSocketFactory (sslSocketFactory )
354- .build ());
355- }
356-
357- private static X509TrustManager createMergedTrustManager ()
358- throws GeneralSecurityException , IOException {
359- // 1. Get default JVM TrustManager
360- TrustManagerFactory defaultTmf =
361- TrustManagerFactory .getInstance (TrustManagerFactory .getDefaultAlgorithm ());
362- defaultTmf .init ((KeyStore ) null );
363- X509TrustManager defaultTm = findX509TrustManager (defaultTmf );
364-
365- // 2. Get Google TrustManager
366- KeyStore googleKeystore = GoogleUtils .getCertificateTrustStore ();
367- TrustManagerFactory googleTmf =
368- TrustManagerFactory .getInstance (TrustManagerFactory .getDefaultAlgorithm ());
369- googleTmf .init (googleKeystore );
370- X509TrustManager googleTm = findX509TrustManager (googleTmf );
371-
372- if (defaultTm == null || googleTm == null ) {
373- throw new IllegalStateException ("Could not find X509TrustManager" );
374- }
375-
376- return new MergedTrustManager (defaultTm , googleTm );
377- }
378-
379- private static X509TrustManager findX509TrustManager (TrustManagerFactory tmf ) {
380- for (TrustManager tm : tmf .getTrustManagers ()) {
381- if (tm instanceof X509TrustManager ) {
382- return (X509TrustManager ) tm ;
383- }
384- }
385- return null ;
386- }
387-
388- private static class MergedTrustManager implements X509TrustManager {
389- private final X509TrustManager defaultTm ;
390- private final X509TrustManager googleTm ;
391-
392- public MergedTrustManager (X509TrustManager defaultTm , X509TrustManager googleTm ) {
393- this .defaultTm = defaultTm ;
394- this .googleTm = googleTm ;
395- }
396-
397- @ Override
398- public X509Certificate [] getAcceptedIssuers () {
399- X509Certificate [] defaultIssuers = defaultTm .getAcceptedIssuers ();
400- X509Certificate [] googleIssuers = googleTm .getAcceptedIssuers ();
401- X509Certificate [] result = new X509Certificate [defaultIssuers .length + googleIssuers .length ];
402- System .arraycopy (defaultIssuers , 0 , result , 0 , defaultIssuers .length );
403- System .arraycopy (googleIssuers , 0 , result , defaultIssuers .length , googleIssuers .length );
404- return result ;
405- }
406-
407- @ Override
408- public void checkClientTrusted (X509Certificate [] chain , String authType )
409- throws CertificateException {
410- try {
411- defaultTm .checkClientTrusted (chain , authType );
412- } catch (CertificateException e ) {
413- googleTm .checkClientTrusted (chain , authType );
414- }
415- }
416-
417- @ Override
418- public void checkServerTrusted (X509Certificate [] chain , String authType )
419- throws CertificateException {
420- try {
421- defaultTm .checkServerTrusted (chain , authType );
422- } catch (CertificateException e ) {
423- // Fall back to Google's trusted certs
424- googleTm .checkServerTrusted (chain , authType );
425- }
426- }
427- }
428320}
0 commit comments