Skip to content

Commit

Permalink
feat(crypto-helper): crypto-helper: implement \HmacSha\ algorithm;
Browse files Browse the repository at this point in the history
  • Loading branch information
TheBestTvarynka committed Dec 6, 2024
1 parent 69dd4cd commit 758d155
Show file tree
Hide file tree
Showing 9 changed files with 694 additions and 303 deletions.
589 changes: 303 additions & 286 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ tracing = "0.1"
hex = "0.4"
gloo-timers = "0.3"
serde = { version = "1.0", features = ["derive"] }
serde_qs = "0.13"
serde_qs = "0.12"
serde_json = "1.0"
base64 = "0.22"
time = { version = "0.3", features = ["local-offset", "wasm-bindgen"] }
Expand All @@ -52,11 +52,11 @@ time = { version = "0.3", features = ["local-offset", "wasm-bindgen"] }
picky-krb = { git = "https://github.com/TheBestTravynka/picky-rs.git", rev = "604a246" }
picky = { version = "7.0.0-rc.8", default-features = false }
md5 = "0.7"
sha1 = "0.10"
sha1 = "0.11.0-pre.3"
sha2 = "0.10.8"
hmac = "0.12.1"
rsa = "0.9"
bcrypt = "0.16"
bcrypt = "0.15"
flate2 = { version = "1.0", features = ["zlib"] }
rand = { version = "0.9.0-alpha.0", features = ["small_rng"] }
rand_chacha = "0.9.0-alpha.0"
Expand All @@ -69,4 +69,4 @@ oid = { version = "0.2", default-features = false }
paste = "1.0"

# diff
similar = { version = "2.6", features = ["serde"] }
similar = { version = "2.4", features = ["serde"] }
100 changes: 93 additions & 7 deletions src/crypto_helper/algorithm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ pub const SHA384: &str = "SHA384";
pub const BCRYPT: &str = "BCRYPT";
pub const ZLIB: &str = "ZLIB";
pub const ARGON2: &str = "ARGON2";
pub const HMAC_SHA: &str = "HMAC-SHA";

