moved keys out of config

I believe we are currently not expecting users to change keys.
If we do, I believe we should think about the UX of changing sensitive
data in the CLI.

Also changed "signing key" to "mrsigner key", since all keys are used
for signing.
This commit is contained in:
ghe0 2025-03-21 02:38:20 +02:00
parent 53a654577d
commit 422e04a538
Signed by: ghe0
GPG Key ID: 451028EE56A0FBB4
5 changed files with 46 additions and 41 deletions

@ -16,6 +16,10 @@ pub struct AccountData {
locked_funds: f64, locked_funds: f64,
wallet_address: String, wallet_address: String,
wallet_path: String, wallet_path: String,
hratls_pubkey: String,
hratls_path: String,
mrsigner: String,
mrsigner_key_path: String,
} }
impl super::HumanOutput for AccountData { impl super::HumanOutput for AccountData {
@ -45,13 +49,7 @@ impl super::HumanOutput for AccountData {
#[derive(Serialize, Deserialize, Debug, Default)] #[derive(Serialize, Deserialize, Debug, Default)]
pub struct Config { pub struct Config {
ssh_key_path: String, ssh_key_path: String,
default_dtrfs: String,
default_kernel: String,
brain_url: String, brain_url: String,
pub hratls_pubkey: String,
pub hratls_path: String,
pub mrsigner: String,
pub signing_key_path: String,
} }
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
@ -186,25 +184,25 @@ impl Config {
pub fn init_config() -> Self { pub fn init_config() -> Self {
// TODO: create if it does not exist // TODO: create if it does not exist
match Self::load_config_from_file() { let mut config = match Self::load_config_from_file() {
Ok(config) => config, Ok(config) => config,
Err(e) => { Err(e) => {
debug!("Could not load config due to error: {e}"); debug!("Could not load config due to error: {e}");
eprintln!("Config file not found. Creating new config file!"); eprintln!("Config file not found. Creating new config file!");
let config = Self { let config = Self::default();
hratls_pubkey: Self::get_hratls_pubkey_hex(),
hratls_path: Self::hratls_private_key_path(),
mrsigner: Self::get_mr_signer(),
signing_key_path: Self::signing_key_path(),
..Default::default()
};
if let Err(e) = config.save_to_disk() { if let Err(e) = config.save_to_disk() {
log::error!("Could not save config to disk: {e}"); log::error!("Could not save config to disk: {e}");
panic!("Could not initialize config."); panic!("Could not initialize config.");
}; };
config config
} }
};
// default to testnet if there is no brain_url
// TODO: remove instruction from docs to set brain_url, since it defaults now
if config.brain_url.is_empty() {
config.brain_url = "http://164.92.249.180:31337".to_string();
} }
config
} }
fn create_wallet_key() -> Result<(), Error> { fn create_wallet_key() -> Result<(), Error> {
@ -294,6 +292,11 @@ impl Config {
} }
pub fn set_brain_url(brain_url: &str) { pub fn set_brain_url(brain_url: &str) {
let brain_url = match brain_url {
"testnet" => "http://164.92.249.180:31337",
"staging" => "http://159.65.58.38:31337",
something_else => something_else,
};
let mut config = Self::init_config(); let mut config = Self::init_config();
info!("Setting brain URL to {brain_url}"); info!("Setting brain URL to {brain_url}");
config.brain_url = brain_url.to_string(); config.brain_url = brain_url.to_string();
@ -342,6 +345,12 @@ impl Config {
Err(_) => log::error!("This error should never happen. Please report this bug."), Err(_) => log::error!("This error should never happen. Please report this bug."),
} }
// TODO: Also populate these fields:
// hratls_pubkey: String,
// hratls_path: String,
// mrsigner: String,
// signing_key_path: String,
account_data account_data
} }
} }
@ -372,14 +381,14 @@ impl Config {
pubkey.iter().fold(String::new(), |acc, x| acc + &format!("{:02X?}", x)) pubkey.iter().fold(String::new(), |acc, x| acc + &format!("{:02X?}", x))
} }
fn hratls_private_key_path() -> String { pub fn hratls_private_key_path() -> String {
Self::path_dir().unwrap() + ("/hratls_private_key.pem") Self::path_dir().unwrap() + ("/hratls_private_key.pem")
} }
} }
impl Config { impl Config {
pub fn get_mr_signer() -> String { pub fn get_mrsigner() -> String {
let mut signing_key_mod = Self::get_signing_key().n().to_vec(); let mut signing_key_mod = Self::get_mrsigner_rsa_key().n().to_vec();
signing_key_mod.reverse(); // make it little endian signing_key_mod.reverse(); // make it little endian
let mut hasher = Hasher::new(MessageDigest::sha256()).unwrap(); let mut hasher = Hasher::new(MessageDigest::sha256()).unwrap();
@ -393,17 +402,17 @@ impl Config {
mr_signer.iter().fold(String::new(), |acc, x| acc + &format!("{:02X?}", x)) mr_signer.iter().fold(String::new(), |acc, x| acc + &format!("{:02X?}", x))
} }
fn get_signing_key() -> Rsa<Private> { fn get_mrsigner_rsa_key() -> Rsa<Private> {
let signing_key_pem_str = let signing_key_pem_str = std::fs::read_to_string(Self::mrsigner_key_path())
std::fs::read_to_string(Self::signing_key_path()).unwrap_or_else(|_| { .unwrap_or_else(|_| {
Self::create_signing_key().expect("Failed to create enclave signing key") Self::create_mrsigner_rsa_key().expect("Failed to create enclave signing key")
}); });
Rsa::private_key_from_pem(signing_key_pem_str.as_ref()).unwrap() Rsa::private_key_from_pem(signing_key_pem_str.as_ref()).unwrap()
} }
fn create_signing_key() -> Result<String, Box<dyn std::error::Error>> { fn create_mrsigner_rsa_key() -> Result<String, Box<dyn std::error::Error>> {
let signing_key_path = Self::signing_key_path(); let signing_key_path = Self::mrsigner_key_path();
if Path::new(&signing_key_path).exists() { if Path::new(&signing_key_path).exists() {
log::debug!("Found signing_key at {signing_key_path}"); log::debug!("Found signing_key at {signing_key_path}");
return Err("Key already exists.".into()); return Err("Key already exists.".into());
@ -415,21 +424,11 @@ impl Config {
Ok(String::from_utf8(pem_pkcs8)?) Ok(String::from_utf8(pem_pkcs8)?)
} }
fn signing_key_path() -> String { pub fn mrsigner_key_path() -> String {
Self::path_dir().unwrap() + ("/app_signing_key.pem") Self::path_dir().unwrap() + ("/app_signing_key.pem")
} }
} }
pub fn get_unified_command_output(output: &std::process::Output) -> String {
format!(
"!!! stdout:\n{}\n!!! stderr:\n{}",
String::from_utf8(output.stdout.clone())
.unwrap_or("Could not grab stdout from installation script.".to_string()),
String::from_utf8(output.stderr.clone())
.unwrap_or("Could not grab stderr from installation script.".to_string())
)
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -442,7 +441,7 @@ mod tests {
#[test] #[test]
fn test_mr_signer() { fn test_mr_signer() {
let mr_signer = Config::get_mr_signer(); let mr_signer = Config::get_mrsigner();
println!("mr_signer: {mr_signer}",); println!("mr_signer: {mr_signer}",);
} }
} }

@ -38,8 +38,8 @@ pub async fn new_app(app_deploy_config: AppDeployConfig) -> Result<NewAppRes> {
req.uuid = "".to_string(); req.uuid = "".to_string();
req.locked_nano = locked_nano; req.locked_nano = locked_nano;
req.admin_pubkey = Config::get_detee_wallet().expect("No wallet found"); req.admin_pubkey = Config::get_detee_wallet()?;
req.hratls_pubkey = Config::init_config().hratls_pubkey; req.hratls_pubkey = Config::get_hratls_pubkey_hex();
let mut daemon_serivce = BrainAppCliClient::connect(Config::get_brain_url()).await?; let mut daemon_serivce = BrainAppCliClient::connect(Config::get_brain_url()).await?;
let res = daemon_serivce.deploy_app(sign_request(req)?).await?; let res = daemon_serivce.deploy_app(sign_request(req)?).await?;

@ -39,7 +39,7 @@ pub async fn connect_dtpm_grpc_client(
) -> Result<DtpmConfigManagerClient<Channel>> { ) -> Result<DtpmConfigManagerClient<Channel>> {
let private_key_pem = Config::get_hratls_private_key(); let private_key_pem = Config::get_hratls_private_key();
let mut mr_signer = [0u8; 32]; let mut mr_signer = [0u8; 32];
hex::decode_to_slice(Config::init_config().mrsigner, &mut mr_signer)?; hex::decode_to_slice(Config::get_mrsigner(), &mut mr_signer)?;
let mr_signers = vec![mr_signer]; let mr_signers = vec![mr_signer];
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();

@ -11,8 +11,8 @@ pub fn package_enclave(
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(" "); .join(" ");
let signing_key_path = Config::init_config().signing_key_path; let signing_key_path = Config::mrsigner_key_path();
let hratls_key_path = Config::init_config().hratls_path; let hratls_key_path = Config::hratls_private_key_path();
let docker_package_str = if package_type == "public" { let docker_package_str = if package_type == "public" {
format!( format!(

@ -64,7 +64,13 @@ impl Args {
if !script_result.status.success() { if !script_result.status.success() {
return Err(Error::FailedExecution(format!( return Err(Error::FailedExecution(format!(
"sev-snp-measure.py failed: {}", "sev-snp-measure.py failed: {}",
crate::config::get_unified_command_output(&script_result) format!(
"!!! stdout:\n{}\n!!! stderr:\n{}",
String::from_utf8(script_result.stdout.clone())
.unwrap_or("Could not grab stdout from installation script.".to_string()),
String::from_utf8(script_result.stderr.clone())
.unwrap_or("Could not grab stderr from installation script.".to_string())
)
))); )));
} }
Ok(String::from_utf8(script_result.stdout) Ok(String::from_utf8(script_result.stdout)