fix: copy the master at each layer so zeroization stays local

This commit is contained in:
randogoth 2026-09-29 20:35:16 +03:00
parent d7179694a6
commit f7452832ea
3 changed files with 19 additions and 5 deletions

View file

@ -67,7 +67,12 @@ class FumiNative {
/// operation, so it never needs an isolate — and widget tests can settle
/// it inside their fake-async zones.
void setMaster(Uint8List master, {int? rotations}) {
_master = master;
// Own copy: the caller keeps its buffer (the onboarding screen zeroes
// its reference on dispose, and wipe zeroes Hive's), and the account
// rebuilds after register/restore/rotate must derive from untouched
// bytes — a shared buffer zeroized elsewhere would rebuild an account
// that matches none of our keys.
_master = Uint8List.fromList(master);
_rebuildAccount(rotations: rotations);
}

View file

@ -145,14 +145,17 @@ class SmolStore {
void setMaster(Uint8List fresh) {
// Hive's in-memory state updates synchronously and persists in the
// background, so the store is consistent without awaiting the write.
unawaited(_meta.put("master", fresh));
// The put takes its own copy: the caller's buffer is the caller's to
// zeroize (the onboarding screen does, on dispose), and a shared object
// would scrub the store's view with it.
unawaited(_meta.put("master", Uint8List.fromList(fresh)));
_native.setMaster(fresh, rotations: 0);
}
/// The master restored from a backup, already at the rotation index the
/// server bound.
void restoreMaster(Uint8List master, int index) {
unawaited(_meta.put("master", master));
unawaited(_meta.put("master", Uint8List.fromList(master)));
_native.setMaster(master, rotations: index);
}