diff --git a/.cargo/config.toml b/.cargo/config.toml index 20f3d57..38583f5 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,7 +1,9 @@ [alias] -# Build the daemon with "firmware" profile and "ring" TLS backend. -# Requires a cross-compiler (see github actions workflows) and is very slow to build. -build-daemon-firmware = "build -p rayhunter-daemon --bin rayhunter-daemon --target armv7-unknown-linux-musleabihf --profile firmware --no-default-features --features ring-tls" +# Build the daemon with "firmware" profile and post-quantum TLS backend. +# Needs an arm-linux-musleabihf cross-compiler in PATH, e.g. a toolchain +# from https://musl.cc, or run inside messense/rust-musl-cross:armv7-musleabihf +# (which is what CI does, see .github/workflows/main.yml). +build-daemon-firmware = "build -p rayhunter-daemon --bin rayhunter-daemon --target armv7-unknown-linux-musleabihf --profile firmware --no-default-features --features pq-tls" # Build the daemon with "firmware-devel" profile and "rustcrypto" backend. # Works with just the Rust toolchain, and is medium-slow to build. Binaries are slightly larger. build-daemon-firmware-devel = "build -p rayhunter-daemon --bin rayhunter-daemon --target armv7-unknown-linux-musleabihf --profile firmware-devel" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b3c7b00..495bbff 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -314,27 +314,25 @@ jobs: - uses: actions/checkout@v4 with: persist-credentials: false - - uses: dtolnay/rust-toolchain@stable - with: - targets: armv7-unknown-linux-musleabihf - - uses: Swatinem/rust-cache@v2 - - name: Install ARM cross-compilation toolchain - run: sudo apt-get update && sudo apt-get install -y gcc-arm-linux-gnueabihf - - name: Build rayhunter-daemon (armv7) + - name: Build frontend run: | pushd daemon/web npm install npm run build popd - # Run with -p so that cargo will select the minimum feature set for this package. - # - # Otherwise, it will consider the union of all requested features - # from all packages in the workspace. For example, if installer - # requires tokio with "full" feature, it will be included no matter - # what the feature selection in rayhunter-daemon is. - # - # https://github.com/rust-lang/cargo/issues/4463 - CC_armv7_unknown_linux_musleabihf=arm-linux-gnueabihf-gcc cargo build-daemon-firmware + - name: Build rayhunter-daemon (armv7) + # Cross-compile inside messense/rust-musl-cross, which bundles an + # arm-linux-musleabihf cross gcc that aws-lc-sys needs. + run: | + mkdir -p "$HOME/.cargo-musl-cross" + docker run --rm \ + --user "$(id -u):$(id -g)" \ + -v "$PWD":/work \ + -v "$HOME/.cargo-musl-cross":/cargo-home \ + -e CARGO_HOME=/cargo-home \ + -w /work \ + messense/rust-musl-cross:armv7-musleabihf \ + cargo build-daemon-firmware - uses: actions/upload-artifact@v4 with: name: rayhunter-daemon diff --git a/Cargo.lock b/Cargo.lock index 3054b0c..7d3336c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -454,6 +454,28 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "aws-lc-rs" +version = "1.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.39.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "axum" version = "0.8.4" @@ -785,10 +807,11 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.23" +version = "1.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" +checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -923,6 +946,15 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -1731,6 +1763,12 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + [[package]] name = "flate2" version = "1.1.1" @@ -1794,6 +1832,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "funty" version = "2.0.0" @@ -2049,10 +2093,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", ] [[package]] @@ -2062,11 +2104,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", - "js-sys", "libc", "r-efi", "wasi 0.14.2+wasi-0.2.4", - "wasm-bindgen", ] [[package]] @@ -3128,12 +3168,6 @@ dependencies = [ "imgref", ] -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - [[package]] name = "mac" version = "0.1.1" @@ -4428,61 +4462,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "quinn" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" -dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "socket2", - "thiserror 2.0.12", - "tokio", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-proto" -version = "0.11.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" -dependencies = [ - "bytes", - "getrandom 0.3.3", - "lru-slab", - "rand 0.9.1", - "ring", - "rustc-hash", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.12", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.59.0", -] - [[package]] name = "quote" version = "1.0.40" @@ -4724,6 +4703,7 @@ dependencies = [ "log", "rayhunter", "reqwest", + "rustls-post-quantum", "rustls-rustcrypto", "serde", "serde_json", @@ -4845,7 +4825,6 @@ dependencies = [ "log", "percent-encoding", "pin-project-lite", - "quinn", "rustls", "rustls-pki-types", "serde", @@ -4940,12 +4919,6 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - [[package]] name = "rustc_version" version = "0.4.1" @@ -4983,14 +4956,15 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.28" +version = "0.23.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" dependencies = [ + "aws-lc-rs", + "log", "once_cell", - "ring", "rustls-pki-types", - "rustls-webpki 0.103.3", + "rustls-webpki 0.103.10", "subtle", "zeroize", ] @@ -5001,10 +4975,20 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ - "web-time", "zeroize", ] +[[package]] +name = "rustls-post-quantum" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0da3cd9229bac4fae1f589c8f875b3c891a058ddaa26eb3bde16b5e43dc174ce" +dependencies = [ + "aws-lc-rs", + "rustls", + "rustls-webpki 0.103.10", +] + [[package]] name = "rustls-rustcrypto" version = "0.0.2-alpha" @@ -5048,10 +5032,11 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.3" +version = "0.103.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" +checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -6099,21 +6084,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "tinyvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokio" version = "1.45.0" @@ -6775,16 +6745,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "webkit2gtk" version = "2.0.1" diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index dd48754..f03674a 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -16,7 +16,7 @@ required-features = ["apidocs"] [features] default = ["rustcrypto-tls"] rustcrypto-tls = ["reqwest/rustls-tls-webpki-roots-no-provider", "dep:rustls-rustcrypto"] -ring-tls = ["reqwest/rustls-tls-webpki-roots"] +pq-tls = ["reqwest/rustls-tls-webpki-roots-no-provider", "dep:rustls-post-quantum"] apidocs = ["dep:utoipa"] [dependencies] @@ -41,5 +41,6 @@ async_zip = { version = "0.0.17", features = ["tokio"] } anyhow = "1.0.98" reqwest = { version = "0.12.20", default-features = false } rustls-rustcrypto = { version = "0.0.2-alpha", optional = true } +rustls-post-quantum = { version = "0.2.4", optional = true } async-trait = "0.1.88" utoipa = { version = "5.4.0", optional = true } diff --git a/daemon/src/crypto_provider.rs b/daemon/src/crypto_provider.rs new file mode 100644 index 0000000..2469e1a --- /dev/null +++ b/daemon/src/crypto_provider.rs @@ -0,0 +1,23 @@ +use std::sync::Once; + +static INSTALL: Once = Once::new(); + +/// Install the default rustls `CryptoProvider` for the current process. +/// +/// This is idempotent so that it's easier to use in tests, but also panics loudly if the +/// initialization fails. +pub fn install_default() { + // Crypto providers fail if they get initialized multiple times, but we don't want to just + // ignore all errors, hence the use of once. + INSTALL.call_once(|| { + #[cfg(feature = "rustcrypto-tls")] + rustls_rustcrypto::provider() + .install_default() + .expect("failed to install rustcrypto crypto provider"); + + #[cfg(feature = "pq-tls")] + rustls_post_quantum::provider() + .install_default() + .expect("failed to install aws-lc-rs post-quantum crypto provider"); + }); +} diff --git a/daemon/src/lib.rs b/daemon/src/lib.rs index f3d4c77..efc2f60 100644 --- a/daemon/src/lib.rs +++ b/daemon/src/lib.rs @@ -1,6 +1,7 @@ pub mod analysis; pub mod battery; pub mod config; +pub mod crypto_provider; pub mod diag; pub mod display; pub mod error; diff --git a/daemon/src/main.rs b/daemon/src/main.rs index 9fb661d..11a7903 100644 --- a/daemon/src/main.rs +++ b/daemon/src/main.rs @@ -1,6 +1,7 @@ mod analysis; mod battery; mod config; +mod crypto_provider; mod diag; mod display; mod error; @@ -173,12 +174,7 @@ fn run_shutdown_thread( async fn main() -> Result<(), RayhunterError> { rayhunter::init_logging(log::LevelFilter::Info); - #[cfg(feature = "rustcrypto-tls")] - { - rustls_rustcrypto::provider() - .install_default() - .expect("Couldn't install rustcrypto provider"); - } + crate::crypto_provider::install_default(); let args = parse_args(); diff --git a/daemon/src/notifications.rs b/daemon/src/notifications.rs index e96f632..7432a6d 100644 --- a/daemon/src/notifications.rs +++ b/daemon/src/notifications.rs @@ -223,10 +223,7 @@ mod tests { } async fn setup_test_server() -> (Arc>>, String) { - #[cfg(feature = "rustcrypto-tls")] - { - let _ = rustls_rustcrypto::provider().install_default(); - } + crate::crypto_provider::install_default(); let received_messages = Arc::new(Mutex::new(Vec::new())); let test_state = TestServerState {