From 291941667d1847c6ba2cd24994fe75ccdd22d681 Mon Sep 17 00:00:00 2001 From: Noor Date: Thu, 3 Apr 2025 19:01:51 +0530 Subject: [PATCH 1/5] feat: add directory support on launch config dtpm proto changed upload files through grpc stream seperated filesystem from dtpm config tar zstd archiving directory to upload test directory support on config test archive directory --- Cargo.lock | 176 +++++++++++++++++++++++++++++--- Cargo.toml | 5 + proto/sgx/dtpm.proto | 12 ++- src/sgx/types/dtpm.rs | 57 ++++++++--- tests/dtpm-config_test.rs | 32 ++++++ tests/fixtures/dtpm_config.yaml | 15 +++ 6 files changed, 265 insertions(+), 32 deletions(-) create mode 100644 tests/dtpm-config_test.rs create mode 100644 tests/fixtures/dtpm_config.yaml diff --git a/Cargo.lock b/Cargo.lock index ede831e..58ca45d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -163,6 +163,17 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +[[package]] +name = "cc" +version = "1.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -177,9 +188,12 @@ dependencies = [ "prost", "serde", "serde_yaml", + "tar", + "tempfile", "thiserror", "tonic", "tonic-build", + "zstd", ] [[package]] @@ -210,6 +224,18 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.59.0", +] + [[package]] name = "fixedbitset" version = "0.4.2" @@ -269,7 +295,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] @@ -449,6 +487,15 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + [[package]] name = "libc" version = "0.2.169" @@ -456,10 +503,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] -name = "linux-raw-sys" -version = "0.4.14" +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", + "redox_syscall", +] + +[[package]] +name = "linux-raw-sys" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" [[package]] name = "log" @@ -501,7 +559,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -574,6 +632,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -663,6 +727,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.8.5" @@ -690,7 +760,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "redox_syscall" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +dependencies = [ + "bitflags", ] [[package]] @@ -730,9 +809,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.42" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" dependencies = [ "bitflags", "errno", @@ -786,6 +865,12 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "slab" version = "0.4.9" @@ -829,13 +914,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" [[package]] -name = "tempfile" -version = "3.14.0" +name = "tar" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tempfile" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ - "cfg-if", "fastrand", + "getrandom 0.3.2", "once_cell", "rustix", "windows-sys 0.59.0", @@ -1066,6 +1162,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -1148,6 +1253,25 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] +name = "xattr" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e" +dependencies = [ + "libc", + "rustix", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -1168,3 +1292,31 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.15+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index f282463..1b4a8d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,11 @@ serde = { version = "1.0.216", features = ["derive"] } serde_yaml = "0.9.34" thiserror = "2.0.11" tonic = "0.12.3" +tar = "0.4.44" +zstd = "0.13.3" [build-dependencies] tonic-build = "0.12.3" + +[dev-dependencies] +tempfile = "3.19.1" diff --git a/proto/sgx/dtpm.proto b/proto/sgx/dtpm.proto index 5622bb3..89cc5d1 100644 --- a/proto/sgx/dtpm.proto +++ b/proto/sgx/dtpm.proto @@ -5,16 +5,19 @@ package dtpm_proto; import "shared/common.proto"; message DtpmConfigData { - repeated FileEntry filesystems = 1; - repeated EnvironmentEntry environments = 2; - repeated ChildProcess child_processes = 3; + repeated EnvironmentEntry environments = 1; + repeated ChildProcess child_processes = 2; } message FileEntry { string path = 1; - string content = 2; + oneof content { + string data = 2; + bytes archive = 3; + } } + message EnvironmentEntry { string name = 1; string value = 2; @@ -52,5 +55,6 @@ message DtpmGetConfigRes { service DtpmConfigManager { rpc SetConfig(DtpmSetConfigReq) returns (DtpmSetConfigRes) {} + rpc UploadFiles(stream FileEntry) returns (DtpmSetConfigRes) {} rpc GetConfig(common_proto.Empty) returns (DtpmGetConfigRes) {} } \ No newline at end of file diff --git a/src/sgx/types/dtpm.rs b/src/sgx/types/dtpm.rs index 7b33293..c3d7212 100644 --- a/src/sgx/types/dtpm.rs +++ b/src/sgx/types/dtpm.rs @@ -1,6 +1,9 @@ use crate::sgx::pb::dtpm_proto; use base64::{engine::general_purpose::STANDARD as BASE64, Engine}; use serde::{Deserialize, Serialize}; +use std::path::Path; +use tar::Builder; +use zstd::Encoder; #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct DtpmConfig { @@ -12,11 +15,7 @@ pub struct DtpmConfig { impl From for DtpmConfig { fn from(pb_val: dtpm_proto::DtpmConfigData) -> Self { DtpmConfig { - filesystems: pb_val - .filesystems - .into_iter() - .map(FileEntry::from) - .collect(), + filesystems: vec![], environments: pb_val .environments .into_iter() @@ -34,7 +33,6 @@ impl From for DtpmConfig { impl From for dtpm_proto::DtpmConfigData { fn from(val: DtpmConfig) -> dtpm_proto::DtpmConfigData { dtpm_proto::DtpmConfigData { - filesystems: val.filesystems.into_iter().map(Into::into).collect(), environments: val.environments.into_iter().map(Into::into).collect(), child_processes: val.child_processes.into_iter().map(Into::into).collect(), } @@ -51,7 +49,11 @@ impl From for FileEntry { fn from(pb_val: dtpm_proto::FileEntry) -> Self { FileEntry { path: pb_val.path, - content: FileContent::Data(pb_val.content), + content: match pb_val.content { + Some(dtpm_proto::file_entry::Content::Data(data)) => FileContent::Data(data), + Some(dtpm_proto::file_entry::Content::Archive(_)) => todo!(), + None => FileContent::Data("".to_string()), + }, } } } @@ -60,8 +62,11 @@ impl From for dtpm_proto::FileEntry { dtpm_proto::FileEntry { path: val.path, content: match val.content { - FileContent::Data(data) => data, - FileContent::Path(path) => path, + FileContent::Path(_) => unimplemented!(), + FileContent::Data(data) => Some(dtpm_proto::file_entry::Content::Data(data)), + FileContent::Archive(file_entry) => { + Some(dtpm_proto::file_entry::Content::Archive(file_entry)) + } }, } } @@ -73,6 +78,8 @@ pub enum FileContent { Path(String), #[serde(rename = "data")] Data(String), + #[serde(rename = "directory")] + Archive(Vec), } #[derive(Debug, Clone, Serialize, Deserialize, Default)] @@ -197,15 +204,33 @@ impl DtpmConfig { } pub fn load_data(mut self) -> Result { - self.filesystems.iter_mut().for_each(|x| { - if let FileContent::Path(path) = &x.content { - let content = - std::fs::read(path).unwrap_or_else(|_| panic!("Unable to read file {path}")); - let encoded = BASE64.encode(content); - x.content = FileContent::Data(encoded); + for file_entry in self.filesystems.iter_mut() { + if let FileContent::Path(path) = &file_entry.content { + if Path::new(path).is_dir() { + let compressed_data = compress_directory(path)?; + file_entry.content = FileContent::Archive(compressed_data); + } else { + let content = std::fs::read(path) + .unwrap_or_else(|_| panic!("Unable to read file {path}")); + let encoded = BASE64.encode(content); + file_entry.content = FileContent::Data(encoded); + } } - }); + } Ok(self) } } + +pub fn compress_directory(input_dir: &str) -> Result> { + let mut tar_builder = Builder::new(Encoder::new(Vec::new(), 3)?); + + tar_builder.append_dir_all(".", input_dir)?; + + tar_builder.finish()?; + + let zstd_encoder = tar_builder.into_inner()?; + let compressed_data = zstd_encoder.finish()?; + + Ok(compressed_data) +} diff --git a/tests/dtpm-config_test.rs b/tests/dtpm-config_test.rs new file mode 100644 index 0000000..44bfd91 --- /dev/null +++ b/tests/dtpm-config_test.rs @@ -0,0 +1,32 @@ +use detee_shared::sgx::types::dtpm::{compress_directory, DtpmConfig}; + +#[test] +fn dtpm_config_dir_support_test() { + let file_path = "tests/fixtures/dtpm_config.yaml"; + let unloaded_config = DtpmConfig::from_path(file_path).unwrap(); + + let loaded_config = unloaded_config.load_data().unwrap(); + + dbg!(&loaded_config); +} + +#[test] +fn test_compression() { + // let file_path = "/Users/user/.cache/hunter/toolchain"; + let file_path = "./tests"; + let compressed_buff = compress_directory(file_path).unwrap(); + + let tmp_dir = tempfile::tempdir() + .unwrap() + .into_path() + .to_string_lossy() + .to_string(); + + dbg!(&tmp_dir); + + std::fs::write( + format!("{}/{}", tmp_dir, "archive.tar.zst"), + &compressed_buff, + ) + .unwrap(); +} diff --git a/tests/fixtures/dtpm_config.yaml b/tests/fixtures/dtpm_config.yaml new file mode 100644 index 0000000..6594cee --- /dev/null +++ b/tests/fixtures/dtpm_config.yaml @@ -0,0 +1,15 @@ +environments: + - name: APP_NAME + value: actix-injectio-from-base-package + - name: PORT + value: 8080 +child_processes: + - path: /bin/actix-app-info + arguments: [] + restart: + max_retries: 2 + delay_seconds: 2 + policy: !OnNonZeroExit true +filesystems: + - path: /bin/actix-app-info + content: !path "/Users/user/tmp/actix-app-info/target/x86_64-unknown-linux-musl/release/actix-app-info" -- 2.43.0 From cf1bc1143c5603d23393cbf13c9a0939136a9339 Mon Sep 17 00:00:00 2001 From: Noor Date: Thu, 3 Apr 2025 14:03:36 +0000 Subject: [PATCH 2/5] fix: dtpm upload file response --- proto/sgx/dtpm.proto | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proto/sgx/dtpm.proto b/proto/sgx/dtpm.proto index 89cc5d1..200b5d2 100644 --- a/proto/sgx/dtpm.proto +++ b/proto/sgx/dtpm.proto @@ -38,7 +38,6 @@ message RestartPolicy { } } - message DtpmSetConfigReq { DtpmConfigData config_data = 1; string metadata = 2; @@ -55,6 +54,6 @@ message DtpmGetConfigRes { service DtpmConfigManager { rpc SetConfig(DtpmSetConfigReq) returns (DtpmSetConfigRes) {} - rpc UploadFiles(stream FileEntry) returns (DtpmSetConfigRes) {} + rpc UploadFiles(stream FileEntry) returns (common_proto.Empty) {} rpc GetConfig(common_proto.Empty) returns (DtpmGetConfigRes) {} } \ No newline at end of file -- 2.43.0 From 8f0222328f91f2c6e2593aaa6a48307aee21587b Mon Sep 17 00:00:00 2001 From: Noor Date: Fri, 4 Apr 2025 13:13:01 +0000 Subject: [PATCH 3/5] feat: decompression add bincode support for serialization and deserialization implement directory decompression tests for decompression --- Cargo.lock | 33 +++++++++++++++++++++++++++++++ Cargo.toml | 1 + build.rs | 4 ++++ proto/sgx/dtpm.proto | 2 +- src/sgx/types/dtpm.rs | 11 +++++++++-- tests/dtpm-config_test.rs | 35 +++++++++++++++++++++++---------- tests/fixtures/dtpm_config.yaml | 2 +- 7 files changed, 74 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58ca45d..7db0592 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,6 +145,26 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bincode" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" +dependencies = [ + "bincode_derive", + "serde", + "unty", +] + +[[package]] +name = "bincode_derive" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" +dependencies = [ + "virtue", +] + [[package]] name = "bitflags" version = "2.6.0" @@ -185,6 +205,7 @@ name = "detee-shared" version = "0.1.0" dependencies = [ "base64", + "bincode", "prost", "serde", "serde_yaml", @@ -1147,6 +1168,18 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "unty" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" + +[[package]] +name = "virtue" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" + [[package]] name = "want" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index 1b4a8d9..379a588 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ thiserror = "2.0.11" tonic = "0.12.3" tar = "0.4.44" zstd = "0.13.3" +bincode = "2.0.1" [build-dependencies] tonic-build = "0.12.3" diff --git a/build.rs b/build.rs index 16bb3cd..d9e8a0c 100644 --- a/build.rs +++ b/build.rs @@ -34,6 +34,10 @@ fn main() -> Result<(), Box> { ".vm_proto.VmNodeListResp", "#[derive(serde::Serialize, serde::Deserialize)]", ) + .type_attribute( + ".dtpm_proto.FileEntry", + "#[derive(serde::Serialize, serde::Deserialize, bincode::Encode, bincode::Decode)]", + ) .compile_protos( &[ "proto/sgx/app.proto", diff --git a/proto/sgx/dtpm.proto b/proto/sgx/dtpm.proto index 200b5d2..084a90f 100644 --- a/proto/sgx/dtpm.proto +++ b/proto/sgx/dtpm.proto @@ -53,7 +53,7 @@ message DtpmGetConfigRes { } service DtpmConfigManager { - rpc SetConfig(DtpmSetConfigReq) returns (DtpmSetConfigRes) {} rpc UploadFiles(stream FileEntry) returns (common_proto.Empty) {} + rpc SetConfig(DtpmSetConfigReq) returns (DtpmSetConfigRes) {} rpc GetConfig(common_proto.Empty) returns (DtpmGetConfigRes) {} } \ No newline at end of file diff --git a/src/sgx/types/dtpm.rs b/src/sgx/types/dtpm.rs index c3d7212..961d117 100644 --- a/src/sgx/types/dtpm.rs +++ b/src/sgx/types/dtpm.rs @@ -2,8 +2,8 @@ use crate::sgx::pb::dtpm_proto; use base64::{engine::general_purpose::STANDARD as BASE64, Engine}; use serde::{Deserialize, Serialize}; use std::path::Path; -use tar::Builder; -use zstd::Encoder; +use tar::{Archive, Builder}; +use zstd::{Decoder, Encoder}; #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct DtpmConfig { @@ -234,3 +234,10 @@ pub fn compress_directory(input_dir: &str) -> Result> { Ok(compressed_data) } + +pub fn decompress_directory(save_path: &str, archive_buff: Vec) -> Result<()> { + let mut archive = Archive::new(Decoder::new(archive_buff.as_slice())?); + + archive.unpack(save_path)?; + Ok(()) +} diff --git a/tests/dtpm-config_test.rs b/tests/dtpm-config_test.rs index 44bfd91..3cbca31 100644 --- a/tests/dtpm-config_test.rs +++ b/tests/dtpm-config_test.rs @@ -1,4 +1,14 @@ -use detee_shared::sgx::types::dtpm::{compress_directory, DtpmConfig}; +use detee_shared::sgx::types::dtpm::{compress_directory, decompress_directory, DtpmConfig}; + +use std::sync::LazyLock; + +static TEMP_DIR: LazyLock = LazyLock::new(|| { + tempfile::tempdir() + .unwrap() + .into_path() + .to_string_lossy() + .to_string() +}); #[test] fn dtpm_config_dir_support_test() { @@ -12,21 +22,26 @@ fn dtpm_config_dir_support_test() { #[test] fn test_compression() { - // let file_path = "/Users/user/.cache/hunter/toolchain"; let file_path = "./tests"; let compressed_buff = compress_directory(file_path).unwrap(); - let tmp_dir = tempfile::tempdir() - .unwrap() - .into_path() - .to_string_lossy() - .to_string(); - - dbg!(&tmp_dir); + dbg!(&TEMP_DIR); std::fs::write( - format!("{}/{}", tmp_dir, "archive.tar.zst"), + format!("{}/{}", *TEMP_DIR, "archive.tar.zst"), &compressed_buff, ) .unwrap(); } + +#[test] +fn test_decompression_02() { + let file_path = "./tests"; + let archive_buff = compress_directory(file_path).unwrap(); + + decompress_directory(&TEMP_DIR, archive_buff).unwrap(); + + let path = format!("{}/{}", *TEMP_DIR, "fixtures/dtpm_config.yaml"); + dbg!(&path); + assert!(std::path::Path::new(&path).exists()); +} diff --git a/tests/fixtures/dtpm_config.yaml b/tests/fixtures/dtpm_config.yaml index 6594cee..39b0607 100644 --- a/tests/fixtures/dtpm_config.yaml +++ b/tests/fixtures/dtpm_config.yaml @@ -12,4 +12,4 @@ child_processes: policy: !OnNonZeroExit true filesystems: - path: /bin/actix-app-info - content: !path "/Users/user/tmp/actix-app-info/target/x86_64-unknown-linux-musl/release/actix-app-info" + content: !path "./tests" -- 2.43.0 From 64d7a1c9e16836615602636e346a356960dabd00 Mon Sep 17 00:00:00 2001 From: Noor Date: Tue, 8 Apr 2025 09:31:45 +0000 Subject: [PATCH 4/5] fix: decompression on enclave unpacking each file into enclave archive with top level directory --- src/sgx/types/dtpm.rs | 38 ++++++++++++++++++++++++++++++-------- tests/dtpm-config_test.rs | 3 +-- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/sgx/types/dtpm.rs b/src/sgx/types/dtpm.rs index 961d117..a50e95d 100644 --- a/src/sgx/types/dtpm.rs +++ b/src/sgx/types/dtpm.rs @@ -205,13 +205,13 @@ impl DtpmConfig { pub fn load_data(mut self) -> Result { for file_entry in self.filesystems.iter_mut() { - if let FileContent::Path(path) = &file_entry.content { - if Path::new(path).is_dir() { - let compressed_data = compress_directory(path)?; + if let FileContent::Path(content_path) = &file_entry.content { + if Path::new(content_path).is_dir() { + let compressed_data = compress_directory(content_path)?; file_entry.content = FileContent::Archive(compressed_data); } else { - let content = std::fs::read(path) - .unwrap_or_else(|_| panic!("Unable to read file {path}")); + let content = std::fs::read(content_path) + .unwrap_or_else(|_| panic!("Unable to read file {content_path}")); let encoded = BASE64.encode(content); file_entry.content = FileContent::Data(encoded); } @@ -223,9 +223,10 @@ impl DtpmConfig { } pub fn compress_directory(input_dir: &str) -> Result> { + let path = format!("{}/", input_dir.split('/').next_back().unwrap_or("files")); let mut tar_builder = Builder::new(Encoder::new(Vec::new(), 3)?); - tar_builder.append_dir_all(".", input_dir)?; + tar_builder.append_dir_all(path, input_dir)?; tar_builder.finish()?; @@ -235,9 +236,30 @@ pub fn compress_directory(input_dir: &str) -> Result> { Ok(compressed_data) } -pub fn decompress_directory(save_path: &str, archive_buff: Vec) -> Result<()> { +pub fn decompress_directory(dst: &str, archive_buff: Vec) -> Result<()> { + /* + for entry in Archive::new(Decoder::new(archive_buff.as_slice())?).entries()? { + let entry = entry?; + let path = entry.path(); + println!( + "Entry: {:?}; type {:?}; size: {}", + path?, + entry.header().entry_type(), + entry.size() + ); + } + */ let mut archive = Archive::new(Decoder::new(archive_buff.as_slice())?); - archive.unpack(save_path)?; + for entry in archive.entries()? { + let mut file = entry?; + let file_path = format!("{dst}/{}", &file.path()?.to_string_lossy()); + if file.header().entry_type() == tar::EntryType::Directory { + std::fs::create_dir_all(file_path)?; + } else { + file.unpack(file_path)?; + } + } + Ok(()) } diff --git a/tests/dtpm-config_test.rs b/tests/dtpm-config_test.rs index 3cbca31..ec6baa7 100644 --- a/tests/dtpm-config_test.rs +++ b/tests/dtpm-config_test.rs @@ -41,7 +41,6 @@ fn test_decompression_02() { decompress_directory(&TEMP_DIR, archive_buff).unwrap(); - let path = format!("{}/{}", *TEMP_DIR, "fixtures/dtpm_config.yaml"); - dbg!(&path); + let path = format!("{}/{}", *TEMP_DIR, "tests/fixtures/dtpm_config.yaml"); assert!(std::path::Path::new(&path).exists()); } -- 2.43.0 From 20ba749427ac4453a06bc8a8ef3fb8f0ec6bb592 Mon Sep 17 00:00:00 2001 From: Noor Date: Tue, 15 Apr 2025 15:04:37 +0000 Subject: [PATCH 5/5] refactor: remove base64 file encoding read and send file as bytes update FileEntry grpc type to bytes fixed FileEntry From implementation --- Cargo.lock | 1 - Cargo.toml | 1 - proto/sgx/dtpm.proto | 2 +- src/sgx/types/dtpm.rs | 17 +++++++++-------- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7db0592..d2283a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,7 +204,6 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" name = "detee-shared" version = "0.1.0" dependencies = [ - "base64", "bincode", "prost", "serde", diff --git a/Cargo.toml b/Cargo.toml index 379a588..f0e9d0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] -base64 = "0.22.1" prost = "0.13.4" serde = { version = "1.0.216", features = ["derive"] } serde_yaml = "0.9.34" diff --git a/proto/sgx/dtpm.proto b/proto/sgx/dtpm.proto index 084a90f..45af42d 100644 --- a/proto/sgx/dtpm.proto +++ b/proto/sgx/dtpm.proto @@ -12,7 +12,7 @@ message DtpmConfigData { message FileEntry { string path = 1; oneof content { - string data = 2; + bytes data = 2; bytes archive = 3; } } diff --git a/src/sgx/types/dtpm.rs b/src/sgx/types/dtpm.rs index a50e95d..e272805 100644 --- a/src/sgx/types/dtpm.rs +++ b/src/sgx/types/dtpm.rs @@ -1,5 +1,5 @@ use crate::sgx::pb::dtpm_proto; -use base64::{engine::general_purpose::STANDARD as BASE64, Engine}; +use bincode::{Decode, Encode}; use serde::{Deserialize, Serialize}; use std::path::Path; use tar::{Archive, Builder}; @@ -39,7 +39,7 @@ impl From for dtpm_proto::DtpmConfigData { } } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct FileEntry { pub path: String, pub content: FileContent, @@ -51,8 +51,10 @@ impl From for FileEntry { path: pb_val.path, content: match pb_val.content { Some(dtpm_proto::file_entry::Content::Data(data)) => FileContent::Data(data), - Some(dtpm_proto::file_entry::Content::Archive(_)) => todo!(), - None => FileContent::Data("".to_string()), + Some(dtpm_proto::file_entry::Content::Archive(archive_data)) => { + FileContent::Archive(archive_data) + } + _ => FileContent::Data(vec![]), }, } } @@ -72,12 +74,12 @@ impl From for dtpm_proto::FileEntry { } } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub enum FileContent { #[serde(rename = "path")] Path(String), #[serde(rename = "data")] - Data(String), + Data(Vec), #[serde(rename = "directory")] Archive(Vec), } @@ -212,8 +214,7 @@ impl DtpmConfig { } else { let content = std::fs::read(content_path) .unwrap_or_else(|_| panic!("Unable to read file {content_path}")); - let encoded = BASE64.encode(content); - file_entry.content = FileContent::Data(encoded); + file_entry.content = FileContent::Data(content); } } } -- 2.43.0