diff --git a/main/commands/all/tls/ping.go b/main/commands/all/tls/ping.go index 7d0ea0d6..99c03b97 100644 --- a/main/commands/all/tls/ping.go +++ b/main/commands/all/tls/ping.go @@ -6,6 +6,9 @@ import ( "encoding/base64" "fmt" "net" + "reflect" + "strconv" + "unsafe" "github.com/xtls/xray-core/main/commands/base" . "github.com/xtls/xray-core/transport/internet/tls" @@ -36,8 +39,13 @@ func executePing(cmd *base.Command, args []string) { base.Fatalf("domain not specified") } - domain := cmdPing.Flag.Arg(0) - fmt.Println("Tls ping: ", domain) + domainWithPort := cmdPing.Flag.Arg(0) + fmt.Println("Tls ping: ", domainWithPort) + TargetPort := 443 + domain, port, err := net.SplitHostPort(domainWithPort) + if err == nil { + TargetPort, _ = strconv.Atoi(port) + } var ip net.IP if len(*pingIPStr) > 0 { @@ -58,14 +66,14 @@ func executePing(cmd *base.Command, args []string) { fmt.Println("-------------------") fmt.Println("Pinging without SNI") { - tcpConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: ip, Port: 443}) + tcpConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: ip, Port: TargetPort}) if err != nil { base.Fatalf("Failed to dial tcp: %s", err) } tlsConn := gotls.Client(tcpConn, &gotls.Config{ InsecureSkipVerify: true, NextProtos: []string{"http/1.1"}, - MaxVersion: gotls.VersionTLS12, + MaxVersion: gotls.VersionTLS13, MinVersion: gotls.VersionTLS12, // Do not release tool before v5's refactor // VerifyPeerCertificate: showCert(), @@ -75,6 +83,7 @@ func executePing(cmd *base.Command, args []string) { fmt.Println("Handshake failure: ", err) } else { fmt.Println("Handshake succeeded") + printTLSConnDetail(tlsConn) printCertificates(tlsConn.ConnectionState().PeerCertificates) } tlsConn.Close() @@ -90,7 +99,7 @@ func executePing(cmd *base.Command, args []string) { tlsConn := gotls.Client(tcpConn, &gotls.Config{ ServerName: domain, NextProtos: []string{"http/1.1"}, - MaxVersion: gotls.VersionTLS12, + MaxVersion: gotls.VersionTLS13, MinVersion: gotls.VersionTLS12, // Do not release tool before v5's refactor // VerifyPeerCertificate: showCert(), @@ -100,6 +109,7 @@ func executePing(cmd *base.Command, args []string) { fmt.Println("handshake failure: ", err) } else { fmt.Println("handshake succeeded") + printTLSConnDetail(tlsConn) printCertificates(tlsConn.ConnectionState().PeerCertificates) } tlsConn.Close() @@ -117,6 +127,23 @@ func printCertificates(certs []*x509.Certificate) { } } +func printTLSConnDetail(tlsConn *gotls.Conn) { + var tlsVersion string + if tlsConn.ConnectionState().Version == gotls.VersionTLS13 { + tlsVersion = "TLS 1.3" + } else if tlsConn.ConnectionState().Version == gotls.VersionTLS12 { + tlsVersion = "TLS 1.2" + } + fmt.Println("TLS Version:", tlsVersion) + curveID := *(*gotls.CurveID)(unsafe.Pointer(reflect.ValueOf(tlsConn).Elem().FieldByName("curveID").UnsafeAddr())) + if curveID != 0 { + PostQuantum := (curveID == gotls.X25519MLKEM768) + fmt.Println("Post-Quantum key exchange:", PostQuantum, "("+curveID.String()+")") + } else { + fmt.Println("Post-Quantum key exchange: false (RSA Exchange)") + } +} + func showCert() func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { hash := GenerateCertChainHash(rawCerts) diff --git a/transport/internet/tls/config.go b/transport/internet/tls/config.go index d6701a7d..517bf40b 100644 --- a/transport/internet/tls/config.go +++ b/transport/internet/tls/config.go @@ -486,11 +486,11 @@ func ConfigFromStreamSettings(settings *internet.MemoryStreamConfig) *Config { func ParseCurveName(curveNames []string) []tls.CurveID { curveMap := map[string]tls.CurveID{ - "curvep256": tls.CurveP256, - "curvep384": tls.CurveP384, - "curvep521": tls.CurveP521, - "x25519": tls.X25519, - "x25519kyber768draft00": 0x6399, + "curvep256": tls.CurveP256, + "curvep384": tls.CurveP384, + "curvep521": tls.CurveP521, + "x25519": tls.X25519, + "x25519mlkem768": tls.X25519MLKEM768, } var curveIDs []tls.CurveID