From 3967caa530d9a10d86331f5a614b0468ba62ad25 Mon Sep 17 00:00:00 2001 From: Alessandro Ros Date: Tue, 18 Jul 2023 23:39:26 +0200 Subject: [PATCH] join validation of TLS fingerprints (#2071) --- internal/core/hls_source.go | 27 +--------------------- internal/core/rtmp_source.go | 24 +++----------------- internal/core/tls_fingerprint.go | 39 ++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 47 deletions(-) create mode 100644 internal/core/tls_fingerprint.go diff --git a/internal/core/hls_source.go b/internal/core/hls_source.go index 0a8cf759..a364fce1 100644 --- a/internal/core/hls_source.go +++ b/internal/core/hls_source.go @@ -2,12 +2,7 @@ package core import ( "context" - "crypto/sha256" - "crypto/tls" - "encoding/hex" - "fmt" "net/http" - "strings" "time" "github.com/bluenviron/gohlslib" @@ -52,31 +47,11 @@ func (s *hlsSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan } }() - var tlsConfig *tls.Config - if cnf.SourceFingerprint != "" { - tlsConfig = &tls.Config{ - InsecureSkipVerify: true, - VerifyConnection: func(cs tls.ConnectionState) error { - h := sha256.New() - h.Write(cs.PeerCertificates[0].Raw) - hstr := hex.EncodeToString(h.Sum(nil)) - fingerprintLower := strings.ToLower(cnf.SourceFingerprint) - - if hstr != fingerprintLower { - return fmt.Errorf("server fingerprint do not match: expected %s, got %s", - fingerprintLower, hstr) - } - - return nil - }, - } - } - c := &gohlslib.Client{ URI: cnf.Source, HTTPClient: &http.Client{ Transport: &http.Transport{ - TLSClientConfig: tlsConfig, + TLSClientConfig: tlsConfigForFingerprint(cnf.SourceFingerprint), }, }, Log: func(level gohlslib.LogLevel, format string, args ...interface{}) { diff --git a/internal/core/rtmp_source.go b/internal/core/rtmp_source.go index 2a3dbc03..d6a9bf12 100644 --- a/internal/core/rtmp_source.go +++ b/internal/core/rtmp_source.go @@ -2,13 +2,10 @@ package core import ( "context" - "crypto/sha256" "crypto/tls" - "encoding/hex" "fmt" "net" "net/url" - "strings" "time" "github.com/bluenviron/gortsplib/v3/pkg/formats" @@ -71,24 +68,9 @@ func (s *rtmpSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf cha return (&net.Dialer{}).DialContext(ctx2, "tcp", u.Host) } - tlsConfig := &tls.Config{ - InsecureSkipVerify: true, - VerifyConnection: func(cs tls.ConnectionState) error { - h := sha256.New() - h.Write(cs.PeerCertificates[0].Raw) - hstr := hex.EncodeToString(h.Sum(nil)) - fingerprintLower := strings.ToLower(cnf.SourceFingerprint) - - if hstr != fingerprintLower { - return fmt.Errorf("server fingerprint do not match: expected %s, got %s", - fingerprintLower, hstr) - } - - return nil - }, - } - - return (&tls.Dialer{Config: tlsConfig}).DialContext(ctx2, "tcp", u.Host) + return (&tls.Dialer{ + Config: tlsConfigForFingerprint(cnf.SourceFingerprint), + }).DialContext(ctx2, "tcp", u.Host) }() if err != nil { return err diff --git a/internal/core/tls_fingerprint.go b/internal/core/tls_fingerprint.go new file mode 100644 index 00000000..ff2f70d7 --- /dev/null +++ b/internal/core/tls_fingerprint.go @@ -0,0 +1,39 @@ +package core + +import ( + "crypto/sha256" + "crypto/tls" + "encoding/hex" + "fmt" + "strings" +) + +type fingerprintValidatorFunc func(tls.ConnectionState) error + +func fingerprintValidator(fingerprint string) fingerprintValidatorFunc { + fingerprintLower := strings.ToLower(fingerprint) + + return func(cs tls.ConnectionState) error { + h := sha256.New() + h.Write(cs.PeerCertificates[0].Raw) + hstr := hex.EncodeToString(h.Sum(nil)) + + if hstr != fingerprintLower { + return fmt.Errorf("source fingerprint does not match: expected %s, got %s", + fingerprintLower, hstr) + } + + return nil + } +} + +func tlsConfigForFingerprint(fingerprint string) *tls.Config { + if fingerprint == "" { + return nil + } + + return &tls.Config{ + InsecureSkipVerify: true, + VerifyConnection: fingerprintValidator(fingerprint), + } +}