Skip to content

Commit 063a0bb

Browse files
committed
Doccomments, tidy, PCCS url
1 parent d25143c commit 063a0bb

File tree

3 files changed

+52
-16
lines changed

3 files changed

+52
-16
lines changed

src/attestation.rs

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
1+
use std::time::SystemTimeError;
2+
13
use configfs_tsm::QuoteGenerationError;
24
use dcap_qvl::{
35
collateral::get_collateral_for_fmspc,
46
quote::{Quote, Report},
57
};
68
use sha2::{Digest, Sha256};
9+
use tdx_quote::QuoteParseError;
710
use thiserror::Error;
811
use tokio_rustls::rustls::pki_types::CertificateDer;
912
use x509_parser::prelude::*;
1013

14+
/// For fetching collateral directly from intel, if no PCCS is specified
1115
const PCS_URL: &str = "https://api.trustedservices.intel.com";
1216

17+
/// Defines how to generate a quote
1318
pub trait QuoteGenerator: Clone + Send + 'static {
14-
/// Whether this is CVM attestation. This should always return true except for the [NoAttestation] case.
19+
/// Whether this is CVM attestation. This should always return true except for the [NoQuoteGenerator] case.
1520
///
1621
/// When false, allows TLS client to be configured without client authentication
1722
fn is_cvm(&self) -> bool;
@@ -24,8 +29,9 @@ pub trait QuoteGenerator: Clone + Send + 'static {
2429
) -> Result<Vec<u8>, AttestationError>;
2530
}
2631

32+
/// Defines how to verify a quote
2733
pub trait QuoteVerifier: Clone + Send + 'static {
28-
/// Whether this is CVM attestation. This should always return true except for the [NoAttestation] case.
34+
/// Whether this is CVM attestation. This should always return true except for the [NoQuoteVerifier] case.
2935
///
3036
/// When false, allows TLS client to be configured without client authentication
3137
fn is_cvm(&self) -> bool;
@@ -39,6 +45,7 @@ pub trait QuoteVerifier: Clone + Send + 'static {
3945
) -> impl Future<Output = Result<(), AttestationError>> + Send;
4046
}
4147

48+
/// Quote generation using configfs_tsm
4249
#[derive(Clone)]
4350
pub struct DcapTdxQuoteGenerator;
4451

@@ -120,10 +127,18 @@ impl CvmImageMeasurements {
120127
}
121128
}
122129
}
130+
131+
/// Verify DCAP TDX quotes, allowing them if they have one of a given set of platform-specific and
132+
/// OS image specific measurements
123133
#[derive(Clone)]
124134
pub struct DcapTdxQuoteVerifier {
135+
/// Platform specific allowed Measurements
136+
/// Currently an option as this may be determined internally on a per-platform basis (Eg: GCP)
125137
pub accepted_platform_measurements: Option<Vec<PlatformMeasurements>>,
138+
/// OS-image specific allows measurement - this is effectively a list of allowed OS images
126139
pub accepted_cvm_image_measurements: Vec<CvmImageMeasurements>,
140+
/// URL of a PCCS (defaults to Intel PCS)
141+
pub pccs_url: Option<String>,
127142
}
128143

