github.com/livekit/protocol@v1.16.1-0.20240517185851-47e4c6bba773/xtls/tls.go (about)

     1  package xtls
     2  
     3  import (
     4  	"crypto/tls"
     5  	"crypto/x509"
     6  	"errors"
     7  	"fmt"
     8  	"os"
     9  )
    10  
    11  type Config struct {
    12  	Enabled bool `json:"enabled" yaml:"enabled"`
    13  
    14  	// Skip server certificate and domain verification.
    15  	Insecure bool `json:"insecure" yaml:"insecure"`
    16  
    17  	// Server name indication for TLS.
    18  	ServerName string `json:"serverName" yaml:"server_name"`
    19  
    20  	// File containing trusted root certificates for verifying the server.
    21  	CACertFile string `json:"caCertFile" yaml:"ca_cert_file"`
    22  
    23  	// File containing client certificate (public key), to present to the
    24  	// server. Must also provide @ClientKey option.
    25  	ClientCertFile string `json:"clientCertFile" yaml:"client_cert_file"`
    26  
    27  	// File containing client private key, to present to the server.
    28  	// Must also provide @ClientCert option.
    29  	ClientKeyFile string `json:"clientKeyFile" yaml:"client_key_file"`
    30  }
    31  
    32  var ErrFailedToLoadCACert = errors.New("failed to load CACertificate")
    33  
    34  func (c *Config) ClientTLSConfig() (*tls.Config, error) {
    35  	tlsConf := tls.Config{
    36  		MinVersion: tls.VersionTLS12,
    37  	}
    38  
    39  	if c.ClientCertFile != "" {
    40  		// Load the client certificates from disk
    41  		certificate, err := tls.LoadX509KeyPair(c.ClientCertFile, c.ClientKeyFile)
    42  		if err != nil {
    43  			return nil, fmt.Errorf("could not load client key pair: %w", err)
    44  		}
    45  
    46  		tlsConf.Certificates = []tls.Certificate{certificate}
    47  	}
    48  
    49  	if c.Insecure {
    50  		// #nosec G402
    51  		tlsConf.InsecureSkipVerify = true
    52  	}
    53  
    54  	if c.ServerName != "" {
    55  		tlsConf.ServerName = c.ServerName
    56  	}
    57  
    58  	if c.CACertFile != "" {
    59  		// Create a certificate pool from the certificate authority
    60  		certPool := x509.NewCertPool()
    61  
    62  		ca, err := os.ReadFile(c.CACertFile)
    63  		if err != nil {
    64  			return nil, fmt.Errorf("could not read ca certificate: %w", err)
    65  		}
    66  
    67  		if ok := certPool.AppendCertsFromPEM(ca); !ok {
    68  			return nil, ErrFailedToLoadCACert
    69  		}
    70  
    71  		tlsConf.RootCAs = certPool
    72  	}
    73  
    74  	return &tlsConf, nil
    75  }