changes
This commit is contained in:
parent
33dd7c5ffc
commit
62521be363
90
src/api/backend/integrity_verification.rs
Normal file
90
src/api/backend/integrity_verification.rs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
use hmac::{Hmac, Mac};
|
||||||
|
use sha2::{Digest, Sha512};
|
||||||
|
|
||||||
|
use crate::errors::ApiError;
|
||||||
|
|
||||||
|
type HashType = Sha512;
|
||||||
|
|
||||||
|
pub trait CustomHash {
|
||||||
|
fn updater(&self, hasher: &mut Sha512);
|
||||||
|
|
||||||
|
fn hash(&self) -> Vec<u8> {
|
||||||
|
let mut hasher = Sha512::new();
|
||||||
|
Self::updater(&self, &mut hasher);
|
||||||
|
hasher.finalize().to_vec()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IntegrityVerifier {
|
||||||
|
mac: Hmac<HashType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntegrityVerifier {
|
||||||
|
pub fn new() -> Result<Self, ApiError> {
|
||||||
|
Ok(Self {
|
||||||
|
mac: Hmac::<HashType>::new_from_slice(
|
||||||
|
include_str!("./verification_secret").as_bytes(),
|
||||||
|
)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sign<T>(&self, data: &T) -> Result<Vec<u8>, ApiError>
|
||||||
|
where
|
||||||
|
T: CustomHash,
|
||||||
|
{
|
||||||
|
let mut mac = self.mac.clone();
|
||||||
|
|
||||||
|
mac.update(&data.hash());
|
||||||
|
let signature = mac.finalize_reset().into_bytes();
|
||||||
|
|
||||||
|
Ok(signature.to_vec())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn verify<T>(&self, data: &T, signature: &[u8]) -> Result<(), ApiError>
|
||||||
|
where
|
||||||
|
T: CustomHash,
|
||||||
|
{
|
||||||
|
let mut mac = self.mac.clone();
|
||||||
|
mac.update(&data.hash());
|
||||||
|
|
||||||
|
match mac.verify_slice_reset(signature) {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(_e) => Err(ApiError::AccessDenied),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use hmac::digest::Update;
|
||||||
|
|
||||||
|
use crate::api::backend::integrity_verification::{CustomHash, IntegrityVerifier};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn integrity_verification() {
|
||||||
|
struct TestData {
|
||||||
|
one: u32,
|
||||||
|
two: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CustomHash for TestData {
|
||||||
|
fn updater(&self, hasher: &mut sha2::Sha512) {
|
||||||
|
hasher.update(&self.one.to_be_bytes());
|
||||||
|
hasher.update(&self.two.as_bytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let verifier = IntegrityVerifier::new().unwrap();
|
||||||
|
|
||||||
|
let mut item = TestData {
|
||||||
|
one: 24,
|
||||||
|
two: "MyTesting".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let signature = verifier.sign(&item).unwrap();
|
||||||
|
assert!(verifier.verify(&item, &signature).is_ok());
|
||||||
|
|
||||||
|
item.two = "Wrong".to_string();
|
||||||
|
assert!(verifier.verify(&item, &signature).is_err());
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ use crate::{api::routes::users::sql::get_users, config::Configuration, errors::A
|
|||||||
|
|
||||||
use super::routes::{auth::models::Credentials, models::Status, users::models::User};
|
use super::routes::{auth::models::Credentials, models::Status, users::models::User};
|
||||||
|
|
||||||
|
pub mod integrity_verification;
|
||||||
pub mod ldap;
|
pub mod ldap;
|
||||||
pub mod private_key_cache;
|
pub mod private_key_cache;
|
||||||
|
|
||||||
@ -65,8 +66,10 @@ impl AuthBackend<User> for ApiBackend {
|
|||||||
// terminate connection
|
// terminate connection
|
||||||
ldap.unbind().await;
|
ldap.unbind().await;
|
||||||
} else {
|
} else {
|
||||||
argon2::verify_encoded(&user.password, password.as_bytes())
|
match argon2::verify_encoded(&user.password, password.as_bytes()) {
|
||||||
.map_err(|_| ApiError::InvalidCredentials)?;
|
Ok(true) => {}
|
||||||
|
_ => return Err(ApiError::InvalidCredentials),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(user.clone()))
|
Ok(Some(user.clone()))
|
||||||
|
Loading…
Reference in New Issue
Block a user