Commit f5ff0bc0 authored by Nugine's avatar Nugine
Browse files

refactor(s3s/sig_v4): support service parameter

parent d165e2dc
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -40,6 +40,9 @@ struct SignatureCtx {
    /// region
    region: Box<str>,

    //// service
    service: Box<str>,

    /// secret key
    secret_key: SecretKey,

@@ -93,7 +96,8 @@ fn parse_chunk_meta(mut input: &[u8]) -> nom::IResult<&[u8], ChunkMeta<'_>> {

/// check signature
fn check_signature(ctx: &SignatureCtx, expected_signature: &[u8], chunk_data: &[Bytes]) -> Option<Box<str>> {
    let string_to_sign = sig_v4::create_chunk_string_to_sign(&ctx.amz_date, &ctx.region, &ctx.prev_signature, 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);

@@ -107,6 +111,7 @@ impl AwsChunkedStream {
        seed_signature: Box<str>,
        amz_date: AmzDate,
        region: Box<str>,
        service: Box<str>,
        secret_key: SecretKey,
        decoded_content_length: usize,
    ) -> Self
@@ -122,6 +127,7 @@ impl AwsChunkedStream {
                let mut ctx = SignatureCtx {
                    amz_date,
                    region,
                    service,
                    secret_key,
                    prev_signature: seed_signature,
                };
@@ -340,6 +346,7 @@ mod tests {
        let seed_signature = "4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9";
        let timestamp = "20130524T000000Z";
        let region = "us-east-1";
        let service = "s3";
        let secret_access_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";

        let date = AmzDate::parse(timestamp).unwrap();
@@ -350,6 +357,7 @@ mod tests {
            seed_signature.into(),
            date,
            region.into(),
            service.into(),
            secret_access_key.into(),
            decoded_content_length,
        );
+5 −2
Original line number Diff line number Diff line
@@ -216,8 +216,9 @@ impl SignatureContext<'_> {
            let canonical_request = sig_v4::create_presigned_canonical_request(method, uri_path, qs.as_ref(), &headers);

            let region = presigned_url.credential.aws_region;
            let service = presigned_url.credential.aws_service;
            let amz_date = &presigned_url.amz_date;
            let string_to_sign = sig_v4::create_string_to_sign(&canonical_request, amz_date, region);
            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)
        };
@@ -297,7 +298,8 @@ impl SignatureContext<'_> {
            };

            let region = authorization.credential.aws_region;
            let string_to_sign = sig_v4::create_string_to_sign(&canonical_request, &amz_date, 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)
        };

@@ -317,6 +319,7 @@ impl SignatureContext<'_> {
                signature.into(),
                amz_date,
                authorization.credential.aws_region.into(),
                authorization.credential.aws_service.into(),
                secret_key.clone(),
                decoded_content_length,
            );
