diff options
author | Alex Auvolat <lx@deuxfleurs.fr> | 2025-02-16 18:25:35 +0100 |
---|---|---|
committer | Alex Auvolat <lx@deuxfleurs.fr> | 2025-02-16 18:25:35 +0100 |
commit | 44a896f9b50680a1fdaeb6aaad18a6bf07e9f3c3 (patch) | |
tree | 78adb23edbfefcc378eb19ecbf4eb38564d28ed6 /src/api/common/signature/streaming.rs | |
parent | cee7560fc1c3e885dc80dfee233211f54ac9db7d (diff) | |
download | garage-44a896f9b50680a1fdaeb6aaad18a6bf07e9f3c3.tar.gz garage-44a896f9b50680a1fdaeb6aaad18a6bf07e9f3c3.zip |
api: add logic to parse x-amz-content-sha256
Diffstat (limited to 'src/api/common/signature/streaming.rs')
-rw-r--r-- | src/api/common/signature/streaming.rs | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/src/api/common/signature/streaming.rs b/src/api/common/signature/streaming.rs index e08a4750..98079ffb 100644 --- a/src/api/common/signature/streaming.rs +++ b/src/api/common/signature/streaming.rs @@ -3,7 +3,6 @@ use std::pin::Pin; use chrono::{DateTime, NaiveDateTime, TimeZone, Utc}; use futures::prelude::*; use futures::task; -use garage_model::key_table::Key; use hmac::Mac; use http_body_util::StreamBody; use hyper::body::{Bytes, Incoming as IncomingBody}; @@ -14,27 +13,47 @@ use garage_util::data::Hash; use super::*; use crate::helpers::*; +use crate::signature::payload::CheckedSignature; pub type ReqBody = BoxBody<Error>; pub fn parse_streaming_body( - api_key: &Key, req: Request<IncomingBody>, - content_sha256: &mut Option<Hash>, + checked_signature: &CheckedSignature, region: &str, service: &str, ) -> Result<Request<ReqBody>, Error> { - match req.headers().get(X_AMZ_CONTENT_SH256) { - Some(header) if header == STREAMING_AWS4_HMAC_SHA256_PAYLOAD => { - let signature = content_sha256 - .take() - .ok_or_bad_request("No signature provided")?; + match checked_signature.content_sha256_header { + ContentSha256Header::StreamingPayload { signed, trailer } => { + if trailer { + return Err(Error::bad_request( + "STREAMING-*-TRAILER is not supported by Garage", + )); + } + if !signed { + return Err(Error::bad_request( + "STREAMING-UNSIGNED-PAYLOAD-* is not supported by Garage", + )); + } - let secret_key = &api_key + let signature = checked_signature + .signature_header + .clone() + .ok_or_bad_request("No signature provided")?; + let signature = hex::decode(signature) + .ok() + .and_then(|bytes| Hash::try_from(&bytes)) + .ok_or_bad_request("Invalid signature")?; + + let secret_key = checked_signature + .key + .as_ref() + .ok_or_bad_request("Cannot sign streaming payload without signing key")? .state .as_option() .ok_or_internal_error("Deleted key state")? - .secret_key; + .secret_key + .to_string(); let date = req .headers() @@ -46,7 +65,7 @@ pub fn parse_streaming_body( let date: DateTime<Utc> = Utc.from_utc_datetime(&date); let scope = compute_scope(&date, region, service); - let signing_hmac = crate::signature::signing_hmac(&date, secret_key, region, service) + let signing_hmac = crate::signature::signing_hmac(&date, &secret_key, region, service) .ok_or_internal_error("Unable to build signing HMAC")?; Ok(req.map(move |body| { |