diff --git a/attested-tls/src/attestation/measurements.rs b/attested-tls/src/attestation/measurements.rs index 69780c2..384426c 100644 --- a/attested-tls/src/attestation/measurements.rs +++ b/attested-tls/src/attestation/measurements.rs @@ -1,6 +1,7 @@ //! Measurements and policy for enforcing them when validating a remote attestation use crate::attestation::{dcap::DcapVerificationError, AttestationError, AttestationType}; use std::{collections::HashMap, path::PathBuf}; +use std::{fmt, fmt::Formatter}; use dcap_qvl::quote::Report; use http::{header::InvalidHeaderValue, HeaderValue}; @@ -34,13 +35,63 @@ impl TryFrom for DcapMeasurementRegister { } /// Represents a set of measurements values for one of the supported CVM platforms -#[derive(Debug, Clone, PartialEq)] +#[derive(Clone, PartialEq)] pub enum MultiMeasurements { Dcap(HashMap), Azure(HashMap), NoAttestation, } +impl fmt::Debug for MultiMeasurements { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Self::Dcap(measurements) => f + .debug_tuple("Dcap") + .field(&DcapHexDebug(measurements)) + .finish(), + Self::Azure(measurements) => f + .debug_tuple("Azure") + .field(&AzureHexDebug(measurements)) + .finish(), + Self::NoAttestation => f.write_str("NoAttestation"), + } + } +} + +/// Used to display measurements as hex +struct DcapHexDebug<'a>(&'a HashMap); + +impl fmt::Debug for DcapHexDebug<'_> { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let mut entries: Vec<_> = self.0.iter().collect(); + entries.sort_by_key(|(register, _)| (*register).clone() as u8); + + let mut map = f.debug_map(); + for (register, value) in entries { + let hex_value = hex::encode(value); + map.entry(register, &hex_value); + } + map.finish() + } +} + +/// Used to display measurements as hex +struct AzureHexDebug<'a>(&'a HashMap); + +impl fmt::Debug for AzureHexDebug<'_> { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let mut entries: Vec<_> = self.0.iter().collect(); + entries.sort_by_key(|(index, _)| **index); + + let mut map = f.debug_map(); + for (index, value) in entries { + let hex_value = hex::encode(value); + map.entry(index, &hex_value); + } + map.finish() + } +} + /// Expected measurement values for policy enforcement #[derive(Debug, Clone, PartialEq)] pub enum ExpectedMeasurements { @@ -749,4 +800,22 @@ mod tests { ])); assert!(policy.check_measurement(&measurements3).is_err()); } + + #[test] + fn test_multi_measurements_debug_prints_hex() { + let dcap = MultiMeasurements::Dcap(HashMap::from([( + DcapMeasurementRegister::MRTD, + [0xabu8; 48], + )])); + let dcap_debug = format!("{dcap:?}"); + assert!(dcap_debug.contains("Dcap")); + assert!(dcap_debug.contains("abababab")); + assert!(!dcap_debug.contains("[171")); + + let azure = MultiMeasurements::Azure(HashMap::from([(9u32, [0x11u8; 32])])); + let azure_debug = format!("{azure:?}"); + assert!(azure_debug.contains("Azure")); + assert!(azure_debug.contains("11111111")); + assert!(!azure_debug.contains("[17")); + } } diff --git a/src/lib.rs b/src/lib.rs index 5c8307e..c6afe8b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -195,7 +195,7 @@ impl ProxyServer { target: String, client_addr: SocketAddr, ) -> Result<(), ProxyError> { - debug!("[proxy-server] accepted connection"); + debug!("[proxy-server] accepted connection with measurements: {measurements:?}"); let http_version = HttpVersion::from_negotiated_protocol_server(&tls_stream); @@ -629,6 +629,7 @@ impl ProxyClient { ProxyError, > { let (tls_stream, measurements, remote_attestation_type) = inner.connect_tcp(target).await?; + debug!("[proxy-client] Connected to proxy server with measurements: {measurements:?}"); // The attestation exchange is now complete - setup an HTTP client let http_version = HttpVersion::from_negotiated_protocol_client(&tls_stream);