From 59b0f9e54fe34b5be25801bbe12c616442ba4e16 Mon Sep 17 00:00:00 2001
From: tec <tec@ucc.gu.uwa.edu.au>
Date: Tue, 4 Feb 2020 02:08:56 +0800
Subject: [PATCH] Add token encryption

---
 Cargo.toml              | 12 +++++++-----
 src/token_management.rs | 31 ++++++++++++++++++++++++-------
 src/user_management.rs  |  2 +-
 3 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 3d18dd1..1c8ee1f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,11 +5,13 @@ authors = ["tec <tec@ucc.gu.uwa.edu.au>"]
 edition = "2018"
 
 [dependencies]
-serenity = "0.8.0"
-rand = "^0.7.2"
+chrono = "^0.4.10"
 lazy_static = "^1.4.0"
 log = "^0.4.8"
-simplelog = "^0.7.4"
-serde_yaml = "^0.8"
+rand = "^0.7.2"
 serde = "^1.0.104"
-chrono = "^0.4.10"
+serde_yaml = "^0.8"
+serenity = "0.8.0"
+simplelog = "^0.7.4"
+openssl = "^0.10"
+base64 = "^0.11"
diff --git a/src/token_management.rs b/src/token_management.rs
index 9bdf049..7de70ed 100644
--- a/src/token_management.rs
+++ b/src/token_management.rs
@@ -1,17 +1,33 @@
+use base64;
 use chrono::{prelude::Utc, DateTime};
+use openssl::symm::{decrypt, encrypt, Cipher};
 use rand::Rng;
 use serenity::model::user::User;
 use std::str;
 
 lazy_static! {
     static ref KEY: [u8; 32] = rand::thread_rng().gen::<[u8; 32]>();
+    static ref CIPHER: Cipher = Cipher::aes_256_cbc();
 }
 
-fn encrypt(plaintext: &str) -> &str {
-    return plaintext;
+fn text_encrypt(plaintext: &str) -> String {
+    let iv: &[u8; 16] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+    let encrypted_vec =
+        encrypt(*CIPHER, &*KEY, Some(iv), plaintext.as_bytes()).expect("encryption failed");
+    return base64::encode(encrypted_vec.as_slice());
 }
-fn decrypt(ciphertext: &str) -> &str {
-    return ciphertext;
+fn text_decrypt(ciphertext: &str) -> String {
+    let iv: &[u8; 16] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+    let decrypted_vec = decrypt(
+        *CIPHER,
+        &*KEY,
+        Some(iv),
+        &base64::decode(ciphertext).expect("Unable to decode"),
+    )
+    .expect("decryption failed");
+    return str::from_utf8(decrypted_vec.as_slice())
+        .expect("Invalid utf8 sequence")
+        .to_owned();
 }
 
 pub fn generate_token<'a>(discord_user: &User, username: &str) -> String {
@@ -24,7 +40,7 @@ pub fn generate_token<'a>(discord_user: &User, username: &str) -> String {
         username
     );
     info!("Token generated for {}: {}", discord_user.name, &payload);
-    encrypt(&payload).to_string()
+    text_encrypt(&payload).to_string()
 }
 
 #[derive(Debug)]
@@ -38,8 +54,9 @@ impl std::fmt::Display for TokenError {
     }
 }
 
-pub fn parse_token(discord_user: &User, token: &str) -> Result<String, TokenError> {
-    let token_components: Vec<_> = decrypt(token).splitn(3, ',').collect();
+pub fn parse_token(discord_user: &User, encrypted_token: &str) -> Result<String, TokenError> {
+    let token = text_decrypt(encrypted_token);
+    let token_components: Vec<_> = token.splitn(3, ',').collect();
     info!(
         "Verification attempt from '{}'(uid: {}) for account '{}' with token from {}",
         discord_user.name, token_components[1], token_components[2], token_components[0]
diff --git a/src/user_management.rs b/src/user_management.rs
index 8f511c0..22da8e1 100644
--- a/src/user_management.rs
+++ b/src/user_management.rs
@@ -63,7 +63,7 @@ impl Commands {
             "Error sending message: {:?}",
             // TODO convert to email
             msg.channel_id
-                .say(&ctx.http, generate_token(&msg.author, account_name))
+               .say(&ctx.http, format!("Hey {} here's that token you ordered: {}\nIf this wasn't you just ignore this.", account_name, generate_token(&msg.author, account_name)))
         );
         e!("Error deleting register message: {:?}", msg.delete(ctx));
     }
-- 
GitLab