Files
IronStorage/docs/android/otp.md
T
hugo 6a864a8d7f
Android ARM verification / rust (push) Failing after 49m4s
Android ARM verification / android (push) Failing after 9s
Dependency security audit / rustsec (push) Successful in 21s
Implement Android TOTP and confirmed HOTP presentation (#107)
2026-10-12 11:43:23 +02:00

50 lines
3.1 KiB
Markdown

# Android one-time passwords
Issue [#107](https://git.rfc1437.de/hugo/IronStorage/issues/107) connects the TOTP
destination to the storage-owned discovery catalog. Opening the list reads cached
metadata without decrypting entries. Select a row, then Unlock to display its
issuer, account, grouped code, countdown and progress. Refresh TOTP catalog is an
explicit authenticated discovery action; the progress/search workflow belongs
to [#110](https://git.rfc1437.de/hugo/IronStorage/issues/110).
The normal entry viewer and TOTP detail use the same code component and native
viewer controller. Decryption, creation and editing reconcile the catalog in
Rust. Only nonsecret row identities and revisions are restored after recreation.
OTP parameters, codes and authentication secrets are never persisted by Kotlin.
Rust computes SHA1/SHA256/SHA512 codes, six/eight digits, custom periods, absolute
validity boundaries, grouping and countdown. The composed code component owns a
STARTED-lifecycle coroutine that submits OS clock facts without touching the
authentication lease. Scrolling it out or leaving stops decryption/countdown ticks;
an expiry-only native window check still erases held codes when hidden. Rust validates each
returned window before publication, including delayed results and backward clock
changes. Lock, background, expiry, entry changes and stale revisions remove codes
and cancel presentation. Explicit copies use the existing sensitive clipboard
adapter and Rust timeout/ownership checks.
HOTP in the normal entry viewer requires Generate next HOTP code and a separate
counter confirmation. The existing pass-otp core increments and atomically commits
the encrypted counter before returning its code. Refresh and Copy use that same
committed counter without incrementing. Stale documents, open editors, failed Git
commits and overflow cannot consume a counter. The TOTP discovery catalog remains
specific to time-based entries. Android exposes no Watch sharing controls.
## Validation
Rust tests cover RFC 6238 algorithm vectors, six/eight digits, 30/60-second
boundaries, cache agreement, polling without lease renewal, malformed URI
diagnostics, stale revision revocation, HOTP confirmation, copy/refresh stability,
commit rollback and counter overflow. Android's NativeOtpPresentationTest uses
real encrypted stores with fake wall/lease clocks to verify catalog-only reads,
boundary transitions, tick lease expiry, clipboard handoff expiry, queued user
actions overtaking read-only observations, both HOTP generations and background
revocation. TotpScreenTest covers explicit unlock, grouped code/countdown/copy,
lock cleanup, HOTP confirm/cancel, tick cancellation on leaving and 300% text
without clipped digits. Computer use inspects the same Compose
components on an ARM64 emulator using disposable presentation fixtures.
All emulator installs preserve the retained app container. Production Keystore
and biometric enrollment are unchanged by this story; the native controller tests
provide deterministic OS capability callbacks. Supported release ABIs remain
arm64-v8a and armeabi-v7a; physical devices and x86_64 are outside this milestone.