Commit 66a2a32
refactor(secret): back Secret with upstream SecretString
`model::secret::Secret` owned its own memsec-backed guarded buffer — a
near-duplicate of `platform_wallet_storage::secrets::SecretString`, which
gained `replace_range` upstream and can now back it directly. Collapse
`Secret` into a newtype over `SecretString`.
Deleted, not kept alongside: `GuardedBuf` and its two `unsafe impl
Send`/`Sync`, its `Drop`, `alloc_failed`, `DEFAULT_CAPACITY`, the
hand-rolled `reserve`/`splice`/`as_bytes`/`from_plaintext` helpers,
`with_capacity` (no callers), the hand-written `Deserialize`, and every
`unsafe` block in the file — eleven of them, now zero. The direct
`memsec` and `region` dependencies go with them; `region` and its
transitive `mach2` leave the graph entirely, and `memsec` remains only
where it belongs, under `platform-wallet-storage`.
Each `TextBuffer` operation reduces to `SecretString::replace_range`.
Char-index to byte-offset translation stays here, via egui's
`byte_index_from_char_index`, which always yields a character boundary at
or before the end of the plaintext — so no edit can trip the bounds
assertions that `replace_range` applies where the old `splice` silently
clamped.
Three behavioral consequences, all favorable:
- Equality goes through `subtle::ConstantTimeEq` rather than a raw
`memsec::memeq` call. `subtle` still short-circuits on a length
mismatch, so the length remains observable through timing exactly as
before; what changes is that the comparison is no longer `unsafe`.
- Deserialization forwards to `SecretString`'s visitor, which copies a
borrowed `&str` straight into guarded memory instead of routing through
a transient `String`, and refuses a value past the vault's
`MAX_PASSPHRASE_LEN` before allocating. The one caller,
`ui/masternodes/testnet_fixture.rs`, supplies WIFs far below it.
- An empty `Secret` now holds no allocation at all, where it previously
locked a 4 KiB page. The UI holds many empty ones.
`subtle` becomes unconditional: `PartialEq` is always compiled, so gating
it on `mcp` no longer works. `secret-serde` is enabled unconditionally on
`platform-wallet-storage` and `secret-schemars` under `mcp`/`cli`, which
are the only features that generate tool schemas. The `JsonSchema` impl
delegates to `SecretString`'s, keeping the schema name `Secret` — and so
its `schema_id` — unchanged for existing MCP clients.
Tests keep their intent: editing, multi-byte UTF-8, growth, take,
trimmed, equality, clone, and drop behavior all still assert observable
`Secret` behavior, and two new cases cover clone independence and serde.
Those testing the deleted internals go with them — the full-capacity wipe
and the no-shared-page guarantee are no longer reachable through
`Secret`'s API and are proven in `platform-wallet-storage`'s own suite.
CLAUDE.md's `#[ignore]` example named the deleted read-after-free test;
it now names the surviving one in `wallet_backend/payments.rs`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>1 parent 129f378 commit 66a2a32
4 files changed
Lines changed: 118 additions & 401 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
69 | 69 | | |
70 | 70 | | |
71 | 71 | | |
72 | | - | |
| 72 | + | |
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
38 | 42 | | |
39 | 43 | | |
| 44 | + | |
40 | 45 | | |
41 | 46 | | |
42 | 47 | | |
| |||
100 | 105 | | |
101 | 106 | | |
102 | 107 | | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | 108 | | |
109 | 109 | | |
110 | | - | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
111 | 113 | | |
112 | 114 | | |
113 | 115 | | |
| |||
122 | 124 | | |
123 | 125 | | |
124 | 126 | | |
125 | | - | |
126 | | - | |
| 127 | + | |
| 128 | + | |
127 | 129 | | |
128 | 130 | | |
129 | 131 | | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | 132 | | |
134 | 133 | | |
135 | 134 | | |
| |||
0 commit comments