mihomo/common/tls/config.go
2022-07-10 20:44:24 +08:00

80 lines
1.5 KiB
Go

package tls
import (
"bytes"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"encoding/hex"
"fmt"
"strings"
"sync"
"time"
)
var fingerprints [][32]byte
var rwLock sync.Mutex
var defaultTLSConfig = &tls.Config{
InsecureSkipVerify: true,
VerifyPeerCertificate: verifyPeerCertificate,
}
var verifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
fingerprints := fingerprints
var preErr error
for i := range rawCerts {
rawCert := rawCerts[i]
cert, err := x509.ParseCertificate(rawCert)
if err == nil {
opts := x509.VerifyOptions{
CurrentTime: time.Now(),
}
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
}
}
preErr = err
}
}
}
return preErr
}
func AddCertFingerprint(fingerprint string) error {
fp := strings.Replace(fingerprint, ":", "", -1)
fpByte, err := hex.DecodeString(fp)
if err != nil {
return err
}
if len(fpByte) != 32 {
return fmt.Errorf("fingerprint string length error,need sha25 fingerprint")
}
rwLock.Lock()
fingerprints = append(fingerprints, *(*[32]byte)(fpByte))
rwLock.Unlock()
return nil
}
func GetDefaultTLSConfig() *tls.Config {
return defaultTLSConfig
}
func MixinTLSConfig(tlsConfig *tls.Config) *tls.Config {
if tlsConfig == nil {
return GetDefaultTLSConfig()
}
tlsConfig.InsecureSkipVerify = true
tlsConfig.VerifyPeerCertificate = verifyPeerCertificate
return tlsConfig
}