diff --git a/Cargo.toml b/Cargo.toml index ea7e0d5..9fdba9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ url = "2" [dev-dependencies] base64ct = "1" -sha2 = "0.10" +sha2 = "0.11" [build-dependencies] bindgen = { version = "0.72", default-features = false, features = ["runtime"] } diff --git a/executor/Cargo.toml b/executor/Cargo.toml index fe679db..763c37c 100644 --- a/executor/Cargo.toml +++ b/executor/Cargo.toml @@ -8,13 +8,13 @@ publish = false [dependencies] axum = "0.8" axum-server = { version = "0.8", features = ["tls-rustls"] } -hmac = "0.12" +hmac = "0.13" jaws = { version = "1", default-features = false, features = ["p256"] } p256 = { version = "0.13", features = ["ecdsa"] } pggomtm = { path = "..", default-features = false, features = ["database-token-contract"] } serde = { version = "1", features = ["derive"] } serde_json = "1" -sha2 = "0.10" +sha2 = "0.11" tokio = { version = "1", features = ["macros", "rt-multi-thread", "sync", "time"] } uuid = { version = "1", features = ["v4"] } zeroize = "1" @@ -24,7 +24,7 @@ bindgen = { version = "0.72", default-features = false, features = ["runtime"] } pkg-config = "0.3" [dev-dependencies] -reqwest = { version = "0.12", default-features = false, features = ["blocking", "json", "rustls-tls-manual-roots"] } +reqwest = { version = "0.13", default-features = false, features = ["blocking", "json", "rustls", "webpki-roots"] } [[example]] name = "mtmpg_executor_fixture" diff --git a/executor/src/auth.rs b/executor/src/auth.rs index 3fcd27b..0ca24c7 100644 --- a/executor/src/auth.rs +++ b/executor/src/auth.rs @@ -1,7 +1,7 @@ use std::collections::BTreeMap; use std::sync::Mutex; -use hmac::{Hmac, Mac}; +use hmac::{Hmac, KeyInit, Mac}; use sha2::{Digest, Sha256}; use zeroize::Zeroizing; @@ -60,9 +60,18 @@ impl HmacAuthenticator { let signature = decode_signature(request.signature).ok_or(AuthenticationError::Unauthorized)?; let body_digest = Sha256::digest(request.body); + let body_digest_hex = body_digest + .iter() + .map(|byte| format!("{byte:02x}")) + .collect::(); let canonical = format!( - "{}\n{}\n{}\n{}\n{}\n{body_digest:x}", - request.version, request.method, request.path, request.timestamp, request.nonce + "{}\n{}\n{}\n{}\n{}\n{}", + request.version, + request.method, + request.path, + request.timestamp, + request.nonce, + body_digest_hex, ); let mut mac = HmacSha256::new_from_slice(&self.secret) .map_err(|_| AuthenticationError::Unauthorized)?; diff --git a/executor/tests/support/pg18_driver.rs b/executor/tests/support/pg18_driver.rs index 39dca8d..6ab78b2 100644 --- a/executor/tests/support/pg18_driver.rs +++ b/executor/tests/support/pg18_driver.rs @@ -6,7 +6,7 @@ use std::sync::atomic::{AtomicU64, Ordering}; use std::thread; use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use hmac::{Hmac, Mac}; +use hmac::{Hmac, KeyInit, Mac}; use reqwest::blocking::{Client, Response}; use reqwest::header::{CONTENT_TYPE, HeaderMap, HeaderValue}; use reqwest::{Certificate, StatusCode}; @@ -411,12 +411,21 @@ fn headers(timestamp: i64, nonce: &str, signature: &str) -> Result Result { let digest = Sha256::digest(body); + let digest_hex = digest + .iter() + .map(|byte| format!("{byte:02x}")) + .collect::(); let canonical = - format!("{WIRE_VERSION}\nPOST\n{EXECUTE_PATH}\n{timestamp}\n{nonce}\n{digest:x}"); + format!("{WIRE_VERSION}\nPOST\n{EXECUTE_PATH}\n{timestamp}\n{nonce}\n{digest_hex}"); let mut mac = HmacSha256::new_from_slice(secret).map_err(|_| invalid_data("invalid HMAC test secret"))?; mac.update(canonical.as_bytes()); - Ok(format!("{:x}", mac.finalize().into_bytes())) + Ok(mac + .finalize() + .into_bytes() + .iter() + .map(|byte| format!("{byte:02x}")) + .collect()) } fn decode_response(response: Response) -> Result<(StatusCode, Value), Box> {