Files
mpc/pkg/integrity/verify_test.go
T
zeekay 4e915d77c3 security: fix 15 custody audit findings, add regression + fuzz tests
Fixes all findings from the Blue Team defensive security review of the
redacted → redacted custody architecture transition.

HIGH:
- S-1: Implement P-256 ECDH + AES-256-GCM encryption of passkey backup shards
- W-2: Reject unparseable WebAuthn public keys (was silently skipping verification)
- O-1: Add Ed25519 binary signature verification package (pkg/integrity)

MEDIUM:
- W-1: Validate attestation is a real P-256 curve point, not raw attestation object
- W-3: Add origin validation to all WebAuthn flows (register, verify, trade approve)
- N-2: Remove plaintext TCP fallback from MPC node transport (TLS mandatory)
- K-1: Fail-closed on empty/whitespace orgID (prevents cross-tenant key leakage)
- A-1: Make AuditEntry immutable (Update/Delete return error)
- A-2: Add MPC-level signing audit log (wallet, message hash, intent, trigger)
- O-3: Invalidate backup shards after key reshare (stale shares are useless)
- O-2: Reject env/file password providers in production (require cloud HSM)

LOW:
- T-1: Add error handling + MarkSignFailed to signing goroutine
- T-2: Verify caller authorization in handleTradeSubmit
- K-2: Secret erasure stub now calls runtime.GC() instead of no-op
- N-1: Add VerifyConnection callback to reject peers without TLS certs

Tests: 69 unit + 7 fuzz targets, ~900K fuzz executions, 19/19 packages green.
Makefile: add -tags json1 for SQLite JSON function support in ORM tests.
2025-12-28 01:00:12 -08:00

105 lines
2.5 KiB
Go

package integrity
import (
"crypto/ed25519"
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"os"
"path/filepath"
"testing"
)
func TestVerifyFile_ValidSignature(t *testing.T) {
pub, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
dir := t.TempDir()
binPath := filepath.Join(dir, "mpcd")
content := []byte("binary-content-here")
if err := os.WriteFile(binPath, content, 0644); err != nil {
t.Fatal(err)
}
if err := SignFile(binPath, priv); err != nil {
t.Fatal(err)
}
if err := SetTrustedKeys([]string{hex.EncodeToString(pub)}); err != nil {
t.Fatal(err)
}
if err := VerifyFile(binPath); err != nil {
t.Fatalf("valid signature rejected: %v", err)
}
}
func TestVerifyFile_TamperedBinary(t *testing.T) {
pub, priv, _ := ed25519.GenerateKey(rand.Reader)
dir := t.TempDir()
binPath := filepath.Join(dir, "mpcd")
os.WriteFile(binPath, []byte("original"), 0644)
SignFile(binPath, priv)
// Tamper with the binary after signing
os.WriteFile(binPath, []byte("tampered"), 0644)
SetTrustedKeys([]string{hex.EncodeToString(pub)})
if err := VerifyFile(binPath); err == nil {
t.Fatal("tampered binary was accepted — O-1 regression")
}
}
func TestVerifyFile_WrongKey(t *testing.T) {
_, priv1, _ := ed25519.GenerateKey(rand.Reader)
pub2, _, _ := ed25519.GenerateKey(rand.Reader)
dir := t.TempDir()
binPath := filepath.Join(dir, "mpcd")
os.WriteFile(binPath, []byte("content"), 0644)
SignFile(binPath, priv1)
// Trust only key2, but signed with key1
SetTrustedKeys([]string{hex.EncodeToString(pub2)})
if err := VerifyFile(binPath); err == nil {
t.Fatal("signature from untrusted key was accepted")
}
}
func TestVerifyFile_NoSignatureFile(t *testing.T) {
pub, _, _ := ed25519.GenerateKey(rand.Reader)
dir := t.TempDir()
binPath := filepath.Join(dir, "mpcd")
os.WriteFile(binPath, []byte("content"), 0644)
SetTrustedKeys([]string{hex.EncodeToString(pub)})
if err := VerifyFile(binPath); err == nil {
t.Fatal("missing .sig file was not detected")
}
}
func TestVerifyFile_NoTrustedKeys(t *testing.T) {
TrustedSigningKeys = nil
if err := VerifyFile("/nonexistent"); err == nil {
t.Fatal("no trusted keys should fail")
}
}
func TestHashFile(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "test")
content := []byte("test-content")
os.WriteFile(path, content, 0644)
got, err := HashFile(path)
if err != nil {
t.Fatal(err)
}
expected := sha256.Sum256(content)
if got != hex.EncodeToString(expected[:]) {
t.Fatalf("hash mismatch: got %s", got)
}
}