summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_keystore.py
blob: b9dd3a453e56ab6c3e64f159b5c6d5ccf97f11b4 (plain) (blame)
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
"""Tests for meshbay_node.keystore."""

import sys

import pytest
from meshbay_common.crypto import generate_gek
from meshbay_node.keystore import (
    create_keystore,
    load_keystore,
    load_or_create_keystore,
    save_keystore,
)


def test_create_and_load(tmp_path):
    path = tmp_path / "keystore.enc"
    keys = create_keystore(path=path, password="testpass99")

    assert keys.sk_ed25519 is not None
    assert keys.sk_x25519 is not None
    assert keys.gek is None
    assert len(keys.pk_ed25519_b64) == 44   # 32 bytes → 44 base64 chars
    assert len(keys.pk_x25519_b64) == 44
    assert path.exists()
    if sys.platform != "win32":
        # NTFS ignores POSIX mode bits; chmod_private is a no-op there (W5).
        assert oct(path.stat().st_mode)[-3:] == "600"

    loaded = load_keystore(path=path, password="testpass99")
    assert loaded.pk_ed25519_b64 == keys.pk_ed25519_b64
    assert loaded.pk_x25519_b64  == keys.pk_x25519_b64
    assert loaded.gek is None


def test_wrong_password_rejected(tmp_path):
    path = tmp_path / "keystore.enc"
    create_keystore(path=path, password="correctpass")
    with pytest.raises(ValueError, match="Wrong password"):
        load_keystore(path=path, password="wrongpass")


def test_create_fails_if_exists(tmp_path):
    path = tmp_path / "keystore.enc"
    create_keystore(path=path, password="pass12345")
    with pytest.raises(FileExistsError):
        create_keystore(path=path, password="pass12345")


def test_load_fails_if_missing(tmp_path):
    with pytest.raises(FileNotFoundError):
        load_keystore(path=tmp_path / "nonexistent.enc", password="x")


def test_save_with_gek(tmp_path):
    path = tmp_path / "keystore.enc"
    keys = create_keystore(path=path, password="testpass99")
    gek = generate_gek()
    keys.gek = gek

    save_keystore(keys, path=path, password="testpass99")

    reloaded = load_keystore(path=path, password="testpass99")
    assert reloaded.gek == gek


def test_load_or_create_creates(tmp_path):
    path = tmp_path / "keystore.enc"
    keys = load_or_create_keystore(path=path, password="testpass99")
    assert keys.sk_ed25519 is not None
    assert path.exists()


def test_load_or_create_loads(tmp_path):
    path = tmp_path / "keystore.enc"
    k1 = load_or_create_keystore(path=path, password="testpass99")
    k2 = load_or_create_keystore(path=path, password="testpass99")
    assert k1.pk_ed25519_b64 == k2.pk_ed25519_b64


def test_keys_unique_per_creation(tmp_path):
    k1 = create_keystore(path=tmp_path / "k1.enc", password="p1234567")
    k2 = create_keystore(path=tmp_path / "k2.enc", password="p1234567")
    assert k1.pk_ed25519_b64 != k2.pk_ed25519_b64


def test_env_var_unlock(tmp_path, monkeypatch):
    path = tmp_path / "keystore.enc"
    create_keystore(path=path, password="envpass42")
    monkeypatch.setenv("MESHBAY_UNLOCK_KEY", "envpass42")
    keys = load_keystore(path=path)   # no password arg
    assert keys.sk_ed25519 is not None


def test_unlock_file(tmp_path):
    path    = tmp_path / "keystore.enc"
    kf_path = tmp_path / "unlock.key"
    kf_path.write_text("filepass42")
    kf_path.chmod(0o600)

    create_keystore(path=path, password="filepass42")
    keys = load_keystore(path=path, unlock_file=kf_path)   # no password arg
    assert keys.sk_ed25519 is not None