tests: add signature verification tests for narinfo, mesh, and config
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I06ef2f37f174d278ce4f727836f339dd6a6a6964
This commit is contained in:
parent
f4804d2150
commit
de100ee611
3 changed files with 246 additions and 10 deletions
|
|
@ -9,6 +9,17 @@ import (
|
|||
"notashelf.dev/ncro/internal/mesh"
|
||||
)
|
||||
|
||||
func freeUDPAddr(t *testing.T) string {
|
||||
t.Helper()
|
||||
conn, err := net.ListenPacket("udp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
addr := conn.LocalAddr().String()
|
||||
conn.Close()
|
||||
return addr
|
||||
}
|
||||
|
||||
func TestAnnounceAndReceive(t *testing.T) {
|
||||
store := mesh.NewRouteStore()
|
||||
node, err := mesh.NewNode("", store)
|
||||
|
|
@ -16,15 +27,9 @@ func TestAnnounceAndReceive(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Bind to an ephemeral port.
|
||||
conn, err := net.ListenPacket("udp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
addr := conn.LocalAddr().String()
|
||||
conn.Close()
|
||||
|
||||
if err := mesh.ListenAndServe(addr, store); err != nil {
|
||||
addr := freeUDPAddr(t)
|
||||
// Allow messages from our own node (its public key is the only allowed key).
|
||||
if err := mesh.ListenAndServe(addr, store, node.PublicKey()); err != nil {
|
||||
t.Fatalf("ListenAndServe: %v", err)
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +46,6 @@ func TestAnnounceAndReceive(t *testing.T) {
|
|||
t.Fatalf("Announce: %v", err)
|
||||
}
|
||||
|
||||
// Give the listener goroutine time to process the packet.
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
entry := store.Get("test-pkg-abc")
|
||||
|
|
@ -52,3 +56,62 @@ func TestAnnounceAndReceive(t *testing.T) {
|
|||
t.Errorf("UpstreamURL = %q", entry.UpstreamURL)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRejectUnknownSender(t *testing.T) {
|
||||
store := mesh.NewRouteStore()
|
||||
|
||||
// Listener node — will reject messages not from trusted
|
||||
trusted, err := mesh.NewNode("", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Untrusted sender
|
||||
untrusted, err := mesh.NewNode("", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
addr := freeUDPAddr(t)
|
||||
// Only allow trusted node's key.
|
||||
if err := mesh.ListenAndServe(addr, store, trusted.PublicKey()); err != nil {
|
||||
t.Fatalf("ListenAndServe: %v", err)
|
||||
}
|
||||
|
||||
routes := []cache.RouteEntry{
|
||||
{StorePath: "untrusted-pkg", UpstreamURL: "https://evil.example.com",
|
||||
TTL: time.Now().Add(time.Hour)},
|
||||
}
|
||||
mesh.Announce(addr, untrusted, routes)
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
if entry := store.Get("untrusted-pkg"); entry != nil {
|
||||
t.Error("route from untrusted sender should have been rejected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRejectTamperedMessage(t *testing.T) {
|
||||
// This is covered by TestVerifyFailsOnTamper in mesh_test.go at the crypto level.
|
||||
// Here we verify the full pipeline rejects a re-signed-but-tampered body.
|
||||
store := mesh.NewRouteStore()
|
||||
node, err := mesh.NewNode("", store)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
addr := freeUDPAddr(t)
|
||||
if err := mesh.ListenAndServe(addr, store, node.PublicKey()); err != nil {
|
||||
t.Fatalf("ListenAndServe: %v", err)
|
||||
}
|
||||
|
||||
// Send a valid message first to confirm it works.
|
||||
routes := []cache.RouteEntry{
|
||||
{StorePath: "legit-pkg", UpstreamURL: "https://cache.nixos.org",
|
||||
TTL: time.Now().Add(time.Hour)},
|
||||
}
|
||||
mesh.Announce(addr, node, routes)
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
if store.Get("legit-pkg") == nil {
|
||||
t.Fatal("valid message should have been accepted")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue