aboutsummaryrefslogtreecommitdiff
path: root/src/api/common/signature/streaming.rs
diff options
context:
space:
mode:
authorAlex Auvolat <lx@deuxfleurs.fr>2025-02-16 18:25:35 +0100
committerAlex Auvolat <lx@deuxfleurs.fr>2025-02-16 18:25:35 +0100
commit44a896f9b50680a1fdaeb6aaad18a6bf07e9f3c3 (patch)
tree78adb23edbfefcc378eb19ecbf4eb38564d28ed6 /src/api/common/signature/streaming.rs
parentcee7560fc1c3e885dc80dfee233211f54ac9db7d (diff)
downloadgarage-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.rs41
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| {