mirror of
https://github.com/imjasonh/esp32
synced 2026-07-06 23:52:24 +00:00
Each OTA fetch is now gated on a Sigstore Bundle signature whose Fulcio cert identifies a member of an allowlist hardcoded in src/trust.rs (currently imjasonh@gmail.com / accounts.google.com). The allowlist cannot be changed via OTA -- only by editing source and reflashing over USB. Publisher (Makefile): make publish now runs cosign sign --yes after the publisher push. Cosign keyless OIDC pops a browser the first time; subsequent signs reuse the cached token within ~10min. Firmware: - src/trust.rs: TRUSTED_IDENTITIES list + bundled Sigstore root and intermediate CA PEMs (trust/fulcio_root.pem, fulcio_intermediate.pem). - src/sig.rs: parse Sigstore Bundle v0.3 (DSSE envelope), verify (a) Fulcio cert SAN email + OID 1.3.6.1.4.1.57264.1.1 issuer match the allowlist, (b) leaf cert chains to bundled Sigstore root via P-384 ECDSA-SHA384, (c) DSSE signature verifies via P-256 ECDSA-SHA256 over the PAE, (d) in-toto Statement subject digest binds to our manifest digest. - src/ota.rs: fetch_manifest now returns the manifest's own SHA256 (the digest cosign signed), not just the parsed body. New fetch_signature_bundle walks the OCI 1.1 referrers layout cosign uses (image index -> inner manifest -> bundle blob). Sig is fetched and verified before the firmware download starts. Crates: p256, p384, x509-cert (with pem feature), base64. Adds ~350 KB to the firmware -- repartitioned ota slots from 1.5MB to 1.75MB to fit (USB-only migration). Bumped OTA thread stack to 48KB for cert-parsing headroom. Verified end-to-end: Jason signed :latest with cosign keyless, device polled, all four verification steps passed (identity, chain, DSSE sig, in-toto binding), then downloaded and applied as before. Phase 4b (Rekor SET / transparency log inclusion proof) and 4c (operational hardening) remain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
43 lines
1.1 KiB
TOML
43 lines
1.1 KiB
TOML
[package]
|
|
name = "esp32-blinky"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
resolver = "2"
|
|
rust-version = "1.77"
|
|
|
|
[[bin]]
|
|
name = "esp32-blinky"
|
|
harness = false
|
|
|
|
[profile.release]
|
|
opt-level = "s"
|
|
|
|
[profile.dev]
|
|
debug = true
|
|
opt-level = "z"
|
|
|
|
[features]
|
|
default = ["std", "esp-idf-svc/native", "esp-idf-svc/binstart"]
|
|
pio = ["esp-idf-svc/pio"]
|
|
std = ["esp-idf-svc/std"]
|
|
|
|
[dependencies]
|
|
# `log` feature makes tracing events emit log records too, so EspLogger
|
|
# (which is a log::Logger) picks them up and writes via esp_log_write.
|
|
# No tracing subscriber needed on the device; structured fields render
|
|
# into the message text.
|
|
tracing = { version = "0.1", features = ["log"] }
|
|
anyhow = "1"
|
|
esp-idf-svc = "0.51"
|
|
embedded-svc = "0.28"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
sha2 = "0.10"
|
|
# Phase 4a: cosign Sigstore Bundle verification.
|
|
p256 = { version = "0.13", features = ["ecdsa"] } # leaf signs DSSE
|
|
p384 = { version = "0.13", features = ["ecdsa"] } # intermediate signs leaf
|
|
x509-cert = { version = "0.2", features = ["pem"] }
|
|
base64 = "0.22"
|
|
|
|
[build-dependencies]
|
|
embuild = "0.33"
|