/*
* Copyright (C) 2012 Intel Corporation
* All rights reserved.
*/
package com.intel.mtwilson.policy.rule;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.intel.mtwilson.model.Pcr;
import com.intel.mtwilson.model.PcrIndex;
import com.intel.mtwilson.policy.BaseRule;
import com.intel.mtwilson.policy.HostReport;
import com.intel.mtwilson.policy.RuleResult;
import com.intel.mtwilson.policy.dynamic.Variable;
import com.intel.mtwilson.policy.fault.PcrManifestMissing;
import com.intel.mtwilson.policy.fault.PcrValueMismatch;
import com.intel.mtwilson.policy.fault.PcrValueMissing;
import java.util.Set;
/**
* The PcrMatchesVariable policy enforces that a specific PCR contains a dynamic
* value that is calculated using known variables. For example, some servers
* may extend a PCR with their UUID - that means the PCR varies even among
* otherwise identical hosts, but if we know what the host's UUID is then we
* are able to calculate what the expected PCR value is and compare to the
* actual value.
*
* @author jbuhacoff
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@JsonIgnoreProperties(ignoreUnknown=true)
public class PcrMatchesVariable extends BaseRule {
private PcrIndex pcrIndex;
private Set<Variable> variables;
private String expression;
protected PcrMatchesVariable() { } // for desearializing jackson
public PcrMatchesVariable(PcrIndex pcrIndex, Set<Variable> variables, String expression) {
this.pcrIndex = pcrIndex;
this.variables = variables;
this.expression = expression;
}
@Override
public RuleResult apply(HostReport hostReport) {
RuleResult report = new RuleResult(this);
// report.check(this);
// report.check("%s: PCR %s is variable", getClass().getSimpleName(),pcrIndex.toString());
if( hostReport.pcrManifest == null ) {
report.fault(new PcrManifestMissing());
}
else {
Pcr actual = hostReport.pcrManifest.getPcr(pcrIndex.toInteger());
if( actual == null ) {
report.fault(new PcrValueMissing(pcrIndex));
}
else {
/**
* 1) create a new database table mw_host_info where we can store host-specific constants UUID when we register a host
* 2) use Rhino javascript interpreter to create javascript binding for certain utility classes (not yet written) so that
* we can write something like PCR[0] = sha1(Host.Module.BIOS + sha1(Host.UUID)) and have that be part of the
* whitelist as a computed value; the BIOS sha1 woud be known and stored in that variable, so that we can extend it
* with the UUID and come up with what the PCR[0] is expected to contain.
* 3) calculate expected value for pcrIndex
* 4) compare with actual value
*
* Rhino references (esp. important for security against arbitrary javascript):
*
* http://www.ibm.com/developerworks/java/library/j-5things9/index.html
* http://www.javalobby.org/java/forums/t87890.html
*
* https://developer.mozilla.org/en-US/docs/Rhino_documentation
* https://developer.mozilla.org/en-US/docs/Scripting_Java
* http://en.wikipedia.org/wiki/Rhino_(JavaScript_engine)
* https://developer.mozilla.org/en-US/docs/Rhino/JavaScript_Compiler
*
* http://riven8192.blogspot.com/2010/07/java-rhino-fine-grained-classshutter.html
* http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/
* http://stackoverflow.com/questions/93911/how-can-you-run-javascript-using-rhino-for-java-in-a-sandbox
*
* http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html
* https://developer.opencloud.com/devportal/display/RD2v0/1+Configuring+Java+Security+of+Rhino
*/
/*
if( !expected.equals(actual) ) {
report.fault(new PcrValueMismatch(pcrIndex, expected.getValue(), actual.getValue()) );
}
*/
}
}
return report;
}
}