129144
impl QuoteVerifier for DcapTdxQuoteVerifier {
@@ -140,18 +155,22 @@ impl QuoteVerifier for DcapTdxQuoteVerifier {
140155
let quote_input = compute_report_input(cert_chain, exporter)?;
141156
let (platform_measurements, image_measurements) = if cfg!(not(test)) {
142157
let now = std::time::SystemTime::now()
143-
.duration_since(std::time::UNIX_EPOCH)
144-
.unwrap()
158+
.duration_since(std::time::UNIX_EPOCH)?
145159
.as_secs();
146-
let quote = Quote::parse(&input).unwrap();
147-
let ca = quote.ca().unwrap();
148-
let fmspc = hex::encode_upper(quote.fmspc().unwrap());
149-
let collateral = get_collateral_for_fmspc(PCS_URL, fmspc, ca, false)
150-
.await
151-
.unwrap();
152-
let _verified_report = dcap_qvl::verify::verify(&input, &collateral, now).unwrap();
153-
154-
let quote = Quote::parse(&input).unwrap();
160+
let quote = Quote::parse(&input)?;
161+
162+
let ca = quote.ca()?;
163+
let fmspc = hex::encode_upper(quote.fmspc()?);
164+
let collateral = get_collateral_for_fmspc(
165+
&self.pccs_url.clone().unwrap_or(PCS_URL.to_string()),
166+
fmspc,
167+
ca,
168+
false,
169+
)
170+
.await?;
171+
172+
let _verified_report = dcap_qvl::verify::verify(&input, &collateral, now)?;
173+
155174
let measurements = (
156175
PlatformMeasurements::from_dcap_qvl_quote(&quote)?,
157176
CvmImageMeasurements::from_dcap_qvl_quote(&quote)?,
@@ -162,7 +181,7 @@ impl QuoteVerifier for DcapTdxQuoteVerifier {
162181
measurements
163182
} else {
164183
// In tests we use mock quotes which will fail to verify
165-
let quote = tdx_quote::Quote::from_bytes(&input).unwrap();
184+
let quote = tdx_quote::Quote::from_bytes(&input)?;
166185
if quote.report_input_data() != quote_input {
167186
return Err(AttestationError::InputMismatch);
168187
}
@@ -176,15 +195,16 @@ impl QuoteVerifier for DcapTdxQuoteVerifier {
176195
if let Some(accepted_platform_measurements) = &self.accepted_platform_measurements
177196
&& !accepted_platform_measurements.contains(&platform_measurements)
178197
{
179-
panic!("Bad measurements");
198+
return Err(AttestationError::UnacceptablePlatformMeasurements);
180199
}
181200

182201
if !self
183202
.accepted_cvm_image_measurements
184203
.contains(&image_measurements)
185204
{
186-
panic!("Bad measurements");
205+
return Err(AttestationError::UnacceptableOsImageMeasurements);
187206
}
207+
188208
Ok(())
189209
}
190210
}
@@ -304,4 +324,14 @@ pub enum AttestationError {
304324
QuoteGeneration(#[from] configfs_tsm::QuoteGenerationError),
305325
#[error("SGX quote given when TDX quote expected")]
306326
SgxNotSupported,
327+
#[error("Platform measurements do not match any accepted values")]
328+
UnacceptablePlatformMeasurements,
329+
#[error("OS image measurements do not match any accepted values")]
330+
UnacceptableOsImageMeasurements,
331+
#[error("System Time: {0}")]
332+
SystemTime(#[from] SystemTimeError),
333+
#[error("DCAP quote verification: {0}")]
334+
DcapQvl(#[from] anyhow::Error),
335+
#[error("Quote parse: {0}")]
336+
QuoteParse(#[from] QuoteParseError),
307337
}

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ mod tests {
536536
rtmr2: [0u8; 48],
537537
rtmr3: [0u8; 48],
538538
}],
539+
pccs_url: None,
539540
};
540541

541542
tokio::spawn(async move {
@@ -595,6 +596,7 @@ mod tests {
595596
rtmr2: [0u8; 48],
596597
rtmr3: [0u8; 48],
597598
}],
599+
pccs_url: None,
598600
};
599601

600602
let proxy_server = ProxyServer::new_with_tls_config(
@@ -672,6 +674,7 @@ mod tests {
672674
rtmr2: [0u8; 48],
673675
rtmr3: [0u8; 48],
674676
}],
677+
pccs_url: None,
675678
};
676679

677680
let proxy_client = ProxyClient::new_with_tls_config(
@@ -730,6 +733,7 @@ mod tests {
730733
rtmr2: [0u8; 48],
731734
rtmr3: [0u8; 48],
732735
}],
736+
pccs_url: None,
733737
};
734738

735739
let retrieved_chain =

src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ async fn main() -> anyhow::Result<()> {
8787
rtmr2: [0u8; 48],
8888
rtmr3: [0u8; 48],
8989
}],
90+
pccs_url: None,
9091
};
9192

9293
let client = ProxyClient::new(
@@ -139,6 +140,7 @@ async fn main() -> anyhow::Result<()> {
139140
rtmr2: [0u8; 48],
140141
rtmr3: [0u8; 48],
141142
}],
143+
pccs_url: None,
142144
};
143145
let cert_chain = get_tls_cert(server, quote_verifier).await?;
144146
println!("{}", certs_to_pem_string(&cert_chain)?);

0 commit comments

Comments
 (0)