fix(tools): validate flash_device.py HMAC secret format before flashing
--hmac-secret accepted any string and passed it through to NVS, silently producing a device that cannot authenticate to the server. Reject anything that isn't exactly 64 hex characters (32 bytes) before generating the NVS image. Auto-generated secrets are validated too as a defensive check. Found via adversarial review (both reviewers, run 2026-05-01-192928). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,11 +15,14 @@ Usage:
|
|||||||
"""
|
"""
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import secrets
|
import secrets
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
HMAC_SECRET_RE = re.compile(r"^[0-9a-fA-F]{64}$")
|
||||||
|
|
||||||
|
|
||||||
NVS_NAMESPACE = "doorcounter"
|
NVS_NAMESPACE = "doorcounter"
|
||||||
NVS_PARTITION_OFFSET = "0x9000"
|
NVS_PARTITION_OFFSET = "0x9000"
|
||||||
@@ -63,6 +66,10 @@ def main():
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
hmac_secret = args.hmac_secret or secrets.token_hex(32)
|
hmac_secret = args.hmac_secret or secrets.token_hex(32)
|
||||||
|
if not HMAC_SECRET_RE.match(hmac_secret):
|
||||||
|
print("Error: --hmac-secret must be exactly 64 hex characters (32 bytes)",
|
||||||
|
file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
if args.hmac_secret is None:
|
if args.hmac_secret is None:
|
||||||
print(f"Generated HMAC secret: {hmac_secret}")
|
print(f"Generated HMAC secret: {hmac_secret}")
|
||||||
print(" *** SAVE THIS — you need it to register the device on the server ***")
|
print(" *** SAVE THIS — you need it to register the device on the server ***")
|
||||||
|
|||||||
Reference in New Issue
Block a user