diff --git a/adapter/outbound/reality.go b/adapter/outbound/reality.go index 766138dad..6711f3787 100644 --- a/adapter/outbound/reality.go +++ b/adapter/outbound/reality.go @@ -1,13 +1,13 @@ package outbound import ( + "crypto/ecdh" "encoding/base64" "encoding/hex" "errors" + "fmt" tlsC "github.com/metacubex/mihomo/component/tls" - - "golang.org/x/crypto/curve25519" ) type RealityOptions struct { @@ -19,10 +19,16 @@ func (o RealityOptions) Parse() (*tlsC.RealityConfig, error) { if o.PublicKey != "" { config := new(tlsC.RealityConfig) - n, err := base64.RawURLEncoding.Decode(config.PublicKey[:], []byte(o.PublicKey)) - if err != nil || n != curve25519.ScalarSize { + const x25519ScalarSize = 32 + var publicKey [x25519ScalarSize]byte + n, err := base64.RawURLEncoding.Decode(publicKey[:], []byte(o.PublicKey)) + if err != nil || n != x25519ScalarSize { return nil, errors.New("invalid REALITY public key") } + config.PublicKey, err = ecdh.X25519().NewPublicKey(publicKey[:]) + if err != nil { + return nil, fmt.Errorf("fail to create REALITY public key: %w", err) + } n, err = hex.Decode(config.ShortID[:], []byte(o.ShortID)) if err != nil || n > tlsC.RealityMaxShortIDLen { diff --git a/component/tls/reality.go b/component/tls/reality.go index f8d5ab23d..687ef1ef9 100644 --- a/component/tls/reality.go +++ b/component/tls/reality.go @@ -28,7 +28,6 @@ import ( utls "github.com/sagernet/utls" "github.com/zhangyunhao116/fastrand" "golang.org/x/crypto/chacha20poly1305" - "golang.org/x/crypto/curve25519" "golang.org/x/crypto/hkdf" "golang.org/x/net/http2" ) @@ -36,7 +35,7 @@ import ( const RealityMaxShortIDLen = 8 type RealityConfig struct { - PublicKey [curve25519.ScalarSize]byte + PublicKey *ecdh.PublicKey ShortID [RealityMaxShortIDLen]byte } @@ -82,10 +81,6 @@ func GetRealityConn(ctx context.Context, conn net.Conn, ClientFingerprint string //log.Debugln("REALITY hello.sessionId[:16]: %v", hello.SessionId[:16]) - publicKey, err := ecdh.X25519().NewPublicKey(realityConfig.PublicKey[:]) - if err != nil { - return nil, err - } ecdheKey := uConn.HandshakeState.State13.EcdheKey if ecdheKey == nil { // WTF??? @@ -94,7 +89,7 @@ func GetRealityConn(ctx context.Context, conn net.Conn, ClientFingerprint string } continue // retry } - authKey, err := ecdheKey.ECDH(publicKey) + authKey, err := ecdheKey.ECDH(realityConfig.PublicKey) if err != nil { return nil, err }