88 lines
2.8 KiB
Python
88 lines
2.8 KiB
Python
from __future__ import annotations
|
|
|
|
import io
|
|
import tarfile
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
import k1link.device_plugins.xgrids_k1.firmware_credential as firmware_credential
|
|
|
|
FIXTURE_SECRET = b"fixture-only-network-secret"
|
|
|
|
|
|
def _tar_gz_member(name: str, payload: bytes) -> bytes:
|
|
output = io.BytesIO()
|
|
with tarfile.open(fileobj=output, mode="w:gz") as archive:
|
|
member = tarfile.TarInfo(name)
|
|
member.size = len(payload)
|
|
archive.addfile(member, io.BytesIO(payload))
|
|
return output.getvalue()
|
|
|
|
|
|
def test_exact_official_archive_extracts_one_bounded_declaration(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
prefix = b"synthetic-rk-prefix"
|
|
apps = (
|
|
b"\x00" * 17
|
|
+ firmware_credential._AP_PSK_DECLARATION
|
|
+ FIXTURE_SECRET
|
|
+ b"\n"
|
|
+ b"\x00" * 31
|
|
)
|
|
image = prefix + apps
|
|
upgrade = _tar_gz_member(firmware_credential.K1_FW302_RK_IMAGE_MEMBER, image)
|
|
outer = _tar_gz_member(firmware_credential.K1_FW302_OUTER_MEMBER, upgrade)
|
|
archive_path = tmp_path / "official-fw.tar"
|
|
archive_path.write_bytes(outer)
|
|
|
|
monkeypatch.setattr(firmware_credential, "K1_FW302_APPS_OFFSET", len(prefix))
|
|
monkeypatch.setattr(firmware_credential, "K1_FW302_APPS_SIZE", len(apps))
|
|
monkeypatch.setattr(
|
|
firmware_credential,
|
|
"_sha256",
|
|
lambda _path: firmware_credential.K1_FW302_OFFICIAL_ARCHIVE_SHA256,
|
|
)
|
|
|
|
secret, digest = firmware_credential.extract_k1_fw302_ap_credential(archive_path)
|
|
try:
|
|
assert secret.reveal_ascii() == FIXTURE_SECRET.decode("ascii")
|
|
assert FIXTURE_SECRET.decode("ascii") not in repr(secret)
|
|
assert digest == firmware_credential.K1_FW302_OFFICIAL_ARCHIVE_SHA256
|
|
finally:
|
|
secret.zeroize()
|
|
|
|
|
|
def test_archive_hash_mismatch_stops_before_unpack(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
archive_path = tmp_path / "wrong-fw.tar"
|
|
archive_path.write_bytes(b"not-reviewed")
|
|
monkeypatch.setattr(firmware_credential, "_sha256", lambda _path: "0" * 64)
|
|
|
|
with pytest.raises(
|
|
firmware_credential.FirmwareCredentialError,
|
|
match="SHA-256",
|
|
):
|
|
firmware_credential.extract_k1_fw302_ap_credential(archive_path)
|
|
|
|
|
|
def test_duplicate_declarations_fail_closed_without_exposing_values() -> None:
|
|
payload = b"\n".join(
|
|
[
|
|
firmware_credential._AP_PSK_DECLARATION + FIXTURE_SECRET,
|
|
firmware_credential._AP_PSK_DECLARATION + b"second-fixture-secret",
|
|
]
|
|
) + b"\n"
|
|
|
|
with pytest.raises(
|
|
firmware_credential.FirmwareCredentialError,
|
|
match="not unique",
|
|
) as raised:
|
|
firmware_credential._credential_from_chunks(iter([payload]))
|
|
|
|
assert FIXTURE_SECRET.decode("ascii") not in str(raised.value)
|