Files
mesh-sdk/go/process/conn_integration_test.go
T

95 lines
3.3 KiB
Go

//go:build integration
package process
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/hex"
"math/big"
"testing"
"time"
"github.com/nats-io/nats-server/v2/server"
)
// selfSignedServer is a nats-server with JetStream and TLS, self-signed, for this test alone (mirroring
// go/internal/testbus.Start, with a certificate added since testbus has none): a mesh's bus presents its own
// certificate in no public trust store, which is exactly what a process pins to (ADR 0436 clause 4).
func selfSignedServer(t *testing.T) (url, fingerprint string) {
t.Helper()
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
}
tmpl := &x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{CommonName: "mesh-sdk-test-bus"},
NotBefore: time.Now().Add(-time.Hour),
NotAfter: time.Now().Add(time.Hour),
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
}
der, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &key.PublicKey, key)
if err != nil {
t.Fatal(err)
}
sum := sha256.Sum256(der)
fingerprint = "sha256:" + hex.EncodeToString(sum[:])
cert := tls.Certificate{Certificate: [][]byte{der}, PrivateKey: key}
opts := &server.Options{Host: "127.0.0.1", Port: server.RANDOM_PORT, JetStream: true, StoreDir: t.TempDir(),
NoLog: true, NoSigs: true, TLSConfig: &tls.Config{Certificates: []tls.Certificate{cert}},
Username: "novox.mesh-mail.send", Password: "the-pw"}
s, err := server.NewServer(opts)
if err != nil {
t.Fatalf("a TLS bus for this test could not be made: %v", err)
}
go s.Start()
if !s.ReadyForConnections(10 * time.Second) {
s.Shutdown()
t.Fatal("a TLS bus for this test did not come up within 10s")
}
t.Cleanup(func() {
s.Shutdown()
s.WaitForShutdown()
})
return s.ClientURL(), fingerprint
}
func mailSenderAccount(url, fingerprint string) Account {
return Account{URL: url, Fingerprint: fingerprint, Node: "novox", Module: "mesh-mail",
User: "novox.mesh-mail.send", Password: "the-pw"}
}
// 1171/AC3: given a test bus with TLS and the account composed for novox.mesh-mail.send, when the package
// connects with the file, then it connects with the inbox prefix _INBOX.novox.mesh-mail.send.
func TestConnectPinsTheFingerprintAndSetsTheInboxPrefix(t *testing.T) {
url, fingerprint := selfSignedServer(t)
account := mailSenderAccount(url, fingerprint)
conn, err := Connect(account)
if err != nil {
t.Fatalf("connecting with the right fingerprint was refused: %v", err)
}
defer conn.Close()
if !conn.nc.IsConnected() {
t.Fatal("the connection did not come up")
}
if got := conn.nc.Opts.InboxPrefix; got != "_INBOX.novox.mesh-mail.send" {
t.Errorf("inbox prefix: %q, want %q", got, "_INBOX.novox.mesh-mail.send")
}
}
// 1171/AC3: connecting with a fingerprint that is not the bus's own leaf certificate is refused.
func TestConnectRefusesTheWrongFingerprint(t *testing.T) {
url, _ := selfSignedServer(t)
account := mailSenderAccount(url, "sha256:0000000000000000000000000000000000000000000000000000000000000000")
if _, err := Connect(account); err == nil {
t.Fatal("connecting with the wrong fingerprint was not refused")
}
}