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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user