Unverified Commit 2d1e5d5a authored by Michael Rossberg's avatar Michael Rossberg Committed by GitHub
Browse files

Added Openssl feature (#125)



* try to use sha from openssl

* capsule in feature

* disable openssl on windows

* s3s: utils: crypto: openssl sha256

---------

Co-authored-by: default avatarNugine <nugine@foxmail.com>
parent cff9779e
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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"
+1 −32
Original line number Diff line number Diff line
@@ -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) {
+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
@@ -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)
}