3131package com .google .auth .mtls ;
3232
3333import com .google .api .client .util .SecurityUtils ;
34- import com .google .common .base .Strings ;
34+ import com .google .api .core .InternalApi ;
35+ import com .google .auth .oauth2 .EnvironmentProvider ;
36+ import com .google .auth .oauth2 .PropertyProvider ;
37+ import com .google .auth .oauth2 .SystemEnvironmentProvider ;
38+ import com .google .auth .oauth2 .SystemPropertyProvider ;
3539import java .io .File ;
3640import java .io .FileInputStream ;
37- import java .io .FileNotFoundException ;
3841import java .io .IOException ;
3942import java .io .InputStream ;
4043import java .io .SequenceInputStream ;
4144import java .security .KeyStore ;
42- import java .util .Locale ;
4345
4446/**
4547 * This class implements {@link MtlsProvider} for the Google Auth library transport layer via {@link
4648 * WorkloadCertificateConfiguration}. This is only meant to be used internally by Google Cloud
4749 * libraries, and the public facing methods may be changed without notice, and have no guarantee of
4850 * backwards compatibility.
4951 */
52+ @ InternalApi
5053public class X509Provider implements MtlsProvider {
51- static final String CERTIFICATE_CONFIGURATION_ENV_VARIABLE = "GOOGLE_API_CERTIFICATE_CONFIG" ;
52- static final String WELL_KNOWN_CERTIFICATE_CONFIG_FILE = "certificate_config.json" ;
53- static final String CLOUDSDK_CONFIG_DIRECTORY = "gcloud" ;
54-
54+ private final EnvironmentProvider envProvider ;
55+ private final PropertyProvider propProvider ;
5556 private final String certConfigPathOverride ;
5657
5758 /**
5859 * Creates an X509 provider with an override path for the certificate configuration, bypassing the
5960 * normal checks for the well known certificate configuration file path and environment variable.
6061 * This is meant for internal Google Cloud usage and behavior may be changed without warning.
6162 *
63+ * @param envProvider environment provider used for environment variables
64+ * @param propProvider property provider used for system properties
6265 * @param certConfigPathOverride the path to read the certificate configuration from.
6366 */
64- public X509Provider (String certConfigPathOverride ) {
67+ @ InternalApi
68+ public X509Provider (
69+ EnvironmentProvider envProvider ,
70+ PropertyProvider propProvider ,
71+ String certConfigPathOverride ) {
72+ this .envProvider = envProvider ;
73+ this .propProvider = propProvider ;
6574 this .certConfigPathOverride = certConfigPathOverride ;
6675 }
6776
77+ /**
78+ * Creates an X509 provider with an override path for the certificate configuration.
79+ *
80+ * @param certConfigPathOverride the path to read the certificate configuration from.
81+ */
82+ public X509Provider (String certConfigPathOverride ) {
83+ this (
84+ SystemEnvironmentProvider .getInstance (),
85+ SystemPropertyProvider .getInstance (),
86+ certConfigPathOverride );
87+ }
88+
6889 /**
6990 * Creates a new X.509 provider that will check the environment variable path and the well known
7091 * Gcloud certificate configuration location. This is meant for internal Google Cloud usage and
@@ -74,29 +95,6 @@ public X509Provider() {
7495 this (null );
7596 }
7697
77- /**
78- * Returns the path to the client certificate file specified by the loaded workload certificate
79- * configuration.
80- *
81- * <p>If the configuration has not been loaded yet (e.g., if {@link #getKeyStore()} has not been
82- * called), this method will attempt to load it first by searching the override path, environment
83- * variable, and well-known locations.
84- *
85- * @return The path to the certificate file.
86- * @throws IOException if the certificate configuration cannot be found or loaded, or if the
87- * configuration file does not specify a certificate path.
88- * @throws CertificateSourceUnavailableException if the configuration file is not found.
89- */
90- public String getCertificatePath () throws IOException {
91- String certPath = getWorkloadCertificateConfiguration ().getCertPath ();
92- if (Strings .isNullOrEmpty (certPath )) {
93- // Ensure the loaded configuration actually contains the required path.
94- throw new CertificateSourceUnavailableException (
95- "Certificate configuration loaded successfully, but does not contain a 'certificate_file' path." );
96- }
97- return certPath ;
98- }
99-
10098 /**
10199 * Finds the certificate configuration file, then builds a Keystore using the X.509 certificate
102100 * and private key pointed to by the configuration. This will check the following locations in
@@ -115,12 +113,14 @@ public String getCertificatePath() throws IOException {
115113 */
116114 @ Override
117115 public KeyStore getKeyStore () throws CertificateSourceUnavailableException , IOException {
118- WorkloadCertificateConfiguration workloadCertConfig = getWorkloadCertificateConfiguration ();
116+ WorkloadCertificateConfiguration workloadCertConfig =
117+ MtlsUtils .getWorkloadCertificateConfiguration (
118+ envProvider , propProvider , certConfigPathOverride );
119119
120120 // Read the certificate and private key file paths into streams.
121- try (InputStream certStream = createInputStream (new File (workloadCertConfig .getCertPath ()));
121+ try (InputStream certStream = new FileInputStream (new File (workloadCertConfig .getCertPath ()));
122122 InputStream privateKeyStream =
123- createInputStream (new File (workloadCertConfig .getPrivateKeyPath ()));
123+ new FileInputStream (new File (workloadCertConfig .getPrivateKeyPath ()));
124124 SequenceInputStream certAndPrivateKeyStream =
125125 new SequenceInputStream (certStream , privateKeyStream )) {
126126
@@ -149,74 +149,4 @@ public boolean isAvailable() throws IOException {
149149 }
150150 return true ;
151151 }
152-
153- private WorkloadCertificateConfiguration getWorkloadCertificateConfiguration ()
154- throws IOException {
155- File certConfig ;
156- if (this .certConfigPathOverride != null ) {
157- certConfig = new File (certConfigPathOverride );
158- } else {
159- String envCredentialsPath = getEnv (CERTIFICATE_CONFIGURATION_ENV_VARIABLE );
160- if (!Strings .isNullOrEmpty (envCredentialsPath )) {
161- certConfig = new File (envCredentialsPath );
162- } else {
163- certConfig = getWellKnownCertificateConfigFile ();
164- }
165- }
166- InputStream certConfigStream = null ;
167- try {
168- if (!isFile (certConfig )) {
169- // Path will be put in the message from the catch block below
170- throw new CertificateSourceUnavailableException ("File does not exist." );
171- }
172- certConfigStream = createInputStream (certConfig );
173- return WorkloadCertificateConfiguration .fromCertificateConfigurationStream (certConfigStream );
174- } finally {
175- if (certConfigStream != null ) {
176- certConfigStream .close ();
177- }
178- }
179- }
180-
181- /*
182- * Start of methods to allow overriding in the test code to isolate from the environment.
183- */
184- boolean isFile (File file ) {
185- return file .isFile ();
186- }
187-
188- InputStream createInputStream (File file ) throws FileNotFoundException {
189- return new FileInputStream (file );
190- }
191-
192- String getEnv (String name ) {
193- return System .getenv (name );
194- }
195-
196- String getOsName () {
197- return getProperty ("os.name" , "" ).toLowerCase (Locale .US );
198- }
199-
200- String getProperty (String property , String def ) {
201- return System .getProperty (property , def );
202- }
203-
204- /*
205- * End of methods to allow overriding in the test code to isolate from the environment.
206- */
207-
208- private File getWellKnownCertificateConfigFile () {
209- File cloudConfigPath ;
210- String envPath = getEnv ("CLOUDSDK_CONFIG" );
211- if (envPath != null ) {
212- cloudConfigPath = new File (envPath );
213- } else if (getOsName ().indexOf ("windows" ) >= 0 ) {
214- File appDataPath = new File (getEnv ("APPDATA" ));
215- cloudConfigPath = new File (appDataPath , CLOUDSDK_CONFIG_DIRECTORY );
216- } else {
217- File configPath = new File (getProperty ("user.home" , "" ), ".config" );
218- cloudConfigPath = new File (configPath , CLOUDSDK_CONFIG_DIRECTORY );
219- }
220- return new File (cloudConfigPath , WELL_KNOWN_CERTIFICATE_CONFIG_FILE );
221- }
222152}
0 commit comments