Skip to content

Commit 8ddbe44

Browse files
committed
Single S2AChannelCredentials + use AdvancedTls.
1 parent 1527374 commit 8ddbe44

File tree

1 file changed

+63
-38
lines changed

1 file changed

+63
-38
lines changed

gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java

Lines changed: 63 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767
import io.grpc.TlsChannelCredentials;
6868
import io.grpc.alts.GoogleDefaultChannelCredentials;
6969
import io.grpc.auth.MoreCallCredentials;
70+
import io.grpc.util.AdvancedTlsX509KeyManager;
71+
import io.grpc.util.AdvancedTlsX509TrustManager;
7072
import java.io.File;
7173
import java.io.IOException;
7274
import java.lang.reflect.Method;
@@ -78,6 +80,7 @@
7880
import java.util.List;
7981
import java.util.Map;
8082
import java.util.concurrent.Executor;
83+
import java.util.concurrent.Executors;
8184
import java.util.concurrent.ScheduledExecutorService;
8285
import java.util.concurrent.TimeUnit;
8386
import java.util.logging.Level;
@@ -161,6 +164,8 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP
161164
@Nullable
162165
private final ApiFunction<ManagedChannelBuilder, ManagedChannelBuilder> channelConfigurator;
163166

167+
private static volatile ChannelCredentials s2aChannelCredentialsObject;
168+
164169
/*
165170
* Experimental feature
166171
*
@@ -556,13 +561,19 @@ ChannelCredentials buildS2AChannelCredentials(
556561
*/
557562
@VisibleForTesting
558563
ChannelCredentials createMtlsToS2AChannelCredentials(
559-
File trustBundle, File privateKey, File certChain) throws IOException {
564+
File trustBundle, File privateKey, File certChain)
565+
throws IOException, GeneralSecurityException {
560566
if (trustBundle == null || privateKey == null || certChain == null) {
561567
return null;
562568
}
569+
AdvancedTlsX509KeyManager keyManager = new AdvancedTlsX509KeyManager();
570+
keyManager.updateIdentityCredentials(certChain, privateKey);
571+
AdvancedTlsX509TrustManager trustManager = AdvancedTlsX509TrustManager.newBuilder().build();
572+
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
573+
trustManager.updateTrustCredentials(trustBundle, 1, TimeUnit.HOURS, executor);
563574
return TlsChannelCredentials.newBuilder()
564-
.keyManager(privateKey, certChain)
565-
.trustManager(trustBundle)
575+
.keyManager(keyManager)
576+
.trustManager(trustManager)
566577
.build();
567578
}
568579

