mirror of
https://github.com/luxfi/connect.git
synced 2026-10-30 16:59:20 +00:00
Every verifier + the dispatcher now fails closed under any malformed/ adversarial input, never throws/panics, and resists DoS. No new dependency; prod runtime tree stays 4 deps, all MIT (zero copyleft). - src/limits.ts <-> go/walletconnect/limits.go: single bounds module — size caps (message/sig/pubkey/address/extra/lines) + chain<->scheme table (chainAllowsScheme) that rejects every illegitimate (chain,scheme) pair up front, closing cross-chain scheme confusion by construction. sig cap = 20 KiB so it clears a Cardano COSE_Sign1 (embeds the payload, ~2x the message) for a large-but-legal message. - dispatcher gate() + total backstop (TS try/catch, Go defer recover) around verifyProof / verifyProofAsync so any throw/panic below -> rejected proof. - per-verifier input bounds before any hash/decode (verifiers are exported, so each is independently safe, not just via dispatch). - caip122 parse: bound message size + line count before split. - strict base64 in bytes.ts (was lenient atob) — also kills a latent TS/Go divergence (Go StdEncoding is strict). - CBOR depth cap (MAX_CBOR_DEPTH=16) + declared-length<=remaining guard both langs; in Go a stack overflow is fatal/non-recoverable so this is load-bearing. - TON workchain range-checked to int32 in TS (Go already did). Tests: 160 TS (was 112) incl fuzz.test.ts (47, 30k+ random inputs) + Go property/corpus + 3 native Fuzz* (610k/1.2M/1.0M execs clean). Invariants: (A) never throws/panics, (B) never ok for a non-valid proof, with a ranCrypto>0 gate proving the fuzzers reach the crypto layer. All prior tests stay green. Bump @luxwallet/connect 0.1.0 -> 0.1.1.
42 lines
1.3 KiB
Go
42 lines
1.3 KiB
Go
package walletconnect
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"strings"
|
|
|
|
"github.com/mr-tron/base58"
|
|
)
|
|
|
|
// Solana verifier — ed25519 over the raw UTF-8 CAIP-122 message (the bytes a
|
|
// wallet's signMessage returns). The account address IS the base58-encoded
|
|
// ed25519 public key, so the key needed to verify is the address itself.
|
|
// Mirrors src/solana/verify.ts.
|
|
|
|
// VerifySolana reports whether signature over message was produced by the key
|
|
// behind address (base58 ed25519 public key). Fails closed on any decode error.
|
|
func VerifySolana(message, signature, address string) bool {
|
|
// Bound attacker-controlled strings before base58-decoding the address or
|
|
// hashing the message (DoS guard; safe when called outside the dispatcher).
|
|
if len(message) > maxMessageLen || len(signature) == 0 || len(signature) > maxSignatureLen {
|
|
return false
|
|
}
|
|
if len(address) == 0 || len(address) > maxAddressLen {
|
|
return false
|
|
}
|
|
pub, err := base58.Decode(strings.TrimSpace(address))
|
|
if err != nil {
|
|
return false
|
|
}
|
|
if len(pub) != ed25519.PublicKeySize { // 32
|
|
return false
|
|
}
|
|
sig, err := decodeSignature(signature)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
if len(sig) != ed25519.SignatureSize { // 64
|
|
return false
|
|
}
|
|
return ed25519.Verify(ed25519.PublicKey(pub), []byte(message), sig)
|
|
}
|