forked from digitalbirdo/BT-LinkkeySync
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathBT-LinkkeySync.py
132 lines (109 loc) · 5.36 KB
/
BT-LinkkeySync.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env python
import plistlib
import os
import platform
import sys
# import pprint
import subprocess
print("---------------------------------")
print(" BT-Linkkeysync by DigitalBird")
print("---------------------------------")
# file where the registry info shall be stored
filename = 'btkeys.reg'
highSierraLoc = float(".".join(platform.mac_ver()[0].split(".")[:2])) >= 10.13
print("> get Bluetooth Link Keys from macOS and store it to blued.plist")
if not highSierraLoc:
output = subprocess.check_output(
"sudo defaults export /private/var/root/Library/Preferences/blued.plist ./blued.plist", shell=True)
else:
output = subprocess.check_output(
"sudo defaults export /private/var/root/Library/Preferences/com.apple.bluetoothd.plist ./blued.plist", shell=True)
print("> convert exported list from binary to xml")
output = subprocess.check_output(
"sudo plutil -convert xml1 ./blued.plist", shell=True)
print("> parse the converted plist")
if sys.version_info[0] == 2:
pl = plistlib.readPlist("./blued.plist")
else:
with open("./blued.plist", 'rb') as fp:
pl = plistlib.load(fp, fmt=None, use_builtin_types=False)
# print the content in a human readable forat
# pprint.pprint(pl)
# open the file where we write the registry information
f = open(filename, 'w')
# function which is used to do the byte swapping and insert commas
def toWinRep(d, splitStr=",", isReverse=True, padEnd=0):
if sys.version_info[0] == 2:
s = d.data.encode("hex")
else:
s = d.data.hex()
if padEnd > 0:
s = s.ljust(padEnd, '0')
if padEnd < 0:
s = s.rjust(0-padEnd, '0')
if isReverse:
mystr = splitStr.join(map(str.__add__, s[-2::-2], s[-1::-2]))
else:
mystr = splitStr.join(map(str.__add__, s[0::2], s[1::2]))
return mystr
print("> Convert the Link Keys and store them to btkeys.reg")
# header for the registry file
f.write("Windows Registry Editor Version 5.00")
# loop over all avialable Bluetooth 2.0 adapters
if "LinkKeys" in pl:
print(" Bluetooth 2.0: " +
str(len(pl["LinkKeys"].keys())) + " Links keys found")
for adapter in pl["LinkKeys"].keys():
f.write(
'\r\n\r\n[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\BTHPORT\\Parameters\\Keys\\'+adapter.replace("-", "")+"]")
# loop over all available devices of this adapter
for device in pl["LinkKeys"][adapter].keys():
f.write('\r\n"'+device.replace("-", "")+'"=hex:' +
toWinRep(pl["LinkKeys"][adapter][device], ""))
else:
print("No Bluetooth 2.0 information available")
# loop over all Bluetooth 4.0 LE adapters
if "SMPDistributionKeys" in pl:
print(" Bluetooth 4.0 LE: " +
str(len(pl["SMPDistributionKeys"].keys())) + " Links keys found")
for adapter in pl["SMPDistributionKeys"].keys():
# loop over all available devices of this adapter
for device in pl["SMPDistributionKeys"][adapter].keys():
dev = '\r\n\r\n[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\BTHPORT\\Parameters\\Keys\\' + \
adapter.replace("-", "")+'\\'+device.replace("-", "") + "]"
# Lonk-Term Key (LTK)
# 128-bit key used to generate the session key for an encrypted connection.
dev += '\r\n"LTK"=hex:' + \
toWinRep(pl["SMPDistributionKeys"][adapter]
[device]["LTK"], isReverse=False)
# dev += '\r"KeyLength"=dword:00000000' # Don't know why this is zero when i pair my BT LE Mouse with windows.
dev += '\r\n"KeyLength"=dword:' + \
toWinRep(pl["SMPDistributionKeys"][adapter]
[device]["LTKLength"], "", padEnd=8)
# Random Number (RAND):
# 64-bit stored value used to identify the LTK. A new RAND is generated each time a unique LTK is distributed.
dev += '\r\n"ERand"=hex(b):' + toWinRep(
pl["SMPDistributionKeys"][adapter][device]["RAND"], isReverse=False)
# Encrypted Diversifier (EDIV)
# 16-bit stored value used to identify the LTK. A new EDIV is generated each time a new LTK is distributed.
dev += '\r\n"EDIV"=dword:' + toWinRep(
pl["SMPDistributionKeys"][adapter][device]["EDIV"], "", padEnd=8,)
# Identity Resolving Key (IRK)
# 128-bit key used to generate and resolve random address.
dev += '\r\n"IRK"=hex:' + \
toWinRep(pl["SMPDistributionKeys"][adapter][device]["IRK"])
# Device Address
# 48-bit Address of the connected device
dev += '\r\n"Address"=hex(b):' + toWinRep(
pl["SMPDistributionKeys"][adapter][device]["Address"], padEnd=-16)
# Don't know whats that, i'm using an Logitech MX Master, and this is written to the registry when i pair it to windows
dev += '\r\n"AddressType"=dword:00000001'
# Connection Signature Resolving Key (CSRK)
# 128-bit key used to sign data and verify signatures on the receiving device.
# Info: CSRK is not stored on the OSX side.
# It seems to be a temporary key which is only needed during the first bundling of the devices. After that, only the LTK is used.
f.write(dev)
else:
print("No Bluetooth 4.0 information available")
f.close()
print("> Registry file generated and ready for import")