mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-04-30 17:38:41 +00:00
Legends never die (#1725)
This commit is contained in:
parent
4c8ee0af50
commit
9e5bc07bf2
34 changed files with 71 additions and 1773 deletions
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/xtls/xray-core/transport/internet/reality"
|
||||
"github.com/xtls/xray-core/transport/internet/stat"
|
||||
"github.com/xtls/xray-core/transport/internet/tls"
|
||||
"github.com/xtls/xray-core/transport/internet/xtls"
|
||||
)
|
||||
|
||||
func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (stat.Connection, error) {
|
||||
|
@ -29,8 +28,6 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
|
|||
|
||||
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
return tls.Client(conn, config.GetTLSConfig(tls.WithDestination(dest))), nil
|
||||
} else if config := xtls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
return xtls.Client(conn, config.GetXTLSConfig(xtls.WithDestination(dest))), nil
|
||||
} else if config := reality.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
return reality.UClient(conn, config, ctx, dest)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
goxtls "github.com/xtls/go"
|
||||
goreality "github.com/xtls/reality"
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
|
@ -17,7 +16,6 @@ import (
|
|||
"github.com/xtls/xray-core/transport/internet/reality"
|
||||
"github.com/xtls/xray-core/transport/internet/stat"
|
||||
"github.com/xtls/xray-core/transport/internet/tls"
|
||||
"github.com/xtls/xray-core/transport/internet/xtls"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
|
@ -25,7 +23,6 @@ type Listener struct {
|
|||
addr *net.UnixAddr
|
||||
ln net.Listener
|
||||
tlsConfig *gotls.Config
|
||||
xtlsConfig *goxtls.Config
|
||||
realityConfig *goreality.Config
|
||||
config *Config
|
||||
addConn internet.ConnHandler
|
||||
|
@ -64,9 +61,6 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti
|
|||
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
ln.tlsConfig = config.GetTLSConfig()
|
||||
}
|
||||
if config := xtls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
ln.xtlsConfig = config.GetXTLSConfig()
|
||||
}
|
||||
if config := reality.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
ln.realityConfig = config.GetREALITYConfig()
|
||||
}
|
||||
|
@ -100,8 +94,6 @@ func (ln *Listener) run() {
|
|||
go func() {
|
||||
if ln.tlsConfig != nil {
|
||||
conn = tls.Server(conn, ln.tlsConfig)
|
||||
} else if ln.xtlsConfig != nil {
|
||||
conn = xtls.Server(conn, ln.xtlsConfig)
|
||||
} else if ln.realityConfig != nil {
|
||||
if conn, err = reality.Server(conn, ln.realityConfig); err != nil {
|
||||
newError(err).AtInfo().WriteToLog()
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/xtls/xray-core/transport/internet"
|
||||
"github.com/xtls/xray-core/transport/internet/stat"
|
||||
"github.com/xtls/xray-core/transport/internet/tls"
|
||||
"github.com/xtls/xray-core/transport/internet/xtls"
|
||||
)
|
||||
|
||||
var globalConv = uint32(dice.RollUint16())
|
||||
|
@ -87,8 +86,6 @@ func DialKCP(ctx context.Context, dest net.Destination, streamSettings *internet
|
|||
|
||||
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
iConn = tls.Client(iConn, config.GetTLSConfig(tls.WithDestination(dest)))
|
||||
} else if config := xtls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
iConn = xtls.Client(iConn, config.GetXTLSConfig(xtls.WithDestination(dest)))
|
||||
}
|
||||
|
||||
return iConn, nil
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
gotls "crypto/tls"
|
||||
"sync"
|
||||
|
||||
goxtls "github.com/xtls/go"
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/buf"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
|
@ -14,7 +13,6 @@ import (
|
|||
"github.com/xtls/xray-core/transport/internet/stat"
|
||||
"github.com/xtls/xray-core/transport/internet/tls"
|
||||
"github.com/xtls/xray-core/transport/internet/udp"
|
||||
"github.com/xtls/xray-core/transport/internet/xtls"
|
||||
)
|
||||
|
||||
type ConnectionID struct {
|
||||
|
@ -29,7 +27,6 @@ type Listener struct {
|
|||
sessions map[ConnectionID]*Connection
|
||||
hub *udp.Hub
|
||||
tlsConfig *gotls.Config
|
||||
xtlsConfig *goxtls.Config
|
||||
config *Config
|
||||
reader PacketReader
|
||||
header internet.PacketHeader
|
||||
|
@ -62,9 +59,6 @@ func NewListener(ctx context.Context, address net.Address, port net.Port, stream
|
|||
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
l.tlsConfig = config.GetTLSConfig()
|
||||
}
|
||||
if config := xtls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
l.xtlsConfig = config.GetXTLSConfig()
|
||||
}
|
||||
|
||||
hub, err := udp.ListenUDP(ctx, address, port, streamSettings, udp.HubCapacity(1024))
|
||||
if err != nil {
|
||||
|
@ -137,8 +131,6 @@ func (l *Listener) OnReceive(payload *buf.Buffer, src net.Destination) {
|
|||
var netConn stat.Connection = conn
|
||||
if l.tlsConfig != nil {
|
||||
netConn = tls.Server(conn, l.tlsConfig)
|
||||
} else if l.xtlsConfig != nil {
|
||||
netConn = xtls.Server(conn, l.xtlsConfig)
|
||||
}
|
||||
|
||||
l.addConn(netConn)
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/xtls/xray-core/transport/internet/reality"
|
||||
"github.com/xtls/xray-core/transport/internet/stat"
|
||||
"github.com/xtls/xray-core/transport/internet/tls"
|
||||
"github.com/xtls/xray-core/transport/internet/xtls"
|
||||
)
|
||||
|
||||
// Dial dials a new TCP connection to the given destination.
|
||||
|
@ -31,9 +30,6 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
|
|||
} else {
|
||||
conn = tls.Client(conn, tlsConfig)
|
||||
}
|
||||
} else if config := xtls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
xtlsConfig := config.GetXTLSConfig(xtls.WithDestination(dest))
|
||||
conn = xtls.Client(conn, xtlsConfig)
|
||||
} else if config := reality.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
if conn, err = reality.UClient(conn, config, ctx, dest); err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
goxtls "github.com/xtls/go"
|
||||
goreality "github.com/xtls/reality"
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
|
@ -15,14 +14,12 @@ import (
|
|||
"github.com/xtls/xray-core/transport/internet/reality"
|
||||
"github.com/xtls/xray-core/transport/internet/stat"
|
||||
"github.com/xtls/xray-core/transport/internet/tls"
|
||||
"github.com/xtls/xray-core/transport/internet/xtls"
|
||||
)
|
||||
|
||||
// Listener is an internet.Listener that listens for TCP connections.
|
||||
type Listener struct {
|
||||
listener net.Listener
|
||||
tlsConfig *gotls.Config
|
||||
xtlsConfig *goxtls.Config
|
||||
realityConfig *goreality.Config
|
||||
authConfig internet.ConnectionAuthenticator
|
||||
config *Config
|
||||
|
@ -78,9 +75,6 @@ func ListenTCP(ctx context.Context, address net.Address, port net.Port, streamSe
|
|||
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
l.tlsConfig = config.GetTLSConfig()
|
||||
}
|
||||
if config := xtls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
l.xtlsConfig = config.GetXTLSConfig()
|
||||
}
|
||||
if config := reality.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
l.realityConfig = config.GetREALITYConfig()
|
||||
}
|
||||
|
@ -118,8 +112,6 @@ func (v *Listener) keepAccepting() {
|
|||
go func() {
|
||||
if v.tlsConfig != nil {
|
||||
conn = tls.Server(conn, v.tlsConfig)
|
||||
} else if v.xtlsConfig != nil {
|
||||
conn = xtls.Server(conn, v.xtlsConfig)
|
||||
} else if v.realityConfig != nil {
|
||||
if conn, err = reality.Server(conn, v.realityConfig); err != nil {
|
||||
newError(err).AtInfo().WriteToLog()
|
||||
|
|
|
@ -1,377 +0,0 @@
|
|||
package xtls
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
xtls "github.com/xtls/go"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/ocsp"
|
||||
"github.com/xtls/xray-core/common/platform/filesystem"
|
||||
"github.com/xtls/xray-core/common/protocol/tls/cert"
|
||||
"github.com/xtls/xray-core/transport/internet"
|
||||
"github.com/xtls/xray-core/transport/internet/tls"
|
||||
)
|
||||
|
||||
var globalSessionCache = xtls.NewLRUClientSessionCache(128)
|
||||
|
||||
// ParseCertificate converts a cert.Certificate to Certificate.
|
||||
func ParseCertificate(c *cert.Certificate) *Certificate {
|
||||
if c != nil {
|
||||
certPEM, keyPEM := c.ToPEM()
|
||||
return &Certificate{
|
||||
Certificate: certPEM,
|
||||
Key: keyPEM,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) loadSelfCertPool() (*x509.CertPool, error) {
|
||||
root := x509.NewCertPool()
|
||||
for _, cert := range c.Certificate {
|
||||
if !root.AppendCertsFromPEM(cert.Certificate) {
|
||||
return nil, newError("failed to append cert").AtWarning()
|
||||
}
|
||||
}
|
||||
return root, nil
|
||||
}
|
||||
|
||||
// BuildCertificates builds a list of TLS certificates from proto definition.
|
||||
func (c *Config) BuildCertificates() []*xtls.Certificate {
|
||||
certs := make([]*xtls.Certificate, 0, len(c.Certificate))
|
||||
for _, entry := range c.Certificate {
|
||||
if entry.Usage != Certificate_ENCIPHERMENT {
|
||||
continue
|
||||
}
|
||||
keyPair, err := xtls.X509KeyPair(entry.Certificate, entry.Key)
|
||||
if err != nil {
|
||||
newError("ignoring invalid X509 key pair").Base(err).AtWarning().WriteToLog()
|
||||
continue
|
||||
}
|
||||
keyPair.Leaf, err = x509.ParseCertificate(keyPair.Certificate[0])
|
||||
if err != nil {
|
||||
newError("ignoring invalid certificate").Base(err).AtWarning().WriteToLog()
|
||||
continue
|
||||
}
|
||||
certs = append(certs, &keyPair)
|
||||
if !entry.OneTimeLoading {
|
||||
var isOcspstapling bool
|
||||
hotReloadInterval := uint64(3600)
|
||||
if entry.OcspStapling != 0 {
|
||||
hotReloadInterval = entry.OcspStapling
|
||||
isOcspstapling = true
|
||||
}
|
||||
index := len(certs) - 1
|
||||
go func(entry *Certificate, cert *xtls.Certificate, index int) {
|
||||
t := time.NewTicker(time.Duration(hotReloadInterval) * time.Second)
|
||||
for {
|
||||
if entry.CertificatePath != "" && entry.KeyPath != "" {
|
||||
newCert, err := filesystem.ReadFile(entry.CertificatePath)
|
||||
if err != nil {
|
||||
newError("failed to parse certificate").Base(err).AtError().WriteToLog()
|
||||
<-t.C
|
||||
continue
|
||||
}
|
||||
newKey, err := filesystem.ReadFile(entry.KeyPath)
|
||||
if err != nil {
|
||||
newError("failed to parse key").Base(err).AtError().WriteToLog()
|
||||
<-t.C
|
||||
continue
|
||||
}
|
||||
if string(newCert) != string(entry.Certificate) && string(newKey) != string(entry.Key) {
|
||||
newKeyPair, err := xtls.X509KeyPair(newCert, newKey)
|
||||
if err != nil {
|
||||
newError("ignoring invalid X509 key pair").Base(err).AtError().WriteToLog()
|
||||
<-t.C
|
||||
continue
|
||||
}
|
||||
if newKeyPair.Leaf, err = x509.ParseCertificate(newKeyPair.Certificate[0]); err != nil {
|
||||
newError("ignoring invalid certificate").Base(err).AtError().WriteToLog()
|
||||
<-t.C
|
||||
continue
|
||||
}
|
||||
cert = &newKeyPair
|
||||
}
|
||||
}
|
||||
if isOcspstapling {
|
||||
if newOCSPData, err := ocsp.GetOCSPForCert(cert.Certificate); err != nil {
|
||||
newError("ignoring invalid OCSP").Base(err).AtWarning().WriteToLog()
|
||||
} else if string(newOCSPData) != string(cert.OCSPStaple) {
|
||||
cert.OCSPStaple = newOCSPData
|
||||
}
|
||||
}
|
||||
certs[index] = cert
|
||||
<-t.C
|
||||
}
|
||||
}(entry, certs[index], index)
|
||||
}
|
||||
}
|
||||
return certs
|
||||
}
|
||||
|
||||
func isCertificateExpired(c *xtls.Certificate) bool {
|
||||
if c.Leaf == nil && len(c.Certificate) > 0 {
|
||||
if pc, err := x509.ParseCertificate(c.Certificate[0]); err == nil {
|
||||
c.Leaf = pc
|
||||
}
|
||||
}
|
||||
|
||||
// If leaf is not there, the certificate is probably not used yet. We trust user to provide a valid certificate.
|
||||
return c.Leaf != nil && c.Leaf.NotAfter.Before(time.Now().Add(-time.Minute))
|
||||
}
|
||||
|
||||
func issueCertificate(rawCA *Certificate, domain string) (*xtls.Certificate, error) {
|
||||
parent, err := cert.ParseCertificate(rawCA.Certificate, rawCA.Key)
|
||||
if err != nil {
|
||||
return nil, newError("failed to parse raw certificate").Base(err)
|
||||
}
|
||||
newCert, err := cert.Generate(parent, cert.CommonName(domain), cert.DNSNames(domain))
|
||||
if err != nil {
|
||||
return nil, newError("failed to generate new certificate for ", domain).Base(err)
|
||||
}
|
||||
newCertPEM, newKeyPEM := newCert.ToPEM()
|
||||
cert, err := xtls.X509KeyPair(newCertPEM, newKeyPEM)
|
||||
return &cert, err
|
||||
}
|
||||
|
||||
func (c *Config) getCustomCA() []*Certificate {
|
||||
certs := make([]*Certificate, 0, len(c.Certificate))
|
||||
for _, certificate := range c.Certificate {
|
||||
if certificate.Usage == Certificate_AUTHORITY_ISSUE {
|
||||
certs = append(certs, certificate)
|
||||
}
|
||||
}
|
||||
return certs
|
||||
}
|
||||
|
||||
func getGetCertificateFunc(c *xtls.Config, ca []*Certificate) func(hello *xtls.ClientHelloInfo) (*xtls.Certificate, error) {
|
||||
var access sync.RWMutex
|
||||
|
||||
return func(hello *xtls.ClientHelloInfo) (*xtls.Certificate, error) {
|
||||
domain := hello.ServerName
|
||||
certExpired := false
|
||||
|
||||
access.RLock()
|
||||
certificate, found := c.NameToCertificate[domain]
|
||||
access.RUnlock()
|
||||
|
||||
if found {
|
||||
if !isCertificateExpired(certificate) {
|
||||
return certificate, nil
|
||||
}
|
||||
certExpired = true
|
||||
}
|
||||
|
||||
if certExpired {
|
||||
newCerts := make([]xtls.Certificate, 0, len(c.Certificates))
|
||||
|
||||
access.Lock()
|
||||
for _, certificate := range c.Certificates {
|
||||
if !isCertificateExpired(&certificate) {
|
||||
newCerts = append(newCerts, certificate)
|
||||
}
|
||||
}
|
||||
|
||||
c.Certificates = newCerts
|
||||
access.Unlock()
|
||||
}
|
||||
|
||||
var issuedCertificate *xtls.Certificate
|
||||
|
||||
// Create a new certificate from existing CA if possible
|
||||
for _, rawCert := range ca {
|
||||
if rawCert.Usage == Certificate_AUTHORITY_ISSUE {
|
||||
newCert, err := issueCertificate(rawCert, domain)
|
||||
if err != nil {
|
||||
newError("failed to issue new certificate for ", domain).Base(err).WriteToLog()
|
||||
continue
|
||||
}
|
||||
|
||||
access.Lock()
|
||||
c.Certificates = append(c.Certificates, *newCert)
|
||||
issuedCertificate = &c.Certificates[len(c.Certificates)-1]
|
||||
access.Unlock()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if issuedCertificate == nil {
|
||||
return nil, newError("failed to create a new certificate for ", domain)
|
||||
}
|
||||
|
||||
access.Lock()
|
||||
c.BuildNameToCertificate()
|
||||
access.Unlock()
|
||||
|
||||
return issuedCertificate, nil
|
||||
}
|
||||
}
|
||||
|
||||
func getNewGetCertificateFunc(certs []*xtls.Certificate, rejectUnknownSNI bool) func(hello *xtls.ClientHelloInfo) (*xtls.Certificate, error) {
|
||||
return func(hello *xtls.ClientHelloInfo) (*xtls.Certificate, error) {
|
||||
if len(certs) == 0 {
|
||||
return nil, errNoCertificates
|
||||
}
|
||||
sni := strings.ToLower(hello.ServerName)
|
||||
if !rejectUnknownSNI && (len(certs) == 1 || sni == "") {
|
||||
return certs[0], nil
|
||||
}
|
||||
gsni := "*"
|
||||
if index := strings.IndexByte(sni, '.'); index != -1 {
|
||||
gsni += sni[index:]
|
||||
}
|
||||
for _, keyPair := range certs {
|
||||
if keyPair.Leaf.Subject.CommonName == sni || keyPair.Leaf.Subject.CommonName == gsni {
|
||||
return keyPair, nil
|
||||
}
|
||||
for _, name := range keyPair.Leaf.DNSNames {
|
||||
if name == sni || name == gsni {
|
||||
return keyPair, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if rejectUnknownSNI {
|
||||
return nil, errNoCertificates
|
||||
}
|
||||
return certs[0], nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Config) parseServerName() string {
|
||||
return c.ServerName
|
||||
}
|
||||
|
||||
func (c *Config) verifyPeerCert(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
|
||||
if c.PinnedPeerCertificateChainSha256 != nil {
|
||||
hashValue := tls.GenerateCertChainHash(rawCerts)
|
||||
for _, v := range c.PinnedPeerCertificateChainSha256 {
|
||||
if hmac.Equal(hashValue, v) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return newError("peer cert is unrecognized: ", base64.StdEncoding.EncodeToString(hashValue))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetXTLSConfig converts this Config into xtls.Config.
|
||||
func (c *Config) GetXTLSConfig(opts ...Option) *xtls.Config {
|
||||
root, err := c.getCertPool()
|
||||
if err != nil {
|
||||
newError("failed to load system root certificate").AtError().Base(err).WriteToLog()
|
||||
}
|
||||
|
||||
if c == nil {
|
||||
return &xtls.Config{
|
||||
ClientSessionCache: globalSessionCache,
|
||||
RootCAs: root,
|
||||
InsecureSkipVerify: false,
|
||||
NextProtos: nil,
|
||||
SessionTicketsDisabled: true,
|
||||
}
|
||||
}
|
||||
|
||||
config := &xtls.Config{
|
||||
ClientSessionCache: globalSessionCache,
|
||||
RootCAs: root,
|
||||
InsecureSkipVerify: c.AllowInsecure,
|
||||
NextProtos: c.NextProtocol,
|
||||
SessionTicketsDisabled: !c.EnableSessionResumption,
|
||||
VerifyPeerCertificate: c.verifyPeerCert,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(config)
|
||||
}
|
||||
|
||||
caCerts := c.getCustomCA()
|
||||
if len(caCerts) > 0 {
|
||||
config.GetCertificate = getGetCertificateFunc(config, caCerts)
|
||||
} else {
|
||||
config.GetCertificate = getNewGetCertificateFunc(c.BuildCertificates(), c.RejectUnknownSni)
|
||||
}
|
||||
|
||||
if sn := c.parseServerName(); len(sn) > 0 {
|
||||
config.ServerName = sn
|
||||
}
|
||||
|
||||
if len(config.NextProtos) == 0 {
|
||||
config.NextProtos = []string{"h2", "http/1.1"}
|
||||
}
|
||||
|
||||
switch c.MinVersion {
|
||||
case "1.0":
|
||||
config.MinVersion = xtls.VersionTLS10
|
||||
case "1.1":
|
||||
config.MinVersion = xtls.VersionTLS11
|
||||
case "1.2":
|
||||
config.MinVersion = xtls.VersionTLS12
|
||||
case "1.3":
|
||||
config.MinVersion = xtls.VersionTLS13
|
||||
}
|
||||
|
||||
switch c.MaxVersion {
|
||||
case "1.0":
|
||||
config.MaxVersion = xtls.VersionTLS10
|
||||
case "1.1":
|
||||
config.MaxVersion = xtls.VersionTLS11
|
||||
case "1.2":
|
||||
config.MaxVersion = xtls.VersionTLS12
|
||||
case "1.3":
|
||||
config.MaxVersion = xtls.VersionTLS13
|
||||
}
|
||||
|
||||
if len(c.CipherSuites) > 0 {
|
||||
id := make(map[string]uint16)
|
||||
for _, s := range xtls.CipherSuites() {
|
||||
id[s.Name] = s.ID
|
||||
}
|
||||
for _, n := range strings.Split(c.CipherSuites, ":") {
|
||||
if id[n] != 0 {
|
||||
config.CipherSuites = append(config.CipherSuites, id[n])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config.PreferServerCipherSuites = c.PreferServerCipherSuites
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
// Option for building XTLS config.
|
||||
type Option func(*xtls.Config)
|
||||
|
||||
// WithDestination sets the server name in XTLS config.
|
||||
func WithDestination(dest net.Destination) Option {
|
||||
return func(config *xtls.Config) {
|
||||
if dest.Address.Family().IsDomain() && config.ServerName == "" {
|
||||
config.ServerName = dest.Address.Domain()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithNextProto sets the ALPN values in XTLS config.
|
||||
func WithNextProto(protocol ...string) Option {
|
||||
return func(config *xtls.Config) {
|
||||
if len(config.NextProtos) == 0 {
|
||||
config.NextProtos = protocol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ConfigFromStreamSettings fetches Config from stream settings. Nil if not found.
|
||||
func ConfigFromStreamSettings(settings *internet.MemoryStreamConfig) *Config {
|
||||
if settings == nil {
|
||||
return nil
|
||||
}
|
||||
config, ok := settings.SecuritySettings.(*Config)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return config
|
||||
}
|
|
@ -1,478 +0,0 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc v3.21.12
|
||||
// source: transport/internet/xtls/config.proto
|
||||
|
||||
package xtls
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Certificate_Usage int32
|
||||
|
||||
const (
|
||||
Certificate_ENCIPHERMENT Certificate_Usage = 0
|
||||
Certificate_AUTHORITY_VERIFY Certificate_Usage = 1
|
||||
Certificate_AUTHORITY_ISSUE Certificate_Usage = 2
|
||||
)
|
||||
|
||||
// Enum value maps for Certificate_Usage.
|
||||
var (
|
||||
Certificate_Usage_name = map[int32]string{
|
||||
0: "ENCIPHERMENT",
|
||||
1: "AUTHORITY_VERIFY",
|
||||
2: "AUTHORITY_ISSUE",
|
||||
}
|
||||
Certificate_Usage_value = map[string]int32{
|
||||
"ENCIPHERMENT": 0,
|
||||
"AUTHORITY_VERIFY": 1,
|
||||
"AUTHORITY_ISSUE": 2,
|
||||
}
|
||||
)
|
||||
|
||||
func (x Certificate_Usage) Enum() *Certificate_Usage {
|
||||
p := new(Certificate_Usage)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Certificate_Usage) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (Certificate_Usage) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_transport_internet_xtls_config_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (Certificate_Usage) Type() protoreflect.EnumType {
|
||||
return &file_transport_internet_xtls_config_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x Certificate_Usage) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Certificate_Usage.Descriptor instead.
|
||||
func (Certificate_Usage) EnumDescriptor() ([]byte, []int) {
|
||||
return file_transport_internet_xtls_config_proto_rawDescGZIP(), []int{0, 0}
|
||||
}
|
||||
|
||||
type Certificate struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// TLS certificate in x509 format.
|
||||
Certificate []byte `protobuf:"bytes,1,opt,name=certificate,proto3" json:"certificate,omitempty"`
|
||||
// TLS key in x509 format.
|
||||
Key []byte `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
|
||||
Usage Certificate_Usage `protobuf:"varint,3,opt,name=usage,proto3,enum=xray.transport.internet.xtls.Certificate_Usage" json:"usage,omitempty"`
|
||||
OcspStapling uint64 `protobuf:"varint,4,opt,name=ocsp_stapling,json=ocspStapling,proto3" json:"ocsp_stapling,omitempty"`
|
||||
// TLS certificate path
|
||||
CertificatePath string `protobuf:"bytes,5,opt,name=certificate_path,json=certificatePath,proto3" json:"certificate_path,omitempty"`
|
||||
// TLS Key path
|
||||
KeyPath string `protobuf:"bytes,6,opt,name=key_path,json=keyPath,proto3" json:"key_path,omitempty"`
|
||||
// If true, one-Time Loading
|
||||
OneTimeLoading bool `protobuf:"varint,7,opt,name=One_time_loading,json=OneTimeLoading,proto3" json:"One_time_loading,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Certificate) Reset() {
|
||||
*x = Certificate{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_transport_internet_xtls_config_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Certificate) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Certificate) ProtoMessage() {}
|
||||
|
||||
func (x *Certificate) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_transport_internet_xtls_config_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Certificate.ProtoReflect.Descriptor instead.
|
||||
func (*Certificate) Descriptor() ([]byte, []int) {
|
||||
return file_transport_internet_xtls_config_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Certificate) GetCertificate() []byte {
|
||||
if x != nil {
|
||||
return x.Certificate
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Certificate) GetKey() []byte {
|
||||
if x != nil {
|
||||
return x.Key
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Certificate) GetUsage() Certificate_Usage {
|
||||
if x != nil {
|
||||
return x.Usage
|
||||
}
|
||||
return Certificate_ENCIPHERMENT
|
||||
}
|
||||
|
||||
func (x *Certificate) GetOcspStapling() uint64 {
|
||||
if x != nil {
|
||||
return x.OcspStapling
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Certificate) GetCertificatePath() string {
|
||||
if x != nil {
|
||||
return x.CertificatePath
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Certificate) GetKeyPath() string {
|
||||
if x != nil {
|
||||
return x.KeyPath
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Certificate) GetOneTimeLoading() bool {
|
||||
if x != nil {
|
||||
return x.OneTimeLoading
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Whether or not to allow self-signed certificates.
|
||||
AllowInsecure bool `protobuf:"varint,1,opt,name=allow_insecure,json=allowInsecure,proto3" json:"allow_insecure,omitempty"`
|
||||
// List of certificates to be served on server.
|
||||
Certificate []*Certificate `protobuf:"bytes,2,rep,name=certificate,proto3" json:"certificate,omitempty"`
|
||||
// Override server name.
|
||||
ServerName string `protobuf:"bytes,3,opt,name=server_name,json=serverName,proto3" json:"server_name,omitempty"`
|
||||
// Lists of string as ALPN values.
|
||||
NextProtocol []string `protobuf:"bytes,4,rep,name=next_protocol,json=nextProtocol,proto3" json:"next_protocol,omitempty"`
|
||||
// Whether or not to enable session (ticket) resumption.
|
||||
EnableSessionResumption bool `protobuf:"varint,5,opt,name=enable_session_resumption,json=enableSessionResumption,proto3" json:"enable_session_resumption,omitempty"`
|
||||
// If true, root certificates on the system will not be loaded for
|
||||
// verification.
|
||||
DisableSystemRoot bool `protobuf:"varint,6,opt,name=disable_system_root,json=disableSystemRoot,proto3" json:"disable_system_root,omitempty"`
|
||||
// The minimum TLS version.
|
||||
MinVersion string `protobuf:"bytes,7,opt,name=min_version,json=minVersion,proto3" json:"min_version,omitempty"`
|
||||
// The maximum TLS version.
|
||||
MaxVersion string `protobuf:"bytes,8,opt,name=max_version,json=maxVersion,proto3" json:"max_version,omitempty"`
|
||||
// Specify cipher suites, except for TLS 1.3.
|
||||
CipherSuites string `protobuf:"bytes,9,opt,name=cipher_suites,json=cipherSuites,proto3" json:"cipher_suites,omitempty"`
|
||||
// Whether the server selects its most preferred ciphersuite.
|
||||
PreferServerCipherSuites bool `protobuf:"varint,10,opt,name=prefer_server_cipher_suites,json=preferServerCipherSuites,proto3" json:"prefer_server_cipher_suites,omitempty"`
|
||||
RejectUnknownSni bool `protobuf:"varint,12,opt,name=reject_unknown_sni,json=rejectUnknownSni,proto3" json:"reject_unknown_sni,omitempty"`
|
||||
// @Document A pinned certificate chain sha256 hash.
|
||||
// @Document If the server's hash does not match this value, the connection will be aborted.
|
||||
// @Document This value replace allow_insecure.
|
||||
// @Critical
|
||||
PinnedPeerCertificateChainSha256 [][]byte `protobuf:"bytes,13,rep,name=pinned_peer_certificate_chain_sha256,json=pinnedPeerCertificateChainSha256,proto3" json:"pinned_peer_certificate_chain_sha256,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Config) Reset() {
|
||||
*x = Config{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_transport_internet_xtls_config_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Config) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Config) ProtoMessage() {}
|
||||
|
||||
func (x *Config) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_transport_internet_xtls_config_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Config.ProtoReflect.Descriptor instead.
|
||||
func (*Config) Descriptor() ([]byte, []int) {
|
||||
return file_transport_internet_xtls_config_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Config) GetAllowInsecure() bool {
|
||||
if x != nil {
|
||||
return x.AllowInsecure
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Config) GetCertificate() []*Certificate {
|
||||
if x != nil {
|
||||
return x.Certificate
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetServerName() string {
|
||||
if x != nil {
|
||||
return x.ServerName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Config) GetNextProtocol() []string {
|
||||
if x != nil {
|
||||
return x.NextProtocol
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetEnableSessionResumption() bool {
|
||||
if x != nil {
|
||||
return x.EnableSessionResumption
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Config) GetDisableSystemRoot() bool {
|
||||
if x != nil {
|
||||
return x.DisableSystemRoot
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Config) GetMinVersion() string {
|
||||
if x != nil {
|
||||
return x.MinVersion
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Config) GetMaxVersion() string {
|
||||
if x != nil {
|
||||
return x.MaxVersion
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Config) GetCipherSuites() string {
|
||||
if x != nil {
|
||||
return x.CipherSuites
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Config) GetPreferServerCipherSuites() bool {
|
||||
if x != nil {
|
||||
return x.PreferServerCipherSuites
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Config) GetRejectUnknownSni() bool {
|
||||
if x != nil {
|
||||
return x.RejectUnknownSni
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Config) GetPinnedPeerCertificateChainSha256() [][]byte {
|
||||
if x != nil {
|
||||
return x.PinnedPeerCertificateChainSha256
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_transport_internet_xtls_config_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_transport_internet_xtls_config_proto_rawDesc = []byte{
|
||||
0x0a, 0x24, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x6e, 0x65, 0x74, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61,
|
||||
0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e,
|
||||
0x78, 0x74, 0x6c, 0x73, 0x22, 0xe3, 0x02, 0x0a, 0x0b, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
|
||||
0x63, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
|
||||
0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69,
|
||||
0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x45, 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67,
|
||||
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74,
|
||||
0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
|
||||
0x74, 0x2e, 0x78, 0x74, 0x6c, 0x73, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
|
||||
0x74, 0x65, 0x2e, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x12,
|
||||
0x23, 0x0a, 0x0d, 0x6f, 0x63, 0x73, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x70, 0x6c, 0x69, 0x6e, 0x67,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6f, 0x63, 0x73, 0x70, 0x53, 0x74, 0x61, 0x70,
|
||||
0x6c, 0x69, 0x6e, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
|
||||
0x61, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f,
|
||||
0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12,
|
||||
0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x50, 0x61, 0x74, 0x68, 0x12, 0x28, 0x0a, 0x10, 0x4f, 0x6e,
|
||||
0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x07,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x4f, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x4c, 0x6f, 0x61,
|
||||
0x64, 0x69, 0x6e, 0x67, 0x22, 0x44, 0x0a, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a,
|
||||
0x0c, 0x45, 0x4e, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12,
|
||||
0x14, 0x0a, 0x10, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x56, 0x45, 0x52,
|
||||
0x49, 0x46, 0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49,
|
||||
0x54, 0x59, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0xd2, 0x04, 0x0a, 0x06, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x69,
|
||||
0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61,
|
||||
0x6c, 0x6c, 0x6f, 0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x4b, 0x0a, 0x0b,
|
||||
0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x29, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f,
|
||||
0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x78, 0x74, 0x6c, 0x73,
|
||||
0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x63, 0x65,
|
||||
0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72,
|
||||
0x76, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
|
||||
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x65,
|
||||
0x78, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x0c, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12,
|
||||
0x3a, 0x0a, 0x19, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x64,
|
||||
0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x72, 0x6f,
|
||||
0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d,
|
||||
0x69, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b,
|
||||
0x6d, 0x61, 0x78, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a,
|
||||
0x0d, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x09,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74,
|
||||
0x65, 0x73, 0x12, 0x3d, 0x0a, 0x1b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x72,
|
||||
0x76, 0x65, 0x72, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69, 0x74, 0x65,
|
||||
0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x53,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65,
|
||||
0x73, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x6e, 0x6b, 0x6e,
|
||||
0x6f, 0x77, 0x6e, 0x5f, 0x73, 0x6e, 0x69, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x72,
|
||||
0x65, 0x6a, 0x65, 0x63, 0x74, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x6e, 0x69, 0x12,
|
||||
0x4e, 0x0a, 0x24, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63,
|
||||
0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e,
|
||||
0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x20, 0x70,
|
||||
0x69, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
|
||||
0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x42,
|
||||
0x76, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e,
|
||||
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x78,
|
||||
0x74, 0x6c, 0x73, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65,
|
||||
0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x6e, 0x65, 0x74, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x1c, 0x58, 0x72, 0x61, 0x79, 0x2e,
|
||||
0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x65, 0x74, 0x2e, 0x58, 0x74, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_transport_internet_xtls_config_proto_rawDescOnce sync.Once
|
||||
file_transport_internet_xtls_config_proto_rawDescData = file_transport_internet_xtls_config_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_transport_internet_xtls_config_proto_rawDescGZIP() []byte {
|
||||
file_transport_internet_xtls_config_proto_rawDescOnce.Do(func() {
|
||||
file_transport_internet_xtls_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_transport_internet_xtls_config_proto_rawDescData)
|
||||
})
|
||||
return file_transport_internet_xtls_config_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_transport_internet_xtls_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_transport_internet_xtls_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_transport_internet_xtls_config_proto_goTypes = []interface{}{
|
||||
(Certificate_Usage)(0), // 0: xray.transport.internet.xtls.Certificate.Usage
|
||||
(*Certificate)(nil), // 1: xray.transport.internet.xtls.Certificate
|
||||
(*Config)(nil), // 2: xray.transport.internet.xtls.Config
|
||||
}
|
||||
var file_transport_internet_xtls_config_proto_depIdxs = []int32{
|
||||
0, // 0: xray.transport.internet.xtls.Certificate.usage:type_name -> xray.transport.internet.xtls.Certificate.Usage
|
||||
1, // 1: xray.transport.internet.xtls.Config.certificate:type_name -> xray.transport.internet.xtls.Certificate
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_transport_internet_xtls_config_proto_init() }
|
||||
func file_transport_internet_xtls_config_proto_init() {
|
||||
if File_transport_internet_xtls_config_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_transport_internet_xtls_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Certificate); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_transport_internet_xtls_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Config); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_transport_internet_xtls_config_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_transport_internet_xtls_config_proto_goTypes,
|
||||
DependencyIndexes: file_transport_internet_xtls_config_proto_depIdxs,
|
||||
EnumInfos: file_transport_internet_xtls_config_proto_enumTypes,
|
||||
MessageInfos: file_transport_internet_xtls_config_proto_msgTypes,
|
||||
}.Build()
|
||||
File_transport_internet_xtls_config_proto = out.File
|
||||
file_transport_internet_xtls_config_proto_rawDesc = nil
|
||||
file_transport_internet_xtls_config_proto_goTypes = nil
|
||||
file_transport_internet_xtls_config_proto_depIdxs = nil
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package xray.transport.internet.xtls;
|
||||
option csharp_namespace = "Xray.Transport.Internet.Xtls";
|
||||
option go_package = "github.com/xtls/xray-core/transport/internet/xtls";
|
||||
option java_package = "com.xray.transport.internet.xtls";
|
||||
option java_multiple_files = true;
|
||||
|
||||
message Certificate {
|
||||
// TLS certificate in x509 format.
|
||||
bytes certificate = 1;
|
||||
|
||||
// TLS key in x509 format.
|
||||
bytes key = 2;
|
||||
|
||||
enum Usage {
|
||||
ENCIPHERMENT = 0;
|
||||
AUTHORITY_VERIFY = 1;
|
||||
AUTHORITY_ISSUE = 2;
|
||||
}
|
||||
|
||||
Usage usage = 3;
|
||||
|
||||
uint64 ocsp_stapling = 4;
|
||||
|
||||
// TLS certificate path
|
||||
string certificate_path = 5;
|
||||
|
||||
// TLS Key path
|
||||
string key_path = 6;
|
||||
|
||||
// If true, one-Time Loading
|
||||
bool One_time_loading = 7;
|
||||
}
|
||||
|
||||
message Config {
|
||||
// Whether or not to allow self-signed certificates.
|
||||
bool allow_insecure = 1;
|
||||
|
||||
// List of certificates to be served on server.
|
||||
repeated Certificate certificate = 2;
|
||||
|
||||
// Override server name.
|
||||
string server_name = 3;
|
||||
|
||||
// Lists of string as ALPN values.
|
||||
repeated string next_protocol = 4;
|
||||
|
||||
// Whether or not to enable session (ticket) resumption.
|
||||
bool enable_session_resumption = 5;
|
||||
|
||||
// If true, root certificates on the system will not be loaded for
|
||||
// verification.
|
||||
bool disable_system_root = 6;
|
||||
|
||||
// The minimum TLS version.
|
||||
string min_version = 7;
|
||||
|
||||
// The maximum TLS version.
|
||||
string max_version = 8;
|
||||
|
||||
// Specify cipher suites, except for TLS 1.3.
|
||||
string cipher_suites = 9;
|
||||
|
||||
// Whether the server selects its most preferred ciphersuite.
|
||||
bool prefer_server_cipher_suites = 10;
|
||||
|
||||
bool reject_unknown_sni = 12;
|
||||
|
||||
/* @Document A pinned certificate chain sha256 hash.
|
||||
@Document If the server's hash does not match this value, the connection will be aborted.
|
||||
@Document This value replace allow_insecure.
|
||||
@Critical
|
||||
*/
|
||||
repeated bytes pinned_peer_certificate_chain_sha256 = 13;
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package xtls
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type rootCertsCache struct {
|
||||
sync.Mutex
|
||||
pool *x509.CertPool
|
||||
}
|
||||
|
||||
func (c *rootCertsCache) load() (*x509.CertPool, error) {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
if c.pool != nil {
|
||||
return c.pool, nil
|
||||
}
|
||||
|
||||
pool, err := x509.SystemCertPool()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.pool = pool
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
var rootCerts rootCertsCache
|
||||
|
||||
func (c *Config) getCertPool() (*x509.CertPool, error) {
|
||||
if c.DisableSystemRoot {
|
||||
return c.loadSelfCertPool()
|
||||
}
|
||||
|
||||
if len(c.Certificate) == 0 {
|
||||
return rootCerts.load()
|
||||
}
|
||||
|
||||
pool, err := x509.SystemCertPool()
|
||||
if err != nil {
|
||||
return nil, newError("system root").AtWarning().Base(err)
|
||||
}
|
||||
for _, cert := range c.Certificate {
|
||||
if !pool.AppendCertsFromPEM(cert.Certificate) {
|
||||
return nil, newError("append cert to root").AtWarning().Base(err)
|
||||
}
|
||||
}
|
||||
return pool, err
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
package xtls_test
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
xtls "github.com/xtls/go"
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/protocol/tls/cert"
|
||||
. "github.com/xtls/xray-core/transport/internet/xtls"
|
||||
)
|
||||
|
||||
func TestCertificateIssuing(t *testing.T) {
|
||||
certificate := ParseCertificate(cert.MustGenerate(nil, cert.Authority(true), cert.KeyUsage(x509.KeyUsageCertSign)))
|
||||
certificate.Usage = Certificate_AUTHORITY_ISSUE
|
||||
|
||||
c := &Config{
|
||||
Certificate: []*Certificate{
|
||||
certificate,
|
||||
},
|
||||
}
|
||||
|
||||
xtlsConfig := c.GetXTLSConfig()
|
||||
xrayCert, err := xtlsConfig.GetCertificate(&xtls.ClientHelloInfo{
|
||||
ServerName: "www.example.com",
|
||||
})
|
||||
common.Must(err)
|
||||
|
||||
x509Cert, err := x509.ParseCertificate(xrayCert.Certificate[0])
|
||||
common.Must(err)
|
||||
if !x509Cert.NotAfter.After(time.Now()) {
|
||||
t.Error("NotAfter: ", x509Cert.NotAfter)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpiredCertificate(t *testing.T) {
|
||||
caCert := cert.MustGenerate(nil, cert.Authority(true), cert.KeyUsage(x509.KeyUsageCertSign))
|
||||
expiredCert := cert.MustGenerate(caCert, cert.NotAfter(time.Now().Add(time.Minute*-2)), cert.CommonName("www.example.com"), cert.DNSNames("www.example.com"))
|
||||
|
||||
certificate := ParseCertificate(caCert)
|
||||
certificate.Usage = Certificate_AUTHORITY_ISSUE
|
||||
|
||||
certificate2 := ParseCertificate(expiredCert)
|
||||
|
||||
c := &Config{
|
||||
Certificate: []*Certificate{
|
||||
certificate,
|
||||
certificate2,
|
||||
},
|
||||
}
|
||||
|
||||
xtlsConfig := c.GetXTLSConfig()
|
||||
xrayCert, err := xtlsConfig.GetCertificate(&xtls.ClientHelloInfo{
|
||||
ServerName: "www.example.com",
|
||||
})
|
||||
common.Must(err)
|
||||
|
||||
x509Cert, err := x509.ParseCertificate(xrayCert.Certificate[0])
|
||||
common.Must(err)
|
||||
if !x509Cert.NotAfter.After(time.Now()) {
|
||||
t.Error("NotAfter: ", x509Cert.NotAfter)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInsecureCertificates(t *testing.T) {
|
||||
c := &Config{}
|
||||
|
||||
xtlsConfig := c.GetXTLSConfig()
|
||||
if len(xtlsConfig.CipherSuites) > 0 {
|
||||
t.Fatal("Unexpected tls cipher suites list: ", xtlsConfig.CipherSuites)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCertificateIssuing(b *testing.B) {
|
||||
certificate := ParseCertificate(cert.MustGenerate(nil, cert.Authority(true), cert.KeyUsage(x509.KeyUsageCertSign)))
|
||||
certificate.Usage = Certificate_AUTHORITY_ISSUE
|
||||
|
||||
c := &Config{
|
||||
Certificate: []*Certificate{
|
||||
certificate,
|
||||
},
|
||||
}
|
||||
|
||||
xtlsConfig := c.GetXTLSConfig()
|
||||
lenCerts := len(xtlsConfig.Certificates)
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = xtlsConfig.GetCertificate(&xtls.ClientHelloInfo{
|
||||
ServerName: "www.example.com",
|
||||
})
|
||||
delete(xtlsConfig.NameToCertificate, "www.example.com")
|
||||
xtlsConfig.Certificates = xtlsConfig.Certificates[:lenCerts]
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package xtls
|
||||
|
||||
import "crypto/x509"
|
||||
|
||||
func (c *Config) getCertPool() (*x509.CertPool, error) {
|
||||
if c.DisableSystemRoot {
|
||||
return c.loadSelfCertPool()
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package xtls
|
||||
|
||||
import "github.com/xtls/xray-core/common/errors"
|
||||
|
||||
type errPathObjHolder struct{}
|
||||
|
||||
func newError(values ...interface{}) *errors.Error {
|
||||
return errors.New(values...).WithPathObj(errPathObjHolder{})
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
package xtls
|
||||
|
||||
import _ "unsafe"
|
||||
|
||||
//go:linkname errNoCertificates github.com/xtls/go.errNoCertificates
|
||||
var errNoCertificates error
|
|
@ -1,35 +0,0 @@
|
|||
package xtls
|
||||
|
||||
import (
|
||||
xtls "github.com/xtls/go"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||
|
||||
type Conn struct {
|
||||
*xtls.Conn
|
||||
}
|
||||
|
||||
func (c *Conn) HandshakeAddress() net.Address {
|
||||
if err := c.Handshake(); err != nil {
|
||||
return nil
|
||||
}
|
||||
state := c.ConnectionState()
|
||||
if state.ServerName == "" {
|
||||
return nil
|
||||
}
|
||||
return net.ParseAddress(state.ServerName)
|
||||
}
|
||||
|
||||
// Client initiates a XTLS client handshake on the given connection.
|
||||
func Client(c net.Conn, config *xtls.Config) net.Conn {
|
||||
xtlsConn := xtls.Client(c, config)
|
||||
return &Conn{Conn: xtlsConn}
|
||||
}
|
||||
|
||||
// Server initiates a XTLS server handshake on the given connection.
|
||||
func Server(c net.Conn, config *xtls.Config) net.Conn {
|
||||
xtlsConn := xtls.Server(c, config)
|
||||
return &Conn{Conn: xtlsConn}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue