Skip to content

Commit

Permalink
Fix: hook in to LTPK to fill the "pk" record.
Browse files Browse the repository at this point in the history
Code cleanup
  • Loading branch information
systemcrash committed Jul 16, 2021
1 parent 4f4ac82 commit 265f050
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 20 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Very quick python implementation of AP2 protocol using **minimal
multi-room** features. For now it implements:
- HomeKit transient pairing (SRP/Curve25519/ChaCha20-Poly1305)
- HomeKit non-transient pairing
- FairPlay (v3) authentication
- Receiving of both REALTIME and BUFFERED Airplay2 audio streams
- Airplay2 Service publication
Expand Down
56 changes: 40 additions & 16 deletions ap2-receiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,30 @@ class Feat(IntFlag):
| Feat.Ft14MFiSoftware | Feat.Ft09AirPlayAudio
)


# PI = Public ID (can be GUID, MAC, some string)
PI = b'aa5cb8df-7f14-4249-901a-5e748ce57a93'


class LTPK():
# Long Term Public Key - get it from the hap module.
def __init__(self):
announce_id, self.ltpk = Hap(PI).configure()
self.public_int = int.from_bytes(self.ltpk, byteorder='big')
# builds a 64 char hex string, for the 32 byte pub key
self.public_string = str.lower("{0:0>4X}".format(self.public_int))

def get_pub_string(self):
return self.public_string

def get_pub_bytes(self):
return self.ltpk


DEVICE_ID = None
IPV4 = None
IPV6 = None

# TODO: Figure out what "PI" is
PI = b'aa5cb8df-7f14-4249-901a-5e748ce57a93'

SERVER_VERSION = "366.0"
HTTP_CT_BPLIST = "application/x-apple-binary-plist"
HTTP_CT_OCTET = "application/octet-stream"
Expand All @@ -170,6 +187,7 @@ class Feat(IntFlag):
HTTP_X_A_HKP = "X-Apple-HKP"
HTTP_X_A_CN = "X-Apple-Client-Name"
HTTP_X_A_PD = "X-Apple-PD"
LTPK = LTPK()


def setup_global_structs(args):
Expand Down Expand Up @@ -255,23 +273,32 @@ def setup_global_structs(args):

mdns_props = {
"srcvers": SERVER_VERSION,
"deviceid": DEVICE_ID,
"deviceid": DEVICE_ID, # typically MAC addr
"features": "%s,%s" % (hex(FEATURES & 0xffffffff), hex(FEATURES >> 32 & 0xffffffff)),
"flags": "0x4",
# "name": "GINO", # random
"model": "Airplay2-Receiver", # random
# "manufacturer": "Pino", # random
# "serialNumber": "01234xX321", # random
"protovers": "1.1",
"acl": "0",
"rsf": "0x0",
"fv": "p20.78000.12",
# Casually generated UUIDs
"pi": "6dccfd20-b166-49cc-a593-6abd5f724ddb",
"gid": "6dccfd20-b166-49cc-a593-6abd5f724ddb",
"gcgl": "0",
# "vn": "65537",
"pk": "ee352b0df39042e201d31564049023af58a106c6d904b74a68aa65012852997f"
"acl": "0", # Access ControL. 0,1,2 == anon,users,admin(?)
# These are found under the <deviceid>@<name> mDNS record.
# "am": "One", # Model
# "cn": "0,1", # CompressioN. 0,1 == None aka PCM, ALAC
# "da": "true", # Digest Auth(?) support
# "et": "0,1,3,4,5", # Audio Encryption Types(?).
# "md": "0,1,2", # MetaData(?) 0,1,2 == Text, Gfx, Progress
# "sf": "0x804", # Status Flags?
# "tp": "UDP", # TransPort for media? csv of transports?
# "vs": "366", # Source version?
"rsf": "0x0", # bitmask: required sender features(?)
"fv": "p20.78000.12", # Firmware version. p20 == AirPlay Src revision?
"pi": PI, # Pairing UUID (generated casually)
"gid": "5dccfd20-b166-49cc-a593-6abd5f724ddb", # Group UUID (generated casually)
"gcgl": "0", # Group Contains Group Leader.
# "isGroupLeader": "0" # See gcgl
# "vn": "65537", # (Airplay) version number (supported) 16.16, 65537 == 1.1
"pk": LTPK.get_pub_string() # Ed25519 PubKey
}


Expand Down Expand Up @@ -818,9 +845,6 @@ def handle_configure(self):
body = self.rfile.read(content_len)
plist = readPlistFromString(body)
self.pp.pprint(plist)
# accessory2_ltsk = nacl.signing.SigningKey.generate()
# accessory2_ltpk = bytes(accessory2_ltsk.verify_key)
# "248E34D7-A496-465E-A2A8-82AD0D099052"
accessory_id, accessory_ltpk = self.server.hap.configure()
configure_info = {
'Identifier': accessory_id.decode('utf-8'),
Expand Down
4 changes: 0 additions & 4 deletions ap2/pairing/hap.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,6 @@ def __init__(self, identifier):

self.device_ltpk = None
self.accessory_id = identifier
# self.accessory_id = b"00000000-0000-0000-0000-deadbeef0bad"
# self.accessory_ltsk = 0
# self.accessory_ltpk = 0

if not path.exists('./pairings/accessory-secret'):
accessory_secret = random(nacl.bindings.crypto_sign_SEEDBYTES)
Expand Down Expand Up @@ -418,7 +415,6 @@ def pair_setup_m5_m6_3(self, session_key):

# self.accessory_ltsk = nacl.signing.SigningKey.generate()
# self.accessory_ltpk = bytes(self.accessory_ltsk.verify_key)
# self.accessory_id = b"00000000-0000-0000-0000-f0989d7cbbab"

accessory_info = accessory_x + self.accessory_id + self.accessory_ltpk
accessory_signed = self.accessory_ltsk.sign(accessory_info)
Expand Down

0 comments on commit 265f050

Please sign in to comment.