From 04e27518af7c51f00f3dcd61ce5eba63e864599b Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Sun, 7 Jun 2026 12:49:19 +0200 Subject: [PATCH] test(client): secure bus end-to-end (auth + TLS + E2E together) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TestSecureBusEndToEnd boots the server with control-plane enforce, NATS nkey auth, and TLS all on; two registered peers connect with nkey+TLS, A creates a Matrix room, invites B, publishes, and B decrypts — proving the three layers compose. This is the headline golden of issue 0001. Co-Authored-By: Claude Opus 4.8 (1M context) --- pkg/client/tls_test.go | 72 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/pkg/client/tls_test.go b/pkg/client/tls_test.go index 236168a..8fc1d5e 100644 --- a/pkg/client/tls_test.go +++ b/pkg/client/tls_test.go @@ -7,13 +7,16 @@ import ( "crypto/tls" "crypto/x509" "crypto/x509/pkix" + "encoding/hex" "encoding/pem" "math/big" "net" + "sync" "testing" "time" "github.com/enmanuel/unibus/pkg/client" + "github.com/enmanuel/unibus/pkg/frame" "github.com/enmanuel/unibus/pkg/membership" "github.com/enmanuel/unibus/pkg/room" ) @@ -111,3 +114,72 @@ func TestNatsTLS(t *testing.T) { t.Fatalf("client without the CA must fail the TLS handshake") } } + +// TestSecureBusEndToEnd is the headline golden of issue 0001: with ALL three +// layers active at once — control-plane request signing (enforce), NATS nkey +// auth, and TLS — two registered peers run an encrypted room end to end. A +// creates a Matrix-policy room, invites B, A publishes and B decrypts. This +// proves the layers compose: signed HTTP control plane + authenticated, +// encrypted data plane + E2E room content. +func TestSecureBusEndToEnd(t *testing.T) { + serverTLS, caPool := genTestCA(t) + h := bootHarness(t, membership.AuthEnforce, true, serverTLS) + waitHealth(t, h.ctrlURL) + + clientTLS := &tls.Config{RootCAs: caPool, MinVersion: tls.VersionTLS12} + secure := func(t *testing.T, handle string) (*client.Client, membership.AuthMode) { + id := mustIdentity(t) + if err := h.store.AddUser(hex.EncodeToString(id.SignPub), handle, membership.RoleMember); err != nil { + t.Fatalf("register %s: %v", handle, err) + } + c, err := client.NewWithOptions(h.natsURL, h.ctrlURL, id, client.Options{UseNkey: true, TLS: clientTLS}) + if err != nil { + t.Fatalf("connect %s securely: %v", handle, err) + } + return c, 0 + } + + a, _ := secure(t, "alice") + defer a.Close() + b, _ := secure(t, "bob") + defer b.Close() + + roomID, err := a.CreateRoom("room.secure", room.ModeMatrix) + if err != nil { + t.Fatalf("A create encrypted room over secure bus: %v", err) + } + if err := a.Invite(roomID, b.Endpoint()); err != nil { + t.Fatalf("A invite B: %v", err) + } + if err := b.Join(roomID); err != nil { + t.Fatalf("B join: %v", err) + } + + var mu sync.Mutex + var got []string + sub, err := b.Subscribe(roomID, func(_ frame.Frame, plaintext []byte) { + mu.Lock() + got = append(got, string(plaintext)) + mu.Unlock() + }) + if err != nil { + t.Fatalf("B subscribe: %v", err) + } + defer sub.Unsubscribe() + time.Sleep(150 * time.Millisecond) + + const msg = "mensaje sobre bus seguro (auth+TLS+E2E)" + if err := a.Publish(roomID, []byte(msg)); err != nil { + t.Fatalf("A publish: %v", err) + } + if !waitFor(&mu, &got, func(rs []string) bool { + for _, r := range rs { + if r == msg { + return true + } + } + return false + }, 2*time.Second) { + t.Fatalf("B did not receive/decrypt the message over the secured bus; got %v", snapshot(&mu, &got)) + } +}