| 110 | } |
| 111 | |
| 112 | func (c *tlsCreds) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (_ net.Conn, _ AuthInfo, err error) { |
| 113 | // use local cfg to avoid clobbering ServerName if using multiple endpoints |
| 114 | cfg := credinternal.CloneTLSConfig(c.config) |
| 115 | |
| 116 | serverName, _, err := net.SplitHostPort(authority) |
| 117 | if err != nil { |
| 118 | // If the authority had no host port or if the authority cannot be parsed, use it as-is. |
| 119 | serverName = authority |
| 120 | } |
| 121 | cfg.ServerName = serverName |
| 122 | |
| 123 | conn := tls.Client(rawConn, cfg) |
| 124 | errChannel := make(chan error, 1) |
| 125 | go func() { |
| 126 | errChannel <- conn.Handshake() |
| 127 | close(errChannel) |
| 128 | }() |
| 129 | select { |
| 130 | case err := <-errChannel: |
| 131 | if err != nil { |
| 132 | conn.Close() |
| 133 | return nil, nil, err |
| 134 | } |
| 135 | case <-ctx.Done(): |
| 136 | conn.Close() |
| 137 | return nil, nil, ctx.Err() |
| 138 | } |
| 139 | |
| 140 | // The negotiated protocol can be either of the following: |
| 141 | // 1. h2: When the server supports ALPN. Only HTTP/2 can be negotiated since |
| 142 | // it is the only protocol advertised by the client during the handshake. |
| 143 | // The tls library ensures that the server chooses a protocol advertised |
| 144 | // by the client. |
| 145 | // 2. "" (empty string): If the server doesn't support ALPN. ALPN is a requirement |
| 146 | // for using HTTP/2 over TLS. We can terminate the connection immediately. |
| 147 | np := conn.ConnectionState().NegotiatedProtocol |
| 148 | if np == "" { |
| 149 | if envconfig.EnforceALPNEnabled { |
| 150 | conn.Close() |
| 151 | return nil, nil, fmt.Errorf("credentials: cannot check peer: missing selected ALPN property. %s", alpnFailureHelpMessage) |
| 152 | } |
| 153 | logger.Warningf("Allowing TLS connection to server %q with ALPN disabled. TLS connections to servers with ALPN disabled will be disallowed in future grpc-go releases", cfg.ServerName) |
| 154 | } |
| 155 | tlsInfo := TLSInfo{ |
| 156 | State: conn.ConnectionState(), |
| 157 | CommonAuthInfo: CommonAuthInfo{ |
| 158 | SecurityLevel: PrivacyAndIntegrity, |
| 159 | }, |
| 160 | } |
| 161 | id := credinternal.SPIFFEIDFromState(conn.ConnectionState()) |
| 162 | if id != nil { |
| 163 | tlsInfo.SPIFFEID = id |
| 164 | } |
| 165 | return credinternal.WrapSyscallConn(rawConn, conn), tlsInfo, nil |
| 166 | } |
| 167 | |
| 168 | func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) { |
| 169 | conn := tls.Server(rawConn, c.config) |