Skip to content

chore(trezor): upgrade trezor-connect-rs to 10.0.1 - #192

Merged
coreyphillips merged 1 commit into
masterfrom
chore/trezor-connect-rs-10.0.1
Nov 6, 2026
Merged

coreyphillips merged 1 commit into
masterfrom
chore/trezor-connect-rs-10.0.1

Conversation

@coreyphillips

Copy link
Copy Markdown
Collaborator

Upgrades trezor-connect-rs from 10.0.0 to 10.0.1, which brings in coreyphillips/trezor-connect-rs#54. That change makes the THP handshake completion step follow the host rules in the THP spec (host state HH3, step 3).

Description

GitHub has no v10.0.x tags, so I compared the published 10.0.0 and 10.0.1 crates file by file. 10.0.1 has no public API changes (the new helpers are pub(crate)) and no dependency changes. Runtime behaviour does change:

Handshake completion Before After
Paired state, no verified credential sent Continued without pairing Error, no retry
Unknown device state Treated as paired Error, no retry
Malformed completion frame Skipped the state check and went on to session creation. A frame under 5 bytes panicked Error, which CallbackTransport retries like other temporary failures
Stored credential with a low-order device key Could match an all-zero masked key Does not verify, so the device pairs again

Changes in this repo

  • Bump both target-specific requirements in Cargo.toml. Cargo.lock changes only the trezor-connect-rs version and checksum.
  • Add a CHANGELOG.md entry under Unreleased.

No source changes are needed. ThpError::HandshakeFailed already maps to TrezorError::ConnectionError in src/modules/trezor/errors.rs, and nothing in the module matches on handshake error text. Apps will see the new failures as ConnectionError.

Left out

Preview

N/A, no UI changes.

QA Notes

Needs a real device before release. Upstream tested against the T3W1 firmware emulator (2.11.1, 2.9.6 and 2-main), but not on a physical Safe 7 over Bluetooth, and the emulator uses UDP so Bluetooth timing is untested. bitkit-core's mobile path uses CallbackTransport over Bluetooth, and I could not run hardware tests for this PR. On a physical Safe 7, please check:

  1. Reconnect with a stored credential: connects with no pairing prompt.
  2. Fresh pairing on a device with no stored credential: the code-entry flow completes and the credential is saved.
  3. Call clear_credentials, then reconnect while the device still remembers the host: expect code-entry pairing, not a ConnectionError. This is the case most likely to show a regression, since a device reporting a paired state here is now rejected.

Checks run (Rust 1.99.1 on macOS, branch based on 4affda1)

  • cargo test --locked modules::trezor: 72 passed
  • cargo fmt --check
  • cargo metadata --locked --format-version 1
  • cargo check --locked --target aarch64-apple-ios (the Bluetooth-only feature set)
  • cargo ndk -t arm64-v8a check --locked with NDK 28.2.13676358
  • Cargo.lock checksum matches the sha256 of the 10.0.1 tarball that was reviewed
  • cargo test --locked --no-fail-fast: 736 passed, 11 failed, 30 ignored. All 11 are Blocktank tests failing on requests to api.stag.blocktank.to. The same 11 test names fail on unchanged master at 4affda1.
  • cargo clippy -- -D warnings: fails with 31 errors on this toolchain. The diagnostics are identical on unchanged master at 4affda1, so none come from this PR. This form of the command is not enforced in CI.

10.0.1 makes the THP handshake follow the host rules in the THP spec. A
paired state now needs a verified stored credential, and a malformed
completion frame is an error instead of continuing to session creation.

The public API and the crate's dependencies are unchanged, so no source
or bindings changes are needed here. The new failures reach callers
through the existing HandshakeFailed mapping as
TrezorError::ConnectionError.

@talosmachina talosmachina 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.

No findings. Bumps trezor-connect-rs from 10.0.0 to 10.0.1 so the THP handshake completion follows the host rules instead of trusting the device's reported state. Reviewed ff2499a, light tier.

What I checked, and 4 candidates I ruled out

Upstream delta: downloaded both crates from crates.io and diffed them. The sha256 of the 10.0.1 tarball is 54e590c2…7fc3a, the checksum in Cargo.lock. Only handshake.rs, the three transports (callback.rs, bluetooth.rs, usb.rs), transport/mod.rs and a new test file changed. Cargo.toml.orig differs in the version line only, so there are no dependency changes. The new items (completion_outcome, completion_response_payload, includes_credential) are pub(crate).
Read in full: the PR diff, the upstream completion_outcome and completion_response_payload, the CallbackTransport retry loop in 10.0.1, and src/modules/trezor/errors.rs.
Build: not run here. talos-pr-run could not read the author's permission on this repo, so it refused, and this review is static.
CI: SwiftPM manifest, manifests, and wake-tests are green. iOS Bindgen, Android Bindgen and usdt-tests were still pending when I wrote this.

Ruled out

  • Error mapping: every new failure is ThpError::HandshakeFailed, which errors.rs:269 maps to TrezorError::ConnectionError. Nothing in src/modules/trezor matches on the handshake text.
  • Retry behaviour as described: in the 10.0.1 CallbackTransport loop, "device reported a paired state without a verified credential" and "invalid state" match none of the retryable substrings, so they fail at once. "Unexpected response to handshake completion" matches Unexpected response and is retried. This matches the table in the description.
  • Short-frame panic: 10.0.0 indexed comp_resp[3] and comp_resp[4] before checking the length. 10.0.1 uses split_first_chunk::<5>(), and the upstream tests cover the 0-byte, 3-byte and 4-byte frames.
  • Credential-rejected path on USB and BLE: CredentialRejected falls through to pairing on those transports, the same as 10.0.0 did for state 0. Only CallbackTransport aborts and retries fresh, and that is unchanged.

Merge confidence: 4/5. The change is on the pairing path, and the PR's code was not built here; real-device checks are still open, as the QA notes say.

@pwltr pwltr left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed commit ff2499a. No findings.

Both crates.io archives match their Cargo.lock checksums, and the 10.0.1 manifest changes only its version. The upstream diff matches the CHANGELOG entry: a paired completion state is accepted only when a credential was sent, a malformed completion frame is an error instead of skipping the pairing decision, and a low-order stored device key no longer verifies. The callback transport still re-pairs after a rejected credential and retries the new frame error.

Review details

General review
Model: Claude Opus 5.5
Reasoning effort: high

@pwltr pwltr left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed ff2499a: no introduced correctness defects identified in the assessed repository integration changes. The trezor-connect-rs 10.0.1 implementation was unavailable in the review environment, so the advertised THP security changes remain unverified.

Review details

General review
Model: GPT-6.1 Sol
Reasoning effort: high

@coreyphillips
coreyphillips merged commit 3c2a7f4 into master Nov 6, 2026
6 checks passed
@coreyphillips
coreyphillips deleted the chore/trezor-connect-rs-10.0.1 branch November 6, 2026 18:58
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.

4 participants