diff --git a/test/test_cli_commands_on_yubikey.py b/test/test_cli_commands_on_yubikey.py index 7b536a94..dd8800f7 100644 --- a/test/test_cli_commands_on_yubikey.py +++ b/test/test_cli_commands_on_yubikey.py @@ -208,6 +208,16 @@ def test_oath_reset(self): 'Success! All credentials have been cleared from the device.', output) + def test_oath_hotp_code(self): + ykman_cli('oath', 'add', '-o', 'HOTP', 'hotp-cred', 'abba') + cred = ykman_cli('oath', 'code', 'hotp-cred') + self.assertIn('659165', cred) + + def test_oath_hotp_steam_code(self): + ykman_cli('oath', 'add', '-o', 'HOTP', 'Steam:steam-cred', 'abba') + cred = ykman_cli('oath', 'code', 'steam-cred') + self.assertIn('CGC3K', cred) + def test_oath_remove(self): ykman_cli('oath', 'add', 'remove-me', 'abba') ykman_cli('oath', 'remove', 'remove-me') diff --git a/ykman/oath.py b/ykman/oath.py index ca83a3f2..172703b0 100644 --- a/ykman/oath.py +++ b/ykman/oath.py @@ -220,10 +220,14 @@ def calculate(self, cred, timestamp=None): challenge = time_challenge(timestamp) data = Tlv(TAG.NAME, cred.name.encode('utf-8')) + \ Tlv(TAG.CHALLENGE, challenge) - resp = self.send_apdu(0, INS.CALCULATE, 0, 0x01, data) + resp = self.send_apdu(0, INS.CALCULATE, 0, 0, data) resp = parse_tlvs(resp)[0].value + # Manual dynamic truncation is required + # for Steam entries, so let's do it for all. digits = six.indexbytes(resp, 0) - code = resp[1:] + resp = resp[1:] + offset = resp[-1] & 0xF + code = resp[offset:offset + 4] code = parse_truncated(code) cred.code = format_code(code, digits, steam=cred.steam) if cred.oath_type != 'hotp':