use crate::ClientSecret;
pub fn hash(salt: &str, client_secret: &ClientSecret) -> Vec<u8> {
cfg_if::cfg_if! {
if #[cfg(not(fips))] {
hash_native(salt, client_secret)
} else {
hash_fips(salt, client_secret)
}
}
}
#[cfg(not(fips))]
fn hash_native(salt: &str, client_secret: &ClientSecret) -> Vec<u8> {
use sha2::{Digest, Sha256};
let mut hashed_result = [0u8; 32];
let mut hasher = Sha256::new();
hasher.update(format!("{}{}", salt, client_secret.as_str()).as_str());
hashed_result.copy_from_slice(&hasher.finalize());
let result = hex::encode(hashed_result);
result.into_bytes()
}
#[cfg(fips)]
fn hash_fips(salt: &str, client_secret: &ClientSecret) -> Vec<u8> {
use pdk_core::ffi::{GetShaDigestArguments, GetShaDigestResult, Message};
let data = format!("{}{}", salt, client_secret.as_str());
let args = GetShaDigestArguments {
data: data.into_bytes(),
..Default::default()
};
let args_bytes = args
.write_to_bytes()
.unwrap_or_else(|e| panic!("Failed to serialize GetShaDigestArguments: {}", e));
match pdk_core::classy::proxy_wasm::hostcalls::call_foreign_function(
"get_sha_digest",
Some(&args_bytes),
) {
Ok(Some(bytes)) => match GetShaDigestResult::parse_from_bytes(&bytes) {
Ok(result) if result.result => {
let hex_result = hex::encode(result.digest);
hex_result.into_bytes()
}
Ok(result) => panic!("get_sha_digest failed: {}", result.error),
Err(e) => panic!("Failed to parse GetShaDigestResult: {}", e),
},
Ok(None) => panic!("get_sha_digest returned no result"),
Err(e) => panic!("get_sha_digest hostcall failed: {:?}", e),
}
}
#[cfg(test)]
mod tests {
use crate::{implementation::hashing::hash, ClientSecret};
#[test]
#[cfg(not(fips))]
fn hash_simple_value() {
let a_secret = &ClientSecret::new(String::from("gateway"));
let a_salt = "some_salt";
let a_hashed_secret = "ada97098baab31248ff4cdd1540e65acfd997fbd05863bd25e67a17d3c30fff3";
assert_eq!(hash(a_salt, a_secret), a_hashed_secret.as_bytes());
}
}