Skip to content

Commit

Permalink
Merge pull request #9 from hairongchen/rust_sdk_enhancement
Browse files Browse the repository at this point in the history
  • Loading branch information
wenhuizhang authored Feb 28, 2024
2 parents 35be015 + 63d8249 commit 551f0ec
Show file tree
Hide file tree
Showing 6 changed files with 315 additions and 78 deletions.
17 changes: 10 additions & 7 deletions sdk/rust/cctrusted_ccnp/proto/ccnp-server.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,30 @@ message GetMeasurementCountResponse {
}

message GetCcReportRequest {
string user_data = 1;
string nonce = 2;
string container_id = 1;
optional string user_data = 2;
optional string nonce = 3;
}

message GetCcReportResponse {
uint32 cc_type = 1;
int32 cc_type = 1;
bytes cc_report = 2;
}

message GetCcMeasurementRequest {
uint32 index = 1;
uint32 algo_id = 2;
string container_id = 1;
uint32 index = 2;
uint32 algo_id = 3;
}

message GetCcMeasurementResponse {
TcgDigest measurement = 1;
}

message GetCcEventlogRequest {
uint32 start = 1;
uint32 count = 2;
string container_id = 1;
optional uint32 start = 2;
optional uint32 count = 3;
}

message TcgDigest {
Expand Down
179 changes: 167 additions & 12 deletions sdk/rust/cctrusted_ccnp/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
use crate::client::ccnp_server_pb::{
ccnp_client::CcnpClient, GetCcEventlogRequest, GetCcEventlogResponse, GetCcMeasurementRequest,
GetCcMeasurementResponse, GetCcReportRequest, GetCcReportResponse,
GetCcMeasurementResponse, GetCcReportRequest, GetCcReportResponse, GetDefaultAlgorithmRequest,
GetDefaultAlgorithmResponse, GetMeasurementCountRequest, GetMeasurementCountResponse,
};
use anyhow::anyhow;
use cctrusted_base::api_data::ExtraArgs;
use cctrusted_base::cc_type::TeeType;
use core::result::Result::Ok;
use hashbrown::HashMap;
use std::fs::read_to_string;
use tokio::net::UnixStream;
use tonic::transport::{Endpoint, Uri};
use tonic::Request;
use tower::service_fn;

//FixMe: use map from cc_type
lazy_static! {
pub static ref TEE_VALUE_TYPE_MAP: HashMap<u32, TeeType> = {
let mut map: HashMap<u32, TeeType> = HashMap::new();
pub static ref TEE_VALUE_TYPE_MAP: HashMap<i32, TeeType> = {
let mut map: HashMap<i32, TeeType> = HashMap::new();
map.insert(-1, TeeType::PLAIN);
map.insert(0, TeeType::TPM);
map.insert(1, TeeType::TDX);
map.insert(2, TeeType::SEV);
Expand All @@ -25,9 +28,6 @@ lazy_static! {

pub mod ccnp_server_pb {
tonic::include_proto!("ccnp_server_pb");

pub(crate) const FILE_DESCRIPTOR_SET: &[u8] =
tonic::include_file_descriptor_set!("ccnp_server_descriptor");
}

pub struct CcnpServiceClient {
Expand All @@ -50,9 +50,20 @@ impl CcnpServiceClient {
.await
.unwrap();

let container_id = match self.get_container_id() {
Ok(id) => id,
Err(e) => {
return Err(anyhow!(
"[get_cc_report_from_server_async] error getting the container ID: {:?}",
e
));
}
};

let request = Request::new(GetCcReportRequest {
nonce: nonce.unwrap(),
user_data: data.unwrap(),
container_id,
nonce,
user_data: data,
});

let mut ccnp_client = CcnpClient::new(channel);
Expand Down Expand Up @@ -80,7 +91,7 @@ impl CcnpServiceClient {
response
}

pub fn get_tee_type_by_value(&self, tee_id: &u32) -> TeeType {
pub fn get_tee_type_by_value(&self, tee_id: &i32) -> TeeType {
match TEE_VALUE_TYPE_MAP.get(tee_id) {
Some(tee_type) => tee_type.clone(),
None => TeeType::PLAIN,
Expand All @@ -101,7 +112,18 @@ impl CcnpServiceClient {
.await
.unwrap();

let container_id = match self.get_container_id() {
Ok(id) => id,
Err(e) => {
return Err(anyhow!(
"[get_cc_measurement_from_server_async] error getting the container ID: {:?}",
e
));
}
};

let request = Request::new(GetCcMeasurementRequest {
container_id,
index: index.into(),
algo_id: algo_id.into(),
});
Expand Down Expand Up @@ -144,9 +166,20 @@ impl CcnpServiceClient {
.await
.unwrap();

let container_id = match self.get_container_id() {
Ok(id) => id,
Err(e) => {
return Err(anyhow!(
"[get_cc_eventlog_from_server_async] error getting the container ID: {:?}",
e
));
}
};

let request = Request::new(GetCcEventlogRequest {
start: start.unwrap(),
count: count.unwrap(),
container_id,
start,
count,
});

let mut ccnp_client = CcnpClient::new(channel);
Expand All @@ -172,4 +205,126 @@ impl CcnpServiceClient {
.block_on(self.get_cc_eventlog_from_server_async(start, count));
response
}

async fn get_cc_measurement_count_from_server_async(
&mut self,
) -> Result<GetMeasurementCountResponse, anyhow::Error> {
let uds_path = self.ccnp_uds_path.parse::<Uri>().unwrap();
let channel = Endpoint::try_from("http://[::]:0")
.unwrap()
.connect_with_connector(service_fn(move |_: Uri| {
UnixStream::connect(uds_path.to_string())
}))
.await
.unwrap();

let request = Request::new(GetMeasurementCountRequest {});

let mut ccnp_client = CcnpClient::new(channel);

let response = ccnp_client
.get_measurement_count(request)
.await
.unwrap()
.into_inner();
Ok(response)
}

// turn async call to sync call
pub fn get_cc_measurement_count_from_server(
&mut self,
) -> Result<GetMeasurementCountResponse, anyhow::Error> {
let response = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap()
.block_on(self.get_cc_measurement_count_from_server_async());
response
}

async fn get_cc_default_algorithm_from_server_async(
&mut self,
) -> Result<GetDefaultAlgorithmResponse, anyhow::Error> {
let uds_path = self.ccnp_uds_path.parse::<Uri>().unwrap();
let channel = Endpoint::try_from("http://[::]:0")
.unwrap()
.connect_with_connector(service_fn(move |_: Uri| {
UnixStream::connect(uds_path.to_string())
}))
.await
.unwrap();

let request = Request::new(GetDefaultAlgorithmRequest {});

let mut ccnp_client = CcnpClient::new(channel);

let response = ccnp_client
.get_default_algorithm(request)
.await
.unwrap()
.into_inner();
Ok(response)
}

// turn async call to sync call
pub fn get_cc_default_algorithm_from_server(
&mut self,
) -> Result<GetDefaultAlgorithmResponse, anyhow::Error> {
let response = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap()
.block_on(self.get_cc_default_algorithm_from_server_async());
response
}

pub fn get_container_id(&self) -> Result<String, anyhow::Error> {
let mountinfo = "/proc/self/mountinfo".to_string();
let docker_pattern = "/docker/containers/";
let k8s_pattern = "/kubelet/pods/";

let data_lines: Vec<String> = read_to_string(mountinfo)
.unwrap()
.lines()
.map(String::from)
.collect();

for line in data_lines {
/*
* line format:
* ... /var/lib/docker/containers/{container-id}/{file} ...
* sample:
*/
if line.contains(docker_pattern) {
let element = line.split(docker_pattern).last();
if element.is_some() {
let (id, _) = element.unwrap().split_once('/').unwrap();
return Ok(id.to_string());
} else {
return Err(anyhow!("[get_container_id] incorrect docker container info in /proc/self/mountinfo!"));
}
}

/*
* line format:
* ... /var/lib/kubelet/pods/{container-id}/{file} ...
* sample:
* 2958 2938 253:1 /var/lib/kubelet/pods/a45f46f0-20be-45ab-ace6-b77e8e2f062c/containers/busybox/8f8d892c /dev/termination-log rw,relatime - ext4 /dev/vda1 rw,discard,errors=remount-ro
*/
if line.contains(k8s_pattern) {
let element = line.split(k8s_pattern).last();
if element.is_some() {
let (left, _) = element.unwrap().split_once('/').unwrap();
let id = left.replace('-', "_");
return Ok(id);
} else {
return Err(anyhow!("[get_container_id] incorrect k8s pod container info in /proc/self/mountinfo!"));
}
}
}

Err(anyhow!(
"[get_container_id] no container info in /proc/self/mountinfo!"
))
}
}
48 changes: 40 additions & 8 deletions sdk/rust/cctrusted_ccnp/src/sdk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,31 @@ impl CCTrustedApi for API {
})
}

// CCTrustedApi trait function: dump report of a CVM in hex and char format
// CCTrustedApi trait function: dump report of in hex and char format
fn dump_cc_report(report: &Vec<u8>) {
dump_data(report)
}

// CCTrustedApi trait function: get max number of CVM IMRs
// CCTrustedApi trait function: get max number of IMRs
fn get_measurement_count() -> Result<u8, anyhow::Error> {
todo!()
let mut ccnp_service_client = CcnpServiceClient {
ccnp_uds_path: UDS_PATH.to_string(),
};

let response = match ccnp_service_client.get_cc_measurement_count_from_server() {
Ok(r) => r,
Err(e) => {
return Err(anyhow!(
"[get_measurement_count] err get cc measurement count: {:?}",
e
));
}
};

Ok(response.count.try_into().unwrap())
}

// CCTrustedApi trait function: get measurements of a CVM
// CCTrustedApi trait function: get measurements
fn get_cc_measurement(index: u8, algo_id: u16) -> Result<TcgDigest, anyhow::Error> {
let mut ccnp_service_client = CcnpServiceClient {
ccnp_uds_path: UDS_PATH.to_string(),
Expand All @@ -74,7 +88,7 @@ impl CCTrustedApi for API {
})
}

// CCTrustedApi trait function: get eventlogs of a CVM
// CCTrustedApi trait function: get eventlogs
fn get_cc_eventlog(
start: Option<u32>,
count: Option<u32>,
Expand Down Expand Up @@ -122,15 +136,33 @@ impl CCTrustedApi for API {
Ok(event_logs)
}

// CCTrustedApi trait function: replay eventlogs of a CVM
// CCTrustedApi trait function: replay eventlogs
fn replay_cc_eventlog(
eventlogs: Vec<EventLogEntry>,
) -> Result<Vec<ReplayResult>, anyhow::Error> {
EventLogs::replay(eventlogs)
}

// CCTrustedApi trait function: get default algorithm of a CVM
// CCTrustedApi trait function: get default algorithm
fn get_default_algorithm() -> Result<Algorithm, anyhow::Error> {
todo!()
let mut ccnp_service_client = CcnpServiceClient {
ccnp_uds_path: UDS_PATH.to_string(),
};

let response = match ccnp_service_client.get_cc_default_algorithm_from_server() {
Ok(r) => r,
Err(e) => {
return Err(anyhow!(
"[get_default_algorithm] err get cc get default algorithm: {:?}",
e
));
}
};

let algo_id = response.algo_id as u16;
Ok(Algorithm {
algo_id,
algo_id_str: ALGO_NAME_MAP.get(&algo_id).unwrap().to_owned(),
})
}
}
Loading

0 comments on commit 551f0ec

Please sign in to comment.