Skip to content

Commit e6a32c9

Browse files
committed
Remove certificate caching from x509 provider.
1 parent c9a67cb commit e6a32c9

File tree

7 files changed

+38
-50
lines changed

7 files changed

+38
-50
lines changed

oauth2_http/java/com/google/auth/mtls/X509Provider.java

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ public class X509Provider {
5252
static final String CERTIFICATE_CONFIGURATION_ENV_VARIABLE = "GOOGLE_API_CERTIFICATE_CONFIG";
5353
static final String WELL_KNOWN_CERTIFICATE_CONFIG_FILE = "certificate_config.json";
5454
static final String CLOUDSDK_CONFIG_DIRECTORY = "gcloud";
55-
private WorkloadCertificateConfiguration loadedConfig;
5655

5756
private final String certConfigPathOverride;
5857

@@ -90,12 +89,7 @@ public X509Provider() {
9089
* @throws CertificateSourceUnavailableException if the configuration file is not found.
9190
*/
9291
public String getCertificatePath() throws IOException {
93-
if (loadedConfig == null) {
94-
// Attempt to load the configuration. This call might throw IOException or
95-
// CertificateSourceUnavailableException if loading fails.
96-
loadedConfig = getWorkloadCertificateConfiguration();
97-
}
98-
String certPath = loadedConfig.getCertPath();
92+
String certPath = getWorkloadCertificateConfiguration().getCertPath();
9993
if (Strings.isNullOrEmpty(certPath)) {
10094
// Ensure the loaded configuration actually contains the required path.
10195
throw new CertificateSourceUnavailableException(
@@ -119,17 +113,14 @@ public String getCertificatePath() throws IOException {
119113
* @throws IOException if there is an error retrieving the certificate configuration.
120114
*/
121115
public KeyStore getKeyStore() throws IOException {
122-
if (loadedConfig == null) {
123-
loadedConfig = getWorkloadCertificateConfiguration();
124-
}
125-
116+
WorkloadCertificateConfiguration workloadCertConfig = getWorkloadCertificateConfiguration();
126117
InputStream certStream = null;
127118
InputStream privateKeyStream = null;
128119
SequenceInputStream certAndPrivateKeyStream = null;
129120
try {
130121
// Read the certificate and private key file paths into separate streams.
131-
File certFile = new File(loadedConfig.getCertPath());
132-
File privateKeyFile = new File(loadedConfig.getPrivateKeyPath());
122+
File certFile = new File(workloadCertConfig.getCertPath());
123+
File privateKeyFile = new File(workloadCertConfig.getPrivateKeyPath());
133124
certStream = createInputStream(certFile);
134125
privateKeyStream = createInputStream(privateKeyFile);
135126

oauth2_http/java/com/google/auth/oauth2/CertificateIdentityPoolSubjectTokenSupplier.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@
3434
import static com.google.common.base.Preconditions.checkNotNull;
3535

3636
import com.google.common.annotations.VisibleForTesting;
37-
import com.google.gson.Gson;
38-
import com.google.gson.JsonArray;
39-
import com.google.gson.JsonPrimitive;
4037
import java.io.ByteArrayInputStream;
4138
import java.io.IOException;
4239
import java.io.InputStream;
@@ -49,15 +46,14 @@
4946
import java.util.Base64;
5047

5148
/**
52-
* Provider for retrieving subject tokens for {@link IdentityPoolCredentials} by reading an X.509
53-
* certificate from the filesystem. The certificate file (e.g., PEM or DER encoded) is read, the
54-
* leaf certificate is base64-encoded (DER format), wrapped in a JSON array, and used as the subject
55-
* token for STS exchange.
49+
* Provider for retrieving the subject tokens for {@link IdentityPoolCredentials} by reading an
50+
* X.509 certificate from the filesystem. The certificate file (e.g., PEM or DER encoded) is read,
51+
* the leaf certificate is base64-encoded (DER format), wrapped in a JSON array, and used as the
52+
* subject token for STS exchange.
5653
*/
5754
public class CertificateIdentityPoolSubjectTokenSupplier
5855
implements IdentityPoolSubjectTokenSupplier {
5956

60-
private static final Gson GSON = new Gson();
6157
private final IdentityPoolCredentialSource credentialSource;
6258

6359
CertificateIdentityPoolSubjectTokenSupplier(IdentityPoolCredentialSource credentialSource) {
@@ -118,10 +114,10 @@ public String getSubjectToken(ExternalAccountSupplierContext context) throws IOE
118114
X509Certificate leafCert = loadLeafCertificate(credentialSource.getCredentialLocation());
119115
String encodedLeafCert = encodeCert(leafCert);
120116

121-
JsonArray certChain = new JsonArray();
122-
certChain.add(new JsonPrimitive(encodedLeafCert));
117+
java.util.List<String> certChain = new java.util.ArrayList<>();
118+
certChain.add(encodedLeafCert);
123119

124-
return GSON.toJson(certChain);
120+
return OAuth2Utils.JSON_FACTORY.toString(certChain);
125121
} catch (CertificateException e) {
126122
// Catch CertificateException to provide a more specific error message including
127123
// the path of the file that failed to parse, and re-throw as IOException

oauth2_http/java/com/google/auth/oauth2/FileIdentityPoolSubjectTokenSupplier.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646
import java.nio.file.Paths;
4747

4848
/**
49-
* Internal provider for retrieving subject tokens for {@link IdentityPoolCredentials} to exchange
50-
* for GCP access tokens via a local file.
49+
* Internal provider for retrieving the subject tokens for {@link IdentityPoolCredentials} to
50+
* exchange for GCP access tokens via a local file.
5151
*/
5252
class FileIdentityPoolSubjectTokenSupplier implements IdentityPoolSubjectTokenSupplier {
5353

oauth2_http/java/com/google/auth/oauth2/IdentityPoolCredentials.java

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,16 @@ public class IdentityPoolCredentials extends ExternalAccountCredentials {
9393
this.metricsHeaderValue = URL_METRICS_HEADER_VALUE;
9494
} else if (credentialSource.credentialSourceType
9595
== IdentityPoolCredentialSourceType.CERTIFICATE) {
96-
this.subjectTokenSupplier = createCertificateSubjectTokenSupplier(builder, credentialSource);
96+
try {
97+
this.subjectTokenSupplier =
98+
createCertificateSubjectTokenSupplier(builder, credentialSource);
99+
} catch (IOException e) {
100+
throw new RuntimeException(
101+
// Wrap IOException in RuntimeException because constructors cannot throw checked
102+
// exceptions.
103+
"Failed to initialize IdentityPoolCredentials from certificate source due to an I/O error.",
104+
e);
105+
}
97106
this.metricsHeaderValue = CERTIFICATE_METRICS_HEADER_VALUE;
98107
} else {
99108
throw new IllegalArgumentException("Source type not supported.");
@@ -145,24 +154,15 @@ public static Builder newBuilder(IdentityPoolCredentials identityPoolCredentials
145154
}
146155

147156
private IdentityPoolSubjectTokenSupplier createCertificateSubjectTokenSupplier(
148-
Builder builder, IdentityPoolCredentialSource credentialSource) {
149-
try {
150-
// Configure the mTLS transport with the x509 keystore.
151-
X509Provider x509Provider = getX509Provider(builder, credentialSource);
152-
KeyStore mtlsKeyStore = x509Provider.getKeyStore();
153-
this.transportFactory = new MtlsHttpTransportFactory(mtlsKeyStore);
154-
155-
// Initialize the subject token supplier with the certificate path.
156-
credentialSource.setCredentialLocation(x509Provider.getCertificatePath());
157-
return new CertificateIdentityPoolSubjectTokenSupplier(credentialSource);
158-
159-
} catch (IOException e) {
160-
throw new RuntimeException(
161-
// Wrap IOException in RuntimeException because constructors cannot throw checked
162-
// exceptions.
163-
"Failed to initialize IdentityPoolCredentials from certificate source due to an I/O error.",
164-
e);
165-
}
157+
Builder builder, IdentityPoolCredentialSource credentialSource) throws IOException {
158+
// Configure the mTLS transport with the x509 keystore.
159+
X509Provider x509Provider = getX509Provider(builder, credentialSource);
160+
KeyStore mtlsKeyStore = x509Provider.getKeyStore();
161+
this.transportFactory = new MtlsHttpTransportFactory(mtlsKeyStore);
162+
163+
// Initialize the subject token supplier with the certificate path.
164+
credentialSource.setCredentialLocation(x509Provider.getCertificatePath());
165+
return new CertificateIdentityPoolSubjectTokenSupplier(credentialSource);
166166
}
167167

168168
private X509Provider getX509Provider(

oauth2_http/java/com/google/auth/oauth2/IdentityPoolSubjectTokenSupplier.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636

3737
@FunctionalInterface
3838
/**
39-
* Provider for retrieving subject tokens for {@Link IdentityPoolCredentials} to exchange for GCP
40-
* access tokens.
39+
* Provider for retrieving the subject tokens for {@Link IdentityPoolCredentials} to exchange for
40+
* GCP access tokens.
4141
*/
4242
public interface IdentityPoolSubjectTokenSupplier extends Serializable {
4343

oauth2_http/java/com/google/auth/oauth2/UrlIdentityPoolSubjectTokenSupplier.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@
4242
import java.io.IOException;
4343

4444
/**
45-
* Provider for retrieving subject tokens for {@link IdentityPoolCredentials} to exchange for GCP
46-
* access tokens. The subject token is retrieved by calling a URL that returns the token.
45+
* Provider for retrieving the subject tokens for {@link IdentityPoolCredentials} to exchange for
46+
* GCP access tokens. The subject token is retrieved by calling a URL that returns the token.
4747
*/
4848
class UrlIdentityPoolSubjectTokenSupplier implements IdentityPoolSubjectTokenSupplier {
4949

oauth2_http/javatests/com/google/auth/oauth2/IdentityPoolCredentialsTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,8 @@ public void build_withCertificateSourceAndCustomX509Provider_success()
10881088
public void build_withDefaultCertificate_throwsOnTransportInitFailure() {
10891089
// Setup credential source to use default certificate config.
10901090
Map<String, Object> certificateMap = new HashMap<>();
1091-
certificateMap.put("use_default_certificate_config", true);
1091+
certificateMap.put("use_default_certificate_config", false);
1092+
certificateMap.put("certificate_config_location", "/non/existing/path/to/certificate.json");
10921093
Map<String, Object> credentialSourceMap = new HashMap<>();
10931094
credentialSourceMap.put("certificate", certificateMap);
10941095
IdentityPoolCredentialSource credentialSource =

0 commit comments

Comments
 (0)