X-Git-Url: http://git.euphorik.ch/?p=rup.git;a=blobdiff_plain;f=src%2Fcrypto.rs;fp=src%2Fcrypto.rs;h=0000000000000000000000000000000000000000;hp=16fbaa0c6b8094fc26a9c2e7537391ee11562b7e;hb=1f84b22050cf470b00aef6b3c3ecb7ae70242e1a;hpb=295ca1daf01ff83964812c50fe1374dd679a0559 diff --git a/src/crypto.rs b/src/crypto.rs deleted file mode 100644 index 16fbaa0..0000000 --- a/src/crypto.rs +++ /dev/null @@ -1,127 +0,0 @@ -use openssl::{symm, sha::sha256}; -use rand::prelude::*; - -#[derive(Debug)] -pub enum KeyError { - UnableToDecodeBase64Key, - WrongKeyLength, -} - -#[derive(Debug)] -pub enum EncryptError { - KeyError(KeyError), - UnsupportedVersion(u8), - UnableToEncrypt, -} - -#[derive(Debug)] -pub enum DecryptError { - KeyError(KeyError), - UnableToParseVersion, - UnsupportedVersion(u8), - MessageToShort, - UnableToDecodeBase64Message, - UnableToDecrypt, - UnableToDecodeMessageAsUTF8String, - HashMismatch, -} - -fn decode_key(key: &str) -> Result, KeyError> { - match base64::decode(key) { - Ok(k) => if k.len() != 16 { Err(KeyError::WrongKeyLength) } else { Ok(k) }, - Err(_e) => Err(KeyError::UnableToDecodeBase64Key) - } -} - -/// Return a random key encoded in base64. -pub fn generate_key() -> String { - let key = rand::thread_rng().gen::<[u8; 16]>(); - base64::encode(key) -} - -/// Encrypt the given text with the given key (first version). The key length must be 128 bits encoded in base64. -/// Ouput formats: -/// * 'version' = 1: "1" + base_64( + hash(message) + aes(message)) -/// * 'version' = 2: "2" + base_64( + aes(hash(message) + message)) -/// IV: 16 bytes randomized. -/// Mode : CBC. -pub fn encrypt(key: &str, plain_text: &str, version: u8) -> Result { - let key_as_bytes = decode_key(key).map_err(EncryptError::KeyError)?; - - let text_as_bytes = plain_text.as_bytes(); - let hash_text = sha256(&text_as_bytes); - let iv = rand::thread_rng().gen::<[u8; 16]>(); - - let cipher_text = - if version == 1 { - symm::encrypt(symm::Cipher::aes_128_cbc(), &key_as_bytes, Some(&iv), text_as_bytes) - .map_err(|_e| EncryptError::UnableToEncrypt)? - } else if version == 2 { - symm::encrypt(symm::Cipher::aes_128_cbc(), &key_as_bytes, Some(&iv), &[&hash_text, text_as_bytes].concat()) - .map_err(|_e| EncryptError::UnableToEncrypt)? - } else { - return Err(EncryptError::UnsupportedVersion(version)) - }; - - let mut result: Vec = Vec::new(); - result.extend(&iv); - - if version == 1 { - result.extend(&hash_text); - } - - result.extend(&cipher_text); - - Ok(version.to_string() + &base64::encode(&result)) -} - -/// Decrypt the given text with the given key. The key length must be 128 bits encoded in base64. -/// Input formats: -/// * version 1: "1" + base_64( + hash(message) + aes(message)) -/// * version 2: "2" + base_64( + aes(hash(message) + message)) -pub fn decrypt(key: &str, cipher_text: &str) -> Result { - let key_as_bytes = decode_key(key).map_err(DecryptError::KeyError)?; - - // Can't decrypt a message with the wrong version. - let first_char = &cipher_text[..1]; - let version: u8 = first_char.parse().map_err(|_e| DecryptError::UnableToParseVersion)?; - - if version != 1 && version != 2 { - return Err(DecryptError::UnsupportedVersion(version)) - } - - let cipher_text_bytes = - base64::decode(&cipher_text.as_bytes()[1..]) - .map_err(|_e| DecryptError::UnableToDecodeBase64Message)?; - - if cipher_text_bytes.len() <= 48 { return Err(DecryptError::MessageToShort) } - - let iv = &cipher_text_bytes[0..16]; - - let (plain_message_bytes, hash) = - if version == 1 { - let encrypted_message = &cipher_text_bytes[48..]; - ( - symm::decrypt(symm::Cipher::aes_128_cbc(), &key_as_bytes, Some(iv), encrypted_message) - .map_err(|_e| DecryptError::UnableToDecrypt)?, - cipher_text_bytes[16..48].to_vec() - ) - } else { - let encrypted_message = &cipher_text_bytes[16..]; - let plain_text = - symm::decrypt(symm::Cipher::aes_128_cbc(), &key_as_bytes, Some(iv), encrypted_message) - .map_err(|_e| DecryptError::UnableToDecrypt)?; - ( - plain_text[32..].to_vec(), - plain_text[0..32].to_vec() - ) - }; - - if sha256(&plain_message_bytes) != hash[..] { return Err(DecryptError::HashMismatch) } - - let plain_message = - String::from_utf8(plain_message_bytes) - .map_err(|_e| DecryptError::UnableToDecodeMessageAsUTF8String)?; - - Ok(plain_message) -}