diff --git a/Cargo.lock b/Cargo.lock index ff8553d1..e3b9b449 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -365,7 +365,7 @@ dependencies = [ "rpassword", "rusqlite", "serde_json", - "sha2", + "sha2 0.11.1", "url", "zeroize", ] @@ -528,7 +528,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "sha2", + "sha2 0.11.1", "subtle", ] @@ -663,7 +663,6 @@ dependencies = [ "block-buffer 0.10.4", "const-oid 0.9.6", "crypto-common 0.1.7", - "subtle", ] [[package]] @@ -983,11 +982,11 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hmac" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "digest 0.10.7", + "digest 0.11.3", ] [[package]] @@ -1236,7 +1235,7 @@ dependencies = [ "rustls", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "thiserror", "tokio", "tokio-rustls", @@ -1311,7 +1310,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "sha2", + "sha2 0.11.1", "tempfile", "thiserror", "tokio", @@ -2424,6 +2423,7 @@ dependencies = [ "core", "futures-util", "getrandom 0.4.3", + "hex", "http-body-util", "iphone-use-mcp", "libc", @@ -2439,7 +2439,7 @@ dependencies = [ "rustls", "serde", "serde_json", - "sha2", + "sha2 0.11.1", "tempfile", "tokio", "tokio-rustls", @@ -2474,6 +2474,17 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha2" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d7069beb7d6ac7b9acd1039986e73443f24234f41074da099d6f994ac9ad19" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.1", + "digest 0.11.3", +] + [[package]] name = "sharded-slab" version = "0.1.7" diff --git a/crates/browser-session/Cargo.toml b/crates/browser-session/Cargo.toml index fed1a789..22af8627 100644 --- a/crates/browser-session/Cargo.toml +++ b/crates/browser-session/Cargo.toml @@ -21,7 +21,7 @@ argon2 = "0.6" base64 = "0.22" rand = "0.10" serde_json = "1" -sha2 = "0.10" +sha2 = "0.11" hex = "0.4" zeroize = "1" clap = { version = "4", features = ["derive"], optional = true } diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 74672349..d5ff16fd 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -6,8 +6,8 @@ license-file = "../../LICENSE" [dependencies] schemars = { version = "1", optional = true } -hmac = "0.12" -sha2 = "0.10" +hmac = "0.13" +sha2 = "0.11" subtle = "2" getrandom = "0.4" base64 = "0.22" diff --git a/crates/core/src/auth.rs b/crates/core/src/auth.rs index d90d72b6..d3265290 100644 --- a/crates/core/src/auth.rs +++ b/crates/core/src/auth.rs @@ -3,7 +3,7 @@ /// Token format: `exp:nonce:sig` /// where `sig = base64url_nopad(HMAC_SHA256(secret, "exp:nonce"))`. use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _}; -use hmac::{Hmac, Mac}; +use hmac::{Hmac, KeyInit, Mac}; use sha2::Sha256; use subtle::ConstantTimeEq; diff --git a/crates/core/src/runner_auth.rs b/crates/core/src/runner_auth.rs index 5d646bd4..b43ed384 100644 --- a/crates/core/src/runner_auth.rs +++ b/crates/core/src/runner_auth.rs @@ -20,7 +20,7 @@ //! [`MAX_SKEW_SECS`] of its own clock, so a captured request cannot be //! replayed or altered. -use hmac::{Hmac, Mac}; +use hmac::{Hmac, KeyInit, Mac}; use sha2::{Digest, Sha256}; use subtle::ConstantTimeEq; diff --git a/crates/mcp/Cargo.toml b/crates/mcp/Cargo.toml index 68d7dae6..0e9930d1 100644 --- a/crates/mcp/Cargo.toml +++ b/crates/mcp/Cargo.toml @@ -50,7 +50,7 @@ libc = "0.2" base64 = "0.22" # Registry checksums (flow update verifies every file against index.json) -sha2 = "0.10" +sha2 = "0.11" hex = "0.4" # `flow publish` clones the registry into a scratch directory diff --git a/crates/mcp/src/task.rs b/crates/mcp/src/task.rs index c0d1cd6a..5d49139f 100644 --- a/crates/mcp/src/task.rs +++ b/crates/mcp/src/task.rs @@ -369,7 +369,7 @@ pub fn start( } use sha2::{Digest, Sha256}; // Keep only the digest; model keys and return parameters are never exposed. - let request_fingerprint = format!("{:x}", Sha256::digest(format!("{request:?}").as_bytes())); + let request_fingerprint = hex::encode(Sha256::digest(format!("{request:?}").as_bytes())); let id = new_id(); let task = Arc::new(Task { state: Mutex::new(State { @@ -1496,7 +1496,7 @@ mod tests { async fn request_id_deduplicates_and_pause_is_nonterminal() { let request=TaskRequest {goal:"synthetic goal".into(),client_request_id:Some("fixture-client".into()),..Default::default()}; use sha2::{Digest, Sha256}; - let request_fingerprint=format!("{:x}",Sha256::digest(format!("{request:?}").as_bytes())); + let request_fingerprint=hex::encode(Sha256::digest(format!("{request:?}").as_bytes())); let task=Arc::new(Task { state: Mutex::new(State {request_fingerprint,id:"fixture-dedup".into(),goal:"synthetic goal".into(),client_request_id:Some("fixture-client".into()),status:Status::Running,phase:"observing",planned_action:None,flow:None,steps:vec![],confirm:None,summary:None,error:None,started_at_ms:unix_ms(),started:Instant::now(),finished_ms:None,models_used:json!({})}), cancel:AtomicBool::new(false),paused:AtomicBool::new(false),cancel_signal:tokio::sync::Notify::new(),answer:Mutex::new(None), diff --git a/crates/server/Cargo.toml b/crates/server/Cargo.toml index c9d7174c..b0919a74 100644 --- a/crates/server/Cargo.toml +++ b/crates/server/Cargo.toml @@ -57,7 +57,8 @@ tempfile = "3" # runner (L2 element-tree control): screenshots arrive base64-encoded. base64 = "0.22" -sha2 = "0.10" +sha2 = "0.11" +hex = "0.4" # ES256 tokens for the App Store Connect API (legacy iOS signing) and the # SHA-1 codesign takes; already in the tree through rustls. ring = "0.17" diff --git a/crates/server/src/setup/embed.rs b/crates/server/src/setup/embed.rs index a91b0e69..5e2c206d 100644 --- a/crates/server/src/setup/embed.rs +++ b/crates/server/src/setup/embed.rs @@ -170,9 +170,17 @@ fn usable(path: &Path) -> Result { } fn file_sha256(path: &Path) -> Option { + use std::io::Read; let mut file = std::fs::File::open(path).ok()?; let mut digest = Sha256::new(); - std::io::copy(&mut file, &mut digest).ok()?; + let mut buf = vec![0u8; 64 * 1024]; + loop { + let n = file.read(&mut buf).ok()?; + if n == 0 { + break; + } + digest.update(&buf[..n]); + } Some( digest .finalize() @@ -322,7 +330,7 @@ mod tests { ); assert_eq!( cache_component(Some(&first)), - format!("embed:{:x}", Sha256::digest(b"one")) + format!("embed:{}", hex::encode(Sha256::digest(b"one"))) ); assert_eq!(cache_component(None), "embed:none"); assert_eq!( diff --git a/crates/server/src/setup/runner.rs b/crates/server/src/setup/runner.rs index 9f7a41f6..c851cde3 100644 --- a/crates/server/src/setup/runner.rs +++ b/crates/server/src/setup/runner.rs @@ -1481,7 +1481,7 @@ mod tests { std::fs::write(&path, bytes).unwrap(); super::super::embed::EmbedLib { path: path.clone(), - sha256: format!("{:x}", ::digest(bytes)), + sha256: hex::encode(::digest(bytes)), } }; let component = super::super::embed::cache_component;