Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading