Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add mtls support to GoogleNetHttpTransport and GoogleApacheHttpTransport #1619

Merged
merged 33 commits into from Nov 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4205102
feat: add mtls support
arithmetic1728 Oct 23, 2020
fa08020
add run cert command
arithmetic1728 Oct 27, 2020
b2d8891
javanet
arithmetic1728 Oct 30, 2020
c7a0e71
Merge branch 'master' of https://github.com/googleapis/google-api-jav…
arithmetic1728 Oct 30, 2020
79e9ac1
add apache
arithmetic1728 Oct 30, 2020
f860389
update
arithmetic1728 Oct 30, 2020
43655ab
fix test
arithmetic1728 Oct 30, 2020
2849ee7
tmp
arithmetic1728 Oct 30, 2020
46d8973
fix
arithmetic1728 Oct 30, 2020
5e063b3
added tests
arithmetic1728 Oct 31, 2020
dceaacf
add apache
arithmetic1728 Oct 31, 2020
0f4f878
finished apache
arithmetic1728 Oct 31, 2020
9e33fac
doc string
arithmetic1728 Nov 1, 2020
547a6c5
Merge branch 'master' of https://github.com/googleapis/google-api-jav…
arithmetic1728 Nov 4, 2020
0442025
update code
arithmetic1728 Nov 4, 2020
d83c115
lint
arithmetic1728 Nov 4, 2020
d92d3b3
refactor: implement MtlsUtils.MtlsProvider interface with default imp…
chingor13 Nov 5, 2020
aa72510
Merge pull request #1 from chingor13/mtls-refactor
arithmetic1728 Nov 5, 2020
05e052c
refactor mtls to a module
arithmetic1728 Nov 5, 2020
312e73a
rename
arithmetic1728 Nov 5, 2020
5209bec
fix exceptions
arithmetic1728 Nov 5, 2020
1edf060
add timeout
arithmetic1728 Nov 6, 2020
daeb967
fix util test
arithmetic1728 Nov 6, 2020
a3cea68
Merge pull request #3 from arithmetic1728/refactor
arithmetic1728 Nov 6, 2020
377f944
add tests
arithmetic1728 Nov 6, 2020
533c76e
lint
arithmetic1728 Nov 6, 2020
9ad39a5
make constructor public
arithmetic1728 Nov 6, 2020
47f8c07
lint
arithmetic1728 Nov 6, 2020
7bf8d8c
make constructor public
arithmetic1728 Nov 6, 2020
55d4eb5
update
arithmetic1728 Nov 9, 2020
46dd6b8
use bigger try catch block
arithmetic1728 Nov 9, 2020
9eee919
update code
arithmetic1728 Nov 10, 2020
5593a90
Update google-api-client/src/main/java/com/google/api/client/googleap…
arithmetic1728 Nov 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -15,7 +15,11 @@
package com.google.api.client.googleapis.apache.v2;

