Files
ObsidianDragon/third_party
DanSandClaude Opus 5.5 20b63bf45d fix(lite-backend): validate WIFs, refuse key import while encrypted
import_taddr decoded a WIF with bs58::decode(..).unwrap(), a [2..66]
slice of its hex and SecretKey::from_slice(..).unwrap(), all under the
wallet write guard that do_import_tk holds. A z-key, a typo or any short
string panicked there and poisoned the wallet until restart, and the
checksum was never verified, so a mistyped WIF that was still valid
base58 imported a different key.

A private key imported into an encrypted wallet was stored without an
enc_key. The import then failed in do_save's lock(), which had already
zeroed the seed while the wallet stayed "unlocked": seed export showed
the all-zero-entropy phrase.

- decode_taddr_wif replaces the old decode: Base58Check with the
  checksum verified, version 0xBC (the config prefix) or 0x80, and the
  0x01 compressed flag. It decodes into a buffer it owns and wipes it
  with sodiumoxide::utils::memzero on every path, including a failed
  checksum. Errors are fixed strings that never contain the key.
- import_taddr and add_imported_sk refuse while the wallet is encrypted,
  as add_taddr and add_zaddr already do.
- do_import_tk and do_import_sk check is_encrypted() before the
  "locked" check, so a locked wallet does not send the user to unlock
  and retry.

Flagged behaviour changes:
- Base58Check, version 0xBC/0x80 and the compressed flag are required;
- uncompressed and foreign-network WIFs are rejected with fixed
  messages (an uncompressed key used to import under the compressed
  address, where its funds are not);
- no panic and no poisoned lock;
- private-key import (t and z) is refused while the wallet is
  encrypted, with a reason that says to remove encryption, import, then
  encrypt again; viewing keys still import;
- the key is never echoed.
No ABI, symbol or wallet format change.

Tests: garbage, z-keys, bad checksums, a transposed or flipped
character, a zero scalar, a wrong flag, uncompressed, 0x05 and 0xEF WIFs
are rejected with their message and leave tkeys usable; the wallet's own
export, a 0x80 WIF and the published key-1 vector still import; the
encrypted refusal in the wallet and the client, locked and unlocked,
leaves lock, save and seed export intact; a viewing key still imports
into an encrypted wallet; a bad timport leaves the wallet lock unpoisoned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:22:00 -05:00
..