Skip to content

Commit

Permalink
Adds serpent encryption and decryption in set and get
Browse files Browse the repository at this point in the history
  • Loading branch information
Blocs committed Feb 28, 2020
1 parent 7118301 commit cbf2d07
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 54 deletions.
7 changes: 4 additions & 3 deletions .github/lucid.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ general:
bind_address: 127.0.0.1
port: 7020
port_ssl: 7021
use_ssl: true
use_ssl: false
ssl_certificate: "tls/cert.pem"
ssl_certificate_key: "tls/key.rsa"
show_banner: false
Expand All @@ -15,8 +15,9 @@ persistence:
enabled: false
location: ""
encryption:
enabled: false
private_key: ""
enabled: true
private_key: "123456789012345678901234123456789012345678901234"
iv: "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
webui:
enabled: true
store:
Expand Down
43 changes: 15 additions & 28 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ tree_magic = "0.2.1"
snafu = "0.6.2"
bytes = "0.5.3"
fern = "0.5.9"
hex-literal = "0.2.1"
hex = "0.3.1"
clap = { version = "2.33.0", features = ["yaml"] }
warp = { version = "0.2.0", features = ["tls"] }
log = { version = "0.4.8", features = ["serde"] }
tokio = { version = "0.2.9", features = ["full"] }
serpent = { git = "https://github.com/RustCrypto/block-ciphers" }
serpent = { git = "https://github.com/RustCrypto/block-ciphers" }
block-modes = "0.3.3"
2 changes: 2 additions & 0 deletions src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ impl Default for Configuration {
encryption: Encryption {
enabled: false,
private_key: String::new(),
iv: String::new(),
},
webui: WebUI { enabled: false },
store: Store { max_limit: 7340032 },
Expand Down Expand Up @@ -89,6 +90,7 @@ pub struct Persistence {
pub struct Encryption {
pub enabled: bool,
pub private_key: String,
pub iv: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down
65 changes: 49 additions & 16 deletions src/kvstore.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use block_modes::block_padding::ZeroPadding;
use block_modes::{BlockMode, Cbc};
use chashmap::CHashMap;
use chrono::{DateTime, Utc};

use serpent::Serpent;

type SerpentCbc = Cbc<Serpent, ZeroPadding>;

#[derive(Debug, Clone)]
pub struct KvElement {
pub data: Vec<u8>,
Expand All @@ -9,34 +15,53 @@ pub struct KvElement {
pub updated_at: DateTime<Utc>,
pub expire_at: DateTime<Utc>,
pub update_count: i32,
pub locked: bool
pub locked: bool,
}

pub struct KvStore {
container: CHashMap<String, KvElement>
container: CHashMap<String, KvElement>,
cipher: Option<Cipher>,
}

pub struct Cipher {
priv_key: [u8; 24],
iv: [u8; 16],
}

impl KvStore
{
pub fn new() -> KvStore
{
impl KvStore {
pub fn new(cipher: Option<[&str; 2]>) -> KvStore {
// TODO: prepare looped persistence
KvStore {
container: CHashMap::new()
let mut kv = KvStore {
container: CHashMap::new(),
cipher: None,
};

if let Some(c) = cipher {
let (mut priv_key, mut iv) = ([0u8; 24], [0u8; 16]);
priv_key[..24].copy_from_slice(&hex::decode(c[0]).unwrap());
iv[..16].copy_from_slice(&hex::decode(c[1]).unwrap());
kv.cipher = Some(Cipher { priv_key, iv });
}

kv
}

pub fn set(&self, key: String, value: Vec<u8>) -> Option<KvElement> {
pub fn set(&self, key: String, mut value: Vec<u8>) -> Option<KvElement> {
// TODO: prepare iterative persistence
let mime_type = tree_magic::from_u8(value.as_ref());

if let Some(c) = &self.cipher {
let cipher = SerpentCbc::new_var(&c.priv_key, &c.iv).unwrap();
value = cipher.encrypt_vec(&value);
}
match &mut self.container.get_mut(&key) {
Some(kv_element) => {
kv_element.data = value;
kv_element.mime_type = mime_type;
kv_element.updated_at = Utc::now();
kv_element.update_count = kv_element.update_count + 1;
kv_element.update_count = kv_element.update_count + 1;
Some(kv_element.to_owned())
},
}
None => {
let kv_element = KvElement {
data: value,
Expand All @@ -54,8 +79,16 @@ impl KvStore

pub fn get(&self, key: String) -> Option<KvElement> {
match self.container.get(&key) {
Some(value) => Some(value.clone()),
None => None
Some(value) => {
let mut cloned_value = value.clone();

if let Some(c) = &self.cipher {
let cipher = SerpentCbc::new_var(&c.priv_key, &c.iv).unwrap();
cloned_value.data = cipher.decrypt_vec(&value.data).unwrap();
}
Some(cloned_value)
}
None => None,
}
}

Expand All @@ -64,8 +97,8 @@ impl KvStore
Some(kv_element) => {
kv_element.locked = to_lock;
true
},
None => false
}
None => false,
}
}

Expand All @@ -74,4 +107,4 @@ impl KvStore
pub fn drop(&self, key: String) {
self.container.remove(&key);
}
}
}
16 changes: 14 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ extern crate serde_derive;
#[macro_use]
extern crate log;

extern crate block_modes;
extern crate hex;
extern crate serpent;

mod configuration;
mod kvstore;
mod lucid;
Expand Down Expand Up @@ -72,7 +76,11 @@ async fn main() -> Result<(), Error> {
.expect("Couldn't start logger");
log::set_max_level(LevelFilter::Debug);

let long_version = format!("{}\n{}\n\nYou can send a tips here: 3BxEYn4RZ3iYETcFpN7nA6VqCY4Hz1tSUK", crate_version!(), CREDITS);
let long_version = format!(
"{}\n{}\n\nYou can send a tips here: 3BxEYn4RZ3iYETcFpN7nA6VqCY4Hz1tSUK",
crate_version!(),
CREDITS
);

let cli_yaml = load_yaml!("cli.yml");
let app = App::from_yaml(&cli_yaml)
Expand Down Expand Up @@ -145,7 +153,11 @@ async fn main() -> Result<(), Error> {
}
if let Some(_) = matches.subcommand_matches("settings") {
if config_path.exists() {
println!("Configuration location: {}\n\n{}", &config_path.to_str().unwrap(), fs::read_to_string(&config_path).context(OpenConfigFile)?);
println!(
"Configuration location: {}\n\n{}",
&config_path.to_str().unwrap(),
fs::read_to_string(&config_path).context(OpenConfigFile)?
);
} else {
return Err(Error::ConfigurationNotFound);
}
Expand Down
13 changes: 10 additions & 3 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,16 @@ impl Server {
}

pub async fn run(&self) {
let store = Arc::new(KvStore::new());
let configuration = self.configuration.read().unwrap();

let mut encryption_key = None;
if configuration.encryption.enabled {
encryption_key = Some([
configuration.encryption.private_key.as_str(),
configuration.encryption.iv.as_str(),
]);
}
let store = Arc::new(KvStore::new(encryption_key));
let store = warp::any().map(move || store.clone());

let config = self.configuration.clone();
Expand All @@ -43,8 +52,6 @@ impl Server {

let webui_enabled = config.clone().and_then(check_webui).untuple_one();

let configuration = self.configuration.read().unwrap();

let api_kv_key_path = path!("api" / "kv" / String).and(path::end());
let api_kv_key = auth.and(
warp::get()
Expand Down

0 comments on commit cbf2d07

Please sign in to comment.