Skip to content

Commit ca4760b

Browse files
committed
feat(server): implement tee info and attestation endpoints
1 parent 4119479 commit ca4760b

9 files changed

Lines changed: 442 additions & 7 deletions

File tree

Cargo.lock

Lines changed: 132 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,11 @@ clap = "4.4.18"
106106
serial_test = "3.2"
107107
color-eyre = "0.6.2"
108108
comfy-table = "7.0"
109+
configfs-tsm = "0.0.2"
109110
const_format = "0.2.32"
110111
curve25519-dalek = "4.1.3"
111112
dashmap = "6.1.0"
113+
dcap-qvl = "0.3"
112114
dirs = "5.0.1"
113115
ed25519-consensus = "2.1.0"
114116
ed25519-dalek = "2.1.1"
@@ -168,6 +170,8 @@ starknet-types-core = "0.2.0"
168170
strum = "0.26.2"
169171
syn = { version = "2.0", features = ["full"] }
170172
tempdir = "0.3.7"
173+
tdx-quote = "0.0.4"
174+
tdx_workload_attestation = "0.1.0"
171175
thiserror = "1.0.56"
172176
thunderdome = "0.6.1"
173177
tokio = "1.47.1"

crates/server/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ publish = true
1010

1111
[dependencies]
1212
axum = { workspace = true, features = ["multipart", "ws", "tokio"] }
13+
base64.workspace = true
1314
eyre.workspace = true
1415
futures-util.workspace = true
1516
hex.workspace = true
@@ -36,6 +37,10 @@ calimero-primitives.workspace = true
3637
calimero-server-primitives.workspace = true
3738
calimero-store = { workspace = true, features = ["serde"] }
3839

40+
[target.'cfg(target_os = "linux")'.dependencies]
41+
configfs-tsm.workspace = true
42+
tdx_workload_attestation = { workspace = true, features = ["tdx-linux"] }
43+
3944
[dev-dependencies]
4045
color-eyre.workspace = true
4146
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }

crates/server/primitives/src/admin.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,3 +1069,75 @@ impl SyncContextResponse {
10691069
Self { data: Empty {} }
10701070
}
10711071
}
1072+
1073+
// -------------------------------------------- TEE API --------------------------------------------
1074+
1075+
#[derive(Debug, Deserialize)]
1076+
#[serde(rename_all = "camelCase")]
1077+
pub struct TeeAttestRequest {
1078+
/// Client-provided nonce for freshness (32 bytes as hex string)
1079+
pub nonce: String,
1080+
/// Optional application ID to include in attestation
1081+
/// If provided, the application's bytecode BlobId (hash) will be included in report_data
1082+
pub application_id: Option<ApplicationId>,
1083+
}
1084+
1085+
impl TeeAttestRequest {
1086+
pub fn new(nonce: String, application_id: Option<ApplicationId>) -> Self {
1087+
Self {
1088+
nonce,
1089+
application_id,
1090+
}
1091+
}
1092+
}
1093+
1094+
#[derive(Debug, Serialize)]
1095+
#[serde(rename_all = "camelCase")]
1096+
pub struct TeeInfoResponseData {
1097+
/// Cloud provider (e.g., "gcp", "azure", "unknown")
1098+
pub cloud_provider: String,
1099+
/// OS image name (e.g., "ubuntu-2404-tdx-v20250115")
1100+
pub os_image: String,
1101+
/// MRTD extracted from TD report (48 bytes hex)
1102+
pub mrtd: String,
1103+
}
1104+
1105+
#[derive(Debug, Serialize)]
1106+
#[serde(rename_all = "camelCase")]
1107+
pub struct TeeInfoResponse {
1108+
pub data: TeeInfoResponseData,
1109+
}
1110+
1111+
impl TeeInfoResponse {
1112+
pub fn new(cloud_provider: String, os_image: String, mrtd: String) -> Self {
1113+
Self {
1114+
data: TeeInfoResponseData {
1115+
cloud_provider,
1116+
os_image,
1117+
mrtd,
1118+
},
1119+
}
1120+
}
1121+
}
1122+
1123+
#[derive(Debug, Serialize)]
1124+
#[serde(rename_all = "camelCase")]
1125+
pub struct TeeAttestResponseData {
1126+
/// Base64-encoded TDX quote
1127+
/// The quote contains the report_data which the client must verify
1128+
pub quote_b64: String,
1129+
}
1130+
1131+
#[derive(Debug, Serialize)]
1132+
#[serde(rename_all = "camelCase")]
1133+
pub struct TeeAttestResponse {
1134+
pub data: TeeAttestResponseData,
1135+
}
1136+
1137+
impl TeeAttestResponse {
1138+
pub fn new(quote_b64: String) -> Self {
1139+
Self {
1140+
data: TeeAttestResponseData { quote_b64 },
1141+
}
1142+
}
1143+
}

crates/server/src/admin/handlers.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ pub mod list_versions;
99
pub mod packages;
1010
pub mod peers;
1111
pub mod proposals;
12+
pub mod tee;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use axum::routing::{get, post};
2+
use axum::Router;
3+
4+
mod attestation;
5+
mod info;
6+
7+
pub fn service() -> Router {
8+
Router::new()
9+
.route("/info", get(info::handler))
10+
.route("/attest", post(attestation::handler))
11+
}

0 commit comments

Comments
 (0)