Fix TLS noise and relocate server key material

This commit is contained in:
2025-10-17 20:06:19 -06:00
parent 43967e758d
commit ce0acd036c
3 changed files with 84 additions and 5 deletions

View File

@@ -7,7 +7,6 @@ from __future__ import annotations
import hashlib import hashlib
import time import time
from datetime import datetime, timezone from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
import jwt import jwt
@@ -16,8 +15,9 @@ from cryptography.hazmat.primitives.asymmetric import ed25519
from Modules.runtime import ensure_runtime_dir, runtime_path from Modules.runtime import ensure_runtime_dir, runtime_path
_KEY_DIR = runtime_path("keys") _KEY_DIR = runtime_path("auth_keys")
_KEY_FILE = _KEY_DIR / "borealis-jwt-ed25519.key" _KEY_FILE = _KEY_DIR / "borealis-jwt-ed25519.key"
_LEGACY_KEY_FILE = runtime_path("keys") / "borealis-jwt-ed25519.key"
class JWTService: class JWTService:
@@ -98,11 +98,17 @@ def load_service() -> JWTService:
def _load_or_create_private_key() -> ed25519.Ed25519PrivateKey: def _load_or_create_private_key() -> ed25519.Ed25519PrivateKey:
ensure_runtime_dir("keys") ensure_runtime_dir("auth_keys")
_migrate_legacy_key_if_present()
if _KEY_FILE.exists(): if _KEY_FILE.exists():
with _KEY_FILE.open("rb") as fh: with _KEY_FILE.open("rb") as fh:
return serialization.load_pem_private_key(fh.read(), password=None) return serialization.load_pem_private_key(fh.read(), password=None)
if _LEGACY_KEY_FILE.exists():
with _LEGACY_KEY_FILE.open("rb") as fh:
return serialization.load_pem_private_key(fh.read(), password=None)
private_key = ed25519.Ed25519PrivateKey.generate() private_key = ed25519.Ed25519PrivateKey.generate()
pem = private_key.private_bytes( pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM, encoding=serialization.Encoding.PEM,
@@ -118,3 +124,17 @@ def _load_or_create_private_key() -> ed25519.Ed25519PrivateKey:
pass pass
return private_key return private_key
def _migrate_legacy_key_if_present() -> None:
if not _LEGACY_KEY_FILE.exists() or _KEY_FILE.exists():
return
try:
ensure_runtime_dir("auth_keys")
try:
_LEGACY_KEY_FILE.replace(_KEY_FILE)
except Exception:
_KEY_FILE.write_bytes(_LEGACY_KEY_FILE.read_bytes())
except Exception:
return

View File

@@ -14,9 +14,11 @@ from Modules.runtime import ensure_runtime_dir, runtime_path
from .keys import base64_from_spki_der from .keys import base64_from_spki_der
_KEY_DIR = runtime_path("keys") _KEY_DIR = runtime_path("script_signing_keys")
_SIGNING_KEY_FILE = _KEY_DIR / "borealis-script-ed25519.key" _SIGNING_KEY_FILE = _KEY_DIR / "borealis-script-ed25519.key"
_SIGNING_PUB_FILE = _KEY_DIR / "borealis-script-ed25519.pub" _SIGNING_PUB_FILE = _KEY_DIR / "borealis-script-ed25519.pub"
_LEGACY_KEY_FILE = runtime_path("keys") / "borealis-script-ed25519.key"
_LEGACY_PUB_FILE = runtime_path("keys") / "borealis-script-ed25519.pub"
class ScriptSigner: class ScriptSigner:
@@ -43,11 +45,17 @@ def load_signer() -> ScriptSigner:
def _load_or_create() -> ed25519.Ed25519PrivateKey: def _load_or_create() -> ed25519.Ed25519PrivateKey:
ensure_runtime_dir("keys") ensure_runtime_dir("script_signing_keys")
_migrate_legacy_material_if_present()
if _SIGNING_KEY_FILE.exists(): if _SIGNING_KEY_FILE.exists():
with _SIGNING_KEY_FILE.open("rb") as fh: with _SIGNING_KEY_FILE.open("rb") as fh:
return serialization.load_pem_private_key(fh.read(), password=None) return serialization.load_pem_private_key(fh.read(), password=None)
if _LEGACY_KEY_FILE.exists():
with _LEGACY_KEY_FILE.open("rb") as fh:
return serialization.load_pem_private_key(fh.read(), password=None)
private_key = ed25519.Ed25519PrivateKey.generate() private_key = ed25519.Ed25519PrivateKey.generate()
pem = private_key.private_bytes( pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM, encoding=serialization.Encoding.PEM,
@@ -70,3 +78,23 @@ def _load_or_create() -> ed25519.Ed25519PrivateKey:
return private_key return private_key
def _migrate_legacy_material_if_present() -> None:
if not _LEGACY_KEY_FILE.exists() or _SIGNING_KEY_FILE.exists():
return
try:
ensure_runtime_dir("script_signing_keys")
try:
_LEGACY_KEY_FILE.replace(_SIGNING_KEY_FILE)
except Exception:
_SIGNING_KEY_FILE.write_bytes(_LEGACY_KEY_FILE.read_bytes())
if _LEGACY_PUB_FILE.exists() and not _SIGNING_PUB_FILE.exists():
try:
_LEGACY_PUB_FILE.replace(_SIGNING_PUB_FILE)
except Exception:
_SIGNING_PUB_FILE.write_bytes(_LEGACY_PUB_FILE.read_bytes())
except Exception:
return

View File

@@ -21,6 +21,7 @@ Section Guide:
import os import os
import sys import sys
from pathlib import Path from pathlib import Path
import ssl
# Ensure the modular server package is importable when the runtime is launched # Ensure the modular server package is importable when the runtime is launched
# from a packaged directory (e.g., Server/Borealis). We look for the canonical # from a packaged directory (e.g., Server/Borealis). We look for the canonical
@@ -41,6 +42,36 @@ eventlet.monkey_patch(thread=False)
from eventlet import tpool from eventlet import tpool
try:
from eventlet.wsgi import HttpProtocol # type: ignore
except Exception:
HttpProtocol = None # type: ignore[assignment]
else:
_original_handle_one_request = HttpProtocol.handle_one_request
def _quiet_tls_http_mismatch(self): # type: ignore[override]
try:
return _original_handle_one_request(self)
except ssl.SSLError as exc: # type: ignore[arg-type]
reason = getattr(exc, "reason", "")
reason_text = str(reason).lower() if reason else ""
message = " ".join(str(arg) for arg in exc.args if arg).lower()
if "http_request" in message or reason_text == "http request":
try:
self.close_connection = True # type: ignore[attr-defined]
except Exception:
pass
try:
conn = getattr(self, "socket", None) or getattr(self, "connection", None)
if conn:
conn.close()
except Exception:
pass
return None
raise
HttpProtocol.handle_one_request = _quiet_tls_http_mismatch # type: ignore[assignment]
import requests import requests
import re import re
import base64 import base64