feat(factory): add local flashing toolkit and secure OTA defaults

This commit is contained in:
admin
2026-03-02 01:57:39 +08:00
parent 809fcf6548
commit 3d3c3ebac2
27 changed files with 5260 additions and 4 deletions

View File

@@ -0,0 +1,95 @@
from __future__ import annotations
import os
import re
SENSITIVE_KEYS = (
"pub_key",
"signature",
"key_b64",
"flash_key_b64",
"sig_b64",
"pub_key_jkt",
"new_pub_key",
"new_pub_key_jkt",
"device_mac",
"operator",
"host",
"port",
"firmware_version",
)
_ANSI_RE = re.compile(r"\x1b\[[0-9;]*[A-Za-z]")
_MAC_RE = re.compile(r"(?i)([0-9a-f]{2}:){5}[0-9a-f]{2}")
_UUID_RE = re.compile(
r"\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b"
)
_URL_RE = re.compile(r"https?://[^\s]+")
_DEVICE_ID_JSON_RE = re.compile(r'("device_id"\s*:\s*")([^"]+)(")', re.IGNORECASE)
_DEVICE_ID_KV_RE = re.compile(r"(\bdevice_id\b\s*[:=]\s*)([^\s,;]+)", re.IGNORECASE)
_JSON_KEY_RE = re.compile(
r'([\'"](?:(?:' + "|".join(SENSITIVE_KEYS) + r'))[\'"]\s*:\s*[\'"])([^\'"]+)([\'"])',
re.IGNORECASE,
)
_KV_RE = re.compile(r"(?i)\b(" + "|".join(SENSITIVE_KEYS) + r")=([^\s,;]+)")
_HEX_BYTES_RE = re.compile(r"\b(?:[0-9a-fA-F]{2}\s+){7,}[0-9a-fA-F]{2}\b")
_BIN_PATH_RE = re.compile(r"(/[^\\s]+?\\.(?:bin(?:\\.enc)?|enc))")
_BIN_NAME_RE = re.compile(r"\b[\w.-]+\\.(?:bin(?:\\.enc)?|enc)\b")
def _sanitize_filename(value: str) -> str:
if not value:
return "unknown"
return re.sub(r"[^A-Za-z0-9._-]+", "_", value)
def _preserve_device_ids(text: str) -> tuple[str, dict[str, str]]:
tokens: dict[str, str] = {}
def _tokenize(value: str) -> str:
token = f"__DEVICE_ID_{len(tokens)}__"
tokens[token] = value
return token
def _replace_json(match: re.Match[str]) -> str:
return f"{match.group(1)}{_tokenize(match.group(2))}{match.group(3)}"
def _replace_kv(match: re.Match[str]) -> str:
return f"{match.group(1)}{_tokenize(match.group(2))}"
text = _DEVICE_ID_JSON_RE.sub(_replace_json, text)
text = _DEVICE_ID_KV_RE.sub(_replace_kv, text)
return text, tokens
def _redact_sensitive(text: str) -> str:
if not text:
return text
text, device_tokens = _preserve_device_ids(text)
text = _ANSI_RE.sub("", text)
text = _MAC_RE.sub("<mac>", text)
text = _UUID_RE.sub("<id>", text)
text = _URL_RE.sub("<url>", text)
text = _JSON_KEY_RE.sub(
lambda m: f"{m.group(1)}<redacted:{len(m.group(2))}>{m.group(3)}", text
)
text = _KV_RE.sub(
lambda m: f"{m.group(1)}=<redacted:{len(m.group(2))}>", text
)
text = _HEX_BYTES_RE.sub("<redacted:hex>", text)
text = _BIN_PATH_RE.sub(lambda m: os.path.basename(m.group(1)), text)
text = _BIN_NAME_RE.sub("<bin>", text)
lowered = text.lower()
if "security features enabled" in lowered:
return "检测到限制,保持默认配置。"
if "compress and encrypt options are mutually exclusive" in lowered:
return "写入选项冲突,已使用默认方式。"
if "will flash input bytes uncompressed" in lowered:
return "将按默认方式写入。"
if "cannot verify written data" in lowered:
return "写入完成,校验已跳过。"
if "secure boot detected" in lowered or "secure download mode is enabled" in lowered:
return "检测到写入限制,请按工艺选择模式。"
for token, value in device_tokens.items():
text = text.replace(token, value)
return text