From 4bab656dfbbd4fa7c21a7b17c160f904ff59dca3 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Wed, 27 Jul 2022 23:52:25 +0800 Subject: [PATCH] feat: v0.2.1 add seckey support --- Cargo.lock | 49 ++++++++++++++++++++++++++++++++++++++++++++----- Cargo.toml | 3 ++- src/serve.rs | 44 +++++++++++++++++++++++++++----------------- 3 files changed, 73 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e66bb8..063a786 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,7 +14,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom", + "getrandom 0.2.7", "once_cell", "version_check", ] @@ -265,6 +265,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.7" @@ -273,7 +284,7 @@ checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -444,7 +455,7 @@ dependencies = [ [[package]] name = "local-mini-kms" -version = "0.2.0" +version = "0.2.1" dependencies = [ "base64", "clap", @@ -454,6 +465,7 @@ dependencies = [ "lazy_static", "rusqlite", "rust_util", + "seckey", "secmem-proc", "serde", "serde_derive", @@ -488,6 +500,17 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memsec" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac78937f19a0c7807e45a931eac41f766f210173ec664ec046d58e6d388a5cb" +dependencies = [ + "getrandom 0.2.7", + "libc", + "windows-sys", +] + [[package]] name = "miniz_oxide" version = "0.5.3" @@ -505,7 +528,7 @@ checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys", ] @@ -647,7 +670,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom", + "getrandom 0.2.7", "redox_syscall", "thiserror", ] @@ -714,6 +737,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "seckey" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b371a3e46636d13277af1daacbecb6f5acbe653bd378a4822ecd1c67790fbb" +dependencies = [ + "getrandom 0.1.16", + "memsec", +] + [[package]] name = "secmem-proc" version = "0.1.1" @@ -1003,6 +1036,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index a2d0500..35691b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "local-mini-kms" -version = "0.2.0" +version = "0.2.1" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -17,6 +17,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" josekit = "0.8.1" secmem-proc = "0.1.1" +seckey = "0.11.2" rust_util = { version = "0.6", features = ["use_clap"] } tokio = { version = "1.19", features = ["full"] } hyper = { version = "0.14.20", features = ["client", "server", "tcp", "http1", "http2"] } diff --git a/src/serve.rs b/src/serve.rs index f90661d..6d218e2 100644 --- a/src/serve.rs +++ b/src/serve.rs @@ -1,4 +1,4 @@ -use std::sync::RwLock; +use std::sync::Mutex; use clap::{App, Arg, ArgMatches, SubCommand}; use hyper::{Body, Client, Method, Request, Response, Server, StatusCode}; @@ -9,6 +9,7 @@ use josekit::jwk::alg::rsa::RsaKeyPair; use josekit::jwk::KeyPair; use rust_util::{debugging, failure_and_exit, information, opt_result, simple_error, success, XResult}; use rust_util::util_clap::{Command, CommandError}; +use seckey::SecBytes; use serde::{Deserialize, Serialize}; use serde_json::{json, Map, Value}; use zeroize::Zeroize; @@ -97,18 +98,18 @@ macro_rules! do_response { struct MemoryKey { database_file: String, instance_rsa_key_pair: RsaKeyPair, - master_key: Option>, + master_key: Option, } lazy_static::lazy_static! { - static ref STATUP_RW_LOCK: RwLock> = RwLock::new(None); + static ref STATUP_RW_LOCK: Mutex> = Mutex::new(None); } fn init_instance(db: &str) -> XResult { let conn = db::open_db(db)?; db::init_db(&conn)?; - let mut startup_rw_lock = STATUP_RW_LOCK.write().expect("Lock write startup rw lock error"); + let mut startup_rw_lock = STATUP_RW_LOCK.lock().expect("Lock write startup rw lock error"); match &*startup_rw_lock { Some(_) => Ok(false), None => { @@ -124,7 +125,7 @@ fn init_instance(db: &str) -> XResult { } fn update_instance_rsa_key_pair() -> XResult { - let mut startup_rw_lock = STATUP_RW_LOCK.write().expect("Lock write startup rw lock error"); + let mut startup_rw_lock = STATUP_RW_LOCK.lock().expect("Lock write startup rw lock error"); match &mut *startup_rw_lock { Some(k) => { k.instance_rsa_key_pair = jose::generate_rsa_key(4096)?; @@ -180,12 +181,12 @@ async fn inner_decrypt(req: Request) -> XResult<(StatusCode, Value)> { let data: DecryptRequest = serde_json::from_reader(whole_body.reader())?; debugging!("To be decrypted value: {}", &data.encrypted_value); - let mut key = match get_master_key() { + let key = match get_master_key() { None => return Ok((StatusCode::BAD_REQUEST, json!({ "error": "status_not_ready" }))), Some(key) => key, }; - let decrypted_value = jose::deserialize_jwe_aes(&data.encrypted_value, &key); - key.zeroize(); + let decrypted_value = jose::deserialize_jwe_aes(&data.encrypted_value, &*key.read()); + drop(key); decrypted_value.map(|v| { let v = MultipleViewValue::from(&v.0); @@ -211,12 +212,12 @@ async fn inner_encrypt(req: Request) -> XResult<(StatusCode, Value)> { let whole_body = hyper::body::aggregate(req).await?; let data: MultipleViewValue = serde_json::from_reader(whole_body.reader())?; let value = data.to_bytes()?; - let mut key = match get_master_key() { + let key = match get_master_key() { None => return Ok((StatusCode::BAD_REQUEST, json!({ "error": "status_not_ready" }))), Some(key) => key, }; - let encrypt_result = jose::serialize_jwe_aes(&value, &key); - key.zeroize(); + let encrypt_result = jose::serialize_jwe_aes(&value, &*key.read()); + drop(key); encrypt_result.map(|e| { (StatusCode::OK, json!({ @@ -251,7 +252,7 @@ async fn inner_init(req: Request) -> XResult<(StatusCode, Value)> { let whole_body = hyper::body::aggregate(req).await?; let init_request: InitRequest = serde_json::from_reader(whole_body.reader())?; - let mut startup_rw_lock = STATUP_RW_LOCK.write().expect("Lock read startup rw lock error"); + let mut startup_rw_lock = STATUP_RW_LOCK.lock().expect("Lock read startup rw lock error"); match &*startup_rw_lock { None => return Ok((StatusCode::INTERNAL_SERVER_ERROR, json!({ "error": "internal_error", "error_message": "not init " }))), Some(memory_key) => match memory_key.master_key { @@ -297,7 +298,10 @@ async fn inner_init(req: Request) -> XResult<(StatusCode, Value)> { } } information!("Set master key success"); - k.master_key = Some(clear_master_key); + let sec_bytes = SecBytes::with(clear_master_key.len(), |buf| buf.copy_from_slice(&clear_master_key.as_slice()[..])); + let mut clear_master_key = clear_master_key; + clear_master_key.zeroize(); + k.master_key = Some(sec_bytes); k.instance_rsa_key_pair = jose::generate_rsa_key(4096)?; } Ok((StatusCode::OK, json!({}))) @@ -308,7 +312,7 @@ async fn status() -> Result> { } async fn inner_status() -> XResult<(StatusCode, Value)> { - let startup_rw_lock = STATUP_RW_LOCK.read().expect("Lock read startup rw lock error"); + let startup_rw_lock = STATUP_RW_LOCK.lock().expect("Lock read startup rw lock error"); let body = match &*startup_rw_lock { None => json!({ "status": "n/a" }), Some(memory_key) => match memory_key.master_key { @@ -331,10 +335,16 @@ async fn get_version() -> Result> { ).into())?) } -fn get_master_key() -> Option> { - let startup_rw_lock = STATUP_RW_LOCK.read().expect("Lock read startup rw lock error"); +fn get_master_key() -> Option { + let startup_rw_lock = STATUP_RW_LOCK.lock().expect("Lock read startup rw lock error"); match &*startup_rw_lock { None => None, - Some(k) => k.master_key.clone(), + Some(k) => match &k.master_key { + None => None, + Some(k) => { + let k = &*k.read(); + Some(SecBytes::with(k.len(), |buf| buf.copy_from_slice(k))) + } + }, } }