예제 #1
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()
예제 #2
0
파일: hap_srp.py 프로젝트: NebzHB/pyatv
    def step4(self, encrypted_data):
        """Last pairing step."""
        chacha = chacha20.Chacha20Cipher(self._session_key, self._session_key)
        decrypted_tlv_bytes = chacha.decrypt(encrypted_data, nounce="PS-Msg06".encode())

        if not decrypted_tlv_bytes:
            raise exceptions.AuthenticationError("data decrypt failed")

        decrypted_tlv = hap_tlv8.read_tlv(decrypted_tlv_bytes)
        _LOGGER.debug("PS-Msg06: %s", decrypted_tlv)

        atv_identifier = decrypted_tlv[TlvValue.Identifier]
        atv_signature = decrypted_tlv[TlvValue.Signature]
        atv_pub_key = decrypted_tlv[TlvValue.PublicKey]
        log_binary(
            _LOGGER,
            "Device",
            Identifier=atv_identifier,
            Signature=atv_signature,
            Public=atv_pub_key,
        )

        # TODO: verify signature here

        return HapCredentials(
            atv_pub_key, self._auth_private, atv_identifier, self.pairing_id
        )
예제 #3
0
파일: hap_srp.py 프로젝트: NebzHB/pyatv
    def step3(self, additional_data=None):
        """Third pairing step."""
        ios_device_x = hkdf_expand(
            "Pair-Setup-Controller-Sign-Salt",
            "Pair-Setup-Controller-Sign-Info",
            binascii.unhexlify(self._session.key),
        )

        self._session_key = hkdf_expand(
            "Pair-Setup-Encrypt-Salt",
            "Pair-Setup-Encrypt-Info",
            binascii.unhexlify(self._session.key),
        )

        device_info = ios_device_x + self.pairing_id + self._auth_public
        device_signature = self._signing_key.sign(device_info)

        tlv = {
            TlvValue.Identifier: self.pairing_id,
            TlvValue.PublicKey: self._auth_public,
            TlvValue.Signature: device_signature,
        }

        if additional_data:
            tlv.update(additional_data)

        chacha = chacha20.Chacha20Cipher(self._session_key, self._session_key)
        encrypted_data = chacha.encrypt(
            hap_tlv8.write_tlv(tlv), nounce="PS-Msg05".encode()
        )
        log_binary(_LOGGER, "Data", Encrypted=encrypted_data)
        return encrypted_data
예제 #4
0
    def _m5_setup(self, _):
        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),
        )

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

        tlv = write_tlv({
            TlvValue.Identifier: self.unique_id,
            TlvValue.PublicKey: self.keys.auth_pub,
            TlvValue.Signature: signature,
        })

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

        msg = messages.crypto_pairing({
            TlvValue.SeqNo: b"\x06",
            TlvValue.EncryptedData: encrypted
        })
        self.has_paired = True

        self.send_to_client(msg)
예제 #5
0
파일: hap_srp.py 프로젝트: NebzHB/pyatv
    def verify1(self, credentials, session_pub_key, encrypted):
        """First verification step."""
        self._shared = self._verify_private.exchange(
            X25519PublicKey.from_public_bytes(session_pub_key)
        )

        session_key = hkdf_expand(
            "Pair-Verify-Encrypt-Salt", "Pair-Verify-Encrypt-Info", self._shared
        )

        chacha = chacha20.Chacha20Cipher(session_key, session_key)
        decrypted_tlv = hap_tlv8.read_tlv(
            chacha.decrypt(encrypted, nounce="PV-Msg02".encode())
        )

        identifier = decrypted_tlv[TlvValue.Identifier]
        signature = decrypted_tlv[TlvValue.Signature]

        if identifier != credentials.atv_id:
            raise exceptions.AuthenticationError("incorrect device response")

        info = session_pub_key + bytes(identifier) + self._public_bytes
        ltpk = Ed25519PublicKey.from_public_bytes(bytes(credentials.ltpk))

        try:
            ltpk.verify(bytes(signature), bytes(info))
        except InvalidSignature as ex:
            raise exceptions.AuthenticationError("signature error") from ex

        device_info = self._public_bytes + credentials.client_id + session_pub_key

        device_signature = Ed25519PrivateKey.from_private_bytes(credentials.ltsk).sign(
            device_info
        )

        tlv = hap_tlv8.write_tlv(
            {
                TlvValue.Identifier: credentials.client_id,
                TlvValue.Signature: device_signature,
            }
        )

        return chacha.encrypt(tlv, nounce="PV-Msg03".encode())
예제 #6
0
    def _m1_verify(self, pairing_data):
        server_pub_key = self.keys.verify_pub.public_bytes(
            encoding=serialization.Encoding.Raw,
            format=serialization.PublicFormat.Raw)
        client_pub_key = pairing_data[TlvValue.PublicKey]

        shared_key = self.keys.verify.exchange(
            X25519PublicKey.from_public_bytes(client_pub_key))

        session_key = hkdf_expand("Pair-Verify-Encrypt-Salt",
                                  "Pair-Verify-Encrypt-Info", shared_key)

        info = server_pub_key + self.unique_id + client_pub_key
        signature = self.keys.sign.sign(info)

        tlv = write_tlv({
            TlvValue.Identifier: self.unique_id,
            TlvValue.Signature: signature
        })

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

        msg = messages.crypto_pairing({
            TlvValue.SeqNo: b"\x02",
            TlvValue.PublicKey: server_pub_key,
            TlvValue.EncryptedData: encrypted,
        })

        self.output_key = hkdf_expand("MediaRemote-Salt",
                                      "MediaRemote-Write-Encryption-Key",
                                      shared_key)

        self.input_key = hkdf_expand("MediaRemote-Salt",
                                     "MediaRemote-Read-Encryption-Key",
                                     shared_key)

        log_binary(_LOGGER,
                   "Keys",
                   Output=self.output_key,
                   Input=self.input_key)
        self.send_to_client(msg)
예제 #7
0
 def enable_encryption(self, output_key: bytes, input_key: bytes) -> None:
     """Enable encryption with the specified keys."""
     self._chacha = chacha20.Chacha20Cipher(output_key,
                                            input_key,
                                            nonce_length=12)
예제 #8
0
파일: connection.py 프로젝트: NebzHB/pyatv
 def enable_encryption(self, output_key, input_key):
     """Enable encryption with the specified keys."""
     self._chacha = chacha20.Chacha20Cipher(output_key, input_key)
예제 #9
0
파일: mrp.py 프로젝트: postlund/pyatv
 def enable_encryption(self, output_key: bytes, input_key: bytes) -> None:
     """Enable encryption with specified keys."""
     self.chacha = chacha20.Chacha20Cipher(output_key, input_key)
     self.state.has_authenticated = True
예제 #10
0
파일: atvproxy.py 프로젝트: postlund/pyatv
 def enable_encryption(self, output_key: bytes, input_key: bytes) -> None:
     """Enable encryption with specified keys."""
     self.chacha = chacha20.Chacha20Cipher(output_key, input_key)