From d13e0903dc589a670deadf2419e8b884d03d7754 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Mon, 15 Jan 2024 19:01:35 +0900 Subject: [PATCH 1/2] add `enclave_debug` flag to cli Signed-off-by: Jun Kimura --- app/src/commands/attestation.rs | 27 ++++++++++------- app/src/commands/elc.rs | 14 ++++----- app/src/commands/enclave.rs | 48 +++++++++++++++++------------- app/src/commands/service.rs | 12 ++++---- app/src/enclave.rs | 6 ++-- app/src/opts.rs | 11 ++++++- modules/enclave-api/src/enclave.rs | 3 +- modules/host/src/enclave.rs | 7 ++--- tests/integration/src/lib.rs | 2 +- 9 files changed, 74 insertions(+), 56 deletions(-) diff --git a/app/src/commands/attestation.rs b/app/src/commands/attestation.rs index c4c1fac0..0a9fb15c 100644 --- a/app/src/commands/attestation.rs +++ b/app/src/commands/attestation.rs @@ -1,4 +1,4 @@ -use crate::opts::Opts; +use crate::opts::{EnclaveOpts, Opts}; use anyhow::{bail, Result}; use clap::Parser; use crypto::Address; @@ -22,7 +22,7 @@ impl AttestationCmd { pub fn run( &self, opts: &Opts, - enclave_loader: impl FnOnce(&Opts, Option<&PathBuf>) -> Result>, + enclave_loader: impl FnOnce(&Opts, Option<&PathBuf>, bool) -> Result>, ) -> Result<()> where S: CommitStore, @@ -34,14 +34,20 @@ impl AttestationCmd { if !home.exists() { bail!("home directory doesn't exist at {:?}", home); } - run_ias_remote_attestation(enclave_loader(opts, cmd.enclave.as_ref())?, cmd) + run_ias_remote_attestation( + enclave_loader(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, + cmd, + ) } #[cfg(feature = "sgx-sw")] AttestationCmd::Simulate(cmd) => { if !home.exists() { bail!("home directory doesn't exist at {:?}", home); } - run_simulate_remote_attestation(enclave_loader(opts, cmd.enclave.as_ref())?, cmd) + run_simulate_remote_attestation( + enclave_loader(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, + cmd, + ) } } } @@ -49,10 +55,9 @@ impl AttestationCmd { #[derive(Clone, Debug, Parser, PartialEq)] pub struct IASRemoteAttestation { - /// Path to the enclave binary - #[clap(long = "enclave", help = "Path to the enclave binary")] - pub enclave: Option, - + /// Options for enclave + #[clap(flatten)] + pub enclave: EnclaveOpts, /// An enclave key attested by Remote Attestation #[clap( long = "enclave_key", @@ -81,9 +86,9 @@ fn run_ias_remote_attestation, S: CommitStore>( #[cfg(feature = "sgx-sw")] #[derive(Clone, Debug, Parser, PartialEq)] pub struct SimulateRemoteAttestation { - /// Path to the enclave binary - #[clap(long = "enclave", help = "Path to the enclave binary")] - pub enclave: Option, + /// Options for enclave + #[clap(flatten)] + pub enclave: EnclaveOpts, /// An enclave key attested by Remote Attestation #[clap( diff --git a/app/src/commands/elc.rs b/app/src/commands/elc.rs index a68892d1..2bf48219 100644 --- a/app/src/commands/elc.rs +++ b/app/src/commands/elc.rs @@ -1,4 +1,4 @@ -use crate::opts::Opts; +use crate::opts::{EnclaveOpts, Opts}; use anyhow::Result; use clap::Parser; use enclave_api::{Enclave, EnclaveProtoAPI}; @@ -24,11 +24,11 @@ impl ELCCmd { } } -#[derive(Clone, Debug, Parser, PartialEq)] +#[derive(Clone, Debug, Parser)] pub struct ELCOpts { - /// Path to the enclave binary - #[clap(long = "enclave", help = "Path to enclave binary")] - pub enclave: Option, + /// Options for enclave + #[clap(flatten)] + pub enclave: EnclaveOpts, /// Path to the proto msg #[clap(long = "msg", help = "Path to proto msg")] pub msg: PathBuf, @@ -45,14 +45,14 @@ impl ELCCmd { pub fn run( &self, opts: &Opts, - enclave_loader: impl FnOnce(&Opts, Option<&PathBuf>) -> Result>, + enclave_loader: impl FnOnce(&Opts, Option<&PathBuf>, bool) -> Result>, ) -> Result<()> where S: CommitStore, Enclave: EnclaveProtoAPI, { let elc_opts = self.opts(); - let enclave = enclave_loader(opts, elc_opts.enclave.as_ref())?; + let enclave = enclave_loader(opts, elc_opts.enclave.path.as_ref(), elc_opts.enclave.debug)?; match self { Self::CreateClient(_) => { let _ = enclave.proto_create_client(elc_opts.load()?)?; diff --git a/app/src/commands/enclave.rs b/app/src/commands/enclave.rs index fb8257db..5e27dda3 100644 --- a/app/src/commands/enclave.rs +++ b/app/src/commands/enclave.rs @@ -1,4 +1,4 @@ -use crate::opts::Opts; +use crate::opts::{EnclaveOpts, Opts}; use anyhow::{anyhow, Result}; use clap::Parser; use ecall_commands::GenerateEnclaveKeyInput; @@ -26,7 +26,7 @@ impl EnclaveCmd { pub fn run( &self, opts: &Opts, - enclave_loader: impl FnOnce(&Opts, Option<&PathBuf>) -> Result>, + enclave_loader: impl FnOnce(&Opts, Option<&PathBuf>, bool) -> Result>, ) -> Result<()> where S: CommitStore, @@ -38,13 +38,18 @@ impl EnclaveCmd { info!("created home directory: {:?}", home); } match self { - Self::GenerateKey(cmd) => { - run_generate_key(enclave_loader(opts, cmd.enclave.as_ref())?, cmd) - } - Self::ListKeys(cmd) => run_list_keys(enclave_loader(opts, cmd.enclave.as_ref())?, cmd), - Self::PruneKeys(cmd) => { - run_prune_keys(enclave_loader(opts, cmd.enclave.as_ref())?, cmd) - } + Self::GenerateKey(cmd) => run_generate_key( + enclave_loader(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, + cmd, + ), + Self::ListKeys(cmd) => run_list_keys( + enclave_loader(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, + cmd, + ), + Self::PruneKeys(cmd) => run_prune_keys( + enclave_loader(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, + cmd, + ), Self::Metadata(cmd) => run_print_metadata(opts, cmd), } } @@ -52,9 +57,9 @@ impl EnclaveCmd { #[derive(Clone, Debug, Parser, PartialEq)] pub struct GenerateKey { - /// Path to the enclave binary - #[clap(long = "enclave", help = "Path to the enclave binary")] - pub enclave: Option, + /// Options for enclave + #[clap(flatten)] + pub enclave: EnclaveOpts, } fn run_generate_key, S: CommitStore>( @@ -70,9 +75,9 @@ fn run_generate_key, S: CommitStore>( #[derive(Clone, Debug, Parser, PartialEq)] pub struct ListKeys { - /// Path to the enclave binary - #[clap(long = "enclave", help = "Path to the enclave binary")] - pub enclave: Option, + /// Options for enclave + #[clap(flatten)] + pub enclave: EnclaveOpts, #[clap( long = "available_only", short = 'a', @@ -122,9 +127,9 @@ fn run_list_keys, S: CommitStore>( #[derive(Clone, Debug, Parser, PartialEq)] pub struct PruneKeys { - /// Path to the enclave binary - #[clap(long = "enclave", help = "Path to the enclave binary")] - pub enclave: Option, + /// Options for enclave + #[clap(flatten)] + pub enclave: EnclaveOpts, /// expiration in seconds from attested_at #[clap(long = "expiration", help = "expiration in seconds from attested_at")] pub expiration: u64, @@ -142,14 +147,15 @@ fn run_prune_keys, S: CommitStore>( #[derive(Clone, Debug, Parser, PartialEq)] pub struct Metadata { - /// Path to the enclave binary - #[clap(long = "enclave", help = "Path to the enclave binary")] - pub enclave: Option, + /// Options for enclave + #[clap(flatten)] + pub enclave: EnclaveOpts, } fn run_print_metadata(opts: &Opts, cmd: &Metadata) -> Result<()> { let metadata = host::sgx_get_metadata( cmd.enclave + .path .clone() .unwrap_or_else(|| opts.default_enclave()), )?; diff --git a/app/src/commands/service.rs b/app/src/commands/service.rs index 6b6642bc..9fc04fbd 100644 --- a/app/src/commands/service.rs +++ b/app/src/commands/service.rs @@ -1,4 +1,4 @@ -use crate::opts::Opts; +use crate::opts::{EnclaveOpts, Opts}; use anyhow::Result; use clap::Parser; use enclave_api::{Enclave, EnclaveProtoAPI}; @@ -18,9 +18,9 @@ pub enum ServiceCmd { #[derive(Clone, Debug, Parser, PartialEq)] pub struct Start { - /// Path to the enclave binary - #[clap(long = "enclave", help = "Path to enclave binary")] - pub enclave: Option, + /// Options for enclave + #[clap(flatten)] + pub enclave: EnclaveOpts, /// Address of the App service #[clap( long = "address", @@ -41,7 +41,7 @@ impl ServiceCmd { pub fn run( &self, opts: &Opts, - enclave_loader: impl FnOnce(&Opts, Option<&PathBuf>) -> Result>, + enclave_loader: impl FnOnce(&Opts, Option<&PathBuf>, bool) -> Result>, ) -> Result<()> where S: CommitStore + 'static, @@ -50,7 +50,7 @@ impl ServiceCmd { match self { Self::Start(cmd) => { let addr = cmd.address.parse()?; - let enclave = enclave_loader(opts, cmd.enclave.as_ref())?; + let enclave = enclave_loader(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?; let mut rb = Builder::new_multi_thread(); let rb = if let Some(threads) = cmd.threads { diff --git a/app/src/enclave.rs b/app/src/enclave.rs index 1f5af365..6984be32 100644 --- a/app/src/enclave.rs +++ b/app/src/enclave.rs @@ -6,11 +6,11 @@ use std::path::PathBuf; use store::transaction::CommitStore; pub(crate) fn build_enclave_loader( -) -> impl FnOnce(&Opts, Option<&PathBuf>) -> Result> +) -> impl FnOnce(&Opts, Option<&PathBuf>, bool) -> Result> where Enclave: EnclaveProtoAPI, { - |opts, path| { + |opts, path, debug| { let path = if let Some(path) = path { path.clone() } else { @@ -18,7 +18,7 @@ where }; let env = host::get_environment().unwrap(); let km = EnclaveKeyManager::new(&env.home)?; - match Enclave::create(&path, km, env.store.clone()) { + match Enclave::create(&path, debug, km, env.store.clone()) { Ok(enclave) => Ok(enclave), Err(x) => { bail!( diff --git a/app/src/opts.rs b/app/src/opts.rs index 494a57f6..47eb5a20 100644 --- a/app/src/opts.rs +++ b/app/src/opts.rs @@ -3,7 +3,7 @@ use clap::Parser; use log::LevelFilter; use std::{path::PathBuf, str::FromStr}; -#[derive(Debug, Parser)] +#[derive(Debug, Clone, Parser)] pub struct Opts { /// Path to the home directory #[clap(long = "home", help = "Path to LCP home directory")] @@ -16,6 +16,15 @@ pub struct Opts { pub log_level: Option, } +#[derive(Debug, Clone, Parser, PartialEq)] +pub struct EnclaveOpts { + /// Path to the enclave binary + #[clap(long = "enclave", help = "Path to enclave binary")] + pub path: Option, + #[clap(long = "enclave_debug", help = "Enable enclave debug mode")] + pub debug: bool, +} + impl Opts { pub fn get_home(&self) -> PathBuf { if let Some(home) = self.home.as_ref() { diff --git a/modules/enclave-api/src/enclave.rs b/modules/enclave-api/src/enclave.rs index 07cf73d6..3e3999fb 100644 --- a/modules/enclave-api/src/enclave.rs +++ b/modules/enclave-api/src/enclave.rs @@ -35,11 +35,12 @@ impl Enclave { pub fn create( path: impl Into, + debug: bool, key_manager: EnclaveKeyManager, store: Arc>, ) -> SgxResult { let path = path.into(); - let enclave = host::create_enclave(path.clone())?; + let enclave = host::create_enclave(path.clone(), debug)?; Ok(Self::new(path, key_manager, store, enclave)) } diff --git a/modules/host/src/enclave.rs b/modules/host/src/enclave.rs index db41c962..d5257e6d 100644 --- a/modules/host/src/enclave.rs +++ b/modules/host/src/enclave.rs @@ -2,19 +2,16 @@ use sgx_types::{metadata::metadata_t, *}; use sgx_urts::SgxEnclave; use std::{ffi::CString, mem::MaybeUninit, path::PathBuf}; -pub fn create_enclave(path: impl Into) -> SgxResult { +pub fn create_enclave(path: impl Into, debug: bool) -> SgxResult { let mut launch_token: sgx_launch_token_t = [0; 1024]; let mut launch_token_updated: i32 = 0; - // call sgx_create_enclave to initialize an enclave instance - // Debug Support: set 2nd parameter to 1 - let debug = 1; let mut misc_attr = sgx_misc_attribute_t { secs_attr: sgx_attributes_t { flags: 0, xfrm: 0 }, misc_select: 0, }; SgxEnclave::create( path.into(), - debug, + debug.into(), &mut launch_token, &mut launch_token_updated, &mut misc_attr, diff --git a/tests/integration/src/lib.rs b/tests/integration/src/lib.rs index 4e06c215..b14590df 100644 --- a/tests/integration/src/lib.rs +++ b/tests/integration/src/lib.rs @@ -81,7 +81,7 @@ mod tests { let env = host::get_environment().unwrap(); let km = EnclaveKeyManager::new(&env.home).unwrap(); - let enclave = Enclave::create(ENCLAVE_FILE, km, env.store.clone()).unwrap(); + let enclave = Enclave::create(ENCLAVE_FILE, false, km, env.store.clone()).unwrap(); match std::env::var(ENV_SETUP_NODES).map(|v| v.to_lowercase()) { Ok(v) if v == "false" => run_test(&enclave).unwrap(), From 4bcc8ecabac92ab7cdbea023ca0e5f1915cfe8db Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Mon, 15 Jan 2024 23:14:41 +0900 Subject: [PATCH 2/2] add `EnclaveLoader` trait and implementation Signed-off-by: Jun Kimura --- app/src/commands/attestation.rs | 21 ++++++++++----------- app/src/commands/elc.rs | 15 ++++++++------- app/src/commands/enclave.rs | 19 +++++++++---------- app/src/commands/service.rs | 12 +++++------- app/src/enclave.rs | 19 ++++++++++++++++--- 5 files changed, 48 insertions(+), 38 deletions(-) diff --git a/app/src/commands/attestation.rs b/app/src/commands/attestation.rs index 0a9fb15c..78b22173 100644 --- a/app/src/commands/attestation.rs +++ b/app/src/commands/attestation.rs @@ -1,10 +1,12 @@ -use crate::opts::{EnclaveOpts, Opts}; +use crate::{ + enclave::EnclaveLoader, + opts::{EnclaveOpts, Opts}, +}; use anyhow::{bail, Result}; use clap::Parser; use crypto::Address; use ecall_commands::IASRemoteAttestationInput; use enclave_api::{Enclave, EnclaveCommandAPI, EnclaveProtoAPI}; -use std::path::PathBuf; use store::transaction::CommitStore; /// `attestation` subcommand @@ -19,14 +21,11 @@ pub enum AttestationCmd { } impl AttestationCmd { - pub fn run( - &self, - opts: &Opts, - enclave_loader: impl FnOnce(&Opts, Option<&PathBuf>, bool) -> Result>, - ) -> Result<()> + pub fn run(&self, opts: &Opts, enclave_loader: L) -> Result<()> where S: CommitStore, Enclave: EnclaveProtoAPI, + L: EnclaveLoader, { let home = opts.get_home(); match self { @@ -35,7 +34,7 @@ impl AttestationCmd { bail!("home directory doesn't exist at {:?}", home); } run_ias_remote_attestation( - enclave_loader(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, + enclave_loader.load(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, cmd, ) } @@ -45,7 +44,7 @@ impl AttestationCmd { bail!("home directory doesn't exist at {:?}", home); } run_simulate_remote_attestation( - enclave_loader(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, + enclave_loader.load(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, cmd, ) } @@ -102,14 +101,14 @@ pub struct SimulateRemoteAttestation { long = "signing_cert_path", help = "Path to a der-encoded file that contains X.509 certificate" )] - pub signing_cert_path: PathBuf, + pub signing_cert_path: std::path::PathBuf, /// Path to a PEM-encoded file that contains PKCS#8 private key #[clap( long = "signing_key", help = "Path to a PEM-encoded file that contains PKCS#8 private key" )] - pub signing_key_path: PathBuf, + pub signing_key_path: std::path::PathBuf, /// Validate a signing certificate using openssl command #[clap( diff --git a/app/src/commands/elc.rs b/app/src/commands/elc.rs index 2bf48219..07aa0f86 100644 --- a/app/src/commands/elc.rs +++ b/app/src/commands/elc.rs @@ -1,4 +1,7 @@ -use crate::opts::{EnclaveOpts, Opts}; +use crate::{ + enclave::EnclaveLoader, + opts::{EnclaveOpts, Opts}, +}; use anyhow::Result; use clap::Parser; use enclave_api::{Enclave, EnclaveProtoAPI}; @@ -42,17 +45,15 @@ impl ELCOpts { } impl ELCCmd { - pub fn run( - &self, - opts: &Opts, - enclave_loader: impl FnOnce(&Opts, Option<&PathBuf>, bool) -> Result>, - ) -> Result<()> + pub fn run(&self, opts: &Opts, enclave_loader: L) -> Result<()> where S: CommitStore, Enclave: EnclaveProtoAPI, + L: EnclaveLoader, { let elc_opts = self.opts(); - let enclave = enclave_loader(opts, elc_opts.enclave.path.as_ref(), elc_opts.enclave.debug)?; + let enclave = + enclave_loader.load(opts, elc_opts.enclave.path.as_ref(), elc_opts.enclave.debug)?; match self { Self::CreateClient(_) => { let _ = enclave.proto_create_client(elc_opts.load()?)?; diff --git a/app/src/commands/enclave.rs b/app/src/commands/enclave.rs index 5e27dda3..224b1b1f 100644 --- a/app/src/commands/enclave.rs +++ b/app/src/commands/enclave.rs @@ -1,4 +1,7 @@ -use crate::opts::{EnclaveOpts, Opts}; +use crate::{ + enclave::EnclaveLoader, + opts::{EnclaveOpts, Opts}, +}; use anyhow::{anyhow, Result}; use clap::Parser; use ecall_commands::GenerateEnclaveKeyInput; @@ -6,7 +9,6 @@ use enclave_api::{Enclave, EnclaveCommandAPI, EnclaveProtoAPI}; use lcp_types::Mrenclave; use log::*; use serde_json::json; -use std::path::PathBuf; use store::transaction::CommitStore; // `enclave` subcommand @@ -23,14 +25,11 @@ pub enum EnclaveCmd { } impl EnclaveCmd { - pub fn run( - &self, - opts: &Opts, - enclave_loader: impl FnOnce(&Opts, Option<&PathBuf>, bool) -> Result>, - ) -> Result<()> + pub fn run(&self, opts: &Opts, enclave_loader: L) -> Result<()> where S: CommitStore, Enclave: EnclaveProtoAPI, + L: EnclaveLoader, { let home = opts.get_home(); if !home.exists() { @@ -39,15 +38,15 @@ impl EnclaveCmd { } match self { Self::GenerateKey(cmd) => run_generate_key( - enclave_loader(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, + enclave_loader.load(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, cmd, ), Self::ListKeys(cmd) => run_list_keys( - enclave_loader(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, + enclave_loader.load(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, cmd, ), Self::PruneKeys(cmd) => run_prune_keys( - enclave_loader(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, + enclave_loader.load(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?, cmd, ), Self::Metadata(cmd) => run_print_metadata(opts, cmd), diff --git a/app/src/commands/service.rs b/app/src/commands/service.rs index 9fc04fbd..0f5a81ae 100644 --- a/app/src/commands/service.rs +++ b/app/src/commands/service.rs @@ -1,10 +1,10 @@ +use crate::enclave::EnclaveLoader; use crate::opts::{EnclaveOpts, Opts}; use anyhow::Result; use clap::Parser; use enclave_api::{Enclave, EnclaveProtoAPI}; use log::*; use service::{run_service, AppService}; -use std::path::PathBuf; use std::sync::Arc; use store::transaction::CommitStore; use tokio::runtime::Builder; @@ -38,19 +38,17 @@ pub struct Start { } impl ServiceCmd { - pub fn run( - &self, - opts: &Opts, - enclave_loader: impl FnOnce(&Opts, Option<&PathBuf>, bool) -> Result>, - ) -> Result<()> + pub fn run(&self, opts: &Opts, enclave_loader: L) -> Result<()> where S: CommitStore + 'static, Enclave: EnclaveProtoAPI, + L: EnclaveLoader, { match self { Self::Start(cmd) => { let addr = cmd.address.parse()?; - let enclave = enclave_loader(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?; + let enclave = + enclave_loader.load(opts, cmd.enclave.path.as_ref(), cmd.enclave.debug)?; let mut rb = Builder::new_multi_thread(); let rb = if let Some(threads) = cmd.threads { diff --git a/app/src/enclave.rs b/app/src/enclave.rs index 6984be32..706bceda 100644 --- a/app/src/enclave.rs +++ b/app/src/enclave.rs @@ -5,12 +5,18 @@ use keymanager::EnclaveKeyManager; use std::path::PathBuf; use store::transaction::CommitStore; -pub(crate) fn build_enclave_loader( -) -> impl FnOnce(&Opts, Option<&PathBuf>, bool) -> Result> +pub trait EnclaveLoader { + fn load(&self, opts: &Opts, path: Option<&PathBuf>, debug: bool) -> Result>; +} + +#[derive(Debug)] +pub struct DefaultEnclaveLoader(std::marker::PhantomData); + +impl EnclaveLoader for DefaultEnclaveLoader where Enclave: EnclaveProtoAPI, { - |opts, path, debug| { + fn load(&self, opts: &Opts, path: Option<&PathBuf>, debug: bool) -> Result> { let path = if let Some(path) = path { path.clone() } else { @@ -30,3 +36,10 @@ where } } } + +pub const fn build_enclave_loader() -> DefaultEnclaveLoader +where + Enclave: EnclaveProtoAPI, +{ + DefaultEnclaveLoader(std::marker::PhantomData) +}