Skip to content

Fix build: bump ledger_secure_sdk_sys to 1.14.1 - #18

Closed
xescure wants to merge 1 commit into
KeetaNetwork:mainfrom
xescure:fix/ledger-sdk-sys-1.14.1
Closed

Fix build: bump ledger_secure_sdk_sys to 1.14.1#18
xescure wants to merge 1 commit into
KeetaNetwork:mainfrom
xescure:fix/ledger-sdk-sys-1.14.1

Conversation

@xescure

@xescure xescure commented Jun 11, 2026

Copy link
Copy Markdown

Problem

Building against the documented builder image (ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest, used by the README and all CI jobs) currently fails for every device while compiling ledger_secure_sdk_sys 1.14.0:

ledger_secure_sdk_sys@1.14.0: ./src/c/src.c:10:10: fatal error: 'checks.h' file not found
error: failed to run custom build command for `ledger_secure_sdk_sys v1.14.0`

Root cause

The crate's bundled C glue (src/c/src.c) does #include "checks.h". The C SDK currently shipped in the builder image (C SDK v26.1.10, API_LEVEL 26) no longer provides that header on the include path for the API-26 devices (nanos+/nanox/stax/flex); it only remains in the legacy Nano S SDK. ledger_secure_sdk_sys 1.14.1 is the upstream patch for this header change.

Fix

Pin the locked ledger_secure_sdk_sys to 1.14.1 (2-line Cargo.lock change). Cargo.toml already declares ledger_device_sdk = "1.*", which pulls the crate transitively, so only the lockfile needs to move.

Verification

Built all four devices in the builder image — all succeed and produce loadable app ELFs:

Device Result
nanosplus
nanox
stax
flex

Why this doesn't warrant a new security audit

The full upstream delta between the trusted 1.14.0 and 1.14.1 is ~30 lines, entirely in the FFI/build layer of the -sys crate (diffed from the crates.io tarballs):

  • build.rs: SDK_C_FILES 13 → 12 — drops src/checks.c from the compiled C file set.
  • src/c/src.c: removes #include "checks.h"; adds a guard so link_pass_nvram treats a wiped/uninitialised .nvram section (0x0/0xFFFFFFFF) as first-run.
  • devices/*.defines: IO_USB_MAX_ENDPOINTS 4→6 (all devices); nanos+ gains HAVE_IO_U2F — USB-transport build config tracking the current C SDK.
  • Cargo.toml authors field (cosmetic) + version + CHANGELOG.

Upstream CHANGELOG (1.14.1): "Make link_pass_nvram resilient to the nvram being wiped", "C SDK: Remove usage of checks.c and checks.h".

The app's auditable surface — this repo's Rust code (key derivation, secp256k1/ed25519/secp256r1 signing, Keeta block parsing, APDU handlers) — is unchanged: only Cargo.lock moves, and only one transitive -sys crate by a single semver patch. Nothing in the delta touches cryptographic primitives, RNG, key storage, signing, or APDU parsing; checks.c/.h is dropped to track the upstream C SDK reorganisation, not a runtime guard removed from the app. 1.14.1 is published and checksummed on crates.io by Ledger, from the same ledger-device-rust-sdk repo already trusted for 1.14.0, and is the minimum change required to keep compiling against the official toolchain. The one genuine runtime change — the link_pass_nvram guard — runs at app load/relocation time, not in any crypto/signing path. A re-audit's scope would be this enumerable ~30-line diff, which contains no security logic.

Considered alternative: pin an older builder image

Instead of bumping the crate, the Docker image could be pinned to the last release whose bundled C SDK still ships checks.h, keeping locked 1.14.0 buildable — ledger-app-dev-tools:4.26.2 (built 2026-01-21, digest sha256:da38cabd688d046d6223ab79f638ddd848510de1991196e7889519e2e2494f2e), the last 4.x before the 5.0.0 major bump (2026-02-03) that coincides with the C SDK dropping checks.c/.h. Rejected because pinning freezes the entire build toolchain to a Jan-2026 C SDK and forgoes later upstream SDK fixes — strictly worse for a security-sensitive app than advancing one crate by a patch — and diverges from :latest, which the README and all CI jobs use.

Note

This PR is intentionally limited to the ledger_secure_sdk_sys bump. The repo's Cargo.lock has pre-existing drift in the node-rs git dependencies (entries lack the ?branch=feat/block qualifier that Cargo.toml specifies), so a local build re-resolves and rewrites those lines. Unrelated to this fix and left untouched.

🤖 Generated with Claude Code

Building against ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest
fails while compiling ledger_secure_sdk_sys 1.14.0:

    ./src/c/src.c:10:10: fatal error: 'checks.h' file not found

The crate's bundled C glue includes checks.h, which the C SDK currently shipped
in the builder image (C SDK v26.1.10, API_LEVEL 26) no longer provides on the
include path for the API-26 devices. ledger_secure_sdk_sys 1.14.1 is the
upstream patch for this header change.

Pinning the locked version to 1.14.1 fixes the build. Verified building all four
devices (nanosplus, nanox, stax, flex) in the builder image.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

xescure added a commit to xescure/ledger-device-application that referenced this pull request Jul 28, 2026
The committed lock entries for the node-rs git dependencies were keyed
without the branch qualifier that Cargo.toml declares:

    Cargo.toml:  git = ".../node-rs", branch = "feat/block"
    Cargo.lock:  source = "git+.../node-rs#ff64476f"   (no ?branch=...)

Cargo keys locked git dependencies by the full source string including
the query, so the mismatch makes it treat the locked entry as a
different source, ignore the recorded commit, and silently re-resolve
to the current head of feat/block on every fresh build.

The recorded pin (ff64476f, 2025-10-07) is a fossil from before the
app used feat/block at all: the initial commit declared node-rs without
a branch, and when fbe72f4 (2026-02-05) switched to feat/block for the
metadata/permissions API, the lock entry became orphaned. Every build
since has floated on the branch head with no pin in effect.

Re-key the entries under the correct source and freeze at

    6571b290200251811b52dfba24a502ce7916ab17

the feat/block head from 2026-03-08 to 2026-06-15 - the version every
demonstrated build and test of this app actually consumed, including
the block-signing compatibility testing merged in KeetaNetwork#16 and the four-
device build verification in KeetaNetwork#18. The later head (7622b5d, a 457+/323-
refactor of keetanetwork-block types.rs/metadata.rs) has never been
exercised with this app; freezing deliberately excludes it. The two
revs have identical dependency graphs (no manifest changes between
them), so this lock differs from the re-resolved one only in the four
rev hashes.

Verified with `cargo metadata --locked` in the official builder image:
the committed lock fails (exit 101, "cannot update the lock file"),
this lock is accepted verbatim (exit 0), and a full nanosplus build
consumes 6571b290 with no lock rewrite.

keetanetwork-block parses blocks for the clear-signing display, so
builds of a security-sensitive app should not float on a moving branch.
Consider also passing --locked in CI so future drift fails loudly.
@xescure

xescure commented Aug 6, 2026

Copy link
Copy Markdown
Author

Fixed by #20

@xescure xescure closed this Aug 6, 2026
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