mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-08 15:28:44 +00:00
@@ -78,6 +78,7 @@ bash -c "$(curl -sSL https://raw.githubusercontent.com/PR0M3TH3AN/SeedPass/main/
|
||||
```powershell
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; $scriptContent = (New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/PR0M3TH3AN/SeedPass/main/scripts/install.ps1'); & ([scriptblock]::create($scriptContent))
|
||||
```
|
||||
The Windows installer will attempt to install Git automatically if it is not already available.
|
||||
*Install the beta branch:*
|
||||
```powershell
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; $scriptContent = (New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/PR0M3TH3AN/SeedPass/main/scripts/install.ps1'); & ([scriptblock]::create($scriptContent)) -Branch beta
|
||||
|
@@ -32,7 +32,19 @@ function Write-Error {
|
||||
# 1. Check for prerequisites
|
||||
Write-Info "Installing SeedPass from branch: '$Branch'"
|
||||
Write-Info "Checking for prerequisites..."
|
||||
if (-not (Get-Command git -ErrorAction SilentlyContinue)) { Write-Error "Git is not installed. Please install it from https://git-scm.com/ and ensure it's in your PATH." }
|
||||
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
|
||||
Write-Warning "Git is not installed. Attempting to install..."
|
||||
if (Get-Command winget -ErrorAction SilentlyContinue) {
|
||||
try { winget install --id Git.Git -e --source winget -h } catch { Write-Error "Failed to install Git via winget. Error: $_" }
|
||||
} elseif (Get-Command choco -ErrorAction SilentlyContinue) {
|
||||
try { choco install git -y } catch { Write-Error "Failed to install Git via Chocolatey. Error: $_" }
|
||||
} elseif (Get-Command scoop -ErrorAction SilentlyContinue) {
|
||||
try { scoop install git } catch { Write-Error "Failed to install Git via Scoop. Error: $_" }
|
||||
} else {
|
||||
Write-Error "Git is not installed. Please install it from https://git-scm.com/ and ensure it's in your PATH."
|
||||
}
|
||||
if (-not (Get-Command git -ErrorAction SilentlyContinue)) { Write-Error "Git installation failed or git not found in PATH after installation." }
|
||||
}
|
||||
$pythonExe = Get-Command python -ErrorAction SilentlyContinue
|
||||
if (-not $pythonExe) { Write-Error "Python 3 is not installed or not in your PATH. Please install it from https://www.python.org/" }
|
||||
|
||||
|
@@ -57,7 +57,21 @@ main() {
|
||||
|
||||
# 2. Check for prerequisites
|
||||
print_info "Checking for prerequisites (git, python3, pip)..."
|
||||
if ! command -v git &> /dev/null; then print_error "Git is not installed. Please install it."; fi
|
||||
if ! command -v git &> /dev/null; then
|
||||
print_warning "Git is not installed. Attempting to install..."
|
||||
if [ "$OS_NAME" = "Linux" ]; then
|
||||
if command -v apt-get &> /dev/null; then sudo apt-get update && sudo apt-get install -y git;
|
||||
elif command -v dnf &> /dev/null; then sudo dnf install -y git;
|
||||
elif command -v pacman &> /dev/null; then sudo pacman -Syu --noconfirm git;
|
||||
else print_error "Git is not installed and automatic installation is not supported on this system."; fi
|
||||
elif [ "$OS_NAME" = "Darwin" ]; then
|
||||
if command -v brew &> /dev/null; then brew install git;
|
||||
else print_error "Git is not installed and Homebrew was not found. Please install Git manually."; fi
|
||||
else
|
||||
print_error "Git is not installed. Please install it."
|
||||
fi
|
||||
if ! command -v git &> /dev/null; then print_error "Git installation failed or git not found in PATH."; fi
|
||||
fi
|
||||
if ! command -v python3 &> /dev/null; then print_error "Python 3 is not installed. Please install it."; fi
|
||||
if ! python3 -m ensurepip --default-pip &> /dev/null && ! command -v pip3 &> /dev/null; then print_error "pip for Python 3 is not available. Please install it."; fi
|
||||
if ! python3 -c "import venv" &> /dev/null; then
|
||||
|
@@ -14,6 +14,7 @@ import json
|
||||
import logging
|
||||
import getpass
|
||||
import os
|
||||
import hashlib
|
||||
from typing import Optional
|
||||
import shutil
|
||||
import time
|
||||
@@ -2267,7 +2268,8 @@ class PasswordManager:
|
||||
|
||||
# Schema version and checksum status
|
||||
stats["schema_version"] = data.get("schema_version")
|
||||
current_checksum = json_checksum(data)
|
||||
json_content = json.dumps(data, indent=4)
|
||||
current_checksum = hashlib.sha256(json_content.encode("utf-8")).hexdigest()
|
||||
chk_path = self.entry_manager.checksum_file
|
||||
if chk_path.exists():
|
||||
stored = chk_path.read_text().strip()
|
||||
|
@@ -4,6 +4,8 @@ from tempfile import TemporaryDirectory
|
||||
|
||||
from helpers import create_vault, TEST_SEED, TEST_PASSWORD
|
||||
|
||||
from nostr.coincurve_keys import Keys
|
||||
|
||||
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
||||
|
||||
from password_manager.entry_management import EntryManager
|
||||
@@ -36,3 +38,11 @@ def test_nostr_key_determinism():
|
||||
assert nsec1 == nsec2
|
||||
assert npub1.startswith("npub")
|
||||
assert nsec1.startswith("nsec")
|
||||
|
||||
priv_hex = Keys.bech32_to_hex(nsec1)
|
||||
derived = Keys(priv_k=priv_hex)
|
||||
encoded_npub = Keys.hex_to_bech32(derived.public_key_hex(), "npub")
|
||||
assert encoded_npub == npub1
|
||||
|
||||
data = enc_mgr.load_json_data(entry_mgr.index_file)
|
||||
assert data["entries"][str(idx)]["label"] == "main"
|
||||
|
@@ -25,3 +25,15 @@ def test_pgp_key_determinism():
|
||||
|
||||
assert fp1 == fp2
|
||||
assert key1 == key2
|
||||
|
||||
# parse returned armored key and verify fingerprint
|
||||
from pgpy import PGPKey
|
||||
|
||||
parsed_key, _ = PGPKey.from_blob(key1)
|
||||
assert parsed_key.fingerprint == fp1
|
||||
|
||||
# ensure the index file stores key_type and user_id
|
||||
data = enc_mgr.load_json_data(entry_mgr.index_file)
|
||||
entry = data["entries"][str(idx)]
|
||||
assert entry["key_type"] == "ed25519"
|
||||
assert entry["user_id"] == "Test"
|
||||
|
@@ -3,6 +3,7 @@ from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
from helpers import create_vault, TEST_SEED, TEST_PASSWORD
|
||||
from mnemonic import Mnemonic
|
||||
|
||||
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
||||
|
||||
@@ -30,6 +31,9 @@ def test_seed_phrase_determinism():
|
||||
phrase24_a = entry_mgr.get_seed_phrase(idx_24, TEST_SEED)
|
||||
phrase24_b = entry_mgr.get_seed_phrase(idx_24, TEST_SEED)
|
||||
|
||||
entry12 = entry_mgr.retrieve_entry(idx_12)
|
||||
entry24 = entry_mgr.retrieve_entry(idx_24)
|
||||
|
||||
seed_bytes = Bip39SeedGenerator(TEST_SEED).Generate()
|
||||
bip85 = BIP85(seed_bytes)
|
||||
expected12 = derive_seed_phrase(bip85, idx_12, 12)
|
||||
@@ -39,3 +43,7 @@ def test_seed_phrase_determinism():
|
||||
assert phrase24_a == phrase24_b == expected24
|
||||
assert len(phrase12_a.split()) == 12
|
||||
assert len(phrase24_a.split()) == 24
|
||||
assert Mnemonic("english").check(phrase12_a)
|
||||
assert Mnemonic("english").check(phrase24_a)
|
||||
assert entry12.get("words") == 12
|
||||
assert entry24.get("words") == 24
|
||||
|
40
src/tests/test_ssh_entry_valid.py
Normal file
40
src/tests/test_ssh_entry_valid.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
from helpers import create_vault, TEST_SEED, TEST_PASSWORD
|
||||
|
||||
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
||||
|
||||
from password_manager.entry_management import EntryManager
|
||||
from password_manager.backup import BackupManager
|
||||
from password_manager.vault import Vault
|
||||
from password_manager.config_manager import ConfigManager
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
|
||||
|
||||
def test_ssh_private_key_corresponds_to_public():
|
||||
with TemporaryDirectory() as tmpdir:
|
||||
tmp_path = Path(tmpdir)
|
||||
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
||||
cfg_mgr = ConfigManager(vault, tmp_path)
|
||||
backup_mgr = BackupManager(tmp_path, cfg_mgr)
|
||||
entry_mgr = EntryManager(vault, backup_mgr)
|
||||
|
||||
idx = entry_mgr.add_ssh_key(TEST_SEED)
|
||||
priv_pem, pub_pem = entry_mgr.get_ssh_key_pair(idx, TEST_SEED)
|
||||
|
||||
priv_key = serialization.load_pem_private_key(
|
||||
priv_pem.encode(),
|
||||
password=None,
|
||||
)
|
||||
derived_pub_pem = (
|
||||
priv_key.public_key()
|
||||
.public_bytes(
|
||||
serialization.Encoding.PEM,
|
||||
serialization.PublicFormat.SubjectPublicKeyInfo,
|
||||
)
|
||||
.decode()
|
||||
)
|
||||
|
||||
assert derived_pub_pem == pub_pem
|
Reference in New Issue
Block a user