import com.google.api.client.googleapis.GoogleUtils;
import com.google.api.client.googleapis.mtls.MtlsProvider;
import com.google.api.client.googleapis.mtls.MtlsUtils;
import com.google.api.client.googleapis.util.Utils;
import com.google.api.client.http.apache.v2.ApacheHttpTransport;
import com.google.api.client.util.Beta;
import com.google.api.client.util.SslUtils;
import java.io.IOException;
import java.net.ProxySelector;
Expand All @@ -24,7 +28,6 @@
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import org.apache.http.client.HttpClient;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
Expand All @@ -39,11 +42,35 @@
public final class GoogleApacheHttpTransport {

/**
* Returns a new instance of {@link ApacheHttpTransport} that uses
* {@link GoogleUtils#getCertificateTrustStore()} for the trusted certificates.
* Returns a new instance of {@link ApacheHttpTransport} that uses {@link
* GoogleUtils#getCertificateTrustStore()} for the trusted certificates. If
* `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true", and the default
* client certificate key store from {@link Utils#loadDefaultMtlsKeyStore()} is not null, then the
* transport uses the default client certificate and is mutual TLS.
*/
public static ApacheHttpTransport newTrustedTransport() throws GeneralSecurityException,
IOException {
public static ApacheHttpTransport newTrustedTransport()
throws GeneralSecurityException, IOException {
return newTrustedTransport(MtlsUtils.getDefaultMtlsProvider());
}

/**
* {@link Beta} <br>
* Returns a new instance of {@link ApacheHttpTransport} that uses {@link
* GoogleUtils#getCertificateTrustStore()} for the trusted certificates. mtlsProvider can be used
* to configure mutual TLS for the transport.
*
* @param mtlsProvider MtlsProvider to configure mutual TLS for the transport
*/
@Beta
public static ApacheHttpTransport newTrustedTransport(MtlsProvider mtlsProvider)
throws GeneralSecurityException, IOException {
KeyStore mtlsKeyStore = null;
String mtlsKeyStorePassword = null;
if (mtlsProvider.useMtlsClientCertificate()) {
mtlsKeyStore = mtlsProvider.getKeyStore();
mtlsKeyStorePassword = mtlsProvider.getKeyStorePassword();
}

PoolingHttpClientConnectionManager connectionManager =
new PoolingHttpClientConnectionManager(-1, TimeUnit.MILLISECONDS);

Expand All @@ -53,22 +80,35 @@ public static ApacheHttpTransport newTrustedTransport() throws GeneralSecurityEx
// Use the included trust store
KeyStore trustStore = GoogleUtils.getCertificateTrustStore();
SSLContext sslContext = SslUtils.getTlsSslContext();
SslUtils.initSslContext(sslContext, trustStore, SslUtils.getPkixTrustManagerFactory());

boolean isMtls = false;
if (mtlsKeyStore != null && mtlsKeyStorePassword != null) {
isMtls = true;
SslUtils.initSslContext(
sslContext,
trustStore,
SslUtils.getPkixTrustManagerFactory(),
mtlsKeyStore,
mtlsKeyStorePassword,
SslUtils.getDefaultKeyManagerFactory());
} else {
SslUtils.initSslContext(sslContext, trustStore, SslUtils.getPkixTrustManagerFactory());
}
LayeredConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);

HttpClient client = HttpClientBuilder.create()
.useSystemProperties()
.setSSLSocketFactory(socketFactory)
.setMaxConnTotal(200)
.setMaxConnPerRoute(20)
.setRoutePlanner(new SystemDefaultRoutePlanner(ProxySelector.getDefault()))
.setConnectionManager(connectionManager)
.disableRedirectHandling()
.disableAutomaticRetries()
.build();
return new ApacheHttpTransport(client);
HttpClient client =
HttpClientBuilder.create()
.useSystemProperties()
.setSSLSocketFactory(socketFactory)
.setMaxConnTotal(200)
.setMaxConnPerRoute(20)
.setRoutePlanner(new SystemDefaultRoutePlanner(ProxySelector.getDefault()))
.setConnectionManager(connectionManager)
.disableRedirectHandling()
.disableAutomaticRetries()
.build();
return new ApacheHttpTransport(client, isMtls);
}

private GoogleApacheHttpTransport() {
}
private GoogleApacheHttpTransport() {}
}
Expand Up @@ -15,7 +15,11 @@
package com.google.api.client.googleapis.javanet;

