aboutsummaryrefslogtreecommitdiff
path: root/src/api/signature/mod.rs
diff options
context:
space:
mode:
authorJill <kokakiwi@deuxfleurs.fr>2022-01-17 10:55:31 +0100
committerAlex <alex@adnab.me>2022-01-17 10:55:31 +0100
commitb45dcc1925d76f3f7dcae7deea0391953ba548e5 (patch)
tree85600f90c41532dc0b50e395e6ea85ca8ba08f53 /src/api/signature/mod.rs
parent60c0033c8bbd3dbc18f8c91f15674a60fd8acdc0 (diff)
downloadgarage-b45dcc1925d76f3f7dcae7deea0391953ba548e5.tar.gz
garage-b45dcc1925d76f3f7dcae7deea0391953ba548e5.zip
Support STREAMING-AWS4-HMAC-SHA256-PAYLOAD (#64) (#156)
Closes #64. Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/156 Co-authored-by: Jill <kokakiwi@deuxfleurs.fr> Co-committed-by: Jill <kokakiwi@deuxfleurs.fr>
Diffstat (limited to 'src/api/signature/mod.rs')
-rw-r--r--src/api/signature/mod.rs47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/api/signature/mod.rs b/src/api/signature/mod.rs
new file mode 100644
index 00000000..ebdee6da
--- /dev/null
+++ b/src/api/signature/mod.rs
@@ -0,0 +1,47 @@
+use chrono::{DateTime, Utc};
+use hmac::{Hmac, Mac, NewMac};
+use sha2::Sha256;
+
+use garage_util::data::{sha256sum, Hash};
+
+use crate::error::*;
+
+pub mod payload;
+pub mod streaming;
+
+pub const SHORT_DATE: &str = "%Y%m%d";
+pub const LONG_DATETIME: &str = "%Y%m%dT%H%M%SZ";
+
+type HmacSha256 = Hmac<Sha256>;
+
+pub fn verify_signed_content(expected_sha256: Hash, body: &[u8]) -> Result<(), Error> {
+ if expected_sha256 != sha256sum(body) {
+ return Err(Error::BadRequest(
+ "Request content hash does not match signed hash".to_string(),
+ ));
+ }
+ Ok(())
+}
+
+pub fn signing_hmac(
+ datetime: &DateTime<Utc>,
+ secret_key: &str,
+ region: &str,
+ service: &str,
+) -> Result<HmacSha256, crypto_mac::InvalidKeyLength> {
+ let secret = String::from("AWS4") + secret_key;
+ let mut date_hmac = HmacSha256::new_varkey(secret.as_bytes())?;
+ date_hmac.update(datetime.format(SHORT_DATE).to_string().as_bytes());
+ let mut region_hmac = HmacSha256::new_varkey(&date_hmac.finalize().into_bytes())?;
+ region_hmac.update(region.as_bytes());
+ let mut service_hmac = HmacSha256::new_varkey(&region_hmac.finalize().into_bytes())?;
+ service_hmac.update(service.as_bytes());
+ let mut signing_hmac = HmacSha256::new_varkey(&service_hmac.finalize().into_bytes())?;
+ signing_hmac.update(b"aws4_request");
+ let hmac = HmacSha256::new_varkey(&signing_hmac.finalize().into_bytes())?;
+ Ok(hmac)
+}
+
+pub fn compute_scope(datetime: &DateTime<Utc>, region: &str) -> String {
+ format!("{}/{}/s3/aws4_request", datetime.format(SHORT_DATE), region,)
+}