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

grpc / grpc-java / #20023

21 Oct 2025 04:08PM UTC coverage: 88.596% (+0.03%) from 88.571%
#20023

push

github

web-flow
xds: Introduce flag for fallback to use the xds channel authority if no SNI is determined to be used. (#12422)

This is to allow the previous behavior if needed, and when the xds
channel authority is used as the SNI, it won't be used for the SAN
validation.

34951 of 39450 relevant lines covered (88.6%)

0.89 hits per line

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

78.18
/../xds/src/main/java/io/grpc/xds/internal/security/SslContextProviderSupplier.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;
18

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

21
import com.google.common.annotations.VisibleForTesting;
22
import com.google.common.base.MoreObjects;
23
import io.grpc.xds.EnvoyServerProtoData.BaseTlsContext;
24
import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext;
25
import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
26
import io.grpc.xds.TlsContextManager;
27
import io.netty.handler.ssl.SslContext;
28
import java.util.AbstractMap;
29
import java.util.Objects;
30
import javax.net.ssl.X509TrustManager;
31

32
/**
33
 * Enables Client or server side to initialize this object with the received {@link BaseTlsContext}
34
 * and communicate it to the consumer i.e. {@link SecurityProtocolNegotiators}
35
 * to lazily evaluate the {@link SslContextProvider}. The supplier prevents credentials leakage in
36
 * cases where the user is not using xDS credentials but the client/server contains a non-default
37
 * {@link BaseTlsContext}.
38
 */
39
public final class SslContextProviderSupplier implements Closeable {
40

41
  private final BaseTlsContext tlsContext;
42
  private final TlsContextManager tlsContextManager;
43
  private SslContextProvider sslContextProvider;
44
  private boolean shutdown;
45

46
  public SslContextProviderSupplier(
47
      BaseTlsContext tlsContext, TlsContextManager tlsContextManager) {
1✔
48
    this.tlsContext = checkNotNull(tlsContext, "tlsContext");
1✔
49
    this.tlsContextManager = checkNotNull(tlsContextManager, "tlsContextManager");
1✔
50
  }
1✔
51

52
  public BaseTlsContext getTlsContext() {
53
    return tlsContext;
1✔
54
  }
55

56
  /** Updates SslContext via the passed callback. */
57
  public synchronized void updateSslContext(
58
      final SslContextProvider.Callback callback, boolean autoSniSanValidationDoesNotApply) {
59
    checkNotNull(callback, "callback");
1✔
60
    try {
61
      if (!shutdown) {
1✔
62
        if (sslContextProvider == null) {
1✔
63
          sslContextProvider = getSslContextProvider();
1✔
64
          if (tlsContext instanceof UpstreamTlsContext && autoSniSanValidationDoesNotApply) {
1✔
65
            ((DynamicSslContextProvider) sslContextProvider).setAutoSniSanValidationDoesNotApply();
×
66
          }
67
        }
68
      }
69
      // we want to increment the ref-count so call findOrCreate again...
70
      final SslContextProvider toRelease = getSslContextProvider();
1✔
71
      toRelease.addCallback(
1✔
72
          new SslContextProvider.Callback(callback.getExecutor()) {
1✔
73

74
            @Override
75
            public void updateSslContextAndExtendedX509TrustManager(
76
                AbstractMap.SimpleImmutableEntry<SslContext, X509TrustManager> sslContextAndTm) {
77
              callback.updateSslContextAndExtendedX509TrustManager(sslContextAndTm);
1✔
78
              releaseSslContextProvider(toRelease);
1✔
79
            }
1✔
80

81
            @Override
82
            public void onException(Throwable throwable) {
83
              callback.onException(throwable);
1✔
84
              releaseSslContextProvider(toRelease);
1✔
85
            }
1✔
86
          });
87
    } catch (final Throwable throwable) {
×
88
      callback.getExecutor().execute(new Runnable() {
×
89
        @Override
90
        public void run() {
91
          callback.onException(throwable);
×
92
        }
×
93
      });
94
    }
1✔
95
  }
1✔
96

97
  private void releaseSslContextProvider(SslContextProvider toRelease) {
98
    if (tlsContext instanceof UpstreamTlsContext) {
1✔
99
      tlsContextManager.releaseClientSslContextProvider(toRelease);
1✔
100
    } else {
101
      tlsContextManager.releaseServerSslContextProvider(toRelease);
1✔
102
    }
103
  }
1✔
104

105
  private SslContextProvider getSslContextProvider() {
106
    return tlsContext instanceof UpstreamTlsContext
1✔
107
        ? tlsContextManager.findOrCreateClientSslContextProvider((UpstreamTlsContext) tlsContext)
1✔
108
        : tlsContextManager.findOrCreateServerSslContextProvider(
1✔
109
            (DownstreamTlsContext) tlsContext);
110
  }
111

112
  @VisibleForTesting public boolean isShutdown() {
113
    return shutdown;
1✔
114
  }
115

116
  /** Called by consumer when tlsContext changes. */
117
  @Override
118
  public synchronized void close() {
119
    if (sslContextProvider != null) {
1✔
120
      if (tlsContext instanceof UpstreamTlsContext) {
1✔
121
        tlsContextManager.releaseClientSslContextProvider(sslContextProvider);
1✔
122
      } else {
123
        tlsContextManager.releaseServerSslContextProvider(sslContextProvider);
1✔
124
      }
125
    }
126
    sslContextProvider = null;
1✔
127
    shutdown = true;
1✔
128
  }
1✔
129

130
  @Override
131
  public boolean equals(Object o) {
132
    if (this == o) {
×
133
      return true;
×
134
    }
135
    if (o == null || getClass() != o.getClass()) {
×
136
      return false;
×
137
    }
138
    SslContextProviderSupplier that = (SslContextProviderSupplier) o;
×
139
    return Objects.equals(tlsContext, that.tlsContext)
×
140
        && Objects.equals(tlsContextManager, that.tlsContextManager);
×
141
  }
142

143
  @Override
144
  public int hashCode() {
145
    return Objects.hash(tlsContext, tlsContextManager);
1✔
146
  }
147

148
  @Override
149
  public String toString() {
150
    return MoreObjects.toStringHelper(this)
1✔
151
        .add("tlsContext", tlsContext)
1✔
152
        .add("tlsContextManager", tlsContextManager)
1✔
153
        .add("sslContextProvider", sslContextProvider)
1✔
154
        .add("shutdown", shutdown)
1✔
155
        .toString();
1✔
156
  }
157
}
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