Skip to content

Commit

Permalink
update API to mathced latest version of tappd
Browse files Browse the repository at this point in the history
  • Loading branch information
Leechael committed Dec 4, 2024
1 parent 966e1ef commit 36dbf50
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 60 deletions.
30 changes: 26 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
60 changes: 18 additions & 42 deletions rpc/proto/tappd_rpc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -30,55 +32,29 @@ 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 {
// TDX quote
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;
}
}
12 changes: 7 additions & 5 deletions src/ra_tls/cert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>,
quote: Option<&'a [u8]>,
event_log: Option<&'a [u8]>,
Expand All @@ -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| {
Expand Down
57 changes: 48 additions & 9 deletions src/rpc_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -16,6 +16,7 @@ use tappd_rpc::{
TdxQuoteArgs,
TdxQuoteResponse,
};
use sha2::Digest;

use crate::{
rpc_call::RpcCall,
Expand Down Expand Up @@ -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
Expand All @@ -73,6 +75,13 @@ impl TappdRpc for InternalRpcHandler {
async fn tdx_quote(self, request: TdxQuoteArgs) -> Result<TdxQuoteResponse> {
let mut runner = TestRunner::default();

let params = Default::default();
let event_logs = <TdxEventLogs as Arbitrary>::arbitrary_with(params)
.new_tree(&mut runner)
.expect("Failed to create event_logs")
.current();
let rtmrs = event_logs.get_rtmr();

let mut header = <Header as Arbitrary>::arbitrary().new_tree(&mut runner).expect("Failed to create value tree").current();
// TODO: the python decoder not a full implementation.
header.version = 4;
Expand All @@ -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());
Expand All @@ -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(),
})
}
}
Expand All @@ -122,9 +135,35 @@ impl RpcCall<AppState> 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(<tag>:<content>)
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)
}

0 comments on commit 36dbf50

Please sign in to comment.