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

grpc / grpc-java / #19544

08 Nov 2024 05:03AM UTC coverage: 84.607% (+0.04%) from 84.566%
#19544

push

github

web-flow
xds: Spiffe Trust Bundle Support (#11627)

Adds verification of SPIFFE based identities using SPIFFE trust bundles.

For in-progress gRFC A87.

34100 of 40304 relevant lines covered (84.61%)

0.85 hits per line

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

97.83
/../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
  @Nullable protected Map<String, List<X509Certificate>> savedSpiffeTrustMap;
45
  private final boolean isUsingSystemRootCerts;
46

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

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

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

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

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

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

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

156
  @Override
157
  public final void updateSpiffeTrustMap(Map<String, List<X509Certificate>> spiffeTrustMap) {
158
    savedSpiffeTrustMap = spiffeTrustMap;
1✔
159
    updateSslContextWhenReady();
1✔
160
  }
1✔
161

162
  private void updateSslContextWhenReady() {
163
    if (isMtls()) {
1✔
164
      if (savedKey != null
1✔
165
          && (savedTrustedRoots != null || isUsingSystemRootCerts || savedSpiffeTrustMap != null)) {
166
        updateSslContext();
1✔
167
        clearKeysAndCerts();
1✔
168
      }
169
    } else if (isClientSideTls()) {
1✔
170
      if (savedTrustedRoots != null || savedSpiffeTrustMap != null) {
1✔
171
        updateSslContext();
1✔
172
        clearKeysAndCerts();
1✔
173
      }
174
    } else if (isServerSideTls()) {
1✔
175
      if (savedKey != null) {
1✔
176
        updateSslContext();
1✔
177
        clearKeysAndCerts();
1✔
178
      }
179
    }
180
  }
1✔
181

182
  private void clearKeysAndCerts() {
183
    savedKey = null;
1✔
184
    savedTrustedRoots = null;
1✔
185
    savedSpiffeTrustMap = null;
1✔
186
    savedCertChain = null;
1✔
187
  }
1✔
188

189
  protected final boolean isMtls() {
190
    return certInstance != null && (rootCertInstance != null || isUsingSystemRootCerts);
1✔
191
  }
192

193
  protected final boolean isClientSideTls() {
194
    return rootCertInstance != null && certInstance == null;
1✔
195
  }
196

197
  protected final boolean isServerSideTls() {
198
    return certInstance != null && rootCertInstance == null;
1✔
199
  }
200

201
  @Override
202
  protected final CertificateValidationContext generateCertificateValidationContext() {
203
    return staticCertificateValidationContext;
1✔
204
  }
205

206
  @Override
207
  public final void close() {
208
    if (certHandle != null) {
1✔
209
      certHandle.close();
1✔
210
    }
211
    if (rootCertHandle != null) {
1✔
212
      rootCertHandle.close();
×
213
    }
214
  }
1✔
215
}
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

© 2025 Coveralls, Inc