diff options
| author | cirakg <cirakg@cirakg.xyz> | 2026-10-20 18:36:54 +0200 |
|---|---|---|
| committer | cirakg <cirakg@cirakg.xyz> | 2026-10-20 18:36:54 +0200 |
| commit | 151bfda5d4c567ff909a61dc9c90bf8eece1db37 (patch) | |
| tree | f8487b91cf6a9ce59dba02e95e67250fc84d8e80 /source/storage/KeyManager.mc | |
| parent | 25910f3a7a7fb28c4a58367b6e56dd2468b60933 (diff) | |
feat(settings): add the Add OTP, Add code and Manage entry forms with a PIN queue for locked entries
The full phone settings form (README 10.2) and its processing (10.3) as one
resumable job: Import, Add OTP, Add code, Manage, then the About fields.
Forms are applied only when their switch is on, cleared afterwards (secret
first; only the secret after a problem), deduplicated by keyed hash, and
report into their Result field and the results screen.
- Add OTP validates per README 10.4; Add code runs the real encoder
(CodeCheck, a job for 2D codes) and caches 2D codes on the way in.
- Manage entry: edit, move, require/drop PIN, replace, counter, delete.
Changes to locked entries are sealed under "q" and applied only after
the PIN is entered under "Phone changes" in the menu.
- About: catalog (800 characters max), version, storage use.
- "Encrypt names" now applies to new and existing entries.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'source/storage/KeyManager.mc')
| -rw-r--r-- | source/storage/KeyManager.mc | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/source/storage/KeyManager.mc b/source/storage/KeyManager.mc index 567288f..47dbd59 100644 --- a/source/storage/KeyManager.mc +++ b/source/storage/KeyManager.mc @@ -84,6 +84,30 @@ class KeyManager { return out; } + // A keyed hash (16 hex characters) of a settings form's content, for + // the applied-forms log (README 10.3). Keyed like the fingerprints, with + // its own label, because the content includes secrets. The parts are + // fed to the native HMAC one by one, each preceded by `separator`, so a + // large import form costs no byte loop here (the watchdog). + function formHash(parts as Array<ByteArray>, separator as Number) as String { + deviceKeys(); + var mac = new Cryptography.HashBasedMessageAuthenticationCode({ + :algorithm => Cryptography.HASH_SHA256, + :key => _fingerprintKey as ByteArray + }); + mac.update(Bytes.fromUtf8("OTPW-FH-1")); + for (var i = 0; i < parts.size(); i++) { + mac.update([separator]b); + if (parts[i].size() > 0) { + mac.update(parts[i]); + } + } + var digest = mac.digest(); + var out = Bytes.toHex(digest.slice(0, FINGERPRINT_BYTES)); + Bytes.wipe(digest); + return out; + } + // True when a PIN has been set. function hasPin() as Boolean { return _store.getValue(WRAP_KEY) != null; |
