mirror of https://github.com/XTLS/Xray-core
				
				
				
			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-2643340434pull/4375/head
							parent
							
								
									db5f18b98c
								
							
						
					
					
						commit
						d4c7cd02fd
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue