Skip to content

Commit 2617ef1

Browse files
committed
Refactor measurements code
1 parent e28d69e commit 2617ef1

File tree

5 files changed

+134
-129
lines changed

5 files changed

+134
-129
lines changed

src/attestation/measurements.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
use crate::attestation::AttestationError;
2+
use dcap_qvl::quote::Report;
3+
use http::{header::InvalidHeaderValue, HeaderValue};
4+
use std::collections::HashMap;
5+
use thiserror::Error;
6+
7+
/// Measurements determined by the CVM platform
8+
#[derive(Clone, PartialEq, Debug)]
9+
pub struct PlatformMeasurements {
10+
pub mrtd: [u8; 48],
11+
pub rtmr0: [u8; 48],
12+
}
13+
14+
impl PlatformMeasurements {
15+
pub fn from_dcap_qvl_quote(quote: &dcap_qvl::quote::Quote) -> Result<Self, AttestationError> {
16+
let report = match quote.report {
17+
Report::TD10(report) => report,
18+
Report::TD15(report) => report.base,
19+
Report::SgxEnclave(_) => {
20+
return Err(AttestationError::SgxNotSupported);
21+
}
22+
};
23+
Ok(Self {
24+
mrtd: report.mr_td,
25+
rtmr0: report.rt_mr0,
26+
})
27+
}
28+
29+
pub fn from_tdx_quote(quote: &tdx_quote::Quote) -> Self {
30+
Self {
31+
mrtd: quote.mrtd(),
32+
rtmr0: quote.rtmr0(),
33+
}
34+
}
35+
}
36+
37+
/// Measurements determined by the CVM image
38+
#[derive(Clone, PartialEq, Debug)]
39+
pub struct CvmImageMeasurements {
40+
pub rtmr1: [u8; 48],
41+
pub rtmr2: [u8; 48],
42+
pub rtmr3: [u8; 48],
43+
}
44+
45+
impl CvmImageMeasurements {
46+
pub fn from_dcap_qvl_quote(quote: &dcap_qvl::quote::Quote) -> Result<Self, AttestationError> {
47+
let report = match quote.report {
48+
Report::TD10(report) => report,
49+
Report::TD15(report) => report.base,
50+
Report::SgxEnclave(_) => {
51+
return Err(AttestationError::SgxNotSupported);
52+
}
53+
};
54+
Ok(Self {
55+
rtmr1: report.rt_mr1,
56+
rtmr2: report.rt_mr2,
57+
rtmr3: report.rt_mr3,
58+
})
59+
}
60+
61+
pub fn from_tdx_quote(quote: &tdx_quote::Quote) -> Self {
62+
Self {
63+
rtmr1: quote.rtmr1(),
64+
rtmr2: quote.rtmr2(),
65+
rtmr3: quote.rtmr3(),
66+
}
67+
}
68+
}
69+
#[derive(Debug, Clone, PartialEq)]
70+
pub struct Measurements {
71+
pub platform: PlatformMeasurements,
72+
pub cvm_image: CvmImageMeasurements,
73+
}
74+
75+
impl Measurements {
76+
pub fn to_header_format(&self) -> Result<HeaderValue, MeasurementFormatError> {
77+
let mut measurements_map = HashMap::new();
78+
measurements_map.insert(0, hex::encode(self.platform.mrtd));
79+
measurements_map.insert(1, hex::encode(self.platform.rtmr0));
80+
measurements_map.insert(2, hex::encode(self.cvm_image.rtmr1));
81+
measurements_map.insert(3, hex::encode(self.cvm_image.rtmr2));
82+
measurements_map.insert(4, hex::encode(self.cvm_image.rtmr3));
83+
Ok(HeaderValue::from_str(&serde_json::to_string(
84+
&measurements_map,
85+
)?)?)
86+
}
87+
88+
pub fn from_header_format(input: &str) -> Result<Self, MeasurementFormatError> {
89+
let measurements_map: HashMap<u32, String> = serde_json::from_str(input)?;
90+
let measurements_map: HashMap<u32, [u8; 48]> = measurements_map
91+
.into_iter()
92+
.map(|(k, v)| (k, hex::decode(v).unwrap().try_into().unwrap()))
93+
.collect();
94+
95+
Ok(Self {
96+
platform: PlatformMeasurements {
97+
mrtd: *measurements_map
98+
.get(&0)
99+
.ok_or(MeasurementFormatError::MissingValue("MRTD".to_string()))?,
100+
rtmr0: *measurements_map
101+
.get(&1)
102+
.ok_or(MeasurementFormatError::MissingValue("RTMR0".to_string()))?,
103+
},
104+
cvm_image: CvmImageMeasurements {
105+
rtmr1: *measurements_map
106+
.get(&2)
107+
.ok_or(MeasurementFormatError::MissingValue("RTMR1".to_string()))?,
108+
rtmr2: *measurements_map
109+
.get(&3)
110+
.ok_or(MeasurementFormatError::MissingValue("RTMR2".to_string()))?,
111+
rtmr3: *measurements_map
112+
.get(&4)
113+
.ok_or(MeasurementFormatError::MissingValue("RTMR3".to_string()))?,
114+
},
115+
})
116+
}
117+
}
118+
119+
#[derive(Error, Debug)]
120+
pub enum MeasurementFormatError {
121+
#[error("JSON: {0}")]
122+
Json(#[from] serde_json::Error),
123+
#[error("Missing value: {0}")]
124+
MissingValue(String),
125+
#[error("Invalid header value: {0}")]
126+
BadHeaderValue(#[from] InvalidHeaderValue),
127+
}

src/attestation.rs renamed to src/attestation/mod.rs

Lines changed: 3 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
pub mod measurements;
2+
3+
use measurements::{CvmImageMeasurements, Measurements, PlatformMeasurements};
14
use std::{
2-
collections::HashMap,
35
fmt::{self, Display, Formatter},
46
time::SystemTimeError,
57
};
@@ -9,7 +11,6 @@ use dcap_qvl::{
911
collateral::get_collateral_for_fmspc,
1012
quote::{Quote, Report},
1113
};
12-
use http::{header::InvalidHeaderValue, HeaderValue};
1314
use sha2::{Digest, Sha256};
1415
use tdx_quote::QuoteParseError;
1516
use thiserror::Error;
@@ -19,66 +20,6 @@ use x509_parser::prelude::*;
1920
/// For fetching collateral directly from intel, if no PCCS is specified
2021
const PCS_URL: &str = "https://api.trustedservices.intel.com";
2122

22-
#[derive(Debug, Clone, PartialEq)]
23-
pub struct Measurements {
24-
pub platform: PlatformMeasurements,
25-
pub cvm_image: CvmImageMeasurements,
26-
}
27-
28-
impl Measurements {
29-
pub fn to_header_format(&self) -> Result<HeaderValue, MeasurementFormatError> {
30-
let mut measurements_map = HashMap::new();
31-
measurements_map.insert(0, hex::encode(self.platform.mrtd));
32-
measurements_map.insert(1, hex::encode(self.platform.rtmr0));
33-
measurements_map.insert(2, hex::encode(self.cvm_image.rtmr1));
34-
measurements_map.insert(3, hex::encode(self.cvm_image.rtmr2));
35-
measurements_map.insert(4, hex::encode(self.cvm_image.rtmr3));
36-
Ok(HeaderValue::from_str(&serde_json::to_string(
37-
&measurements_map,
38-
)?)?)
39-
}
40-
41-
pub fn from_header_format(input: &str) -> Result<Self, MeasurementFormatError> {
42-
let measurements_map: HashMap<u32, String> = serde_json::from_str(input)?;
43-
let measurements_map: HashMap<u32, [u8; 48]> = measurements_map
44-
.into_iter()
45-
.map(|(k, v)| (k, hex::decode(v).unwrap().try_into().unwrap()))
46-
.collect();
47-
48-
Ok(Self {
49-
platform: PlatformMeasurements {
50-
mrtd: *measurements_map
51-
.get(&0)
52-
.ok_or(MeasurementFormatError::MissingValue("MRTD".to_string()))?,
53-
rtmr0: *measurements_map
54-
.get(&1)
55-
.ok_or(MeasurementFormatError::MissingValue("RTMR0".to_string()))?,
56-
},
57-
cvm_image: CvmImageMeasurements {
58-
rtmr1: *measurements_map
59-
.get(&2)
60-
.ok_or(MeasurementFormatError::MissingValue("RTMR1".to_string()))?,
61-
rtmr2: *measurements_map
62-
.get(&3)
63-
.ok_or(MeasurementFormatError::MissingValue("RTMR2".to_string()))?,
64-
rtmr3: *measurements_map
65-
.get(&4)
66-
.ok_or(MeasurementFormatError::MissingValue("RTMR3".to_string()))?,
67-
},
68-
})
69-
}
70-
}
71-
72-
#[derive(Error, Debug)]
73-
pub enum MeasurementFormatError {
74-
#[error("JSON: {0}")]
75-
Json(#[from] serde_json::Error),
76-
#[error("Missing value: {0}")]
77-
MissingValue(String),
78-
#[error("Invalid header value: {0}")]
79-
BadHeaderValue(#[from] InvalidHeaderValue),
80-
}
81-
8223
/// Type of attestaion used
8324
/// Only supported (or soon-to-be supported) types are given
8425
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -164,69 +105,6 @@ impl QuoteGenerator for DcapTdxQuoteGenerator {
164105
}
165106
}
166107

167-
/// Measurements determined by the CVM platform
168-
#[derive(Clone, PartialEq, Debug)]
169-
pub struct PlatformMeasurements {
170-
pub mrtd: [u8; 48],
171-
pub rtmr0: [u8; 48],
172-
}
173-
174-
impl PlatformMeasurements {
175-
fn from_dcap_qvl_quote(quote: &dcap_qvl::quote::Quote) -> Result<Self, AttestationError> {
176-
let report = match quote.report {
177-
Report::TD10(report) => report,
178-
Report::TD15(report) => report.base,
179-
Report::SgxEnclave(_) => {
180-
return Err(AttestationError::SgxNotSupported);
181-
}
182-
};
183-
Ok(Self {
184-
mrtd: report.mr_td,
185-
rtmr0: report.rt_mr0,
186-
})
187-
}
188-
189-
fn from_tdx_quote(quote: &tdx_quote::Quote) -> Self {
190-
Self {
191-
mrtd: quote.mrtd(),
192-
rtmr0: quote.rtmr0(),
193-
}
194-
}
195-
}
196-
197-
/// Measurements determined by the CVM image
198-
#[derive(Clone, PartialEq, Debug)]
199-
pub struct CvmImageMeasurements {
200-
pub rtmr1: [u8; 48],
201-
pub rtmr2: [u8; 48],
202-
pub rtmr3: [u8; 48],
203-
}
204-
205-
impl CvmImageMeasurements {
206-
fn from_dcap_qvl_quote(quote: &dcap_qvl::quote::Quote) -> Result<Self, AttestationError> {
207-
let report = match quote.report {
208-
Report::TD10(report) => report,
209-
Report::TD15(report) => report.base,
210-
Report::SgxEnclave(_) => {
211-
return Err(AttestationError::SgxNotSupported);
212-
}
213-
};
214-
Ok(Self {
215-
rtmr1: report.rt_mr1,
216-
rtmr2: report.rt_mr2,
217-
rtmr3: report.rt_mr3,
218-
})
219-
}
220-
221-
fn from_tdx_quote(quote: &tdx_quote::Quote) -> Self {
222-
Self {
223-
rtmr1: quote.rtmr1(),
224-
rtmr2: quote.rtmr2(),
225-
rtmr3: quote.rtmr3(),
226-
}
227-
}
228-
}
229-
230108
/// Verify DCAP TDX quotes, allowing them if they have one of a given set of platform-specific and
231109
/// OS image specific measurements
232110
#[derive(Clone)]

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pub mod attestation;
22

3-
use attestation::{AttestationError, AttestationType, Measurements};
3+
use attestation::{measurements::Measurements, AttestationError, AttestationType};
44
pub use attestation::{
55
DcapTdxQuoteGenerator, DcapTdxQuoteVerifier, NoQuoteGenerator, NoQuoteVerifier, QuoteGenerator,
66
QuoteVerifier,
@@ -690,7 +690,7 @@ fn server_name_from_host(
690690

691691
#[cfg(test)]
692692
mod tests {
693-
use crate::attestation::CvmImageMeasurements;
693+
use crate::attestation::measurements::CvmImageMeasurements;
694694

695695
use super::*;
696696
use test_helpers::{

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{fs::File, net::SocketAddr, path::PathBuf};
44
use tokio_rustls::rustls::pki_types::{CertificateDer, PrivateKeyDer};
55

66
use attested_tls_proxy::{
7-
attestation::{AttestationType, CvmImageMeasurements},
7+
attestation::{measurements::CvmImageMeasurements, AttestationType},
88
get_tls_cert, DcapTdxQuoteGenerator, DcapTdxQuoteVerifier, NoQuoteGenerator, NoQuoteVerifier,
99
ProxyClient, ProxyServer, TlsCertAndKey,
1010
};

src/test_helpers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use tokio_rustls::rustls::{
1212
};
1313

1414
use crate::{
15-
attestation::{CvmImageMeasurements, Measurements, PlatformMeasurements},
15+
attestation::measurements::{CvmImageMeasurements, Measurements, PlatformMeasurements},
1616
MEASUREMENT_HEADER,
1717
};
1818

0 commit comments

Comments
 (0)