24
24
import io .grpc .xds .client .Bootstrapper .CertificateProviderInfo ;
25
25
import io .grpc .xds .internal .security .CommonTlsContextUtil ;
26
26
import io .grpc .xds .internal .security .DynamicSslContextProvider ;
27
+ import java .io .Closeable ;
27
28
import java .security .PrivateKey ;
28
29
import java .security .cert .X509Certificate ;
29
30
import java .util .List ;
34
35
abstract class CertProviderSslContextProvider extends DynamicSslContextProvider implements
35
36
CertificateProvider .Watcher {
36
37
37
- @ Nullable private final CertificateProviderStore . Handle certHandle ;
38
- @ Nullable private final CertificateProviderStore . Handle rootCertHandle ;
38
+ @ Nullable private final NoExceptionCloseable certHandle ;
39
+ @ Nullable private final NoExceptionCloseable rootCertHandle ;
39
40
@ Nullable private final CertificateProviderInstance certInstance ;
40
41
@ Nullable protected final CertificateProviderInstance rootCertInstance ;
41
42
@ Nullable protected PrivateKey savedKey ;
@@ -55,38 +56,50 @@ protected CertProviderSslContextProvider(
55
56
super (tlsContext , staticCertValidationContext );
56
57
this .certInstance = certInstance ;
57
58
this .rootCertInstance = rootCertInstance ;
58
- String certInstanceName = null ;
59
- if (certInstance != null && certInstance .isInitialized ()) {
60
- certInstanceName = certInstance .getInstanceName ();
59
+ this .isUsingSystemRootCerts = rootCertInstance == null
60
+ && CommonTlsContextUtil .isUsingSystemRootCerts (tlsContext .getCommonTlsContext ());
61
+ boolean createCertInstance = certInstance != null && certInstance .isInitialized ();
62
+ boolean createRootCertInstance = rootCertInstance != null && rootCertInstance .isInitialized ();
63
+ boolean sharedCertInstance = createCertInstance && createRootCertInstance
64
+ && rootCertInstance .getInstanceName ().equals (certInstance .getInstanceName ());
65
+ if (createCertInstance ) {
61
66
CertificateProviderInfo certProviderInstanceConfig =
62
- getCertProviderConfig (certProviders , certInstanceName );
67
+ getCertProviderConfig (certProviders , certInstance .getInstanceName ());
68
+ CertificateProvider .Watcher watcher = this ;
69
+ if (!sharedCertInstance && !isUsingSystemRootCerts ) {
70
+ watcher = new IgnoreUpdatesWatcher (watcher , /* ignoreRootCertUpdates= */ true );
71
+ }
72
+ // TODO: Previously we'd hang if certProviderInstanceConfig were null or
73
+ // certInstance.isInitialized() == false. Now we'll proceed. Those should be errors, or are
74
+ // they impossible and should be assertions?
63
75
certHandle = certProviderInstanceConfig == null ? null
64
76
: certificateProviderStore .createOrGetProvider (
65
77
certInstance .getCertificateName (),
66
78
certProviderInstanceConfig .pluginName (),
67
79
certProviderInstanceConfig .config (),
68
- this ,
69
- true );
80
+ watcher ,
81
+ true ):: close ;
70
82
} else {
71
83
certHandle = null ;
72
84
}
73
- if (rootCertInstance != null
74
- && rootCertInstance .isInitialized ()
75
- && !rootCertInstance .getInstanceName ().equals (certInstanceName )) {
85
+ if (createRootCertInstance && !sharedCertInstance ) {
76
86
CertificateProviderInfo certProviderInstanceConfig =
77
87
getCertProviderConfig (certProviders , rootCertInstance .getInstanceName ());
78
88
rootCertHandle = certProviderInstanceConfig == null ? null
79
89
: certificateProviderStore .createOrGetProvider (
80
90
rootCertInstance .getCertificateName (),
81
91
certProviderInstanceConfig .pluginName (),
82
92
certProviderInstanceConfig .config (),
83
- this ,
84
- true );
93
+ new IgnoreUpdatesWatcher (this , /* ignoreRootCertUpdates= */ false ),
94
+ false )::close ;
95
+ } else if (rootCertInstance == null
96
+ && CommonTlsContextUtil .isUsingSystemRootCerts (tlsContext .getCommonTlsContext ())) {
97
+ SystemRootCertificateProvider systemRootProvider = new SystemRootCertificateProvider (this );
98
+ systemRootProvider .start ();
99
+ rootCertHandle = systemRootProvider ::close ;
85
100
} else {
86
101
rootCertHandle = null ;
87
102
}
88
- this .isUsingSystemRootCerts = rootCertInstance == null
89
- && CommonTlsContextUtil .isUsingSystemRootCerts (tlsContext .getCommonTlsContext ());
90
103
}
91
104
92
105
private static CertificateProviderInfo getCertProviderConfig (
@@ -150,17 +163,16 @@ public final void updateSpiffeTrustMap(Map<String, List<X509Certificate>> spiffe
150
163
151
164
private void updateSslContextWhenReady () {
152
165
if (isMtls ()) {
153
- if (savedKey != null
154
- && (savedTrustedRoots != null || isUsingSystemRootCerts || savedSpiffeTrustMap != null )) {
166
+ if (savedKey != null && (savedTrustedRoots != null || savedSpiffeTrustMap != null )) {
155
167
updateSslContext ();
156
168
clearKeysAndCerts ();
157
169
}
158
- } else if (isClientSideTls ()) {
170
+ } else if (isRegularTlsAndClientSide ()) {
159
171
if (savedTrustedRoots != null || savedSpiffeTrustMap != null ) {
160
172
updateSslContext ();
161
173
clearKeysAndCerts ();
162
174
}
163
- } else if (isServerSideTls ()) {
175
+ } else if (isRegularTlsAndServerSide ()) {
164
176
if (savedKey != null ) {
165
177
updateSslContext ();
166
178
clearKeysAndCerts ();
@@ -170,20 +182,22 @@ private void updateSslContextWhenReady() {
170
182
171
183
private void clearKeysAndCerts () {
172
184
savedKey = null ;
173
- savedTrustedRoots = null ;
174
- savedSpiffeTrustMap = null ;
185
+ if (!isUsingSystemRootCerts ) {
186
+ savedTrustedRoots = null ;
187
+ savedSpiffeTrustMap = null ;
188
+ }
175
189
savedCertChain = null ;
176
190
}
177
191
178
192
protected final boolean isMtls () {
179
193
return certInstance != null && (rootCertInstance != null || isUsingSystemRootCerts );
180
194
}
181
195
182
- protected final boolean isClientSideTls () {
183
- return rootCertInstance != null && certInstance == null ;
196
+ protected final boolean isRegularTlsAndClientSide () {
197
+ return ( rootCertInstance != null || isUsingSystemRootCerts ) && certInstance == null ;
184
198
}
185
199
186
- protected final boolean isServerSideTls () {
200
+ protected final boolean isRegularTlsAndServerSide () {
187
201
return certInstance != null && rootCertInstance == null ;
188
202
}
189
203
@@ -201,4 +215,9 @@ public final void close() {
201
215
rootCertHandle .close ();
202
216
}
203
217
}
218
+
219
+ interface NoExceptionCloseable extends Closeable {
220
+ @ Override
221
+ void close ();
222
+ }
204
223
}
0 commit comments