Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

AES Transport creates the key even if the device is offline #675

Copy link
Copy link
@bdraco

Description

@bdraco
Issue body actions
Screenshot 2024-01-22 at 7 00 21 PM

suggested solution is https://docs.aiohttp.org/en/stable/client_quickstart.html#streaming-uploads

diff --git a/kasa/aestransport.py b/kasa/aestransport.py
index 65b0045..ca74cc6 100644
--- a/kasa/aestransport.py
+++ b/kasa/aestransport.py
@@ -8,7 +8,7 @@ import base64
 import hashlib
 import logging
 import time
-from typing import Dict, Optional, cast
+from typing import Dict, Optional, cast, TYPE_CHECKING
 
 from cryptography.hazmat.primitives import padding, serialization
 from cryptography.hazmat.primitives.asymmetric import padding as asymmetric_padding
@@ -86,6 +86,8 @@ class AesTransport(BaseTransport):
 
         self._login_token = None
 
+        self._key_pair: Optional[KeyPair] = None
+
         _LOGGER.debug("Created AES transport for %s", self._host)
 
     @property
@@ -185,33 +187,35 @@ class AesTransport(BaseTransport):
         self._handle_response_error_code(resp_dict, "Error logging in")
         self._login_token = resp_dict["result"]["token"]
 
+    async def _generate_request_body(self) -> str:
+        """Generate the request body."""
+        self._key_pair = KeyPair.create_key_pair()
+        pub_key = (
+            "-----BEGIN PUBLIC KEY-----\n"
+            + self._key_pair.get_public_key()
+            + "\n-----END PUBLIC KEY-----\n"
+        )
+        handshake_params = {"key": pub_key}
+        _LOGGER.debug(f"Handshake params: {handshake_params}")
+        request_body = {"method": "handshake", "params": handshake_params}
+        _LOGGER.debug(f"Request {request_body}")
+        return json_dumps(request_body)
+
     async def perform_handshake(self):
         """Perform the handshake."""
         _LOGGER.debug("Will perform handshaking...")
         _LOGGER.debug("Generating keypair")
 
+        self._key_pair = None
         self._handshake_done = False
         self._session_expire_at = None
         self._session_cookie = None
 
         url = f"http://{self._host}/app"
-        key_pair = KeyPair.create_key_pair()
-
-        pub_key = (
-            "-----BEGIN PUBLIC KEY-----\n"
-            + key_pair.get_public_key()
-            + "\n-----END PUBLIC KEY-----\n"
-        )
-        handshake_params = {"key": pub_key}
-        _LOGGER.debug(f"Handshake params: {handshake_params}")
-
-        request_body = {"method": "handshake", "params": handshake_params}
-
-        _LOGGER.debug(f"Request {request_body}")
 
         status_code, resp_dict = await self._http_client.post(
             url,
-            json=request_body,
+            data=self._generate_request_body(),
             headers=self.COMMON_HEADERS,
             cookies_dict=self._session_cookie,
         )
@@ -240,8 +244,10 @@ class AesTransport(BaseTransport):
             self._session_cookie = {self.SESSION_COOKIE_NAME: cookie}
 
         self._session_expire_at = time.time() + 86400
+        if TYPE_CHECKING:
+            assert self._key_pair is not None
         self._encryption_session = AesEncyptionSession.create_from_keypair(
-            handshake_key, key_pair
+            handshake_key, self._key_pair
         )
 
         self._handshake_done = True
Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.