diff --git a/apex_otp_import.py b/apex_otp_import.py index d611d11..73c80a5 100644 --- a/apex_otp_import.py +++ b/apex_otp_import.py @@ -446,10 +446,12 @@ class OathSession: return def reset(self): - """RESET: wipe all credentials and any password (P1P2 = 0xDEAD).""" + """RESET: wipe all credentials and any password (P1P2 = 0xDEAD). + Unlike Yubico's OATH, this applet gates RESET behind authentication when + a password is set, so a locked applet must be VALIDATEd first.""" data, sw = self.ch.send(0x00, INS_RESET, 0xDE, 0xAD) if sw != 0x9000: - raise OathError(sw, "RESET failed") + raise OathError(sw, f"RESET failed ({sw_message(sw)})") return @@ -642,6 +644,10 @@ def main(argv=None): return 1 oath = OathSession(CardChannel(connection)) oath.select() + if oath.locked: + # This applet requires authentication before RESET (unlike Yubico). + pw = args.password or getpass.getpass("Applet password (required to reset): ") + oath.validate(pw) oath.reset() print(f"Applet reset on '{reader}' (all credentials and any password wiped).") return 0