auth — Firmware authentication

Firmware 7.18+ challenge-response authentication.

Seestar firmware 7.18 introduced a mandatory RSA challenge-response handshake on port 4700. The telescope sends a random challenge string; the client must sign it with a private RSA key (SHA-1, PKCS#1 v1.5) and return the base64-encoded signature.

The private key is the same for all devices — it is embedded inside ZWO’s Android APK (libopenssllib.so) and can be extracted with the extract_pem.py script from the seestar-api-research repository.

Key discovery order:

  1. SEESTAR_KEY_PATH environment variable

  2. seestar.pem in the current working directory

  3. ~/.seestarpy/seestar.pem

If no key is found, authentication is silently skipped (backward-compatible with older firmware that does not require it).

Signing uses the cryptography library when available (pip install seestarpy[auth]), falling back to the openssl command-line tool.

Example:

# Option A — set env var and let seestarpy find it automatically:
#   export SEESTAR_KEY_PATH=/path/to/seestar.pem

# Option B — place the key where auto-discovery finds it:
#   cp seestar.pem ~/.seestarpy/seestar.pem

# Option C — set at runtime:
from seestarpy import auth
auth.set_key_path("/path/to/seestar.pem")
exception seestarpy.auth.AuthenticationError

Bases: Exception

Raised when telescope authentication fails.

seestarpy.auth.authenticate(sock, key_path=None)

Perform the 3-step auth handshake on a synchronous socket.

Parameters:
  • sock (socket.socket) – A connected TCP socket to the Seestar (port 4700).

  • key_path (str, optional) – Path to the PEM key file. Defaults to KEY_PATH.

Returns:

True if authentication succeeded or was not required.

Return type:

bool

Raises:

AuthenticationError – If the telescope rejects the client signature.

async seestarpy.auth.authenticate_async(reader, writer, key_path=None)

Perform the 3-step auth handshake on an async connection.

Parameters:
  • reader (asyncio.StreamReader)

  • writer (asyncio.StreamWriter)

  • key_path (str, optional) – Path to the PEM key file. Defaults to KEY_PATH.

Returns:

True if authentication succeeded or was not required.

Return type:

bool

Raises:

AuthenticationError – If the telescope rejects the client signature.

seestarpy.auth.set_key_path(path)

Override the RSA key path at runtime.

Parameters:

path (str or Path) – Absolute or relative path to the PEM private key file.

Raises:

FileNotFoundError – If path does not point to an existing file.

seestarpy.auth.sign_challenge(key_path, challenge)

Sign a challenge string with RSA-SHA1 and return a base64 signature.

Tries the cryptography library first, then falls back to the openssl command-line tool.

Parameters:
  • key_path (str) – Path to the PEM private key file.

  • challenge (str) – The challenge string received from the telescope.

Returns:

Base64-encoded RSA-SHA1 signature.

Return type:

str