github.com/kelleygo/clashcore@v1.0.2/transport/vmess/tls.go (about)

     1  package vmess
     2  
     3  import (
     4  	"context"
     5  	"crypto/tls"
     6  	"errors"
     7  	"net"
     8  
     9  	"github.com/kelleygo/clashcore/component/ca"
    10  	tlsC "github.com/kelleygo/clashcore/component/tls"
    11  )
    12  
    13  type TLSConfig struct {
    14  	Host              string
    15  	SkipCertVerify    bool
    16  	FingerPrint       string
    17  	ClientFingerprint string
    18  	NextProtos        []string
    19  	Reality           *tlsC.RealityConfig
    20  }
    21  
    22  func StreamTLSConn(ctx context.Context, conn net.Conn, cfg *TLSConfig) (net.Conn, error) {
    23  	tlsConfig := &tls.Config{
    24  		ServerName:         cfg.Host,
    25  		InsecureSkipVerify: cfg.SkipCertVerify,
    26  		NextProtos:         cfg.NextProtos,
    27  	}
    28  
    29  	var err error
    30  	tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, cfg.FingerPrint)
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  
    35  	if len(cfg.ClientFingerprint) != 0 {
    36  		if cfg.Reality == nil {
    37  			utlsConn, valid := GetUTLSConn(conn, cfg.ClientFingerprint, tlsConfig)
    38  			if valid {
    39  				err := utlsConn.(*tlsC.UConn).HandshakeContext(ctx)
    40  				return utlsConn, err
    41  			}
    42  		} else {
    43  			return tlsC.GetRealityConn(ctx, conn, cfg.ClientFingerprint, tlsConfig, cfg.Reality)
    44  		}
    45  	}
    46  	if cfg.Reality != nil {
    47  		return nil, errors.New("REALITY is based on uTLS, please set a client-fingerprint")
    48  	}
    49  
    50  	tlsConn := tls.Client(conn, tlsConfig)
    51  
    52  	err = tlsConn.HandshakeContext(ctx)
    53  	return tlsConn, err
    54  }
    55  
    56  func GetUTLSConn(conn net.Conn, ClientFingerprint string, tlsConfig *tls.Config) (net.Conn, bool) {
    57  
    58  	if fingerprint, exists := tlsC.GetFingerprint(ClientFingerprint); exists {
    59  		utlsConn := tlsC.UClient(conn, tlsConfig, fingerprint)
    60  
    61  		return utlsConn, true
    62  	}
    63  
    64  	return nil, false
    65  }