Skip to content

Commit 8cdeb5e

Browse files
authored
chore: update apache http transports to use default jdk certs (#2616)
* chore: update apahce http transport clients to use default jdk certs * fix typo * fix formatting * added back missing java doc * fixed formatting and added additional test * added IT tests for apache http transport * move documentation update to separate PR
1 parent 857362a commit 8cdeb5e

File tree

4 files changed

+143
-31
lines changed

4 files changed

+143
-31
lines changed

google-api-client-apache-v5/src/main/java/com/google/api/client/googleapis/apache/v5/GoogleApache5HttpTransport.java

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@
1414

1515
package com.google.api.client.googleapis.apache.v5;
1616

17-
import com.google.api.client.googleapis.GoogleUtils;
1817
import com.google.api.client.googleapis.mtls.MtlsProvider;
1918
import com.google.api.client.googleapis.mtls.MtlsUtils;
20-
import com.google.api.client.googleapis.util.Utils;
2119
import com.google.api.client.http.apache.v5.Apache5HttpTransport;
2220
import com.google.api.client.util.SslUtils;
2321
import com.google.common.annotations.Beta;
@@ -48,11 +46,11 @@
4846
public final class GoogleApache5HttpTransport {
4947

5048
/**
51-
* Returns a new instance of {@link Apache5HttpTransport} that uses {@link
52-
* GoogleUtils#getCertificateTrustStore()} for the trusted certificates. If
53-
* `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true", and the default
54-
* client certificate key store from {@link Utils#loadDefaultMtlsKeyStore()} is not null, then the
55-
* transport uses the default client certificate and is mutual TLS.
49+
* Returns a new instance of {@link Apache5HttpTransport} that uses default jdk certificates for
50+
* the trusted certificates. If `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to
51+
* "true", and the default client certificate key store from {@link
52+
* Utils#loadDefaultMtlsKeyStore()} is not null, then the transport uses the default client
53+
* certificate and is mutual TLS.
5654
*/
5755
public static Apache5HttpTransport newTrustedTransport()
5856
throws GeneralSecurityException, IOException {
@@ -61,9 +59,8 @@ public static Apache5HttpTransport newTrustedTransport()
6159

6260
/**
6361
* {@link Beta} <br>
64-
* Returns a new instance of {@link Apache5HttpTransport} that uses {@link
65-
* GoogleUtils#getCertificateTrustStore()} for the trusted certificates. mtlsProvider can be used
66-
* to configure mutual TLS for the transport.
62+
* Returns a new instance of {@link Apache5HttpTransport} that uses default jdk certificates for
63+
* the trusted certificates. mtlsProvider can be used to configure mutual TLS for the transport.
6764
*
6865
* @param mtlsProvider MtlsProvider to configure mutual TLS for the transport
6966
*/
@@ -109,22 +106,20 @@ public SocketFactoryRegistryHandler(MtlsProvider mtlsProvider)
109106
mtlsKeyStorePassword = mtlsProvider.getKeyStorePassword();
110107
}
111108

112-
// Use the included trust store
113-
KeyStore trustStore = GoogleUtils.getCertificateTrustStore();
114109
SSLContext sslContext = SslUtils.getTlsSslContext();
115110

116111
if (mtlsKeyStore != null && mtlsKeyStorePassword != null) {
117112
this.isMtls = true;
118113
SslUtils.initSslContext(
119114
sslContext,
120-
trustStore,
115+
null,
121116
SslUtils.getPkixTrustManagerFactory(),
122117
mtlsKeyStore,
123118
mtlsKeyStorePassword,
124119
SslUtils.getDefaultKeyManagerFactory());
125120
} else {
126121
this.isMtls = false;
127-
SslUtils.initSslContext(sslContext, trustStore, SslUtils.getPkixTrustManagerFactory());
122+
SslUtils.initSslContext(sslContext, null, SslUtils.getPkixTrustManagerFactory());
128123
}
129124
LayeredConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
130125

google-api-client-apache-v5/src/test/java/com/google/api/client/googleapis/apache/v5/ITGoogleApache5HttpTransportTest.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@
3030
public class ITGoogleApache5HttpTransportTest {
3131

3232
@Test
33-
public void testHttpRequestFailsWhenMakingRequestToSiteWithoutGoogleCerts()
33+
public void testHttpRequestFailsWhenMakingRequestToSiteWithoutDefaultJdkCerts()
3434
throws GeneralSecurityException, IOException {
3535
Apache5HttpTransport apache5HttpTransport = GoogleApache5HttpTransport.newTrustedTransport();
36-
HttpGet httpGet = new HttpGet("https://maven.com/");
36+
// Use a self-signed certificate site that won't be trusted by default trust store
37+
HttpGet httpGet = new HttpGet("https://self-signed.badssl.com/");
3738
Exception exception = null;
3839
try {
3940
apache5HttpTransport
@@ -43,7 +44,7 @@ public void testHttpRequestFailsWhenMakingRequestToSiteWithoutGoogleCerts()
4344
new HttpClientResponseHandler<Void>() {
4445
@Override
4546
public Void handleResponse(ClassicHttpResponse response) {
46-
fail("Should not have been able to complete SSL request on non google site.");
47+
fail("Should not have been able to complete SSL request with untrusted cert.");
4748
return null;
4849
}
4950
});
@@ -73,4 +74,23 @@ public Void handleResponse(ClassicHttpResponse response) {
7374
}
7475
});
7576
}
77+
78+
@Test
79+
public void testHttpRequestPassesWhenMakingRequestToSiteContainedInDefaultCerts()
80+
throws Exception {
81+
Apache5HttpTransport apache5HttpTransport = GoogleApache5HttpTransport.newTrustedTransport();
82+
HttpGet httpGet = new HttpGet("https://central.sonatype.com/");
83+
84+
apache5HttpTransport
85+
.getHttpClient()
86+
.execute(
87+
httpGet,
88+
new HttpClientResponseHandler<Void>() {
89+
@Override
90+
public Void handleResponse(ClassicHttpResponse response) {
91+
assertEquals(200, response.getCode());
92+
return null;
93+
}
94+
});
95+
}
7696
}

