Pin QUIC fabric endpoint certificates

This commit is contained in:
2026-05-16 10:51:06 +03:00
parent 3386a5e9b2
commit 4ebc6629e6
6 changed files with 157 additions and 18 deletions
@@ -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 {