Skip to content

Commit 9bd2bc7

Browse files
committed
Add attestation type detection
1 parent ddd3015 commit 9bd2bc7

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

src/attestation/mod.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,23 @@ impl AttestationType {
6666
AttestationType::DcapTdx => "dcap-tdx",
6767
}
6868
}
69+
70+
/// Detect what platform we are on by attempting an attestation
71+
pub async fn detect() -> Self {
72+
// First attempt azure, if the feature is present
73+
#[cfg(feature = "azure")]
74+
{
75+
if azure::create_azure_attestation([0; 64]).await.is_ok() {
76+
return AttestationType::AzureTdx;
77+
}
78+
}
79+
// Otherwise try DCAP quote - this internally checks that the quote provider is `tdx_guest`
80+
if configfs_tsm::create_tdx_quote([0; 64]).is_ok() {
81+
// TODO Possibly also check if it looks like we are on GCP (eg: hit metadata API)
82+
return AttestationType::DcapTdx;
83+
}
84+
AttestationType::None
85+
}
6986
}
7087

7188
/// SCALE encode (used over the wire)
@@ -99,6 +116,25 @@ pub struct AttestationGenerator {
99116
}
100117

101118
impl AttestationGenerator {
119+
/// Create an [AttestationGenerator] detecting the attestation type if it is specified as 'auto'
120+
pub async fn new_with_detection(
121+
attestation_type_string: Option<String>,
122+
dummy_dcap_url: Option<String>,
123+
) -> Result<Self, AttestationError> {
124+
let attestaton_type = if attestation_type_string.as_deref() == Some("auto") {
125+
tracing::info!("Doing attestation type detection...");
126+
AttestationType::detect().await
127+
} else {
128+
serde_json::from_value(serde_json::Value::String(
129+
attestation_type_string.unwrap_or("none".to_string()),
130+
))
131+
.unwrap()
132+
};
133+
tracing::info!("Local platform: {attestaton_type}");
134+
135+
Self::new(attestaton_type, dummy_dcap_url)
136+
}
137+
102138
pub fn new(
103139
attestation_type: AttestationType,
104140
dummy_dcap_url: Option<String>,
@@ -116,6 +152,8 @@ impl AttestationGenerator {
116152
}
117153
}
118154

155+
/// Create an [AttestationGenerator] without a given dummy DCAP url - meaning Dummy attestation
156+
/// type will not be possible
119157
pub fn new_not_dummy(attestation_type: AttestationType) -> Result<Self, AttestationError> {
120158
if attestation_type == AttestationType::Dummy {
121159
return Err(AttestationError::DummyUrl);
@@ -127,6 +165,7 @@ impl AttestationGenerator {
127165
})
128166
}
129167

168+
/// Create a dummy [AttestationGenerator]
130169
pub fn new_dummy(dummy_dcap_url: Option<String>) -> Result<Self, AttestationError> {
131170
match dummy_dcap_url {
132171
Some(url) => {
@@ -181,6 +220,9 @@ impl AttestationGenerator {
181220
}
182221
}
183222

223+
/// Generate a dummy attestaion by using an external service for the attestation generation
224+
///
225+
/// This is for testing only
184226
async fn generate_dummy_attestation(
185227
&self,
186228
input_data: [u8; 64],
@@ -351,3 +393,14 @@ pub enum AttestationError {
351393
#[error("Dummy server: {0}")]
352394
DummyServer(String),
353395
}
396+
397+
#[cfg(test)]
398+
mod tests {
399+
use super::*;
400+
401+
#[tokio::test]
402+
async fn attestation_detection_does_not_panic() {
403+
// We dont enforce what platform the test is run on, only that the function does not panic
404+
let _ = AttestationGenerator::new_with_detection(Some("auto".to_string()), None).await;
405+
}
406+
}

0 commit comments

Comments
 (0)