51 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			51 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package mqtt
 | 
						|
 | 
						|
import (
 | 
						|
	"MQTTLogger/config"
 | 
						|
	"crypto/tls"
 | 
						|
	"crypto/x509"
 | 
						|
	"fmt"
 | 
						|
	"net/url"
 | 
						|
	"os"
 | 
						|
 | 
						|
	"go.uber.org/zap"
 | 
						|
)
 | 
						|
 | 
						|
func NewTLSConfig(logger *zap.Logger, config *config.Config) *tls.Config {
 | 
						|
 | 
						|
	if config.CACert == "" {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	certpool := x509.NewCertPool()
 | 
						|
	pemCerts, err := os.ReadFile(config.CACert)
 | 
						|
	if err == nil {
 | 
						|
		certpool.AppendCertsFromPEM(pemCerts)
 | 
						|
	} else {
 | 
						|
		logger.Fatal("error loading CA cert", zap.Error(err))
 | 
						|
	}
 | 
						|
 | 
						|
	return &tls.Config{
 | 
						|
		RootCAs:            certpool,
 | 
						|
		InsecureSkipVerify: true,
 | 
						|
		Certificates:       nil,
 | 
						|
		VerifyPeerCertificate: func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
 | 
						|
			cert, err := x509.ParseCertificate(rawCerts[0])
 | 
						|
			if err != nil {
 | 
						|
				return fmt.Errorf("failed to parse certificate: %w", err)
 | 
						|
			}
 | 
						|
 | 
						|
			opts := x509.VerifyOptions{Roots: certpool}
 | 
						|
			if _, err := cert.Verify(opts); err != nil {
 | 
						|
				return fmt.Errorf("failed to verify chain: %w", err)
 | 
						|
			}
 | 
						|
 | 
						|
			expectedCN, _ := url.Parse(config.URI)
 | 
						|
			if cert.Subject.CommonName != expectedCN.Hostname() {
 | 
						|
				return fmt.Errorf("unexpected CN, expected %s but got %s", expectedCN.Host, cert.Subject.CommonName)
 | 
						|
			}
 | 
						|
			return nil
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 |