+36 −14
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ pub fn create_canonical_request(

/// create string to sign
#[must_use]
pub fn create_string_to_sign(canonical_request: &str, amz_date: &AmzDate, region: &str) -> String {
pub fn create_string_to_sign(canonical_request: &str, amz_date: &AmzDate, region: &str, service: &str) -> String {
    let mut ans = String::with_capacity(256);

    {
@@ -204,7 +204,9 @@ pub fn create_string_to_sign(canonical_request: &str, amz_date: &AmzDate, region
        ans.push_str(&amz_date.fmt_date());
        ans.push('/');
        ans.push_str(region); // TODO: use a `Region` type
        ans.push_str("/s3/aws4_request\n");
        ans.push('/');
        ans.push_str(service);
        ans.push_str("/aws4_request\n");
    }

    {
@@ -216,7 +218,13 @@ pub fn create_string_to_sign(canonical_request: &str, amz_date: &AmzDate, region
}

/// create `string_to_sign` of a chunk
pub fn create_chunk_string_to_sign(amz_date: &AmzDate, region: &str, prev_signature: &str, chunk_data: &[Bytes]) -> String {
pub fn create_chunk_string_to_sign(
    amz_date: &AmzDate,
    region: &str,
    service: &str,
    prev_signature: &str,
    chunk_data: &[Bytes],
) -> String {
    let mut ans = String::with_capacity(256);

    {
@@ -230,7 +238,9 @@ pub fn create_chunk_string_to_sign(amz_date: &AmzDate, region: &str, prev_signat
        ans.push_str(&amz_date.fmt_date());
        ans.push('/');
        ans.push_str(region); // TODO: use a `Region` type
        ans.push_str("/s3/aws4_request\n");
        ans.push('/');
        ans.push_str(service);
        ans.push_str("/aws4_request\n");
    }
    {
        ans.push_str(prev_signature);
@@ -385,6 +395,7 @@ mod tests {
        let timestamp = "20130524T000000Z";
        // let bucket = "examplebucket";
        let region = "us-east-1";
        let service = "s3";
        let path = "/test.txt";

        let headers = OrderedHeaders::from_slice_unchecked(&[
@@ -416,7 +427,7 @@ mod tests {
        );

        let date = AmzDate::parse(timestamp).unwrap();
        let string_to_sign = create_string_to_sign(&canonical_request, &date, region);
        let string_to_sign = create_string_to_sign(&canonical_request, &date, region, service);
        assert_eq!(
            string_to_sign,
            concat!(
@@ -438,6 +449,7 @@ mod tests {
        let timestamp = "20130524T000000Z";
        // let bucket = "examplebucket";
        let region = "us-east-1";
        let service = "s3";
        let path = "/test$file.text";

        let headers = OrderedHeaders::from_slice_unchecked(&[
@@ -472,7 +484,7 @@ mod tests {
        );

        let date = AmzDate::parse(timestamp).unwrap();
        let string_to_sign = create_string_to_sign(&canonical_request, &date, region);
        let string_to_sign = create_string_to_sign(&canonical_request, &date, region, service);
        assert_eq!(
            string_to_sign,
            concat!(
@@ -494,6 +506,7 @@ mod tests {
        let timestamp = "20130524T000000Z";
        // let bucket = "examplebucket";
        let region = "us-east-1";
        let service = "s3";
        let path = "/examplebucket/chunkObject.txt";

        let headers = OrderedHeaders::from_slice_unchecked(&[
@@ -531,7 +544,7 @@ mod tests {
        );

        let date = AmzDate::parse(timestamp).unwrap();
        let string_to_sign = create_string_to_sign(&canonical_request, &date, region);
        let string_to_sign = create_string_to_sign(&canonical_request, &date, region, service);
        assert_eq!(
            string_to_sign,
            concat!(
@@ -551,12 +564,13 @@ mod tests {
        let secret_access_key = SecretKey::from("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY");
        let timestamp = "20130524T000000Z";
        let region = "us-east-1";
        let service = "s3";
        let date = AmzDate::parse(timestamp).unwrap();

        let seed_signature = "4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9";

        let chunk1_string_to_sign =
            create_chunk_string_to_sign(&date, region, seed_signature, &[Bytes::from(vec![b'a'; 64 * 1024])]);
            create_chunk_string_to_sign(&date, region, service, seed_signature, &[Bytes::from(vec![b'a'; 64 * 1024])]);
        assert_eq!(
            chunk1_string_to_sign,
            concat!(
@@ -573,7 +587,7 @@ mod tests {
        assert_eq!(chunk1_signature, "ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648");

        let chunk2_string_to_sign =
            create_chunk_string_to_sign(&date, region, &chunk1_signature, &[Bytes::from(vec![b'a'; 1024])]);
            create_chunk_string_to_sign(&date, region, service, &chunk1_signature, &[Bytes::from(vec![b'a'; 1024])]);
        assert_eq!(
            chunk2_string_to_sign,
            concat!(
@@ -589,7 +603,7 @@ mod tests {
        let chunk2_signature = calculate_signature(&chunk2_string_to_sign, &secret_access_key, &date, region);
        assert_eq!(chunk2_signature, "0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497");

        let chunk3_string_to_sign = create_chunk_string_to_sign(&date, region, &chunk2_signature, &[]);
        let chunk3_string_to_sign = create_chunk_string_to_sign(&date, region, service, &chunk2_signature, &[]);
        assert_eq!(
            chunk3_string_to_sign,
            concat!(
@@ -613,6 +627,7 @@ mod tests {
        let timestamp = "20130524T000000Z";
        // let bucket = "examplebucket";
        let region = "us-east-1";
        let service = "s3";
        let path = "/";

        let headers = OrderedHeaders::from_slice_unchecked(&[
@@ -642,7 +657,7 @@ mod tests {
        );

        let date = AmzDate::parse(timestamp).unwrap();
        let string_to_sign = create_string_to_sign(&canonical_request, &date, region);
        let string_to_sign = create_string_to_sign(&canonical_request, &date, region, service);
        assert_eq!(
            string_to_sign,
            concat!(
@@ -664,6 +679,7 @@ mod tests {
        let timestamp = "20130524T000000Z";
        // let bucket = "examplebucket";
        let region = "us-east-1";
        let service = "s3";
        let path = "/";

        let headers = OrderedHeaders::from_slice_unchecked(&[
@@ -694,7 +710,7 @@ mod tests {
        );

        let date = AmzDate::parse(timestamp).unwrap();
        let string_to_sign = create_string_to_sign(&canonical_request, &date, region);
        let string_to_sign = create_string_to_sign(&canonical_request, &date, region, service);
        assert_eq!(
            string_to_sign,
            concat!(
@@ -755,7 +771,12 @@ mod tests {
            "UNSIGNED-PAYLOAD",
        ));

        let string_to_sign = create_string_to_sign(&canonical_request, &info.amz_date, info.credential.aws_region);
        let string_to_sign = create_string_to_sign(
            &canonical_request,
            &info.amz_date,
            info.credential.aws_region,
            info.credential.aws_service,
        );
        assert_eq!(
            string_to_sign,
            concat!(
@@ -798,6 +819,7 @@ mod tests {
        let payload = Payload::Empty;
        let date = AmzDate::parse(x_amz_date).unwrap();
        let region = "us-east-1";
        let service = "s3";

        let secret_access_key = SecretKey::from("minioadmin");

@@ -812,7 +834,7 @@ mod tests {

            let canonical_request = create_canonical_request(req.method(), uri_path, query_strings, &signed_headers, payload);

            let string_to_sign = create_string_to_sign(&canonical_request, &date, region);
            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);
            assert_eq!(signature, "96ad058ca27352e0fc2bd4efd8973792077570667bdaf749655f42e204bc649c");