diff --git a/Cargo.lock b/Cargo.lock index 1f3ea63..d433b8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,15 +99,6 @@ version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" -[[package]] -name = "arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" -dependencies = [ - "derive_arbitrary", -] - [[package]] name = "assert-json-diff" version = "2.0.2" @@ -184,11 +175,11 @@ checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "block-buffer" -version = "0.10.4" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -211,12 +202,12 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cbindgen" -version = "0.28.0" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadd868a2ce9ca38de7eeafdcec9c7065ef89b42b32f0839278d55f35c54d1ff" +checksum = "befbfd072a8e81c02f8c507aefce431fe5e7d051f83d48a23ffc9b9fe5a11799" dependencies = [ "clap", - "heck 0.4.1", + "heck", "indexmap", "log", "proc-macro2", @@ -298,6 +289,12 @@ dependencies = [ "zstd", ] +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "cookie" version = "0.18.1" @@ -329,9 +326,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.17" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" dependencies = [ "libc", ] @@ -381,12 +378,11 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" dependencies = [ - "generic-array", - "typenum", + "hybrid-array", ] [[package]] @@ -422,24 +418,14 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "derive_arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "digest" -version = "0.10.7" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" dependencies = [ "block-buffer", + "const-oid", "crypto-common", ] @@ -616,16 +602,6 @@ dependencies = [ "slab", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - [[package]] name = "getrandom" version = "0.2.17" @@ -708,12 +684,6 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -771,6 +741,15 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hybrid-array" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" version = "1.9.0" @@ -1048,15 +1027,15 @@ dependencies = [ [[package]] name = "mock_instant" -version = "0.5.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e1d4c44418358edcac6e1d9ce59cea7fb38052429c7704033f1196f0c179e6a" +checksum = "dce6dd36094cac388f119d2e9dc82dc730ef91c32a6222170d630e5414b956e6" [[package]] name = "mockall" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" +checksum = "f58d964098a5f9c6b63d0798e5372fd04708193510a7af313c22e9f29b7b620b" dependencies = [ "cfg-if", "downcast", @@ -1068,9 +1047,9 @@ dependencies = [ [[package]] name = "mockall_derive" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" +checksum = "ca41ce716dda6a9be188b385aa78ee5260fc25cd3802cb2a8afdc6afbe6b6dbf" dependencies = [ "cfg-if", "proc-macro2", @@ -1569,11 +1548,11 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.9" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -1616,9 +1595,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.9" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", "cpufeatures", @@ -1809,44 +1788,42 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.23" +version = "0.9.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ - "serde", + "indexmap", + "serde_core", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_parser", + "toml_writer", + "winnow 0.7.15", ] [[package]] name = "toml_datetime" -version = "0.6.11" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ - "serde", + "serde_core", ] [[package]] -name = "toml_edit" -version = "0.22.27" +name = "toml_parser" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow", + "winnow 1.0.1", ] [[package]] -name = "toml_write" -version = "0.1.2" +name = "toml_writer" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" [[package]] name = "tracing" @@ -1867,6 +1844,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "typed-path" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e28f89b80c87b8fb0cf04ab448d5dd0dd0ade2f8891bae878de66a75a28600e" + [[package]] name = "typenum" version = "1.19.0" @@ -2208,9 +2191,12 @@ name = "winnow" version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" -dependencies = [ - "memchr", -] + +[[package]] +name = "winnow" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" [[package]] name = "wit-bindgen" @@ -2228,7 +2214,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" dependencies = [ "anyhow", - "heck 0.5.0", + "heck", "wit-parser", ] @@ -2239,7 +2225,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", - "heck 0.5.0", + "heck", "indexmap", "prettyplease", "syn", @@ -2411,15 +2397,15 @@ dependencies = [ [[package]] name = "zip" -version = "3.0.0" +version = "8.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12598812502ed0105f607f941c386f43d441e00148fce9dec3ca5ffb0bde9308" +checksum = "dcab981e19633ebcf0b001ddd37dd802996098bc1864f90b7c5d970ce76c1d59" dependencies = [ - "arbitrary", "crc32fast", "flate2", "indexmap", "memchr", + "typed-path", "zopfli", ] diff --git a/library/Cargo.toml b/library/Cargo.toml index fc81a6d..a784521 100644 --- a/library/Cargo.toml +++ b/library/Cargo.toml @@ -41,10 +41,10 @@ ring = "0.17.8" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.93" # For computing hashes of patch files for validation. -sha2 = "0.10.6" +sha2 = "0.11.0" uuid = { version = "1.18.1", features = ["v4"] } # For decompressing .apk files. -zip = { version = "3.0.0", default-features = false, features = ["deflate"] } +zip = { version = "8.5.1", default-features = false, features = ["deflate"] } [target.'cfg(target_os = "android")'.dependencies] # For logging to Android logcat. @@ -62,9 +62,9 @@ oslog = "0.2.0" simple_logger = "5.0.0" [dev-dependencies] -mockall = "0.13.1" +mockall = "0.14.0" mockito = "1.2.0" -mock_instant = "0.5.1" +mock_instant = "0.6.0" # Gives #[serial] attribute for locking all of our shorebird_init # tests to a single thread so they don't conflict with each other. serial_test = "3.2.0" @@ -72,4 +72,4 @@ tempfile = "3" # [build-dependencies] -cbindgen = "0.28.0" +cbindgen = "0.29.2" diff --git a/library/src/cache/mod.rs b/library/src/cache/mod.rs index c6ae0e5..4bf5e33 100644 --- a/library/src/cache/mod.rs +++ b/library/src/cache/mod.rs @@ -3,6 +3,7 @@ mod patch_manager; mod signing; pub mod updater_state; +pub use signing::hash_file; pub use updater_state::UpdaterState; /// The public interface for talking about patches to the Cache. diff --git a/library/src/cache/signing.rs b/library/src/cache/signing.rs index fb2daf4..6322c8e 100644 --- a/library/src/cache/signing.rs +++ b/library/src/cache/signing.rs @@ -6,10 +6,18 @@ use std::path::Path; /// Reads the file at `path` and returns the SHA-256 hash of its contents as a String. pub fn hash_file>(path: P) -> Result { use sha2::{Digest, Sha256}; // `Digest` is needed for `Sha256::new()`; + use std::io::Read; let mut file = std::fs::File::open(path)?; let mut hasher = Sha256::new(); - std::io::copy(&mut file, &mut hasher)?; + let mut buf = [0u8; 8192]; + loop { + let n = file.read(&mut buf)?; + if n == 0 { + break; + } + hasher.update(&buf[..n]); + } let hash = hasher.finalize(); Ok(hex::encode(hash)) } diff --git a/library/src/updater.rs b/library/src/updater.rs index b280f1b..034489f 100644 --- a/library/src/updater.rs +++ b/library/src/updater.rs @@ -296,19 +296,11 @@ pub fn check_for_downloadable_update(channel: Option<&str>) -> anyhow::Result anyhow::Result<()> { - use sha2::{Digest, Sha256}; // `Digest` is needed for `Sha256::new()`; - - let expected = hex::decode(expected_string).context("Invalid hash string from server.")?; - - // Based on guidance from: - // - - let mut file = fs::File::open(path).with_file_context(FileOperation::ReadFile, path)?; - let mut hasher = Sha256::new(); - std::io::copy(&mut file, &mut hasher).with_file_context(FileOperation::ReadFile, path)?; - // Check that the length from copy is the same as the file size? - let hash = hasher.finalize(); - let hash_matches = hash.as_slice() == expected; + // Validate the expected string is a hex-encoded hash. + hex::decode(expected_string).context("Invalid hash string from server.")?; + let hash = crate::cache::hash_file(path) + .with_context(|| format!("Failed to hash file: {:?}", path))?; + let hash_matches = hash == expected_string; // This is a common error for developers. We could avoid it entirely // by sending the hash of `libapp.so` to the server and having the // server only send updates when the hash matches. @@ -321,7 +313,7 @@ fn check_hash(path: &Path, expected_string: &str) -> anyhow::Result<()> { binary. Path: {:?}, expected: {}, got: {}", path, expected_string, - hex::encode(hash) + hash ); } shorebird_debug!("Hash match: {:?}", path);