Add qr_to_sheet.py: decode saved OTP QR screenshots and append new
credentials to the canonical CSV, deduplicated on the otpauth:// data.
Add otpauth.py (parse_otpauth / canonical_key / build_otpauth), shared
by both tools. The canonical format becomes a minimal CSV (issuer,
account, otpauth_uri, source_file); load_credentials reads CSV or xlsx
and derives crypto from the immutable otpauth_uri while taking
issuer/account from their editable label columns.
Halt import on control characters or a ':'/'/' inside an issuer or
account (they collide with the OATH issuer:account separator and period/
prefix), on a composed name over 64 bytes with a clearer per-field
message, and on a digit count outside 6-8 or a non-positive period.
Reuse each credential's post-PUT memory reading as the baseline for the
next, halving the memory-applet SELECTs (each triggers a garbage
collection). A 34-credential profiling run now completes in seconds.
The applet gates RESET behind authentication when a password is set
(unlike Yubico OATH, which allows an unauthenticated reset). --reset now
authenticates with the applet password (--password or prompt) before
resetting a locked applet, and the RESET error includes the status-word
meaning.
Add two admin operations on the OATH protocol layer: --reset (RESET
0x04/0xDEAD) and --set-password, which sets an access password after a
successful import only if the applet has none. Fix _parse_select to mask
the SELECT ALGORITHM tag to its low nibble (the applet reports the full
type|algo byte, e.g. 0x21), which previously broke validate on a locked
applet. Add a clean top-level OathError handler.
Import TOTP credentials from the export spreadsheet into a VivoKey Apex
OTP (ykneo-oath) applet over PC/SC. Includes the OATH protocol layer
(SELECT/VALIDATE/LIST/PUT with 61xx reassembly), PBKDF2 password
authentication, pre-flight input validation, ask-per-conflict handling,
optional javacard-memory profiling, and hardware-free unit tests.