3232package com .google .auth .mtls ;
3333
3434import com .google .api .client .util .SecurityUtils ;
35+ import com .google .common .base .Strings ;
3536import java .io .File ;
3637import java .io .FileInputStream ;
3738import java .io .FileNotFoundException ;
4142import java .security .KeyStore ;
4243import java .util .Locale ;
4344
45+ /**
46+ * This class provides certificate key stores to the Google Auth library transport layer via
47+ * certificate configuration files. This is only meant to be used internally to Google Cloud
48+ * libraries, and the public facing methods may be changed without notice, and have no guarantee of
49+ * backwards compatability.
50+ */
4451public class X509Provider {
4552 static final String CERTIFICATE_CONFIGURATION_ENV_VARIABLE = "GOOGLE_API_CERTIFICATE_CONFIG" ;
4653 static final String WELL_KNOWN_CERTIFICATE_CONFIG_FILE = "certificate_config.json" ;
4754 static final String CLOUDSDK_CONFIG_DIRECTORY = "gcloud" ;
4855
4956 private String certConfigPathOverride ;
5057
58+ /**
59+ * Creates an X509 provider with an override path for the certificate configuration, bypassing the
60+ * normal checks for the well known certificate configuration file path and environment variable.
61+ * This is meant for internal Google Cloud usage and behavior may be changed without warning.
62+ *
63+ * @param certConfigPathOverride the path to read the certificate configuration from.
64+ */
5165 public X509Provider (String certConfigPathOverride ) {
5266 this .certConfigPathOverride = certConfigPathOverride ;
5367 }
5468
69+ /**
70+ * Creates a new X.509 provider that will check the environment variable path and the well known
71+ * Gcloud certificate configuration location. This is meant for internal Google Cloud usage and
72+ * behavior may be changed without warning.
73+ */
5574 public X509Provider () {
5675 this (null );
5776 }
@@ -76,20 +95,24 @@ public KeyStore getKeyStore() throws IOException {
7695
7796 InputStream certStream = null ;
7897 InputStream privateKeyStream = null ;
98+ SequenceInputStream certAndPrivateKeyStream = null ;
7999 try {
80100 // Read the certificate and private key file paths into separate streams.
81101 File certFile = new File (workloadCertConfig .getCertPath ());
82102 File privateKeyFile = new File (workloadCertConfig .getPrivateKeyPath ());
83- certStream = readStream (certFile );
84- privateKeyStream = readStream (privateKeyFile );
103+ certStream = createInputStream (certFile );
104+ privateKeyStream = createInputStream (privateKeyFile );
85105
86106 // Merge the two streams into a single stream.
87- SequenceInputStream certAndPrivateKeyStream =
88- new SequenceInputStream (certStream , privateKeyStream );
107+ certAndPrivateKeyStream = new SequenceInputStream (certStream , privateKeyStream );
89108
90109 // Build a key store using the combined stream.
91110 return SecurityUtils .createMtlsKeyStore (certAndPrivateKeyStream );
111+ } catch (CertificateSourceUnavailableException e ) {
112+ // Throw the CertificateSourceUnavailableException without wrapping.
113+ throw e ;
92114 } catch (Exception e ) {
115+ // Wrap all other exception types to an IOException.
93116 throw new IOException (e );
94117 } finally {
95118 if (certStream != null ) {
@@ -98,6 +121,9 @@ public KeyStore getKeyStore() throws IOException {
98121 if (privateKeyStream != null ) {
99122 privateKeyStream .close ();
100123 }
124+ if (certAndPrivateKeyStream != null ) {
125+ certAndPrivateKeyStream .close ();
126+ }
101127 }
102128 }
103129
@@ -108,7 +134,7 @@ private WorkloadCertificateConfiguration getWorkloadCertificateConfiguration()
108134 certConfig = new File (certConfigPathOverride );
109135 } else {
110136 String envCredentialsPath = getEnv (CERTIFICATE_CONFIGURATION_ENV_VARIABLE );
111- if (envCredentialsPath != null && ! envCredentialsPath . isEmpty ( )) {
137+ if (! Strings . isNullOrEmpty ( envCredentialsPath )) {
112138 certConfig = new File (envCredentialsPath );
113139 } else {
114140 certConfig = getWellKnownCertificateConfigFile ();
@@ -120,13 +146,13 @@ private WorkloadCertificateConfiguration getWorkloadCertificateConfiguration()
120146 // Path will be put in the message from the catch block below
121147 throw new IOException ("File does not exist." );
122148 }
123- certConfigStream = readStream (certConfig );
149+ certConfigStream = createInputStream (certConfig );
124150 return WorkloadCertificateConfiguration .fromCertificateConfigurationStream (certConfigStream );
125151 } catch (Exception e ) {
126152 // Although it is also the cause, the message of the caught exception can have very
127153 // important information for diagnosing errors, so include its message in the
128154 // outer exception message also.
129- throw new IOException (
155+ throw new CertificateSourceUnavailableException (
130156 String .format (
131157 "Error reading certificate configuration file value '%s': %s" ,
132158 certConfig .getPath (), e .getMessage ()),
@@ -145,7 +171,7 @@ boolean isFile(File file) {
145171 return file .isFile ();
146172 }
147173
148- InputStream readStream (File file ) throws FileNotFoundException {
174+ InputStream createInputStream (File file ) throws FileNotFoundException {
149175 return new FileInputStream (file );
150176 }
151177
0 commit comments