mirror of
https://github.com/garethgeorge/backrest.git
synced 2026-05-04 20:10:36 +00:00
147 lines
4.2 KiB
Go
147 lines
4.2 KiB
Go
package syncapi
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"testing"
|
|
|
|
v1 "github.com/garethgeorge/backrest/gen/go/v1"
|
|
"github.com/garethgeorge/backrest/internal/cryptoutil"
|
|
)
|
|
|
|
func newTestIdentity(t *testing.T) *cryptoutil.PrivateKey {
|
|
t.Helper()
|
|
proto, err := cryptoutil.GeneratePrivateKey()
|
|
if err != nil {
|
|
t.Fatalf("generate identity: %v", err)
|
|
}
|
|
priv, err := cryptoutil.NewPrivateKey(proto)
|
|
if err != nil {
|
|
t.Fatalf("load identity: %v", err)
|
|
}
|
|
return priv
|
|
}
|
|
|
|
func freshTranscript(t *testing.T) []byte {
|
|
t.Helper()
|
|
buf := make([]byte, 32)
|
|
if _, err := rand.Read(buf); err != nil {
|
|
t.Fatalf("rand: %v", err)
|
|
}
|
|
return buf
|
|
}
|
|
|
|
func TestHandshake_RoundTrip(t *testing.T) {
|
|
identity := newTestIdentity(t)
|
|
transcript := freshTranscript(t)
|
|
|
|
packet, err := createHandshakePacket("alice", identity, "", transcript)
|
|
if err != nil {
|
|
t.Fatalf("createHandshakePacket: %v", err)
|
|
}
|
|
peerKey, err := verifyHandshakePacket(packet, transcript)
|
|
if err != nil {
|
|
t.Fatalf("verifyHandshakePacket: %v", err)
|
|
}
|
|
if peerKey.KeyID() != identity.KeyID() {
|
|
t.Fatalf("verified key ID mismatch: %s vs %s", peerKey.KeyID(), identity.KeyID())
|
|
}
|
|
}
|
|
|
|
func TestHandshake_TranscriptMismatchFails(t *testing.T) {
|
|
identity := newTestIdentity(t)
|
|
transcriptA := freshTranscript(t)
|
|
transcriptB := freshTranscript(t)
|
|
|
|
packet, err := createHandshakePacket("alice", identity, "", transcriptA)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := verifyHandshakePacket(packet, transcriptB); err == nil {
|
|
t.Fatal("expected handshake to reject mismatched transcript (MITM scenario)")
|
|
}
|
|
}
|
|
|
|
func TestHandshake_TamperedSignatureFails(t *testing.T) {
|
|
identity := newTestIdentity(t)
|
|
transcript := freshTranscript(t)
|
|
|
|
packet, err := createHandshakePacket("alice", identity, "", transcript)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
packet.GetHandshake().Signature[0] ^= 0xff
|
|
if _, err := verifyHandshakePacket(packet, transcript); err == nil {
|
|
t.Fatal("expected tampered signature to fail verification")
|
|
}
|
|
}
|
|
|
|
func TestHandshake_TamperedInstanceIdFails(t *testing.T) {
|
|
identity := newTestIdentity(t)
|
|
transcript := freshTranscript(t)
|
|
|
|
packet, err := createHandshakePacket("alice", identity, "", transcript)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
packet.GetHandshake().InstanceId = "mallory"
|
|
if _, err := verifyHandshakePacket(packet, transcript); err == nil {
|
|
t.Fatal("expected tampered instance ID to fail verification")
|
|
}
|
|
}
|
|
|
|
func TestHandshake_TamperedPairingSecretFails(t *testing.T) {
|
|
identity := newTestIdentity(t)
|
|
transcript := freshTranscript(t)
|
|
|
|
packet, err := createHandshakePacket("alice", identity, "secret-1", transcript)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
packet.GetHandshake().PairingSecret = "secret-2"
|
|
if _, err := verifyHandshakePacket(packet, transcript); err == nil {
|
|
t.Fatal("expected tampered pairing secret to fail verification")
|
|
}
|
|
}
|
|
|
|
func TestHandshake_WrongKeyFails(t *testing.T) {
|
|
signer := newTestIdentity(t)
|
|
imposter := newTestIdentity(t)
|
|
transcript := freshTranscript(t)
|
|
|
|
packet, err := createHandshakePacket("alice", signer, "", transcript)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Substitute the imposter's public key (and matching keyid) — the
|
|
// signature was made under the real signer's key, so verification must
|
|
// fail.
|
|
packet.GetHandshake().PublicKey = imposter.PublicKey.PublicKeyProto()
|
|
if _, err := verifyHandshakePacket(packet, transcript); err == nil {
|
|
t.Fatal("expected wrong public key to fail verification")
|
|
}
|
|
}
|
|
|
|
func TestHandshake_AuthorizationByKeyID(t *testing.T) {
|
|
identity := newTestIdentity(t)
|
|
transcript := freshTranscript(t)
|
|
packet, err := createHandshakePacket("alice", identity, "", transcript)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
peer := &v1.Multihost_Peer{
|
|
InstanceId: "alice",
|
|
Keyid: identity.KeyID(),
|
|
}
|
|
if err := authorizeHandshakeAsPeer(packet, peer); err != nil {
|
|
t.Fatalf("authorize matching peer: %v", err)
|
|
}
|
|
mismatchedInstance := &v1.Multihost_Peer{InstanceId: "bob", Keyid: identity.KeyID()}
|
|
if err := authorizeHandshakeAsPeer(packet, mismatchedInstance); err == nil {
|
|
t.Fatal("expected instance-ID mismatch to fail authorization")
|
|
}
|
|
mismatchedKey := &v1.Multihost_Peer{InstanceId: "alice", Keyid: "ed25519.bogus"}
|
|
if err := authorizeHandshakeAsPeer(packet, mismatchedKey); err == nil {
|
|
t.Fatal("expected key-ID mismatch to fail authorization")
|
|
}
|
|
}
|