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])
Exemple #2
0
 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))