import com.google.api.client.googleapis.GoogleUtils;
import com.google.api.client.googleapis.mtls.MtlsProvider;
import com.google.api.client.googleapis.mtls.MtlsUtils;
import com.google.api.client.googleapis.util.Utils;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.util.Beta;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
Expand All @@ -29,32 +33,60 @@
public class GoogleNetHttpTransport {

/**
* Returns a new instance of {@link NetHttpTransport} that uses
* {@link GoogleUtils#getCertificateTrustStore()} for the trusted certificates using
* {@link com.google.api.client.http.javanet.NetHttpTransport.Builder#trustCertificates(KeyStore)}
* .
* Returns a new instance of {@link NetHttpTransport} that uses {@link
* GoogleUtils#getCertificateTrustStore()} for the trusted certificates using {@link
* com.google.api.client.http.javanet.NetHttpTransport.Builder#trustCertificates(KeyStore)}. If
* `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true", and the default
* client certificate key store from {@link Utils#loadDefaultMtlsKeyStore()} is not null, then the
* transport uses the default client certificate and is mutual TLS.
*
* <p>
* This helper method doesn't provide for customization of the {@link NetHttpTransport}, such as
* the ability to specify a proxy. To do use, use
* {@link com.google.api.client.http.javanet.NetHttpTransport.Builder}, for example:
* </p>
* <p>This helper method doesn't provide for customization of the {@link NetHttpTransport}, such
* as the ability to specify a proxy. To do use, use {@link
* com.google.api.client.http.javanet.NetHttpTransport.Builder}, for example:
*
* <pre>
static HttpTransport newProxyTransport() throws GeneralSecurityException, IOException {
NetHttpTransport.Builder builder = new NetHttpTransport.Builder();
builder.trustCertificates(GoogleUtils.getCertificateTrustStore());
builder.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 3128)));
return builder.build();
}
* static HttpTransport newProxyTransport() throws GeneralSecurityException, IOException {
* NetHttpTransport.Builder builder = new NetHttpTransport.Builder();
* builder.trustCertificates(GoogleUtils.getCertificateTrustStore());
* builder.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 3128)));
* return builder.build();
* }
* </pre>
*/
public static NetHttpTransport newTrustedTransport()
throws GeneralSecurityException, IOException {
return new NetHttpTransport.Builder().trustCertificates(GoogleUtils.getCertificateTrustStore())
.build();
return newTrustedTransport(MtlsUtils.getDefaultMtlsProvider());
}

private GoogleNetHttpTransport() {
/**
* {@link Beta} <br>
* Returns a new instance of {@link NetHttpTransport} that uses {@link
* GoogleUtils#getCertificateTrustStore()} for the trusted certificates using {@link
* com.google.api.client.http.javanet.NetHttpTransport.Builder#trustCertificates(KeyStore)}.
* mtlsProvider can be used to configure mutual TLS for the transport.
*
* @param mtlsProvider MtlsProvider to configure mutual TLS for the transport
*/
@Beta
public static NetHttpTransport newTrustedTransport(MtlsProvider mtlsProvider)
throws GeneralSecurityException, IOException {
KeyStore mtlsKeyStore = null;
String mtlsKeyStorePassword = null;
if (mtlsProvider.useMtlsClientCertificate()) {
mtlsKeyStore = mtlsProvider.getKeyStore();
mtlsKeyStorePassword = mtlsProvider.getKeyStorePassword();
}

if (mtlsKeyStore != null && mtlsKeyStorePassword != null) {
return new NetHttpTransport.Builder()
.trustCertificates(
GoogleUtils.getCertificateTrustStore(), mtlsKeyStore, mtlsKeyStorePassword)
.build();
}
return new NetHttpTransport.Builder()
.trustCertificates(GoogleUtils.getCertificateTrustStore())
.build();
}

private GoogleNetHttpTransport() {}
}
@@ -0,0 +1,43 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/

package com.google.api.client.googleapis.mtls;

import java.util.List;

import com.google.api.client.json.GenericJson;
import com.google.api.client.util.Beta;
import com.google.api.client.util.Key;

/**
* {@link Beta} <br>
* Data class representing context_aware_metadata.json file.
*
* @since 1.31
*/
@Beta
public class ContextAwareMetadataJson extends GenericJson {
/** Cert provider command */
@Key("cert_provider_command")
private List<String> commands;

/**
* Returns the cert provider command.
*
* @since 1.31
*/
public final List<String> getCommands() {
return commands;
}
}
@@ -0,0 +1,45 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/

package com.google.api.client.googleapis.mtls;

import com.google.api.client.util.Beta;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;

/**
* {@link Beta} <br>
* Provider interface for mutual TLS. It is used in {@link
* GoogleApacheHttpTransport#newTrustedTransport(MtlsProvider)} and {@link
* GoogleNetHttpTransport#newTrustedTransport(MtlsProvider)} to configure the mutual TLS in the
* transport.
*
* @since 1.31
*/
@Beta
public interface MtlsProvider {
/**
* Returns if mutual TLS client certificate should be used. If the value is true, the key store
* from {@link #getKeyStore()} and key store password from {@link #getKeyStorePassword()} will be
* used to configure mutual TLS transport.
*/
boolean useMtlsClientCertificate();

/** The key store to use for mutual TLS. */
String getKeyStorePassword();

/** The password for mutual TLS key store. */
KeyStore getKeyStore() throws IOException, GeneralSecurityException;
}