Skip to content

feat(unlocker): support Biscuit OTA rescue and expose TLS failures - #25

Open
FrostyMead wants to merge 2 commits into
crosspoint-reader:masterfrom
FrostyMead:biscuit-ota-rescue
Open

feat(unlocker): support Biscuit OTA rescue and expose TLS failures#25
FrostyMead wants to merge 2 commits into
crosspoint-reader:masterfrom
FrostyMead:biscuit-ota-rescue

Conversation

@FrostyMead

Copy link
Copy Markdown

Summary

Adds explicit OTA support for Biscuit and exposes TCP/TLS failures that
currently happen before the Unlocker's normal HTTP request logging.

Background

An XTEINK X4 running Biscuit successfully joins the Unlocker hotspot and
resolves api.github.com to 192.168.137.1, but Biscuit reports
Update failed and the existing helper logs no GitHub manifest request.

The previous Unlocker could report its servers as ready before ports 80 and
443 had successfully bound. TLS handshake failures occurring before Axum were
also not logged.

Separately, Biscuit requires an HTTPS OTA download URL. The generic Unlocker
response previously supplied Biscuit with an HTTP firmware URL.

Changes

  • bind HTTP and HTTPS sockets before reporting readiness
  • return and log bind failures
  • log incoming HTTPS TCP connections and client addresses
  • log TLS handshake start, success and available failure details
  • log negotiated TLS version, cipher, ALPN and successful-handshake SNI
  • supervise unexpected server exits and task failures
  • add a Biscuit-only release manifest containing:
    • tag_name exactly 99.9.9
    • exactly one asset named firmware.bin
    • the selected firmware's exact byte size
    • https://unlocker.crosspointreader.com/firmware/firmware.bin
    • explicit JSON Content-Length
    • no chunked transfer encoding
  • preserve existing stock Xteink, CrossPoint, CrossInk, INX, CrossPet and
    CPR-vCodex behaviour
  • correct the diagnostic ESP32-C3 chip ID mapping
  • add focused response and compatibility tests
  • document the Stage A and Stage B findings and Escape Hatch verification

Validation

  • cargo fmt -p unlocker-core -- --check
  • cargo test --locked -p unlocker-core — 4 passed
  • cargo check --locked -p unlocker-core
  • cargo clippy --locked -p unlocker-core --all-targets
  • git diff --check

The public repository omits the production privkey.pem, so no helper or
installer build was attempted. No replacement key, self-signed certificate
or TLS bypass was introduced.

Certificate action required

The certificate currently committed in fullchain.pem expires on
2026-07-30. Any Windows test installer must use a currently valid
unlocker.crosspointreader.com certificate, complete chain and the
maintainers' legitimate matching private key.

Maintainer test request

Please produce a Windows test installer using the legitimate renewed
certificate infrastructure.

For the first device test:

  1. Select X4.
  2. Select the verified Escape Hatch recovery image.
  3. Start the hotspot and confirm ports 80 and 443 bind successfully.
  4. Connect the Biscuit device.
  5. Run Check for Updates once.
  6. Save the complete helper log.
  7. Do not confirm installation until the selected firmware image, SHA-256,
    size, ESP32-C3 chip ID and returned manifest have been verified.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@FrostyMead, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 20 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e8ae9784-38f9-443f-9b08-1c31c10c165b

📥 Commits

Reviewing files that changed from the base of the PR and between 8aebd0f and 29ac941.

📒 Files selected for processing (1)
  • unlocker-tool/crates/unlocker-core/src/http.rs
📝 Walkthrough

Walkthrough

The patch adds Biscuit-specific fixed-length OTA manifest handling, HTTPS firmware URL selection, TLS handshake logging, synchronous listener binding, supervised server shutdown, ESP32-C3 chip mapping corrections, tests, and maintainer validation documentation.

Changes

Biscuit OTA rescue

Layer / File(s) Summary
Biscuit manifest contract
unlocker-tool/crates/unlocker-core/src/http.rs, FINDINGS.md
Biscuit responses now use the required fixed-length JSON manifest and HTTPS firmware URL while stock and vCodex routes remain covered by tests.
TLS diagnostics and server supervision
unlocker-tool/crates/unlocker-core/src/http.rs, FINDINGS.md
HTTPS connections log TCP and TLS handshake details, listeners bind synchronously, and server task termination is supervised and reported.
Validation and maintainer material
FINDINGS.md, unlocker-tool/crates/unlocker-core/Cargo.toml
Development test support and documentation record certificate requirements, safety checks, validation scope, and maintainer test procedures.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers: itsthisjustin