pub const SUPPORTED_ALGORITHMS: [&str; 13] = [
pub const SUPPORTED_ALGORITHMS: [&str; 14] = [
MD5,
SHA1,
SHA256,
Expand All @@ -34,13 +35,16 @@ pub const SUPPORTED_ALGORITHMS: [&str; 13] = [
BCRYPT,
ZLIB,
ARGON2,
HMAC_SHA,
];

pub const HASHING_ALGOS: [&str; 7] = [MD5, SHA1, SHA256, SHA384, SHA512, BCRYPT, ARGON2];

pub const ENCRYPTION_ALGOS: [&str; 3] = [AES128_CTS_HMAC_SHA1_96, AES256_CTS_HMAC_SHA1_96, RSA];

pub const HMAC_ALGOS: [&str; 2] = [HMAC_SHA1_96_AES128, HMAC_SHA1_96_AES256];
pub const HMAC_ALGOS: [&str; 3] = [HMAC_SHA1_96_AES128, HMAC_SHA1_96_AES256, HMAC_SHA];

pub const HMAC_HASH_ALGOS: [&str; 3] = [SHA256, SHA384, SHA512];

pub const COMPRESSION_ALGOS: [&str; 1] = [ZLIB];

Expand Down Expand Up @@ -87,10 +91,7 @@ pub enum KrbMode {

impl From<KrbMode> for bool {
fn from(mode: KrbMode) -> Self {
match mode {
KrbMode::Encrypt => false,
KrbMode::Decrypt => true,
}
matches!(mode, KrbMode::Decrypt)
}
}

Expand Down Expand Up @@ -531,6 +532,87 @@ impl From<&Argon2Action> for bool {
}
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Default)]
pub enum HmacShaAction {
#[default]
Sign,
#[serde(serialize_with = "serialize_bytes", deserialize_with = "deserialize_bytes")]
Verify(Vec<u8>),
}

impl From<bool> for HmacShaAction {
fn from(value: bool) -> Self {
if value {
Self::Verify(Vec::new())
} else {
Self::Sign
}
}
}

impl From<&HmacShaAction> for bool {
fn from(value: &HmacShaAction) -> Self {
matches!(value, HmacShaAction::Verify(_))
}
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub enum HmacShaAlgorithm {
Sha256,
Sha384,
Sha512,
}

impl TryFrom<&str> for HmacShaAlgorithm {
type Error = String;

fn try_from(value: &str) -> Result<Self, Self::Error> {
Ok(match value {
SHA256 => Self::Sha256,
SHA384 => Self::Sha384,
SHA512 => Self::Sha512,
_ => return Err(format!("hmac: unsupported hash algorithm: {}", value)),
})
}
}

impl AsRef<str> for HmacShaAlgorithm {
fn as_ref(&self) -> &str {
match self {
HmacShaAlgorithm::Sha256 => SHA256,
HmacShaAlgorithm::Sha384 => SHA384,
HmacShaAlgorithm::Sha512 => SHA512,
}
}
}

impl PartialEq<&str> for HmacShaAlgorithm {
fn eq(&self, other: &&str) -> bool {
self.as_ref() == *other
}
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct HmacShaInput {
pub hash_alg: HmacShaAlgorithm,
#[serde(serialize_with = "serialize_bytes", deserialize_with = "deserialize_bytes")]
pub key: Vec<u8>,
#[serde(serialize_with = "serialize_bytes", deserialize_with = "deserialize_bytes")]
pub msg: Vec<u8>,
pub action: HmacShaAction,
}

impl Default for HmacShaInput {
fn default() -> Self {
Self {
hash_alg: HmacShaAlgorithm::Sha256,
key: Default::default(),
msg: Default::default(),
action: Default::default(),
}
}
}

#[allow(clippy::large_enum_variant)]
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub enum Algorithm {
Expand All @@ -552,6 +634,7 @@ pub enum Algorithm {
Bcrypt(BcryptInput),
Zlib(ZlibInput),
Argon2(Argon2Input),
HmacSha(HmacShaInput),
}

impl TryFrom<&str> for Algorithm {
Expand Down Expand Up @@ -584,6 +667,8 @@ impl TryFrom<&str> for Algorithm {
return Ok(Algorithm::Zlib(Default::default()));
} else if value == ARGON2 {
return Ok(Algorithm::Argon2(Default::default()));
} else if value == HMAC_SHA {
return Ok(Algorithm::HmacSha(Default::default()));
}

Err(format!(
Expand All @@ -609,6 +694,7 @@ impl From<&Algorithm> for &str {
Algorithm::Bcrypt(_) => BCRYPT,
Algorithm::Zlib(_) => ZLIB,
Algorithm::Argon2(_) => ARGON2,
Algorithm::HmacSha(_) => HMAC_SHA,
}
}
}
Expand All @@ -623,6 +709,6 @@ impl PartialEq<&str> for &Algorithm {

impl Default for Algorithm {
fn default() -> Self {
Algorithm::Zlib(Default::default())
Algorithm::HmacSha(Default::default())
}
}
125 changes: 123 additions & 2 deletions src/crypto_helper/computations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use rsa::rand_core::OsRng;
use rsa::Pkcs1v15Encrypt;

use super::algorithm::{
Argon2Action, Argon2Input, BcryptAction, BcryptInput, KrbInput, KrbInputData, KrbMode, RsaAction, RsaInput,
ZlibInput, ZlibMode,
Argon2Action, Argon2Input, BcryptAction, BcryptInput, HmacShaAction, HmacShaAlgorithm, HmacShaInput, KrbInput,
KrbInputData, KrbMode, RsaAction, RsaInput, ZlibInput, ZlibMode,
};

pub fn process_rsa(input: &RsaInput) -> Result<Vec<u8>, String> {
Expand Down Expand Up @@ -132,3 +132,124 @@ pub fn process_argon2(input: &Argon2Input) -> Result<Vec<u8>, String> {
}
}
}

pub fn process_hmac_sha(input: &HmacShaInput) -> Result<Vec<u8>, String> {
let HmacShaInput {
hash_alg,
key,
msg,
action,
} = input;

match &action {
HmacShaAction::Sign => match hash_alg {
HmacShaAlgorithm::Sha256 => {
if key.len() < 32 {
return Err(format!(
"hmac: invalid key length: expected at least 32 bytes but got {}",
key.len()
));
}

Ok(sign_hmac!(
hash_alg: sha2::Sha256,
key: key,
msg: msg,
))
}
HmacShaAlgorithm::Sha384 => {
if key.len() < 48 {
return Err(format!(
"hmac: invalid key length: expected at least 48 bytes but got {}",
key.len()
));
}

Ok(sign_hmac!(
hash_alg: sha2::Sha384,
key: key,
msg: msg,
))
}
HmacShaAlgorithm::Sha512 => {
if key.len() < 64 {
return Err(format!(
"hmac: invalid key length: expected at least 64 bytes but got {}",
key.len()
));
}

Ok(sign_hmac!(
hash_alg: sha2::Sha512,
key: key,
msg: msg,
))
}
},
HmacShaAction::Verify(digest) => match hash_alg {
HmacShaAlgorithm::Sha256 => {
if key.len() < 32 {
return Err(format!(
"hmac: invalid key length: expected at least 32 bytes but got {}",
key.len()
));
}

Ok(
if verify_hmac!(
hash_alg: sha2::Sha256,
key: key,
msg: msg,
digest: digest.as_slice(),
) {
vec![1]
} else {
vec![0]
},
)
}
HmacShaAlgorithm::Sha384 => {
if key.len() < 48 {
return Err(format!(
"hmac: invalid key length: expected at least 48 bytes but got {}",
key.len()
));
}

Ok(
if verify_hmac!(
hash_alg: sha2::Sha384,
key: key,
msg: msg,
digest: digest.as_slice(),
) {
vec![1]
} else {
vec![0]
},
)
}
HmacShaAlgorithm::Sha512 => {
if key.len() < 64 {
return Err(format!(
"hmac: invalid key length: expected at least 64 bytes but got {}",
key.len()
));
}

Ok(
if verify_hmac!(
hash_alg: sha2::Sha512,
key: key,
msg: msg,
digest: digest.as_slice(),
) {
vec![1]
} else {
vec![0]
},
)
}
},
}
}
7 changes: 6 additions & 1 deletion src/crypto_helper/info/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,15 @@ fn get_algorithm_info(algorithm: &Algorithm) -> Html {
</span>
},
Algorithm::Argon2(_) => html! {
<span>{"Use Argon2 to encrypt/verify your data."}
<span>{"Use Argon2 to hash/verify your data."}
<a href="https://www.rfc-editor.org/rfc/inline-errata/rfc9106.html">{"RFC"}</a>
</span>
},
Algorithm::HmacSha(_) => html! {
<span>{"Use HMAC-SHA to sign/verify your data."}
<a href="https://www.rfc-editor.org/rfc/rfc6234">{"RFC"}</a>
</span>
},
}
}

Expand Down
Loading

0 comments on commit 758d155

Please sign in to comment.