aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2024-02-27 23:46:49 +0100
committerAlex Auvolat <alex@adnab.me>2024-02-28 12:24:21 +0100
commita5e4bfeae9d705e0c8a56dfd8268e1309999c5cd (patch)
treed7aba3377c3af35d93c75b7adb09bd420a07e6bd
parent4c1d42cc5fcaa69818ec177f19577ad57952a117 (diff)
downloadgarage-a5e4bfeae9d705e0c8a56dfd8268e1309999c5cd.tar.gz
garage-a5e4bfeae9d705e0c8a56dfd8268e1309999c5cd.zip
[fix-presigned] write comments
-rw-r--r--src/api/signature/payload.rs21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/api/signature/payload.rs b/src/api/signature/payload.rs
index c88bb144..8a7a4341 100644
--- a/src/api/signature/payload.rs
+++ b/src/api/signature/payload.rs
@@ -40,10 +40,10 @@ pub async fn check_payload_signature(
) -> Result<(Option<Key>, Option<Hash>), Error> {
let query = parse_query_map(request.uri())?;
- if query.contains_key(X_AMZ_ALGORITHM.as_str()) {
- check_presigned_signature(garage, service, request, query).await
- } else if request.headers().contains_key(AUTHORIZATION) {
+ if request.headers().contains_key(AUTHORIZATION) {
check_standard_signature(garage, service, request, query).await
+ } else if query.contains_key(X_AMZ_ALGORITHM.as_str()) {
+ check_presigned_signature(garage, service, request, query).await
} else {
// Unsigned (anonymous) request
let content_sha256 = request
@@ -70,7 +70,11 @@ async fn check_standard_signature(
) -> Result<(Option<Key>, Option<Hash>), Error> {
let authorization = Authorization::parse(request.headers())?;
- // Verify that all necessary request headers are signed
+ // Verify that all necessary request headers are included in signed_headers
+ // For standard AWSv4 signatures, the following must be incldued:
+ // - the Host header (in all cases)
+ // - the Content-Type header, if it is used in the request
+ // - all x-amz-* headers used in the request
let signed_headers = split_signed_headers(&authorization)?;
if !signed_headers.contains(&HOST) {
return Err(Error::bad_request("Header `Host` should be signed"));
@@ -129,7 +133,10 @@ async fn check_presigned_signature(
let algorithm = query.get(X_AMZ_ALGORITHM.as_str()).unwrap();
let authorization = Authorization::parse_presigned(algorithm, &query)?;
- // Check that all mandatory signed headers are included
+ // Verify that all necessary request headers are included in signed_headers
+ // For AWSv4 pre-signed URLs, the following must be incldued:
+ // - the Host header (in all cases)
+ // - all x-amz-* headers used in the request
let signed_headers = split_signed_headers(&authorization)?;
if !signed_headers.contains(&HOST) {
return Err(Error::bad_request("Header `Host` should be signed"));
@@ -145,6 +152,10 @@ async fn check_presigned_signature(
}
}
+ // The X-Amz-Signature value is passed as a query parameter,
+ // but the signature cannot be computed from a string that contains itself.
+ // AWS specifies that all query params except X-Amz-Signature are included
+ // in the canonical request.
query.remove(X_AMZ_SIGNATURE.as_str());
let canonical_request = canonical_request(
service,