mirror of
https://github.com/danbulant/Portfolio
synced 2026-05-24 12:35:31 +00:00
feat: convert crypto to our service error
This commit is contained in:
parent
98c59694a7
commit
e1ee5b796a
2 changed files with 58 additions and 26 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue