From 67af32300208e80cc5bffb1bf0370feb05b16579 Mon Sep 17 00:00:00 2001 From: Simone Chemelli Date: Mon, 27 May 2024 18:33:16 +0000 Subject: [PATCH 1/2] chore: fix remaining typing --- midealocal/cloud.py | 14 +++++--------- midealocal/device.py | 2 +- midealocal/security.py | 10 +++++----- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/midealocal/cloud.py b/midealocal/cloud.py index 102cbda8..3692d311 100644 --- a/midealocal/cloud.py +++ b/midealocal/cloud.py @@ -97,7 +97,7 @@ def _make_general_data(self) -> dict[Any, Any]: return {} async def _api_request( - self, endpoint: str, data: dict, header: dict[Any, Any] | None = None + self, endpoint: str, data: dict[str, Any], header: dict[str, Any] | None = None ) -> dict | None: header = header or {} if not data.get("reqId"): @@ -249,7 +249,7 @@ async def login(self) -> bool: ): self._access_token = response["mdata"]["accessToken"] self._security.set_aes_keys( - self._security.aes_decrypt_with_fixed_key(response["key"]), None + self._security.aes_decrypt_with_fixed_key(response["key"]), b"0" ) return True @@ -319,11 +319,7 @@ async def get_device_info(self, device_id: str) -> dict[str, Any] | None: device_info = { "name": response.get("name"), "type": int(model_type, 16) if model_type else 0, - "sn": ( - self._security.aes_decrypt(response.get("sn")) - if response.get("sn") - else "" - ), + "sn": (self._security.aes_decrypt(response.get("sn") or "")), "sn8": response.get("sn8", "00000000"), "model_number": model_number, "manufacturer_code": response.get("enterpriseCode", "0000"), @@ -413,7 +409,7 @@ def _make_general_data(self) -> dict[str, Any]: } async def _api_request( - self, endpoint: str, data: dict, header: dict | None = None + self, endpoint: str, data: dict[str, Any], header: dict[str, Any] | None = None ) -> dict[str, Any] | None: header = header or {} header.update( @@ -582,7 +578,7 @@ def _make_general_data(self) -> dict[str, Any]: return data async def _api_request( - self, endpoint: str, data: dict, header: dict[str, Any] | None = None + self, endpoint: str, data: dict[str, Any], header: dict[str, Any] | None = None ) -> dict[str, Any] | None: header = header or {} if not data.get("reqId"): diff --git a/midealocal/device.py b/midealocal/device.py index e3309c25..a0bb2aa5 100644 --- a/midealocal/device.py +++ b/midealocal/device.py @@ -229,7 +229,7 @@ def refresh_status(self, wait_response: bool = False) -> None: if error_count == len(cmds): raise RefreshFailed - def pre_process_message(self, msg: bytes) -> bool: + def pre_process_message(self, msg: bytearray) -> bool: if msg[9] == MessageType.query_appliance: message = MessageApplianceResponse(msg) self._appliance_query = False diff --git a/midealocal/security.py b/midealocal/security.py index 9dff687b..dec181eb 100644 --- a/midealocal/security.py +++ b/midealocal/security.py @@ -33,9 +33,9 @@ def __init__( self._fixed_key = format(fixed_key, "x").encode("ascii") if fixed_key else None self._fixed_iv = format(fixed_iv, "x").encode("ascii") if fixed_iv else None - def sign(self, url: str, data: str, random: str) -> str | None: + def sign(self, url: str, data: dict[str, Any] | str, random: str) -> str | None: msg: str = self._iot_key or "" - msg += data + msg += str(data) msg += random if not self._hmac_key: return None @@ -80,7 +80,7 @@ def set_aes_keys(self, key: bytes | str, iv: bytes | str) -> None: self._aes_key = key self._aes_iv = iv - def aes_encrypt_with_fixed_key(self, data: str) -> bytes: + def aes_encrypt_with_fixed_key(self, data: bytes) -> bytes: return self.aes_encrypt(data, self._fixed_key, self._fixed_iv) def aes_decrypt_with_fixed_key(self, data: str) -> str: @@ -205,10 +205,10 @@ def __init__(self) -> None: self._request_count = 0 self._response_count = 0 - def aes_decrypt(self, raw: bytes) -> bytes: + def aes_decrypt(self, raw: bytes) -> bytearray: try: return cast( - bytes, + bytearray, unpad(AES.new(self.aes_key, AES.MODE_ECB).decrypt(bytearray(raw)), 16), ) except ValueError: From a907e6558eb2b9a2cda8baab4394e32f5e804d4e Mon Sep 17 00:00:00 2001 From: Simone Chemelli Date: Tue, 28 May 2024 09:54:01 +0000 Subject: [PATCH 2/2] chore: fix logic after typing --- midealocal/security.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/midealocal/security.py b/midealocal/security.py index dec181eb..e207f190 100644 --- a/midealocal/security.py +++ b/midealocal/security.py @@ -89,6 +89,8 @@ def aes_decrypt_with_fixed_key(self, data: str) -> str: def aes_encrypt( self, data: str | bytes, key: bytes | None = None, iv: bytes | None = None ) -> bytes: + if len(data) == 0: + return b"" if key is not None: aes_key = key aes_iv = iv @@ -99,7 +101,7 @@ def aes_encrypt( raise ValueError("Encrypt need a key") if isinstance(data, str): data = bytes.fromhex(data) - if aes_iv is None: # ECB + if aes_iv is None or aes_iv == b"0": # ECB return cast(bytes, AES.new(aes_key, AES.MODE_ECB).encrypt(pad(data, 16))) # CBC return cast( @@ -109,6 +111,8 @@ def aes_encrypt( def aes_decrypt( self, data: str | bytes, key: bytes | None = None, iv: bytes | None = None ) -> str: + if len(data) == 0: + return "" if key is not None: aes_key = key aes_iv = iv @@ -119,7 +123,7 @@ def aes_decrypt( raise ValueError("Encrypt need a key") if isinstance(data, str): data = bytes.fromhex(data) - if aes_iv is None: # ECB + if aes_iv is None or aes_iv == b"0": # ECB return cast( str, unpad(