mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-09-16 14:30:28 +00:00
Compare commits
1
Commits
main
...
session-resume
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50162ff81d |
@@ -13,6 +13,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
utls "github.com/refraction-networking/utls"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/ocsp"
|
||||
@@ -22,6 +23,7 @@ import (
|
||||
)
|
||||
|
||||
var globalSessionCache = tls.NewLRUClientSessionCache(128)
|
||||
var uGlobalSessionCache = utls.NewLRUClientSessionCache(128)
|
||||
|
||||
// ParseCertificate converts a cert.Certificate to Certificate.
|
||||
func ParseCertificate(c *cert.Certificate) *Certificate {
|
||||
@@ -280,12 +282,10 @@ func (c *Config) parseServerName() string {
|
||||
return c.ServerName
|
||||
}
|
||||
|
||||
func (r *RandCarrier) verifyPeerCert(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) (err error) {
|
||||
// extract x509 certificates from rawCerts (verifiedChains will be nil if InsecureSkipVerify is true)
|
||||
certs := make([]*x509.Certificate, len(rawCerts))
|
||||
for i, asn1Data := range rawCerts {
|
||||
certs[i], _ = x509.ParseCertificate(asn1Data)
|
||||
}
|
||||
// Note: Remember to update uVerifyConnectionAdapter if this function needs more fields in the future.
|
||||
func (r *RandCarrier) verifyConnection(cs tls.ConnectionState) error {
|
||||
certs := cs.PeerCertificates
|
||||
// extract x509 certificates from cs.PeerCertificates
|
||||
if len(certs) == 0 {
|
||||
return errors.New("unexpected certs")
|
||||
}
|
||||
@@ -325,7 +325,7 @@ func (r *RandCarrier) verifyPeerCert(rawCerts [][]byte, verifiedChains [][]*x509
|
||||
}
|
||||
}
|
||||
if verifyResult == foundCA {
|
||||
errors.New("peer cert is invalid (against pinned CA and verifyPeerCertByName)")
|
||||
return errors.New("peer cert is invalid (against pinned CA and verifyPeerCertByName)")
|
||||
}
|
||||
return errors.New("peer cert is invalid (against root CAs and verifyPeerCertByName)")
|
||||
}
|
||||
@@ -352,6 +352,18 @@ func (r *RandCarrier) verifyPeerCert(rawCerts [][]byte, verifiedChains [][]*x509
|
||||
return nil // r.PinnedPeerCertSha256==nil && r.verifyPeerCertByName==nil
|
||||
}
|
||||
|
||||
func uVerifyConnectionAdapter(f func(tls.ConnectionState) error) func(utls.ConnectionState) error {
|
||||
if f == nil {
|
||||
return nil
|
||||
}
|
||||
return func(cs utls.ConnectionState) error {
|
||||
standardCS := tls.ConnectionState{
|
||||
PeerCertificates: cs.PeerCertificates,
|
||||
}
|
||||
return f(standardCS)
|
||||
}
|
||||
}
|
||||
|
||||
type RandCarrier struct {
|
||||
Config *tls.Config
|
||||
RootCAs *x509.CertPool
|
||||
@@ -389,7 +401,7 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
|
||||
RootCAs: root,
|
||||
NextProtos: slices.Clone(c.NextProtocol),
|
||||
SessionTicketsDisabled: !c.EnableSessionResumption,
|
||||
VerifyPeerCertificate: randCarrier.verifyPeerCert,
|
||||
VerifyConnection: randCarrier.verifyConnection,
|
||||
}
|
||||
randCarrier.Config = config
|
||||
if len(c.VerifyPeerCertByName) > 0 {
|
||||
|
||||
@@ -110,15 +110,15 @@ func TestVerifyPeerLeafCert(t *testing.T) {
|
||||
PinnedPeerCertSha256: [][]byte{leafHash[:]},
|
||||
}
|
||||
|
||||
rawCerts := [][]byte{leaf.Raw}
|
||||
err := r.verifyPeerCert(rawCerts, nil)
|
||||
cs := tls.ConnectionState{PeerCertificates: []*x509.Certificate{leaf}}
|
||||
err := r.verifyConnection(cs)
|
||||
if err != nil {
|
||||
t.Fatal("expected to verify leaf cert signed by pinned CA, but got error:", err)
|
||||
}
|
||||
|
||||
// make the pinned hash incorrect
|
||||
r.PinnedPeerCertSha256[0][0] += 1
|
||||
err = r.verifyPeerCert(rawCerts, nil)
|
||||
err = r.verifyConnection(cs)
|
||||
if err == nil {
|
||||
t.Fatal("expected to fail verifying leaf cert with incorrect pinned CA hash, but got no error")
|
||||
}
|
||||
@@ -138,15 +138,15 @@ func TestVerifyPeerCACert(t *testing.T) {
|
||||
PinnedPeerCertSha256: [][]byte{caHash[:]},
|
||||
}
|
||||
|
||||
rawCerts := [][]byte{leaf.Raw, ca.Raw}
|
||||
err := r.verifyPeerCert(rawCerts, nil)
|
||||
cs := tls.ConnectionState{PeerCertificates: []*x509.Certificate{leaf, ca}}
|
||||
err := r.verifyConnection(cs)
|
||||
if err != nil {
|
||||
t.Fatal("expected to verify leaf cert signed by pinned CA, but got error:", err)
|
||||
}
|
||||
|
||||
// make the pinned hash incorrect
|
||||
r.PinnedPeerCertSha256[0][0] += 1
|
||||
err = r.verifyPeerCert(rawCerts, nil)
|
||||
err = r.verifyConnection(cs)
|
||||
if err == nil {
|
||||
t.Fatal("expected to fail verifying leaf cert with incorrect pinned CA hash, but got no error")
|
||||
}
|
||||
|
||||
@@ -152,11 +152,16 @@ func copyConfig(c *tls.Config) *utls.Config {
|
||||
RootCAs: c.RootCAs,
|
||||
ServerName: c.ServerName,
|
||||
InsecureSkipVerify: c.InsecureSkipVerify,
|
||||
VerifyPeerCertificate: c.VerifyPeerCertificate,
|
||||
VerifyConnection: uVerifyConnectionAdapter(c.VerifyConnection),
|
||||
SessionTicketsDisabled: c.SessionTicketsDisabled,
|
||||
KeyLogWriter: c.KeyLogWriter,
|
||||
EncryptedClientHelloConfigList: c.EncryptedClientHelloConfigList,
|
||||
NextProtos: c.NextProtos,
|
||||
}
|
||||
if c.ClientSessionCache != nil {
|
||||
config.ClientSessionCache = uGlobalSessionCache
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user