def calculate(self, slot, challenge=None, totp=False, digits=6, wait_for_touch=True): if totp: if challenge is None: challenge = time_challenge(time.time()) else: challenge = time_challenge(challenge) else: challenge = a2b_hex(challenge) resp = create_string_buffer(64) # Some versions of the NEO firmware returns error 11 too often. # Give the YubiKey 10 tries to do the calculation. for idx in range(10): try: check( ykpers.yk_challenge_response(self._dev, SLOTS[slot], wait_for_touch, len(challenge), challenge, sizeof(resp), resp)) except YkpersError as e: if idx < 10 and e.errno == 11 and wait_for_touch is True: # Error 11 when wait_for_touch is true is an unexpected # state, let's try again. continue else: raise if totp: return format_code(parse_totp_hash(resp.raw[:20]), digits) else: return b2a_hex(resp.raw[:20])
def test_time_challenge(self): self.assertEqual(b'\0' * 8, time_challenge(0)) self.assertEqual(b'\x00\x00\x00\x00\x00\x06G\x82', time_challenge(12345678)) self.assertEqual(b'\x00\x00\x00\x00\x02\xf2\xeaC', time_challenge(1484223461.2644958))