/* * Copyright (C) 2012 Intel Corporation * All rights reserved. */ package test.policy; import com.intel.mtwilson.policy.rule.*; import com.intel.dcsg.cpg.crypto.Sha1Digest; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.fasterxml.jackson.module.mrbean.MrBeanModule; import com.intel.mtwilson.model.*; import com.intel.mtwilson.policy.*; import com.intel.mtwilson.policy.fault.*; import com.intel.mtwilson.policy.Fault; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import org.apache.commons.io.IOUtils; import com.fasterxml.jackson.databind.ObjectWriter; //import org.codehaus.jackson.map.ObjectMapper; //import org.codehaus.jackson.map.ObjectWriter; import org.junit.Test; import static org.junit.Assert.*; /** * * @author jbuhacoff */ public class HostTrustReportTest { /** * Output: Check: PcrMatchesConstant: PCR 0, aabbccddeeaabbccddeeaabbccddeeaabbccddee * Json output: { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "0" } }, "faults" : [ ], "trusted" : true, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" } * */ @Test public void testPcrMatchesConstantPolicyPass() { Pcr expected = new Pcr(0, "aabbccddeeaabbccddeeaabbccddeeaabbccddee"); PcrMatchesConstant policy = new PcrMatchesConstant(expected); HostReport hostReport = new HostReport(); hostReport.pcrManifest = new PcrManifest(); hostReport.pcrManifest.setPcr(expected); // set actual = expected so it should pass RuleResult report = policy.apply(hostReport); assertTrue(report.isTrusted()); // printFaults(report); printReport(report); printReportJson(report); } /** * Output: Check: PcrMatchesConstant: PCR 0, aabbccddeeaabbccddeeaabbccddeeaabbccddee Fault: Host PCR 0 with value aabbccddeeaabbccddeeaabbccddeeaabbccdd00 does not match expected value aabbccddeeaabbccddeeaabbccddeeaabbccddee [PcrValueMismatch] * * Json output: { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "0" } }, "faults" : [ { "cause" : null, "more" : [ ], "pcrIndex" : "0", "expectedValue" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "actualValue" : "aabbccddeeaabbccddeeaabbccddeeaabbccdd00", "faultName" : "com.intel.mtwilson.policy.fault.PcrValueMismatch" } ], "trusted" : false, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" } * */ @Test public void testPcrMatchesConstantPolicyFail() { Pcr expected = new Pcr(0, "aabbccddeeaabbccddeeaabbccddeeaabbccddee"); Pcr actual = new Pcr(0, "aabbccddeeaabbccddeeaabbccddeeaabbccdd00"); PcrMatchesConstant policy = new PcrMatchesConstant(expected); HostReport hostReport = new HostReport(); hostReport.pcrManifest = new PcrManifest(); hostReport.pcrManifest.setPcr(actual); // set actual != expected so it should fail RuleResult report = policy.apply(hostReport); assertFalse(report.isTrusted()); // printFaults(report); printReport(report); printReportJson(report); } /** * Example output: { "policy" : { "checks" : [ { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "1" } }, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" }, { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "2" } }, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" } ] }, "faults" : [ ], "trusted" : true, "policyName" : "com.intel.mtwilson.policy.RequireAll" } * */ @Test public void testPcrMatchesConstantPolicyListPass() { Pcr expected1 = new Pcr(1, "aabbccddeeaabbccddeeaabbccddeeaabbccddee"); PcrMatchesConstant policy1 = new PcrMatchesConstant(expected1); Pcr expected2 = new Pcr(2, "aabbccddeeaabbccddeeaabbccddeeaabbccddee"); PcrMatchesConstant policy2 = new PcrMatchesConstant(expected2); HostReport hostReport = new HostReport(); hostReport.pcrManifest = new PcrManifest(); hostReport.pcrManifest.setPcr(expected1); // set actual = expected so it should pass hostReport.pcrManifest.setPcr(expected2); // set actual = expected so it should pass // ArrayList<TrustPolicy> policies = new ArrayList<TrustPolicy>(); // policies.add(policy1); // policies.add(policy2); PolicyEngine engine = new PolicyEngine(); // List<TrustReport> report = engine.apply(hostReport, policies); List<RuleResult> reports = engine.applyAll(hostReport, policy1, policy2); for(RuleResult report : reports) { printReport(report); printReportJson(report); } /** * Sample output for below: { "policyName" : "test pcr matches constant", "reports" : [ { "rule" : { "markers" : [ "bios" ], "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "0" } }, "faults" : [ ], "trusted" : true, "ruleName" : "com.intel.mtwilson.policy.rule.PcrMatchesConstant" }, { "rule" : { "markers" : [ "vmm" ], "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "17" } }, "faults" : [ ], "trusted" : true, "ruleName" : "com.intel.mtwilson.policy.rule.PcrMatchesConstant" } ], "trusted" : true } * */ // now do the same thing but with a policy Policy policy = new Policy("test pcr matches constant", policy1, policy2); TrustReport report = engine.apply(hostReport, policy); printReportJson(report); } /** * Example output: * { "policy" : { "checks" : [ { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "1" } }, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" }, { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "2" } }, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" } ] }, "marks" : [ { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "2" } }, "marks" : [ ], "faults" : [ ], "trusted" : true, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" } ], "faults" : [ { "cause" : null, "report" : { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "1" } }, "marks" : [ ], "faults" : [ { "cause" : null, "pcrIndex" : "1", "expectedValue" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "actualValue" : "aabbccddeeaabbccddeeaabbccddeeaabbccdd11", "faultName" : "com.intel.mtwilson.policy.fault.PcrValueMismatch" } ], "trusted" : false, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" }, "faultName" : "com.intel.mtwilson.policy.fault.Cite" } ], "trusted" : false, "policyName" : "com.intel.mtwilson.policy.RequireAll" } * */ @Test public void testPcrMatchesConstantPolicyListFailRequireAll() { Pcr expected1 = new Pcr(1, "aabbccddeeaabbccddeeaabbccddeeaabbccddee"); Pcr actual1 = new Pcr(1, "aabbccddeeaabbccddeeaabbccddeeaabbccdd11"); PcrMatchesConstant policy1 = new PcrMatchesConstant(expected1); Pcr expected2 = new Pcr(2, "aabbccddeeaabbccddeeaabbccddeeaabbccddee"); Pcr actual2 = expected2;// new Pcr(2, "aabbccddeeaabbccddeeaabbccddeeaabbccdd22"); PcrMatchesConstant policy2 = new PcrMatchesConstant(expected2); HostReport hostReport = new HostReport(); hostReport.pcrManifest = new PcrManifest(); hostReport.pcrManifest.setPcr(actual1); hostReport.pcrManifest.setPcr(actual2); // ArrayList<TrustPolicy> policies = new ArrayList<TrustPolicy>(); // policies.add(policy1); // policies.add(policy2); PolicyEngine engine = new PolicyEngine(); // List<TrustReport> report = engine.apply(hostReport, policies); List<RuleResult> reports = engine.applyAll(hostReport, policy1, policy2); for(RuleResult report : reports) { printReport(report); printReportJson(report); } } /** * * Example output, notice that because all policies failed the output is just like any other failure report. * { "policy" : { "checks" : [ { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "1" } }, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" }, { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "2" } }, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" } ] }, "faults" : [ { "cause" : null, "report" : { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "1" } }, "faults" : [ { "cause" : null, "pcrIndex" : "1", "expectedValue" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "actualValue" : "aabbccddeeaabbccddeeaabbccddeeaabbccdd11", "faultName" : "com.intel.mtwilson.policy.fault.PcrValueMismatch" } ], "trusted" : false, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" }, "faultName" : "com.intel.mtwilson.policy.fault.Cite" }, { "cause" : null, "report" : { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "2" } }, "faults" : [ { "cause" : null, "pcrIndex" : "2", "expectedValue" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "actualValue" : "aabbccddeeaabbccddeeaabbccddeeaabbccdd22", "faultName" : "com.intel.mtwilson.policy.fault.PcrValueMismatch" } ], "trusted" : false, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" }, "faultName" : "com.intel.mtwilson.policy.fault.Cite" } ], "trusted" : false, "policyName" : "com.intel.mtwilson.policy.RequireAny" } * * */ @Test public void testPcrMatchesConstantPolicyListFailRequireAny() { Pcr expected1 = new Pcr(1, "aabbccddeeaabbccddeeaabbccddeeaabbccddee"); Pcr actual1 = new Pcr(1, "aabbccddeeaabbccddeeaabbccddeeaabbccdd11"); PcrMatchesConstant policy1 = new PcrMatchesConstant(expected1); Pcr expected2 = new Pcr(2, "aabbccddeeaabbccddeeaabbccddeeaabbccddee"); Pcr actual2 = new Pcr(2, "aabbccddeeaabbccddeeaabbccddeeaabbccdd22"); PcrMatchesConstant policy2 = new PcrMatchesConstant(expected2); HostReport hostReport = new HostReport(); hostReport.pcrManifest = new PcrManifest(); hostReport.pcrManifest.setPcr(actual1); hostReport.pcrManifest.setPcr(actual2); // ArrayList<TrustPolicy> policies = new ArrayList<TrustPolicy>(); // policies.add(policy1); // policies.add(policy2); PolicyEngine engine = new PolicyEngine(); // List<TrustReport> report = engine.apply(hostReport, policies); List<RuleResult> reports = engine.applyAll(hostReport, policy1, policy2); for(RuleResult report : reports) { printReport(report); printReportJson(report); } } /** * Example output, notice that because ONE policy succeeded, the overall result is trusted and * there are no faults listed... in order to be fully compatible with expectations for the TrustReport * object. However, for the policies that failed (and didn't matter since ONE did pass) the faults * are still recorded, in the "optionalFaults" field. { "policy" : { "checks" : [ { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "1" } }, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" }, { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "2" } }, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" } ] }, "faults" : [ ], "optionalFaults" : [ { "cause" : null, "report" : { "policy" : { "expectedPcr" : { "value" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "index" : "1" } }, "faults" : [ { "cause" : null, "pcrIndex" : "1", "expectedValue" : "aabbccddeeaabbccddeeaabbccddeeaabbccddee", "actualValue" : "aabbccddeeaabbccddeeaabbccddeeaabbccdd11", "faultName" : "com.intel.mtwilson.policy.fault.PcrValueMismatch" } ], "trusted" : false, "policyName" : "com.intel.mtwilson.policy.PcrMatchesConstant" }, "faultName" : "com.intel.mtwilson.policy.fault.Cite" } ], "trusted" : true, "policyName" : "com.intel.mtwilson.policy.RequireAny" } * */ @Test public void testPcrMatchesConstantPolicyListPassRequireAny() { Pcr expected1 = new Pcr(1, "aabbccddeeaabbccddeeaabbccddeeaabbccddee"); Pcr actual1 = new Pcr(1, "aabbccddeeaabbccddeeaabbccddeeaabbccdd11"); PcrMatchesConstant policy1 = new PcrMatchesConstant(expected1); Pcr expected2 = new Pcr(2, "aabbccddeeaabbccddeeaabbccddeeaabbccddee"); Pcr actual2 = expected2; PcrMatchesConstant policy2 = new PcrMatchesConstant(expected2); HostReport hostReport = new HostReport(); hostReport.pcrManifest = new PcrManifest(); hostReport.pcrManifest.setPcr(actual1); hostReport.pcrManifest.setPcr(actual2); // ArrayList<TrustPolicy> policies = new ArrayList<TrustPolicy>(); // policies.add(policy1); // policies.add(policy2); PolicyEngine engine = new PolicyEngine(); // List<TrustReport> report = engine.apply(hostReport, policies); List<RuleResult> reports = engine.applyAll(hostReport, policy1, policy2); for(RuleResult report : reports) { printReport(report); printReportJson(report); } } /** * Example output using custom prints: * Check: PcrModuleManifestIncludesModuleSet: com.intel.mtwilson.policy.PcrModuleManifestIncludesModuleSet@5a07232e Fault: Module manifest for PCR 8 missing 1 expected entries [PcrModuleManifestMissingExpectedEntries] Modules missing from PCR 8: - 0011001100110011001100330033003300330033 vendorA-moduleXYZ-1.0.3 * * Example output using json: { "policy" : { "pcrModuleManifest" : { "pcrIndex" : "8", "moduleManifest" : [ { "label" : "vendorA-moduleXYZ-1.0.2", "value" : "0011001100110011001100220022002200220022" }, { "label" : "vendorA-moduleXYZ-1.0.3", "value" : "0011001100110011001100330033003300330033" } ] } }, "faults" : [ { "cause" : null, "pcrIndex" : "8", "missingEntries" : [ { "label" : "vendorA-moduleXYZ-1.0.3", "value" : "0011001100110011001100330033003300330033" } ], "faultName" : "com.intel.mtwilson.policy.fault.PcrModuleManifestMissingExpectedEntries" } ], "trusted" : false, "policyName" : "com.intel.mtwilson.policy.PcrModuleManifestIncludesModuleSet" } * * */ @Test public void testPcrModuleManifestFailWithDetails() { HashSet<Measurement> expectedModuleSet = new HashSet<Measurement>(); expectedModuleSet.add(new Measurement(new Sha1Digest("0011001100110011001100220022002200220022"), "vendorA-moduleXYZ-1.0.2")); expectedModuleSet.add(new Measurement(new Sha1Digest("0011001100110011001100330033003300330033"), "vendorA-moduleXYZ-1.0.3")); PcrEventLogIncludes policy = new PcrEventLogIncludes(new PcrIndex(8), expectedModuleSet); ArrayList<Measurement> actualModuleSet = new ArrayList<Measurement>(); actualModuleSet.add(new Measurement(new Sha1Digest("0011001100110011001100220022002200220022"), "vendorA-moduleXYZ-1.0.2")); actualModuleSet.add(new Measurement(new Sha1Digest("1012134056708910234580990553434570343245"), "vendorB-moduleABC-0.5.0")); PcrEventLog actual = new PcrEventLog(new PcrIndex(8), actualModuleSet); HostReport hostReport = new HostReport(); hostReport.pcrManifest = new PcrManifest(); hostReport.pcrManifest.setPcrEventLog(new PcrEventLog(new PcrIndex(8),actualModuleSet)); RuleResult report = policy.apply(hostReport); assertFalse(report.isTrusted()); // printFaults(report); printReport(report); // look for the list of missing modules and print it for(Fault fault : report.getFaults()) { if( fault instanceof PcrEventLogMissingExpectedEntries ) { PcrEventLogMissingExpectedEntries details = (PcrEventLogMissingExpectedEntries)fault; System.out.println(String.format("Modules missing from PCR %d:", details.getPcrIndex().toInteger())); for(Measurement m : details.getMissingEntries()) { System.out.println(String.format("- %s %s", m.getValue().toString(), m.getLabel())); } } } printReportJson(report); } private static ObjectWriter json = new com.fasterxml.jackson.databind.ObjectMapper().writerWithDefaultPrettyPrinter(); /* private static ObjectWriter writer; @BeforeClass public void initJsonMapper () { writer = mapper.writerWithDefaultPrettyPrinter(); } public void printJson(Object value) { try { System.out.println(mapper.writeValueAsString(value)); } catch(Exception e) { System.out.println("Cannot print value: "+e.toString()); } }*/ private void printReport(List<RuleResult> list) { for(RuleResult report : list) { printReport(report); } } private void printReport(RuleResult report) { System.out.println("Check: "+report.getRule().getClass().getSimpleName()+": "+report.getRule().toString()); printFaults(report); } private void printReportJson(TrustReport report) { try { System.out.println(json.writeValueAsString(report)); } catch(Exception e) { System.out.println("Cannot write report: "+e.toString()); } } private void printReportJson(RuleResult report) { try { System.out.println(json.writeValueAsString(report)); } catch(Exception e) { System.out.println("Cannot write report: "+e.toString()); } /* System.out.println("Check: "+report.getPolicy().getClass().getSimpleName()+": "+report.getPolicy().toString()); try { System.out.println(mapper.writeValueAsString(report.getPolicy())); } catch(Exception e) { System.out.println("Cannot describe policy: "+e.toString()); } for(Fault fault : report.getFaults()) { try { System.out.println(mapper.writeValueAsString(fault)); } catch(Exception e) { System.out.println("Cannot describe fault: "+e.toString()); } }*/ } private void printFaults(RuleResult m) { for(Fault fault : m.getFaults()) { System.out.println("Fault: "+fault.toString()+" ["+fault.getClass().getSimpleName()+"]"); if( fault.getCause() != null ) { System.out.println(" Caused by: "+fault.getCause().toString()); } } } /* private void printFaults(Fault[] faults, int indentLevel) { String indent = ""; for(int i=0; i<indentLevel; i++) { indent += " "; } for(Fault fault : faults) { System.out.println(indent+"Fault: "+fault.toString()+" ["+fault.getClass().getSimpleName()+"]"); if( fault.getCause() != null ) { System.out.println(indent+" Caused by: "+fault.getCause().toString()); } } }*/ /* private void printChecks(TrustReport m) { for(Check check : m.getChecks()) { System.out.println("Check: "+check.toString()+" ["+check.getClass().getSimpleName()+"]"); // if( check.getMore() != null ) { // printChecks(check.getMore(), 1); // } printFaults(m); } } private void printChecks(Check[] checks, int indentLevel) { String indent = ""; for(int i=0; i<indentLevel; i++) { indent += " "; } for(Check check : checks) { System.out.println(indent+"Check: "+check.toString()+" ["+check.getClass().getSimpleName()+"]"); if( check.getMore() != null ) { printChecks(check.getMore(), indentLevel+1); } } }*/ // XXX this doesn't work right now. it's impossible to deserialize the json or the xml unless // we include type information when we serialize... like the "policyName" but generated by jackson // for every object. @Test public void testReadJsonTrustReportAndFindMarks() throws IOException { InputStream in = getClass().getResourceAsStream("/trustreport-1.xml"); com.fasterxml.jackson.databind.ObjectMapper xml = new XmlMapper(); xml.registerModule(new MrBeanModule()); RuleResult report = xml.reader(RuleResult.class).readValue(in); IOUtils.closeQuietly(in); /* TrustReport biosReport = report.findMark("com.intel.mtwilson.policy.impl.TrustedBios"); assertNotNull(biosReport); assertTrue(biosReport.isTrusted()); TrustReport vmmReport = report.findMark("com.intel.mtwilson.policy.impl.TrustedVmm"); assertNotNull(vmmReport); assertTrue(vmmReport.isTrusted()); TrustReport locationReport = report.findMark("com.intel.mtwilson.policy.impl.TrustedLocation"); assertNull(locationReport); // the report did not include a location policy */ } }