package xtls
import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"os"
)
type Config struct {
Enabled bool `json:"enabled" yaml:"enabled"`
Insecure bool `json:"insecure" yaml:"insecure" config:"allowempty"`
ServerName string `json:"serverName" yaml:"server_name" config:"allowempty"`
CACertFile string `json:"caCertFile" yaml:"ca_cert_file" config:"allowempty"`
ClientCertFile string `json:"clientCertFile" yaml:"client_cert_file" config:"allowempty"`
ClientKeyFile string `json:"clientKeyFile" yaml:"client_key_file" config:"allowempty"`
}
var ErrFailedToLoadCACert = errors.New("failed to load CACertificate")
func (c *Config) ClientTLSConfig() (*tls.Config, error) {
tlsConf := tls.Config{
MinVersion: tls.VersionTLS12,
}
if c.ClientCertFile != "" {
certificate, err := tls.LoadX509KeyPair(c.ClientCertFile, c.ClientKeyFile)
if err != nil {
return nil, fmt.Errorf("could not load client key pair: %w", err)
}
tlsConf.Certificates = []tls.Certificate{certificate}
}
if c.Insecure {
tlsConf.InsecureSkipVerify = true
}
if c.ServerName != "" {
tlsConf.ServerName = c.ServerName
}
if c.CACertFile != "" {
certPool := x509.NewCertPool()
ca, err := os.ReadFile(c.CACertFile)
if err != nil {
return nil, fmt.Errorf("could not read ca certificate: %w", err)
}
if ok := certPool.AppendCertsFromPEM(ca); !ok {
return nil, ErrFailedToLoadCACert
}
tlsConf.RootCAs = certPool
}
return &tlsConf, nil
}