File size: 4,535 Bytes
c87f72b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
"""Tests for the titan security modules."""

from __future__ import annotations

import pytest

from titan import (
    FAISS_PARTITION_SEED,
    HardwareHandshake,
    DeviceAuthError,
    PacketValidationError,
    SignalNoiseFilter,
)
from titan.device_auth import HWID_ENV_VAR


class TestConstants:
    def test_faiss_partition_seed_value(self):
        assert FAISS_PARTITION_SEED == 9293

    def test_faiss_partition_seed_is_int(self):
        assert isinstance(FAISS_PARTITION_SEED, int)


class TestSignalNoiseFilter:
    def _good_packet(self, payload: str = "ok") -> dict:
        return {"device_id": "d1", "timestamp": 1, "payload": payload}

    def test_accepts_well_formed_packet(self):
        f = SignalNoiseFilter()
        assert f.is_valid(self._good_packet()) is True

    def test_rejects_non_mapping(self):
        f = SignalNoiseFilter()
        assert f.is_valid("not a dict") is False
        assert f.is_valid(None) is False

    def test_rejects_missing_field(self):
        f = SignalNoiseFilter()
        bad = self._good_packet()
        del bad["device_id"]
        assert f.is_valid(bad) is False

    def test_rejects_empty_field(self):
        f = SignalNoiseFilter()
        bad = self._good_packet()
        bad["device_id"] = ""
        assert f.is_valid(bad) is False

    def test_rejects_oversized_payload(self):
        f = SignalNoiseFilter(max_packet_bytes=4)
        assert f.is_valid(self._good_packet("12345")) is False

    def test_validate_raises_on_invalid(self):
        f = SignalNoiseFilter()
        with pytest.raises(PacketValidationError):
            f.validate({"device_id": "d"})

    def test_filter_stream_drops_and_counts(self):
        f = SignalNoiseFilter()
        packets = [
            self._good_packet("a"),
            {"device_id": "d"},       # missing fields
            self._good_packet("b"),
            "garbage",                 # not a mapping
        ]
        kept = list(f.filter_stream(packets))
        assert len(kept) == 2
        assert f.accepted_count == 2
        assert f.dropped_count == 2

    def test_rejects_non_positive_max(self):
        with pytest.raises(ValueError):
            SignalNoiseFilter(max_packet_bytes=0)


class TestHardwareHandshake:
    def test_requires_hwid(self, monkeypatch):
        monkeypatch.delenv(HWID_ENV_VAR, raising=False)
        with pytest.raises(DeviceAuthError):
            HardwareHandshake()

    def test_reads_hwid_from_env(self, monkeypatch):
        monkeypatch.setenv(HWID_ENV_VAR, "env-hwid")
        hs = HardwareHandshake()
        challenge = hs.generate_challenge()
        assert hs.verify(challenge, hs.sign(challenge))

    def test_sign_and_verify_roundtrip(self):
        hs = HardwareHandshake(hwid="secret-hwid")
        challenge = hs.generate_challenge(16)
        sig = hs.sign(challenge)
        assert isinstance(sig, str)
        assert hs.verify(challenge, sig) is True

    def test_verify_rejects_bad_signature(self):
        hs = HardwareHandshake(hwid="secret-hwid")
        challenge = hs.generate_challenge()
        assert hs.verify(challenge, "deadbeef") is False

    def test_verify_rejects_tampered_challenge(self):
        hs = HardwareHandshake(hwid="secret-hwid")
        challenge = hs.generate_challenge()
        sig = hs.sign(challenge)
        assert hs.verify(challenge + b"x", sig) is False

    def test_different_hwids_produce_different_signatures(self):
        a = HardwareHandshake(hwid="hwid-a")
        b = HardwareHandshake(hwid="hwid-b")
        challenge = b"same-challenge"
        assert a.sign(challenge) != b.sign(challenge)
        assert a.verify(challenge, b.sign(challenge)) is False

    def test_rejects_unsupported_algorithm(self):
        with pytest.raises(DeviceAuthError):
            HardwareHandshake(hwid="x", algorithm="definitely-not-real")

    def test_generate_challenge_length(self):
        hs = HardwareHandshake(hwid="x")
        assert len(hs.generate_challenge(24)) == 24

    def test_generate_challenge_rejects_non_positive(self):
        hs = HardwareHandshake(hwid="x")
        with pytest.raises(ValueError):
            hs.generate_challenge(0)

    def test_sign_rejects_non_bytes(self):
        hs = HardwareHandshake(hwid="x")
        with pytest.raises(TypeError):
            hs.sign("not-bytes")  # type: ignore[arg-type]

    def test_verify_rejects_non_string_signature(self):
        hs = HardwareHandshake(hwid="x")
        assert hs.verify(b"chal", 12345) is False  # type: ignore[arg-type]