-
Notifications
You must be signed in to change notification settings - Fork 10
/
export2yubikey.py
executable file
·66 lines (47 loc) · 1.73 KB
/
export2yubikey.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!/usr/bin/python3
# -*- coding: future_fstrings -*-
import sys
from urllib.parse import urlparse, parse_qs
from base64 import b64decode, b32encode
import OtpMigration_pb2 as otp
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
if len(sys.argv) < 2:
eprint("Usage: {0} <data>".format(sys.argv[0]))
eprint("<data> should be a otpauth-migration:// url")
sys.exit(1)
url = urlparse(sys.argv[1])
if url.scheme != 'otpauth-migration':
eprint("Only otpauth-migration URLs can be parsed")
sys.exit(2)
qs = parse_qs(url.query)
if 'data' not in qs:
eprint("Missing `data` field in query string")
sys.exit(3)
data = b64decode(qs["data"][0])
payload = otp.MigrationPayload.FromString(data)
for params in payload.otp_parameters:
ykargs = ["oath","add"]
otp_type = otp.OtpType.Name(params.type)
ykargs.extend(["-o", otp_type])
if params.digits == otp.DigitCount.SIX:
otp_digits = "6"
elif params.digits == otp.DigitCount.EIGHT:
otp_digits = "8"
else:
raise Exception(f"Unexpected DigitCount: {otp.DigitCount.Name(params.digits)}")
ykargs.extend(["-d", otp_digits])
otp_algorirthm = otp.Algorithm.Name(params.algorithm)
ykargs.extend(["-a", otp_algorirthm])
if params.type == otp.OtpType.HOTP:
ykargs.extend(["-c", params.counter])
elif params.type == otp.OtpType.TOTP:
ykargs.extend(["-p", "30"])
else:
raise Exception(f"Unexpected OtpType: {otp.OtpType.Name(params.type)}")
if len(params.issuer) > 0:
ykargs.extend(["-i", '"'+params.issuer+'"'])
ykargs.append('"' + params.name + '"')
ykargs.append(b32encode(params.secret).decode("UTF-8"))
#print(ykargs)
print("ykman " + " ".join(ykargs))