MCPcopy Create free account
hub / github.com/Keeper-Security/Commander / get_totp_code

Function get_totp_code

keepercommander/record.py:22–63  ·  view source on GitHub ↗
(url, offset=None)

Source from the content-addressed store, hash-verified

20
21
22def get_totp_code(url, offset=None): # type: (str, Optional[int]) -> Optional[Tuple[str, int, int]]
23 comp = parse.urlparse(url)
24 if comp.scheme == 'otpauth':
25 secret = None
26 algorithm = 'SHA1'
27 digits = 6
28 period = 30
29 for k, v in parse.parse_qsl(comp.query):
30 if k == 'secret':
31 secret = v
32 elif k == 'algorithm':
33 algorithm = v
34 elif k == 'digits':
35 digits = int(v)
36 elif k == 'period':
37 period = int(v)
38 if secret:
39 tm_base = int(datetime.datetime.now().timestamp())
40 tm = tm_base / period
41 if isinstance(offset, int):
42 tm += offset
43 alg = algorithm.lower()
44 if alg in hashlib.__dict__:
45 reminder = len(secret) % 8
46 if reminder in {2, 4, 5, 7}:
47 padding = '=' * (8 - reminder)
48 secret += padding
49 key = bytes(b32decode(secret))
50 msg = int(tm).to_bytes(8, byteorder='big')
51 hash = hashlib.__dict__[alg]
52 hm = hmac.new(key, msg=msg, digestmod=hash)
53 digest = hm.digest()
54 offset = digest[-1] & 0x0f
55 base = bytearray(digest[offset:offset + 4])
56 base[0] = base[0] & 0x7f
57 code_int = int.from_bytes(base, byteorder='big')
58 code = str(code_int % (10 ** digits))
59 if len(code) < digits:
60 code = code.rjust(digits, '0')
61 return code, period - (tm_base % period), period
62 else:
63 raise Exception(f'Unsupported hash algorithm: {algorithm}')
64
65
66class Record:

Callers 7

displayMethod · 0.85
displayMethod · 0.85
executeMethod · 0.85
executeMethod · 0.85
display_codeMethod · 0.85
executeMethod · 0.85
display_totpMethod · 0.85

Calls 1

b32decodeFunction · 0.85

Tested by

no test coverage detected