feat: v0.1.0
This commit is contained in:
66
Cargo.lock
generated
66
Cargo.lock
generated
@@ -72,6 +72,15 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.1.0"
|
||||
@@ -105,6 +114,15 @@ dependencies = [
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
@@ -114,6 +132,26 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-next"
|
||||
version = "2.0.0"
|
||||
@@ -217,6 +255,16 @@ dependencies = [
|
||||
"pin-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.7"
|
||||
@@ -409,6 +457,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"tokio",
|
||||
"zeroize",
|
||||
]
|
||||
@@ -696,6 +745,17 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.0"
|
||||
@@ -884,6 +944,12 @@ version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.1"
|
||||
|
||||
@@ -10,6 +10,7 @@ zeroize = "1.5.7"
|
||||
clap = "2.33"
|
||||
hex = "0.4"
|
||||
base64 = "0.13.0"
|
||||
sha2 = "0.10.2"
|
||||
lazy_static = "1.4.0"
|
||||
serde_derive = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
181
src/cli.rs
181
src/cli.rs
@@ -1,6 +1,14 @@
|
||||
use std::io::Write;
|
||||
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use rust_util::simple_error;
|
||||
use hyper::{Body, Client, Method, Request, Response, StatusCode};
|
||||
use hyper::body::Buf;
|
||||
use josekit::jwk::Jwk;
|
||||
use rust_util::{debugging, opt_value_result, simple_error, success, XResult};
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
use serde_json::{json, Value};
|
||||
|
||||
use crate::jose;
|
||||
|
||||
pub struct CommandImpl;
|
||||
|
||||
@@ -9,10 +17,175 @@ impl Command for CommandImpl {
|
||||
|
||||
fn subcommand<'a>(&self) -> App<'a, 'a> {
|
||||
SubCommand::with_name(self.name()).about("Local mini KMS cli")
|
||||
.arg(Arg::with_name("connect").long("connect").takes_value(true).default_value("127.0.0.1:6567").help("Connect server"))
|
||||
.arg(Arg::with_name("connect").long("connect").takes_value(true).default_value("127.0.0.1:5567").help("Connect server"))
|
||||
.arg(Arg::with_name("init").long("init").help("Init server"))
|
||||
.arg(Arg::with_name("offline-init").long("offline-init").help("Offline init server"))
|
||||
.arg(Arg::with_name("encrypt").long("encrypt").help("Encrypt text"))
|
||||
.arg(Arg::with_name("decrypt").long("decrypt").help("Decrypt text"))
|
||||
.arg(Arg::with_name("value").long("value").takes_value(true).help("Value, for encrypt or decrypt"))
|
||||
.arg(Arg::with_name("value-hex").long("value-hex").takes_value(true).help("Value(hex), for encrypt"))
|
||||
.arg(Arg::with_name("value-base64").long("value-base64").takes_value(true).help("Value(base64), for encrypt"))
|
||||
}
|
||||
|
||||
fn run(&self, _arg_matches: &ArgMatches, _sub_arg_matches: &ArgMatches) -> CommandError {
|
||||
simple_error!("Not implemented")
|
||||
fn run(&self, arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
|
||||
let init = sub_arg_matches.is_present("init");
|
||||
let offline_init = sub_arg_matches.is_present("offline-init");
|
||||
let encrypt = sub_arg_matches.is_present("encrypt");
|
||||
let decrypt = sub_arg_matches.is_present("decrypt");
|
||||
let rt = tokio::runtime::Runtime::new().expect("Create tokio runtime error");
|
||||
if init {
|
||||
rt.block_on(async {
|
||||
do_init(arg_matches, sub_arg_matches).await
|
||||
})
|
||||
} else if offline_init {
|
||||
do_offline_init(arg_matches, sub_arg_matches)
|
||||
} else if encrypt {
|
||||
rt.block_on(async {
|
||||
do_encrypt(arg_matches, sub_arg_matches).await
|
||||
})
|
||||
} else if decrypt {
|
||||
rt.block_on(async {
|
||||
do_decrypt(arg_matches, sub_arg_matches).await
|
||||
})
|
||||
} else {
|
||||
simple_error!("Need a flag")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn do_init(_arg_matches: &ArgMatches<'_>, sub_arg_matches: &ArgMatches<'_>) -> CommandError {
|
||||
let connect = sub_arg_matches.value_of("connect").expect("Get argument listen error");
|
||||
|
||||
let client = Client::new();
|
||||
let uri = format!("http://{}/status", connect);
|
||||
debugging!("Request uri: {}", &uri);
|
||||
let req = Request::builder().method(Method::GET).uri(uri).body(Body::empty())?;
|
||||
let req_response = client.request(req).await?;
|
||||
if req_response.status() != StatusCode::OK {
|
||||
return simple_error!("Server status is not success: {}", req_response.status().as_u16());
|
||||
}
|
||||
let data = response_to_value(req_response).await?;
|
||||
debugging!("Get status: {}", &data);
|
||||
let status = &data["status"];
|
||||
if let Some(status) = status.as_str() {
|
||||
if status == "ready" {
|
||||
success!("Server is already init");
|
||||
return Ok(Some(0));
|
||||
}
|
||||
if status != "not-ready" {
|
||||
return simple_error!("Server status is NOT not-ready");
|
||||
}
|
||||
}
|
||||
let instance_public_key_jwk = &data["instance_public_key_jwk"];
|
||||
println!("Instance server public key JWK: {}", instance_public_key_jwk);
|
||||
|
||||
let line = read_line("Input encrypted master key: ")?;
|
||||
let uri = format!("http://{}/init", connect);
|
||||
debugging!("Request uri: {}", &uri);
|
||||
let body = json!({
|
||||
"encrypted_master_key": line,
|
||||
});
|
||||
let body = serde_json::to_string(&body)?;
|
||||
let req = Request::builder().method(Method::POST).uri(uri).body(Body::from(body))?;
|
||||
|
||||
let req_response = client.request(req).await?;
|
||||
if req_response.status() != StatusCode::OK {
|
||||
let status = req_response.status().as_u16();
|
||||
let data = response_to_value(req_response).await?;
|
||||
return simple_error!("Server status is not success: {}, response: {}", status, data);
|
||||
}
|
||||
success!("Init finished");
|
||||
Ok(Some(0))
|
||||
}
|
||||
|
||||
async fn do_encrypt(_arg_matches: &ArgMatches<'_>, sub_arg_matches: &ArgMatches<'_>) -> CommandError {
|
||||
let connect = sub_arg_matches.value_of("connect").expect("Get argument listen error");
|
||||
let value = sub_arg_matches.value_of("value");
|
||||
let value_hex = sub_arg_matches.value_of("value-hex");
|
||||
let value_base64 = sub_arg_matches.value_of("value-base64");
|
||||
|
||||
let client = Client::new();
|
||||
let uri = format!("http://{}/encrypt", connect);
|
||||
debugging!("Request uri: {}", &uri);
|
||||
let body = if let Some(value) = value {
|
||||
json!({ "value": value })
|
||||
} else if let Some(value_hex) = value_hex {
|
||||
json!({ "value_hex": value_hex })
|
||||
} else if let Some(value_base64) = value_base64 {
|
||||
json!({ "value_base64": value_base64 })
|
||||
} else {
|
||||
return simple_error!("Require one of value, value-hex, value-base64");
|
||||
};
|
||||
let body = serde_json::to_string(&body)?;
|
||||
let req = Request::builder().method(Method::POST).uri(uri).body(Body::from(body))?;
|
||||
|
||||
let req_response = client.request(req).await?;
|
||||
if req_response.status() != StatusCode::OK {
|
||||
let status = req_response.status().as_u16();
|
||||
let data = response_to_value(req_response).await?;
|
||||
return simple_error!("Server status is not success: {}, response: {}", status, data);
|
||||
}
|
||||
let data = response_to_value(req_response).await?;
|
||||
success!("Encrypted value: {}", data["encrypted_value"].as_str().expect("Get encrypted_value error"));
|
||||
Ok(Some(0))
|
||||
}
|
||||
|
||||
async fn do_decrypt(_arg_matches: &ArgMatches<'_>, sub_arg_matches: &ArgMatches<'_>) -> CommandError {
|
||||
let connect = sub_arg_matches.value_of("connect").expect("Get argument listen error");
|
||||
let value = opt_value_result!(sub_arg_matches.value_of("value"), "Argument value required");
|
||||
|
||||
let client = Client::new();
|
||||
let uri = format!("http://{}/decrypt", connect);
|
||||
debugging!("Request uri: {}", &uri);
|
||||
let body = json!({ "encrypted_value": value });
|
||||
let body = serde_json::to_string(&body)?;
|
||||
let req = Request::builder().method(Method::POST).uri(uri).body(Body::from(body))?;
|
||||
|
||||
let req_response = client.request(req).await?;
|
||||
if req_response.status() != StatusCode::OK {
|
||||
let status = req_response.status().as_u16();
|
||||
let data = response_to_value(req_response).await?;
|
||||
return simple_error!("Server status is not success: {}, response: {}", status, data);
|
||||
}
|
||||
let data = response_to_value(req_response).await?;
|
||||
success!("Encrypted value(hex): {}", data["value_hex"].as_str().expect("Get value_hex error"));
|
||||
success!("Encrypted value(base64): {}", data["value_base64"].as_str().expect("Get value_base64 error"));
|
||||
success!("Encrypted value: {}", String::from_utf8_lossy(&hex::decode(data["value_hex"].as_str().expect("Get value_hex error"))?).to_string());
|
||||
Ok(Some(0))
|
||||
}
|
||||
|
||||
fn do_offline_init(_arg_matches: &ArgMatches<'_>, _sub_arg_matches: &ArgMatches<'_>) -> CommandError {
|
||||
let line = read_line("Input master key: ")?;
|
||||
let master_key = if line.starts_with("hex:") {
|
||||
let hex: String = line.chars().skip(4).collect();
|
||||
hex::decode(&hex)?
|
||||
} else if line.starts_with("base64:") {
|
||||
let base64: String = line.chars().skip(7).collect();
|
||||
base64::decode(&base64)?
|
||||
} else {
|
||||
line.as_bytes().to_vec()
|
||||
};
|
||||
let jwk = read_line("Input JWK: ")?;
|
||||
let jwk = Jwk::from_bytes(jwk.as_bytes())?;
|
||||
let encrypted_master_key = jose::serialize_jwe_rsa(&master_key, &jwk)?;
|
||||
|
||||
success!("Encrypted master key: {}", encrypted_master_key);
|
||||
Ok(Some(0))
|
||||
}
|
||||
|
||||
fn read_line(prompt: &str) -> XResult<String> {
|
||||
std::io::stdout().write(prompt.as_bytes()).ok();
|
||||
std::io::stdout().flush().ok();
|
||||
let mut line = String::new();
|
||||
if let Err(e) = std::io::stdin().read_line(&mut line) {
|
||||
return simple_error!("Read from terminal failed: {}", e);
|
||||
}
|
||||
Ok(line.trim().to_string())
|
||||
}
|
||||
|
||||
async fn response_to_value(response: Response<Body>) -> XResult<Value> {
|
||||
let req_body = response.into_body();
|
||||
let whole_body = hyper::body::aggregate(req_body).await?;
|
||||
let data: Value = serde_json::from_reader(whole_body.reader())?;
|
||||
Ok(data)
|
||||
}
|
||||
28
src/jose.rs
28
src/jose.rs
@@ -6,6 +6,7 @@ use josekit::jwk::alg::rsa::RsaKeyPair;
|
||||
use josekit::jwk::Jwk;
|
||||
use rust_util::XResult;
|
||||
use serde_json::Value;
|
||||
use sha2::Digest;
|
||||
|
||||
const LOCAL_KMS_PREFIX: &'static str = "LKMS:";
|
||||
|
||||
@@ -13,23 +14,24 @@ pub fn generate_rsa_key(bits: u32) -> XResult<RsaKeyPair> {
|
||||
Ok(RsaKeyPair::generate(bits)?)
|
||||
}
|
||||
|
||||
// pub fn serialize_jwe_rsa(payload: &[u8], jwk: &Jwk) -> XResult<String> {
|
||||
// let mut header = JweHeader::new();
|
||||
// header.set_content_encryption("A256GCM");
|
||||
// header.set_claim("vendor", Some(Value::String("local-mini-kms".to_string())))?;
|
||||
// let encrypter = RsaesJweAlgorithm::RsaOaep.encrypter_from_jwk(&jwk)?;
|
||||
// Ok(format!("{}{}", LOCAL_KMS_PREFIX, jwe::serialize_compact(payload, &header, &encrypter)?))
|
||||
// }
|
||||
pub fn serialize_jwe_rsa(payload: &[u8], jwk: &Jwk) -> XResult<String> {
|
||||
let mut header = JweHeader::new();
|
||||
header.set_content_encryption("A256GCM");
|
||||
header.set_claim("vendor", Some(Value::String("local-mini-kms".to_string())))?;
|
||||
let encrypter = RsaesJweAlgorithm::RsaOaep.encrypter_from_jwk(&jwk)?;
|
||||
Ok(format!("{}{}", LOCAL_KMS_PREFIX, jwe::serialize_compact(payload, &header, &encrypter)?))
|
||||
}
|
||||
|
||||
pub fn deserialize_jwe_rsa(jwe: &str, jwk: &Jwk) -> XResult<(Vec<u8>, JweHeader)> {
|
||||
let decrypter = RsaesJweAlgorithm::RsaOaep.decrypter_from_jwk(jwk)?;
|
||||
Ok(jwe::deserialize_json(&get_jwe(jwe), &decrypter)?)
|
||||
Ok(jwe::deserialize_compact(&get_jwe(jwe), &decrypter)?)
|
||||
}
|
||||
|
||||
pub fn serialize_jwe_aes(payload: &[u8], key: &[u8]) -> XResult<String> {
|
||||
let mut header = JweHeader::new();
|
||||
header.set_content_encryption("A256GCM");
|
||||
header.set_claim("vendor", Some(Value::String("local-mini-kms".to_string())))?;
|
||||
header.set_claim("version", Some(Value::String(get_master_key_checksum(key))))?;
|
||||
let encrypter = AeskwJweAlgorithm::A256kw.encrypter_from_bytes(key)?;
|
||||
Ok(format!("{}{}", LOCAL_KMS_PREFIX, jwe::serialize_compact(payload, &header, &encrypter)?))
|
||||
}
|
||||
@@ -39,6 +41,16 @@ pub fn deserialize_jwe_aes(jwe: &str, key: &[u8]) -> XResult<(Vec<u8>, JweHeader
|
||||
Ok(jwe::deserialize_compact(&get_jwe(jwe), &decrypter)?)
|
||||
}
|
||||
|
||||
fn get_master_key_checksum(key: &[u8]) -> String {
|
||||
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());
|
||||
hex::encode(&digest[0..8])
|
||||
}
|
||||
|
||||
fn get_jwe(jwe: &str) -> String {
|
||||
if jwe.starts_with(LOCAL_KMS_PREFIX) {
|
||||
jwe.chars().skip(LOCAL_KMS_PREFIX.len()).collect()
|
||||
|
||||
49
src/serve.rs
49
src/serve.rs
@@ -7,10 +7,10 @@ use hyper::client::HttpConnector;
|
||||
use hyper::service::{make_service_fn, service_fn};
|
||||
use josekit::jwk::alg::rsa::RsaKeyPair;
|
||||
use josekit::jwk::KeyPair;
|
||||
use rust_util::{debugging, failure_and_exit, information, opt_result, opt_value_result, simple_error, success, XResult};
|
||||
use rust_util::{debugging, failure_and_exit, information, opt_result, simple_error, success, XResult};
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Value};
|
||||
use serde_json::{json, Map, Value};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use crate::{db, jose};
|
||||
@@ -165,10 +165,42 @@ impl MultipleViewValue {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct DecryptRequest {
|
||||
encrypted_value: String,
|
||||
}
|
||||
|
||||
async fn decrypt(req: Request<Body>) -> Result<Response<Body>> {
|
||||
do_response!(inner_decrypt(req).await)
|
||||
}
|
||||
|
||||
async fn inner_decrypt(req: Request<Body>) -> XResult<(StatusCode, Value)> {
|
||||
let whole_body = hyper::body::aggregate(req).await?;
|
||||
let data: serde_json::Value = serde_json::from_reader(whole_body.reader())?;
|
||||
Ok(Response::builder().body(format!("{}", data).into())?)
|
||||
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() {
|
||||
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();
|
||||
|
||||
decrypted_value.map(|v| {
|
||||
let v = MultipleViewValue::from(&v.0);
|
||||
let mut map = Map::new();
|
||||
if let Some(v) = &v.value {
|
||||
map.insert("value".to_string(), Value::String(v.to_string()));
|
||||
}
|
||||
if let Some(v) = &v.value_hex {
|
||||
map.insert("value_hex".to_string(), Value::String(v.to_string()));
|
||||
}
|
||||
if let Some(v) = &v.value_base64 {
|
||||
map.insert("value_base64".to_string(), Value::String(v.to_string()));
|
||||
}
|
||||
(StatusCode::OK, Value::Object(map))
|
||||
})
|
||||
}
|
||||
|
||||
async fn encrypt(req: Request<Body>) -> Result<Response<Body>> {
|
||||
@@ -179,7 +211,10 @@ async fn inner_encrypt(req: Request<Body>) -> 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 = opt_value_result!( get_master_key(), "Server is not init");
|
||||
let mut 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();
|
||||
|
||||
@@ -230,6 +265,7 @@ async fn inner_init(req: Request<Body>) -> XResult<(StatusCode, Value)> {
|
||||
} else if let Some(clear_master_key_hex) = init_request.clear_master_key_hex {
|
||||
hex::decode(clear_master_key_hex)?
|
||||
} else if let Some(encrypted_master_key) = init_request.encrypted_master_key {
|
||||
debugging!("Received encrypted master key: {}", encrypted_master_key);
|
||||
if let Some(k) = &*startup_rw_lock {
|
||||
let (clear_master_key, _) = jose::deserialize_jwe_rsa(&encrypted_master_key, &k.instance_rsa_key_pair.to_jwk_private_key())?;
|
||||
clear_master_key
|
||||
@@ -262,6 +298,7 @@ async fn inner_init(req: Request<Body>) -> XResult<(StatusCode, Value)> {
|
||||
}
|
||||
information!("Set master key success");
|
||||
k.master_key = Some(clear_master_key);
|
||||
k.instance_rsa_key_pair = jose::generate_rsa_key(4096)?;
|
||||
}
|
||||
Ok((StatusCode::OK, json!({})))
|
||||
}
|
||||
@@ -278,10 +315,10 @@ async fn inner_status() -> XResult<(StatusCode, Value)> {
|
||||
None => json!({
|
||||
"status": "not-ready",
|
||||
"instance_public_key_jwk": memory_key.instance_rsa_key_pair.to_jwk_key_pair().to_public_key()?,
|
||||
"instance_public_key_pem": String::from_utf8_lossy(&memory_key.instance_rsa_key_pair.to_pem_public_key()).to_string(),
|
||||
}),
|
||||
Some(_) => json!({
|
||||
"status": "ready",
|
||||
"instance_public_key_jwk": memory_key.instance_rsa_key_pair.to_jwk_key_pair().to_public_key()?,
|
||||
}),
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user