Beispiel #1
0
def test_pack_ptr():
    assert pack(["a", "a"]) == b"\xD2\x41\x61\xA0"
    assert (pack(["foo", "bar", "foo",
                  "bar"]) == b"\xD4\x43\x66\x6F\x6F\x43\x62\x61\x72\xA0\xA1")
    assert (pack({
        "a": "b",
        "c": {
            "d": "a"
        },
        "d": True
    }) == b"\xE3\x41\x61\x41\x62\x41\x63\xE1\x41\x64\xA0\xA3\x01")
Beispiel #2
0
    def send_opack(self, frame_type: FrameType, data: Dict[str, Any]) -> None:
        """Send data encoded with OPACK."""
        # Add XID if not present
        if "_x" not in data:
            data["_x"] = self._xid
            self._xid += 1

        _LOGGER.debug("Send OPACK: %s", data)
        self.connection.send(frame_type, opack.pack(data))
Beispiel #3
0
    async def finish_pairing(self, username: str, pin_code: int) -> HapCredentials:
        """Finish pairing process."""
        self.srp.step1(pin_code)

        pub_key, proof = self.srp.step2(self._atv_pub_key, self._atv_salt)

        resp = await self.protocol.exchange_auth(
            FrameType.PS_Next,
            {
                PAIRING_DATA_KEY: write_tlv(
                    {
                        TlvValue.SeqNo: b"\x03",
                        TlvValue.PublicKey: pub_key,
                        TlvValue.Proof: proof,
                    }
                ),
                "_pwTy": 1,
            },
        )

        pairing_data = _get_pairing_data(resp)
        atv_proof = pairing_data[TlvValue.Proof]
        log_binary(_LOGGER, "Device", Proof=atv_proof)

        # TODO: Dummy data: what to set? needed at all?
        additional_data = {
            "altIRK": b"-\x54\xe0\x7a\x88*en\x11\xab\x82v-'%\xc5",
            "accountID": "DC6A7CB6-CA1A-4BF4-880D-A61B717814DB",
            "model": "AppleTV6,2",
            "wifiMAC": b"@\xff\xa1\x8f\xa1\xb9",
            "name": "Living Room",
            "mac": b"@\xc4\xff\x8f\xb1\x99",
        }

        encrypted_data = self.srp.step3(
            additional_data={17: opack.pack(additional_data)}
        )

        resp = await self.protocol.exchange_auth(
            FrameType.PS_Next,
            {
                PAIRING_DATA_KEY: write_tlv(
                    {
                        TlvValue.SeqNo: b"\x05",
                        TlvValue.EncryptedData: encrypted_data,
                    }
                ),
                "_pwTy": 1,
            },
        )

        pairing_data = _get_pairing_data(resp)
        encrypted_data = pairing_data[TlvValue.EncryptedData]

        return self.srp.step4(encrypted_data)
Beispiel #4
0
def test_golden():
    data = {
        "_i": "_systemInfo",
        "_x": 1254122577,
        "_btHP": False,
        "_c": {
            "_pubID":
            "AA:BB:CC:DD:EE:FF",
            "_sv":
            "230.1",
            "_bf":
            0,
            "_siriInfo": {
                "collectorElectionVersion": 1.0,
                "deviceCapabilities": {
                    "seymourEnabled": 1,
                    "voiceTriggerEnabled": 2
                },
                "sharedDataProtoBuf": 512 * b"\x08",
            },
            "_stA": [
                "com.apple.LiveAudio",
                "com.apple.siri.wakeup",
                "com.apple.Seymour",
                "com.apple.announce",
                "com.apple.coreduet.sync",
                "com.apple.SeymourSession",
            ],
            "_i":
            "6c62fca18b11",
            "_clFl":
            128,
            "_idsID":
            "44E14ABC-DDDD-4188-B661-11BAAAF6ECDE",
            "_hkUID": [UUID("17ed160a-81f8-4488-962c-6b1a83eb0081")],
            "_dC":
            "1",
            "_sf":
            256,
            "model":
            "iPhone10,6",
            "name":
            "iPhone",
        },
        "_t": 2,
    }

    packed = pack(data)
    unpacked = unpack(packed)

    assert DeepDiff(unpacked, data, ignore_order=True)
Beispiel #5
0
    def send_to_client(self, frame_type: FrameType, data: object) -> None:
        _LOGGER.debug("Send %s with data: %s", frame_type, data)

        data = opack.pack(data)

        payload_length = len(data) + (16 if self.chacha else 0)
        header = bytes([frame_type.value]) + payload_length.to_bytes(
            3, byteorder="big")

        if self.chacha:
            data = self.chacha.encrypt(data, aad=header)

        log_binary(_LOGGER, ">> Send", Header=header, Data=data)
        self.transport.write(header + data)
