Commit f443e848 authored by Nugine's avatar Nugine
Browse files

fix(s3s/sig_v4): support sts signature

parent f5ff0bc0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -99,7 +99,7 @@ fn check_signature(ctx: &SignatureCtx, expected_signature: &[u8], chunk_data: &[
    let string_to_sign =
        sig_v4::create_chunk_string_to_sign(&ctx.amz_date, &ctx.region, &ctx.service, &ctx.prev_signature, chunk_data);

    let chunk_signature = sig_v4::calculate_signature(&string_to_sign, &ctx.secret_key, &ctx.amz_date, &ctx.region);
    let chunk_signature = sig_v4::calculate_signature(&string_to_sign, &ctx.secret_key, &ctx.amz_date, &ctx.region, &ctx.service);

    (chunk_signature.as_bytes() == expected_signature).then(|| chunk_signature.into())
}
+17 −11
Original line number Diff line number Diff line
@@ -158,7 +158,7 @@ impl SignatureContext<'_> {
        let secret_key = auth.get_secret_key(&access_key).await?;

        let string_to_sign = info.policy;
        let signature = sig_v4::calculate_signature(string_to_sign, &secret_key, &amz_date, credential.aws_region);
        let signature = sig_v4::calculate_signature(string_to_sign, &secret_key, &amz_date, credential.aws_region, credential.aws_service);

        let expected_signature = info.x_amz_signature;
        if signature != expected_signature {
@@ -220,7 +220,7 @@ impl SignatureContext<'_> {
            let amz_date = &presigned_url.amz_date;
            let string_to_sign = sig_v4::create_string_to_sign(&canonical_request, amz_date, region, service);

            sig_v4::calculate_signature(&string_to_sign, &secret_key, amz_date, region)
            sig_v4::calculate_signature(&string_to_sign, &secret_key, amz_date, region, service)
        };

        let expected_signature = presigned_url.signature;
@@ -243,18 +243,27 @@ impl SignatureContext<'_> {
            a.signed_headers.sort_unstable();
            a
        };
        let region = authorization.credential.aws_region;
        let service = authorization.credential.aws_service;

        if !matches!(service, "s3" | "sts") {
            return Err(s3_error!(NotImplemented, "unknown service"));
        }

        let auth = require_auth(self.auth)?;

        let amz_content_sha256 =
            extract_amz_content_sha256(&self.hs)?.ok_or_else(|| invalid_request!("missing header: x-amz-content-sha256"))?;
        let amz_content_sha256 = extract_amz_content_sha256(&self.hs)?;

        if service == "s3" && amz_content_sha256.is_none() {
            return Err(invalid_request!("missing header: x-amz-content-sha256"));
        }

        let access_key = authorization.credential.access_key_id;
        let secret_key = auth.get_secret_key(access_key).await?;

        let amz_date = extract_amz_date(&self.hs)?.ok_or_else(|| invalid_request!("missing header: x-amz-date"))?;

        let is_stream = matches!(amz_content_sha256, AmzContentSha256::MultipleChunks);
        let is_stream = matches!(amz_content_sha256, Some(AmzContentSha256::MultipleChunks));

        let signature = {
            let method = &self.req_method;
@@ -268,13 +277,13 @@ impl SignatureContext<'_> {
                let payload = sig_v4::Payload::MultipleChunks;
                sig_v4::create_canonical_request(method, uri_path, query_strings, &headers, payload)
            } else if matches!(*self.req_method, Method::GET | Method::HEAD) {
                let payload = if matches!(amz_content_sha256, AmzContentSha256::UnsignedPayload) {
                let payload = if matches!(amz_content_sha256, Some(AmzContentSha256::UnsignedPayload)) {
                    sig_v4::Payload::Unsigned
                } else {
                    sig_v4::Payload::Empty
                };
                sig_v4::create_canonical_request(method, uri_path, query_strings, &headers, payload)
            } else if matches!(amz_content_sha256, AmzContentSha256::UnsignedPayload) {
            } else if matches!(amz_content_sha256, Some(AmzContentSha256::UnsignedPayload)) {
                sig_v4::create_canonical_request(method, uri_path, query_strings, &headers, sig_v4::Payload::Unsigned)
            } else {
                let bytes = super::extract_full_body(self.content_length, self.req_body).await?;
@@ -296,11 +305,8 @@ impl SignatureContext<'_> {
                    )
                }
            };

            let region = authorization.credential.aws_region;
            let service = authorization.credential.aws_service;
            let string_to_sign = sig_v4::create_string_to_sign(&canonical_request, &amz_date, region, service);
            sig_v4::calculate_signature(&string_to_sign, &secret_key, &amz_date, region)
            sig_v4::calculate_signature(&string_to_sign, &secret_key, &amz_date, region, service)
        };

        let expected_signature = authorization.signature;
