From 3585c185e9c2fe5829f2d8ce9fa5acd50b09e26f Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Tue, 8 Oct 2024 18:50:08 +0200 Subject: [PATCH 01/13] Add gen-quote bin crate --- crates/utils/gen-quote/Cargo.toml | 12 ++++++ .../gen-quote/gen-quote.manifest.template | 42 +++++++++++++++++++ crates/utils/gen-quote/src/main.rs | 15 +++++++ 3 files changed, 69 insertions(+) create mode 100644 crates/utils/gen-quote/Cargo.toml create mode 100644 crates/utils/gen-quote/gen-quote.manifest.template create mode 100644 crates/utils/gen-quote/src/main.rs diff --git a/crates/utils/gen-quote/Cargo.toml b/crates/utils/gen-quote/Cargo.toml new file mode 100644 index 00000000..f4f8953d --- /dev/null +++ b/crates/utils/gen-quote/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "quartz-gen-quote" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +readme.workspace = true +repository.workspace = true +authors.workspace = true + +[dependencies] +hex = "0.4.3" diff --git a/crates/utils/gen-quote/gen-quote.manifest.template b/crates/utils/gen-quote/gen-quote.manifest.template new file mode 100644 index 00000000..9a9b3341 --- /dev/null +++ b/crates/utils/gen-quote/gen-quote.manifest.template @@ -0,0 +1,42 @@ +# Manifest file for creating dummy quotes + +libos.entrypoint = "{{ quartz_dir }}/target/release/gen-quote + +loader.log_level = "{{ log_level }}" +loader.entrypoint = "file:{{ gramine.libos }}" +loader.env.LD_LIBRARY_PATH = "/lib:/usr/local/lib:{{ arch_libdir }}:/usr{{ arch_libdir }}" +loader.env.HOME = "{{ home }}" +loader.env.INSIDE_SGX = "1" +loader.env.TLS = { passthrough = true } +loader.env.RA_TYPE = { passthrough = true } +loader.env.RA_TLS_ALLOW_DEBUG_ENCLAVE_INSECURE = { passthrough = true } +loader.env.RA_TLS_ALLOW_OUTDATED_TCB_INSECURE = { passthrough = true } +loader.env.RA_TLS_MRENCLAVE = { passthrough = true } +loader.env.RA_TLS_MRSIGNER = { passthrough = true } +loader.env.RA_TLS_ISV_SVN = { passthrough = true } +loader.env.RA_TLS_ISV_PROD_ID = { passthrough = true } +loader.env.MYAPP_DATA = { passthrough = true } + +fs.mounts = [ + { uri = "file:{{ gramine.runtimedir() }}", path = "/lib" }, + { uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" }, + { uri = "file:/usr/{{ arch_libdir }}", path = "/usr{{ arch_libdir }}" }, + { uri = "file:{{ quartz_dir }}", path = "{{ quartz_dir }}" }, +] + +sgx.enclave_size = "512M" +sgx.max_threads = 1 +sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} + +sgx.remote_attestation = "{{ ra_type }}" +sgx.ra_client_linkable = {{ 'true' if ra_client_linkable == '1' else 'false' }} + +sgx.trusted_files = [ + "file:{{ gramine.libos }}", + "file:{{ quartz_dir }}/target/release/", + "file:{{ gramine.runtimedir() }}/", + "file:{{ arch_libdir }}/", + "file:/usr/{{ arch_libdir }}/", +] + +sys.enable_sigterm_injection = true diff --git a/crates/utils/gen-quote/src/main.rs b/crates/utils/gen-quote/src/main.rs new file mode 100644 index 00000000..384cb97a --- /dev/null +++ b/crates/utils/gen-quote/src/main.rs @@ -0,0 +1,15 @@ +use std::{ + fs::File, + io::{self, Read}, +}; + +fn main() -> io::Result<()> { + let mut file = File::open("/dev/attestation")?; + let mut buffer = Vec::new(); + file.read_to_end(&mut buffer)?; + + let quote_hex = hex::encode(&buffer); + println!("{}", quote_hex); + + Ok(()) +} From 66cf353a50b94f8257e088d71787ca63457340ba Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Tue, 8 Oct 2024 19:20:11 +0200 Subject: [PATCH 02/13] Write user-data before reading quote --- crates/utils/gen-quote/src/main.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/utils/gen-quote/src/main.rs b/crates/utils/gen-quote/src/main.rs index 384cb97a..9bf087ae 100644 --- a/crates/utils/gen-quote/src/main.rs +++ b/crates/utils/gen-quote/src/main.rs @@ -1,10 +1,15 @@ use std::{ fs::File, - io::{self, Read}, + io::{self, Read, Write}, }; fn main() -> io::Result<()> { - let mut file = File::open("/dev/attestation")?; + let user_data = [0u8; 64]; + let mut user_report_data = File::create("/dev/attestation/user_report_data")?; + user_report_data.write_all(user_data.as_slice())?; + user_report_data.flush()?; + + let mut file = File::open("/dev/attestation/quote")?; let mut buffer = Vec::new(); file.read_to_end(&mut buffer)?; From 9f3b9adff6839165836bad1b5b502469f5306437 Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Tue, 8 Oct 2024 19:20:26 +0200 Subject: [PATCH 03/13] Fix manifest template --- crates/utils/gen-quote/gen-quote.manifest.template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/utils/gen-quote/gen-quote.manifest.template b/crates/utils/gen-quote/gen-quote.manifest.template index 9a9b3341..89639dbe 100644 --- a/crates/utils/gen-quote/gen-quote.manifest.template +++ b/crates/utils/gen-quote/gen-quote.manifest.template @@ -1,6 +1,6 @@ # Manifest file for creating dummy quotes -libos.entrypoint = "{{ quartz_dir }}/target/release/gen-quote +libos.entrypoint = "{{ quartz_dir }}/target/release/quartz-gen-quote" loader.log_level = "{{ log_level }}" loader.entrypoint = "file:{{ gramine.libos }}" @@ -25,7 +25,7 @@ fs.mounts = [ ] sgx.enclave_size = "512M" -sgx.max_threads = 1 +sgx.max_threads = 2 sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} sgx.remote_attestation = "{{ ra_type }}" From 5a62fa7aa3fc747028406608f6a4585bc8f03688 Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Tue, 8 Oct 2024 20:17:22 +0200 Subject: [PATCH 04/13] Boilerplate for `quartz print-fmspc` --- Cargo.lock | 7 +++++++ crates/cli/src/cli.rs | 4 ++++ crates/cli/src/handler.rs | 2 ++ crates/cli/src/handler/print_fmspc.rs | 29 ++++++++++++++++++++++++++ crates/cli/src/request.rs | 6 +++++- crates/cli/src/request/print_fmspc.rs | 10 +++++++++ crates/cli/src/response.rs | 5 ++++- crates/cli/src/response/print_fmspc.rs | 12 +++++++++++ 8 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 crates/cli/src/handler/print_fmspc.rs create mode 100644 crates/cli/src/request/print_fmspc.rs create mode 100644 crates/cli/src/response/print_fmspc.rs diff --git a/Cargo.lock b/Cargo.lock index 1696e807..33aed5bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4319,6 +4319,13 @@ dependencies = [ "urlencoding", ] +[[package]] +name = "quartz-gen-quote" +version = "0.1.0" +dependencies = [ + "hex", +] + [[package]] name = "quartz-print-fmspc" version = "0.1.0" diff --git a/crates/cli/src/cli.rs b/crates/cli/src/cli.rs index fabac748..940010ad 100644 --- a/crates/cli/src/cli.rs +++ b/crates/cli/src/cli.rs @@ -79,6 +79,9 @@ pub enum Command { /// Build, deploy, perform handshake, and run quartz app while listening for changes Dev(DevArgs), + + /// Print the FMSPC of the current platform (SGX only) + PrintFmspc, } #[allow(clippy::large_enum_variant)] @@ -296,6 +299,7 @@ impl ToFigment for Command { Command::Dev(args) => Figment::from(Serialized::defaults(args)) .merge(Serialized::defaults(&args.contract_deploy)) .merge(Serialized::defaults(&args.enclave_build)), + Command::PrintFmspc => Figment::default(), } } } diff --git a/crates/cli/src/handler.rs b/crates/cli/src/handler.rs index be800c96..1f6ced96 100644 --- a/crates/cli/src/handler.rs +++ b/crates/cli/src/handler.rs @@ -12,6 +12,7 @@ pub mod enclave_build; pub mod enclave_start; pub mod handshake; pub mod init; +pub mod print_fmspc; #[async_trait] pub trait Handler { @@ -33,6 +34,7 @@ impl Handler for Request { Request::EnclaveBuild(request) => request.handle(config).await, Request::EnclaveStart(request) => request.handle(config).await, Request::Dev(request) => request.handle(config).await, + Request::PrintFmspc(request) => request.handle(config).await, } .map(Into::into) } diff --git a/crates/cli/src/handler/print_fmspc.rs b/crates/cli/src/handler/print_fmspc.rs new file mode 100644 index 00000000..52864883 --- /dev/null +++ b/crates/cli/src/handler/print_fmspc.rs @@ -0,0 +1,29 @@ +use async_trait::async_trait; +use color_eyre::{eyre::eyre, owo_colors::OwoColorize, Report, Result}; +use tracing::info; + +use crate::{ + config::Config, + handler::Handler, + request::print_fmspc::PrintFmspcRequest, + response::{print_fmspc::PrintFmspcResponse, Response}, +}; + +#[async_trait] +impl Handler for PrintFmspcRequest { + type Response = Response; + + async fn handle + Send>(self, config: C) -> Result { + let config = config.as_ref().clone(); + + if config.mock_sgx { + return Err(eyre!( + "MOCK_SGX is enabled! print-fmpsc is only available if SGX is enabled" + )); + } + + info!("{}", "\nGenerating dummy quote".blue().bold()); + + Ok(PrintFmspcResponse.into()) + } +} diff --git a/crates/cli/src/request.rs b/crates/cli/src/request.rs index 17c98209..367698d0 100644 --- a/crates/cli/src/request.rs +++ b/crates/cli/src/request.rs @@ -5,7 +5,7 @@ use crate::{ request::{ contract_build::ContractBuildRequest, contract_deploy::ContractDeployRequest, dev::DevRequest, enclave_build::EnclaveBuildRequest, enclave_start::EnclaveStartRequest, - handshake::HandshakeRequest, init::InitRequest, + handshake::HandshakeRequest, init::InitRequest, print_fmspc::PrintFmspcRequest, }, }; @@ -17,6 +17,8 @@ pub mod enclave_start; pub mod handshake; pub mod init; +pub mod print_fmspc; + #[derive(Clone, Debug)] pub enum Request { Init(InitRequest), @@ -26,6 +28,7 @@ pub enum Request { EnclaveBuild(EnclaveBuildRequest), EnclaveStart(EnclaveStartRequest), Dev(DevRequest), + PrintFmspc(PrintFmspcRequest), } impl TryFrom for Request { @@ -62,6 +65,7 @@ impl TryFrom for Request { } .into()) } + Command::PrintFmspc => Ok(Request::PrintFmspc(PrintFmspcRequest)), } } } diff --git a/crates/cli/src/request/print_fmspc.rs b/crates/cli/src/request/print_fmspc.rs new file mode 100644 index 00000000..8dbbd4b4 --- /dev/null +++ b/crates/cli/src/request/print_fmspc.rs @@ -0,0 +1,10 @@ +use crate::request::Request; + +#[derive(Clone, Debug)] +pub struct PrintFmspcRequest; + +impl From for Request { + fn from(request: PrintFmspcRequest) -> Self { + Self::PrintFmspc(request) + } +} diff --git a/crates/cli/src/response.rs b/crates/cli/src/response.rs index 2839c172..c5a21cd7 100644 --- a/crates/cli/src/response.rs +++ b/crates/cli/src/response.rs @@ -3,7 +3,7 @@ use serde::Serialize; use crate::response::{ contract_build::ContractBuildResponse, contract_deploy::ContractDeployResponse, dev::DevResponse, enclave_build::EnclaveBuildResponse, enclave_start::EnclaveStartResponse, - handshake::HandshakeResponse, init::InitResponse, + handshake::HandshakeResponse, init::InitResponse, print_fmspc::PrintFmspcResponse, }; pub mod contract_build; @@ -14,6 +14,8 @@ pub mod enclave_start; pub mod handshake; pub mod init; +pub mod print_fmspc; + #[derive(Clone, Debug, Serialize)] pub enum Response { Init(InitResponse), @@ -23,4 +25,5 @@ pub enum Response { EnclaveBuild(EnclaveBuildResponse), EnclaveStart(EnclaveStartResponse), Dev(DevResponse), + PrintFmspc(PrintFmspcResponse), } diff --git a/crates/cli/src/response/print_fmspc.rs b/crates/cli/src/response/print_fmspc.rs new file mode 100644 index 00000000..d446ab42 --- /dev/null +++ b/crates/cli/src/response/print_fmspc.rs @@ -0,0 +1,12 @@ +use serde::Serialize; + +use crate::response::Response; + +#[derive(Clone, Debug, Serialize)] +pub struct PrintFmspcResponse; + +impl From for Response { + fn from(response: PrintFmspcResponse) -> Self { + Self::PrintFmspc(response) + } +} From 031c1ea62385c84240196b8136fda3bda216e687 Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Tue, 8 Oct 2024 21:04:11 +0200 Subject: [PATCH 05/13] Move gen-quote into CLI --- crates/cli/Cargo.toml | 4 ++++ .../src/bin}/gen-quote.manifest.template | 2 +- .../src/main.rs => cli/src/bin/gen-quote.rs} | 0 crates/utils/gen-quote/Cargo.toml | 12 ------------ 4 files changed, 5 insertions(+), 13 deletions(-) rename crates/{utils/gen-quote => cli/src/bin}/gen-quote.manifest.template (95%) rename crates/{utils/gen-quote/src/main.rs => cli/src/bin/gen-quote.rs} (100%) delete mode 100644 crates/utils/gen-quote/Cargo.toml diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index a85b1d63..e1c305f9 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -13,6 +13,10 @@ readme = "README.md" name = "quartz" path = "src/main.rs" +[[bin]] +name = "gen-quote" +path = "src/bin/gen-quote.rs" + [dependencies] async-trait.workspace = true cargo-generate.workspace = true diff --git a/crates/utils/gen-quote/gen-quote.manifest.template b/crates/cli/src/bin/gen-quote.manifest.template similarity index 95% rename from crates/utils/gen-quote/gen-quote.manifest.template rename to crates/cli/src/bin/gen-quote.manifest.template index 89639dbe..a4e37be6 100644 --- a/crates/utils/gen-quote/gen-quote.manifest.template +++ b/crates/cli/src/bin/gen-quote.manifest.template @@ -1,6 +1,6 @@ # Manifest file for creating dummy quotes -libos.entrypoint = "{{ quartz_dir }}/target/release/quartz-gen-quote" +libos.entrypoint = "{{ gen_quote_bin_path }}" loader.log_level = "{{ log_level }}" loader.entrypoint = "file:{{ gramine.libos }}" diff --git a/crates/utils/gen-quote/src/main.rs b/crates/cli/src/bin/gen-quote.rs similarity index 100% rename from crates/utils/gen-quote/src/main.rs rename to crates/cli/src/bin/gen-quote.rs diff --git a/crates/utils/gen-quote/Cargo.toml b/crates/utils/gen-quote/Cargo.toml deleted file mode 100644 index f4f8953d..00000000 --- a/crates/utils/gen-quote/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "quartz-gen-quote" -version.workspace = true -edition.workspace = true -rust-version.workspace = true -license.workspace = true -readme.workspace = true -repository.workspace = true -authors.workspace = true - -[dependencies] -hex = "0.4.3" From c29ed0f514d3a1e0bb7c1ac9632c89a49871f707 Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Tue, 8 Oct 2024 21:05:30 +0200 Subject: [PATCH 06/13] Impl handler for print-fmspc --- crates/cli/src/handler/print_fmspc.rs | 93 ++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/crates/cli/src/handler/print_fmspc.rs b/crates/cli/src/handler/print_fmspc.rs index 52864883..ffb74078 100644 --- a/crates/cli/src/handler/print_fmspc.rs +++ b/crates/cli/src/handler/print_fmspc.rs @@ -1,6 +1,13 @@ +use std::{env, path::PathBuf}; + use async_trait::async_trait; -use color_eyre::{eyre::eyre, owo_colors::OwoColorize, Report, Result}; -use tracing::info; +use color_eyre::{ + eyre::{eyre, Context}, + owo_colors::OwoColorize, + Report, Result, +}; +use tokio::process::Command; +use tracing::{debug, info}; use crate::{ config::Config, @@ -22,8 +29,90 @@ impl Handler for PrintFmspcRequest { )); } + debug!("{}", "\nGenerating SGX private key".blue().bold()); + + let _ = Command::new("gramine-sgx-gen-private-key") + .output() + .await + .map_err(|e| eyre!("Failed to execute gramine-sgx-gen-private-key: {}", e))?; + + let host = target_lexicon::HOST; + let arch_libdir = format!( + "/lib/{}-{}-{}", + host.architecture, host.operating_system, host.environment + ); + + let home_dir = dirs::home_dir() + .ok_or_else(|| eyre!("Home directory not set"))? + .display() + .to_string(); + + let current_exe_path = + env::current_exe().context("Failed to get current executable path")?; + let gen_quote_bin_path = file_path(current_exe_path.clone(), "gen-quote"); + let gen_quote_manifest_path = file_path(current_exe_path, "gen-quote.manifest.template"); + + let status = Command::new("gramine-manifest") + .arg("-Dlog_level=error") + .arg(format!("-Dhome={}", home_dir)) + .arg(format!("-Darch_libdir={}", arch_libdir)) + .arg("-Dra_type=dcap") + .arg("-Dra_client_linkable=1") + .arg(format!( + "-Dgen_quote_bin_path={}", + gen_quote_bin_path.display() + )) + .arg(gen_quote_manifest_path) + .arg("gen-quote.manifest") + .current_dir("/tmp/") + .status() + .await + .map_err(|e| eyre!("Failed to execute gramine-manifest: {}", e))?; + + if !status.success() { + return Err(eyre!( + "gramine-manifest command failed with status: {:?}", + status + )); + } + + let status = Command::new("gramine-sgx-sign") + .arg("--manifest") + .arg("gen-quote.manifest") + .arg("--output") + .arg("gen-quote.manifest.sgx") + .current_dir("/tmp/") + .status() + .await + .map_err(|e| eyre!("Failed to execute gramine-sgx-sign: {}", e))?; + + if !status.success() { + return Err(eyre!( + "gramine-sgx-sign command failed with status: {:?}", + status + )); + } + info!("{}", "\nGenerating dummy quote".blue().bold()); + let mut child = Command::new("gramine-sgx") + .arg("./gen-quote") + .kill_on_drop(true) + .current_dir("/tmp/") + .spawn() + .map_err(|e| eyre!("Failed to spawn gramine-sgx child process: {}", e))?; + + let status = child.wait().await?; + if !status.success() { + return Err(eyre!("Couldn't build enclave. {:?}", status)); + } + Ok(PrintFmspcResponse.into()) } } + +fn file_path(mut current_exe_path: PathBuf, file_name: &str) -> PathBuf { + current_exe_path.pop(); + current_exe_path.push(file_name); + current_exe_path +} From 43c58b21fb79e4c97107be842a3821d995ee20c4 Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Tue, 8 Oct 2024 21:06:49 +0200 Subject: [PATCH 07/13] Update Cargo.lock --- Cargo.lock | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33aed5bb..1696e807 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4319,13 +4319,6 @@ dependencies = [ "urlencoding", ] -[[package]] -name = "quartz-gen-quote" -version = "0.1.0" -dependencies = [ - "hex", -] - [[package]] name = "quartz-print-fmspc" version = "0.1.0" From 01e0488266c247cca36daa2ee7a2ad53790d860e Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Tue, 8 Oct 2024 21:27:40 +0200 Subject: [PATCH 08/13] Build dummy enclave if required --- crates/cli/Cargo.toml | 1 + crates/cli/src/handler/print_fmspc.rs | 26 ++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index e1c305f9..fb0484a4 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -8,6 +8,7 @@ license.workspace = true repository.workspace = true keywords = ["blockchain", "cosmos", "tendermint", "cycles", "quartz"] readme = "README.md" +default-run = "quartz" [[bin]] name = "quartz" diff --git a/crates/cli/src/handler/print_fmspc.rs b/crates/cli/src/handler/print_fmspc.rs index ffb74078..552d42ba 100644 --- a/crates/cli/src/handler/print_fmspc.rs +++ b/crates/cli/src/handler/print_fmspc.rs @@ -29,6 +29,30 @@ impl Handler for PrintFmspcRequest { )); } + let current_exe_path = + env::current_exe().context("Failed to get current executable path")?; + let exe_path_str = current_exe_path.to_string_lossy(); + + if exe_path_str.contains("target") { + // i.e. this isn't a `cargo install` based installation + + info!("{}", "\nBuilding dummy enclave".blue().bold()); + + let mut cargo = Command::new("cargo"); + let command = cargo.arg("build"); + + if exe_path_str.contains("release") { + // add the release flag to make sure it's built in the right place + command.arg("--release"); + } + + let status = command.status().await?; + + if !status.success() { + return Err(eyre!("Couldn't build enclave. {:?}", status)); + } + } + debug!("{}", "\nGenerating SGX private key".blue().bold()); let _ = Command::new("gramine-sgx-gen-private-key") @@ -47,8 +71,6 @@ impl Handler for PrintFmspcRequest { .display() .to_string(); - let current_exe_path = - env::current_exe().context("Failed to get current executable path")?; let gen_quote_bin_path = file_path(current_exe_path.clone(), "gen-quote"); let gen_quote_manifest_path = file_path(current_exe_path, "gen-quote.manifest.template"); From ffef3ea73f85f19af84e040f120e415d3d299384 Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Tue, 8 Oct 2024 21:52:12 +0200 Subject: [PATCH 09/13] use tempfile/dir and fix manifest template handling --- crates/cli/src/handler/print_fmspc.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/crates/cli/src/handler/print_fmspc.rs b/crates/cli/src/handler/print_fmspc.rs index 552d42ba..3fbcc735 100644 --- a/crates/cli/src/handler/print_fmspc.rs +++ b/crates/cli/src/handler/print_fmspc.rs @@ -6,7 +6,8 @@ use color_eyre::{ owo_colors::OwoColorize, Report, Result, }; -use tokio::process::Command; +use tempfile::tempdir; +use tokio::{fs::File, io::AsyncWriteExt, process::Command}; use tracing::{debug, info}; use crate::{ @@ -16,6 +17,8 @@ use crate::{ response::{print_fmspc::PrintFmspcResponse, Response}, }; +const GEN_QUOTE_MANIFEST_TEMPLATE: &str = include_str!("../bin/gen-quote.manifest.template"); + #[async_trait] impl Handler for PrintFmspcRequest { type Response = Response; @@ -72,7 +75,15 @@ impl Handler for PrintFmspcRequest { .to_string(); let gen_quote_bin_path = file_path(current_exe_path.clone(), "gen-quote"); - let gen_quote_manifest_path = file_path(current_exe_path, "gen-quote.manifest.template"); + + let temp_dir = tempdir()?; + let temp_dir_path = temp_dir.path(); + + let gen_quote_manifest_path = temp_dir_path.join("gen-quote.manifest.template"); + let mut gen_quote_manifest_file = File::create(&gen_quote_manifest_path).await?; + gen_quote_manifest_file + .write_all(GEN_QUOTE_MANIFEST_TEMPLATE.as_bytes()) + .await?; let status = Command::new("gramine-manifest") .arg("-Dlog_level=error") @@ -86,7 +97,7 @@ impl Handler for PrintFmspcRequest { )) .arg(gen_quote_manifest_path) .arg("gen-quote.manifest") - .current_dir("/tmp/") + .current_dir(temp_dir_path) .status() .await .map_err(|e| eyre!("Failed to execute gramine-manifest: {}", e))?; @@ -103,7 +114,7 @@ impl Handler for PrintFmspcRequest { .arg("gen-quote.manifest") .arg("--output") .arg("gen-quote.manifest.sgx") - .current_dir("/tmp/") + .current_dir(temp_dir_path) .status() .await .map_err(|e| eyre!("Failed to execute gramine-sgx-sign: {}", e))?; @@ -120,7 +131,7 @@ impl Handler for PrintFmspcRequest { let mut child = Command::new("gramine-sgx") .arg("./gen-quote") .kill_on_drop(true) - .current_dir("/tmp/") + .current_dir(temp_dir_path) .spawn() .map_err(|e| eyre!("Failed to spawn gramine-sgx child process: {}", e))?; From c9c7027febcd32fec8387f6f306e6eff010b651f Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Tue, 8 Oct 2024 22:00:02 +0200 Subject: [PATCH 10/13] Fix paths in manifest --- crates/cli/src/bin/gen-quote.manifest.template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/cli/src/bin/gen-quote.manifest.template b/crates/cli/src/bin/gen-quote.manifest.template index a4e37be6..4e52bf6c 100644 --- a/crates/cli/src/bin/gen-quote.manifest.template +++ b/crates/cli/src/bin/gen-quote.manifest.template @@ -21,7 +21,7 @@ fs.mounts = [ { uri = "file:{{ gramine.runtimedir() }}", path = "/lib" }, { 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:{{ gen_quote_bin_path }}", path = "{{ gen_quote_bin_path }}" }, ] sgx.enclave_size = "512M" @@ -33,7 +33,7 @@ sgx.ra_client_linkable = {{ 'true' if ra_client_linkable == '1' else 'false' }} sgx.trusted_files = [ "file:{{ gramine.libos }}", - "file:{{ quartz_dir }}/target/release/", + "file:{{ gen_quote_bin_path }}", "file:{{ gramine.runtimedir() }}/", "file:{{ arch_libdir }}/", "file:/usr/{{ arch_libdir }}/", From 72a84bcd889da1ab46ba78c75bc381a8b31f5fdd Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Tue, 8 Oct 2024 22:12:38 +0200 Subject: [PATCH 11/13] Print fmspc --- Cargo.lock | 1 + crates/cli/Cargo.toml | 1 + crates/cli/src/handler/print_fmspc.rs | 22 ++++++++++++++++++---- crates/cli/src/response/print_fmspc.rs | 5 ++++- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1696e807..2caea904 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4353,6 +4353,7 @@ dependencies = [ "cosmrs", "cosmwasm-std", "cw-client", + "dcap-qvl", "dirs 5.0.1", "displaydoc", "figment", diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index fb0484a4..1f26d491 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -53,6 +53,7 @@ figment = { version = "0.10.19", features = ["env", "toml"] } clearscreen = "3.0.0" cargo_metadata = "0.18.1" serde_with = "3.10.0" +dcap-qvl = "0.1.0" # cosmos cosmrs.workspace = true diff --git a/crates/cli/src/handler/print_fmspc.rs b/crates/cli/src/handler/print_fmspc.rs index 3fbcc735..381db56d 100644 --- a/crates/cli/src/handler/print_fmspc.rs +++ b/crates/cli/src/handler/print_fmspc.rs @@ -6,6 +6,7 @@ use color_eyre::{ owo_colors::OwoColorize, Report, Result, }; +use dcap_qvl::collateral::get_collateral; use tempfile::tempdir; use tokio::{fs::File, io::AsyncWriteExt, process::Command}; use tracing::{debug, info}; @@ -18,6 +19,7 @@ use crate::{ }; const GEN_QUOTE_MANIFEST_TEMPLATE: &str = include_str!("../bin/gen-quote.manifest.template"); +const DEFAULT_PCCS_URL: &str = "https://localhost:8081/sgx/certification/v4/"; #[async_trait] impl Handler for PrintFmspcRequest { @@ -128,19 +130,31 @@ impl Handler for PrintFmspcRequest { info!("{}", "\nGenerating dummy quote".blue().bold()); - let mut child = Command::new("gramine-sgx") + let child = Command::new("gramine-sgx") .arg("./gen-quote") .kill_on_drop(true) .current_dir(temp_dir_path) .spawn() .map_err(|e| eyre!("Failed to spawn gramine-sgx child process: {}", e))?; - let status = child.wait().await?; - if !status.success() { + let output = child.wait_with_output().await?; + if !output.status.success() { return Err(eyre!("Couldn't build enclave. {:?}", status)); } - Ok(PrintFmspcResponse.into()) + let quote = output.stdout; + + let collateral = + get_collateral(DEFAULT_PCCS_URL, "e, std::time::Duration::from_secs(10)) + .await + .expect("failed to get collateral"); + let tcb_info: serde_json::Value = serde_json::from_str(&collateral.tcb_info) + .expect("Retrieved Tcbinfo is not valid JSON"); + + Ok(PrintFmspcResponse { + fmspc: tcb_info["fmspc"].to_string().parse()?, + } + .into()) } } diff --git a/crates/cli/src/response/print_fmspc.rs b/crates/cli/src/response/print_fmspc.rs index d446ab42..b2877cae 100644 --- a/crates/cli/src/response/print_fmspc.rs +++ b/crates/cli/src/response/print_fmspc.rs @@ -1,9 +1,12 @@ +use quartz_common::enclave::types::Fmspc; use serde::Serialize; use crate::response::Response; #[derive(Clone, Debug, Serialize)] -pub struct PrintFmspcResponse; +pub struct PrintFmspcResponse { + pub fmspc: Fmspc, +} impl From for Response { fn from(response: PrintFmspcResponse) -> Self { From 0666f2f9a6c15c5f57545e9fe8f2ed6876b117cd Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Tue, 8 Oct 2024 22:39:23 +0200 Subject: [PATCH 12/13] Print quote without newline --- crates/cli/src/bin/gen-quote.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cli/src/bin/gen-quote.rs b/crates/cli/src/bin/gen-quote.rs index 9bf087ae..01ca3556 100644 --- a/crates/cli/src/bin/gen-quote.rs +++ b/crates/cli/src/bin/gen-quote.rs @@ -14,7 +14,7 @@ fn main() -> io::Result<()> { file.read_to_end(&mut buffer)?; let quote_hex = hex::encode(&buffer); - println!("{}", quote_hex); + print!("{}", quote_hex); Ok(()) } From 4d61a669cb41a492355cb698e980ef2e4190d576 Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Tue, 8 Oct 2024 22:40:26 +0200 Subject: [PATCH 13/13] Fix print-fmspc impl --- crates/cli/src/handler/print_fmspc.rs | 8 +++++--- crates/cli/src/response/print_fmspc.rs | 3 +-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/crates/cli/src/handler/print_fmspc.rs b/crates/cli/src/handler/print_fmspc.rs index 381db56d..dec34c48 100644 --- a/crates/cli/src/handler/print_fmspc.rs +++ b/crates/cli/src/handler/print_fmspc.rs @@ -1,4 +1,4 @@ -use std::{env, path::PathBuf}; +use std::{env, path::PathBuf, process::Stdio}; use async_trait::async_trait; use color_eyre::{ @@ -134,6 +134,8 @@ impl Handler for PrintFmspcRequest { .arg("./gen-quote") .kill_on_drop(true) .current_dir(temp_dir_path) + .stdout(Stdio::piped()) // Redirect stdout to a pipe + .stderr(Stdio::piped()) // Redirect stderr to a pipe .spawn() .map_err(|e| eyre!("Failed to spawn gramine-sgx child process: {}", e))?; @@ -142,7 +144,7 @@ impl Handler for PrintFmspcRequest { return Err(eyre!("Couldn't build enclave. {:?}", status)); } - let quote = output.stdout; + let quote = hex::decode(output.stdout)?; let collateral = get_collateral(DEFAULT_PCCS_URL, "e, std::time::Duration::from_secs(10)) @@ -152,7 +154,7 @@ impl Handler for PrintFmspcRequest { .expect("Retrieved Tcbinfo is not valid JSON"); Ok(PrintFmspcResponse { - fmspc: tcb_info["fmspc"].to_string().parse()?, + fmspc: tcb_info["fmspc"].to_string(), } .into()) } diff --git a/crates/cli/src/response/print_fmspc.rs b/crates/cli/src/response/print_fmspc.rs index b2877cae..112bb418 100644 --- a/crates/cli/src/response/print_fmspc.rs +++ b/crates/cli/src/response/print_fmspc.rs @@ -1,11 +1,10 @@ -use quartz_common::enclave::types::Fmspc; use serde::Serialize; use crate::response::Response; #[derive(Clone, Debug, Serialize)] pub struct PrintFmspcResponse { - pub fmspc: Fmspc, + pub fmspc: String, } impl From for Response {