• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

grpc / grpc-java / #19524

25 Oct 2024 09:06AM UTC coverage: 84.61% (-0.007%) from 84.617%
#19524

push

github

web-flow
Xds: Implement using system root trust CA for TLS server authentication (#11470)

Allow using system root certs for server cert validation rather than CA root certs provided by the control plane when the validation context provided by the control plane specifies so.

33855 of 40013 relevant lines covered (84.61%)

0.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.73
/../xds/src/main/java/io/grpc/xds/internal/security/certprovider/CertProviderSslContextProvider.java
1
/*
2
 * Copyright 2020 The gRPC Authors
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package io.grpc.xds.internal.security.certprovider;
18

19
import io.envoyproxy.envoy.config.core.v3.Node;
20
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CertificateValidationContext;
21
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext;
22
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext.CertificateProviderInstance;
23
import io.grpc.xds.EnvoyServerProtoData.BaseTlsContext;
24
import io.grpc.xds.client.Bootstrapper.CertificateProviderInfo;
25
import io.grpc.xds.internal.security.CommonTlsContextUtil;
26
import io.grpc.xds.internal.security.DynamicSslContextProvider;
27
import java.security.PrivateKey;
28
import java.security.cert.X509Certificate;
29
import java.util.List;
30
import java.util.Map;
31
import javax.annotation.Nullable;
32

33
/** Base class for {@link CertProviderClientSslContextProvider}. */
34
abstract class CertProviderSslContextProvider extends DynamicSslContextProvider implements
35
    CertificateProvider.Watcher {
36

37
  @Nullable private final CertificateProviderStore.Handle certHandle;
38
  @Nullable private final CertificateProviderStore.Handle rootCertHandle;
39
  @Nullable private final CertificateProviderInstance certInstance;
40
  @Nullable protected final CertificateProviderInstance rootCertInstance;
41
  @Nullable protected PrivateKey savedKey;
42
  @Nullable protected List<X509Certificate> savedCertChain;
43
  @Nullable protected List<X509Certificate> savedTrustedRoots;
44
  private final boolean isUsingSystemRootCerts;
45

46
  protected CertProviderSslContextProvider(
47
      Node node,
48
      @Nullable Map<String, CertificateProviderInfo> certProviders,
49
      CertificateProviderInstance certInstance,
50
      CertificateProviderInstance rootCertInstance,
51
      CertificateValidationContext staticCertValidationContext,
52
      BaseTlsContext tlsContext,
53
      CertificateProviderStore certificateProviderStore) {
54
    super(tlsContext, staticCertValidationContext);
1✔
55
    this.certInstance = certInstance;
1✔
56
    this.rootCertInstance = rootCertInstance;
1✔
57
    String certInstanceName = null;
1✔
58
    if (certInstance != null && certInstance.isInitialized()) {
1✔
59
      certInstanceName = certInstance.getInstanceName();
1✔
60
      CertificateProviderInfo certProviderInstanceConfig =
1✔
61
          getCertProviderConfig(certProviders, certInstanceName);
1✔
62
      certHandle = certProviderInstanceConfig == null ? null
1✔
63
          : certificateProviderStore.createOrGetProvider(
1✔
64
              certInstance.getCertificateName(),
1✔
65
              certProviderInstanceConfig.pluginName(),
1✔
66
              certProviderInstanceConfig.config(),
1✔
67
              this,
68
              true);
69
    } else {
1✔
70
      certHandle = null;
1✔
71
    }
72
    if (rootCertInstance != null
1✔
73
        && rootCertInstance.isInitialized()
1✔
74
        && !rootCertInstance.getInstanceName().equals(certInstanceName)) {
1✔
75
      CertificateProviderInfo certProviderInstanceConfig =
1✔
76
          getCertProviderConfig(certProviders, rootCertInstance.getInstanceName());
1✔
77
      rootCertHandle = certProviderInstanceConfig == null ? null
1✔
78
          : certificateProviderStore.createOrGetProvider(
1✔
79
              rootCertInstance.getCertificateName(),
1✔
80
              certProviderInstanceConfig.pluginName(),
1✔
81
              certProviderInstanceConfig.config(),
1✔
82
              this,
83
              true);
84
    } else {
1✔
85
      rootCertHandle = null;
1✔
86
    }
87
    this.isUsingSystemRootCerts = rootCertInstance == null
1✔
88
        && CommonTlsContextUtil.isUsingSystemRootCerts(tlsContext.getCommonTlsContext());
1✔
89
  }
1✔
90

91
  private static CertificateProviderInfo getCertProviderConfig(
92
      @Nullable Map<String, CertificateProviderInfo> certProviders, String pluginInstanceName) {
93
    return certProviders != null ? certProviders.get(pluginInstanceName) : null;
1✔
94
  }
95

96
  @Nullable
97
  protected static CertificateProviderInstance getCertProviderInstance(
98
      CommonTlsContext commonTlsContext) {
99
    if (commonTlsContext.hasTlsCertificateProviderInstance()) {
1✔
100
      return CommonTlsContextUtil.convert(commonTlsContext.getTlsCertificateProviderInstance());
1✔
101
    } else if (commonTlsContext.hasTlsCertificateCertificateProviderInstance()) {
1✔
102
      return commonTlsContext.getTlsCertificateCertificateProviderInstance();
1✔
103
    }
104
    return null;
1✔
105
  }
106

107
  @Nullable
108
  protected static CertificateValidationContext getStaticValidationContext(
109
      CommonTlsContext commonTlsContext) {
110
    if (commonTlsContext.hasValidationContext()) {
1✔
111
      return commonTlsContext.getValidationContext();
1✔
112
    } else if (commonTlsContext.hasCombinedValidationContext()) {
1✔
113
      CommonTlsContext.CombinedCertificateValidationContext combinedValidationContext =
1✔
114
          commonTlsContext.getCombinedValidationContext();
1✔
115
      if (combinedValidationContext.hasDefaultValidationContext()) {
1✔
116
        return combinedValidationContext.getDefaultValidationContext();
1✔
117
      }
118
    }
119
    return null;
1✔
120
  }
121

122
  @Nullable
123
  protected static CommonTlsContext.CertificateProviderInstance getRootCertProviderInstance(
124
      CommonTlsContext commonTlsContext) {
125
    CertificateValidationContext certValidationContext = getStaticValidationContext(
1✔
126
        commonTlsContext);
127
    if (certValidationContext != null && certValidationContext.hasCaCertificateProviderInstance()) {
1✔
128
      return CommonTlsContextUtil.convert(certValidationContext.getCaCertificateProviderInstance());
1✔
129
    }
130
    if (commonTlsContext.hasCombinedValidationContext()) {
1✔
131
      CommonTlsContext.CombinedCertificateValidationContext combinedValidationContext =
1✔
132
          commonTlsContext.getCombinedValidationContext();
1✔
133
      if (combinedValidationContext.hasValidationContextCertificateProviderInstance()) {
1✔
134
        return combinedValidationContext.getValidationContextCertificateProviderInstance();
1✔
135
      }
136
    } else if (commonTlsContext.hasValidationContextCertificateProviderInstance()) {
1✔
137
      return commonTlsContext.getValidationContextCertificateProviderInstance();
×
138
    }
139
    return null;
1✔
140
  }
141

142
  @Override
143
  public final void updateCertificate(PrivateKey key, List<X509Certificate> certChain) {
144
    savedKey = key;
1✔
145
    savedCertChain = certChain;
1✔
146
    updateSslContextWhenReady();
1✔
147
  }
1✔
148

149
  @Override
150
  public final void updateTrustedRoots(List<X509Certificate> trustedRoots) {
151
    savedTrustedRoots = trustedRoots;
1✔
152
    updateSslContextWhenReady();
1✔
153
  }
1✔
154

155
  private void updateSslContextWhenReady() {
156
    if (isMtls()) {
1✔
157
      if (savedKey != null && (savedTrustedRoots != null || isUsingSystemRootCerts)) {
1✔
158
        updateSslContext();
1✔
159
        clearKeysAndCerts();
1✔
160
      }
161
    } else if (isClientSideTls()) {
1✔
162
      if (savedTrustedRoots != null) {
1✔
163
        updateSslContext();
1✔
164
        clearKeysAndCerts();
1✔
165
      }
166
    } else if (isServerSideTls()) {
1✔
167
      if (savedKey != null) {
1✔
168
        updateSslContext();
1✔
169
        clearKeysAndCerts();
1✔
170
      }
171
    }
172
  }
1✔
173

174
  private void clearKeysAndCerts() {
175
    savedKey = null;
1✔
176
    savedTrustedRoots = null;
1✔
177
    savedCertChain = null;
1✔
178
  }
1✔
179

180
  protected final boolean isMtls() {
181
    return certInstance != null && (rootCertInstance != null || isUsingSystemRootCerts);
1✔
182
  }
183

184
  protected final boolean isClientSideTls() {
185
    return rootCertInstance != null && certInstance == null;
1✔
186
  }
187

188
  protected final boolean isServerSideTls() {
189
    return certInstance != null && rootCertInstance == null;
1✔
190
  }
191

192
  @Override
193
  protected final CertificateValidationContext generateCertificateValidationContext() {
194
    return staticCertificateValidationContext;
1✔
195
  }
196

197
  @Override
198
  public final void close() {
199
    if (certHandle != null) {
1✔
200
      certHandle.close();
1✔
201
    }
202
    if (rootCertHandle != null) {
1✔
203
      rootCertHandle.close();
×
204
    }
205
  }
1✔
206
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc