Pin QUIC fabric endpoint certificates
This commit is contained in:
@@ -2,7 +2,10 @@ package mesh
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -34,6 +37,34 @@ func NewQUICFabricTransport(config *quic.Config) *QUICFabricTransport {
|
||||
return &QUICFabricTransport{Config: config}
|
||||
}
|
||||
|
||||
func quicTLSConfigForTarget(target FabricTransportTarget) *tls.Config {
|
||||
expectedFingerprint := normalizeCertSHA256(target.PeerCertSHA256)
|
||||
config := &tls.Config{NextProtos: []string{fabricQUICNextProto}}
|
||||
if expectedFingerprint == "" {
|
||||
return config
|
||||
}
|
||||
config.InsecureSkipVerify = true
|
||||
config.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
|
||||
if len(rawCerts) == 0 {
|
||||
return fmt.Errorf("quic peer certificate missing")
|
||||
}
|
||||
sum := sha256.Sum256(rawCerts[0])
|
||||
actual := hex.EncodeToString(sum[:])
|
||||
if actual != expectedFingerprint {
|
||||
return fmt.Errorf("quic peer certificate fingerprint mismatch")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
func normalizeCertSHA256(value string) string {
|
||||
value = strings.ToLower(strings.TrimSpace(value))
|
||||
value = strings.ReplaceAll(value, "sha256:", "")
|
||||
value = strings.ReplaceAll(value, ":", "")
|
||||
return value
|
||||
}
|
||||
|
||||
func (t *QUICFabricTransport) Connect(ctx context.Context, target FabricTransportTarget) (FabricTransportSession, error) {
|
||||
if target.Endpoint == "" {
|
||||
return nil, fmt.Errorf("quic fabric endpoint is required")
|
||||
@@ -41,7 +72,7 @@ func (t *QUICFabricTransport) Connect(ctx context.Context, target FabricTranspor
|
||||
target.Endpoint = strings.TrimPrefix(strings.TrimSpace(target.Endpoint), "quic://")
|
||||
tlsConfig := target.TLSConfig
|
||||
if tlsConfig == nil {
|
||||
tlsConfig = &tls.Config{NextProtos: []string{fabricQUICNextProto}}
|
||||
tlsConfig = quicTLSConfigForTarget(target)
|
||||
} else {
|
||||
tlsConfig = tlsConfig.Clone()
|
||||
if len(tlsConfig.NextProtos) == 0 {
|
||||
|
||||
Reference in New Issue
Block a user