MITM freedom RAW TLS: Allow "fromMitm" to be written at any position in verifyPeerCertInNames, Add checking for alpn "fromMitm"

https://github.com/XTLS/Xray-core/issues/4348#issuecomment-2643340434
This commit is contained in:
RPRX 2025-02-08 12:11:25 +00:00 committed by GitHub
parent db5f18b98c
commit d4c7cd02fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 29 additions and 14 deletions

View File

@ -433,6 +433,13 @@ func (c *TLSConfig) Build() (proto.Message, error) {
if c.ALPN != nil && len(*c.ALPN) > 0 {
config.NextProtocol = []string(*c.ALPN)
}
if len(config.NextProtocol) > 1 {
for _, p := range config.NextProtocol {
if tcp.IsFromMitm(p) {
return nil, errors.New(`only one element is allowed in "alpn" when using "fromMitm" in it`)
}
}
}
if c.CurvePreferences != nil && len(*c.CurvePreferences) > 0 {
config.CurvePreferences = []string(*c.CurvePreferences)
}
@ -443,7 +450,7 @@ func (c *TLSConfig) Build() (proto.Message, error) {
config.CipherSuites = c.CipherSuites
config.Fingerprint = strings.ToLower(c.Fingerprint)
if config.Fingerprint != "unsafe" && tls.GetFingerprint(config.Fingerprint) == nil {
return nil, errors.New(`unknown fingerprint: `, config.Fingerprint)
return nil, errors.New(`unknown "fingerprint": `, config.Fingerprint)
}
config.RejectUnknownSni = c.RejectUnknownSNI
@ -472,7 +479,7 @@ func (c *TLSConfig) Build() (proto.Message, error) {
config.MasterKeyLog = c.MasterKeyLog
if c.ServerNameToVerify != "" {
return nil, errors.PrintRemovedFeatureError("serverNameToVerify", "verifyPeerCertInNames")
return nil, errors.PrintRemovedFeatureError(`"serverNameToVerify"`, `"verifyPeerCertInNames"`)
}
config.VerifyPeerCertInNames = c.VerifyPeerCertInNames

View File

@ -2,6 +2,7 @@ package tcp
import (
"context"
"slices"
"strings"
"github.com/xtls/xray-core/common"
@ -33,17 +34,24 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
if IsFromMitm(tlsConfig.ServerName) {
tlsConfig.ServerName = mitmServerName
}
r, ok := tlsConfig.Rand.(*tls.RandCarrier)
isFromMitmVerify := ok && len(r.VerifyPeerCertInNames) > 0 && IsFromMitm(r.VerifyPeerCertInNames[0])
if isFromMitmVerify {
r.VerifyPeerCertInNames = r.VerifyPeerCertInNames[1:]
after := mitmServerName
for {
if len(after) > 0 {
r.VerifyPeerCertInNames = append(r.VerifyPeerCertInNames, after)
}
_, after, _ = strings.Cut(after, ".")
if !strings.Contains(after, ".") {
isFromMitmVerify := false
if r, ok := tlsConfig.Rand.(*tls.RandCarrier); ok && len(r.VerifyPeerCertInNames) > 0 {
for i, name := range r.VerifyPeerCertInNames {
if IsFromMitm(name) {
isFromMitmVerify = true
r.VerifyPeerCertInNames[0], r.VerifyPeerCertInNames[i] = r.VerifyPeerCertInNames[i], r.VerifyPeerCertInNames[0]
r.VerifyPeerCertInNames = r.VerifyPeerCertInNames[1:]
after := mitmServerName
for {
if len(after) > 0 {
r.VerifyPeerCertInNames = append(r.VerifyPeerCertInNames, after)
}
_, after, _ = strings.Cut(after, ".")
if !strings.Contains(after, ".") {
break
}
}
slices.Reverse(r.VerifyPeerCertInNames)
break
}
}

View File

@ -300,7 +300,7 @@ func (r *RandCarrier) verifyPeerCert(rawCerts [][]byte, verifiedChains [][]*x509
}
}
if r.PinnedPeerCertificateChainSha256 == nil {
errors.New("peer cert is invalid.")
return errors.New("peer cert is invalid.")
}
}