feat: convert crypto to our service error

This commit is contained in:
EETagent 2022-11-14 14:06:48 +01:00
parent 98c59694a7
commit e1ee5b796a
2 changed files with 58 additions and 26 deletions

View file

@ -34,9 +34,7 @@ pub fn random_8_char_string() -> String {
s
}
pub async fn hash_password(
password_plain_text: String,
) -> Result<String, Box<dyn std::error::Error>> {
pub async fn hash_password(password_plain_text: String) -> Result<String, ServiceError> {
let argon_config = Argon2::new(
argon2::Algorithm::Argon2i,
argon2::Version::V0x13,
@ -56,13 +54,13 @@ pub async fn hash_password(
let hash_string = hash.await??;
return Ok(hash_string);
Ok(hash_string)
}
pub async fn verify_password(
password_plaint_text: String,
hash: String,
) -> Result<bool, Box<dyn std::error::Error>> {
) -> Result<bool, ServiceError> {
let argon_config = Argon2::new(
argon2::Algorithm::Argon2i,
argon2::Version::V0x13,
@ -106,7 +104,7 @@ fn convert_key_aes256(key: &str) -> Vec<u8> {
pub async fn encrypt_password(
password_plain_text: String,
key: String,
) -> Result<String, Box<dyn std::error::Error>> {
) -> Result<String, ServiceError> {
let hash = tokio::task::spawn_blocking(move || {
let aes_key_nonce = convert_key_aes256(&key);
@ -127,7 +125,7 @@ pub async fn encrypt_password(
pub async fn decrypt_password(
password_cipher_text: String,
key: String,
) -> Result<String, Box<dyn std::error::Error>> {
) -> Result<String, ServiceError> {
let input = base64::decode(password_cipher_text).unwrap();
let plain = tokio::task::spawn_blocking(move || {
let aes_key_nonce = convert_key_aes256(&key);
@ -148,7 +146,7 @@ pub async fn decrypt_password(
pub async fn encrypt_password_age(
password_plain_text: &str,
key: &str,
) -> Result<String, age::EncryptError> {
) -> Result<String, ServiceError> {
let encryptor = age::Encryptor::with_user_passphrase(age::secrecy::Secret::new(key.to_owned()));
let mut encrypt_buffer = Vec::new();
@ -169,7 +167,7 @@ pub async fn encrypt_password_age(
pub async fn decrypt_password_age(
password_encrypted: &str,
key: &str,
) -> Result<String, Box<dyn std::error::Error>> {
) -> Result<String, ServiceError> {
let encrypted = base64::decode(password_encrypted)?;
let decryptor = match age::Decryptor::new_async(&encrypted[..]).await? {
@ -200,7 +198,7 @@ async fn age_encrypt_with_recipients<W: tokio::io::AsyncWrite + Unpin>(
input_buffer: &[u8],
output_buffer: &mut W,
recipients: &Vec<&str>,
) -> Result<(), age::EncryptError> {
) -> Result<(), ServiceError> {
let public_keys = recipients
.into_iter()
.map(|recipient| {
@ -233,14 +231,15 @@ async fn age_decrypt_with_private_key<R: tokio::io::AsyncRead + Unpin>(
input_buffer: R,
output_buffer: &mut Vec<u8>,
key: &str,
) -> Result<(), Box<dyn std::error::Error>> {
) -> Result<(), ServiceError> {
let decryptor = match age::Decryptor::new_async(input_buffer.compat()).await? {
age::Decryptor::Recipients(d) => d,
_ => unreachable!(),
};
let mut decrypt_writer = decryptor.decrypt_async(iter::once(
&age::x25519::Identity::from_str(key)? as &dyn age::Identity,
&age::x25519::Identity::from_str(key).map_err(|e| ServiceError::AgeKeyError(e.to_string()))?
as &dyn age::Identity,
))?;
decrypt_writer.read_to_end(output_buffer).await?;
@ -251,7 +250,7 @@ async fn age_decrypt_with_private_key<R: tokio::io::AsyncRead + Unpin>(
pub async fn encrypt_password_with_recipients(
password_plain_text: &str,
recipients: &Vec<&str>,
) -> Result<String, age::EncryptError> {
) -> Result<String, ServiceError> {
let mut encrypt_buffer = Vec::new();
age_encrypt_with_recipients(
@ -267,25 +266,22 @@ pub async fn encrypt_password_with_recipients(
pub async fn decrypt_password_with_private_key(
password_encrypted: &str,
key: &str,
) -> Result<String, ServiceError> { // TODO More specific error handling
let Ok(encrypted) = base64::decode(password_encrypted) else {
return Err(ServiceError::CryptoEncryptFailed);
};
) -> Result<String, ServiceError> {
let encrypted = base64::decode(password_encrypted)?;
let mut decrypt_buffer = Vec::new();
if age_decrypt_with_private_key(encrypted.as_slice(), &mut decrypt_buffer, key).await.is_err() {
return Err(ServiceError::CryptoDecryptFailed);
};
age_decrypt_with_private_key(encrypted.as_slice(), &mut decrypt_buffer, key).await?;
String::from_utf8(decrypt_buffer).map_err(|_| ServiceError::CryptoDecryptFailed)
let string = String::from_utf8(decrypt_buffer)?;
Ok(string)
}
pub async fn encrypt_file_with_recipients<P: AsRef<Path>>(
plain_file_path: P,
cipher_file_path: P,
recipients: Vec<&str>,
) -> Result<(), age::EncryptError> {
) -> Result<(), ServiceError> {
let mut cipher_file = tokio::fs::File::create(cipher_file_path).await?;
let mut plain_file = tokio::fs::File::open(plain_file_path).await?;
@ -293,14 +289,19 @@ pub async fn encrypt_file_with_recipients<P: AsRef<Path>>(
tokio::io::AsyncReadExt::read_to_end(&mut plain_file, &mut plain_file_contents).await?;
age_encrypt_with_recipients(plain_file_contents.as_slice(), &mut cipher_file, &recipients).await
age_encrypt_with_recipients(
plain_file_contents.as_slice(),
&mut cipher_file,
&recipients,
)
.await
}
pub async fn decrypt_file_with_private_key<P: AsRef<Path>>(
cipher_file_path: P,
plain_file_path: P,
key: &str,
) -> Result<(), Box<dyn std::error::Error>> {
) -> Result<(), ServiceError> {
let cipher_file = tokio::fs::File::open(cipher_file_path).await?;
let mut plain_file = tokio::fs::File::create(plain_file_path).await?;
@ -316,7 +317,7 @@ pub async fn decrypt_file_with_private_key<P: AsRef<Path>>(
pub async fn decrypt_file_with_private_key_as_buffer<P: AsRef<Path>>(
cipher_file_path: P,
key: &str,
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
) -> Result<Vec<u8>, ServiceError> {
let cipher_file = tokio::fs::File::open(cipher_file_path).await?;
let mut plain_file = Vec::new();

View file

@ -33,10 +33,30 @@ pub enum ServiceError {
CryptoDecryptFailed,
#[error("Candidate details not set, please contact technical support")]
CandidateDetailsNotSet,
#[error("Tokio join error")]
TokioJoinError(#[from] tokio::task::JoinError),
#[error("Age encrypt error")]
AgeEncryptError(#[from] age::EncryptError),
#[error("Age decrypt error")]
AgeDecryptError(#[from] age::DecryptError),
#[error("Age key error")]
AgeKeyError(String),
#[error("IO error")]
IOError(#[from] std::io::Error),
#[error("Base64 decode error")]
Base64DecodeError(#[from] base64::DecodeError),
#[error("UTF8 decode error")]
UTF8DecodeError(#[from] std::string::FromUtf8Error),
#[error("Argon config error")]
ArgonConfigError(#[from] argon2::Error),
#[error("Argon hash error")]
ArgonHashError(#[from] argon2::password_hash::Error),
#[error("AES error")]
AesError(#[from] aes_gcm_siv::Error),
}
impl ServiceError {
// TODO: Převod do thiserror
fn code_and_message(&self) -> (u16, String) {
match self {
ServiceError::InvalidApplicationId => (400, "Invalid application id".to_string()),
@ -54,6 +74,17 @@ impl ServiceError {
ServiceError::CryptoEncryptFailed => (500, "Crypto encryption failed, please contact technical support".to_string()),
ServiceError::CryptoDecryptFailed => (500, "Crypto decryption failed, please contact technical support".to_string()),
ServiceError::CandidateDetailsNotSet => (500, "Candidate details not set, please contact technical support".to_string()),
// TODO: Dodělat hlášky
ServiceError::AgeEncryptError(_) => (500, "Age encrypt error".to_string()),
ServiceError::AgeDecryptError(_) => (500, "Age decrypt error".to_string()),
ServiceError::AgeKeyError(_) => (500, "Age key error".to_string()),
ServiceError::IOError(_) => (500, "IO error".to_string()),
ServiceError::Base64DecodeError(_) => (500, "Base64 decode error".to_string()),
ServiceError::UTF8DecodeError(_) => (500, "UTF8 decode error".to_string()),
ServiceError::ArgonHashError(_) => (500, "Argon hash error".to_string()),
ServiceError::TokioJoinError(_) => (500, "Tokio join error".to_string()),
ServiceError::AesError(_) => (500, "AES error".to_string()),
ServiceError::ArgonConfigError(_) => (500, "Argon config error".to_string()),
}
}