Skip to content

Commit 251862e

Browse files
committed
WIP - read remote measurements from JSON file
1 parent c907f62 commit 251862e

File tree

6 files changed

+158
-53
lines changed

6 files changed

+158
-53
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ http-body-util = "0.1.3"
2626
bytes = "1.10.1"
2727
http = "1.3.1"
2828
serde_json = "1.0.145"
29+
serde = "1.0.228"
2930

3031
[dev-dependencies]
3132
rcgen = "0.14.5"

src/attestation.rs

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use std::{
2-
collections::HashMap,
3-
fmt::{self, Display, Formatter},
4-
time::SystemTimeError,
2+
collections::HashMap, fmt::{self, Display, Formatter}, path::PathBuf, sync::Arc, time::SystemTimeError
53
};
64

75
use configfs_tsm::QuoteGenerationError;
@@ -15,6 +13,9 @@ use tdx_quote::QuoteParseError;
1513
use thiserror::Error;
1614
use tokio_rustls::rustls::pki_types::CertificateDer;
1715
use x509_parser::prelude::*;
16+
use serde::Deserialize;
17+
18+
use crate::test_helpers::default_measurements;
1819

1920
/// For fetching collateral directly from intel, if no PCCS is specified
2021
const PCS_URL: &str = "https://api.trustedservices.intel.com";
@@ -79,6 +80,39 @@ pub enum MeasurementFormatError {
7980
BadHeaderValue(#[from] InvalidHeaderValue),
8081
}
8182

83+
#[derive(Debug)]
84+
pub struct MeasurementRecord {
85+
measurement_id: String,
86+
attestation_type: AttestationType,
87+
measurements: Measurements,
88+
}
89+
90+
#[derive(Debug, Deserialize)]
91+
struct MeasurementRecordSimple {
92+
measurement_id: String,
93+
attestation_type: String,
94+
measurements: HashMap<String, MeasurementEntry>,
95+
}
96+
97+
#[derive(Debug, Deserialize)]
98+
struct MeasurementEntry {
99+
expected: String,
100+
}
101+
102+
pub async fn get_measurements_from_file(measurement_file: PathBuf) -> Vec<MeasurementRecord> {
103+
let measurements_json = tokio::fs::read(measurement_file).await.unwrap();
104+
let measurements_simple: Vec<MeasurementRecordSimple> = serde_json::from_slice(&measurements_json).unwrap();
105+
let measurements = Vec::new();
106+
for measurement in measurements_simple {
107+
measurements.push(MeasurementRecord {
108+
measurement_id: measurement.measurement_id,
109+
attestation_type: AttestationType::from_str(&measurement.attestation_type).unwrap(),
110+
measurements: Measurements { platform: PlatformMeasurements { mrtd: (), rtmr0: () }, cvm_image: CvmImageMeasurements { rtmr1: (), rtmr2: (), rtmr3: () } }
111+
});
112+
}
113+
measurements
114+
}
115+
82116
/// Type of attestaion used
83117
/// Only supported (or soon-to-be supported) types are given
84118
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -106,6 +140,26 @@ impl AttestationType {
106140
AttestationType::GcpTdx => "gcp-tdx",
107141
}
108142
}
143+
144+
pub fn from_str(input: &str) -> Result<Self, AttestationError> {
145+
match input {
146+
"none" => Ok(Self::None),
147+
"dummy" => Ok(Self::Dummy),
148+
"azure-tdx" => Ok(Self::AzureTdx),
149+
"qemu-tdx" => Ok(Self::QemuTdx),
150+
"gcp-tdx" => Ok(Self::GcpTdx),
151+
_ => Err(AttestationError::AttestationTypeNotSupported)
152+
}
153+
}
154+
155+
pub fn get_quote_generator(&self) -> Result<Arc<dyn QuoteGenerator>, AttestationError> {
156+
match self {
157+
AttestationType::None => Ok(Arc::new(NoQuoteGenerator)),
158+
AttestationType::AzureTdx => Err(AttestationError::AttestationTypeNotSupported),
159+
AttestationType::Dummy => Err(AttestationError::AttestationTypeNotSupported),
160+
_ => Ok(Arc::new(DcapTdxQuoteGenerator { attestation_type: *self })),
161+
}
162+
}
109163
}
110164

111165
impl Display for AttestationType {
@@ -115,7 +169,7 @@ impl Display for AttestationType {
115169
}
116170

117171
/// Defines how to generate a quote
118-
pub trait QuoteGenerator: Clone + Send + 'static {
172+
pub trait QuoteGenerator: Send + Sync + 'static {
119173
/// Type of attestation used
120174
fn attestation_type(&self) -> AttestationType;
121175

@@ -441,4 +495,6 @@ pub enum AttestationError {
441495
DcapQvl(#[from] anyhow::Error),
442496
#[error("Quote parse: {0}")]
443497
QuoteParse(#[from] QuoteParseError),
498+
#[error("Attestation type not supported")]
499+
AttestationTypeNotSupported,
444500
}

src/lib.rs

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,26 +47,24 @@ pub struct TlsCertAndKey {
4747
}
4848

4949
/// Inner struct used by [ProxyClient] and [ProxyServer]
50-
struct Proxy<L, R>
50+
struct Proxy<R>
5151
where
52-
L: QuoteGenerator,
5352
R: QuoteVerifier,
5453
{
5554
/// The underlying TCP listener
5655
listener: TcpListener,
5756
/// Quote generation type to use (including none)
58-
local_quote_generator: L,
57+
local_quote_generator: Arc<dyn QuoteGenerator>,
5958
/// Verifier for remote attestation (including none)
6059
remote_quote_verifier: R,
6160
}
6261

6362
/// A TLS over TCP server which provides an attestation before forwarding traffic to a given target address
64-
pub struct ProxyServer<L, R>
63+
pub struct ProxyServer<R>
6564
where
66-
L: QuoteGenerator,
6765
R: QuoteVerifier,
6866
{
69-
inner: Proxy<L, R>,
67+
inner: Proxy<R>,
7068
/// The certificate chain
7169
cert_chain: Vec<CertificateDer<'static>>,
7270
/// For accepting TLS connections
@@ -75,12 +73,12 @@ where
7573
target: SocketAddr,
7674
}
7775

78-
impl<L: QuoteGenerator, R: QuoteVerifier> ProxyServer<L, R> {
76+
impl<R: QuoteVerifier> ProxyServer<R> {
7977
pub async fn new(
8078
cert_and_key: TlsCertAndKey,
8179
local: impl ToSocketAddrs,
8280
target: SocketAddr,
83-
local_quote_generator: L,
81+
local_quote_generator: Arc<dyn QuoteGenerator>,
8482
remote_quote_verifier: R,
8583
client_auth: bool,
8684
) -> Result<Self, ProxyError> {
@@ -121,7 +119,7 @@ impl<L: QuoteGenerator, R: QuoteVerifier> ProxyServer<L, R> {
121119
server_config: Arc<ServerConfig>,
122120
local: impl ToSocketAddrs,
123121
target: SocketAddr,
124-
local_quote_generator: L,
122+
local_quote_generator: Arc<dyn QuoteGenerator>,
125123
remote_quote_verifier: R,
126124
) -> Result<Self, ProxyError> {
127125
let acceptor = tokio_rustls::TlsAcceptor::from(server_config);
@@ -177,7 +175,7 @@ impl<L: QuoteGenerator, R: QuoteVerifier> ProxyServer<L, R> {
177175
acceptor: TlsAcceptor,
178176
target: SocketAddr,
179177
cert_chain: Vec<CertificateDer<'static>>,
180-
local_quote_generator: L,
178+
local_quote_generator: Arc<dyn QuoteGenerator>,
181179
remote_quote_verifier: R,
182180
) -> Result<(), ProxyError> {
183181
let mut tls_stream = acceptor.accept(inbound).await?;
@@ -303,25 +301,24 @@ fn full<T: Into<Bytes>>(chunk: T) -> BoxBody<Bytes, hyper::Error> {
303301
.boxed()
304302
}
305303

306-
pub struct ProxyClient<L, R>
304+
pub struct ProxyClient<R>
307305
where
308-
L: QuoteGenerator,
309306
R: QuoteVerifier,
310307
{
311-
inner: Proxy<L, R>,
308+
inner: Proxy<R>,
312309
connector: TlsConnector,
313310
/// The host and port of the proxy server
314311
target: String,
315312
/// Certificate chain for client auth
316313
cert_chain: Option<Vec<CertificateDer<'static>>>,
317314
}
318315

319-
impl<L: QuoteGenerator, R: QuoteVerifier> ProxyClient<L, R> {
316+
impl<R: QuoteVerifier> ProxyClient<R> {
320317
pub async fn new(
321318
cert_and_key: Option<TlsCertAndKey>,
322319
address: impl ToSocketAddrs,
323320
server_name: String,
324-
local_quote_generator: L,
321+
local_quote_generator: Arc<dyn QuoteGenerator>,
325322
remote_quote_verifier: R,
326323
) -> Result<Self, ProxyError> {
327324
if local_quote_generator.attestation_type() != AttestationType::None
@@ -363,7 +360,7 @@ impl<L: QuoteGenerator, R: QuoteVerifier> ProxyClient<L, R> {
363360
client_config: Arc<ClientConfig>,
364361
local: impl ToSocketAddrs,
365362
target_name: String,
366-
local_quote_generator: L,
363+
local_quote_generator: Arc<dyn QuoteGenerator>,
367364
remote_quote_verifier: R,
368365
cert_chain: Option<Vec<CertificateDer<'static>>>,
369366
) -> Result<Self, ProxyError> {
@@ -423,7 +420,7 @@ impl<L: QuoteGenerator, R: QuoteVerifier> ProxyClient<L, R> {
423420
connector: TlsConnector,
424421
target: String,
425422
cert_chain: Option<Vec<CertificateDer<'static>>>,
426-
local_quote_generator: L,
423+
local_quote_generator: Arc<dyn QuoteGenerator>,
427424
remote_quote_verifier: R,
428425
) -> Result<(), ProxyError> {
429426
let http = Builder::new();
@@ -467,7 +464,7 @@ impl<L: QuoteGenerator, R: QuoteVerifier> ProxyClient<L, R> {
467464
connector: TlsConnector,
468465
target: String,
469466
cert_chain: Option<Vec<CertificateDer<'static>>>,
470-
local_quote_generator: L,
467+
local_quote_generator: Arc<dyn QuoteGenerator>,
471468
remote_quote_verifier: R,
472469
) -> Result<
473470
(
@@ -528,7 +525,7 @@ impl<L: QuoteGenerator, R: QuoteVerifier> ProxyClient<L, R> {
528525
connector: TlsConnector,
529526
target: String,
530527
cert_chain: Option<Vec<CertificateDer<'static>>>,
531-
local_quote_generator: L,
528+
local_quote_generator: Arc<dyn QuoteGenerator>,
532529
remote_quote_verifier: R,
533530
) -> Result<Response<BoxBody<bytes::Bytes, hyper::Error>>, ProxyError> {
534531
let remote_attestation_type = remote_quote_verifier.attestation_type();
@@ -710,9 +707,9 @@ mod tests {
710707
server_config,
711708
"127.0.0.1:0",
712709
target_addr,
713-
DcapTdxQuoteGenerator {
710+
Arc::new(DcapTdxQuoteGenerator {
714711
attestation_type: AttestationType::Dummy,
715-
},
712+
}),
716713
NoQuoteVerifier,
717714
)
718715
.await
@@ -739,7 +736,7 @@ mod tests {
739736
client_config,
740737
"127.0.0.1:0".to_string(),
741738
proxy_addr.to_string(),
742-
NoQuoteGenerator,
739+
Arc::new(NoQuoteGenerator),
743740
quote_verifier,
744741
None,
745742
)
@@ -807,9 +804,9 @@ mod tests {
807804
server_tls_server_config,
808805
"127.0.0.1:0",
809806
target_addr,
810-
DcapTdxQuoteGenerator {
807+
Arc::new(DcapTdxQuoteGenerator {
811808
attestation_type: AttestationType::Dummy,
812-
},
809+
}),
813810
quote_verifier.clone(),
814811
)
815812
.await
@@ -825,9 +822,9 @@ mod tests {
825822
client_tls_client_config,
826823
"127.0.0.1:0",
827824
proxy_addr.to_string(),
828-
DcapTdxQuoteGenerator {
825+
Arc::new(DcapTdxQuoteGenerator {
829826
attestation_type: AttestationType::Dummy,
830-
},
827+
}),
831828
quote_verifier,
832829
Some(client_cert_chain),
833830
)
@@ -876,9 +873,9 @@ mod tests {
876873
server_config,
877874
"127.0.0.1:0",
878875
target_addr,
879-
DcapTdxQuoteGenerator {
876+
Arc::new(DcapTdxQuoteGenerator {
880877
attestation_type: AttestationType::Dummy,
881-
},
878+
}),
882879
NoQuoteVerifier,
883880
)
884881
.await

0 commit comments

Comments
 (0)