Beispiel #6
0
    def _m5_setup(self, pairing_data):
        session_key = hkdf_expand(
            "Pair-Setup-Encrypt-Salt",
            "Pair-Setup-Encrypt-Info",
            binascii.unhexlify(self.session.key),
        )

        acc_device_x = hkdf_expand(
            "Pair-Setup-Accessory-Sign-Salt",
            "Pair-Setup-Accessory-Sign-Info",
            binascii.unhexlify(self.session.key),
        )

        chacha = chacha20.Chacha20Cipher(session_key, session_key)
        decrypted_tlv_bytes = chacha.decrypt(
            pairing_data[TlvValue.EncryptedData], nounce="PS-Msg05".encode())

        _LOGGER.debug("MSG5 EncryptedData=%s", read_tlv(decrypted_tlv_bytes))

        other = {
            "altIRK": b"-\x54\xe0\x7a\x88*en\x11\xab\x82v-'%\xc5",
            "accountID": "DC6A7CB6-CA1A-4BF4-880D-A61B717814DB",
            "model": "AppleTV6,2",
            "wifiMAC": b"@\xff\xa1\x8f\xa1\xb9",
            "name": "Living Room",
            "mac": b"@\xc4\xff\x8f\xb1\x99",
        }

        device_info = acc_device_x + self.unique_id + self.keys.auth_pub
        signature = self.keys.sign.sign(device_info)

        tlv = {
            TlvValue.Identifier: self.unique_id,
            TlvValue.PublicKey: self.keys.auth_pub,
            TlvValue.Signature: signature,
            17: opack.pack(other),
        }

        tlv = write_tlv(tlv)

        chacha = chacha20.Chacha20Cipher(session_key, session_key)
        encrypted = chacha.encrypt(tlv, nounce="PS-Msg06".encode())

        tlv = write_tlv({
            TlvValue.SeqNo: b"\x06",
            TlvValue.EncryptedData: encrypted
        })

        self.send_to_client(FrameType.PS_Next, {"_pd": tlv})
        self.has_paired()
Beispiel #7
0
    def send_to_client(self, frame_type: FrameType, data: object) -> None:
        """Send data to client device (iOS)."""
        if not self.transport:
            _LOGGER.error("Tried to send to client, but not connected")
            return

        payload = opack.pack(data)

        payload_length = len(payload) + (16 if self.chacha else 0)
        header = bytes([frame_type.value]) + payload_length.to_bytes(
            3, byteorder="big")

        if self.chacha:
            payload = self.chacha.encrypt(payload, aad=header)
            log_binary(_LOGGER, ">> Send", Header=header, Encrypted=payload)

        self.transport.write(header + payload)
Beispiel #8
0
def test_pack_boolean():
    assert pack(True) == b"\x01"
    assert pack(False) == b"\x02"
Beispiel #9
0
def test_pack_endless_dict():
    assert pack(dict((chr(x), chr(x + 1)) for x in range(97, 127, 2))) == (
        b"\xEF" + b"\x41" + b"\x41".join(bytes([x])
                                         for x in range(97, 127)) + b"\x03")
Beispiel #10
0
def test_pack_dict():
    assert pack({}) == b"\xe0"
    assert pack({"a": 12, False: None}) == b"\xe2\x41\x61\x14\x02\x04"
    assert pack({True: {"a": 2}}) == b"\xe1\x01\xe1\x41\x61\x0a"
Beispiel #11
0
def test_pack_endless_array():
    assert pack(15 * ["a"]) == b"\xDF\x41\x61" + 14 * b"\xa0" + b"\x03"
Beispiel #12
0
def test_pack_array():
    assert pack([]) == b"\xd0"
    assert pack([1, "test", False]) == b"\xd3\x09\x44\x74\x65\x73\x74\x02"
    assert pack([[True]]) == b"\xd1\xd1\x01"
Beispiel #13
0
def test_pack_longer_raw_bytes():
    assert pack(33 * b"\x61") == b"\x91\x21" + (33 * b"\x61")
    assert pack(256 * b"\x61") == b"\x92\x00\x01" + (256 * b"\x61")
Beispiel #14
0
def test_pack_uuid():
    assert (pack(UUID("{12345678-1234-5678-1234-567812345678}")) ==
            b"\x05\x124Vx\x124Vx\x124Vx\x124Vx")
Beispiel #15
0
def test_pack_longer_strings():
    assert pack(33 * "a") == b"\x61\x21" + (33 * b"\x61")
    assert pack(256 * "a") == b"\x62\x00\x01" + (256 * b"\x61")
Beispiel #16
0
def test_pack_short_strings():
    assert pack("a") == b"\x41\x61"
    assert pack("abc") == b"\x43\x61\x62\x63"
    assert pack(0x20 * "a") == b"\x60" + (0x20 * b"\x61")
Beispiel #17
0
def test_pack_larger_integers():
    assert pack(0x28) == b"\x30\x28"
    assert pack(0x1FF) == b"\x31\xFF\x01"
    assert pack(0x1FFFFFF) == b"\x32\xFF\xFF\xFF\x01"
    assert pack(0x1FFFFFFFFFFFFFF) == b"\x33\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"
Beispiel #18
0
def test_pack_small_integers():
    assert pack(0) == b"\x08"
    assert pack(0xF) == b"\x17"
    assert pack(0x27) == b"\x2F"
Beispiel #19
0
def test_pack_absolute_time():
    with pytest.raises(NotImplementedError):
        pack(datetime.now())
Beispiel #20
0
def test_pack_unsupported_type():
    with pytest.raises(TypeError):
        pack(set())
Beispiel #21
0
def test_pack_short_raw_bytes():
    assert pack(b"\xac") == b"\x71\xac"
    assert pack(b"\x12\x34\x56") == b"\x73\x12\x34\x56"
    assert pack(0x20 * b"\xad") == b"\x90" + (0x20 * b"\xad")
Beispiel #22
0
def test_pack_float64():
    assert pack(1.0) == b"\x36\x00\x00\x00\x00\x00\x00\xF0\x3F"
Beispiel #23
0
def test_pack_none():
    assert pack(None) == b"\x04"