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