Sequence Diagram(s)

sequenceDiagram
  participant Biscuit
  participant github_releases_latest
  participant biscuit_manifest_response
  participant HTTPS_firmware_URL
  Biscuit->>github_releases_latest: Request latest manifest
  github_releases_latest->>biscuit_manifest_response: Build Biscuit manifest response
  biscuit_manifest_response-->>Biscuit: Return fixed-length JSON with firmware.bin
  Biscuit->>HTTPS_firmware_URL: Download firmware over HTTPS
Loading
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: Biscuit OTA rescue support and TLS failure logging.
Description check ✅ Passed The description matches the changeset and covers the Biscuit OTA support, diagnostics, tests, and certificate notes.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@unlocker-tool/crates/unlocker-core/src/http.rs`:
- Around line 774-796: Update the server startup flow in start so both HTTP and
HTTPS axum_server Server objects are constructed before spawning either
supervise_server task. Only spawn the HTTP and HTTPS tasks after both from_tcp
calls succeed, ensuring an HTTPS construction error returns without leaving the
HTTP task or listener orphaned; preserve the existing ServerHandles wiring and
shutdown behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ad1f91bd-2216-45ba-8448-f9f1d4a0c71e

📥 Commits

Reviewing files that changed from the base of the PR and between 9b39a7a and 8aebd0f.

⛔ Files ignored due to path filters (1)
  • unlocker-tool/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • FINDINGS.md
  • unlocker-tool/crates/unlocker-core/Cargo.toml
  • unlocker-tool/crates/unlocker-core/src/http.rs
📜 Review details
🧰 Additional context used
🪛 LanguageTool
FINDINGS.md

[uncategorized] ~21-~21: The official name of this software platform is spelled with a capital “H”.
Context: ...manifest connection:** Biscuit resolves api.github.com, opens TLS to port 443, and req...

(GITHUB)


[uncategorized] ~69-~69: The official name of this software platform is spelled with a capital “H”.
Context: ...before this patch - DNS already spoofs api.github.com and `unlocker.crosspointreader.c...

(GITHUB)


[uncategorized] ~231-~231: The official name of this software platform is spelled with a capital “H”.
Context: ...he hotspot. 5. Confirm Biscuit resolves api.github.com to 192.168.137.1. 6. Run **Check...

(GITHUB)

🔇 Additional comments (7)
unlocker-tool/crates/unlocker-core/Cargo.toml (1)

34-35: LGTM!

FINDINGS.md (1)

1-373: LGTM!

unlocker-tool/crates/unlocker-core/src/http.rs (5)

4-13: LGTM!

Also applies to: 23-42


89-92: 🎯 Functional Correctness

Chip ID mapping fix looks correct.

Confirmed against Espressif's esp_image_header_t.chip_id assignments: 5 = ESP32-C3, 9 = ESP32-S3. The old code's 5→S3/6→C3 mapping was indeed wrong; this correction and the accompanying esp32c3_image_chip_id_is_five test are accurate.

Also applies to: 130-141


143-222: 🩺 Stability & Availability

Custom TLS acceptor implementation looks solid.

The LoggingTlsAcceptor wrapping RustlsAcceptor follows axum-server's documented custom-Accept pattern, and the Accept<TcpStream, S> impl signature matches the library trait. Logging TCP/TLS diagnostics here (rather than relying on axum-server's internal accept loop, which silently discards acceptor errors) is a sound fix for the "invisible pre-manifest failure" problem described in FINDINGS.md.


337-337: LGTM!

Also applies to: 554-589, 649-657, 694-694


939-1130: LGTM!

Tests cover the Biscuit fixed-length manifest, stock/vCodex routes, per-repo scheme selection (including the biscuit-next substring-collision edge case), and the corrected chip ID mapping.

Comment thread unlocker-tool/crates/unlocker-core/src/http.rs
@itsthisjustin

Copy link
Copy Markdown
Contributor

Hey thanks for this PR! I will test and get this pushed up prior to the 7/30 deadline

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants