with figerprint match option when encryption with asc file, extra assurance the file is the target asc file

This commit is contained in:
LC mac
2026-01-07 02:21:03 +08:00
parent 875fa17d6c
commit d02e1d872e

View File

@@ -251,6 +251,19 @@ def interactive_mnemonic_word_by_word() -> str:
# -----------------------------------------------------------------------------
# Fingerprint
# -----------------------------------------------------------------------------
def normalize_fpr(s: str) -> str:
s = (s or "").strip().replace(" ", "").replace(":", "").replace("-", "")
if s.lower().startswith("0x"):
s = s[2:]
return s.upper()
def require_fingerprint_match(actual_fpr: str, expected_fpr: str, context: str) -> None:
a = normalize_fpr(actual_fpr)
e = normalize_fpr(expected_fpr)
if not e:
return
if a != e:
raise ValueError(f"{context}: PGP fingerprint mismatch (expected {e}, got {a})")
def get_master_fingerprint(seed_bytes: bytes) -> str:
@@ -315,12 +328,20 @@ def sha256_hex_bytes(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def cmd_fetchkey(url: str, out_path: Optional[str], timeout: int, off_screen: bool) -> None:
def cmd_fetchkey(
url: str,
out_path: Optional[str],
timeout: int,
off_screen: bool,
expected_fingerprint: str = "",
) -> None:
require_for_fetchkey()
armored, raw = fetch_ascii_armored_text(url, timeout=timeout)
s256 = sha256_hex_bytes(raw)
fpr = pgp_fingerprint(armored)
require_fingerprint_match(fpr, expected_fingerprint, "fetchkey")
temp_file = None
if off_screen:
@@ -699,7 +720,8 @@ def cmd_gen(args) -> None:
if is_pgp:
with open(args.pgp_pubkey_file, "r", encoding="utf-8") as f:
pub = f.read()
fpr = pgp_fingerprint(pub)
require_fingerprint_match(fpr, args.expected_fingerprint, "encrypt(gen)")
payload = build_payload_gen(
mnemonic=mnemonic,
passphrase_used=bool(passphrase),
@@ -802,7 +824,11 @@ def cmd_recover(args) -> None:
if is_pgp:
with open(args.pgp_pubkey_file, "r", encoding="utf-8") as f:
pub = f.read()
fpr = pgp_fingerprint(pub)
require_fingerprint_match(fpr, args.expected_fingerprint, "encrypt(gen)")
fpr = pgp_fingerprint(pub)
require_fingerprint_match(fpr, args.expected_fingerprint, "encrypt")
payload = build_payload_recover(
fp=fp,
sol_profile=args.sol_profile,
@@ -902,6 +928,8 @@ def build_parser() -> argparse.ArgumentParser:
action="store_true",
help="Enable off-screen mode: no printing of sensitive data to stdout.",
)
p_fetch.add_argument("--expected-fingerprint", default="", help="Refuse if downloaded key fingerprint does not match (40 hex chars).")
def add_common(p: argparse.ArgumentParser) -> None:
p.add_argument("--force", action="store_true", help="Allow printing sensitive output even when stdout is not a TTY (dangerous).")
@@ -914,6 +942,7 @@ def build_parser() -> argparse.ArgumentParser:
p.add_argument("--pgp-pubkey-file", default=None)
p.add_argument("--pgp-ignore-usage-flags", action="store_true")
p.add_argument("--expected-fingerprint", default="", help="Refuse if PGP recipient key fingerprint does not match.")
p.add_argument(
"--sol-profile",
@@ -970,7 +999,7 @@ def main() -> None:
try:
if args.cmd == "fetchkey":
cmd_fetchkey(args.url, args.out, args.timeout, args.off_screen)
cmd_fetchkey(args.url, args.out, args.timeout, args.off_screen, args.expected_fingerprint)
return
if args.cmd == "gen":
cmd_gen(args)