From 9d27bdc646d13f39c697fac8331af2fccb004c49 Mon Sep 17 00:00:00 2001 From: achenging <2787641+achenging@users.noreply.github.com> Date: Mon, 20 Jan 2025 16:31:18 +0800 Subject: [PATCH] fixed: support to use custom tls cert to vmess wss --- component/ca/config.go | 30 +++++++++++++++++++++++++++++- hub/executor/executor.go | 7 +++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/component/ca/config.go b/component/ca/config.go index 9d002db6..6a3c6649 100644 --- a/component/ca/config.go +++ b/component/ca/config.go @@ -7,6 +7,7 @@ import ( "crypto/x509" _ "embed" "encoding/hex" + "encoding/pem" "errors" "fmt" "os" @@ -14,6 +15,9 @@ import ( "strings" "sync" + log "github.com/metacubex/mihomo/log" + + CN "github.com/metacubex/mihomo/common/net" C "github.com/metacubex/mihomo/constant" ) @@ -27,14 +31,38 @@ var _CaCertificates []byte var DisableEmbedCa, _ = strconv.ParseBool(os.Getenv("DISABLE_EMBED_CA")) var DisableSystemCa, _ = strconv.ParseBool(os.Getenv("DISABLE_SYSTEM_CA")) +func AddCertificateKeyPair(certificate string, privateKey string) { + + certKeyPair, err := CN.ParseCert(certificate, privateKey, C.Path) + if err != nil { + log.Warnln("failed to parse certificate and privateKey: %v", err) + } + for _, certPEM := range certKeyPair.Certificate { + // []byte to x509.Certificate + customCertificate, err := x509.ParseCertificate(certPEM) + if err != nil { + log.Warnln("failed to parse x509 certificate: %v", err) + } + trustCerts = append(trustCerts, customCertificate) + globalCertPool.AddCert(customCertificate) + } +} func AddCertificate(certificate string) error { mutex.Lock() defer mutex.Unlock() if certificate == "" { return fmt.Errorf("certificate is empty") } - if cert, err := x509.ParseCertificate([]byte(certificate)); err == nil { + + block, _ := pem.Decode([]byte(certificate)) + if block == nil { + log.Fatalln("failed to parse PEM block containing the certificate") + return fmt.Errorf("decode certificate failed") + } + + if cert, err := x509.ParseCertificate(block.Bytes); err == nil { trustCerts = append(trustCerts, cert) + globalCertPool.AddCert(cert) return nil } else { return fmt.Errorf("add certificate failed") diff --git a/hub/executor/executor.go b/hub/executor/executor.go index 3fed360c..b94e32f1 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -89,7 +89,14 @@ func ApplyConfig(cfg *config.Config, force bool) { tunnel.OnSuspend() + //This method is confusing, when ResetCertificate + //it will clear the trusted certificates and call the initialize CertPool internally + //it will not add any certificates to the global ca.ResetCertificate() + //check the private key and certificate , add the global certs + if cfg.TLS.PrivateKey != "" && cfg.TLS.Certificate != "" { + ca.AddCertificateKeyPair(cfg.TLS.Certificate, cfg.TLS.PrivateKey) + } for _, c := range cfg.TLS.CustomTrustCert { if err := ca.AddCertificate(c); err != nil { log.Warnln("%s\nadd error: %s", c, err.Error())