curvetls icon indicating copy to clipboard operation
curvetls copied to clipboard

Implementing gRPC TransportCredentials interface

Open anxiousmodernman opened this issue 7 years ago • 1 comments

Howdy, thanks for providing an implementation of this protocol in Go. I'm interested in alternatives to TLS for transport security.

My issue is, I need to wrap a net.Listener and not a net.Conn, because I'd like to use gRPC.

We should be able to implement the TransportCredentials interface.

// TransportCredentials defines the common interface for all the live gRPC wire
// protocols and supported transport security protocols (e.g., TLS, SSL).
type TransportCredentials interface {
	// ClientHandshake does the authentication handshake specified by the corresponding
	// authentication protocol on rawConn for clients. It returns the authenticated
	// connection and the corresponding auth information about the connection.
	// Implementations must use the provided context to implement timely cancellation.
	// gRPC will try to reconnect if the error returned is a temporary error
	// (io.EOF, context.DeadlineExceeded or err.Temporary() == true).
	// If the returned error is a wrapper error, implementations should make sure that
	// the error implements Temporary() to have the correct retry behaviors.
	//
	// If the returned net.Conn is closed, it MUST close the net.Conn provided.
	ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error)
	// ServerHandshake does the authentication handshake for servers. It returns
	// the authenticated connection and the corresponding auth information about
	// the connection.
	//
	// If the returned net.Conn is closed, it MUST close the net.Conn provided.
	ServerHandshake(net.Conn) (net.Conn, AuthInfo, error)
	// Info provides the ProtocolInfo of this TransportCredentials.
	Info() ProtocolInfo
	// Clone makes a copy of this TransportCredentials.
	Clone() TransportCredentials
	// OverrideServerName overrides the server name used to verify the hostname on the returned certificates from the server.
	// gRPC internals also use it to override the virtual hosting name if it is set.
	// It must be called before dialing. Currently, this is only used by grpclb.
	OverrideServerName(string) error
}

Then we could start a curvetls-powered gRPC server with something like:

lis, _ := net.Listen("tcp", "...")
s := grpc.NewServer(curvetls.GRPCCredentials(pub, priv))
go func() { s.Serve(lis) }

I'm going to fork and give it a try. It seems like it should be straightforward. I'll comment here if I encounter any roadblocks.

anxiousmodernman avatar Dec 24 '17 01:12 anxiousmodernman

Perhaps this implementation does not belong in core, but since I need access to some types that are currently private (to do the handshake in the way that gRPC makes us do it), I will depend on my own fork of curvetls. If there is a better way, I am willing to help. It might just be a matter of exporting things.

Closing PR #2 for now.

anxiousmodernman avatar Feb 24 '18 23:02 anxiousmodernman