From 36dbf5065bde5bad0a4a5c868bd6ec40efb1d622 Mon Sep 17 00:00:00 2001 From: Leechael Yim Date: Wed, 4 Dec 2024 23:42:08 +0800 Subject: [PATCH] update API to mathced latest version of tappd --- Cargo.lock | 30 +++++++++++++++++--- Cargo.toml | 1 + rpc/proto/tappd_rpc.proto | 60 ++++++++++++--------------------------- src/ra_tls/cert.rs | 12 ++++---- src/rpc_service.rs | 57 +++++++++++++++++++++++++++++++------ 5 files changed, 100 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d159ac6..9d4a56e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -301,7 +301,7 @@ dependencies = [ "bitflags 2.6.0", "cexpr", "clang-sys", - "itertools 0.12.1", + "itertools 0.10.5", "lazy_static", "lazycell", "log", @@ -696,7 +696,7 @@ checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "dcap-qvl" version = "0.1.3" -source = "git+https://github.com/Leechael/dcap-qvl?branch=feat-arbitrary#01b0e7527e3a20301a2e6c68182cb39fd5f187c0" +source = "git+https://github.com/Leechael/dcap-qvl?branch=feat-arbitrary#adfa5708c6c1826f6fc648661650a4e6037a236f" dependencies = [ "anyhow", "asn1_der", @@ -718,6 +718,8 @@ dependencies = [ "serde", "serde_bytes", "serde_json", + "sha2", + "sha3", "tracing", "urlencoding", "x509-cert", @@ -1756,6 +1758,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -2462,7 +2473,7 @@ checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", "heck 0.5.0", - "itertools 0.12.1", + "itertools 0.10.5", "log", "multimap 0.10.0", "once_cell", @@ -2495,7 +2506,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.12.1", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.79", @@ -3469,6 +3480,16 @@ dependencies = [ "digest", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -3714,6 +3735,7 @@ dependencies = [ "serde", "serde_json", "sha2", + "sha3", "tappd-rpc", "tokio", "tracing", diff --git a/Cargo.toml b/Cargo.toml index f9f366f..badc198 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ scale = { package = "parity-scale-codec", version = "3.6.5", default-features = "derive", ] } reqwest = "0.12.8" +sha3 = "0.10.8" [workspace] members = ["rpc"] diff --git a/rpc/proto/tappd_rpc.proto b/rpc/proto/tappd_rpc.proto index 6e53773..5e18deb 100644 --- a/rpc/proto/tappd_rpc.proto +++ b/rpc/proto/tappd_rpc.proto @@ -19,6 +19,8 @@ message DeriveKeyArgs { string path = 1; // Subject of the certificate to request string subject = 2; + // DNS alternative names for the certificate + repeated string alt_names = 3; } // The response to a DeriveKey request @@ -30,9 +32,24 @@ message DeriveKeyResponse { } // The request to get a TDX quote +// The report data is prefixed with `app-data:` before hashing unless the algorithm is `raw`. +// Final report data is hash(`app-data:` + report_data) if the algorithm is not `raw`. message TdxQuoteArgs { // Report data bytes report_data = 1; + // The hash algorithm to use to process the report data. Default is `sha512`. + // Supported algorithms are: + // - `sha256` + // - `sha384` + // - `sha512` + // - `sha3-256` + // - `sha3-384` + // - `sha3-512` + // - `keccak256` + // - `keccak384` + // - `keccak512` + // - `raw`: Passes the report_data directly to the driver without any processing + string hash_algorithm = 2; } message TdxQuoteResponse { @@ -40,45 +57,4 @@ message TdxQuoteResponse { bytes quote = 1; // Event log string event_log = 2; -} - - -service Worker { - // Get worker info - rpc Info(google.protobuf.Empty) returns (WorkerInfo) {} - // Get worker containers - rpc ListContainers(google.protobuf.Empty) returns (ListContainersResponse) {} -} - -message ListContainersResponse { - repeated Container containers = 1; -} - -message Container { - // The ID of this container - string id = 1; - // The names that this container has been given - repeated string names = 2; - // The name of the image used when creating this container - string image = 3; - // The ID of the image that this container was created from - string image_id = 4; - // Command to run when starting the container - string command = 5; - // When the container was created - int64 created = 6; - // The state of this container (e.g. Exited) - string state = 7; - // The status of this container (e.g. Exited) - string status = 8; -} - -// The request to derive a key -message WorkerInfo { - // Worker ID - string app_id = 1; - // App certificate - string app_cert = 2; - // TCB info - string tcb_info = 3; -} +} \ No newline at end of file diff --git a/src/ra_tls/cert.rs b/src/ra_tls/cert.rs index d2bc240..42bef3c 100644 --- a/src/ra_tls/cert.rs +++ b/src/ra_tls/cert.rs @@ -90,7 +90,7 @@ pub struct CertRequest<'a> { key: &'a KeyPair, org_name: Option<&'a str>, subject: &'a str, - alt_subject: Option<&'a str>, + alt_names: Option<&'a [String]>, ca_level: Option, quote: Option<&'a [u8]>, event_log: Option<&'a [u8]>, @@ -106,10 +106,12 @@ impl<'a> CertRequest<'a> { } dn.push(DnType::CommonName, self.subject); params.distinguished_name = dn; - if let Some(alt_subject) = self.alt_subject { - params - .subject_alt_names - .push(SanType::DnsName(alt_subject.try_into()?)); + if let Some(alt_names) = self.alt_names { + for alt_name in alt_names { + params + .subject_alt_names + .push(SanType::DnsName(alt_name.clone().try_into()?)); + } } // if let Some(quote) = self.quote { // let content = yasna::construct_der(|writer| { diff --git a/src/rpc_service.rs b/src/rpc_service.rs index bc2cca8..f01299d 100644 --- a/src/rpc_service.rs +++ b/src/rpc_service.rs @@ -7,7 +7,7 @@ use proptest::{ test_runner::TestRunner, }; use scale::Encode; -use dcap_qvl::quote::{Header, TDReport10, AuthDataV4}; +use dcap_qvl::quote::{AuthDataV4, Header, TDReport10, TdxEventLogs}; use tappd_rpc::{ tappd_server::{TappdRpc, TappdServer}, // Container, @@ -16,6 +16,7 @@ use tappd_rpc::{ TdxQuoteArgs, TdxQuoteResponse, }; +use sha2::Digest; use crate::{ rpc_call::RpcCall, @@ -56,6 +57,7 @@ impl TappdRpc for InternalRpcHandler { .context("Failed to derive key")?; let req = CertRequest::builder() .subject(&request.subject) + .alt_names(&request.alt_names) .key(&derived_key) .build(); let cert = self @@ -73,6 +75,13 @@ impl TappdRpc for InternalRpcHandler { async fn tdx_quote(self, request: TdxQuoteArgs) -> Result { let mut runner = TestRunner::default(); + let params = Default::default(); + let event_logs = ::arbitrary_with(params) + .new_tree(&mut runner) + .expect("Failed to create event_logs") + .current(); + let rtmrs = event_logs.get_rtmr(); + let mut header =
::arbitrary().new_tree(&mut runner).expect("Failed to create value tree").current(); // TODO: the python decoder not a full implementation. header.version = 4; @@ -83,7 +92,11 @@ impl TappdRpc for InternalRpcHandler { .new_tree(&mut runner) .expect("Failed to create value tree") .current(); - body.report_data = sha2_512(&request.report_data); + body.rt_mr0 = rtmrs[0]; + body.rt_mr1 = rtmrs[1]; + body.rt_mr2 = rtmrs[2]; + body.rt_mr3 = rtmrs[3]; + body.report_data = to_report_data_with_hash(&request.report_data, &request.hash_algorithm)?; let mut encoded = Vec::new(); encoded.extend(header.encode()); @@ -99,7 +112,7 @@ impl TappdRpc for InternalRpcHandler { Ok(TdxQuoteResponse { quote: encoded, - event_log: String::from("mock_event_log"), + event_log: event_logs.to_json().unwrap_or_default(), }) } } @@ -122,9 +135,35 @@ impl RpcCall for InternalRpcHandler { } } -fn sha2_512(data: &[u8]) -> [u8; 64] { - use sha2::{Digest, Sha512}; - let mut hasher = Sha512::new(); - hasher.update(data); - hasher.finalize().into() -} +fn to_report_data_with_hash(content: &[u8], hash: &str) -> Result<[u8; 64]> { + macro_rules! do_hash { + ($hash: ty) => {{ + // The format is: + // hash(:) + let mut hasher = <$hash>::new(); + hasher.update("app-data".as_bytes()); + hasher.update(b":"); + hasher.update(content); + let output = hasher.finalize(); + + let mut padded = [0u8; 64]; + padded[..output.len()].copy_from_slice(&output); + padded + }}; + } + let output = match hash { + "sha256" => do_hash!(sha2::Sha256), + "sha384" => do_hash!(sha2::Sha384), + // Default to sha512 + "" | "sha512" => do_hash!(sha2::Sha512), + "sha3-256" => do_hash!(sha3::Sha3_256), + "sha3-384" => do_hash!(sha3::Sha3_384), + "sha3-512" => do_hash!(sha3::Sha3_512), + "keccak256" => do_hash!(sha3::Keccak256), + "keccak384" => do_hash!(sha3::Keccak384), + "keccak512" => do_hash!(sha3::Keccak512), + "raw" => content.try_into().ok().context("invalid content length")?, + _ => anyhow::bail!("invalid hash algorithm"), + }; + Ok(output) +} \ No newline at end of file