mirror of
https://github.com/luxfi/mpc.git
synced 2026-09-24 00:26:24 +00:00
Fixes all findings from the Blue Team defensive security review of the → 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.
63 lines
1.6 KiB
Go
63 lines
1.6 KiB
Go
package integrity
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func FuzzVerifyFile(f *testing.F) {
|
|
// Generate a real key pair for seeding
|
|
pub, priv, _ := ed25519.GenerateKey(rand.Reader)
|
|
|
|
f.Add([]byte("valid binary content"), []byte(hex.EncodeToString(ed25519.Sign(priv, []byte("valid binary content")))))
|
|
f.Add([]byte(""), []byte(""))
|
|
f.Add([]byte("content"), []byte("not-hex"))
|
|
f.Add([]byte("content"), []byte("deadbeef"))
|
|
|
|
f.Fuzz(func(t *testing.T, content []byte, sigBytes []byte) {
|
|
dir := t.TempDir()
|
|
binPath := filepath.Join(dir, "test-binary")
|
|
os.WriteFile(binPath, content, 0644)
|
|
os.WriteFile(binPath+".sig", sigBytes, 0644)
|
|
|
|
SetTrustedKeys([]string{hex.EncodeToString(pub)})
|
|
|
|
// Must not panic regardless of input
|
|
err := VerifyFile(binPath)
|
|
|
|
// If verification passes, the signature must actually be valid
|
|
if err == nil {
|
|
// Double-check: manually verify
|
|
sigHex := string(sigBytes)
|
|
sig, decErr := hex.DecodeString(sigHex)
|
|
if decErr != nil || len(sig) != ed25519.SignatureSize {
|
|
t.Fatal("verification passed but signature is malformed")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func FuzzSetTrustedKeys(f *testing.F) {
|
|
f.Add("deadbeef")
|
|
f.Add("")
|
|
f.Add("not-hex!")
|
|
pub, _, _ := ed25519.GenerateKey(rand.Reader)
|
|
f.Add(hex.EncodeToString(pub))
|
|
|
|
f.Fuzz(func(t *testing.T, keyHex string) {
|
|
// Must not panic
|
|
err := SetTrustedKeys([]string{keyHex})
|
|
if err == nil {
|
|
// Valid key: must be exactly 32 bytes
|
|
decoded, _ := hex.DecodeString(keyHex)
|
|
if len(decoded) != ed25519.PublicKeySize {
|
|
t.Fatalf("accepted key of length %d (expected %d)", len(decoded), ed25519.PublicKeySize)
|
|
}
|
|
}
|
|
})
|
|
}
|