[#265] IMA/TBoot PCR ignore policy (#271)

* Updated code to include an official policy to ignore IMA and TBoot.  The policies will disable if firmware validation is disabled.
This commit is contained in:
Cyrus 2020-06-23 12:48:06 -04:00 committed by GitHub
parent 1448b35e5e
commit 6a62002b05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 641 additions and 116 deletions

View File

@ -8,6 +8,7 @@ import java.security.cert.CertificateException;
import hirs.data.persist.TPMMeasurementRecord;
import hirs.data.persist.SwidResource;
import hirs.data.persist.PCRPolicy;
import hirs.validation.SupplyChainCredentialValidator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -241,7 +242,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
.select(this.certificateManager)
.byDeviceId(device.getId()).getCertificate();
validations.add(validateFirmware(pc, attCert));
validations.add(validateFirmware(pc, attCert, policy.getPcrPolicy()));
}
// Generate validation summary, save it, and return it.
@ -314,73 +315,72 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
}
return subPlatformScv;
}
private static final int IMA_TEN = 9;
private SupplyChainValidation validateFirmware(final PlatformCredential pc,
final IssuedAttestationCertificate attCert) {
final IssuedAttestationCertificate attCert, final PCRPolicy pcrPolicy) {
ReferenceManifest rim = null;
ReferenceManifest rim;
String[] baseline = new String[Integer.SIZE];
Level level = Level.ERROR;
AppraisalStatus fwStatus;
if (attCert != null) {
String[] pcrsSet = attCert.getPcrValues().split("\\+");
String[] pcrs1 = pcrsSet[0].split("\\n");
String[] pcrs256 = pcrsSet[1].split("\\n");
AppraisalStatus fwStatus = null;
if (pc != null) {
rim = ReferenceManifest.select(
this.referenceManifestManager)
.byManufacturer(pc.getManufacturer())
.getRIM();
if (rim == null) {
fwStatus = new AppraisalStatus(FAIL, String.format("Firmware validation failed: "
+ "No associated RIM file could be found for %s",
pc.getManufacturer()));
fwStatus = new AppraisalStatus(FAIL,
String.format("Firmware validation failed: "
+ "No associated RIM file could be found for %s",
pc.getManufacturer()));
} else {
StringBuilder sb = new StringBuilder();
fwStatus = new AppraisalStatus(PASS,
SupplyChainCredentialValidator.FIRMWARE_VALID);
String failureMsg = "Firmware validation failed: PCR %s does not"
+ " match%n";
List<SwidResource> swids = rim.parseResource();
for (SwidResource swid : swids) {
baseline = swid.getPcrValues()
.toArray(new String[swid.getPcrValues().size()]);
}
pcrPolicy.setBaselinePcrs(baseline);
}
}
int imaValue = IMA_TEN;
String pcrNum;
String pcrValue;
if (baseline[0].length() == TPMMeasurementRecord.SHA_BYTE_LENGTH) {
for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) {
pcrNum = pcrs1[i + 1].split(":")[0].trim();
pcrValue = pcrs1[i + 1].split(":")[1].trim();
if (i != imaValue) {
if (!baseline[i].equals(pcrValue)) {
sb.append(String.format(failureMsg, pcrNum));
}
}
}
} else if (baseline[0].length() == TPMMeasurementRecord.SHA_256_BYTE_LENGTH) {
for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) {
pcrNum = pcrs256[i + 1].split(":")[0].trim();
pcrValue = pcrs256[i + 1].split(":")[1].trim();
if (i != imaValue) {
if (!baseline[i].equals(pcrValue)) {
sb.append(String.format(failureMsg, pcrNum));
}
}
}
if (attCert != null && fwStatus == null) {
String[] pcrsSet = attCert.getPcrValues().split("\\+");
String[] pcrs1 = pcrsSet[0].split("\\n");
String[] pcrs256 = pcrsSet[1].split("\\n");
String[] quote = new String[TPMMeasurementRecord.MAX_PCR_ID + 1];
int offset = 0;
StringBuilder sb;
fwStatus = new AppraisalStatus(PASS,
SupplyChainCredentialValidator.FIRMWARE_VALID);
if (baseline[0].length() == TPMMeasurementRecord.SHA_BYTE_LENGTH) {
// quote from provisioner is formated to indicate the encryption
if (pcrs1[0].split(":")[0].contains("sha")) {
offset = 1;
}
if (sb.length() > 0) {
level = Level.ERROR;
fwStatus = new AppraisalStatus(FAIL, sb.toString());
} else {
level = Level.INFO;
for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) {
//update quote with the pcr only, based on offset
quote[i] = pcrs1[i + offset].split(":")[1].trim();
}
} else if (baseline[0].length() == TPMMeasurementRecord.SHA_256_BYTE_LENGTH) {
// quote from provisioner is formated to indicate the encryption
if (pcrs256[0].split(":")[0].contains("sha")) {
offset = 1;
}
for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) {
//update quote with the pcr only, based on offset
quote[i] = pcrs256[i + offset].split(":")[1].trim();
}
}
sb = pcrPolicy.validatePcrs(quote);
if (sb.length() > 0) {
level = Level.ERROR;
fwStatus = new AppraisalStatus(FAIL, sb.toString());
} else {
level = Level.INFO;
}
} else {
fwStatus = new AppraisalStatus(FAIL, "Associated Issued Attestation"

View File

@ -13,12 +13,16 @@ public class PolicyPageModel {
private boolean enablePcCertificateValidation;
private boolean enablePcCertificateAttributeValidation;
private boolean enableFirmwareValidation;
private boolean enableIgnoreIma;
private boolean enableIgnoreTboot;
// Variables to get policy settings from page
private String pcValidate;
private String pcAttributeValidate;
private String ecValidate;
private String fmValidate;
private String ignoreIma;
private String ignoretBoot;
/**
* Constructor. Sets fields from policy.
@ -30,6 +34,8 @@ public class PolicyPageModel {
this.enablePcCertificateValidation = policy.isPcValidationEnabled();
this.enablePcCertificateAttributeValidation = policy.isPcAttributeValidationEnabled();
this.enableFirmwareValidation = policy.isFirmwareValidationEnabled();
this.enableIgnoreIma = policy.isIgnoreImaEnabled();
this.enableIgnoreTboot = policy.isIgnoreTbootEnabled();
}
/**
@ -74,6 +80,22 @@ public class PolicyPageModel {
return enableFirmwareValidation;
}
/**
* Gets the Enable Ignore IMA state.
* @return the validation state.
*/
public boolean getEnableIgnoreIma() {
return enableIgnoreIma;
}
/**
* Gets the Enable Ignore TBoot state.
* @return the validation state.
*/
public boolean getEnableIgnoreTboot() {
return enableIgnoreTboot;
}
/**
* Gets the EC Validation value.
*
@ -110,6 +132,24 @@ public class PolicyPageModel {
return fmValidate;
}
/**
* Gets the Ignore IMA validation value.
*
* @return the model string representation of this field (checked or unchecked)
*/
public String getIgnoreIma() {
return ignoreIma;
}
/**
* Gets the Ignore TBoot validation value.
*
* @return the model string representation of this field (checked or unchecked)
*/
public String getIgnoretBoot() {
return ignoretBoot;
}
/**
* Sets the EC Validation state.
*
@ -147,6 +187,24 @@ public class PolicyPageModel {
this.enableFirmwareValidation = enableFirmwareValidation;
}
/**
* Sets the Enable Ignore IMA state.
*
* @param enableIgnoreIma true if performing validation, false otherwise
*/
public void setEnableIgnoreIma(final boolean enableIgnoreIma) {
this.enableIgnoreIma = enableIgnoreIma;
}
/**
* Sets the Enable Ignore TBoot state.
*
* @param enableIgnoreTboot true if performing validation, false otherwise
*/
public void setEnableIgnoreTboot(final boolean enableIgnoreTboot) {
this.enableIgnoreTboot = enableIgnoreTboot;
}
/**
* Sets the Platform Certificate Validation state.
*
@ -183,6 +241,24 @@ public class PolicyPageModel {
this.fmValidate = fmValidate;
}
/**
* Sets the Ignore IMA state.
*
* @param ignoreIma "checked" if enabling validation, false otherwise
*/
public void setIgnoreIma(final String ignoreIma) {
this.ignoreIma = ignoreIma;
}
/**
* Sets the Ignore Tboot state.
*
* @param ignoretBoot "checked" if enabling validation, false otherwise
*/
public void setIgnoretBoot(final String ignoretBoot) {
this.ignoretBoot = ignoretBoot;
}
@Override
public String toString() {
return "PolicyPageModel{"

View File

@ -36,35 +36,36 @@ public class PolicyPageController extends PageController<NoPageParams> {
private static final Logger LOGGER = getLogger(PolicyPageController.class);
/**
* Represents a web request indicating to enable a setting (based on radio buttons from a
* web form).
* Represents a web request indicating to enable a setting (based on radio
* buttons from a web form).
*/
private static final String ENABLED_PARAMETER_VALUE = "checked";
private PolicyManager policyManager;
private AppraiserManager appraiserManager;
/**
* Model attribute name used by initPage for the initial data passed to the page.
* Model attribute name used by initPage for the initial data passed to the
* page.
*/
public static final String INITIAL_DATA = "initialData";
/**
* Flash attribute name used by initPage and post for the data forwarded during the redirect
* from the POST operation back to the page.
* Flash attribute name used by initPage and post for the data forwarded
* during the redirect from the POST operation back to the page.
*/
public static final String RESULT_DATA = "resultData";
/**
* Constructor.
*
* @param policyManager the policy manager
* @param appraiserManager the appraiser manager
*/
@Autowired
public PolicyPageController(final PolicyManager policyManager,
final AppraiserManager appraiserManager) {
final AppraiserManager appraiserManager) {
super(POLICY);
this.policyManager = policyManager;
@ -75,7 +76,8 @@ public class PolicyPageController extends PageController<NoPageParams> {
* Returns the path for the view and the data model for the page.
*
* @param params The object to map url parameters into.
* @param model The data model for the request. Can contain data from redirect.
* @param model The data model for the request. Can contain data from
* redirect.
* @return the path for the view and data model for the page.
*/
@Override
@ -96,11 +98,12 @@ public class PolicyPageController extends PageController<NoPageParams> {
}
/**
* Updates the Platform Cert Validation policy setting and redirects back
* to the original page.
* Updates the Platform Cert Validation policy setting and redirects back to
* the original page.
*
* @param ppModel The data posted by the form mapped into an object.
* @param attr RedirectAttributes used to forward data back to the original page.
* @param attr RedirectAttributes used to forward data back to the original
* page.
* @return View containing the url and parameters
* @throws URISyntaxException if malformed URI
*/
@ -108,12 +111,11 @@ public class PolicyPageController extends PageController<NoPageParams> {
public RedirectView updatePcVal(@ModelAttribute final PolicyPageModel ppModel,
final RedirectAttributes attr) throws URISyntaxException {
Map<String, Object> model = new HashMap<>();
PageMessages messages = new PageMessages();
String successMessage;
boolean pcValidationOptionEnabled =
ppModel.getPcValidate().equalsIgnoreCase(ENABLED_PARAMETER_VALUE);
boolean pcValidationOptionEnabled
= ppModel.getPcValidate().equalsIgnoreCase(ENABLED_PARAMETER_VALUE);
try {
SupplyChainPolicy policy = getDefaultPolicyAndSetInModel(ppModel, model);
@ -122,8 +124,8 @@ public class PolicyPageController extends PageController<NoPageParams> {
if (!isPolicyValid(policy.isEcValidationEnabled(), pcValidationOptionEnabled,
policy.isPcAttributeValidationEnabled())) {
handleUserError(model, messages,
"Unable to change Platform Validation setting,"
+ " invalid policy configuration.");
"Unable to change Platform Validation setting,"
+ " invalid policy configuration.");
return redirectToSelf(new NoPageParams(), model, attr);
}
// set the policy option and create display message
@ -132,11 +134,11 @@ public class PolicyPageController extends PageController<NoPageParams> {
successMessage = "Platform certificate validation enabled";
} else {
policy.setPcValidationEnabled(false);
policy.setPcAttributeValidationEnabled(false);
successMessage = "Platform certificate validation disabled";
}
savePolicyAndApplySuccessMessage(ppModel, model, messages, successMessage, policy);
} catch (PolicyManagerException e) {
// Log and return any error messages to the user
handlePolicyManagerUpdateError(model, messages, e,
@ -147,19 +149,19 @@ public class PolicyPageController extends PageController<NoPageParams> {
}
/**
* Updates the Platform Cert Attribute Validation policy setting and redirects back
* to the original page.
* Updates the Platform Cert Attribute Validation policy setting and
* redirects back to the original page.
*
* @param ppModel The data posted by the form mapped into an object.
* @param attr RedirectAttributes used to forward data back to the original page.
* @param attr RedirectAttributes used to forward data back to the original
* page.
* @return View containing the url and parameters
* @throws URISyntaxException if malformed URI
*/
@RequestMapping(value = "update-pc-attribute-validation", method = RequestMethod.POST)
public RedirectView updatePcAttributeVal(@ModelAttribute final PolicyPageModel ppModel,
final RedirectAttributes attr)
throws URISyntaxException {
final RedirectAttributes attr)
throws URISyntaxException {
Map<String, Object> model = new HashMap<>();
PageMessages messages = new PageMessages();
@ -170,14 +172,13 @@ public class PolicyPageController extends PageController<NoPageParams> {
try {
SupplyChainPolicy policy = getDefaultPolicyAndSetInModel(ppModel, model);
// If PC Attribute Validation is enabled without PC Validation, disallow change
if (!isPolicyValid(policy.isEcValidationEnabled(),
policy.isPcValidationEnabled(), pcAttributeValidationOptionEnabled)) {
handleUserError(model, messages,
"To enable Platform Attribute Validation, Platform Credential Validation"
+ " must also be enabled.");
"To enable Platform Attribute Validation, Platform Credential Validation"
+ " must also be enabled.");
return redirectToSelf(new NoPageParams(), model, attr);
}
// set the policy option and create display message
@ -190,7 +191,6 @@ public class PolicyPageController extends PageController<NoPageParams> {
}
savePolicyAndApplySuccessMessage(ppModel, model, messages, successMessage, policy);
} catch (PolicyManagerException e) {
// Log and return any error messages to the user
handlePolicyManagerUpdateError(model, messages, e,
@ -201,11 +201,12 @@ public class PolicyPageController extends PageController<NoPageParams> {
}
/**
* Updates the Endorsement Credential Validation policy setting and redirects back
* to the original page.
* Updates the Endorsement Credential Validation policy setting and
* redirects back to the original page.
*
* @param ppModel The data posted by the form mapped into an object.
* @param attr RedirectAttributes used to forward data back to the original page.
* @param attr RedirectAttributes used to forward data back to the original
* page.
* @return View containing the url and parameters
* @throws URISyntaxException if malformed URI
*/
@ -217,8 +218,8 @@ public class PolicyPageController extends PageController<NoPageParams> {
Map<String, Object> model = new HashMap<>();
PageMessages messages = new PageMessages();
String successMessage;
boolean ecValidationOptionEnabled =
ppModel.getEcValidate().equalsIgnoreCase(ENABLED_PARAMETER_VALUE);
boolean ecValidationOptionEnabled
= ppModel.getEcValidate().equalsIgnoreCase(ENABLED_PARAMETER_VALUE);
try {
SupplyChainPolicy policy = getDefaultPolicyAndSetInModel(ppModel, model);
@ -227,8 +228,8 @@ public class PolicyPageController extends PageController<NoPageParams> {
if (!isPolicyValid(ecValidationOptionEnabled, policy.isPcValidationEnabled(),
policy.isPcAttributeValidationEnabled())) {
handleUserError(model, messages,
"To disable Endorsement Credential Validation, Platform Validation"
+ " must also be disabled.");
"To disable Endorsement Credential Validation, Platform Validation"
+ " must also be disabled.");
return redirectToSelf(new NoPageParams(), model, attr);
}
// set the policy option and create success message
@ -254,11 +255,12 @@ public class PolicyPageController extends PageController<NoPageParams> {
}
/**
* Updates the Endorsement Credential Validation policy setting and redirects back
* to the original page.
* Updates the Firmware Validation policy setting and
* redirects back to the original page.
*
* @param ppModel The data posted by the form mapped into an object.
* @param attr RedirectAttributes used to forward data back to the original page.
* @param attr RedirectAttributes used to forward data back to the original
* page.
* @return View containing the url and parameters
* @throws URISyntaxException if malformed URI
*/
@ -279,8 +281,8 @@ public class PolicyPageController extends PageController<NoPageParams> {
//If firmware is enabled without PC attributes, disallow change
if (firmwareValidationOptionEnabled && !policy.isPcAttributeValidationEnabled()) {
handleUserError(model, messages,
"Firmware validation can not be "
+ "enabled without PC Attributes policy enabled.");
"Firmware validation can not be "
+ "enabled without PC Attributes policy enabled.");
return redirectToSelf(new NoPageParams(), model, attr);
}
@ -290,13 +292,15 @@ public class PolicyPageController extends PageController<NoPageParams> {
successMessage = "Firmware validation enabled";
} else {
policy.setFirmwareValidationEnabled(false);
policy.getPcrPolicy().setEnableIgnoreIma(false);
policy.getPcrPolicy().setEnableIgnoretBoot(false);
successMessage = "Firmware validation disabled";
}
savePolicyAndApplySuccessMessage(ppModel, model, messages, successMessage, policy);
} catch (PolicyManagerException e) {
handlePolicyManagerUpdateError(model, messages, e,
"Error changing ACA endorsement validation policy",
"Error changing ACA firmware validation policy",
"Error updating policy. \n" + e.getMessage());
}
@ -305,26 +309,128 @@ public class PolicyPageController extends PageController<NoPageParams> {
return redirectToSelf(new NoPageParams(), model, attr);
}
/**
* Updates the ignore IMA policy setting and
* redirects back to the original page.
*
* @param ppModel The data posted by the form mapped into an object.
* @param attr RedirectAttributes used to forward data back to the original
* page.
* @return View containing the url and parameters
* @throws URISyntaxException if malformed URI
*/
@RequestMapping(value = "update-ima-ignore", method = RequestMethod.POST)
public RedirectView updateIgnoreIma(@ModelAttribute final PolicyPageModel ppModel,
final RedirectAttributes attr) throws URISyntaxException {
// set the data received to be populated back into the form
Map<String, Object> model = new HashMap<>();
PageMessages messages = new PageMessages();
String successMessage;
boolean ignoreImaOptionEnabled = ppModel.getIgnoreIma()
.equalsIgnoreCase(ENABLED_PARAMETER_VALUE);
try {
SupplyChainPolicy policy = getDefaultPolicyAndSetInModel(ppModel, model);
//If Ignore IMA is enabled without firmware, disallow change
if (ignoreImaOptionEnabled && !policy.isFirmwareValidationEnabled()) {
handleUserError(model, messages,
"Ignore IMA can not be "
+ "enabled without Firmware Valdiation policy enabled.");
return redirectToSelf(new NoPageParams(), model, attr);
}
// set the policy option and create success message
if (ignoreImaOptionEnabled) {
policy.getPcrPolicy().setEnableIgnoreIma(true);
successMessage = "Ignore IMA enabled";
} else {
policy.getPcrPolicy().setEnableIgnoreIma(false);
successMessage = "Ignore IMA disabled";
}
savePolicyAndApplySuccessMessage(ppModel, model, messages, successMessage, policy);
} catch (PolicyManagerException e) {
handlePolicyManagerUpdateError(model, messages, e,
"Error changing ACA IMA ignore policy",
"Error updating policy. \n" + e.getMessage());
}
// return the redirect
return redirectToSelf(new NoPageParams(), model, attr);
}
/**
* Updates the ignore TBoot policy setting and
* redirects back to the original page.
*
* @param ppModel The data posted by the form mapped into an object.
* @param attr RedirectAttributes used to forward data back to the original
* page.
* @return View containing the url and parameters
* @throws URISyntaxException if malformed URI
*/
@RequestMapping(value = "update-tboot-ignore", method = RequestMethod.POST)
public RedirectView updateIgnoreTboot(@ModelAttribute final PolicyPageModel ppModel,
final RedirectAttributes attr) throws URISyntaxException {
// set the data received to be populated back into the form
Map<String, Object> model = new HashMap<>();
PageMessages messages = new PageMessages();
String successMessage;
boolean ignoreTbootOptionEnabled = ppModel.getIgnoretBoot()
.equalsIgnoreCase(ENABLED_PARAMETER_VALUE);
try {
SupplyChainPolicy policy = getDefaultPolicyAndSetInModel(ppModel, model);
//If Ignore TBoot is enabled without firmware, disallow change
if (ignoreTbootOptionEnabled && !policy.isFirmwareValidationEnabled()) {
handleUserError(model, messages,
"Ignore TBoot can not be "
+ "enabled without Firmware Valdiation policy enabled.");
return redirectToSelf(new NoPageParams(), model, attr);
}
// set the policy option and create success message
if (ignoreTbootOptionEnabled) {
policy.getPcrPolicy().setEnableIgnoretBoot(true);
successMessage = "Ignore TBoot enabled";
} else {
policy.getPcrPolicy().setEnableIgnoretBoot(false);
successMessage = "Ignore TBoot disabled";
}
savePolicyAndApplySuccessMessage(ppModel, model, messages, successMessage, policy);
} catch (PolicyManagerException e) {
handlePolicyManagerUpdateError(model, messages, e,
"Error changing ACA TBoot ignore policy",
"Error updating policy. \n" + e.getMessage());
}
// return the redirect
return redirectToSelf(new NoPageParams(), model, attr);
}
private void handlePolicyManagerUpdateError(final Map<String, Object> model,
final PageMessages messages,
final PolicyManagerException e,
final String message, final String error) {
final PageMessages messages,
final PolicyManagerException e,
final String message, final String error) {
LOGGER.error(message, e);
messages.addError(error);
model.put(MESSAGES_ATTRIBUTE, messages);
}
private void handleUserError(final Map<String, Object> model,
final PageMessages messages,
final String errorMessage) {
final PageMessages messages,
final String errorMessage) {
messages.addError(errorMessage);
model.put(MESSAGES_ATTRIBUTE, messages);
}
/**
* Takes in policy setting states and determines if policy configuration is valid or not.
* PC Attribute Validation must have PC Validation Enabled
* PC Validation must have EC Validation enabled
* Takes in policy setting states and determines if policy configuration is
* valid or not. PC Attribute Validation must have PC Validation Enabled PC
* Validation must have EC Validation enabled
*
* @param isEcEnable EC Validation Policy State
* @param isPcEnable PC Validation Policy State
@ -353,9 +459,10 @@ public class PolicyPageController extends PageController<NoPageParams> {
supplyChainAppraiser);
}
/**
* Gets the default policy and applies the current values in to the page model.
* Gets the default policy and applies the current values in to the page
* model.
*
* @param ppModel the page model
* @param model the map of string messages to be displayed on the view
* @return The default Supply Chain Policy
@ -371,10 +478,10 @@ public class PolicyPageController extends PageController<NoPageParams> {
}
private void savePolicyAndApplySuccessMessage(final PolicyPageModel ppModel,
final Map<String, Object> model,
final PageMessages messages,
final String successMessage,
final SupplyChainPolicy policy) {
final Map<String, Object> model,
final PageMessages messages,
final String successMessage,
final SupplyChainPolicy policy) {
// save the policy to the DB
policyManager.updatePolicy(policy);

View File

@ -27,7 +27,7 @@
</li>
</form:form>
</div>
<%-- Platform validation --%>
<div class="aca-input-box">
<form:form method="POST" modelAttribute="initialData" action="policy/update-pc-validation">
@ -48,20 +48,21 @@
<div class="aca-input-box">
<form:form method="POST" modelAttribute="initialData" action="policy/update-pc-attribute-validation">
<ul>
<li>Platform Attribute Credential Validation: ${initialData.enablePcCertificateAttributeValidation ? 'Enabled' : 'Disabled'}
<my:editor id="pcAttributePolicyEditor" label="Edit Settings">
<div class="radio">
<label><input id="pcAttrTop" type="radio" name="pcAttributeValidate" ${initialData.enablePcCertificateAttributeValidation ? 'checked' : ''} value="checked"/> Platform Credential Attributes will be validated</label>
</div>
<div class="radio">
<label><input id="pcAttrBot" type="radio" name="pcAttributeValidate" ${initialData.enablePcCertificateAttributeValidation ? '' : 'checked'} value="unchecked"/> Platform Credential Attributes will not be validated</label>
</div>
</my:editor>
</li>
<li>Platform Attribute Credential Validation: ${initialData.enablePcCertificateAttributeValidation ? 'Enabled' : 'Disabled'}
<my:editor id="pcAttributePolicyEditor" label="Edit Settings">
<div class="radio">
<label><input id="pcAttrTop" type="radio" name="pcAttributeValidate" ${initialData.enablePcCertificateAttributeValidation ? 'checked' : ''} value="checked"/> Platform Credential Attributes will be validated</label>
</div>
<div class="radio">
<label><input id="pcAttrBot" type="radio" name="pcAttributeValidate" ${initialData.enablePcCertificateAttributeValidation ? '' : 'checked'} value="unchecked"/> Platform Credential Attributes will not be validated</label>
</div>
</my:editor>
</li>
</ul>
</form:form>
</div>
<%-- Firmware validation --%>
<div class="aca-input-box">
<form:form method="POST" modelAttribute="initialData" action="policy/update-firmware-validation">
<li>Firmware Validation: ${initialData.enableFirmwareValidation ? 'Enabled' : 'Disabled'}
@ -73,8 +74,34 @@
<label><input id="firmwareBot" type="radio" name="fmValidate" ${initialData.enableFirmwareValidation ? '' : 'checked'} value="unchecked"/> Firmware will not be validated</label>
</div>
</my:editor>
</li>
</form:form>
</form:form>
<ul>
<form:form method="POST" modelAttribute="initialData" action="policy/update-ima-ignore">
<li>Ignore IMA PCR Entry: ${initialData.enableIgnoreIma ? 'Enabled' : 'Disabled'}
<my:editor id="ignoreImaPolicyEditor" label="Edit Settings">
<div class="radio">
<label><input id="imaTop" type="radio" name="ignoreIma" ${initialData.enableIgnoreIma ? 'checked' : ''} value="checked"/> Ignore IMA enabled</label>
</div>
<div class="radio">
<label><input id="imaBot" type="radio" name="ignoreIma" ${initialData.enableIgnoreIma ? '' : 'checked'} value="unchecked"/> Ignore IMA disabled</label>
</div>
</my:editor>
</li>
</form:form>
<form:form method="POST" modelAttribute="initialData" action="policy/update-tboot-ignore">
<li>Ignore TBOOT PCRs Entry: ${initialData.enableIgnoreTboot ? 'Enabled' : 'Disabled'}
<my:editor id="ignoreTbootPolicyEditor" label="Edit Settings">
<div class="radio">
<label><input id="tbootTop" type="radio" name="ignoretBoot" ${initialData.enableIgnoreTboot ? 'checked' : ''} value="checked"/> Ignore TBoot enabled</label>
</div>
<div class="radio">
<label><input id="tbootBot" type="radio" name="ignoretBoot" ${initialData.enableIgnoreTboot ? '' : 'checked'} value="unchecked"/> Ignore TBoot disabled</label>
</div>
</my:editor>
</li>
</form:form>
</ul>
</li>
</div>
</ul>
</jsp:body>

View File

@ -13,7 +13,7 @@ public abstract class ArchivableEntity extends AbstractEntity {
/**
* Defining the size of a message field for error display.
*/
public static final int MAX_MESSAGE_LENGTH = 520;
public static final int MAX_MESSAGE_LENGTH = 1200;
@Column(name = "archived_time")
private Date archivedTime;

View File

@ -0,0 +1,144 @@
package hirs.data.persist;
import javax.persistence.Column;
import javax.persistence.Entity;
import static org.apache.logging.log4j.LogManager.getLogger;
import org.apache.logging.log4j.Logger;
/**
* The class handles the flags that ignore certain PCRs for validation.
*/
@Entity
public final class PCRPolicy extends Policy {
private static final Logger LOGGER = getLogger(PCRPolicy.class);
// PCR 10
private static final int IMA_PCR = 10;
// PCR 17-19
private static final int TBOOT_PCR = 17;
private static final int NUM_OF_IMA_PCR = 1;
private static final int NUM_OF_TBOOT_PCR = 3;
@Column(nullable = false)
private boolean enableIgnoreIma = false;
@Column(nullable = false)
private boolean enableIgnoretBoot = false;
@Column(nullable = false)
private boolean linuxOs = false;
private String[] baselinePcrs;
/**
* Default constructor.
*/
public PCRPolicy() {
baselinePcrs = new String[TPMMeasurementRecord.MAX_PCR_ID + 1];
}
/**
* Constructor to parse PCR values.
*
* @param pcrValues RIM provided baseline PCRs
*/
public PCRPolicy(final String[] pcrValues) {
baselinePcrs = new String[TPMMeasurementRecord.MAX_PCR_ID + 1];
for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) {
baselinePcrs[i] = pcrValues[i];
}
}
/**
* Compares the baseline pcr list and the quote pcr list. If the
* ignore flags are set, 10 and 17-19 will be skipped for comparison.
*
* @param quotePcrs non-baseline pcr list
* @return a StringBuilder that is empty if everything passes.
*/
public StringBuilder validatePcrs(final String[] quotePcrs) {
StringBuilder sb = new StringBuilder();
String failureMsg = "PCR %d does not match%n";
for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) {
if (enableIgnoreIma && i == IMA_PCR) {
LOGGER.info("PCR Policy IMA Ignore enabled.");
i += NUM_OF_IMA_PCR;
}
if (enableIgnoretBoot && i == TBOOT_PCR) {
LOGGER.info("PCR Policy TBoot Ignore enabled.");
i += NUM_OF_TBOOT_PCR;
}
if (!baselinePcrs[i].equals(quotePcrs[i])) {
sb.append(String.format(failureMsg, i));
}
}
return sb;
}
/**
* Getter for the array of baseline PCRs.
* @return instance of the PCRs.
*/
public String[] getBaselinePcrs() {
return baselinePcrs.clone();
}
/**
* Setter for the array of baseline PCRs.
* @param baselinePcrs instance of the PCRs.
*/
public void setBaselinePcrs(final String[] baselinePcrs) {
this.baselinePcrs = baselinePcrs.clone();
}
/**
* Getter for the IMA ignore flag.
* @return true if IMA is to be ignored.
*/
public boolean isEnableIgnoreIma() {
return enableIgnoreIma;
}
/**
* Setter for the IMA ignore flag.
* @param enableIgnoreIma true if IMA is to be ignored.
*/
public void setEnableIgnoreIma(final boolean enableIgnoreIma) {
this.enableIgnoreIma = enableIgnoreIma;
}
/**
* Getter for the TBoot ignore flag.
* @return true if TBoot is to be ignored.
*/
public boolean isEnableIgnoretBoot() {
return enableIgnoretBoot;
}
/**
* Setter for the TBoot ignore flag.
* @param enableIgnoretBoot true if TBoot is to be ignored.
*/
public void setEnableIgnoretBoot(final boolean enableIgnoretBoot) {
this.enableIgnoretBoot = enableIgnoretBoot;
}
/**
* Getter for a flag to indicate the type of OS.
* @return true if the system is linux.
*/
public boolean isLinuxOs() {
return linuxOs;
}
/**
* Setter for the type of OS.
* @param linuxOs value of the flag depending on the OS
*/
public void setLinuxOs(final boolean linuxOs) {
this.linuxOs = linuxOs;
}
}

View File

@ -1,6 +1,7 @@
package hirs.data.persist;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
/**
@ -36,6 +37,9 @@ public class SupplyChainPolicy extends Policy {
@Column(nullable = false)
private boolean replaceEC = false;
@Embedded
private PCRPolicy pcrPolicy = new PCRPolicy();
/**
* Constructor used to initialize SupplyChainPolicy object.
*
@ -147,6 +151,40 @@ public class SupplyChainPolicy extends Policy {
this.enableFirmwareValidation = enableFirmwareValidation;
}
/**
* Returns whether or not to validate the ignore ima on the device.
*
* @return whether or not to validate the ignore imag.
*/
public boolean isIgnoreImaEnabled() {
return this.pcrPolicy.isEnableIgnoreIma();
}
/**
* Sets whether or not validate the ignore ima on the device.
* @param enableIgnoreIma whether or not to validate the ignore ima
*/
public void setIgnoreImaEnabled(final boolean enableIgnoreIma) {
this.pcrPolicy.setEnableIgnoreIma(enableIgnoreIma);
}
/**
* Returns whether or not to validate the ignore tboot on the device.
*
* @return whether or not to validate the ignore tboot
*/
public boolean isIgnoreTbootEnabled() {
return this.pcrPolicy.isEnableIgnoretBoot();
}
/**
* Sets whether or not validate the ignore tboot on the device.
* @param enableIgnoreTboot whether or not to validate the ignore tboot
*/
public void setIgnoreTbootEnabled(final boolean enableIgnoreTboot) {
this.pcrPolicy.setEnableIgnoretBoot(enableIgnoreTboot);
}
/**
* Returns whether or not to allow expired credentials and certificates to be considered
* valid if their supply chain is otherwise verified.
@ -193,5 +231,17 @@ public class SupplyChainPolicy extends Policy {
this.replaceEC = replaceEC;
}
/**
* @return the PCR Policy
*/
public PCRPolicy getPcrPolicy() {
return pcrPolicy;
}
/**
* @param pcrPolicy to apply
*/
public void setPcrPolicy(final PCRPolicy pcrPolicy) {
this.pcrPolicy = pcrPolicy;
}
}

View File

@ -0,0 +1,121 @@
package hirs.data.persist;
import org.testng.Assert;
import org.testng.annotations.Test;
/**
* Tests for the PCRPolicyTest class.
*/
public class PCRPolicyTest {
private static final String[] BASELINE_PCRS = new String[]{
"cc8695ee470cd21f32de41df451376d9e751cadb",
"b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236",
"b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236",
"b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236",
"e6e2c4ee5c8c79fa9ca827dd2b1b8341872a141f",
"e44e1f53a4f2b2eabcdc9f2a450d84c0c3999364",
"b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236",
"c18a8143298f26eff6b01c1c8d859b6583261467",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"335425f6d34a0a601b1debfd34752f90226253f5",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000"};
private static final String[] QUOTE_PCRS = new String[]{
"cc8695ee470cd21f32de41df451376d9e751cadb",
"b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236",
"b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236",
"b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236",
"e6e2c4ee5c8c79fa9ca827dd2b1b8341872a141f",
"e44e1f53a4f2b2eabcdc9f2a450d84c0c3999364",
"b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236",
"c18a8143298f26eff6b01c1c8d859b6583261467",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"96c28d350ed092531d3f6f27d05a58d9f5dd8765",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"335425f6d34a0a601b1debfd34752f90226253f5",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"ffffffffffffffffffffffffffffffffffffffff",
"ffffffffffffffffffffffffffffffffffffffff",
"ffffffffffffffffffffffffffffffffffffffff",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000"};
/**
* Test of testValidatePcrsPass method, of class PCRPolicy.
*/
@Test
public void testValidatePcrsPass() {
PCRPolicy instance = new PCRPolicy(BASELINE_PCRS);
instance.setEnableIgnoreIma(false);
instance.setEnableIgnoretBoot(false);
StringBuilder result = instance.validatePcrs(BASELINE_PCRS);
Assert.assertEquals(result.length(), 0);
}
/**
* Test of testValidatePcrsFail method, of class PCRPolicy.
*/
@Test
public void testValidatePcrsFail() {
PCRPolicy instance = new PCRPolicy(BASELINE_PCRS);
instance.setEnableIgnoreIma(false);
instance.setEnableIgnoretBoot(false);
StringBuilder result = instance.validatePcrs(QUOTE_PCRS);
Assert.assertNotEquals(result.length(), 0);
}
/**
* Test of testValidatePcrsFailIgnoreIma method, of class PCRPolicy.
*/
@Test
public void testValidatePcrsFailIgnoreIma() {
PCRPolicy instance = new PCRPolicy(BASELINE_PCRS);
instance.setEnableIgnoreIma(true);
instance.setEnableIgnoretBoot(false);
StringBuilder result = instance.validatePcrs(QUOTE_PCRS);
Assert.assertNotEquals(result.length(), 0);
}
/**
* Test of testValidatePcrsFailIgnoreTBoot method, of class PCRPolicy.
*/
@Test
public void testValidatePcrsFailIgnoreTBoot() {
PCRPolicy instance = new PCRPolicy(BASELINE_PCRS);
instance.setEnableIgnoreIma(false);
instance.setEnableIgnoretBoot(true);
StringBuilder result = instance.validatePcrs(QUOTE_PCRS);
Assert.assertNotEquals(result.length(), 0);
}
/**
* Test of testValidatePcrsPassIgnoreImaAndTBoot method, of class PCRPolicy.
*/
@Test
public void testValidatePcrsPassIgnoreImaAndTBoot() {
PCRPolicy instance = new PCRPolicy(BASELINE_PCRS);
instance.setEnableIgnoreIma(true);
instance.setEnableIgnoretBoot(true);
StringBuilder result = instance.validatePcrs(QUOTE_PCRS);
Assert.assertEquals(result.length(), 0);
}
}