aboutsummaryrefslogtreecommitdiff
path: root/src/api/common/signature/mod.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/mod.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/mod.rs')
-rw-r--r--src/api/common/signature/mod.rs51
1 files changed, 26 insertions, 25 deletions
diff --git a/src/api/common/signature/mod.rs b/src/api/common/signature/mod.rs
index 08b0aa7e..2421d696 100644
--- a/src/api/common/signature/mod.rs
+++ b/src/api/common/signature/mod.rs
@@ -27,7 +27,7 @@ pub const X_AMZ_DATE: HeaderName = HeaderName::from_static("x-amz-date");
pub const X_AMZ_EXPIRES: HeaderName = HeaderName::from_static("x-amz-expires");
pub const X_AMZ_SIGNEDHEADERS: HeaderName = HeaderName::from_static("x-amz-signedheaders");
pub const X_AMZ_SIGNATURE: HeaderName = HeaderName::from_static("x-amz-signature");
-pub const X_AMZ_CONTENT_SH256: HeaderName = HeaderName::from_static("x-amz-content-sha256");
+pub const X_AMZ_CONTENT_SHA256: HeaderName = HeaderName::from_static("x-amz-content-sha256");
pub const X_AMZ_TRAILER: HeaderName = HeaderName::from_static("x-amz-trailer");
/// Result of `sha256("")`
@@ -40,6 +40,7 @@ type HmacSha256 = Hmac<Sha256>;
// Possible values for x-amz-content-sha256, in addition to the actual sha256
pub const UNSIGNED_PAYLOAD: &str = "UNSIGNED-PAYLOAD";
+pub const STREAMING_UNSIGNED_PAYLOAD_TRAILER: &str = "STREAMING-UNSIGNED-PAYLOAD-TRAILER";
pub const STREAMING_AWS4_HMAC_SHA256_PAYLOAD: &str = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD";
// Used in the computation of StringToSign
@@ -47,46 +48,46 @@ pub const AWS4_HMAC_SHA256_PAYLOAD: &str = "AWS4-HMAC-SHA256-PAYLOAD";
// ---- enums to describe stuff going on in signature calculation ----
+#[derive(Debug)]
pub enum ContentSha256Header {
UnsignedPayload,
- Sha256Hash(String),
- StreamingPayload {
- trailer: Option<TrailerHeader>,
- algorithm: Option<SigningAlgorithm>,
- },
+ Sha256Hash(Hash),
+ StreamingPayload { trailer: bool, signed: bool },
}
-pub enum SigningAlgorithm {
- AwsHmacSha256,
-}
+// ---- top-level functions ----
-pub enum TrailerHeader {
- XAmzChecksumCrc32,
- XAmzChecksumCrc32c,
- XAmzChecksumCrc64Nvme,
+pub struct VerifiedRequest {
+ pub request: Request<streaming::ReqBody>,
+ pub access_key: Key,
+ pub content_sha256_header: ContentSha256Header,
+ // TODO: oneshot chans to retrieve hashes after reading all body
}
-// ---- top-level functions ----
-
pub async fn verify_request(
garage: &Garage,
mut req: Request<IncomingBody>,
service: &'static str,
-) -> Result<(Request<streaming::ReqBody>, Key, Option<Hash>), Error> {
- let (api_key, mut content_sha256) =
- payload::check_payload_signature(&garage, &mut req, service).await?;
- let api_key =
- api_key.ok_or_else(|| Error::forbidden("Garage does not support anonymous access yet"))?;
-
- let req = streaming::parse_streaming_body(
- &api_key,
+) -> Result<VerifiedRequest, Error> {
+ let checked_signature = payload::check_payload_signature(&garage, &mut req, service).await?;
+ eprintln!("checked signature: {:?}", checked_signature);
+
+ let request = streaming::parse_streaming_body(
req,
- &mut content_sha256,
+ &checked_signature,
&garage.config.s3_api.s3_region,
service,
)?;
- Ok((req, api_key, content_sha256))
+ let access_key = checked_signature
+ .key
+ .ok_or_else(|| Error::forbidden("Garage does not support anonymous access yet"))?;
+
+ Ok(VerifiedRequest {
+ request,
+ access_key,
+ content_sha256_header: checked_signature.content_sha256_header,
+ })
}
pub fn verify_signed_content(expected_sha256: Hash, body: &[u8]) -> Result<(), Error> {