func NewTLS(c *gmtls.Config) credentials.TransportCredentials {
	tc := &tlsCreds{cloneTLSConfig(c)}
	tc.config.NextProtos = alpnProtoStr
	return tc
}
NewTLS uses c to construct a TransportCredentials based on TLS.
package gmcredentials
import (
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"strings"
	"github.com/tjfoc/gmsm/sm2"
	"github.com/tjfoc/gmtls"
	"google.golang.org/grpc/credentials"
	"golang.org/x/net/context"
)
var (
	alpnProtoStr = []string{"h2"}
)
type PerRPCCredentials interface {
	GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
	RequireTransportSecurity() bool
}
type ProtocolInfo struct {
	ProtocolVersion string
	SecurityProtocol string
	SecurityVersion string
	ServerName string
}
type AuthInfo interface {
	AuthType() string
}
var (
	ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC")
)
type TLSInfo struct {
	State gmtls.ConnectionState
}
func (t TLSInfo) AuthType() string {
	return "tls"
}
type tlsCreds struct {
	config *gmtls.Config
}
func (c tlsCreds) Info() credentials.ProtocolInfo {
	return credentials.ProtocolInfo{
		SecurityProtocol: "tls",
		SecurityVersion:  "1.2",
		ServerName:       c.config.ServerName,
	}
}
func (c *tlsCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (_ net.Conn, _ credentials.AuthInfo, err error) {
	cfg := cloneTLSConfig(c.config)
	if cfg.ServerName == "" {
		colonPos := strings.LastIndex(addr, ":")
		if colonPos == -1 {
			colonPos = len(addr)
		}
		cfg.ServerName = addr[:colonPos]
	}
	conn := gmtls.Client(rawConn, cfg)
	errChannel := make(chan error, 1)
	go func() {
		errChannel <- conn.Handshake()
	}()
	select {
	case err := <-errChannel:
		if err != nil {
			return nil, nil, err
		}
	case <-ctx.Done():
		return nil, nil, ctx.Err()
	}
	return conn, TLSInfo{conn.ConnectionState()}, nil
}
func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
	conn := gmtls.Server(rawConn, c.config)
	if err := conn.Handshake(); err != nil {
		return nil, nil, err
	}
	return conn, TLSInfo{conn.ConnectionState()}, nil
}
func (c *tlsCreds) Clone() credentials.TransportCredentials {
	return NewTLS(c.config)
}
func (c *tlsCreds) OverrideServerName(serverNameOverride string) error {
	c.config.ServerName = serverNameOverride
	return nil
}