package link import ( "context" "crypto/ed25519" "encoding/json" "testing" ) // verified runs what Run does to a delivery body, without a broker: unmarshal, check the // signature, and only then apply. Isolating it keeps this test about the check rather than about // AMQP, which is tested against a real broker in the lab. func verified(t *testing.T, signer ed25519.PublicKey, body []byte) (Report, bool) { t.Helper() applied := false report := handleBody(context.Background(), Membership{Node: "anchor", Signer: signer}, body, func(context.Context, []byte, []byte) Report { applied = true return Report{Applied: []string{"something"}} }) return report, applied } func signedBody(t *testing.T, private ed25519.PrivateKey, declaration string) []byte { t.Helper() raw, err := json.Marshal(Signed{ Declaration: []byte(declaration), Signature: ed25519.Sign(private, []byte(declaration)), }) if err != nil { t.Fatal(err) } return raw } func TestTheMeshsOwnDeclarationIsApplied(t *testing.T) { public, private, err := ed25519.GenerateKey(nil) if err != nil { t.Fatal(err) } report, applied := verified(t, public, signedBody(t, private, `{"declaration":1}`)) if !applied { t.Fatalf("a declaration the mesh signed was not applied: %s", report.Refused) } } // Defends novox/hq ADR 0002: everything reaching a node arrives over the broker — and therefore // ADR 0004's consequence, that the broker is not trusted to say who is speaking. // // A transport nobody authenticates per-message would let whatever holds the connection attribute // a declaration to any node it liked. func TestAForgedDeclarationIsNeverApplied(t *testing.T) { // The check that stands between "the mesh changes this machine" and "anybody does". The host // applies whatever the link delivers, so a forged declaration is the whole machine. public, _, err := ed25519.GenerateKey(nil) if err != nil { t.Fatal(err) } _, other, err := ed25519.GenerateKey(nil) if err != nil { t.Fatal(err) } report, applied := verified(t, public, signedBody(t, other, `{"declaration":1}`)) if applied { t.Fatal("a declaration signed by another key was applied") } if report.Refused != ErrForged.Error() { t.Errorf("refused, but not as a forgery: %q", report.Refused) } } func TestATamperedDeclarationIsNeverApplied(t *testing.T) { // A broker that changed the declaration in flight, keeping the signature. This is what makes // pinning the transport insufficient on its own. public, private, err := ed25519.GenerateKey(nil) if err != nil { t.Fatal(err) } raw, err := json.Marshal(Signed{ Declaration: []byte(`{"declaration":1,"resources":["something else entirely"]}`), Signature: ed25519.Sign(private, []byte(`{"declaration":1}`)), }) if err != nil { t.Fatal(err) } report, applied := verified(t, public, raw) if applied { t.Fatal("a declaration altered after signing was applied") } if report.Refused != ErrForged.Error() { t.Errorf("refused, but not as a forgery: %q", report.Refused) } } func TestAMalformedMessageIsToldApartFromAForgery(t *testing.T) { // novox/hq ADR 0004 requires these to be distinguishable: one means somebody is trying, the // other means something is broken, and they need different responses from a person. public, _, err := ed25519.GenerateKey(nil) if err != nil { t.Fatal(err) } report, applied := verified(t, public, []byte("this is not a message")) if applied { t.Fatal("something unparseable was applied") } if report.Refused == ErrForged.Error() { t.Error("a malformed message was reported as a forgery; those must be distinguishable") } } func TestTheWireFormatIsExactlyTheseFieldNames(t *testing.T) { // The contract with the control plane, which defines these separately. A matching test lives // there; rename a field on either side and both fail. for _, c := range []struct { value any expect []string }{ {Signed{Declaration: []byte("{}"), Signature: []byte("x")}, []string{"declaration", "signature"}}, {Report{Node: "n", Applied: []string{"a"}, Failed: map[string]string{"k": "v"}, Refused: "r"}, []string{"node", "applied", "failed", "refused"}}, // novox/hq ADR 0100: what an adopted node holds, the firewall it was found with, and what // is reachable on it. {Report{Node: "n", Held: []Held{{ID: "i"}}, Firewall: "ufw", Reachable: []Reach{{Port: 1}}}, []string{"node", "held", "firewall", "reachable"}}, {Held{ID: "i", Module: "m", Kind: "file", Target: "/t", Changed: "rewritten", Kept: "/k"}, []string{"id", "module", "kind", "target", "since", "changed", "kept"}}, {Reach{Protocol: "tcp", Address: "0.0.0.0", Port: 8080, By: "c", Published: true, ContainerPort: 80}, []string{"protocol", "address", "port", "by", "published", "container-port"}}, } { raw, err := json.Marshal(c.value) if err != nil { t.Fatal(err) } var fields map[string]any if err := json.Unmarshal(raw, &fields); err != nil { t.Fatal(err) } for _, want := range c.expect { if _, ok := fields[want]; !ok { t.Errorf("%T has no %q field; the control plane uses that name", c.value, want) } } if len(fields) != len(c.expect) { t.Errorf("%T has %d fields, expected %d: %v", c.value, len(fields), len(c.expect), fields) } } }