google-api-client/src/main/java/com/google/api/client/googleapis/apache/v2/GoogleApacheHttpTransport.java

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@
1414

1515
package com.google.api.client.googleapis.apache.v2;
1616

17-
import com.google.api.client.googleapis.GoogleUtils;
1817
import com.google.api.client.googleapis.mtls.MtlsProvider;
1918
import com.google.api.client.googleapis.mtls.MtlsUtils;
20-
import com.google.api.client.googleapis.util.Utils;
2119
import com.google.api.client.http.apache.v2.ApacheHttpTransport;
2220
import com.google.api.client.util.Beta;
2321
import com.google.api.client.util.SslUtils;
@@ -47,11 +45,11 @@
4745
public final class GoogleApacheHttpTransport {
4846

4947
/**
50-
* Returns a new instance of {@link ApacheHttpTransport} that uses {@link
51-
* GoogleUtils#getCertificateTrustStore()} for the trusted certificates. If
52-
* `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true", and the default
53-
* client certificate key store from {@link Utils#loadDefaultMtlsKeyStore()} is not null, then the
54-
* transport uses the default client certificate and is mutual TLS.
48+
* Returns a new instance of {@link ApacheHttpTransport} that uses default jdk certificates for
49+
* the trusted certificates. If `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to
50+
* "true", and the default client certificate key store from {@link
51+
* Utils#loadDefaultMtlsKeyStore()} is not null, then the transport uses the default client
52+
* certificate and is mutual TLS.
5553
*/
5654
public static ApacheHttpTransport newTrustedTransport()
5755
throws GeneralSecurityException, IOException {
@@ -60,9 +58,8 @@ public static ApacheHttpTransport newTrustedTransport()
6058

6159
/**
6260
* {@link Beta} <br>
63-
* Returns a new instance of {@link ApacheHttpTransport} that uses {@link
64-
* GoogleUtils#getCertificateTrustStore()} for the trusted certificates. mtlsProvider can be used
65-
* to configure mutual TLS for the transport.
61+
* Returns a new instance of {@link ApacheHttpTransport} that default jdk certs for the trusted
62+
* certificates. mtlsProvider can be used to configure mutual TLS for the transport.
6663
*
6764
* @param mtlsProvider MtlsProvider to configure mutual TLS for the transport
6865
*/
@@ -105,22 +102,20 @@ public SocketFactoryRegistryHandler(MtlsProvider mtlsProvider)
105102
mtlsKeyStorePassword = mtlsProvider.getKeyStorePassword();
106103
}
107104

108-
// Use the included trust store
109-
KeyStore trustStore = GoogleUtils.getCertificateTrustStore();
110105
SSLContext sslContext = SslUtils.getTlsSslContext();
111106

112107
if (mtlsKeyStore != null && mtlsKeyStorePassword != null) {
113108
this.isMtls = true;
114109
SslUtils.initSslContext(
115110
sslContext,
116-
trustStore,
111+
null,
117112
SslUtils.getPkixTrustManagerFactory(),
118113
mtlsKeyStore,
119114
mtlsKeyStorePassword,
120115
SslUtils.getDefaultKeyManagerFactory());
121116
} else {
122117
this.isMtls = false;
123-
SslUtils.initSslContext(sslContext, trustStore, SslUtils.getPkixTrustManagerFactory());
118+
SslUtils.initSslContext(sslContext, null, SslUtils.getPkixTrustManagerFactory());
124119
}
125120
LayeredConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
126121

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License
10+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11+
* or implied. See the License for the specific language governing permissions and limitations under
12+
* the License.
13+
*/
14+
15+
package com.google.api.client.googleapis.apache.v2;
16+
17+
import static org.junit.Assert.assertEquals;
18+
import static org.junit.Assert.assertNotNull;
19+
import static org.junit.Assert.fail;
20+
21+
import com.google.api.client.http.apache.v2.ApacheHttpTransport;
22+
import java.io.IOException;
23+
import java.security.GeneralSecurityException;
24+
import javax.net.ssl.SSLHandshakeException;
25+
import org.apache.http.HttpResponse;
26+
import org.apache.http.client.ClientProtocolException;
27+
import org.apache.http.client.ResponseHandler;
28+
import org.apache.http.client.methods.HttpGet;
29+
import org.junit.Test;
30+
31+
public class ITGoogleApacheHttpTransportTest {
32+
33+
@Test
34+
public void testHttpRequestFailsWhenMakingRequestToSiteWithoutDefaultJdkCerts()
35+
throws GeneralSecurityException, IOException {
36+
ApacheHttpTransport apacheHttpTransport = GoogleApacheHttpTransport.newTrustedTransport();
37+
// Use a self-signed certificate site that won't be trusted by default trust store
38+
HttpGet httpGet = new HttpGet("https://self-signed.badssl.com/");
39+
Exception exception = null;
40+
try {
41+
apacheHttpTransport
42+
.getHttpClient()
43+
.execute(
44+
httpGet,
45+
new ResponseHandler<Object>() {
46+
47+
@Override
48+
public Object handleResponse(HttpResponse httpResponse)
49+
throws ClientProtocolException, IOException {
50+
fail("Should not have been able to complete SSL request with untrusted cert.");
51+
return null;
52+
}
53+
});
54+
fail("Expected SSLHandshakeException was not thrown");
55+
} catch (SSLHandshakeException e) {
56+
exception = e;
57+
}
58+
59+
assertNotNull(exception);
60+
assertEquals(exception.getClass(), SSLHandshakeException.class);
61+
}
62+
63+
@Test
64+
public void testHttpRequestPassesWhenMakingRequestToGoogleSite() throws Exception {
65+
ApacheHttpTransport apacheHttpTransport = GoogleApacheHttpTransport.newTrustedTransport();
66+
HttpGet httpGet = new HttpGet("https://www.google.com/");
67+
68+
apacheHttpTransport
69+
.getHttpClient()
70+
.execute(
71+
httpGet,
72+
new ResponseHandler<Object>() {
73+
@Override
74+
public Object handleResponse(HttpResponse httpResponse)
75+
throws ClientProtocolException, IOException {
76+
assertEquals(200, httpResponse.getStatusLine().getStatusCode());
77+
return null;
78+
}
79+
});
80+
}
81+
82+
@Test
83+
public void testHttpRequestPassesWhenMakingRequestToSiteContainedInDefaultCerts()
84+
throws Exception {
85+
86+
ApacheHttpTransport apacheHttpTransport = GoogleApacheHttpTransport.newTrustedTransport();
87+
HttpGet httpGet = new HttpGet("https://central.sonatype.com/");
88+
89+
apacheHttpTransport
90+
.getHttpClient()
91+
.execute(
92+
httpGet,
93+
new ResponseHandler<Object>() {
94+
@Override
95+
public Object handleResponse(HttpResponse httpResponse)
96+
throws ClientProtocolException, IOException {
97+
assertEquals(200, httpResponse.getStatusLine().getStatusCode());
98+
return null;
99+
}
100+
});
101+
}
102+
}

0 commit comments

Comments
 (0)