From 24ec339fdefda26ca940b19b5840cfa3d958880d Mon Sep 17 00:00:00 2001 From: peg Date: Thu, 26 Feb 2026 11:56:36 +0100 Subject: [PATCH 1/2] Add json measurement output option and tdx attestation type --- attested-tls/src/attestation/measurements.rs | 12 +++++++ attested-tls/src/lib.rs | 11 +++--- src/lib.rs | 4 +-- src/main.rs | 38 ++++++++++++++++---- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/attested-tls/src/attestation/measurements.rs b/attested-tls/src/attestation/measurements.rs index b7c109e..9c0300c 100644 --- a/attested-tls/src/attestation/measurements.rs +++ b/attested-tls/src/attestation/measurements.rs @@ -299,6 +299,18 @@ impl MeasurementPolicy { } } + /// Accept any TDX attestation regardless of platform + pub fn tdx() -> Self { + Self { + accepted_measurements: vec![ + MeasurementRecord::allow_any_measurement(AttestationType::DcapTdx), + MeasurementRecord::allow_any_measurement(AttestationType::QemuTdx), + MeasurementRecord::allow_any_measurement(AttestationType::GcpTdx), + MeasurementRecord::allow_any_measurement(AttestationType::AzureTdx), + ], + } + } + /// Expect mock measurements used in tests #[cfg(any(test, feature = "mock"))] pub fn mock() -> Self { diff --git a/attested-tls/src/lib.rs b/attested-tls/src/lib.rs index 70301bd..dbd08a2 100644 --- a/attested-tls/src/lib.rs +++ b/attested-tls/src/lib.rs @@ -419,8 +419,9 @@ impl AttestedTlsClient { pub async fn get_tls_cert( &self, server_name: &str, - ) -> Result>, AttestedTlsError> { - let (mut tls_stream, _, _) = self.connect_tcp(server_name).await?; + ) -> Result<(Vec>, Option), AttestedTlsError> { + let (mut tls_stream, measurements, _attestation_type) = + self.connect_tcp(server_name).await?; let (_io, server_connection) = tls_stream.get_ref(); @@ -431,7 +432,7 @@ impl AttestedTlsClient { tls_stream.shutdown().await?; - Ok(remote_cert_chain) + Ok((remote_cert_chain, measurements)) } } @@ -440,7 +441,7 @@ pub async fn get_tls_cert( server_name: String, attestation_verifier: AttestationVerifier, remote_certificate: Option>, -) -> Result>, AttestedTlsError> { +) -> Result<(Vec>, Option), AttestedTlsError> { tracing::debug!("Getting remote TLS cert"); let attested_tls_client = AttestedTlsClient::new( None, @@ -458,7 +459,7 @@ pub async fn get_tls_cert_with_config( server_name: &str, attestation_verifier: AttestationVerifier, client_config: ClientConfig, -) -> Result>, AttestedTlsError> { +) -> Result<(Vec>, Option), AttestedTlsError> { let attested_tls_client = AttestedTlsClient::new_with_tls_config( client_config, AttestationGenerator::with_no_attestation(), diff --git a/src/lib.rs b/src/lib.rs index c4d1a97..48ab0ae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,7 +65,7 @@ pub async fn get_tls_cert( attestation_verifier: AttestationVerifier, remote_certificate: Option>, allow_self_signed: bool, -) -> Result>, AttestedTlsError> { +) -> Result<(Vec>, Option), AttestedTlsError> { if allow_self_signed { let client_tls_config = self_signed::client_tls_config_allow_self_signed()?; attested_tls::get_tls_cert_with_config( @@ -1114,7 +1114,7 @@ mod tests { proxy_server.accept().await.unwrap(); }); - let retrieved_chain = get_tls_cert_with_config( + let (retrieved_chain, _measurements) = get_tls_cert_with_config( &proxy_server_addr.to_string(), AttestationVerifier::mock(), client_config, diff --git a/src/main.rs b/src/main.rs index 72b4398..d929778 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ use anyhow::{anyhow, ensure}; +use attested_tls::attestation::measurements::MultiMeasurements; use clap::{Parser, Subcommand}; use std::{ fs::File, @@ -126,6 +127,9 @@ enum CliCommand { /// Enables verification of self-signed TLS certificates #[arg(long)] allow_self_signed: bool, + /// Filename to write measurements as JSON to + #[arg(long)] + out_measurements: Option, }, /// Serve a filesystem path over an attested channel AttestedFileServer { @@ -201,12 +205,22 @@ async fn main() -> anyhow::Result<()> { MeasurementPolicy::from_file_or_url(server_measurements).await? } None => { - let allowed_server_attestation_type: AttestationType = serde_json::from_value( - serde_json::Value::String(cli.allowed_remote_attestation_type.ok_or(anyhow!( + match cli + .allowed_remote_attestation_type + .ok_or(anyhow!( "Either a measurements file or an allowed attestation type must be provided" - ))?), - )?; - MeasurementPolicy::single_attestation_type(allowed_server_attestation_type) + ))? + .to_lowercase() + .as_str() + { + "tdx" => MeasurementPolicy::tdx(), + attestation_type => { + let allowed_server_attestation_type: AttestationType = serde_json::from_value( + serde_json::Value::String(attestation_type.to_string()), + )?; + MeasurementPolicy::single_attestation_type(allowed_server_attestation_type) + } + } } }; @@ -340,6 +354,7 @@ async fn main() -> anyhow::Result<()> { server, tls_ca_certificate, allow_self_signed, + out_measurements, } => { let remote_tls_cert = match tls_ca_certificate { Some(remote_cert_filename) => Some( @@ -350,13 +365,24 @@ async fn main() -> anyhow::Result<()> { ), None => None, }; - let cert_chain = get_tls_cert( + let (cert_chain, measurements) = get_tls_cert( server, attestation_verifier, remote_tls_cert, allow_self_signed, ) .await?; + + // If the user chose to write measurements to a file as JSON + if let Some(path_to_write_measurements) = out_measurements { + std::fs::write( + path_to_write_measurements, + measurements + .unwrap_or(MultiMeasurements::NoAttestation) + .to_header_format()? + .as_bytes(), + )?; + } println!("{}", certs_to_pem_string(&cert_chain)?); } CliCommand::AttestedFileServer { From f8d74607f2d836f9a9a231f2e7a6e43064a0af75 Mon Sep 17 00:00:00 2001 From: peg Date: Thu, 26 Feb 2026 12:55:08 +0100 Subject: [PATCH 2/2] Add logging to get-tls-cert command --- src/lib.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 48ab0ae..58e0ec9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -66,17 +66,20 @@ pub async fn get_tls_cert( remote_certificate: Option>, allow_self_signed: bool, ) -> Result<(Vec>, Option), AttestedTlsError> { - if allow_self_signed { + let (cert, measurements) = if allow_self_signed { let client_tls_config = self_signed::client_tls_config_allow_self_signed()?; attested_tls::get_tls_cert_with_config( &server_name, attestation_verifier, client_tls_config, ) - .await + .await? } else { - attested_tls::get_tls_cert(server_name, attestation_verifier, remote_certificate).await - } + attested_tls::get_tls_cert(server_name, attestation_verifier, remote_certificate).await? + }; + + debug!("[get-tls-cert] Connected to proxy server with measurements: {measurements:?}"); + Ok((cert, measurements)) } /// A TLS over TCP server which provides an attestation before forwarding traffic to a given target address