mirror of https://github.com/grpc/grpc-go.git
credentials/xds: Move non-user facing functionality to an internal package (#4117)
This commit is contained in:
parent
644d506ebb
commit
d79063fdde
|
@ -32,21 +32,13 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"google.golang.org/grpc/attributes"
|
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/credentials/tls/certprovider"
|
|
||||||
"google.golang.org/grpc/internal"
|
|
||||||
credinternal "google.golang.org/grpc/internal/credentials"
|
credinternal "google.golang.org/grpc/internal/credentials"
|
||||||
"google.golang.org/grpc/resolver"
|
xdsinternal "google.golang.org/grpc/internal/credentials/xds"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
internal.GetXDSHandshakeInfoForTesting = getHandshakeInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientOptions contains parameters to configure a new client-side xDS
|
// ClientOptions contains parameters to configure a new client-side xDS
|
||||||
// credentials implementation.
|
// credentials implementation.
|
||||||
type ClientOptions struct {
|
type ClientOptions struct {
|
||||||
|
@ -97,193 +89,6 @@ type credsImpl struct {
|
||||||
fallback credentials.TransportCredentials
|
fallback credentials.TransportCredentials
|
||||||
}
|
}
|
||||||
|
|
||||||
// handshakeAttrKey is the type used as the key to store HandshakeInfo in
|
|
||||||
// the Attributes field of resolver.Address.
|
|
||||||
type handshakeAttrKey struct{}
|
|
||||||
|
|
||||||
// SetHandshakeInfo returns a copy of addr in which the Attributes field is
|
|
||||||
// updated with hInfo.
|
|
||||||
func SetHandshakeInfo(addr resolver.Address, hInfo *HandshakeInfo) resolver.Address {
|
|
||||||
addr.Attributes = addr.Attributes.WithValues(handshakeAttrKey{}, hInfo)
|
|
||||||
return addr
|
|
||||||
}
|
|
||||||
|
|
||||||
// getHandshakeInfo returns a pointer to the HandshakeInfo stored in attr.
|
|
||||||
func getHandshakeInfo(attr *attributes.Attributes) *HandshakeInfo {
|
|
||||||
v := attr.Value(handshakeAttrKey{})
|
|
||||||
hi, _ := v.(*HandshakeInfo)
|
|
||||||
return hi
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandshakeInfo wraps all the security configuration required by client and
|
|
||||||
// server handshake methods in credsImpl. The xDS implementation will be
|
|
||||||
// responsible for populating these fields.
|
|
||||||
//
|
|
||||||
// Safe for concurrent access.
|
|
||||||
//
|
|
||||||
// TODO(easwars): Move this type and any other non-user functionality to an
|
|
||||||
// internal package.
|
|
||||||
type HandshakeInfo struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
rootProvider certprovider.Provider
|
|
||||||
identityProvider certprovider.Provider
|
|
||||||
acceptedSANs map[string]bool // Only on the client side.
|
|
||||||
requireClientCert bool // Only on server side.
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRootCertProvider updates the root certificate provider.
|
|
||||||
func (hi *HandshakeInfo) SetRootCertProvider(root certprovider.Provider) {
|
|
||||||
hi.mu.Lock()
|
|
||||||
hi.rootProvider = root
|
|
||||||
hi.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetIdentityCertProvider updates the identity certificate provider.
|
|
||||||
func (hi *HandshakeInfo) SetIdentityCertProvider(identity certprovider.Provider) {
|
|
||||||
hi.mu.Lock()
|
|
||||||
hi.identityProvider = identity
|
|
||||||
hi.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetAcceptedSANs updates the list of accepted SANs.
|
|
||||||
func (hi *HandshakeInfo) SetAcceptedSANs(sans []string) {
|
|
||||||
hi.mu.Lock()
|
|
||||||
hi.acceptedSANs = make(map[string]bool, len(sans))
|
|
||||||
for _, san := range sans {
|
|
||||||
hi.acceptedSANs[san] = true
|
|
||||||
}
|
|
||||||
hi.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRequireClientCert updates whether a client cert is required during the
|
|
||||||
// ServerHandshake(). A value of true indicates that we are performing mTLS.
|
|
||||||
func (hi *HandshakeInfo) SetRequireClientCert(require bool) {
|
|
||||||
hi.mu.Lock()
|
|
||||||
hi.requireClientCert = require
|
|
||||||
hi.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UseFallbackCreds returns true when fallback credentials are to be used based
|
|
||||||
// on the contents of the HandshakeInfo.
|
|
||||||
func (hi *HandshakeInfo) UseFallbackCreds() bool {
|
|
||||||
if hi == nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
hi.mu.Lock()
|
|
||||||
defer hi.mu.Unlock()
|
|
||||||
return hi.identityProvider == nil && hi.rootProvider == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hi *HandshakeInfo) makeClientSideTLSConfig(ctx context.Context) (*tls.Config, error) {
|
|
||||||
hi.mu.Lock()
|
|
||||||
// On the client side, rootProvider is mandatory. IdentityProvider is
|
|
||||||
// optional based on whether the client is doing TLS or mTLS.
|
|
||||||
if hi.rootProvider == nil {
|
|
||||||
return nil, errors.New("xds: CertificateProvider to fetch trusted roots is missing, cannot perform TLS handshake. Please check configuration on the management server")
|
|
||||||
}
|
|
||||||
// Since the call to KeyMaterial() can block, we read the providers under
|
|
||||||
// the lock but call the actual function after releasing the lock.
|
|
||||||
rootProv, idProv := hi.rootProvider, hi.identityProvider
|
|
||||||
hi.mu.Unlock()
|
|
||||||
|
|
||||||
// InsecureSkipVerify needs to be set to true because we need to perform
|
|
||||||
// custom verification to check the SAN on the received certificate.
|
|
||||||
// Currently the Go stdlib does complete verification of the cert (which
|
|
||||||
// includes hostname verification) or none. We are forced to go with the
|
|
||||||
// latter and perform the normal cert validation ourselves.
|
|
||||||
cfg := &tls.Config{InsecureSkipVerify: true}
|
|
||||||
|
|
||||||
km, err := rootProv.KeyMaterial(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("xds: fetching trusted roots from CertificateProvider failed: %v", err)
|
|
||||||
}
|
|
||||||
cfg.RootCAs = km.Roots
|
|
||||||
|
|
||||||
if idProv != nil {
|
|
||||||
km, err := idProv.KeyMaterial(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("xds: fetching identity certificates from CertificateProvider failed: %v", err)
|
|
||||||
}
|
|
||||||
cfg.Certificates = km.Certs
|
|
||||||
}
|
|
||||||
return cfg, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hi *HandshakeInfo) makeServerSideTLSConfig(ctx context.Context) (*tls.Config, error) {
|
|
||||||
cfg := &tls.Config{ClientAuth: tls.NoClientCert}
|
|
||||||
hi.mu.Lock()
|
|
||||||
// On the server side, identityProvider is mandatory. RootProvider is
|
|
||||||
// optional based on whether the server is doing TLS or mTLS.
|
|
||||||
if hi.identityProvider == nil {
|
|
||||||
return nil, errors.New("xds: CertificateProvider to fetch identity certificate is missing, cannot perform TLS handshake. Please check configuration on the management server")
|
|
||||||
}
|
|
||||||
// Since the call to KeyMaterial() can block, we read the providers under
|
|
||||||
// the lock but call the actual function after releasing the lock.
|
|
||||||
rootProv, idProv := hi.rootProvider, hi.identityProvider
|
|
||||||
if hi.requireClientCert {
|
|
||||||
cfg.ClientAuth = tls.RequireAndVerifyClientCert
|
|
||||||
}
|
|
||||||
hi.mu.Unlock()
|
|
||||||
|
|
||||||
// identityProvider is mandatory on the server side.
|
|
||||||
km, err := idProv.KeyMaterial(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("xds: fetching identity certificates from CertificateProvider failed: %v", err)
|
|
||||||
}
|
|
||||||
cfg.Certificates = km.Certs
|
|
||||||
|
|
||||||
if rootProv != nil {
|
|
||||||
km, err := rootProv.KeyMaterial(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("xds: fetching trusted roots from CertificateProvider failed: %v", err)
|
|
||||||
}
|
|
||||||
cfg.ClientCAs = km.Roots
|
|
||||||
}
|
|
||||||
return cfg, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hi *HandshakeInfo) matchingSANExists(cert *x509.Certificate) bool {
|
|
||||||
if len(hi.acceptedSANs) == 0 {
|
|
||||||
// An empty list of acceptedSANs means "accept everything".
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
var sans []string
|
|
||||||
// SANs can be specified in any of these four fields on the parsed cert.
|
|
||||||
sans = append(sans, cert.DNSNames...)
|
|
||||||
sans = append(sans, cert.EmailAddresses...)
|
|
||||||
for _, ip := range cert.IPAddresses {
|
|
||||||
sans = append(sans, ip.String())
|
|
||||||
}
|
|
||||||
for _, uri := range cert.URIs {
|
|
||||||
sans = append(sans, uri.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
hi.mu.Lock()
|
|
||||||
defer hi.mu.Unlock()
|
|
||||||
for _, san := range sans {
|
|
||||||
if hi.acceptedSANs[san] {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewHandshakeInfo returns a new instance of HandshakeInfo with the given root
|
|
||||||
// and identity certificate providers.
|
|
||||||
func NewHandshakeInfo(root, identity certprovider.Provider, sans ...string) *HandshakeInfo {
|
|
||||||
acceptedSANs := make(map[string]bool, len(sans))
|
|
||||||
for _, san := range sans {
|
|
||||||
acceptedSANs[san] = true
|
|
||||||
}
|
|
||||||
return &HandshakeInfo{
|
|
||||||
rootProvider: root,
|
|
||||||
identityProvider: identity,
|
|
||||||
acceptedSANs: acceptedSANs,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientHandshake performs the TLS handshake on the client-side.
|
// ClientHandshake performs the TLS handshake on the client-side.
|
||||||
//
|
//
|
||||||
// It looks for the presence of a HandshakeInfo value in the passed in context
|
// It looks for the presence of a HandshakeInfo value in the passed in context
|
||||||
|
@ -314,7 +119,7 @@ func (c *credsImpl) ClientHandshake(ctx context.Context, authority string, rawCo
|
||||||
if chi.Attributes == nil {
|
if chi.Attributes == nil {
|
||||||
return c.fallback.ClientHandshake(ctx, authority, rawConn)
|
return c.fallback.ClientHandshake(ctx, authority, rawConn)
|
||||||
}
|
}
|
||||||
hi := getHandshakeInfo(chi.Attributes)
|
hi := xdsinternal.GetHandshakeInfo(chi.Attributes)
|
||||||
if hi.UseFallbackCreds() {
|
if hi.UseFallbackCreds() {
|
||||||
return c.fallback.ClientHandshake(ctx, authority, rawConn)
|
return c.fallback.ClientHandshake(ctx, authority, rawConn)
|
||||||
}
|
}
|
||||||
|
@ -331,7 +136,7 @@ func (c *credsImpl) ClientHandshake(ctx context.Context, authority string, rawCo
|
||||||
// 4. Key usage to match whether client/server usage.
|
// 4. Key usage to match whether client/server usage.
|
||||||
// 5. A `VerifyPeerCertificate` function which performs normal peer
|
// 5. A `VerifyPeerCertificate` function which performs normal peer
|
||||||
// cert verification using configured roots, and the custom SAN checks.
|
// cert verification using configured roots, and the custom SAN checks.
|
||||||
cfg, err := hi.makeClientSideTLSConfig(ctx)
|
cfg, err := hi.ClientSideTLSConfig(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -362,7 +167,7 @@ func (c *credsImpl) ClientHandshake(ctx context.Context, authority string, rawCo
|
||||||
}
|
}
|
||||||
// The SANs sent by the MeshCA are encoded as SPIFFE IDs. We need to
|
// The SANs sent by the MeshCA are encoded as SPIFFE IDs. We need to
|
||||||
// only look at the SANs on the leaf cert.
|
// only look at the SANs on the leaf cert.
|
||||||
if !hi.matchingSANExists(certs[0]) {
|
if !hi.MatchingSANExists(certs[0]) {
|
||||||
return fmt.Errorf("SANs received in leaf certificate %+v does not match any of the accepted SANs", certs[0])
|
return fmt.Errorf("SANs received in leaf certificate %+v does not match any of the accepted SANs", certs[0])
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -410,7 +215,9 @@ func (c *credsImpl) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.Aut
|
||||||
// passed to this function does not implement this interface, or if the
|
// passed to this function does not implement this interface, or if the
|
||||||
// `HandshakeInfo` does not contain the information we are looking for, we
|
// `HandshakeInfo` does not contain the information we are looking for, we
|
||||||
// delegate the handshake to the fallback credentials.
|
// delegate the handshake to the fallback credentials.
|
||||||
hiConn, ok := rawConn.(interface{ XDSHandshakeInfo() *HandshakeInfo })
|
hiConn, ok := rawConn.(interface {
|
||||||
|
XDSHandshakeInfo() *xdsinternal.HandshakeInfo
|
||||||
|
})
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.fallback.ServerHandshake(rawConn)
|
return c.fallback.ServerHandshake(rawConn)
|
||||||
}
|
}
|
||||||
|
@ -430,7 +237,7 @@ func (c *credsImpl) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.Aut
|
||||||
}
|
}
|
||||||
ctx, cancel := context.WithDeadline(context.Background(), deadline)
|
ctx, cancel := context.WithDeadline(context.Background(), deadline)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
cfg, err := hi.makeServerSideTLSConfig(ctx)
|
cfg, err := hi.ServerSideTLSConfig(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import (
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/credentials/tls/certprovider"
|
"google.golang.org/grpc/credentials/tls/certprovider"
|
||||||
"google.golang.org/grpc/internal"
|
"google.golang.org/grpc/internal"
|
||||||
|
xdsinternal "google.golang.org/grpc/internal/credentials/xds"
|
||||||
"google.golang.org/grpc/internal/grpctest"
|
"google.golang.org/grpc/internal/grpctest"
|
||||||
"google.golang.org/grpc/internal/testutils"
|
"google.golang.org/grpc/internal/testutils"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
|
@ -217,8 +218,8 @@ func newTestContextWithHandshakeInfo(parent context.Context, root, identity cert
|
||||||
// Creating the HandshakeInfo and adding it to the attributes is very
|
// Creating the HandshakeInfo and adding it to the attributes is very
|
||||||
// similar to what the CDS balancer would do when it intercepts calls to
|
// similar to what the CDS balancer would do when it intercepts calls to
|
||||||
// NewSubConn().
|
// NewSubConn().
|
||||||
info := NewHandshakeInfo(root, identity, sans...)
|
info := xdsinternal.NewHandshakeInfo(root, identity, sans...)
|
||||||
addr := SetHandshakeInfo(resolver.Address{}, info)
|
addr := xdsinternal.SetHandshakeInfo(resolver.Address{}, info)
|
||||||
|
|
||||||
// Moving the attributes from the resolver.Address to the context passed to
|
// Moving the attributes from the resolver.Address to the context passed to
|
||||||
// the handshaker is done in the transport layer. Since we directly call the
|
// the handshaker is done in the transport layer. Since we directly call the
|
||||||
|
@ -529,12 +530,12 @@ func (s) TestClientCredsProviderSwitch(t *testing.T) {
|
||||||
// Create a root provider which will fail the handshake because it does not
|
// Create a root provider which will fail the handshake because it does not
|
||||||
// use the correct trust roots.
|
// use the correct trust roots.
|
||||||
root1 := makeRootProvider(t, "x509/client_ca_cert.pem")
|
root1 := makeRootProvider(t, "x509/client_ca_cert.pem")
|
||||||
handshakeInfo := NewHandshakeInfo(root1, nil, defaultTestCertSAN)
|
handshakeInfo := xdsinternal.NewHandshakeInfo(root1, nil, defaultTestCertSAN)
|
||||||
|
|
||||||
// We need to repeat most of what newTestContextWithHandshakeInfo() does
|
// We need to repeat most of what newTestContextWithHandshakeInfo() does
|
||||||
// here because we need access to the underlying HandshakeInfo so that we
|
// here because we need access to the underlying HandshakeInfo so that we
|
||||||
// can update it before the next call to ClientHandshake().
|
// can update it before the next call to ClientHandshake().
|
||||||
addr := SetHandshakeInfo(resolver.Address{}, handshakeInfo)
|
addr := xdsinternal.SetHandshakeInfo(resolver.Address{}, handshakeInfo)
|
||||||
contextWithHandshakeInfo := internal.NewClientHandshakeInfoContext.(func(context.Context, credentials.ClientHandshakeInfo) context.Context)
|
contextWithHandshakeInfo := internal.NewClientHandshakeInfoContext.(func(context.Context, credentials.ClientHandshakeInfo) context.Context)
|
||||||
ctx = contextWithHandshakeInfo(ctx, credentials.ClientHandshakeInfo{Attributes: addr.Attributes})
|
ctx = contextWithHandshakeInfo(ctx, credentials.ClientHandshakeInfo{Attributes: addr.Attributes})
|
||||||
if _, _, err := creds.ClientHandshake(ctx, authority, conn); err == nil {
|
if _, _, err := creds.ClientHandshake(ctx, authority, conn); err == nil {
|
||||||
|
|
|
@ -32,6 +32,7 @@ import (
|
||||||
|
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/credentials/tls/certprovider"
|
"google.golang.org/grpc/credentials/tls/certprovider"
|
||||||
|
xdsinternal "google.golang.org/grpc/internal/credentials/xds"
|
||||||
"google.golang.org/grpc/testdata"
|
"google.golang.org/grpc/testdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -94,11 +95,11 @@ func (s) TestServerCredsWithoutFallback(t *testing.T) {
|
||||||
|
|
||||||
type wrapperConn struct {
|
type wrapperConn struct {
|
||||||
net.Conn
|
net.Conn
|
||||||
xdsHI *HandshakeInfo
|
xdsHI *xdsinternal.HandshakeInfo
|
||||||
deadline time.Time
|
deadline time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wc *wrapperConn) XDSHandshakeInfo() *HandshakeInfo {
|
func (wc *wrapperConn) XDSHandshakeInfo() *xdsinternal.HandshakeInfo {
|
||||||
return wc.xdsHI
|
return wc.xdsHI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +107,7 @@ func (wc *wrapperConn) GetDeadline() time.Time {
|
||||||
return wc.deadline
|
return wc.deadline
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWrappedConn(conn net.Conn, xdsHI *HandshakeInfo, deadline time.Time) *wrapperConn {
|
func newWrappedConn(conn net.Conn, xdsHI *xdsinternal.HandshakeInfo, deadline time.Time) *wrapperConn {
|
||||||
return &wrapperConn{Conn: conn, xdsHI: xdsHI, deadline: deadline}
|
return &wrapperConn{Conn: conn, xdsHI: xdsHI, deadline: deadline}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@ func (s) TestServerCredsInvalidHandshakeInfo(t *testing.T) {
|
||||||
t.Fatalf("NewServerCredentials(%v) failed: %v", opts, err)
|
t.Fatalf("NewServerCredentials(%v) failed: %v", opts, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
info := NewHandshakeInfo(&fakeProvider{}, nil)
|
info := xdsinternal.NewHandshakeInfo(&fakeProvider{}, nil)
|
||||||
conn := newWrappedConn(nil, info, time.Time{})
|
conn := newWrappedConn(nil, info, time.Time{})
|
||||||
if _, _, err := creds.ServerHandshake(conn); err == nil {
|
if _, _, err := creds.ServerHandshake(conn); err == nil {
|
||||||
t.Fatal("ServerHandshake succeeded without identity certificate provider in HandshakeInfo")
|
t.Fatal("ServerHandshake succeeded without identity certificate provider in HandshakeInfo")
|
||||||
|
@ -156,7 +157,7 @@ func (s) TestServerCredsProviderFailure(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
info := NewHandshakeInfo(test.rootProvider, test.identityProvider)
|
info := xdsinternal.NewHandshakeInfo(test.rootProvider, test.identityProvider)
|
||||||
conn := newWrappedConn(nil, info, time.Time{})
|
conn := newWrappedConn(nil, info, time.Time{})
|
||||||
if _, _, err := creds.ServerHandshake(conn); err == nil || !strings.Contains(err.Error(), test.wantErr) {
|
if _, _, err := creds.ServerHandshake(conn); err == nil || !strings.Contains(err.Error(), test.wantErr) {
|
||||||
t.Fatalf("ServerHandshake() returned error: %q, wantErr: %q", err, test.wantErr)
|
t.Fatalf("ServerHandshake() returned error: %q, wantErr: %q", err, test.wantErr)
|
||||||
|
@ -178,7 +179,7 @@ func (s) TestServerCredsHandshakeTimeout(t *testing.T) {
|
||||||
// Create a test server which uses the xDS server credentials created above
|
// Create a test server which uses the xDS server credentials created above
|
||||||
// to perform TLS handshake on incoming connections.
|
// to perform TLS handshake on incoming connections.
|
||||||
ts := newTestServerWithHandshakeFunc(func(rawConn net.Conn) handshakeResult {
|
ts := newTestServerWithHandshakeFunc(func(rawConn net.Conn) handshakeResult {
|
||||||
hi := NewHandshakeInfo(makeRootProvider(t, "x509/client_ca_cert.pem"), makeIdentityProvider(t, "x509/server2_cert.pem", "x509/server2_key.pem"))
|
hi := xdsinternal.NewHandshakeInfo(makeRootProvider(t, "x509/client_ca_cert.pem"), makeIdentityProvider(t, "x509/server2_cert.pem", "x509/server2_key.pem"))
|
||||||
hi.SetRequireClientCert(true)
|
hi.SetRequireClientCert(true)
|
||||||
|
|
||||||
// Create a wrapped conn which can return the HandshakeInfo created
|
// Create a wrapped conn which can return the HandshakeInfo created
|
||||||
|
@ -231,7 +232,7 @@ func (s) TestServerCredsHandshakeFailure(t *testing.T) {
|
||||||
ts := newTestServerWithHandshakeFunc(func(rawConn net.Conn) handshakeResult {
|
ts := newTestServerWithHandshakeFunc(func(rawConn net.Conn) handshakeResult {
|
||||||
// Create a HandshakeInfo which has a root provider which does not match
|
// Create a HandshakeInfo which has a root provider which does not match
|
||||||
// the certificate sent by the client.
|
// the certificate sent by the client.
|
||||||
hi := NewHandshakeInfo(makeRootProvider(t, "x509/server_ca_cert.pem"), makeIdentityProvider(t, "x509/client2_cert.pem", "x509/client2_key.pem"))
|
hi := xdsinternal.NewHandshakeInfo(makeRootProvider(t, "x509/server_ca_cert.pem"), makeIdentityProvider(t, "x509/client2_cert.pem", "x509/client2_key.pem"))
|
||||||
hi.SetRequireClientCert(true)
|
hi.SetRequireClientCert(true)
|
||||||
|
|
||||||
// Create a wrapped conn which can return the HandshakeInfo and
|
// Create a wrapped conn which can return the HandshakeInfo and
|
||||||
|
@ -313,7 +314,7 @@ func (s) TestServerCredsHandshakeSuccess(t *testing.T) {
|
||||||
// created above to perform TLS handshake on incoming connections.
|
// created above to perform TLS handshake on incoming connections.
|
||||||
ts := newTestServerWithHandshakeFunc(func(rawConn net.Conn) handshakeResult {
|
ts := newTestServerWithHandshakeFunc(func(rawConn net.Conn) handshakeResult {
|
||||||
// Create a HandshakeInfo with information from the test table.
|
// Create a HandshakeInfo with information from the test table.
|
||||||
hi := NewHandshakeInfo(test.rootProvider, test.identityProvider)
|
hi := xdsinternal.NewHandshakeInfo(test.rootProvider, test.identityProvider)
|
||||||
hi.SetRequireClientCert(test.requireClientCert)
|
hi.SetRequireClientCert(test.requireClientCert)
|
||||||
|
|
||||||
// Create a wrapped conn which can return the HandshakeInfo and
|
// Create a wrapped conn which can return the HandshakeInfo and
|
||||||
|
@ -390,11 +391,11 @@ func (s) TestServerCredsProviderSwitch(t *testing.T) {
|
||||||
// to perform TLS handshake on incoming connections.
|
// to perform TLS handshake on incoming connections.
|
||||||
ts := newTestServerWithHandshakeFunc(func(rawConn net.Conn) handshakeResult {
|
ts := newTestServerWithHandshakeFunc(func(rawConn net.Conn) handshakeResult {
|
||||||
cnt++
|
cnt++
|
||||||
var hi *HandshakeInfo
|
var hi *xdsinternal.HandshakeInfo
|
||||||
if cnt == 1 {
|
if cnt == 1 {
|
||||||
// Create a HandshakeInfo which has a root provider which does not match
|
// Create a HandshakeInfo which has a root provider which does not match
|
||||||
// the certificate sent by the client.
|
// the certificate sent by the client.
|
||||||
hi = NewHandshakeInfo(makeRootProvider(t, "x509/server_ca_cert.pem"), makeIdentityProvider(t, "x509/client2_cert.pem", "x509/client2_key.pem"))
|
hi = xdsinternal.NewHandshakeInfo(makeRootProvider(t, "x509/server_ca_cert.pem"), makeIdentityProvider(t, "x509/client2_cert.pem", "x509/client2_key.pem"))
|
||||||
hi.SetRequireClientCert(true)
|
hi.SetRequireClientCert(true)
|
||||||
|
|
||||||
// Create a wrapped conn which can return the HandshakeInfo and
|
// Create a wrapped conn which can return the HandshakeInfo and
|
||||||
|
@ -409,7 +410,7 @@ func (s) TestServerCredsProviderSwitch(t *testing.T) {
|
||||||
return handshakeResult{}
|
return handshakeResult{}
|
||||||
}
|
}
|
||||||
|
|
||||||
hi = NewHandshakeInfo(makeRootProvider(t, "x509/client_ca_cert.pem"), makeIdentityProvider(t, "x509/server1_cert.pem", "x509/server1_key.pem"))
|
hi = xdsinternal.NewHandshakeInfo(makeRootProvider(t, "x509/client_ca_cert.pem"), makeIdentityProvider(t, "x509/server1_cert.pem", "x509/server1_key.pem"))
|
||||||
hi.SetRequireClientCert(true)
|
hi.SetRequireClientCert(true)
|
||||||
|
|
||||||
// Create a wrapped conn which can return the HandshakeInfo and
|
// Create a wrapped conn which can return the HandshakeInfo and
|
||||||
|
|
|
@ -0,0 +1,230 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2020 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Package xds contains non-user facing functionality of the xds credentials.
|
||||||
|
package xds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/attributes"
|
||||||
|
"google.golang.org/grpc/credentials/tls/certprovider"
|
||||||
|
"google.golang.org/grpc/internal"
|
||||||
|
"google.golang.org/grpc/resolver"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
internal.GetXDSHandshakeInfoForTesting = GetHandshakeInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// handshakeAttrKey is the type used as the key to store HandshakeInfo in
|
||||||
|
// the Attributes field of resolver.Address.
|
||||||
|
type handshakeAttrKey struct{}
|
||||||
|
|
||||||
|
// SetHandshakeInfo returns a copy of addr in which the Attributes field is
|
||||||
|
// updated with hInfo.
|
||||||
|
func SetHandshakeInfo(addr resolver.Address, hInfo *HandshakeInfo) resolver.Address {
|
||||||
|
addr.Attributes = addr.Attributes.WithValues(handshakeAttrKey{}, hInfo)
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHandshakeInfo returns a pointer to the HandshakeInfo stored in attr.
|
||||||
|
func GetHandshakeInfo(attr *attributes.Attributes) *HandshakeInfo {
|
||||||
|
v := attr.Value(handshakeAttrKey{})
|
||||||
|
hi, _ := v.(*HandshakeInfo)
|
||||||
|
return hi
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandshakeInfo wraps all the security configuration required by client and
|
||||||
|
// server handshake methods in xds credentials. The xDS implementation will be
|
||||||
|
// responsible for populating these fields.
|
||||||
|
//
|
||||||
|
// Safe for concurrent access.
|
||||||
|
type HandshakeInfo struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
rootProvider certprovider.Provider
|
||||||
|
identityProvider certprovider.Provider
|
||||||
|
acceptedSANs map[string]bool // Only on the client side.
|
||||||
|
requireClientCert bool // Only on server side.
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRootCertProvider updates the root certificate provider.
|
||||||
|
func (hi *HandshakeInfo) SetRootCertProvider(root certprovider.Provider) {
|
||||||
|
hi.mu.Lock()
|
||||||
|
hi.rootProvider = root
|
||||||
|
hi.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetIdentityCertProvider updates the identity certificate provider.
|
||||||
|
func (hi *HandshakeInfo) SetIdentityCertProvider(identity certprovider.Provider) {
|
||||||
|
hi.mu.Lock()
|
||||||
|
hi.identityProvider = identity
|
||||||
|
hi.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAcceptedSANs updates the list of accepted SANs.
|
||||||
|
func (hi *HandshakeInfo) SetAcceptedSANs(sans []string) {
|
||||||
|
hi.mu.Lock()
|
||||||
|
hi.acceptedSANs = make(map[string]bool, len(sans))
|
||||||
|
for _, san := range sans {
|
||||||
|
hi.acceptedSANs[san] = true
|
||||||
|
}
|
||||||
|
hi.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRequireClientCert updates whether a client cert is required during the
|
||||||
|
// ServerHandshake(). A value of true indicates that we are performing mTLS.
|
||||||
|
func (hi *HandshakeInfo) SetRequireClientCert(require bool) {
|
||||||
|
hi.mu.Lock()
|
||||||
|
hi.requireClientCert = require
|
||||||
|
hi.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UseFallbackCreds returns true when fallback credentials are to be used based
|
||||||
|
// on the contents of the HandshakeInfo.
|
||||||
|
func (hi *HandshakeInfo) UseFallbackCreds() bool {
|
||||||
|
if hi == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
hi.mu.Lock()
|
||||||
|
defer hi.mu.Unlock()
|
||||||
|
return hi.identityProvider == nil && hi.rootProvider == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientSideTLSConfig constructs a tls.Config to be used in a client-side
|
||||||
|
// handshake based on the contents of the HandshakeInfo.
|
||||||
|
func (hi *HandshakeInfo) ClientSideTLSConfig(ctx context.Context) (*tls.Config, error) {
|
||||||
|
hi.mu.Lock()
|
||||||
|
// On the client side, rootProvider is mandatory. IdentityProvider is
|
||||||
|
// optional based on whether the client is doing TLS or mTLS.
|
||||||
|
if hi.rootProvider == nil {
|
||||||
|
return nil, errors.New("xds: CertificateProvider to fetch trusted roots is missing, cannot perform TLS handshake. Please check configuration on the management server")
|
||||||
|
}
|
||||||
|
// Since the call to KeyMaterial() can block, we read the providers under
|
||||||
|
// the lock but call the actual function after releasing the lock.
|
||||||
|
rootProv, idProv := hi.rootProvider, hi.identityProvider
|
||||||
|
hi.mu.Unlock()
|
||||||
|
|
||||||
|
// InsecureSkipVerify needs to be set to true because we need to perform
|
||||||
|
// custom verification to check the SAN on the received certificate.
|
||||||
|
// Currently the Go stdlib does complete verification of the cert (which
|
||||||
|
// includes hostname verification) or none. We are forced to go with the
|
||||||
|
// latter and perform the normal cert validation ourselves.
|
||||||
|
cfg := &tls.Config{InsecureSkipVerify: true}
|
||||||
|
|
||||||
|
km, err := rootProv.KeyMaterial(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("xds: fetching trusted roots from CertificateProvider failed: %v", err)
|
||||||
|
}
|
||||||
|
cfg.RootCAs = km.Roots
|
||||||
|
|
||||||
|
if idProv != nil {
|
||||||
|
km, err := idProv.KeyMaterial(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("xds: fetching identity certificates from CertificateProvider failed: %v", err)
|
||||||
|
}
|
||||||
|
cfg.Certificates = km.Certs
|
||||||
|
}
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerSideTLSConfig constructs a tls.Config to be used in a server-side
|
||||||
|
// handshake based on the contents of the HandshakeInfo.
|
||||||
|
func (hi *HandshakeInfo) ServerSideTLSConfig(ctx context.Context) (*tls.Config, error) {
|
||||||
|
cfg := &tls.Config{ClientAuth: tls.NoClientCert}
|
||||||
|
hi.mu.Lock()
|
||||||
|
// On the server side, identityProvider is mandatory. RootProvider is
|
||||||
|
// optional based on whether the server is doing TLS or mTLS.
|
||||||
|
if hi.identityProvider == nil {
|
||||||
|
return nil, errors.New("xds: CertificateProvider to fetch identity certificate is missing, cannot perform TLS handshake. Please check configuration on the management server")
|
||||||
|
}
|
||||||
|
// Since the call to KeyMaterial() can block, we read the providers under
|
||||||
|
// the lock but call the actual function after releasing the lock.
|
||||||
|
rootProv, idProv := hi.rootProvider, hi.identityProvider
|
||||||
|
if hi.requireClientCert {
|
||||||
|
cfg.ClientAuth = tls.RequireAndVerifyClientCert
|
||||||
|
}
|
||||||
|
hi.mu.Unlock()
|
||||||
|
|
||||||
|
// identityProvider is mandatory on the server side.
|
||||||
|
km, err := idProv.KeyMaterial(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("xds: fetching identity certificates from CertificateProvider failed: %v", err)
|
||||||
|
}
|
||||||
|
cfg.Certificates = km.Certs
|
||||||
|
|
||||||
|
if rootProv != nil {
|
||||||
|
km, err := rootProv.KeyMaterial(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("xds: fetching trusted roots from CertificateProvider failed: %v", err)
|
||||||
|
}
|
||||||
|
cfg.ClientCAs = km.Roots
|
||||||
|
}
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchingSANExists returns true if the SAN contained in the passed in
|
||||||
|
// certificate is present in the list of accepted SANs in the HandshakeInfo.
|
||||||
|
//
|
||||||
|
// If the list of accepted SANs in the HandshakeInfo is empty, this function
|
||||||
|
// returns true for all input certificates.
|
||||||
|
func (hi *HandshakeInfo) MatchingSANExists(cert *x509.Certificate) bool {
|
||||||
|
if len(hi.acceptedSANs) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var sans []string
|
||||||
|
// SANs can be specified in any of these four fields on the parsed cert.
|
||||||
|
sans = append(sans, cert.DNSNames...)
|
||||||
|
sans = append(sans, cert.EmailAddresses...)
|
||||||
|
for _, ip := range cert.IPAddresses {
|
||||||
|
sans = append(sans, ip.String())
|
||||||
|
}
|
||||||
|
for _, uri := range cert.URIs {
|
||||||
|
sans = append(sans, uri.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
hi.mu.Lock()
|
||||||
|
defer hi.mu.Unlock()
|
||||||
|
for _, san := range sans {
|
||||||
|
if hi.acceptedSANs[san] {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHandshakeInfo returns a new instance of HandshakeInfo with the given root
|
||||||
|
// and identity certificate providers.
|
||||||
|
func NewHandshakeInfo(root, identity certprovider.Provider, sans ...string) *HandshakeInfo {
|
||||||
|
acceptedSANs := make(map[string]bool, len(sans))
|
||||||
|
for _, san := range sans {
|
||||||
|
acceptedSANs[san] = true
|
||||||
|
}
|
||||||
|
return &HandshakeInfo{
|
||||||
|
rootProvider: root,
|
||||||
|
identityProvider: identity,
|
||||||
|
acceptedSANs: acceptedSANs,
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,17 +27,16 @@ import (
|
||||||
"google.golang.org/grpc/connectivity"
|
"google.golang.org/grpc/connectivity"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/credentials/tls/certprovider"
|
"google.golang.org/grpc/credentials/tls/certprovider"
|
||||||
"google.golang.org/grpc/credentials/xds"
|
|
||||||
"google.golang.org/grpc/internal/buffer"
|
"google.golang.org/grpc/internal/buffer"
|
||||||
|
xdsinternal "google.golang.org/grpc/internal/credentials/xds"
|
||||||
"google.golang.org/grpc/internal/grpclog"
|
"google.golang.org/grpc/internal/grpclog"
|
||||||
"google.golang.org/grpc/internal/grpcsync"
|
"google.golang.org/grpc/internal/grpcsync"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
"google.golang.org/grpc/serviceconfig"
|
"google.golang.org/grpc/serviceconfig"
|
||||||
"google.golang.org/grpc/xds/internal/balancer/edsbalancer"
|
"google.golang.org/grpc/xds/internal/balancer/edsbalancer"
|
||||||
"google.golang.org/grpc/xds/internal/client"
|
"google.golang.org/grpc/xds/internal/client"
|
||||||
"google.golang.org/grpc/xds/internal/client/bootstrap"
|
|
||||||
|
|
||||||
xdsclient "google.golang.org/grpc/xds/internal/client"
|
xdsclient "google.golang.org/grpc/xds/internal/client"
|
||||||
|
"google.golang.org/grpc/xds/internal/client/bootstrap"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -81,7 +80,7 @@ func (cdsBB) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.
|
||||||
updateCh: buffer.NewUnbounded(),
|
updateCh: buffer.NewUnbounded(),
|
||||||
closed: grpcsync.NewEvent(),
|
closed: grpcsync.NewEvent(),
|
||||||
cancelWatch: func() {}, // No-op at this point.
|
cancelWatch: func() {}, // No-op at this point.
|
||||||
xdsHI: xds.NewHandshakeInfo(nil, nil),
|
xdsHI: xdsinternal.NewHandshakeInfo(nil, nil),
|
||||||
}
|
}
|
||||||
b.logger = prefixLogger((b))
|
b.logger = prefixLogger((b))
|
||||||
b.logger.Infof("Created")
|
b.logger.Infof("Created")
|
||||||
|
@ -188,7 +187,7 @@ type cdsBalancer struct {
|
||||||
// a new provider is to be created.
|
// a new provider is to be created.
|
||||||
cachedRoot certprovider.Provider
|
cachedRoot certprovider.Provider
|
||||||
cachedIdentity certprovider.Provider
|
cachedIdentity certprovider.Provider
|
||||||
xdsHI *xds.HandshakeInfo
|
xdsHI *xdsinternal.HandshakeInfo
|
||||||
xdsCredsInUse bool
|
xdsCredsInUse bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,7 +505,7 @@ type ccWrapper struct {
|
||||||
|
|
||||||
// The certificate providers in this HandshakeInfo are updated based on the
|
// The certificate providers in this HandshakeInfo are updated based on the
|
||||||
// received security configuration in the Cluster resource.
|
// received security configuration in the Cluster resource.
|
||||||
xdsHI *xds.HandshakeInfo
|
xdsHI *xdsinternal.HandshakeInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSubConn intercepts NewSubConn() calls from the child policy and adds an
|
// NewSubConn intercepts NewSubConn() calls from the child policy and adds an
|
||||||
|
@ -515,7 +514,7 @@ type ccWrapper struct {
|
||||||
func (ccw *ccWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
|
func (ccw *ccWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
|
||||||
newAddrs := make([]resolver.Address, len(addrs))
|
newAddrs := make([]resolver.Address, len(addrs))
|
||||||
for i, addr := range addrs {
|
for i, addr := range addrs {
|
||||||
newAddrs[i] = xds.SetHandshakeInfo(addr, ccw.xdsHI)
|
newAddrs[i] = xdsinternal.SetHandshakeInfo(addr, ccw.xdsHI)
|
||||||
}
|
}
|
||||||
return ccw.ClientConn.NewSubConn(newAddrs, opts)
|
return ccw.ClientConn.NewSubConn(newAddrs, opts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"google.golang.org/grpc/credentials/tls/certprovider"
|
"google.golang.org/grpc/credentials/tls/certprovider"
|
||||||
"google.golang.org/grpc/credentials/xds"
|
"google.golang.org/grpc/credentials/xds"
|
||||||
"google.golang.org/grpc/internal"
|
"google.golang.org/grpc/internal"
|
||||||
|
xdsinternal "google.golang.org/grpc/internal/credentials/xds"
|
||||||
"google.golang.org/grpc/internal/testutils"
|
"google.golang.org/grpc/internal/testutils"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
xdsclient "google.golang.org/grpc/xds/internal/client"
|
xdsclient "google.golang.org/grpc/xds/internal/client"
|
||||||
|
@ -188,7 +189,7 @@ func makeNewSubConn(ctx context.Context, edsCC balancer.ClientConn, parentCC *xd
|
||||||
if got, want := gotAddrs[0].Addr, addrs[0].Addr; got != want {
|
if got, want := gotAddrs[0].Addr, addrs[0].Addr; got != want {
|
||||||
return fmt.Errorf("resolver.Address passed to parent ClientConn has address %q, want %q", got, want)
|
return fmt.Errorf("resolver.Address passed to parent ClientConn has address %q, want %q", got, want)
|
||||||
}
|
}
|
||||||
getHI := internal.GetXDSHandshakeInfoForTesting.(func(attr *attributes.Attributes) *xds.HandshakeInfo)
|
getHI := internal.GetXDSHandshakeInfoForTesting.(func(attr *attributes.Attributes) *xdsinternal.HandshakeInfo)
|
||||||
hi := getHI(gotAddrs[0].Attributes)
|
hi := getHI(gotAddrs[0].Attributes)
|
||||||
if hi == nil {
|
if hi == nil {
|
||||||
return errors.New("resolver.Address passed to parent ClientConn doesn't contain attributes")
|
return errors.New("resolver.Address passed to parent ClientConn doesn't contain attributes")
|
||||||
|
|
|
@ -29,9 +29,9 @@ import (
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/credentials/tls/certprovider"
|
"google.golang.org/grpc/credentials/tls/certprovider"
|
||||||
"google.golang.org/grpc/credentials/xds"
|
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
"google.golang.org/grpc/internal"
|
"google.golang.org/grpc/internal"
|
||||||
|
xdsinternal "google.golang.org/grpc/internal/credentials/xds"
|
||||||
internalgrpclog "google.golang.org/grpc/internal/grpclog"
|
internalgrpclog "google.golang.org/grpc/internal/grpclog"
|
||||||
"google.golang.org/grpc/internal/grpcsync"
|
"google.golang.org/grpc/internal/grpcsync"
|
||||||
xdsclient "google.golang.org/grpc/xds/internal/client"
|
xdsclient "google.golang.org/grpc/xds/internal/client"
|
||||||
|
@ -210,7 +210,7 @@ func (s *GRPCServer) newListenerWrapper(lis net.Listener) (*listenerWrapper, err
|
||||||
lw := &listenerWrapper{
|
lw := &listenerWrapper{
|
||||||
Listener: lis,
|
Listener: lis,
|
||||||
closed: grpcsync.NewEvent(),
|
closed: grpcsync.NewEvent(),
|
||||||
xdsHI: xds.NewHandshakeInfo(nil, nil),
|
xdsHI: xdsinternal.NewHandshakeInfo(nil, nil),
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is used to notify that a good update has been received and that
|
// This is used to notify that a good update has been received and that
|
||||||
|
@ -436,7 +436,7 @@ type listenerWrapper struct {
|
||||||
cachedIdentity certprovider.Provider
|
cachedIdentity certprovider.Provider
|
||||||
|
|
||||||
// Wraps all information required by the xds handshaker.
|
// Wraps all information required by the xds handshaker.
|
||||||
xdsHI *xds.HandshakeInfo
|
xdsHI *xdsinternal.HandshakeInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accept blocks on an Accept() on the underlying listener, and wraps the
|
// Accept blocks on an Accept() on the underlying listener, and wraps the
|
||||||
|
@ -480,7 +480,7 @@ type conn struct {
|
||||||
// This is the same HandshakeInfo as stored in the listenerWrapper that
|
// This is the same HandshakeInfo as stored in the listenerWrapper that
|
||||||
// created this conn. The former updates the HandshakeInfo whenever it
|
// created this conn. The former updates the HandshakeInfo whenever it
|
||||||
// receives new security configuration.
|
// receives new security configuration.
|
||||||
xdsHI *xds.HandshakeInfo
|
xdsHI *xdsinternal.HandshakeInfo
|
||||||
|
|
||||||
// The connection deadline as configured by the grpc.Server on the rawConn
|
// The connection deadline as configured by the grpc.Server on the rawConn
|
||||||
// that is returned by a call to Accept(). This is set to the connection
|
// that is returned by a call to Accept(). This is set to the connection
|
||||||
|
@ -512,6 +512,6 @@ func (c *conn) GetDeadline() time.Time {
|
||||||
|
|
||||||
// XDSHandshakeInfo returns a pointer to the HandshakeInfo stored in conn. This
|
// XDSHandshakeInfo returns a pointer to the HandshakeInfo stored in conn. This
|
||||||
// will be invoked by the ServerHandshake() method of the XdsCredentials.
|
// will be invoked by the ServerHandshake() method of the XdsCredentials.
|
||||||
func (c *conn) XDSHandshakeInfo() *xds.HandshakeInfo {
|
func (c *conn) XDSHandshakeInfo() *xdsinternal.HandshakeInfo {
|
||||||
return c.xdsHI
|
return c.xdsHI
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue