130 lines
3.5 KiB
Python
Executable File
130 lines
3.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Utility to retrieve Ed25519 signing public key for client configuration.
|
|
|
|
This script outputs the public key in base64 format for adding to
|
|
SignatureVerificationService.ts on the client side.
|
|
|
|
Usage:
|
|
python get_signing_key.py
|
|
"""
|
|
|
|
# Standard library imports
|
|
import base64
|
|
import os
|
|
import sys
|
|
from typing import Tuple
|
|
|
|
# Third-party imports
|
|
from cryptography.hazmat.backends import default_backend
|
|
from cryptography.hazmat.primitives import serialization
|
|
|
|
|
|
def get_signing_public_key() -> Tuple[str, str]:
|
|
"""Read signing public key from file.
|
|
|
|
Returns:
|
|
Tuple of (PEM format string, base64 encoded string).
|
|
|
|
Raises:
|
|
SystemExit: If key file not found or failed to load.
|
|
"""
|
|
key_file = os.getenv(
|
|
"ED25519_SIGNING_KEY_PATH", "/app/secrets/ed25519_signing_key.pem"
|
|
)
|
|
|
|
if not os.path.exists(key_file):
|
|
print(
|
|
f"ERROR: Signing key file not found: {key_file}",
|
|
file=sys.stderr,
|
|
)
|
|
print("", file=sys.stderr)
|
|
print("SOLUTION:", file=sys.stderr)
|
|
print(
|
|
"1. Start the API server first to generate the key:",
|
|
file=sys.stderr,
|
|
)
|
|
print(
|
|
" docker-compose up remote_access_api",
|
|
file=sys.stderr,
|
|
)
|
|
print(
|
|
"2. Or run this script inside the container:",
|
|
file=sys.stderr,
|
|
)
|
|
print(
|
|
" docker-compose exec remote_access_api python get_signing_key.py",
|
|
file=sys.stderr,
|
|
)
|
|
sys.exit(1)
|
|
|
|
try:
|
|
with open(key_file, "rb") as f:
|
|
private_key_pem = f.read()
|
|
|
|
private_key = serialization.load_pem_private_key(
|
|
private_key_pem, password=None, backend=default_backend()
|
|
)
|
|
|
|
public_key = private_key.public_key()
|
|
|
|
public_key_pem = public_key.public_bytes(
|
|
encoding=serialization.Encoding.PEM,
|
|
format=serialization.PublicFormat.SubjectPublicKeyInfo,
|
|
)
|
|
|
|
public_key_b64 = base64.b64encode(public_key_pem).decode("utf-8")
|
|
|
|
return public_key_pem.decode("utf-8"), public_key_b64
|
|
|
|
except Exception as e:
|
|
print(
|
|
f"ERROR: Failed to load signing key: {e}",
|
|
file=sys.stderr,
|
|
)
|
|
sys.exit(1)
|
|
|
|
|
|
def main() -> None:
|
|
"""Main function to display signing public key."""
|
|
print("=" * 80)
|
|
print("Ed25519 Signing Public Key for Client Configuration")
|
|
print("=" * 80)
|
|
print("")
|
|
|
|
pem, base64_encoded = get_signing_public_key()
|
|
|
|
print("PEM Format:")
|
|
print(pem)
|
|
|
|
print("Base64 Encoded (for client configuration):")
|
|
print(base64_encoded)
|
|
print("")
|
|
|
|
print("=" * 80)
|
|
print("How to use:")
|
|
print("=" * 80)
|
|
print("")
|
|
print("1. Copy the Base64 encoded key above")
|
|
print("")
|
|
print(
|
|
"2. Update MachineControlCenter/src/renderer/services/SignatureVerificationService.ts:"
|
|
)
|
|
print("")
|
|
print(" const TRUSTED_SIGNING_KEYS: Record<Environment, string> = {")
|
|
print(f" production: '{base64_encoded}',")
|
|
print(f" development: '{base64_encoded}',")
|
|
print(f" local: '{base64_encoded}'")
|
|
print(" };")
|
|
print("")
|
|
print("3. Rebuild the client application:")
|
|
print(" cd MachineControlCenter")
|
|
print(" npm run build")
|
|
print("")
|
|
print("=" * 80)
|
|
print("")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|