@@ -404,6 +404,7 @@ pub enum MeasurementSetError {
404404/// This is a collection to represent the measurements received from an
405405/// attestor. These measurements will come from the measurement log and the
406406/// DiceTcbInfo extension(s) in the attestation cert chain / pki path.
407+ #[ derive( Debug , PartialEq ) ]
407408pub struct MeasurementSet ( HashSet < Measurement > ) ;
408409
409410/// Construct a MeasurementSet from the provided artifacts. The
@@ -458,6 +459,22 @@ impl MeasurementSet {
458459 pub fn is_subset ( & self , corpus : & ReferenceMeasurements ) -> bool {
459460 self . 0 . is_subset ( & corpus. 0 )
460461 }
462+
463+ /// Return the actual differences from the corpus, useful for debugging
464+ pub fn difference (
465+ & self ,
466+ corpus : & ReferenceMeasurements ,
467+ ) -> Option < MeasurementSet > {
468+ if self . is_subset ( corpus) {
469+ None
470+ } else {
471+ let mut measurements = HashSet :: new ( ) ;
472+ for measurement in self . 0 . difference ( & corpus. 0 ) {
473+ measurements. insert ( * measurement) ;
474+ }
475+ Some ( MeasurementSet ( measurements) )
476+ }
477+ }
461478}
462479
463480impl std:: iter:: IntoIterator for MeasurementSet {
@@ -602,8 +619,8 @@ pub fn verify_attestation(
602619/// process.
603620#[ derive( Debug , Error ) ]
604621pub enum VerifyMeasurementsError {
605- #[ error( "Measurements are not a subset of reference measurements" ) ]
606- NotSubset ,
622+ #[ error( "Measurements are not a subset of reference measurements: {0} " ) ]
623+ NotSubset ( MeasurementSet ) ,
607624}
608625
609626/// This function implements the core of our attestation appraisal policy.
@@ -613,10 +630,13 @@ pub fn verify_measurements(
613630 measurements : & MeasurementSet ,
614631 corpus : & ReferenceMeasurements ,
615632) -> Result < ( ) , VerifyMeasurementsError > {
616- if measurements. is_subset ( corpus) {
617- Ok ( ( ) )
633+ // This should be equivallent to measurements.subset(corpus) but
634+ // give us the entries that are not in the corpus for debugging
635+ // purposes
636+ if let Some ( diff) = measurements. difference ( corpus) {
637+ Err ( VerifyMeasurementsError :: NotSubset ( diff) )
618638 } else {
619- Err ( VerifyMeasurementsError :: NotSubset )
639+ Ok ( ( ) )
620640 }
621641}
622642
@@ -785,4 +805,72 @@ ezRrVF9+9OkCymi+xqWG8UN87sN/9Qk=
785805
786806 assert ! ( res. is_err( ) ) ;
787807 }
808+
809+ const MEASUREMENT_A : [ u8 ; 32 ] = [ 0x1 ; 32 ] ;
810+ const MEASUREMENT_B : [ u8 ; 32 ] = [ 0x2 ; 32 ] ;
811+ const MEASUREMENT_C : [ u8 ; 32 ] = [ 0x3 ; 32 ] ;
812+
813+ #[ test]
814+ fn basic_measurement_set_tests ( ) {
815+ let measurement_a = Measurement :: fake ( MEASUREMENT_A ) ;
816+ let measurement_b = Measurement :: fake ( MEASUREMENT_B ) ;
817+ let measurement_c = Measurement :: fake ( MEASUREMENT_C ) ;
818+
819+ let mut corpus = HashSet :: new ( ) ;
820+
821+ corpus. insert ( measurement_a) ;
822+ corpus. insert ( measurement_b) ;
823+ corpus. insert ( measurement_c) ;
824+
825+ let corpus = ReferenceMeasurements ( corpus) ;
826+
827+ let mut set_a = HashSet :: new ( ) ;
828+ set_a. insert ( measurement_a) ;
829+ let set_a = MeasurementSet ( set_a) ;
830+
831+ assert ! ( set_a. is_subset( & corpus) ) ;
832+
833+ let mut set_b = HashSet :: new ( ) ;
834+ set_b. insert ( measurement_b) ;
835+ let set_b = MeasurementSet ( set_b) ;
836+
837+ assert ! ( set_b. is_subset( & corpus) ) ;
838+
839+ let mut set_c = HashSet :: new ( ) ;
840+ set_c. insert ( measurement_c) ;
841+ let set_c = MeasurementSet ( set_c) ;
842+
843+ assert ! ( verify_measurements( & set_c, & corpus) . is_ok( ) ) ;
844+ }
845+
846+ #[ test]
847+ fn missing_measurement_set_tests ( ) {
848+ let measurement_a = Measurement :: fake ( MEASUREMENT_A ) ;
849+ let measurement_b = Measurement :: fake ( MEASUREMENT_B ) ;
850+ let measurement_c = Measurement :: fake ( MEASUREMENT_C ) ;
851+
852+ let mut corpus = HashSet :: new ( ) ;
853+
854+ corpus. insert ( measurement_a) ;
855+ corpus. insert ( measurement_b) ;
856+
857+ let corpus = ReferenceMeasurements ( corpus) ;
858+
859+ let mut set_c = HashSet :: new ( ) ;
860+ set_c. insert ( measurement_c) ;
861+ let set_c = MeasurementSet ( set_c) ;
862+
863+ let mut other_c = HashSet :: new ( ) ;
864+ other_c. insert ( measurement_c) ;
865+ let other_c = MeasurementSet ( other_c) ;
866+
867+ match verify_measurements ( & set_c, & corpus) {
868+ Ok ( ( ) ) => panic ! ( "expected an error" ) ,
869+ Err ( e) => match e {
870+ VerifyMeasurementsError :: NotSubset ( set) => {
871+ assert ! ( other_c == set)
872+ }
873+ } ,
874+ }
875+ }
788876}
0 commit comments