MCPcopy
hub / github.com/grpc/grpc-go / ClientSideTLSConfig

Method ClientSideTLSConfig

internal/credentials/xds/handshake_info.go:160–209  ·  view source on GitHub ↗

ClientSideTLSConfig constructs a tls.Config to be used in a client-side handshake based on the contents of the HandshakeInfo. hostname is passed as a parameter here instead of being part of the HandshakeInfo because HandshakeInfo contains cluster-level security configuration that applies to all end

(ctx context.Context, hostname string)

Source from the content-addressed store, hash-verified

158// specific to each endpoint. This allows sharing a single HandshakeInfo
159// instance across multiple endpoints in the same cluster.
160func (hi *HandshakeInfo) ClientSideTLSConfig(ctx context.Context, hostname string) (*tls.Config, error) {
161 // On the client side, rootProvider is mandatory. IdentityProvider is
162 // optional based on whether the client is doing TLS or mTLS.
163 if hi.rootProvider == nil {
164 return nil, errors.New("xds: CertificateProvider to fetch trusted roots is missing, cannot perform TLS handshake. Please check configuration on the management server")
165 }
166 // Since the call to KeyMaterial() can block, we read the providers under
167 // the lock but call the actual function after releasing the lock.
168 rootProv, idProv := hi.rootProvider, hi.identityProvider
169
170 // InsecureSkipVerify needs to be set to true because we need to perform
171 // custom verification to check the SAN on the received certificate.
172 // Currently the Go stdlib does complete verification of the cert (which
173 // includes hostname verification) or none. We are forced to go with the
174 // latter and perform the normal cert validation ourselves.
175 cfg := &tls.Config{
176 InsecureSkipVerify: true,
177 NextProtos: []string{"h2"},
178 }
179
180 km, err := rootProv.KeyMaterial(ctx)
181 if err != nil {
182 return nil, fmt.Errorf("xds: fetching trusted roots from CertificateProvider failed: %v", err)
183 }
184 cfg.RootCAs = km.Roots
185
186 // If AutoHostSNI is true, and the endpoint hostname is present, we use the
187 // endpoint hostname as the SNI value and also for SAN validation.
188 // Otherwise, we use the SNI value from HandshakeInfo (which is configured
189 // by the control plane) and validating SANs based on that.
190 sni := hi.sni
191 if hi.useAutoHostSNI && hostname != "" {
192 sni = hostname
193 }
194
195 cfg.VerifyPeerCertificate = hi.buildVerifyFunc(km, true, sni)
196
197 if idProv != nil {
198 km, err := idProv.KeyMaterial(ctx)
199 if err != nil {
200 return nil, fmt.Errorf("xds: fetching identity certificates from CertificateProvider failed: %v", err)
201 }
202 cfg.Certificates = km.Certs
203 }
204
205 if envconfig.XDSSNIEnabled && sni != "" {
206 cfg.ServerName = sni
207 }
208 return cfg, nil
209}
210
211func (hi *HandshakeInfo) buildVerifyFunc(km *certprovider.KeyMaterial, isClient bool, sni string) func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
212 return func(rawCerts [][]byte, _ [][]*x509.Certificate) error {

Calls 3

buildVerifyFuncMethod · 0.95
KeyMaterialMethod · 0.65
ErrorfMethod · 0.65