Skip to content

Commit

Permalink
Added Openssl feature (#125)
Browse files Browse the repository at this point in the history
* try to use sha from openssl

* capsule in feature

* disable openssl on windows

* s3s: utils: crypto: openssl sha256

---------

Co-authored-by: Nugine <[email protected]>
  • Loading branch information
nomick and Nugine authored Jan 24, 2024
1 parent cff9779 commit 2d1e5d5
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 32 deletions.
6 changes: 6 additions & 0 deletions crates/s3s/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
33 changes: 1 addition & 32 deletions crates/s3s/src/sig_v4/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
56 changes: 56 additions & 0 deletions crates/s3s/src/utils/crypto.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
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
Expand All @@ -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)
}

0 comments on commit 2d1e5d5

Please sign in to comment.