|
|
@@ -0,0 +1,77 @@
|
|
|
+Import("env")
|
|
|
+
|
|
|
+from pathlib import Path
|
|
|
+import subprocess
|
|
|
+import tempfile
|
|
|
+
|
|
|
+
|
|
|
+def render_pem_array(name, pem_text):
|
|
|
+ lines = []
|
|
|
+ for chunk in pem_text.splitlines(keepends=True):
|
|
|
+ escaped = chunk.replace("\\", "\\\\").replace('"', '\\"').replace("\n", "\\n")
|
|
|
+ lines.append(f' "{escaped}"')
|
|
|
+ joined = "\n".join(lines) if lines else ' ""'
|
|
|
+ return f"static const char {name}[] =\n{joined};\n"
|
|
|
+
|
|
|
+
|
|
|
+project_dir = Path(env["PROJECT_DIR"])
|
|
|
+header_path = project_dir / "src/helpers/mqtt/WebPanelCert.h"
|
|
|
+
|
|
|
+if header_path.exists():
|
|
|
+ existing = header_path.read_text()
|
|
|
+ if "AUTO-GENERATED BY generate_web_panel_cert.py" in existing and "kServerKeyPem" in existing:
|
|
|
+ Return()
|
|
|
+
|
|
|
+with tempfile.TemporaryDirectory() as tmp:
|
|
|
+ tmp_path = Path(tmp)
|
|
|
+ key_path = tmp_path / "web-panel-key.pem"
|
|
|
+ cert_path = tmp_path / "web-panel-cert.pem"
|
|
|
+
|
|
|
+ try:
|
|
|
+ subprocess.run(
|
|
|
+ ["openssl", "ecparam", "-name", "prime256v1", "-genkey", "-noout", "-out", str(key_path)],
|
|
|
+ check=True,
|
|
|
+ stdout=subprocess.PIPE,
|
|
|
+ stderr=subprocess.PIPE,
|
|
|
+ text=True,
|
|
|
+ )
|
|
|
+ subprocess.run(
|
|
|
+ [
|
|
|
+ "openssl",
|
|
|
+ "req",
|
|
|
+ "-new",
|
|
|
+ "-x509",
|
|
|
+ "-key",
|
|
|
+ str(key_path),
|
|
|
+ "-out",
|
|
|
+ str(cert_path),
|
|
|
+ "-days",
|
|
|
+ "3650",
|
|
|
+ "-subj",
|
|
|
+ "/CN=meshcore-local",
|
|
|
+ ],
|
|
|
+ check=True,
|
|
|
+ stdout=subprocess.PIPE,
|
|
|
+ stderr=subprocess.PIPE,
|
|
|
+ text=True,
|
|
|
+ )
|
|
|
+ except FileNotFoundError as exc:
|
|
|
+ raise RuntimeError("openssl is required to generate the web panel certificate header") from exc
|
|
|
+ except subprocess.CalledProcessError as exc:
|
|
|
+ raise RuntimeError(
|
|
|
+ f"openssl failed while generating the web panel certificate header: {exc.stderr.strip()}"
|
|
|
+ ) from exc
|
|
|
+
|
|
|
+ cert_pem = cert_path.read_text()
|
|
|
+ key_pem = key_path.read_text()
|
|
|
+
|
|
|
+header_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
+header_path.write_text(
|
|
|
+ "#pragma once\n\n"
|
|
|
+ "// AUTO-GENERATED BY generate_web_panel_cert.py. DO NOT COMMIT.\n\n"
|
|
|
+ "namespace mqtt_web_panel_cert {\n\n"
|
|
|
+ f"{render_pem_array('kServerCertPem', cert_pem)}\n"
|
|
|
+ f"{render_pem_array('kServerKeyPem', key_pem)}"
|
|
|
+ "}\n",
|
|
|
+ encoding="utf-8",
|
|
|
+)
|