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

Method ClientHandshake

credentials/xds/xds.go:93–170  ·  view source on GitHub ↗

ClientHandshake performs the TLS handshake on the client-side. It looks for the presence of a HandshakeInfo value in the passed in context (added using a call to NewContextWithHandshakeInfo()), and retrieves identity and root certificates from there. It also retrieves a list of acceptable SANs and

(ctx context.Context, authority string, rawConn net.Conn)

Source from the content-addressed store, hash-verified

91// by the peer. It uses fallback credentials if no HandshakeInfo is present in
92// the passed in context.
93func (c *credsImpl) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
94 if !c.isClient {
95 return nil, nil, errors.New("ClientHandshake() is not supported for server credentials")
96 }
97
98 // The clusterimpl balancer constructs a new HandshakeInfo using a call to
99 // NewHandshakeInfo(), and then adds it to the attributes field of the
100 // resolver.Address when handling calls to NewSubConn(). The transport layer
101 // takes care of shipping these attributes in the context to this handshake
102 // function. We first read the credentials.ClientHandshakeInfo type from the
103 // context, which contains the attributes added by the clusterimpl balancer.
104 // We then read the HandshakeInfo from the attributes to get to the actual
105 // data that we need here for the handshake.
106 chi := credentials.ClientHandshakeInfoFromContext(ctx)
107 // If there are no attributes in the received context or the attributes does
108 // not contain a HandshakeInfo, it could either mean that the user did not
109 // specify an `xds` scheme in their dial target or that the xDS server did
110 // not provide any security configuration. In both of these cases, we use
111 // the fallback credentials specified by the user.
112 if chi.Attributes == nil {
113 return c.fallback.ClientHandshake(ctx, authority, rawConn)
114 }
115
116 hi := xdsinternal.HandshakeInfoFromAttributes(chi.Attributes).Load()
117 if hi == nil {
118 return c.fallback.ClientHandshake(ctx, authority, rawConn)
119 }
120 if hi.UseFallbackCreds() {
121 return c.fallback.ClientHandshake(ctx, authority, rawConn)
122 }
123
124 // We build the tls.Config with the following values
125 // 1. Root certificate as returned by the root provider.
126 // 2. Identity certificate as returned by the identity provider. This may be
127 // empty on the client side, if the client is not doing mTLS.
128 // 3. InsecureSkipVerify to true. Certificates used in Mesh environments
129 // usually contains the identity of the workload presenting the
130 // certificate as a SAN (instead of a hostname in the CommonName field).
131 // This means that normal certificate verification as done by the
132 // standard library will fail.
133 // 4. Key usage to match whether client/server usage.
134 // 5. A `VerifyPeerCertificate` function which performs normal peer
135 // cert verification using configured roots, and the custom SAN checks.
136 hostname := xdsinternal.Hostname(chi.Attributes)
137 cfg, err := hi.ClientSideTLSConfig(ctx, hostname)
138 if err != nil {
139 return nil, nil, err
140 }
141
142 // Perform the TLS handshake with the tls.Config that we have. We run the
143 // actual Handshake() function in a goroutine because we need to respect the
144 // deadline specified on the passed in context, and we need a way to cancel
145 // the handshake if the context is cancelled.
146 conn := tls.Client(rawConn, cfg)
147 errCh := make(chan error, 1)
148 go func() {
149 errCh <- conn.Handshake()
150 close(errCh)

Callers

nothing calls this directly

Calls 8

UseFallbackCredsMethod · 0.80
ClientSideTLSConfigMethod · 0.80
ErrMethod · 0.80
ClientHandshakeMethod · 0.65
CloseMethod · 0.65
LoadMethod · 0.45
DoneMethod · 0.45

Tested by

no test coverage detected