feat: make clippy happy & update denpendencies

This commit is contained in:
2024-09-03 22:37:32 +08:00
parent 15201b92a5
commit d6c49a15ea
11 changed files with 492 additions and 384 deletions

1
.gitignore vendored
View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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
} }

View File

@@ -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(())
} }

View File

@@ -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])
} }

View File

@@ -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");

View File

@@ -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| {

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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();