feat: reality add support-x25519mlkem768, it only works with new version server

This commit is contained in:
wwqgtxx 2025-05-15 10:14:18 +08:00
parent 83213d493e
commit 5cf0f18c29
4 changed files with 30 additions and 27 deletions

View File

@ -13,11 +13,14 @@ import (
type RealityOptions struct { type RealityOptions struct {
PublicKey string `proxy:"public-key"` PublicKey string `proxy:"public-key"`
ShortID string `proxy:"short-id"` ShortID string `proxy:"short-id"`
SupportX25519MLKEM768 bool `proxy:"support-x25519mlkem768"`
} }
func (o RealityOptions) Parse() (*tlsC.RealityConfig, error) { func (o RealityOptions) Parse() (*tlsC.RealityConfig, error) {
if o.PublicKey != "" { if o.PublicKey != "" {
config := new(tlsC.RealityConfig) config := new(tlsC.RealityConfig)
config.SupportX25519MLKEM768 = o.SupportX25519MLKEM768
const x25519ScalarSize = 32 const x25519ScalarSize = 32
publicKey, err := base64.RawURLEncoding.DecodeString(o.PublicKey) publicKey, err := base64.RawURLEncoding.DecodeString(o.PublicKey)

View File

@ -35,6 +35,8 @@ const RealityMaxShortIDLen = 8
type RealityConfig struct { type RealityConfig struct {
PublicKey *ecdh.PublicKey PublicKey *ecdh.PublicKey
ShortID [RealityMaxShortIDLen]byte ShortID [RealityMaxShortIDLen]byte
SupportX25519MLKEM768 bool
} }
func GetRealityConn(ctx context.Context, conn net.Conn, fingerprint UClientHelloID, tlsConfig *tls.Config, realityConfig *RealityConfig) (net.Conn, error) { func GetRealityConn(ctx context.Context, conn net.Conn, fingerprint UClientHelloID, tlsConfig *tls.Config, realityConfig *RealityConfig) (net.Conn, error) {
@ -48,38 +50,36 @@ func GetRealityConn(ctx context.Context, conn net.Conn, fingerprint UClientHello
SessionTicketsDisabled: true, SessionTicketsDisabled: true,
VerifyPeerCertificate: verifier.VerifyPeerCertificate, VerifyPeerCertificate: verifier.VerifyPeerCertificate,
} }
clientID := utls.ClientHelloID{
Client: fingerprint.Client, uConn := utls.UClient(conn, uConfig, fingerprint)
Version: fingerprint.Version,
Seed: fingerprint.Seed,
}
uConn := utls.UClient(conn, uConfig, clientID)
verifier.UConn = uConn verifier.UConn = uConn
err := uConn.BuildHandshakeState() err := uConn.BuildHandshakeState()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// ------for X25519MLKEM768 does not work properly with reality------- if !realityConfig.SupportX25519MLKEM768 {
// Iterate over extensions and check // ------for X25519MLKEM768 does not work properly with the old reality server-------
for _, extension := range uConn.Extensions { // Iterate over extensions and check
if ce, ok := extension.(*utls.SupportedCurvesExtension); ok { for _, extension := range uConn.Extensions {
ce.Curves = slices.DeleteFunc(ce.Curves, func(curveID utls.CurveID) bool { if ce, ok := extension.(*utls.SupportedCurvesExtension); ok {
return curveID == utls.X25519MLKEM768 ce.Curves = slices.DeleteFunc(ce.Curves, func(curveID utls.CurveID) bool {
}) return curveID == utls.X25519MLKEM768
})
}
if ks, ok := extension.(*utls.KeyShareExtension); ok {
ks.KeyShares = slices.DeleteFunc(ks.KeyShares, func(share utls.KeyShare) bool {
return share.Group == utls.X25519MLKEM768
})
}
} }
if ks, ok := extension.(*utls.KeyShareExtension); ok { // Rebuild the client hello
ks.KeyShares = slices.DeleteFunc(ks.KeyShares, func(share utls.KeyShare) bool { err = uConn.BuildHandshakeState()
return share.Group == utls.X25519MLKEM768 if err != nil {
}) return nil, err
} }
// --------------------------------------------------------------------
} }
// Rebuild the client hello
err = uConn.BuildHandshakeState()
if err != nil {
return nil, err
}
// --------------------------------------------------------------------
hello := uConn.HandshakeState.Hello hello := uConn.HandshakeState.Hello
rawSessionID := hello.Raw[39 : 39+32] // the location of session ID rawSessionID := hello.Raw[39 : 39+32] // the location of session ID
@ -144,7 +144,7 @@ func GetRealityConn(ctx context.Context, conn net.Conn, fingerprint UClientHello
log.Debugln("REALITY Authentication: %v, AEAD: %T", verifier.verified, aeadCipher) log.Debugln("REALITY Authentication: %v, AEAD: %T", verifier.verified, aeadCipher)
if !verifier.verified { if !verifier.verified {
go realityClientFallback(uConn, uConfig.ServerName, clientID) go realityClientFallback(uConn, uConfig.ServerName, fingerprint)
return nil, errors.New("REALITY authentication failed") return nil, errors.New("REALITY authentication failed")
} }

2
go.mod
View File

@ -36,7 +36,7 @@ require (
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee github.com/metacubex/smux v0.0.0-20250503055512-501391591dee
github.com/metacubex/tfo-go v0.0.0-20250503140532-decbcfccbfdf github.com/metacubex/tfo-go v0.0.0-20250503140532-decbcfccbfdf
github.com/metacubex/utls v1.7.0-alpha.3 github.com/metacubex/utls v1.7.3
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181
github.com/miekg/dns v1.1.63 // lastest version compatible with golang1.20 github.com/miekg/dns v1.1.63 // lastest version compatible with golang1.20
github.com/mroth/weightedrand/v2 v2.1.0 github.com/mroth/weightedrand/v2 v2.1.0

4
go.sum
View File

@ -138,8 +138,8 @@ github.com/metacubex/smux v0.0.0-20250503055512-501391591dee h1:lp6hJ+4wCLZu113a
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE= github.com/metacubex/smux v0.0.0-20250503055512-501391591dee/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE=
github.com/metacubex/tfo-go v0.0.0-20250503140532-decbcfccbfdf h1:LwID1wz4tzypidd412dd4dC1H0m1TgRCQ/XvRvMJDFM= github.com/metacubex/tfo-go v0.0.0-20250503140532-decbcfccbfdf h1:LwID1wz4tzypidd412dd4dC1H0m1TgRCQ/XvRvMJDFM=
github.com/metacubex/tfo-go v0.0.0-20250503140532-decbcfccbfdf/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw= github.com/metacubex/tfo-go v0.0.0-20250503140532-decbcfccbfdf/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
github.com/metacubex/utls v1.7.0-alpha.3 h1:cp1cEMUnoifiWrGHRzo+nCwPRveN9yPD8QaRFmfcYxA= github.com/metacubex/utls v1.7.3 h1:yDcMEWojFh+t8rU9X0HPcZDPAoFze/rIIyssqivzj8A=
github.com/metacubex/utls v1.7.0-alpha.3/go.mod h1:oknYT0qTOwE4hjPmZOEpzVdefnW7bAdGLvZcqmk4TLU= github.com/metacubex/utls v1.7.3/go.mod h1:oknYT0qTOwE4hjPmZOEpzVdefnW7bAdGLvZcqmk4TLU=
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 h1:hJLQviGySBuaynlCwf/oYgIxbVbGRUIKZCxdya9YrbQ= github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 h1:hJLQviGySBuaynlCwf/oYgIxbVbGRUIKZCxdya9YrbQ=
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181/go.mod h1:phewKljNYiTVT31Gcif8RiCKnTUOgVWFJjccqYM8s+Y= github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181/go.mod h1:phewKljNYiTVT31Gcif8RiCKnTUOgVWFJjccqYM8s+Y=
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY= github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=