From b03572dccaa73a66212746b79869e69c9c301880 Mon Sep 17 00:00:00 2001 From: Chris Pick Date: Wed, 14 Aug 2024 19:33:58 -0400 Subject: [PATCH] Fix signature mismatch by sorting query parameters https://cloud.google.com/storage/docs/authentication/canonical-requests#about-query-strings > The parameters in the query string must be sorted by name using a > lexicographical sort by code point value. Fixes #298 --- storage/src/sign.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/storage/src/sign.rs b/storage/src/sign.rs index 9dc21a72..ef7cd1e9 100644 --- a/storage/src/sign.rs +++ b/storage/src/sign.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use std::fmt::{Debug, Formatter}; use std::ops::Deref; use std::time::{Duration, SystemTime}; @@ -213,13 +213,20 @@ pub(crate) fn create_signed_buffer( // append query parameters { + let mut query_parameters = [ + ("X-Goog-Algorithm", "GOOG4-RSA-SHA256"), + ("X-Goog-Credential", &format!("{}/{}", google_access_id, credential_scope)), + ("X-Goog-Date", ×tamp), + ("X-Goog-Expires", opts.expires.as_secs().to_string().as_str()), + ("X-Goog-SignedHeaders", &signed_headers), + ] + .into_iter() + .map(|(key, value)| (key.to_owned(), vec![value.to_owned()])) + .collect::>(); + query_parameters.extend(opts.query_parameters.clone()); + let mut query = builder.query_pairs_mut(); - query.append_pair("X-Goog-Algorithm", "GOOG4-RSA-SHA256"); - query.append_pair("X-Goog-Credential", &format!("{}/{}", google_access_id, credential_scope)); - query.append_pair("X-Goog-Date", ×tamp); - query.append_pair("X-Goog-Expires", opts.expires.as_secs().to_string().as_str()); - query.append_pair("X-Goog-SignedHeaders", &signed_headers); - for (k, values) in &opts.query_parameters { + for (k, values) in &query_parameters { for value in values { query.append_pair(k.as_str(), value.as_str()); }