Harden M9: Ed25519 attestation, full SHA-256 integrity, locked-by-default, prompt improvements, registry verification
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
"""Local publisher signing-key storage."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from .attestation import generate_keypair
|
||||
from .config import CONFIG_DIR
|
||||
|
||||
SIGNING_KEY_FILE = CONFIG_DIR / "release-signing-key.json"
|
||||
|
||||
|
||||
def load_signing_key(path: Path = SIGNING_KEY_FILE) -> Optional[Tuple[str, str]]:
|
||||
if not path.exists():
|
||||
return None
|
||||
data = json.loads(path.read_text(encoding="utf-8"))
|
||||
private_key = data.get("private_key", "")
|
||||
public_key = data.get("public_key", "")
|
||||
if not private_key or not public_key:
|
||||
raise ValueError("Signing key file is incomplete")
|
||||
return private_key, public_key
|
||||
|
||||
|
||||
def initialize_signing_key(
|
||||
path: Path = SIGNING_KEY_FILE, *, overwrite: bool = False
|
||||
) -> Tuple[str, str]:
|
||||
if path.exists() and not overwrite:
|
||||
existing = load_signing_key(path)
|
||||
if existing is None:
|
||||
raise ValueError("Signing key file could not be loaded")
|
||||
return existing
|
||||
private_key, public_key = generate_keypair()
|
||||
path.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
|
||||
path.write_text(json.dumps({
|
||||
"algorithm": "ed25519",
|
||||
"private_key": private_key,
|
||||
"public_key": public_key,
|
||||
}, indent=2) + "\n", encoding="utf-8")
|
||||
os.chmod(path, 0o600)
|
||||
return private_key, public_key
|
||||
Reference in New Issue
Block a user