Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions plugins/s3_auth/aws_auth_v4.cc
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,22 @@ isUriEncoded(const String &in, bool isObjectName)
return false;
}

String
canonicalEncode(const String &in, bool isObjectName)
{
String canonical;
if (!isUriEncoded(in, isObjectName)) {
/* Not URI-encoded */
canonical = uriEncode(in, isObjectName);
} else {
/* URI-encoded, then don't encode since AWS does not encode which is not mentioned in the spec,
* asked AWS, still waiting for confirmation */
canonical = in;
}

return canonical;
}

/**
* @brief trim the white-space character from the beginning and the end of the string ("in-place", just moving pointers around)
*
Expand Down Expand Up @@ -287,7 +303,7 @@ getCanonicalRequestSha256Hash(TsInterface &api, bool signPayload, const StringSe
str = api.getPath(&length);
String path("/");
path.append(str, length);
String canonicalUri = uriEncode(path, /* isObjectName */ true);
String canonicalUri = canonicalEncode(path, /* isObjectName */ true);
sha256Update(&canonicalRequestSha256Ctx, canonicalUri);
sha256Update(&canonicalRequestSha256Ctx, "\n");

Expand All @@ -306,18 +322,9 @@ getCanonicalRequestSha256Hash(TsInterface &api, bool signPayload, const StringSe
String param(token.substr(0, pos == String::npos ? token.size() : pos));
String value(pos == String::npos ? "" : token.substr(pos + 1, token.size()));

String encodedParam = uriEncode(param, /* isObjectName */ false);

String encodedParam = canonicalEncode(param, /* isObjectName */ false);
paramNames.insert(encodedParam);

if (!isUriEncoded(value, /* isObjectName */ false)) {
/* Not URI-encoded */
paramsMap[encodedParam] = uriEncode(value, /* isObjectName */ false);
} else {
/* URI-encoded, then don't encode since AWS does not encode which is not mentioned in the spec,
* asked AWS, still waiting for confirmation */
paramsMap[encodedParam] = value;
}
paramsMap[encodedParam] = canonicalEncode(value, /* isObjectName */ false);
}

String queryStr;
Expand Down
11 changes: 6 additions & 5 deletions plugins/s3_auth/unit_tests/test_aws_auth_v4.cc
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ TEST_CASE("AWSAuthSpecByExample: GET Bucket List Objects, query param value alre
MockTsInterface api;
api._method.assign("GET");
api._host.assign("examplebucket.s3.amazonaws.com");
api._path.assign("");
api._path.assign("PATH==");
api._query.assign("key=TEST==");
api._headers["Host"] = "examplebucket.s3.amazonaws.com";
api._headers["x-amz-content-sha256"] = "UNSIGNED-PAYLOAD";
Expand All @@ -642,18 +642,18 @@ TEST_CASE("AWSAuthSpecByExample: GET Bucket List Objects, query param value alre
"AWS4-HMAC-SHA256 "
"Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,"
"SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
"Signature=60b410f6a0ffe09b91c2aef1f179945916b45ea215278e6b8f6cfb8d461e3706",
"Signature=3b195c74eaa89790c596114a9fcb8515d6a3cc78577f8941c46b09ee7f501194",
/* Canonical Request sha256 */
"1035b1d75dad9e94fa99fa6edc2cf7d489f38796109a132721621977737a41cc",
"7b3c74369013172ce9cb3da99b5d14e358382953e7b560b4c9bf0a46e73933cb",
/* Date and time*/
"20130524T000000Z",
/* String to sign */
"AWS4-HMAC-SHA256\n"
"20130524T000000Z\n"
"20130524/us-east-1/s3/aws4_request\n"
"1035b1d75dad9e94fa99fa6edc2cf7d489f38796109a132721621977737a41cc",
"7b3c74369013172ce9cb3da99b5d14e358382953e7b560b4c9bf0a46e73933cb",
/* Signature */
"60b410f6a0ffe09b91c2aef1f179945916b45ea215278e6b8f6cfb8d461e3706",
"3b195c74eaa89790c596114a9fcb8515d6a3cc78577f8941c46b09ee7f501194",
/* Payload hash */
"UNSIGNED-PAYLOAD",
/* Signed Headers */
Expand All @@ -664,6 +664,7 @@ TEST_CASE("AWSAuthSpecByExample: GET Bucket List Objects, query param value alre

/* Now make query param value encoded beforehand and expect the same result,
* it should not URI encode it twice according to AWS real behavior undocumented in the specification.*/
api._path.assign("PATH%3D%3D");
api._query.assign("key=TEST%3D%3D");
ValidateBench(api, /*signePayload */ false, &now, bench, defaultIncludeHeaders, defaultExcludeHeaders);
}
Expand Down