@@ -595,43 +606,57 @@ ChannelCredentials createPlaintextToS2AChannelCredentials(String plaintextAddres
595606
* @return {@link ChannelCredentials} configured to use S2A to create mTLS connection.
596607
*/
597608
ChannelCredentials createS2ASecuredChannelCredentials() {
598-
SecureSessionAgentConfig config = s2aConfigProvider.getConfig();
599-
String plaintextAddress = config.getPlaintextAddress();
600-
String mtlsAddress = config.getMtlsAddress();
601-
if (Strings.isNullOrEmpty(mtlsAddress)) {
602-
// Fallback to plaintext connection to S2A.
603-
LOG.log(
604-
Level.INFO,
605-
"Cannot establish an mTLS connection to S2A because autoconfig endpoint did not return a mtls address to reach S2A.");
606-
return createPlaintextToS2AChannelCredentials(plaintextAddress);
607-
}
608-
// Currently, MTLS to MDS is only available on GCE. See:
609-
// https://cloud.google.com/compute/docs/metadata/overview#https-mds
610-
// Try to load MTLS-MDS creds.
611-
File rootFile = new File(MTLS_MDS_ROOT_PATH);
612-
File certKeyFile = new File(MTLS_MDS_CERT_CHAIN_AND_KEY_PATH);
613-
if (rootFile.isFile() && certKeyFile.isFile()) {
614-
// Try to connect to S2A using mTLS.
615-
ChannelCredentials mtlsToS2AChannelCredentials = null;
616-
try {
617-
mtlsToS2AChannelCredentials =
618-
createMtlsToS2AChannelCredentials(rootFile, certKeyFile, certKeyFile);
619-
} catch (IOException ignore) {
620-
// Fallback to plaintext-to-S2A connection on error.
621-
LOG.log(
622-
Level.WARNING,
623-
"Cannot establish an mTLS connection to S2A due to error creating MTLS to MDS TlsChannelCredentials credentials, falling back to plaintext connection to S2A: "
624-
+ ignore.getMessage());
625-
return createPlaintextToS2AChannelCredentials(plaintextAddress);
609+
if (s2aChannelCredentialsObject == null) {
610+
synchronized (InstantiatingGrpcChannelProvider.class) {
611+
if (s2aChannelCredentialsObject == null) {
612+
SecureSessionAgentConfig config = s2aConfigProvider.getConfig();
613+
String plaintextAddress = config.getPlaintextAddress();
614+
String mtlsAddress = config.getMtlsAddress();
615+
if (Strings.isNullOrEmpty(mtlsAddress)) {
616+
// Fallback to plaintext connection to S2A.
617+
LOG.log(
618+
Level.INFO,
619+
"Cannot establish an mTLS connection to S2A because autoconfig endpoint did not return a mtls address to reach S2A.");
620+
s2aChannelCredentialsObject = createPlaintextToS2AChannelCredentials(plaintextAddress);
621+
return s2aChannelCredentialsObject;
622+
}
623+
// Currently, MTLS to MDS is only available on GCE. See:
624+
// https://cloud.google.com/compute/docs/metadata/overview#https-mds
625+
// Try to load MTLS-MDS creds.
626+
File rootFile = new File(MTLS_MDS_ROOT_PATH);
627+
File certKeyFile = new File(MTLS_MDS_CERT_CHAIN_AND_KEY_PATH);
628+
if (rootFile.isFile() && certKeyFile.isFile()) {
629+
// Try to connect to S2A using mTLS.
630+
ChannelCredentials mtlsToS2AChannelCredentials = null;
631+
try {
632+
mtlsToS2AChannelCredentials =
633+
createMtlsToS2AChannelCredentials(rootFile, certKeyFile, certKeyFile);
634+
} catch (IOException | GeneralSecurityException ignore) {
635+
// Fallback to plaintext-to-S2A connection on error.
636+
LOG.log(
637+
Level.WARNING,
638+
"Cannot establish an mTLS connection to S2A due to error creating MTLS to MDS TlsChannelCredentials credentials, falling back to plaintext connection to S2A: "
639+
+ ignore.getMessage());
640+
s2aChannelCredentialsObject =
641+
createPlaintextToS2AChannelCredentials(plaintextAddress);
642+
return s2aChannelCredentialsObject;
643+
}
644+
s2aChannelCredentialsObject =
645+
buildS2AChannelCredentials(mtlsAddress, mtlsToS2AChannelCredentials);
646+
return s2aChannelCredentialsObject;
647+
} else {
648+
// Fallback to plaintext-to-S2A connection if MTLS-MDS creds do not exist.
649+
LOG.log(
650+
Level.INFO,
651+
"Cannot establish an mTLS connection to S2A because MTLS to MDS credentials do not"
652+
+ " exist on filesystem, falling back to plaintext connection to S2A");
653+
s2aChannelCredentialsObject = createPlaintextToS2AChannelCredentials(plaintextAddress);
654+
return s2aChannelCredentialsObject;
655+
}
656+
}
626657
}
627-
return buildS2AChannelCredentials(mtlsAddress, mtlsToS2AChannelCredentials);
628-
} else {
629-
// Fallback to plaintext-to-S2A connection if MTLS-MDS creds do not exist.
630-
LOG.log(
631-
Level.INFO,
632-
"Cannot establish an mTLS connection to S2A because MTLS to MDS credentials do not exist on filesystem, falling back to plaintext connection to S2A");
633-
return createPlaintextToS2AChannelCredentials(plaintextAddress);
634658
}
659+
return s2aChannelCredentialsObject;
635660
}
636661

637662
private ManagedChannel createSingleChannel() throws IOException {

0 commit comments

Comments
 (0)