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>
61 lines
1.4 KiB
Go
61 lines
1.4 KiB
Go
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
|
|
}
|