From 634bc6a8f3e9be7975154ce786a4322461f3a8a7 Mon Sep 17 00:00:00 2001 From: Daniel Gushchyan <39884512+dangush@users.noreply.github.com> Date: Fri, 4 Oct 2024 05:41:59 -0700 Subject: [PATCH] feat: input admin secret to gramine as env var (#238) Co-authored-by: hu55a1n1 --- .github/workflows/rust.yml | 15 ++++--- crates/cli/src/cli.rs | 8 ---- crates/cli/src/handler/dev.rs | 7 ++-- crates/cli/src/handler/enclave_start.rs | 9 +++-- crates/cli/src/request.rs | 2 - crates/cli/src/request/dev.rs | 1 - crates/cli/src/request/enclave_start.rs | 3 -- crates/enclave/core/src/server.rs | 3 +- crates/utils/cw-client/data/admin.sk | 1 - crates/utils/cw-client/src/grpc.rs | 40 +++++++++---------- .../enclave/quartz.manifest.template | 4 +- examples/transfers/enclave/src/cli.rs | 5 +-- examples/transfers/enclave/src/main.rs | 4 +- examples/transfers/enclave/src/wslistener.rs | 16 ++++++-- 14 files changed, 54 insertions(+), 64 deletions(-) delete mode 100644 crates/utils/cw-client/data/admin.sk diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8e5f412..3e2f58f 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -5,19 +5,18 @@ on: - .github/workflows/rust.yml - Cargo.lock - Cargo.toml - - core/** - - relayer/** - - utils/** + - crates/** + - examples/** + - "!examples/transfers/frontend/**" push: - branches: master + branches: main paths: - .github/workflows/rust.yml - - .gitmodules - Cargo.lock - Cargo.toml - - core/** - - relayer/** - - utils/** + - crates/** + - examples/** + - "!examples/transfers/frontend/**" env: CARGO_INCREMENTAL: 0 diff --git a/crates/cli/src/cli.rs b/crates/cli/src/cli.rs index 8f29c92..fabac74 100644 --- a/crates/cli/src/cli.rs +++ b/crates/cli/src/cli.rs @@ -223,10 +223,6 @@ pub struct EnclaveStartArgs { #[arg(long)] pub unsafe_trust_latest: bool, - /// file containing the secret key of the tx-sender for the enclave - #[arg(long)] - pub sk_file: PathBuf, - /// FMSPC (Family-Model-Stepping-Platform-Custom SKU); required if `MOCK_SGX` is not set #[arg(long)] #[serde(skip_serializing_if = "Option::is_none")] @@ -264,10 +260,6 @@ pub struct DevArgs { #[command(flatten)] pub enclave_build: EnclaveBuildArgs, - /// file containing the secret key of the tx-sender for the enclave - #[arg(long)] - pub sk_file: PathBuf, - /// FMSPC (Family-Model-Stepping-Platform-Custom SKU); required if `MOCK_SGX` is not set #[arg(long)] #[serde(skip_serializing_if = "Option::is_none")] diff --git a/crates/cli/src/handler/dev.rs b/crates/cli/src/handler/dev.rs index 5c80a75..8be483a 100644 --- a/crates/cli/src/handler/dev.rs +++ b/crates/cli/src/handler/dev.rs @@ -170,7 +170,6 @@ async fn dev_driver( fn spawn_enclave_start(args: &DevRequest, config: &Config) -> Result<(), Error> { // In separate process, launch the enclave let enclave_start = EnclaveStartRequest { - sk_file: args.sk_file.clone(), unsafe_trust_latest: args.unsafe_trust_latest, fmspc: args.fmspc.clone(), tcbinfo_contract: args.tcbinfo_contract.clone(), @@ -180,9 +179,11 @@ fn spawn_enclave_start(args: &DevRequest, config: &Config) -> Result<(), Error> let config_cpy = config.clone(); tokio::spawn(async move { - let res = enclave_start.handle(config_cpy).await?; + if let Err(e) = enclave_start.handle(config_cpy).await { + eprintln!("Error running enclave start.\n {}", e); + } - Ok::(res) + Ok::<(), Error>(()) }); Ok(()) diff --git a/crates/cli/src/handler/enclave_start.rs b/crates/cli/src/handler/enclave_start.rs index 3a1e365..053eff2 100644 --- a/crates/cli/src/handler/enclave_start.rs +++ b/crates/cli/src/handler/enclave_start.rs @@ -76,6 +76,12 @@ impl Handler for EnclaveStartRequest { )); }; + if let Err(_) = std::env::var("ADMIN_SK") { + return Err(Error::GenericErr( + "ADMIN_SK environment variable is not set".to_string(), + )); + }; + let enclave_dir = fs::canonicalize(config.app_dir.join("enclave"))?; // gramine private key @@ -92,7 +98,6 @@ impl Handler for EnclaveStartRequest { &config.chain_id, quartz_dir_canon, &enclave_dir, - &self.sk_file, fmspc, tcbinfo_contract, dcap_verifier_contract, @@ -194,7 +199,6 @@ async fn gramine_manifest( chain_id: &Id, quartz_dir: &Path, enclave_dir: &Path, - sk_file: &Path, fmspc: Fmspc, tcbinfo_contract: AccountId, dcap_verifier_contract: AccountId, @@ -225,7 +229,6 @@ async fn gramine_manifest( .arg(format!("-Dquartz_dir={}", quartz_dir.display())) .arg(format!("-Dtrusted_height={}", trusted_height)) .arg(format!("-Dtrusted_hash={}", trusted_hash)) - .arg(format!("-Dsk_file={}", sk_file.display())) .arg(format!("-Dfmspc={}", hex::encode(fmspc))) .arg(format!("-Dnode_url={}", node_url)) .arg(format!("-Dws_url={}", ws_url)) diff --git a/crates/cli/src/request.rs b/crates/cli/src/request.rs index 5f0f987..60ad6c1 100644 --- a/crates/cli/src/request.rs +++ b/crates/cli/src/request.rs @@ -48,7 +48,6 @@ impl TryFrom for Request { label: args.contract_deploy.label, contract_manifest: args.contract_deploy.contract_manifest, release: args.enclave_build.release, - sk_file: args.sk_file, fmspc: args.fmspc, tcbinfo_contract: args.tcbinfo_contract, dcap_verifier_contract: args.dcap_verifier_contract, @@ -102,7 +101,6 @@ impl TryFrom for Request { EnclaveCommand::Build(_) => Ok(EnclaveBuildRequest {}.into()), EnclaveCommand::Start(args) => Ok(EnclaveStartRequest { unsafe_trust_latest: args.unsafe_trust_latest, - sk_file: args.sk_file, fmspc: args.fmspc, tcbinfo_contract: args.tcbinfo_contract, dcap_verifier_contract: args.dcap_verifier_contract, diff --git a/crates/cli/src/request/dev.rs b/crates/cli/src/request/dev.rs index 8ea1bbe..c4f493a 100644 --- a/crates/cli/src/request/dev.rs +++ b/crates/cli/src/request/dev.rs @@ -13,7 +13,6 @@ pub struct DevRequest { pub label: String, pub contract_manifest: PathBuf, pub release: bool, - pub sk_file: PathBuf, pub fmspc: Option, pub tcbinfo_contract: Option, pub dcap_verifier_contract: Option, diff --git a/crates/cli/src/request/enclave_start.rs b/crates/cli/src/request/enclave_start.rs index 9b1fba5..2946b8a 100644 --- a/crates/cli/src/request/enclave_start.rs +++ b/crates/cli/src/request/enclave_start.rs @@ -1,5 +1,3 @@ -use std::path::PathBuf; - use cosmrs::AccountId; use quartz_common::enclave::types::Fmspc; use tendermint::{block::Height, Hash}; @@ -13,7 +11,6 @@ use crate::{ #[derive(Clone, Debug)] pub struct EnclaveStartRequest { pub unsafe_trust_latest: bool, - pub sk_file: PathBuf, pub fmspc: Option, pub tcbinfo_contract: Option, pub dcap_verifier_contract: Option, diff --git a/crates/enclave/core/src/server.rs b/crates/enclave/core/src/server.rs index 1bab59e..f21d1ab 100644 --- a/crates/enclave/core/src/server.rs +++ b/crates/enclave/core/src/server.rs @@ -1,7 +1,6 @@ use std::{ convert::Infallible, net::SocketAddr, - path::PathBuf, sync::{Arc, Mutex}, time::Duration, }; @@ -87,7 +86,7 @@ pub struct WsListenerConfig { pub tx_sender: String, pub trusted_hash: Hash, pub trusted_height: Height, - pub sk_file: PathBuf, + pub admin_sk: String, } /// A trait for wrapping a tonic service with the gRPC server handler diff --git a/crates/utils/cw-client/data/admin.sk b/crates/utils/cw-client/data/admin.sk deleted file mode 100644 index e5b16d5..0000000 --- a/crates/utils/cw-client/data/admin.sk +++ /dev/null @@ -1 +0,0 @@ -ffc4d3c9119e9e8263de08c0f6e2368ac5c2dacecfeb393f6813da7d178873d2 \ No newline at end of file diff --git a/crates/utils/cw-client/src/grpc.rs b/crates/utils/cw-client/src/grpc.rs index be93ede..00eb4c2 100644 --- a/crates/utils/cw-client/src/grpc.rs +++ b/crates/utils/cw-client/src/grpc.rs @@ -1,4 +1,4 @@ -use std::{error::Error, fs::File, io::Read, path::PathBuf}; +use std::error::Error; use anyhow::anyhow; use cosmos_sdk_proto::{ @@ -31,15 +31,14 @@ use serde::de::DeserializeOwned; use crate::CwClient; -#[derive(Clone, Debug)] pub struct GrpcClient { - sk_file: PathBuf, + sk: SigningKey, url: Url, } impl GrpcClient { - pub fn new(sk_file: PathBuf, url: Url) -> Self { - Self { sk_file, url } + pub fn new(sk: SigningKey, url: Url) -> Self { + Self { sk, url } } } @@ -91,16 +90,7 @@ impl CwClient for GrpcClient { msg: M, _fees: &str, ) -> Result { - let secret = { - let mut secret_hex = String::new(); - let mut sk_file = File::open(self.sk_file.clone())?; - sk_file.read_to_string(&mut secret_hex)?; - let secret = hex::decode(secret_hex)?; - SigningKey::from_slice(&secret) - .map_err(|e| anyhow!("failed to read secret key: {}", e))? - }; - - let tm_pubkey = secret.public_key(); + let tm_pubkey = self.sk.public_key(); let sender = tm_pubkey .account_id("neutron") .map_err(|e| anyhow!("failed to create AccountId from pubkey: {}", e))?; @@ -122,7 +112,7 @@ impl CwClient for GrpcClient { denom: "untrn".parse().expect("hardcoded denom"), }; let tx_bytes = tx_bytes( - &secret, + &self.sk, amount, gas, tm_pubkey, @@ -221,18 +211,22 @@ mod tests { use serde_json::json; use transfers_contract::msg::{execute::Request, QueryMsg::GetRequests}; - use crate::{CwClient, GrpcClient}; + use crate::{grpc::GrpcClient, CwClient}; #[tokio::test] #[ignore] async fn test_query() -> Result<(), Box> { - let sk_file = "../data/admin.sk".parse().unwrap(); + let sk = hex::decode("ffc4d3c9119e9e8263de08c0f6e2368ac5c2dacecfeb393f6813da7d178873d2") + .unwrap() + .as_slice() + .try_into() + .unwrap(); let url = "https://grpc-falcron.pion-1.ntrn.tech:80".parse().unwrap(); let contract = "neutron15ruzx9wvrupt9cffzsp6868uad2svhfym2nsgxm2skpeqr3qrd4q4uwk83" .parse() .unwrap(); - let cw_client = GrpcClient::new(sk_file, url); + let cw_client = GrpcClient::new(sk, url); let resp: Vec = cw_client .query_smart(&contract, json!(GetRequests {})) .await?; @@ -244,14 +238,18 @@ mod tests { #[tokio::test] #[ignore] async fn test_execute() -> Result<(), Box> { - let sk_file = "data/admin.sk".parse().unwrap(); + let sk = hex::decode("ffc4d3c9119e9e8263de08c0f6e2368ac5c2dacecfeb393f6813da7d178873d2") + .unwrap() + .as_slice() + .try_into() + .unwrap(); let url = "https://grpc-falcron.pion-1.ntrn.tech:80".parse().unwrap(); let contract = "neutron15ruzx9wvrupt9cffzsp6868uad2svhfym2nsgxm2skpeqr3qrd4q4uwk83" .parse() .unwrap(); let chain_id = "pion-1".parse().unwrap(); - let cw_client = GrpcClient::new(sk_file, url); + let cw_client = GrpcClient::new(sk, url); let tx_hash = cw_client .tx_execute( &contract, diff --git a/examples/transfers/enclave/quartz.manifest.template b/examples/transfers/enclave/quartz.manifest.template index 1648be7..dbb0d30 100644 --- a/examples/transfers/enclave/quartz.manifest.template +++ b/examples/transfers/enclave/quartz.manifest.template @@ -20,6 +20,7 @@ loader.env.RA_TLS_EPID_API_KEY = { passthrough = true } loader.env.MYAPP_DATA = { passthrough = true } loader.env.QUARTZ_PORT = { passthrough = true } loader.env.SSL_CERT_FILE = { passthrough = true } +loader.env.ADMIN_SK = { passthrough = true } loader.insecure__use_host_env = true loader.argv = ["quartz-app-transfers-enclave", @@ -39,7 +40,6 @@ fs.mounts = [ { uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" }, { uri = "file:/usr/{{ arch_libdir }}", path = "/usr{{ arch_libdir }}" }, { uri = "file:{{ quartz_dir }}", path = "{{ quartz_dir }}" }, - { uri = "file:{{ quartz_dir }}/../../crates/utils/cw-client/data/admin.sk", path = "/admin.sk" }, { uri = "file:/etc/ssl/certs/ca-certificates.crt", path = "/etc/ssl/certs/ca-certificates.crt" }, { uri = "file:/usr/lib/ssl/cert.pem", path = "/usr/lib/ssl/cert.pem" }, ] @@ -60,11 +60,9 @@ sgx.trusted_files = [ "file:{{ arch_libdir }}/", "file:/usr/{{ arch_libdir }}/", "file:/etc/ssl/certs/ca-certificates.crt", - "file:{{ quartz_dir }}/../../crates/utils/cw-client/data/admin.sk", ] sgx.allowed_files = [ - "file:admin.sk", "file:/etc/nsswitch.conf", "file:/etc/host.conf", "file:/etc/ethers", diff --git a/examples/transfers/enclave/src/cli.rs b/examples/transfers/enclave/src/cli.rs index dce99ab..81738a8 100644 --- a/examples/transfers/enclave/src/cli.rs +++ b/examples/transfers/enclave/src/cli.rs @@ -1,4 +1,4 @@ -use std::{env, net::SocketAddr, path::PathBuf}; +use std::{env, net::SocketAddr}; use clap::Parser; use color_eyre::eyre::{eyre, Result}; @@ -76,9 +76,6 @@ pub struct Cli { #[clap(long, default_value = "admin")] pub tx_sender: String, - - #[clap(long, default_value = "admin.sk")] - pub sk_file: PathBuf, } fn default_rpc_addr() -> SocketAddr { diff --git a/examples/transfers/enclave/src/main.rs b/examples/transfers/enclave/src/main.rs index da4b5ed..20892f0 100644 --- a/examples/transfers/enclave/src/main.rs +++ b/examples/transfers/enclave/src/main.rs @@ -41,6 +41,8 @@ use crate::wslistener::WsListener; async fn main() -> Result<(), Box> { let args = Cli::parse(); + let admin_sk = std::env::var("ADMIN_SK")?; + let light_client_opts = LightClientOpts::new( args.chain_id.clone(), args.trusted_height.into(), @@ -80,7 +82,7 @@ async fn main() -> Result<(), Box> { trusted_hash: args.trusted_hash, trusted_height: args.trusted_height, chain_id: args.chain_id, - sk_file: args.sk_file, + admin_sk, }; let sk = Arc::new(Mutex::new(None)); diff --git a/examples/transfers/enclave/src/wslistener.rs b/examples/transfers/enclave/src/wslistener.rs index 78d097e..7c7e253 100644 --- a/examples/transfers/enclave/src/wslistener.rs +++ b/examples/transfers/enclave/src/wslistener.rs @@ -169,8 +169,11 @@ where A: Attestor, A::RawAttestation: for<'de> Deserialize<'de>, { - let chain_id = &ChainId::from_str(&ws_config.chain_id)?; - let cw_client = GrpcClient::new(ws_config.sk_file.clone(), ws_config.grpc_url.clone()); + let sk = hex::decode(ws_config.admin_sk.clone())? + .as_slice() + .try_into() + .map_err(|e| anyhow!("failed to read/parse sk: {}", e))?; + let cw_client = GrpcClient::new(sk, ws_config.grpc_url.clone()); // Query contract state let requests: Vec = cw_client @@ -243,6 +246,7 @@ where }); // Post response to chain + let chain_id = &ChainId::from_str(&ws_config.chain_id)?; let output = cw_client .tx_execute( contract, @@ -269,8 +273,11 @@ where A: Attestor, A::RawAttestation: for<'de> Deserialize<'de>, { - let chain_id = &ChainId::from_str(&ws_config.chain_id)?; - let cw_client = GrpcClient::new(ws_config.sk_file.clone(), ws_config.grpc_url.clone()); + let sk = hex::decode(ws_config.admin_sk.clone())? + .as_slice() + .try_into() + .map_err(|e| anyhow!("failed to read/parse sk: {}", e))?; + let cw_client = GrpcClient::new(sk, ws_config.grpc_url.clone()); // Query contract state let state: HexBinary = cw_client @@ -309,6 +316,7 @@ where }); // Post response to chain + let chain_id = &ChainId::from_str(&ws_config.chain_id)?; let output = cw_client .tx_execute( contract,