Speak protocol 3.0 and fall back to 2.0 only when that is the reflector's maximum.
A reflector that has moved to 3.0 will not accept a station that always announces 2.0, and a 2.x reflector still needs one explicit plaintext session. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
package station
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var errHostMismatch = errors.New("host mismatch")
|
||||
|
||||
func tlsConfig(host string, caPEM []byte, client tls.Certificate, present bool) (*tls.Config, error) {
|
||||
pool := x509.NewCertPool()
|
||||
if !pool.AppendCertsFromPEM(caPEM) {
|
||||
return nil, errors.New("ca bundle")
|
||||
}
|
||||
cfg := &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
RootCAs: pool,
|
||||
InsecureSkipVerify: true,
|
||||
VerifyConnection: func(cs tls.ConnectionState) error {
|
||||
return verifyPeer(host, pool, cs)
|
||||
},
|
||||
}
|
||||
if present {
|
||||
cfg.Certificates = []tls.Certificate{client}
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func verifyPeer(host string, pool *x509.CertPool, cs tls.ConnectionState) error {
|
||||
if len(cs.PeerCertificates) == 0 {
|
||||
return errors.New("no peer certificate")
|
||||
}
|
||||
leaf := cs.PeerCertificates[0]
|
||||
opts := x509.VerifyOptions{Roots: pool, KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}}
|
||||
if len(cs.PeerCertificates) > 1 {
|
||||
opts.Intermediates = x509.NewCertPool()
|
||||
for _, cert := range cs.PeerCertificates[1:] {
|
||||
opts.Intermediates.AddCert(cert)
|
||||
}
|
||||
}
|
||||
if _, err := leaf.Verify(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
host = strings.TrimSuffix(host, ".")
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
for _, cand := range leaf.IPAddresses {
|
||||
if cand.Equal(ip) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return errHostMismatch
|
||||
}
|
||||
if err := leaf.VerifyHostname(host); err != nil {
|
||||
return errHostMismatch
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user