mirror of
https://github.com/luxfi/mpc.git
synced 2026-09-24 00:26:24 +00:00
Security (from red team review): - Replay protection: request_id + timestamp freshness on sign API - Ed25519 message auth re-enabled on all protocol messages - DKG timeout (5min) + signing timeout (30s) with watchdog - Dedup map TTL cleanup (10min expiry, 2min sweep) BLS threshold signing: - KeyTypeBLS + keygen/signing sessions - TrustedDealer pattern for BLS DKG - CBOR serialization for BLS config - 8 tests ZapDB KMS-backing: - HSM PasswordProvider wired to ZapDB init - Supports: AWS KMS, GCP KMS, Azure KV, env, file - Default env for backward compat - 19 tests Also: sr25519 sessions, fixed SignWireMessage build break
81 lines
1.7 KiB
Go
81 lines
1.7 KiB
Go
package api
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestReplayGuard_RejectsMissingRequestID(t *testing.T) {
|
|
rg := newReplayGuard()
|
|
defer rg.stop()
|
|
|
|
reason := rg.check("", 0)
|
|
if reason == "" {
|
|
t.Fatal("expected rejection for empty request_id")
|
|
}
|
|
}
|
|
|
|
func TestReplayGuard_AcceptsFirstRequest(t *testing.T) {
|
|
rg := newReplayGuard()
|
|
defer rg.stop()
|
|
|
|
reason := rg.check("req-1", time.Now().Unix())
|
|
if reason != "" {
|
|
t.Fatalf("expected acceptance, got: %s", reason)
|
|
}
|
|
}
|
|
|
|
func TestReplayGuard_RejectsDuplicate(t *testing.T) {
|
|
rg := newReplayGuard()
|
|
defer rg.stop()
|
|
|
|
ts := time.Now().Unix()
|
|
reason := rg.check("req-dup", ts)
|
|
if reason != "" {
|
|
t.Fatalf("first request should succeed, got: %s", reason)
|
|
}
|
|
|
|
reason = rg.check("req-dup", ts)
|
|
if reason == "" {
|
|
t.Fatal("expected rejection for duplicate request_id")
|
|
}
|
|
if reason != "duplicate request_id" {
|
|
t.Fatalf("unexpected reason: %s", reason)
|
|
}
|
|
}
|
|
|
|
func TestReplayGuard_RejectsStaleTimestamp(t *testing.T) {
|
|
rg := newReplayGuard()
|
|
defer rg.stop()
|
|
|
|
staleTS := time.Now().Add(-2 * time.Minute).Unix()
|
|
reason := rg.check("req-stale", staleTS)
|
|
if reason == "" {
|
|
t.Fatal("expected rejection for stale timestamp")
|
|
}
|
|
}
|
|
|
|
func TestReplayGuard_AcceptsZeroTimestamp(t *testing.T) {
|
|
rg := newReplayGuard()
|
|
defer rg.stop()
|
|
|
|
// timestamp=0 skips age check (used by bridge endpoints)
|
|
reason := rg.check("req-no-ts", 0)
|
|
if reason != "" {
|
|
t.Fatalf("expected acceptance with zero timestamp, got: %s", reason)
|
|
}
|
|
}
|
|
|
|
func TestReplayGuard_DifferentIDsAccepted(t *testing.T) {
|
|
rg := newReplayGuard()
|
|
defer rg.stop()
|
|
|
|
ts := time.Now().Unix()
|
|
for i := 0; i < 100; i++ {
|
|
reason := rg.check("req-"+string(rune('A'+i)), ts)
|
|
if reason != "" {
|
|
t.Fatalf("request %d should succeed, got: %s", i, reason)
|
|
}
|
|
}
|
|
}
|