refactor: replace experimental.fingerprints with custom-certificates and Change the fingerprint verification logic to SSL pinning
This commit is contained in:
parent
2095f4f670
commit
b6b6413d04
19 changed files with 91 additions and 97 deletions
|
@ -150,7 +150,7 @@ func NewHttp(option HttpOption) (*Http, error) {
|
||||||
sni = option.SNI
|
sni = option.SNI
|
||||||
}
|
}
|
||||||
if len(option.Fingerprint) == 0 {
|
if len(option.Fingerprint) == 0 {
|
||||||
tlsConfig = tlsC.GetGlobalFingerprintTLSConfig(&tls.Config{
|
tlsConfig = tlsC.GetGlobalTLSConfig(&tls.Config{
|
||||||
InsecureSkipVerify: option.SkipCertVerify,
|
InsecureSkipVerify: option.SkipCertVerify,
|
||||||
ServerName: sni,
|
ServerName: sni,
|
||||||
})
|
})
|
||||||
|
|
|
@ -178,7 +178,7 @@ func NewHysteria(option HysteriaOption) (*Hysteria, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tlsConfig = tlsC.GetGlobalFingerprintTLSConfig(tlsConfig)
|
tlsConfig = tlsC.GetGlobalTLSConfig(tlsConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(option.ALPN) > 0 {
|
if len(option.ALPN) > 0 {
|
||||||
|
|
|
@ -223,7 +223,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(shadowTLSOpt.Fingerprint) == 0 {
|
if len(shadowTLSOpt.Fingerprint) == 0 {
|
||||||
tlsConfig = tlsC.GetGlobalFingerprintTLSConfig(tlsConfig)
|
tlsConfig = tlsC.GetGlobalTLSConfig(tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, shadowTLSOpt.Fingerprint); err != nil {
|
if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, shadowTLSOpt.Fingerprint); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -167,7 +167,7 @@ func NewSocks5(option Socks5Option) (*Socks5, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(option.Fingerprint) == 0 {
|
if len(option.Fingerprint) == 0 {
|
||||||
tlsConfig = tlsC.GetGlobalFingerprintTLSConfig(tlsConfig)
|
tlsConfig = tlsC.GetGlobalTLSConfig(tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint); err != nil {
|
if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint); err != nil {
|
||||||
|
|
|
@ -268,7 +268,7 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(option.Fingerprint) == 0 {
|
if len(option.Fingerprint) == 0 {
|
||||||
tlsConfig = tlsC.GetGlobalFingerprintTLSConfig(tlsConfig)
|
tlsConfig = tlsC.GetGlobalTLSConfig(tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint); err != nil {
|
if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint); err != nil {
|
||||||
|
|
|
@ -143,7 +143,7 @@ func NewTuic(option TuicOption) (*Tuic, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tlsConfig = tlsC.GetGlobalFingerprintTLSConfig(tlsConfig)
|
tlsConfig = tlsC.GetGlobalTLSConfig(tlsConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(option.ALPN) > 0 {
|
if len(option.ALPN) > 0 {
|
||||||
|
|
|
@ -98,7 +98,7 @@ func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(v.option.Fingerprint) == 0 {
|
if len(v.option.Fingerprint) == 0 {
|
||||||
wsOpts.TLSConfig = tlsC.GetGlobalFingerprintTLSConfig(tlsConfig)
|
wsOpts.TLSConfig = tlsC.GetGlobalTLSConfig(tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
wsOpts.TLSConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, v.option.Fingerprint)
|
wsOpts.TLSConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, v.option.Fingerprint)
|
||||||
}
|
}
|
||||||
|
@ -522,7 +522,7 @@ func NewVless(option VlessOption) (*Vless, error) {
|
||||||
ServiceName: v.option.GrpcOpts.GrpcServiceName,
|
ServiceName: v.option.GrpcOpts.GrpcServiceName,
|
||||||
Host: v.option.ServerName,
|
Host: v.option.ServerName,
|
||||||
}
|
}
|
||||||
tlsConfig := tlsC.GetGlobalFingerprintTLSConfig(&tls.Config{
|
tlsConfig := tlsC.GetGlobalTLSConfig(&tls.Config{
|
||||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
InsecureSkipVerify: v.option.SkipCertVerify,
|
||||||
ServerName: v.option.ServerName,
|
ServerName: v.option.ServerName,
|
||||||
})
|
})
|
||||||
|
|
|
@ -115,7 +115,7 @@ func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(v.option.Fingerprint) == 0 {
|
if len(v.option.Fingerprint) == 0 {
|
||||||
wsOpts.TLSConfig = tlsC.GetGlobalFingerprintTLSConfig(tlsConfig)
|
wsOpts.TLSConfig = tlsC.GetGlobalTLSConfig(tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
if wsOpts.TLSConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, v.option.Fingerprint); err != nil {
|
if wsOpts.TLSConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, v.option.Fingerprint); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -6,63 +6,57 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
CN "github.com/Dreamacro/clash/common/net"
|
||||||
|
|
||||||
xtls "github.com/xtls/go"
|
xtls "github.com/xtls/go"
|
||||||
)
|
)
|
||||||
|
|
||||||
var globalFingerprints = make([][32]byte, 0)
|
var tlsCertificates = make([]tls.Certificate, 0)
|
||||||
var mutex sync.Mutex
|
|
||||||
|
|
||||||
func verifyPeerCertificateAndFingerprints(fingerprints *[][32]byte, insecureSkipVerify bool) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
|
var mutex sync.RWMutex
|
||||||
return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
|
var errNotMacth error = errors.New("certificate fingerprints do not match")
|
||||||
if insecureSkipVerify {
|
|
||||||
|
func AddCertificate(privateKey, certificate string) error {
|
||||||
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
if cert, err := CN.ParseCert(certificate, privateKey); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
tlsCertificates = append(tlsCertificates, cert)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var preErr error
|
func GetCertificates() []tls.Certificate {
|
||||||
|
mutex.RLock()
|
||||||
|
defer mutex.RUnlock()
|
||||||
|
return tlsCertificates
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyFingerprint(fingerprint *[32]byte) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
|
||||||
|
return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
|
||||||
|
// ssl pining
|
||||||
for i := range rawCerts {
|
for i := range rawCerts {
|
||||||
rawCert := rawCerts[i]
|
rawCert := rawCerts[i]
|
||||||
cert, err := x509.ParseCertificate(rawCert)
|
cert, err := x509.ParseCertificate(rawCert)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
opts := x509.VerifyOptions{
|
hash := sha256.Sum256(cert.Raw)
|
||||||
CurrentTime: time.Now(),
|
if bytes.Equal(fingerprint[:], hash[:]) {
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := cert.Verify(opts); err == nil {
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
fingerprint := sha256.Sum256(cert.Raw)
|
|
||||||
for _, fp := range *fingerprints {
|
|
||||||
if bytes.Equal(fingerprint[:], fp[:]) {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
preErr = err
|
|
||||||
}
|
}
|
||||||
|
return errNotMacth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return preErr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddCertFingerprint(fingerprint string) error {
|
|
||||||
fpByte, err2 := convertFingerprint(fingerprint)
|
|
||||||
if err2 != nil {
|
|
||||||
return err2
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex.Lock()
|
|
||||||
globalFingerprints = append(globalFingerprints, *fpByte)
|
|
||||||
mutex.Unlock()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertFingerprint(fingerprint string) (*[32]byte, error) {
|
func convertFingerprint(fingerprint string) (*[32]byte, error) {
|
||||||
|
fingerprint = strings.TrimSpace(strings.Replace(fingerprint, ":", "", -1))
|
||||||
fpByte, err := hex.DecodeString(fingerprint)
|
fpByte, err := hex.DecodeString(fingerprint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -75,7 +69,7 @@ func convertFingerprint(fingerprint string) (*[32]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDefaultTLSConfig() *tls.Config {
|
func GetDefaultTLSConfig() *tls.Config {
|
||||||
return GetGlobalFingerprintTLSConfig(nil)
|
return GetGlobalTLSConfig(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSpecifiedFingerprintTLSConfig specified fingerprint
|
// GetSpecifiedFingerprintTLSConfig specified fingerprint
|
||||||
|
@ -83,33 +77,20 @@ func GetSpecifiedFingerprintTLSConfig(tlsConfig *tls.Config, fingerprint string)
|
||||||
if fingerprintBytes, err := convertFingerprint(fingerprint); err != nil {
|
if fingerprintBytes, err := convertFingerprint(fingerprint); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
if tlsConfig == nil {
|
tlsConfig = GetGlobalTLSConfig(tlsConfig)
|
||||||
return &tls.Config{
|
tlsConfig.VerifyPeerCertificate = verifyFingerprint(fingerprintBytes)
|
||||||
InsecureSkipVerify: true,
|
|
||||||
VerifyPeerCertificate: verifyPeerCertificateAndFingerprints(&[][32]byte{*fingerprintBytes}, false),
|
|
||||||
}, nil
|
|
||||||
} else {
|
|
||||||
tlsConfig.VerifyPeerCertificate = verifyPeerCertificateAndFingerprints(&[][32]byte{*fingerprintBytes}, tlsConfig.InsecureSkipVerify)
|
|
||||||
tlsConfig.InsecureSkipVerify = true
|
tlsConfig.InsecureSkipVerify = true
|
||||||
return tlsConfig, nil
|
return tlsConfig, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func GetGlobalFingerprintTLSConfig(tlsConfig *tls.Config) *tls.Config {
|
func GetGlobalTLSConfig(tlsConfig *tls.Config) *tls.Config {
|
||||||
// If there's at least one fingerprint then we could skip the general check
|
|
||||||
// If there's no fingerprints but the config insists then we should skip.
|
|
||||||
// Otherwise we should do a general verification.
|
|
||||||
shouldSkipVerify := len(globalFingerprints) != 0 || tlsConfig != nil && tlsConfig.InsecureSkipVerify
|
|
||||||
if tlsConfig == nil {
|
if tlsConfig == nil {
|
||||||
return &tls.Config{
|
return &tls.Config{
|
||||||
InsecureSkipVerify: shouldSkipVerify,
|
Certificates: tlsCertificates,
|
||||||
VerifyPeerCertificate: verifyPeerCertificateAndFingerprints(&globalFingerprints, false),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tlsConfig.Certificates = append(tlsConfig.Certificates, tlsCertificates...)
|
||||||
tlsConfig.VerifyPeerCertificate = verifyPeerCertificateAndFingerprints(&globalFingerprints, tlsConfig.InsecureSkipVerify)
|
|
||||||
tlsConfig.InsecureSkipVerify = shouldSkipVerify
|
|
||||||
return tlsConfig
|
return tlsConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,29 +99,37 @@ func GetSpecifiedFingerprintXTLSConfig(tlsConfig *xtls.Config, fingerprint strin
|
||||||
if fingerprintBytes, err := convertFingerprint(fingerprint); err != nil {
|
if fingerprintBytes, err := convertFingerprint(fingerprint); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
if tlsConfig == nil {
|
tlsConfig=GetGlobalXTLSConfig(tlsConfig)
|
||||||
return &xtls.Config{
|
tlsConfig.VerifyPeerCertificate = verifyFingerprint(fingerprintBytes)
|
||||||
InsecureSkipVerify: true,
|
|
||||||
VerifyPeerCertificate: verifyPeerCertificateAndFingerprints(&[][32]byte{*fingerprintBytes}, false),
|
|
||||||
}, nil
|
|
||||||
} else {
|
|
||||||
tlsConfig.VerifyPeerCertificate = verifyPeerCertificateAndFingerprints(&[][32]byte{*fingerprintBytes}, tlsConfig.InsecureSkipVerify)
|
|
||||||
tlsConfig.InsecureSkipVerify = true
|
tlsConfig.InsecureSkipVerify = true
|
||||||
return tlsConfig, nil
|
return tlsConfig, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func GetGlobalFingerprintXTLSConfig(tlsConfig *xtls.Config) *xtls.Config {
|
func GetGlobalXTLSConfig(tlsConfig *xtls.Config) *xtls.Config {
|
||||||
shouldSkipVerify := len(globalFingerprints) != 0 || tlsConfig != nil && tlsConfig.InsecureSkipVerify
|
xtlsCerts := make([]xtls.Certificate, len(tlsCertificates))
|
||||||
|
for _, cert := range tlsCertificates {
|
||||||
|
tlsSsaList := make([]xtls.SignatureScheme, len(cert.SupportedSignatureAlgorithms))
|
||||||
|
for _, ssa := range cert.SupportedSignatureAlgorithms {
|
||||||
|
tlsSsa := xtls.SignatureScheme(ssa)
|
||||||
|
tlsSsaList = append(tlsSsaList, tlsSsa)
|
||||||
|
}
|
||||||
|
xtlsCert := xtls.Certificate{
|
||||||
|
Certificate: cert.Certificate,
|
||||||
|
PrivateKey: cert.PrivateKey,
|
||||||
|
OCSPStaple: cert.OCSPStaple,
|
||||||
|
SignedCertificateTimestamps: cert.SignedCertificateTimestamps,
|
||||||
|
Leaf: cert.Leaf,
|
||||||
|
SupportedSignatureAlgorithms: tlsSsaList,
|
||||||
|
}
|
||||||
|
xtlsCerts = append(xtlsCerts, xtlsCert)
|
||||||
|
}
|
||||||
if tlsConfig == nil {
|
if tlsConfig == nil {
|
||||||
return &xtls.Config{
|
return &xtls.Config{
|
||||||
InsecureSkipVerify: shouldSkipVerify,
|
Certificates: xtlsCerts,
|
||||||
VerifyPeerCertificate: verifyPeerCertificateAndFingerprints(&globalFingerprints, false),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConfig.VerifyPeerCertificate = verifyPeerCertificateAndFingerprints(&globalFingerprints, tlsConfig.InsecureSkipVerify)
|
tlsConfig.Certificates = xtlsCerts
|
||||||
tlsConfig.InsecureSkipVerify = shouldSkipVerify
|
|
||||||
return tlsConfig
|
return tlsConfig
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"container/list"
|
"container/list"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
P "github.com/Dreamacro/clash/component/process"
|
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -14,6 +13,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
P "github.com/Dreamacro/clash/component/process"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/adapter"
|
"github.com/Dreamacro/clash/adapter"
|
||||||
"github.com/Dreamacro/clash/adapter/outbound"
|
"github.com/Dreamacro/clash/adapter/outbound"
|
||||||
"github.com/Dreamacro/clash/adapter/outboundgroup"
|
"github.com/Dreamacro/clash/adapter/outboundgroup"
|
||||||
|
@ -116,6 +117,11 @@ type Profile struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type TLS struct {
|
type TLS struct {
|
||||||
|
RawCert
|
||||||
|
CustomTrustCert []RawCert `yaml:"custom-certifactes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RawCert struct {
|
||||||
Certificate string `yaml:"certificate"`
|
Certificate string `yaml:"certificate"`
|
||||||
PrivateKey string `yaml:"private-key"`
|
PrivateKey string `yaml:"private-key"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
||||||
ch := make(chan result, 1)
|
ch := make(chan result, 1)
|
||||||
go func() {
|
go func() {
|
||||||
if strings.HasSuffix(c.Client.Net, "tls") {
|
if strings.HasSuffix(c.Client.Net, "tls") {
|
||||||
conn = tls.Client(conn, tlsC.GetGlobalFingerprintTLSConfig(c.Client.TLSConfig))
|
conn = tls.Client(conn, tlsC.GetGlobalTLSConfig(c.Client.TLSConfig))
|
||||||
}
|
}
|
||||||
|
|
||||||
msg, _, err := c.Client.ExchangeWithConn(m, &D.Conn{
|
msg, _, err := c.Client.ExchangeWithConn(m, &D.Conn{
|
||||||
|
|
|
@ -374,7 +374,7 @@ func (doh *dnsOverHTTPS) createClient(ctx context.Context) (*http.Client, error)
|
||||||
// HTTP3 is enabled in the upstream options). If this attempt is successful,
|
// HTTP3 is enabled in the upstream options). If this attempt is successful,
|
||||||
// it returns an HTTP3 transport, otherwise it returns the H1/H2 transport.
|
// it returns an HTTP3 transport, otherwise it returns the H1/H2 transport.
|
||||||
func (doh *dnsOverHTTPS) createTransport(ctx context.Context) (t http.RoundTripper, err error) {
|
func (doh *dnsOverHTTPS) createTransport(ctx context.Context) (t http.RoundTripper, err error) {
|
||||||
tlsConfig := tlsC.GetGlobalFingerprintTLSConfig(
|
tlsConfig := tlsC.GetGlobalTLSConfig(
|
||||||
&tls.Config{
|
&tls.Config{
|
||||||
InsecureSkipVerify: false,
|
InsecureSkipVerify: false,
|
||||||
MinVersion: tls.VersionTLS12,
|
MinVersion: tls.VersionTLS12,
|
||||||
|
|
|
@ -298,7 +298,7 @@ func (doq *dnsOverQUIC) openStream(ctx context.Context, conn quic.Connection) (q
|
||||||
|
|
||||||
// openConnection opens a new QUIC connection.
|
// openConnection opens a new QUIC connection.
|
||||||
func (doq *dnsOverQUIC) openConnection(ctx context.Context) (conn quic.Connection, err error) {
|
func (doq *dnsOverQUIC) openConnection(ctx context.Context) (conn quic.Connection, err error) {
|
||||||
tlsConfig := tlsC.GetGlobalFingerprintTLSConfig(
|
tlsConfig := tlsC.GetGlobalTLSConfig(
|
||||||
&tls.Config{
|
&tls.Config{
|
||||||
InsecureSkipVerify: false,
|
InsecureSkipVerify: false,
|
||||||
NextProtos: []string{
|
NextProtos: []string{
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
"github.com/Dreamacro/clash/component/profile/cachefile"
|
"github.com/Dreamacro/clash/component/profile/cachefile"
|
||||||
"github.com/Dreamacro/clash/component/resolver"
|
"github.com/Dreamacro/clash/component/resolver"
|
||||||
SNI "github.com/Dreamacro/clash/component/sniffer"
|
SNI "github.com/Dreamacro/clash/component/sniffer"
|
||||||
"github.com/Dreamacro/clash/component/tls"
|
CTLS "github.com/Dreamacro/clash/component/tls"
|
||||||
"github.com/Dreamacro/clash/component/trie"
|
"github.com/Dreamacro/clash/component/trie"
|
||||||
"github.com/Dreamacro/clash/config"
|
"github.com/Dreamacro/clash/config"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
|
@ -146,10 +146,9 @@ func updateExperimental(c *config.Config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func preUpdateExperimental(c *config.Config) {
|
func preUpdateExperimental(c *config.Config) {
|
||||||
for _, fingerprint := range c.Experimental.Fingerprints {
|
CTLS.AddCertificate(c.TLS.PrivateKey, c.TLS.Certificate)
|
||||||
if err := tls.AddCertFingerprint(fingerprint); err != nil {
|
for _, c := range c.TLS.CustomTrustCert {
|
||||||
log.Warnln("fingerprint[%s] is err, %s", fingerprint, err.Error())
|
CTLS.AddCertificate(c.PrivateKey, c.Certificate)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ func (t *Trojan) StreamConn(conn net.Conn) (net.Conn, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(t.option.Fingerprint) == 0 {
|
if len(t.option.Fingerprint) == 0 {
|
||||||
xtlsConfig = tlsC.GetGlobalFingerprintXTLSConfig(xtlsConfig)
|
xtlsConfig = tlsC.GetGlobalXTLSConfig(xtlsConfig)
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
if xtlsConfig, err = tlsC.GetSpecifiedFingerprintXTLSConfig(xtlsConfig, t.option.Fingerprint); err != nil {
|
if xtlsConfig, err = tlsC.GetSpecifiedFingerprintXTLSConfig(xtlsConfig, t.option.Fingerprint); err != nil {
|
||||||
|
@ -107,7 +107,7 @@ func (t *Trojan) StreamConn(conn net.Conn) (net.Conn, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(t.option.Fingerprint) == 0 {
|
if len(t.option.Fingerprint) == 0 {
|
||||||
tlsConfig = tlsC.GetGlobalFingerprintTLSConfig(tlsConfig)
|
tlsConfig = tlsC.GetGlobalTLSConfig(tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, t.option.Fingerprint); err != nil {
|
if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, t.option.Fingerprint); err != nil {
|
||||||
|
|
|
@ -43,7 +43,7 @@ func NewV2rayObfs(conn net.Conn, option *Option) (net.Conn, error) {
|
||||||
NextProtos: []string{"http/1.1"},
|
NextProtos: []string{"http/1.1"},
|
||||||
}
|
}
|
||||||
if len(option.Fingerprint) == 0 {
|
if len(option.Fingerprint) == 0 {
|
||||||
config.TLSConfig = tlsC.GetGlobalFingerprintTLSConfig(tlsConfig)
|
config.TLSConfig = tlsC.GetGlobalTLSConfig(tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
if config.TLSConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint); err != nil {
|
if config.TLSConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint); err != nil {
|
||||||
|
|
|
@ -23,7 +23,7 @@ func StreamXTLSConn(conn net.Conn, cfg *XTLSConfig) (net.Conn, error) {
|
||||||
NextProtos: cfg.NextProtos,
|
NextProtos: cfg.NextProtos,
|
||||||
}
|
}
|
||||||
if len(cfg.Fingerprint) == 0 {
|
if len(cfg.Fingerprint) == 0 {
|
||||||
xtlsConfig = tlsC.GetGlobalFingerprintXTLSConfig(xtlsConfig)
|
xtlsConfig = tlsC.GetGlobalXTLSConfig(xtlsConfig)
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
if xtlsConfig, err = tlsC.GetSpecifiedFingerprintXTLSConfig(xtlsConfig, cfg.Fingerprint); err != nil {
|
if xtlsConfig, err = tlsC.GetSpecifiedFingerprintXTLSConfig(xtlsConfig, cfg.Fingerprint); err != nil {
|
||||||
|
|
|
@ -24,7 +24,7 @@ func StreamTLSConn(conn net.Conn, cfg *TLSConfig) (net.Conn, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cfg.FingerPrint) == 0 {
|
if len(cfg.FingerPrint) == 0 {
|
||||||
tlsConfig = tlsC.GetGlobalFingerprintTLSConfig(tlsConfig)
|
tlsConfig = tlsC.GetGlobalTLSConfig(tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, cfg.FingerPrint); err != nil {
|
if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, cfg.FingerPrint); err != nil {
|
||||||
|
|
Loading…
Reference in a new issue