Loading crates/s3s/Cargo.toml +6 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,12 @@ categories = ["web-programming", "web-programming::http-server"] all-features = true rustdoc-args = ["--cfg", "docsrs"] [features] openssl = ["dep:openssl"] [target.'cfg(not(windows))'.dependencies] openssl = { version = "0.10.62", optional = true } [dependencies] arrayvec = "0.7.4" async-trait = "0.1.73" Loading crates/s3s/src/sig_v4/methods.rs +1 −32 Original line number Diff line number Diff line Loading @@ -4,46 +4,15 @@ use super::AmzDate; use crate::auth::SecretKey; use crate::http::OrderedHeaders; use crate::utils::crypto::hmac_sha256; use crate::utils::crypto::{hex, hex_sha256, hex_sha256_chunk, hmac_sha256}; use crate::utils::stable_sort_by_first; use std::mem::MaybeUninit; use hex_simd::{AsOut, AsciiCase}; use hyper::body::Bytes; use hyper::Method; use rust_utils::str::StrExt; use sha2::{Digest, Sha256}; use smallvec::SmallVec; use zeroize::Zeroize; /// `f(hex(src))` fn hex_bytes32<R>(src: &[u8; 32], f: impl FnOnce(&str) -> R) -> R { let buf: &mut [_] = &mut [MaybeUninit::uninit(); 64]; let ans = hex_simd::encode_as_str(src.as_ref(), buf.as_out(), AsciiCase::Lower); f(ans) } /// `f(hex(sha256(data)))` fn hex_sha256<R>(data: &[u8], f: impl FnOnce(&str) -> R) -> R { let src = Sha256::digest(data); hex_bytes32(src.as_ref(), f) } /// `f(hex(sha256(chunk)))` fn hex_sha256_chunk<R>(chunk: &[Bytes], f: impl FnOnce(&str) -> R) -> R { let src = { let mut h = Sha256::new(); chunk.iter().for_each(|data| h.update(data)); h.finalize() }; hex_bytes32(src.as_ref(), f) } fn hex(data: impl AsRef<[u8]>) -> String { hex_simd::encode_to_string(data, hex_simd::AsciiCase::Lower) } /// custom uri encode #[allow(clippy::indexing_slicing, clippy::inline_always, clippy::unwrap_used)] fn uri_encode(output: &mut String, input: &str, encode_slash: bool) { Loading crates/s3s/src/utils/crypto.rs +56 −0 Original line number Diff line number Diff line use std::mem::MaybeUninit; use hex_simd::{AsOut, AsciiCase}; use hyper::body::Bytes; /// verify sha256 checksum string pub fn is_sha256_checksum(s: &str) -> bool { // TODO: optimize Loading @@ -24,3 +29,54 @@ pub fn hmac_sha256(key: impl AsRef<[u8]>, data: impl AsRef<[u8]>) -> [u8; 32] { m.update(data.as_ref()); m.finalize().into_bytes().into() } pub fn hex(data: impl AsRef<[u8]>) -> String { hex_simd::encode_to_string(data, hex_simd::AsciiCase::Lower) } /// `f(hex(src))` fn hex_bytes32<R>(src: impl AsRef<[u8]>, f: impl FnOnce(&str) -> R) -> R { let buf: &mut [_] = &mut [MaybeUninit::uninit(); 64]; let ans = hex_simd::encode_as_str(src.as_ref(), buf.as_out(), AsciiCase::Lower); f(ans) } #[cfg(not(all(feature = "openssl", not(windows))))] fn sha256(data: &[u8]) -> impl AsRef<[u8; 32]> { use sha2::{Digest, Sha256}; <Sha256 as Digest>::digest(data) } #[cfg(all(feature = "openssl", not(windows)))] fn sha256(data: &[u8]) -> impl AsRef<[u8]> { use openssl::hash::{Hasher, MessageDigest}; let mut h = Hasher::new(MessageDigest::sha256()).unwrap(); h.update(data).unwrap(); h.finish().unwrap() } #[cfg(not(all(feature = "openssl", not(windows))))] fn sha256_chunk(chunk: &[Bytes]) -> impl AsRef<[u8; 32]> { use sha2::{Digest, Sha256}; let mut h = <Sha256 as Digest>::new(); chunk.iter().for_each(|data| h.update(data)); h.finalize() } #[cfg(all(feature = "openssl", not(windows)))] fn sha256_chunk(chunk: &[Bytes]) -> impl AsRef<[u8]> { use openssl::hash::{Hasher, MessageDigest}; let mut h = Hasher::new(MessageDigest::sha256()).unwrap(); chunk.iter().for_each(|data| h.update(data).unwrap()); h.finish().unwrap() } /// `f(hex(sha256(data)))` pub fn hex_sha256<R>(data: &[u8], f: impl FnOnce(&str) -> R) -> R { hex_bytes32(sha256(data).as_ref(), f) } /// `f(hex(sha256(chunk)))` pub fn hex_sha256_chunk<R>(chunk: &[Bytes], f: impl FnOnce(&str) -> R) -> R { hex_bytes32(sha256_chunk(chunk).as_ref(), f) } Loading
crates/s3s/Cargo.toml +6 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,12 @@ categories = ["web-programming", "web-programming::http-server"] all-features = true rustdoc-args = ["--cfg", "docsrs"] [features] openssl = ["dep:openssl"] [target.'cfg(not(windows))'.dependencies] openssl = { version = "0.10.62", optional = true } [dependencies] arrayvec = "0.7.4" async-trait = "0.1.73" Loading
crates/s3s/src/sig_v4/methods.rs +1 −32 Original line number Diff line number Diff line Loading @@ -4,46 +4,15 @@ use super::AmzDate; use crate::auth::SecretKey; use crate::http::OrderedHeaders; use crate::utils::crypto::hmac_sha256; use crate::utils::crypto::{hex, hex_sha256, hex_sha256_chunk, hmac_sha256}; use crate::utils::stable_sort_by_first; use std::mem::MaybeUninit; use hex_simd::{AsOut, AsciiCase}; use hyper::body::Bytes; use hyper::Method; use rust_utils::str::StrExt; use sha2::{Digest, Sha256}; use smallvec::SmallVec; use zeroize::Zeroize; /// `f(hex(src))` fn hex_bytes32<R>(src: &[u8; 32], f: impl FnOnce(&str) -> R) -> R { let buf: &mut [_] = &mut [MaybeUninit::uninit(); 64]; let ans = hex_simd::encode_as_str(src.as_ref(), buf.as_out(), AsciiCase::Lower); f(ans) } /// `f(hex(sha256(data)))` fn hex_sha256<R>(data: &[u8], f: impl FnOnce(&str) -> R) -> R { let src = Sha256::digest(data); hex_bytes32(src.as_ref(), f) } /// `f(hex(sha256(chunk)))` fn hex_sha256_chunk<R>(chunk: &[Bytes], f: impl FnOnce(&str) -> R) -> R { let src = { let mut h = Sha256::new(); chunk.iter().for_each(|data| h.update(data)); h.finalize() }; hex_bytes32(src.as_ref(), f) } fn hex(data: impl AsRef<[u8]>) -> String { hex_simd::encode_to_string(data, hex_simd::AsciiCase::Lower) } /// custom uri encode #[allow(clippy::indexing_slicing, clippy::inline_always, clippy::unwrap_used)] fn uri_encode(output: &mut String, input: &str, encode_slash: bool) { Loading
crates/s3s/src/utils/crypto.rs +56 −0 Original line number Diff line number Diff line use std::mem::MaybeUninit; use hex_simd::{AsOut, AsciiCase}; use hyper::body::Bytes; /// verify sha256 checksum string pub fn is_sha256_checksum(s: &str) -> bool { // TODO: optimize Loading @@ -24,3 +29,54 @@ pub fn hmac_sha256(key: impl AsRef<[u8]>, data: impl AsRef<[u8]>) -> [u8; 32] { m.update(data.as_ref()); m.finalize().into_bytes().into() } pub fn hex(data: impl AsRef<[u8]>) -> String { hex_simd::encode_to_string(data, hex_simd::AsciiCase::Lower) } /// `f(hex(src))` fn hex_bytes32<R>(src: impl AsRef<[u8]>, f: impl FnOnce(&str) -> R) -> R { let buf: &mut [_] = &mut [MaybeUninit::uninit(); 64]; let ans = hex_simd::encode_as_str(src.as_ref(), buf.as_out(), AsciiCase::Lower); f(ans) } #[cfg(not(all(feature = "openssl", not(windows))))] fn sha256(data: &[u8]) -> impl AsRef<[u8; 32]> { use sha2::{Digest, Sha256}; <Sha256 as Digest>::digest(data) } #[cfg(all(feature = "openssl", not(windows)))] fn sha256(data: &[u8]) -> impl AsRef<[u8]> { use openssl::hash::{Hasher, MessageDigest}; let mut h = Hasher::new(MessageDigest::sha256()).unwrap(); h.update(data).unwrap(); h.finish().unwrap() } #[cfg(not(all(feature = "openssl", not(windows))))] fn sha256_chunk(chunk: &[Bytes]) -> impl AsRef<[u8; 32]> { use sha2::{Digest, Sha256}; let mut h = <Sha256 as Digest>::new(); chunk.iter().for_each(|data| h.update(data)); h.finalize() } #[cfg(all(feature = "openssl", not(windows)))] fn sha256_chunk(chunk: &[Bytes]) -> impl AsRef<[u8]> { use openssl::hash::{Hasher, MessageDigest}; let mut h = Hasher::new(MessageDigest::sha256()).unwrap(); chunk.iter().for_each(|data| h.update(data).unwrap()); h.finish().unwrap() } /// `f(hex(sha256(data)))` pub fn hex_sha256<R>(data: &[u8], f: impl FnOnce(&str) -> R) -> R { hex_bytes32(sha256(data).as_ref(), f) } /// `f(hex(sha256(chunk)))` pub fn hex_sha256_chunk<R>(chunk: &[Bytes], f: impl FnOnce(&str) -> R) -> R { hex_bytes32(sha256_chunk(chunk).as_ref(), f) }