+12 −12
Original line number Diff line number Diff line
@@ -263,7 +263,7 @@ pub fn create_chunk_string_to_sign(

/// calculate signature
#[must_use]
pub fn calculate_signature(string_to_sign: &str, secret_key: &SecretKey, amz_date: &AmzDate, region: &str) -> String {
pub fn calculate_signature(string_to_sign: &str, secret_key: &SecretKey, amz_date: &AmzDate, region: &str, service: &str) -> String {
    let mut secret = {
        let secret_key = secret_key.expose();
        let mut buf = <SmallVec<[u8; 128]>>::with_capacity(secret_key.len().saturating_add(4));
@@ -283,7 +283,7 @@ pub fn calculate_signature(string_to_sign: &str, secret_key: &SecretKey, amz_dat
    let date_region_key = hmac_sha256(date_key, region); // TODO: use a `Region` type

    // DateRegionServiceKey
    let date_region_service_key = hmac_sha256(date_region_key, "s3");
    let date_region_service_key = hmac_sha256(date_region_key, service);

    // SigningKey
    let signing_key = hmac_sha256(date_region_service_key, "aws4_request");
@@ -438,7 +438,7 @@ mod tests {
            )
        );

        let signature = calculate_signature(&string_to_sign, &secret_access_key, &date, region);
        let signature = calculate_signature(&string_to_sign, &secret_access_key, &date, region, service);
        assert_eq!(signature, "f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41");
    }

@@ -495,7 +495,7 @@ mod tests {
            )
        );

        let signature = calculate_signature(&string_to_sign, &secret_access_key, &date, region);
        let signature = calculate_signature(&string_to_sign, &secret_access_key, &date, region, service);
        assert_eq!(signature, "98ad721746da40c64f1a55b78f14c238d841ea1380cd77a1b5971af0ece108bd");
    }

@@ -555,7 +555,7 @@ mod tests {
            )
        );

        let signature = calculate_signature(&string_to_sign, &secret_access_key, &date, region);
        let signature = calculate_signature(&string_to_sign, &secret_access_key, &date, region, service);
        assert_eq!(signature, "4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9",);
    }

@@ -583,7 +583,7 @@ mod tests {
            )
        );

        let chunk1_signature = calculate_signature(&chunk1_string_to_sign, &secret_access_key, &date, region);
        let chunk1_signature = calculate_signature(&chunk1_string_to_sign, &secret_access_key, &date, region, service);
        assert_eq!(chunk1_signature, "ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648");

        let chunk2_string_to_sign =
@@ -600,7 +600,7 @@ mod tests {
            )
        );

        let chunk2_signature = calculate_signature(&chunk2_string_to_sign, &secret_access_key, &date, region);
        let chunk2_signature = calculate_signature(&chunk2_string_to_sign, &secret_access_key, &date, region, service);
        assert_eq!(chunk2_signature, "0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497");

        let chunk3_string_to_sign = create_chunk_string_to_sign(&date, region, service, &chunk2_signature, &[]);
@@ -616,7 +616,7 @@ mod tests {
            )
        );

        let chunk3_signature = calculate_signature(&chunk3_string_to_sign, &secret_access_key, &date, region);
        let chunk3_signature = calculate_signature(&chunk3_string_to_sign, &secret_access_key, &date, region, service);
        assert_eq!(chunk3_signature, "b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9");
    }

@@ -668,7 +668,7 @@ mod tests {
            )
        );

        let signature = calculate_signature(&string_to_sign, &secret_access_key, &date, region);
        let signature = calculate_signature(&string_to_sign, &secret_access_key, &date, region, service);
        assert_eq!(signature, "fea454ca298b7da1c68078a5d1bdbfbbe0d65c699e0f91ac7a200a0136783543");
    }

@@ -721,7 +721,7 @@ mod tests {
            )
        );

        let signature = calculate_signature(&string_to_sign, &secret_access_key, &date, region);
        let signature = calculate_signature(&string_to_sign, &secret_access_key, &date, region, service);
        assert_eq!(signature, "34b48302e7b5fa45bde8084f4b7868a86f0a534bc59db6670ed5711ef69dc6f7");
    }

@@ -787,7 +787,7 @@ mod tests {
            )
        );

        let signature = calculate_signature(&string_to_sign, &secret_access_key, &info.amz_date, info.credential.aws_region);
        let signature = calculate_signature(&string_to_sign, &secret_access_key, &info.amz_date, info.credential.aws_region, info.credential.aws_service);
        assert_eq!(signature, "aeeed9bbccd4d02ee5c0109b86d86835f995330da4c265957d157751f604d404");
        assert_eq!(signature, info.signature);
    }
@@ -836,7 +836,7 @@ mod tests {

            let string_to_sign = create_string_to_sign(&canonical_request, &date, region, service);

            let signature = calculate_signature(&string_to_sign, &secret_access_key, &date, region);
            let signature = calculate_signature(&string_to_sign, &secret_access_key, &date, region, service);
            assert_eq!(signature, "96ad058ca27352e0fc2bd4efd8973792077570667bdaf749655f42e204bc649c");
        }
    }