Repository: scionproto/scion
Pull request #4460 (2023-12-27 11:26:55)

control: pluggable segment signer
Make the segment signer pluggable. This decouples the beacon extender from the trust signer implementation and allows plugging in different implementations.

<!-- Reviewable:start -->
- - -
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/scionproto/scion/4460)
<!-- Reviewable:end -->



Patch:
diff --git a/control/beaconing/BUILD.bazel b/control/beaconing/BUILD.bazel
index 9d3233939..ff9009613 100644
--- a/control/beaconing/BUILD.bazel
+++ b/control/beaconing/BUILD.bazel
@@ -25,6 +25,7 @@ go_library(
         "//pkg/private/prom:go_default_library",
         "//pkg/private/serrors:go_default_library",
         "//pkg/private/util:go_default_library",
+        "//pkg/proto/crypto:go_default_library",
         "//pkg/segment:go_default_library",
         "//pkg/segment/extensions/digest:go_default_library",
         "//pkg/segment/extensions/epic:go_default_library",
@@ -37,7 +38,6 @@ go_library(
         "//private/segment/verifier:go_default_library",
         "//private/topology:go_default_library",
         "//private/tracing:go_default_library",
-        "//private/trust:go_default_library",
         "@com_github_opentracing_opentracing_go//:go_default_library",
     ],
 )
diff --git a/control/beaconing/extender.go b/control/beaconing/extender.go
index cf440eaa1..5475ad63b 100644
--- a/control/beaconing/extender.go
+++ b/control/beaconing/extender.go
@@ -26,17 +26,28 @@ import (
 	"github.com/scionproto/scion/pkg/metrics"
 	"github.com/scionproto/scion/pkg/private/serrors"
 	"github.com/scionproto/scion/pkg/private/util"
+	cryptopb "github.com/scionproto/scion/pkg/proto/crypto"
 	seg "github.com/scionproto/scion/pkg/segment"
 	"github.com/scionproto/scion/pkg/segment/extensions/digest"
 	"github.com/scionproto/scion/pkg/segment/extensions/epic"
 	"github.com/scionproto/scion/pkg/slayers/path"
-	"github.com/scionproto/scion/private/trust"
 )
 
 // SignerGen generates signers and returns their expiration time.
 type SignerGen interface {
 	// Generate generates a signer it.
-	Generate(ctx context.Context) (trust.Signer, error)
+	Generate(ctx context.Context) (Signer, error)
+}
+
+type Signer interface {
+	Sign(context.Context, []byte, ...[]byte) (*cryptopb.SignedMessage, error)
+	GetExpiration() time.Time
+}
+
+type SignerGenFunc func(ctx context.Context) (Signer, error)
+
+func (f SignerGenFunc) Generate(ctx context.Context) (Signer, error) {
+	return f(ctx)
 }
 
 // Extender extends path segments.
@@ -104,14 +115,14 @@ func (s *DefaultExtender) Extend(
 	}
 	// Make sure the hop expiration time is not longer than the signer expiration time.
 	expTime := s.MaxExpTime()
-	if ts.Add(path.ExpTimeToDuration(expTime)).After(signer.Expiration) {
+	if ts.Add(path.ExpTimeToDuration(expTime)).After(signer.GetExpiration()) {
 		metrics.GaugeSet(s.SegmentExpirationDeficient, 1)
 		var err error
-		expTime, err = path.ExpTimeFromDuration(signer.Expiration.Sub(ts))
+		expTime, err = path.ExpTimeFromDuration(signer.GetExpiration().Sub(ts))
 		if err != nil {
 			return serrors.WrapStr(
 				"calculating expiry time from signer expiration time", err,
-				"signer_expiration", signer.Expiration,
+				"signer_expiration", signer.GetExpiration(),
 			)
 		}
 	} else {
diff --git a/control/cmd/control/main.go b/control/cmd/control/main.go
index c5e4c70a5..d5cd9a359 100644
--- a/control/cmd/control/main.go
+++ b/control/cmd/control/main.go
@@ -780,13 +780,15 @@ func realMain(ctx context.Context) error {
 		},
 		SegmentRegister: beaconinggrpc.Registrar{Dialer: dialer},
 		BeaconStore:     beaconStore,
-		SignerGen:       signer.SignerGen,
-		Inspector:       inspector,
-		Metrics:         metrics,
-		DRKeyEngine:     drkeyEngine,
-		MACGen:          macGen,
-		NextHopper:      topo,
-		StaticInfo:      func() *beaconing.StaticInfoCfg { return staticInfo },
+		SignerGen: beaconing.SignerGenFunc(func(ctx context.Context) (beaconing.Signer, error) {
+			return signer.SignerGen.Generate(ctx)
+		}),
+		Inspector:   inspector,
+		Metrics:     metrics,
+		DRKeyEngine: drkeyEngine,
+		MACGen:      macGen,
+		NextHopper:  topo,
+		StaticInfo:  func() *beaconing.StaticInfoCfg { return staticInfo },
 
 		OriginationInterval:       globalCfg.BS.OriginationInterval.Duration,
 		PropagationInterval:       globalCfg.BS.PropagationInterval.Duration,
diff --git a/private/trust/signer.go b/private/trust/signer.go
index 4551bdb03..8e1694095 100644
--- a/private/trust/signer.go
+++ b/private/trust/signer.go
@@ -135,6 +135,10 @@ func (s Signer) validate(ctx context.Context, now time.Time) error {
 	return nil
 }
 
+func (s Signer) GetExpiration() time.Time {
+	return s.Expiration
+}
+
 func (s Signer) Equal(o Signer) bool {
 	return s.IA.Equal(o.IA) &&
 		bytes.Equal(s.SubjectKeyID, o.SubjectKeyID) &&


Test patch:
diff --git a/control/beaconing/writer_test.go b/control/beaconing/writer_test.go
index e253f6b2d..5f3ac9d6a 100644
--- a/control/beaconing/writer_test.go
+++ b/control/beaconing/writer_test.go
@@ -349,7 +349,7 @@ type testSignerGen struct {
 	Signer trust.Signer
 }
 
-func (s testSignerGen) Generate(ctx context.Context) (trust.Signer, error) {
+func (s testSignerGen) Generate(ctx context.Context) (beaconing.Signer, error) {
 	return s.Signer, nil
 }
 
diff --git a/pkg/experimental/hiddenpath/beaconwriter_test.go b/pkg/experimental/hiddenpath/beaconwriter_test.go
index b9b0cabcc..3031a3579 100644
--- a/pkg/experimental/hiddenpath/beaconwriter_test.go
+++ b/pkg/experimental/hiddenpath/beaconwriter_test.go
@@ -356,7 +356,7 @@ type testSignerGen struct {
 	Signer trust.Signer
 }
 
-func (s testSignerGen) Generate(ctx context.Context) (trust.Signer, error) {
+func (s testSignerGen) Generate(ctx context.Context) (beaconing.Signer, error) {
 	return s.Signer, nil
 }