feat: make clippy happy & update denpendencies
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
local-mini-kms
|
||||||
LOCAL_README.md
|
LOCAL_README.md
|
||||||
*_gitignore.*
|
*_gitignore.*
|
||||||
local-mini-kms.db
|
local-mini-kms.db
|
||||||
|
|||||||
804
Cargo.lock
generated
804
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "local-mini-kms"
|
name = "local-mini-kms"
|
||||||
version = "0.3.3"
|
version = "0.3.4"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ fn do_offline_init(_arg_matches: &ArgMatches<'_>, _sub_arg_matches: &ArgMatches<
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_line(prompt: &str) -> XResult<String> {
|
fn read_line(prompt: &str) -> XResult<String> {
|
||||||
std::io::stdout().write(prompt.as_bytes()).ok();
|
std::io::stdout().write_all(prompt.as_bytes()).ok();
|
||||||
std::io::stdout().flush().ok();
|
std::io::stdout().flush().ok();
|
||||||
let mut line = String::new();
|
let mut line = String::new();
|
||||||
if let Err(e) = std::io::stdin().read_line(&mut line) {
|
if let Err(e) = std::io::stdin().read_line(&mut line) {
|
||||||
@@ -246,5 +246,5 @@ async fn do_inner_request(sub_arg_matches: &ArgMatches<'_>, action: &str, body:
|
|||||||
let data = response_to_value(req_response).await?;
|
let data = response_to_value(req_response).await?;
|
||||||
return simple_error!("Server status is not success: {}, response: {}", status, data);
|
return simple_error!("Server status is not success: {}, response: {}", status, data);
|
||||||
}
|
}
|
||||||
Ok(response_to_value(req_response).await?)
|
response_to_value(req_response).await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use rusqlite::{Connection, params};
|
use rusqlite::{Connection, params};
|
||||||
use rust_util::{debugging, information, opt_result, simple_error, success, XResult};
|
use rust_util::{debugging, information, opt_result, simple_error, success, XResult};
|
||||||
|
|
||||||
pub const DEFAULT_MASTER_KEY_VERIFICATION_KEY: &'static str = "__master_verification_key";
|
pub const DEFAULT_MASTER_KEY_VERIFICATION_KEY: &str = "__master_verification_key";
|
||||||
|
|
||||||
pub struct Key {
|
pub struct Key {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@@ -44,7 +44,7 @@ pub fn insert_key(conn: &Connection, key: &Key) -> XResult<()> {
|
|||||||
let default_comment = "".to_string();
|
let default_comment = "".to_string();
|
||||||
let _ = conn.execute(
|
let _ = conn.execute(
|
||||||
"INSERT INTO keys (name, value, comment) VALUES (?1, ?2, ?3)",
|
"INSERT INTO keys (name, value, comment) VALUES (?1, ?2, ?3)",
|
||||||
(&key.name, &key.encrypted_key, key.comment.as_ref().unwrap_or_else(|| &default_comment)),
|
(&key.name, &key.encrypted_key, key.comment.as_ref().unwrap_or(&default_comment)),
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/jose.rs
16
src/jose.rs
@@ -8,7 +8,7 @@ use rust_util::XResult;
|
|||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use sha2::Digest;
|
use sha2::Digest;
|
||||||
|
|
||||||
const LOCAL_KMS_PREFIX: &'static str = "LKMS:";
|
const LOCAL_KMS_PREFIX: &str = "LKMS:";
|
||||||
|
|
||||||
pub fn generate_rsa_key(bits: u32) -> XResult<RsaKeyPair> {
|
pub fn generate_rsa_key(bits: u32) -> XResult<RsaKeyPair> {
|
||||||
Ok(RsaKeyPair::generate(bits)?)
|
Ok(RsaKeyPair::generate(bits)?)
|
||||||
@@ -18,7 +18,7 @@ pub fn serialize_jwe_rsa(payload: &[u8], jwk: &Jwk) -> XResult<String> {
|
|||||||
let mut header = JweHeader::new();
|
let mut header = JweHeader::new();
|
||||||
header.set_content_encryption("A256GCM");
|
header.set_content_encryption("A256GCM");
|
||||||
header.set_claim("vendor", Some(Value::String("local-mini-kms".to_string())))?;
|
header.set_claim("vendor", Some(Value::String("local-mini-kms".to_string())))?;
|
||||||
let encrypter = RsaesJweAlgorithm::RsaOaep.encrypter_from_jwk(&jwk)?;
|
let encrypter = RsaesJweAlgorithm::RsaOaep.encrypter_from_jwk(jwk)?;
|
||||||
Ok(format!("{}{}", LOCAL_KMS_PREFIX, jwe::serialize_compact(payload, &header, &encrypter)?))
|
Ok(format!("{}{}", LOCAL_KMS_PREFIX, jwe::serialize_compact(payload, &header, &encrypter)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,12 +42,12 @@ pub fn deserialize_jwe_aes(jwe: &str, key: &[u8]) -> XResult<(Vec<u8>, JweHeader
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_master_key_checksum(key: &[u8]) -> String {
|
fn get_master_key_checksum(key: &[u8]) -> String {
|
||||||
let digest = sha2::Sha256::digest(&key);
|
let digest = sha2::Sha256::digest(key);
|
||||||
let digest = sha2::Sha256::digest(&digest.as_slice());
|
let digest = sha2::Sha256::digest(digest.as_slice());
|
||||||
let digest = sha2::Sha256::digest(&digest.as_slice());
|
let digest = sha2::Sha256::digest(digest.as_slice());
|
||||||
let digest = sha2::Sha256::digest(&digest.as_slice());
|
let digest = sha2::Sha256::digest(digest.as_slice());
|
||||||
let digest = sha2::Sha256::digest(&digest.as_slice());
|
let digest = sha2::Sha256::digest(digest.as_slice());
|
||||||
let digest = sha2::Sha256::digest(&digest.as_slice());
|
let digest = sha2::Sha256::digest(digest.as_slice());
|
||||||
hex::encode(&digest[0..8])
|
hex::encode(&digest[0..8])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
src/serve.rs
22
src/serve.rs
@@ -1,16 +1,15 @@
|
|||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||||
use hyper::{Body, Client, Method, Request, Response, Server, StatusCode};
|
|
||||||
use hyper::client::HttpConnector;
|
use hyper::client::HttpConnector;
|
||||||
use hyper::server::conn::AddrStream;
|
use hyper::server::conn::AddrStream;
|
||||||
use hyper::service::{make_service_fn, service_fn};
|
use hyper::service::{make_service_fn, service_fn};
|
||||||
use rust_util::{failure_and_exit, information, success, warning, XResult};
|
use hyper::{Body, Client, Method, Request, Response, Server, StatusCode};
|
||||||
use rust_util::util_clap::{Command, CommandError};
|
use rust_util::util_clap::{Command, CommandError};
|
||||||
|
use rust_util::{failure_and_exit, information, success, warning, XResult};
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
|
|
||||||
use crate::{db, jose, proc};
|
|
||||||
use crate::do_response;
|
use crate::do_response;
|
||||||
use crate::serve_common::{self, GenericError, MemoryKey, Result};
|
use crate::serve_common::{self, GenericError, MemoryKey, Result};
|
||||||
use crate::serve_encrypt_decrypt;
|
use crate::serve_encrypt_decrypt;
|
||||||
@@ -19,6 +18,7 @@ use crate::serve_init::InitRequest;
|
|||||||
use crate::serve_read_write;
|
use crate::serve_read_write;
|
||||||
use crate::serve_status;
|
use crate::serve_status;
|
||||||
use crate::yubikey_hmac;
|
use crate::yubikey_hmac;
|
||||||
|
use crate::{db, jose, proc};
|
||||||
|
|
||||||
pub struct CommandImpl;
|
pub struct CommandImpl;
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ impl Command for CommandImpl {
|
|||||||
|
|
||||||
let listen = sub_arg_matches.value_of("listen").expect("Get argument listen error");
|
let listen = sub_arg_matches.value_of("listen").expect("Get argument listen error");
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let addr = listen.parse().expect(&format!("Parse listen error: {}", listen));
|
let addr = listen.parse().unwrap_or_else(|_| panic!("Parse listen error: {}", listen));
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
let new_service = make_service_fn(move |conn: &AddrStream| {
|
let new_service = make_service_fn(move |conn: &AddrStream| {
|
||||||
let remote_addr = conn.remote_addr();
|
let remote_addr = conn.remote_addr();
|
||||||
@@ -76,7 +76,17 @@ async fn response_requests(
|
|||||||
_client: Client<HttpConnector>,
|
_client: Client<HttpConnector>,
|
||||||
) -> Result<Response<Body>> {
|
) -> Result<Response<Body>> {
|
||||||
let process = proc::get_process(remote_addr.port());
|
let process = proc::get_process(remote_addr.port());
|
||||||
information!("Receive request: {}, from: {}, process: {:?}", req.uri(), remote_addr, process);
|
match process {
|
||||||
|
None => information!( "Receive request: {}, from: {}", req.uri(), remote_addr ),
|
||||||
|
Some(process) => information!(
|
||||||
|
"Receive request: {}, from: {}, process: {} {} {:?}",
|
||||||
|
req.uri(),
|
||||||
|
remote_addr,
|
||||||
|
process.pid,
|
||||||
|
process.comm,
|
||||||
|
process.exec
|
||||||
|
),
|
||||||
|
}
|
||||||
match (req.method(), req.uri().path()) {
|
match (req.method(), req.uri().path()) {
|
||||||
(&Method::POST, "/init") => serve_init::init(req).await,
|
(&Method::POST, "/init") => serve_init::init(req).await,
|
||||||
(&Method::POST, "/update") => update().await,
|
(&Method::POST, "/update") => update().await,
|
||||||
@@ -189,7 +199,7 @@ fn init_with_yubikey_challenge(rt: &Runtime, sub_arg_matches: &ArgMatches) {
|
|||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
match jose::deserialize_jwe_aes(&init_encrypted_master_key, &challenge_key) {
|
match jose::deserialize_jwe_aes(init_encrypted_master_key, &challenge_key) {
|
||||||
Err(e) => warning!("Yubikey seal master key failed: {}", e),
|
Err(e) => warning!("Yubikey seal master key failed: {}", e),
|
||||||
Ok((key, _)) => {
|
Ok((key, _)) => {
|
||||||
success!("Yubikey un-seal master key success");
|
success!("Yubikey un-seal master key success");
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ async fn inner_decrypt(req: Request<Body>) -> XResult<(StatusCode, Value)> {
|
|||||||
None => return serve_common::error("status_not_ready"),
|
None => return serve_common::error("status_not_ready"),
|
||||||
Some(key) => key,
|
Some(key) => key,
|
||||||
};
|
};
|
||||||
let decrypted_value = jose::deserialize_jwe_aes(&data.encrypted_value, &*key.read());
|
let decrypted_value = jose::deserialize_jwe_aes(&data.encrypted_value, &key.read());
|
||||||
drop(key);
|
drop(key);
|
||||||
|
|
||||||
decrypted_value.map(|v| {
|
decrypted_value.map(|v| {
|
||||||
@@ -49,7 +49,7 @@ async fn inner_encrypt(req: Request<Body>) -> XResult<(StatusCode, Value)> {
|
|||||||
None => return serve_common::error("status_not_ready"),
|
None => return serve_common::error("status_not_ready"),
|
||||||
Some(key) => key,
|
Some(key) => key,
|
||||||
};
|
};
|
||||||
let encrypt_result = jose::serialize_jwe_aes(&value, &*key.read());
|
let encrypt_result = jose::serialize_jwe_aes(&value, &key.read());
|
||||||
drop(key);
|
drop(key);
|
||||||
|
|
||||||
encrypt_result.map(|e| {
|
encrypt_result.map(|e| {
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
use base64::Engine;
|
|
||||||
use base64::engine::general_purpose::STANDARD;
|
use base64::engine::general_purpose::STANDARD;
|
||||||
use hyper::{Body, Request, Response, StatusCode};
|
use base64::Engine;
|
||||||
use hyper::body::Buf;
|
use hyper::body::Buf;
|
||||||
|
use hyper::{Body, Request, Response, StatusCode};
|
||||||
use rust_util::{debugging, information, opt_result, success, warning, XResult};
|
use rust_util::{debugging, information, opt_result, success, warning, XResult};
|
||||||
use seckey::SecBytes;
|
use seckey::SecBytes;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use zeroize::Zeroize;
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
use crate::{db, jose};
|
|
||||||
use crate::db::Key;
|
use crate::db::Key;
|
||||||
use crate::do_response;
|
use crate::do_response;
|
||||||
use crate::serve_common::{self, Result};
|
use crate::serve_common::{self, Result};
|
||||||
use crate::yubikey_hmac;
|
use crate::yubikey_hmac;
|
||||||
|
use crate::{db, jose};
|
||||||
|
|
||||||
pub async fn init(req: Request<Body>) -> Result<Response<Body>> {
|
pub async fn init(req: Request<Body>) -> Result<Response<Body>> {
|
||||||
do_response!(inner_init(req).await)
|
do_response!(inner_init(req).await)
|
||||||
@@ -37,9 +37,8 @@ pub async fn inner_init_request(init_request: InitRequest) -> XResult<(StatusCod
|
|||||||
let mut startup_rw_lock = serve_common::STATUP_RW_LOCK.lock().expect("Lock read startup rw lock error");
|
let mut startup_rw_lock = serve_common::STATUP_RW_LOCK.lock().expect("Lock read startup rw lock error");
|
||||||
match &*startup_rw_lock {
|
match &*startup_rw_lock {
|
||||||
None => return Ok((StatusCode::INTERNAL_SERVER_ERROR, json!({ "error": "internal_error", "error_message": "not init " }))),
|
None => return Ok((StatusCode::INTERNAL_SERVER_ERROR, json!({ "error": "internal_error", "error_message": "not init " }))),
|
||||||
Some(memory_key) => match memory_key.master_key {
|
Some(memory_key) => if memory_key.master_key.is_some() {
|
||||||
Some(_) => return Ok((StatusCode::BAD_REQUEST, json!({ "error": "bad_request", "error_message": "already init " }))),
|
return Ok((StatusCode::BAD_REQUEST, json!({ "error": "bad_request", "error_message": "already init " })));
|
||||||
None => {}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +91,7 @@ pub async fn inner_init_request(init_request: InitRequest) -> XResult<(StatusCod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let sec_bytes = SecBytes::with(clear_master_key.len(), |buf| buf.copy_from_slice(&clear_master_key.as_slice()[..]));
|
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;
|
let mut clear_master_key = clear_master_key;
|
||||||
clear_master_key.zeroize();
|
clear_master_key.zeroize();
|
||||||
k.master_key = Some(sec_bytes);
|
k.master_key = Some(sec_bytes);
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ async fn inner_read(req: Request<Body>) -> XResult<(StatusCode, Value)> {
|
|||||||
None => return serve_common::error("status_not_ready"),
|
None => return serve_common::error("status_not_ready"),
|
||||||
Some(key) => key,
|
Some(key) => key,
|
||||||
};
|
};
|
||||||
let data = jose::deserialize_jwe_aes(&db_key_value.encrypted_key, &*key.read())?;
|
let data = jose::deserialize_jwe_aes(&db_key_value.encrypted_key, &key.read())?;
|
||||||
drop(key);
|
drop(key);
|
||||||
|
|
||||||
let mut map = byte_to_multi_view_map(&data.0);
|
let mut map = byte_to_multi_view_map(&data.0);
|
||||||
@@ -82,7 +82,7 @@ async fn inner_write(req: Request<Body>) -> XResult<(StatusCode, Value)> {
|
|||||||
None => return serve_common::error("status_not_ready"),
|
None => return serve_common::error("status_not_ready"),
|
||||||
Some(key) => key,
|
Some(key) => key,
|
||||||
};
|
};
|
||||||
let encrypt_value = jose::serialize_jwe_aes(&value, &*key.read())?;
|
let encrypt_value = jose::serialize_jwe_aes(&value, &key.read())?;
|
||||||
drop(key);
|
drop(key);
|
||||||
|
|
||||||
let new_db_key = Key {
|
let new_db_key = Key {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ pub fn yubikey_challenge_as_32_bytes(challenge_bytes: &[u8]) -> XResult<Vec<u8>>
|
|||||||
.set_slot(Slot::Slot2);
|
.set_slot(Slot::Slot2);
|
||||||
|
|
||||||
// In HMAC Mode, the result will always be the SAME for the SAME provided challenge
|
// In HMAC Mode, the result will always be the SAME for the SAME provided challenge
|
||||||
let hmac_result = opt_result!(yubi.challenge_response_hmac(&challenge_bytes, config), "Challenge HMAC failed: {}");
|
let hmac_result = opt_result!(yubi.challenge_response_hmac(challenge_bytes, config), "Challenge HMAC failed: {}");
|
||||||
|
|
||||||
// Just for debug, lets check the hex
|
// Just for debug, lets check the hex
|
||||||
let v: &[u8] = hmac_result.deref();
|
let v: &[u8] = hmac_result.deref();
|
||||||
|
|||||||
Reference in New Issue
Block a user