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

grpc / grpc-java / #20002

29 Sep 2025 04:21PM UTC coverage: 88.592% (+0.02%) from 88.575%
#20002

push

github

web-flow
xds: xDS based SNI setting and SAN validation (#12378)

When using xDS credentials make SNI for the Tls handshake to be
configured via xDS, rather than use the channel authority as the SNI,
and make SAN validation to be able to use the SNI sent when so
instructed via xDS.

Implements A101.

34877 of 39368 relevant lines covered (88.59%)

0.89 hits per line

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

90.91
/../xds/src/main/java/io/grpc/xds/internal/security/SslContextProvider.java
1
/*
2
 * Copyright 2019 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;
18

19
import static com.google.common.base.Preconditions.checkNotNull;
20
import static com.google.common.base.Preconditions.checkState;
21

22
import com.google.common.annotations.VisibleForTesting;
23
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext;
24
import io.grpc.Internal;
25
import io.grpc.xds.EnvoyServerProtoData.BaseTlsContext;
26
import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext;
27
import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
28
import io.grpc.xds.internal.security.trust.XdsTrustManagerFactory;
29
import io.netty.handler.ssl.ClientAuth;
30
import io.netty.handler.ssl.SslContext;
31
import io.netty.handler.ssl.SslContextBuilder;
32
import java.io.IOException;
33
import java.security.cert.CertStoreException;
34
import java.security.cert.CertificateException;
35
import java.util.AbstractMap;
36
import java.util.concurrent.Executor;
37
import javax.net.ssl.X509TrustManager;
38

39
/**
40
 * A SslContextProvider is a "container" or provider of SslContext. This is used by gRPC-xds to
41
 * obtain an SslContext, so is not part of the public API of gRPC. This "container" may represent a
42
 * stream that is receiving the requested secret(s) or it could represent file-system based
43
 * secret(s) that are dynamic.
44
 */
45
@Internal
46
public abstract class SslContextProvider implements Closeable {
47

48
  protected final BaseTlsContext tlsContext;
49

50
  @VisibleForTesting public abstract static class Callback {
51
    private final Executor executor;
52

53
    protected Callback(Executor executor) {
1✔
54
      this.executor = executor;
1✔
55
    }
1✔
56

57
    @VisibleForTesting public Executor getExecutor() {
58
      return executor;
1✔
59
    }
60

61
    /** Informs callee of new/updated SslContext. */
62
    @VisibleForTesting public abstract void updateSslContextAndExtendedX509TrustManager(
63
        AbstractMap.SimpleImmutableEntry<SslContext, X509TrustManager> sslContext);
64

65
    /** Informs callee of an exception that was generated. */
66
    @VisibleForTesting protected abstract void onException(Throwable throwable);
67
  }
68

69
  protected SslContextProvider(BaseTlsContext tlsContext) {
1✔
70
    this.tlsContext = checkNotNull(tlsContext, "tlsContext");
1✔
71
  }
1✔
72

73
  protected CommonTlsContext getCommonTlsContext() {
74
    return tlsContext.getCommonTlsContext();
1✔
75
  }
76

77
  protected void setClientAuthValues(
78
      SslContextBuilder sslContextBuilder, XdsTrustManagerFactory xdsTrustManagerFactory)
79
      throws CertificateException, IOException, CertStoreException {
80
    DownstreamTlsContext downstreamTlsContext = getDownstreamTlsContext();
1✔
81
    if (xdsTrustManagerFactory != null) {
1✔
82
      sslContextBuilder.trustManager(xdsTrustManagerFactory);
1✔
83
      sslContextBuilder.clientAuth(
1✔
84
          downstreamTlsContext.isRequireClientCertificate()
1✔
85
              ? ClientAuth.REQUIRE
1✔
86
              : ClientAuth.OPTIONAL);
×
87
    } else {
88
      sslContextBuilder.clientAuth(ClientAuth.NONE);
1✔
89
    }
90
  }
1✔
91

92
  /** Returns the DownstreamTlsContext in this SslContextProvider if this is server side. **/
93
  public DownstreamTlsContext getDownstreamTlsContext() {
94
    checkState(tlsContext instanceof DownstreamTlsContext,
1✔
95
        "expected DownstreamTlsContext");
96
    return ((DownstreamTlsContext)tlsContext);
1✔
97
  }
98

99
  /** Returns the UpstreamTlsContext in this SslContextProvider if this is client side. **/
100
  public UpstreamTlsContext getUpstreamTlsContext() {
101
    checkState(tlsContext instanceof UpstreamTlsContext,
1✔
102
        "expected UpstreamTlsContext");
103
    return ((UpstreamTlsContext)tlsContext);
1✔
104
  }
105

106
  /** Closes this provider and releases any resources. */
107
  @Override
108
  public abstract void close();
109

110
  /**
111
   * Registers a callback on the given executor. The callback will run when SslContext becomes
112
   * available or immediately if the result is already available.
113
   */
114
  public abstract void addCallback(Callback callback);
115

116
  protected final void performCallback(
117
          final SslContextGetter sslContextGetter, final Callback callback) {
118
    checkNotNull(sslContextGetter, "sslContextGetter");
1✔
119
    checkNotNull(callback, "callback");
1✔
120
    callback.executor.execute(
1✔
121
        new Runnable() {
1✔
122
          @Override
123
          public void run() {
124
            try {
125
              AbstractMap.SimpleImmutableEntry<SslContext, X509TrustManager> sslContextAndTm =
1✔
126
                  sslContextGetter.get();
1✔
127
              callback.updateSslContextAndExtendedX509TrustManager(sslContextAndTm);
1✔
128
            } catch (Throwable e) {
×
129
              callback.onException(e);
×
130
            }
1✔
131
          }
1✔
132
        });
133
  }
1✔
134

135
  /** Allows implementations to compute or get SslContext. */
136
  protected interface SslContextGetter {
137
    AbstractMap.SimpleImmutableEntry<SslContext,X509TrustManager> get() throws Exception;
138
  }
139
}
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