blob: 36fe2c531e5b0a85f9eccc98ccc01144e761f1b8 [file]
use crate::client::*;
use crate::verifytree::mbtree::*;
use hex;
use merklebtree::iterator::prev;
use merklebtree::merklebtree::{MerkleBTree, Nodes};
use merklebtree::node::Node;
use merklebtree::sgxdb;
use merklebtree::traits::CalculateHash;
use parking_lot::RwLock;
use ring::hmac::Key;
use ring::{digest, hmac, rand};
use rocksdb::{DBVector, DB};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
pub struct server {
db_handler: Arc<RwLock<DB>>,
sgx_counter: i32,
hmac_key: Key,
present_mbtree: Merklebtree,
deleted_mbtree: Merklebtree,
sgx_present_root_node: Node<key_version>,
sgx_delete_root_node: Node<key_version>,
}
//hmacPayload is used to compute hmac
#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct hmac_payload {
key: String,
value: String,
counter: i32,
}
//storePayload is used to store value in the db
#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct store_payload {
value: String,
tag: String,
ctr: i32,
}
#[derive(Clone, Debug)]
pub struct sgx_private_data {
hmac_key: Key,
sgx_counter: i32,
persisted_present_hash: String,
persisted_present_hmac: String,
persisted_deleted_hash: String,
persisted_deleted_hmac: String,
}
#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct mbtree_payload {
root_hash: String,
sgx_counter: i32,
}
impl server {
fn db_put(&mut self, key: String, value: String) {
let db = self.db_handler.clone();
db.write().put(key.as_bytes(), value.as_bytes()).unwrap();
}
fn db_get(&mut self, key: String) -> String {
let db = self.db_handler.clone();
let r = db.read().get(key.as_str());
match r {
Err(t) => return String::new(),
Ok(t) => match t {
None => return String::new(),
Some(t) => return t.to_utf8().unwrap().to_string(),
},
}
}
fn db_delete(&mut self, key: String) {
let db = self.db_handler.clone();
db.write().delete(key.as_bytes()).unwrap();
}
fn present_search(&mut self, key: String) -> search_result {
let (get_result, mut present_subnodes) = self.present_mbtree.search(key);
if get_result.existed {
present_subnodes.nodes_map.remove(&0).unwrap();
present_subnodes
.nodes_map
.insert(0, self.sgx_present_root_node.clone());
sgxdb::verify_subnodes_hash(&present_subnodes);
}
get_result
}
fn delete_search(&mut self, key: String) -> search_result {
let (get_result, mut delete_subnodes) = self.deleted_mbtree.search(key);
if get_result.existed {
delete_subnodes.nodes_map.remove(&0).unwrap();
delete_subnodes
.nodes_map
.insert(0, self.sgx_delete_root_node.clone());
sgxdb::verify_subnodes_hash(&delete_subnodes);
}
get_result
}
fn present_remove(&mut self, key: String) {
let mut present_subnodes = self.present_mbtree.delete(key.clone());
if present_subnodes.nodes_map.len() == 0 {
return;
}
present_subnodes.nodes_map.remove(&0).unwrap();
present_subnodes
.nodes_map
.insert(0, self.sgx_present_root_node.clone());
sgxdb::verify_subnodes_hash(&present_subnodes);
let kv = key_version {
key: key.clone(),
version: 0,
};
self.present_mbtree
.mbtree
.remove(kv.clone(), &mut present_subnodes);
let node_hash = self.present_mbtree.nodes.merkleroot();
let subnode_hash = present_subnodes.merkleroot();
assert_eq!(node_hash, subnode_hash);
self.sgx_present_root_node = present_subnodes.nodes_map.remove(&0).unwrap();
}
fn delete_remove(&mut self, key: String) {
let mut delete_subnodes = self.deleted_mbtree.delete(key.clone());
if delete_subnodes.nodes_map.len() == 0 {
return;
}
delete_subnodes.nodes_map.remove(&0).unwrap();
delete_subnodes
.nodes_map
.insert(0, self.sgx_delete_root_node.clone());
sgxdb::verify_subnodes_hash(&delete_subnodes);
let kv = key_version {
key: key.clone(),
version: 0,
};
self.deleted_mbtree
.mbtree
.remove(kv.clone(), &mut delete_subnodes);
let node_hash = self.deleted_mbtree.nodes.merkleroot();
let subnode_hash = delete_subnodes.merkleroot();
assert_eq!(node_hash, subnode_hash);
self.sgx_delete_root_node = delete_subnodes.nodes_map.remove(&0).unwrap();
}
fn present_build_with_kv(&mut self, kv: key_version) {
if self.sgx_present_root_node.content.len() == 0 {
self.sgx_present_root_node = Node::new_node(kv.clone(), 0);
self.sgx_present_root_node.root_flag = true;
self.present_mbtree.build_with_key_value(kv.clone());
return;
}
let mut present_subnodes = self.present_mbtree.build_with_key_value(kv.clone());
present_subnodes.nodes_map.remove(&0).unwrap();
present_subnodes
.nodes_map
.insert(0, self.sgx_present_root_node.clone());
sgxdb::verify_subnodes_hash(&present_subnodes);
self.present_mbtree
.mbtree
.put(kv.clone(), &mut present_subnodes);
let node_hash = self.present_mbtree.nodes.merkleroot();
let subnode_hash = present_subnodes.merkleroot();
assert_eq!(node_hash, subnode_hash);
self.sgx_present_root_node = present_subnodes.nodes_map.remove(&0).unwrap();
}
fn delete_build_with_kv(&mut self, kv: key_version) {
if self.sgx_delete_root_node.content.len() == 0 {
self.sgx_delete_root_node = Node::new_node(kv.clone(), 0);
self.sgx_delete_root_node.root_flag = true;
self.deleted_mbtree.build_with_key_value(kv.clone());
return;
}
let mut delete_subnodes = self.deleted_mbtree.build_with_key_value(kv.clone());
delete_subnodes.nodes_map.remove(&0).unwrap();
delete_subnodes
.nodes_map
.insert(0, self.sgx_present_root_node.clone());
sgxdb::verify_subnodes_hash(&delete_subnodes);
self.deleted_mbtree
.mbtree
.put(kv.clone(), &mut delete_subnodes);
let node_hash = self.deleted_mbtree.nodes.merkleroot();
let subnode_hash = delete_subnodes.merkleroot();
assert_eq!(node_hash, subnode_hash);
self.sgx_delete_root_node = delete_subnodes.nodes_map.remove(&0).unwrap();
}
}
pub fn new_server(key_value: Vec<u8>) -> server {
let path = "rocksdb";
let db = DB::open_default(path).unwrap();
let db_handler = Arc::new(RwLock::new(db));
let s_key = hmac::Key::new(hmac::HMAC_SHA256, key_value.as_ref());
server {
db_handler,
sgx_counter: 0,
hmac_key: s_key,
present_mbtree: new_mbtree(),
deleted_mbtree: new_mbtree(),
sgx_present_root_node: Node::new_empty(0),
sgx_delete_root_node: Node::new_empty(0),
}
}
impl server {
pub fn handle_req(&mut self, req: request) -> response {
//TODO:safecheck for the insecurity mbtree should be added
let mut op_status = true;
let mut get_result = String::new();
if req.req_type == String::from("put") {
self.veritasdb_put(req.clone());
} else if req.req_type == String::from("get") {
get_result = self.veritasdb_get(req.clone());
} else if req.req_type == String::from("delete") {
self.veritasdb_delete(req.clone());
} else if req.req_type == String::from("insert") {
self.veritasdb_insert(req.clone());
}
response {
rsp_status: op_status,
req_type: req.req_type,
data: get_result,
error_info: "".to_string(),
}
}
pub fn veritasdb_get(&mut self, req: request) -> String {
let data = self.db_get(req.key.clone());
if data == "".to_string() {
return String::new();
}
let sp: store_payload = serde_json::from_str(data.as_str()).unwrap();
let hmac_data = hmac_payload {
key: req.key.clone(),
value: sp.value.clone(),
counter: sp.ctr,
};
let hmac_string = serde_json::to_string(&hmac_data).unwrap();
let verify_result = self.verify_hmac(hmac_string, sp.tag.clone());
let sr = self.present_search(req.key.clone());
if verify_result && sp.ctr == sr.version {
return sp.value;
} else {
panic!("verify failed");
}
String::new();
}
pub fn veritasdb_put(&mut self, req: request) {
let get_result = self.present_search(req.key.clone());
if get_result.existed {
let hmac_data = hmac_payload {
key: req.key.clone(),
value: req.value.clone(),
counter: get_result.version + 1,
};
let hmac_string = serde_json::to_string(&hmac_data).unwrap();
let tag_string = self.compute_hmac(hmac_string);
//try to put it into kvdb
let store_data = store_payload {
value: req.value.clone().to_string(),
tag: tag_string,
ctr: get_result.version + 1,
};
let store_string = serde_json::to_string(&store_data).unwrap();
self.db_put(req.key.clone(), store_string.clone());
//update present if there is no error
self.present_build_with_kv(key_version {
key: req.key,
version: get_result.version + 1,
});
} else {
println!("key doesn't exist in present when called put");
return;
}
}
pub fn veritasdb_insert(&mut self, req: request) {
let sr = self.present_search(req.key.clone());
if sr.existed {
println!("key existed in present when called insert");
return;
} else {
let mut ctr = 0;
let delete_sr = self.delete_search(req.key.clone());
if delete_sr.existed {
ctr = delete_sr.version + 1;
} else {
ctr = 0;
}
let hmac_data = hmac_payload {
key: req.key.clone(),
value: req.value.clone(),
counter: ctr,
};
let hmac_string = serde_json::to_string(&hmac_data).unwrap();
let tag_string = self.compute_hmac(hmac_string);
let store_data = store_payload {
value: req.value,
ctr: ctr,
tag: tag_string,
};
let store_string = serde_json::to_string(&store_data).unwrap();
self.db_put(req.key.clone(), store_string);
self.present_build_with_kv(key_version {
key: req.key.clone(),
version: ctr,
});
self.delete_remove(req.key.clone());
}
}
pub fn veritasdb_delete(&mut self, req: request) {
let get_result = self.db_get(req.key.clone());
if get_result == "".to_string() {
} else {
self.db_delete(req.key.clone());
let sr = self.present_search(req.key.clone());
self.delete_build_with_kv(key_version {
key: req.key.clone(),
version: sr.version,
});
self.present_remove(req.key.clone());
}
}
pub fn compute_hmac(&mut self, msg: String) -> String {
let tag = hmac::sign(&self.hmac_key, msg.as_str().as_bytes());
let tag_string = hex::encode(tag.as_ref());
tag_string
}
pub fn verify_hmac(&mut self, msg: String, tag_string: String) -> bool {
let result = hmac::verify(
&self.hmac_key,
msg.as_bytes(),
hex::decode(tag_string).unwrap().as_ref(),
);
match result {
Ok(t) => return true,
Err(e) => return false,
}
}
}