Require auth to reset a locked applet

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.
This commit is contained in:
2026-07-08 13:34:18 -07:00
parent 602bbc13f7
commit bb09e0636d

View File

@@ -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