Merge pull request #350 from nsacyber/ignore-gpt-events

[#349] Ignore GPT PCR
This commit is contained in:
Cyrus 2021-05-04 10:14:53 -04:00 committed by GitHub
commit 1d33054577
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 160 additions and 15 deletions

View File

@ -17,6 +17,7 @@ public class PolicyPageModel {
private boolean generateOnExpiration; private boolean generateOnExpiration;
private boolean enableIgnoreIma; private boolean enableIgnoreIma;
private boolean enableIgnoreTboot; private boolean enableIgnoreTboot;
private boolean enableIgnoreGpt;
// Variables to get policy settings from page // Variables to get policy settings from page
private String pcValidate; private String pcValidate;
@ -29,6 +30,7 @@ public class PolicyPageModel {
private String reissueThreshold; private String reissueThreshold;
private String ignoreIma; private String ignoreIma;
private String ignoretBoot; private String ignoretBoot;
private String ignoreGpt;
private String expirationValue; private String expirationValue;
private String thresholdValue; private String thresholdValue;
@ -48,6 +50,7 @@ public class PolicyPageModel {
this.reissueThreshold = policy.getReissueThreshold(); this.reissueThreshold = policy.getReissueThreshold();
this.enableIgnoreIma = policy.isIgnoreImaEnabled(); this.enableIgnoreIma = policy.isIgnoreImaEnabled();
this.enableIgnoreTboot = policy.isIgnoreTbootEnabled(); this.enableIgnoreTboot = policy.isIgnoreTbootEnabled();
this.enableIgnoreGpt = policy.isIgnoreGptEnabled();
this.expirationValue = policy.getValidityDays(); this.expirationValue = policy.getValidityDays();
this.thresholdValue = policy.getReissueThreshold(); this.thresholdValue = policy.getReissueThreshold();
} }
@ -128,6 +131,14 @@ public class PolicyPageModel {
return enableIgnoreTboot; return enableIgnoreTboot;
} }
/**
* Gets the Enable Ignore GPT state.
* @return the validation state.
*/
public boolean getEnableIgnoreGpt() {
return enableIgnoreGpt;
}
/** /**
* Gets the EC Validation value. * Gets the EC Validation value.
* *
@ -218,6 +229,15 @@ public class PolicyPageModel {
return ignoretBoot; return ignoretBoot;
} }
/**
* Gets the Ignore GPT validation value.
*
* @return the model string representation of this field (checked or unchecked)
*/
public String getIgnoreGpt() {
return ignoreGpt;
}
/** /**
* Sets the EC Validation state. * Sets the EC Validation state.
* *
@ -292,6 +312,15 @@ public class PolicyPageModel {
this.enableIgnoreTboot = enableIgnoreTboot; this.enableIgnoreTboot = enableIgnoreTboot;
} }
/**
* Sets the Enable Ignore GPT state.
*
* @param enableIgnoreGpt true if performing validation, false otherwise
*/
public void setEnableIgnoreGpt(final boolean enableIgnoreGpt) {
this.enableIgnoreGpt = enableIgnoreGpt;
}
/** /**
* Sets the Platform Certificate Validation state. * Sets the Platform Certificate Validation state.
* *
@ -366,6 +395,15 @@ public class PolicyPageModel {
this.ignoretBoot = ignoretBoot; this.ignoretBoot = ignoretBoot;
} }
/**
* Sets the Ignore GPT state.
*
* @param ignoreGpt "checked" if enabling validation, false otherwise
*/
public void setIgnoreGpt(final String ignoreGpt) {
this.ignoreGpt = ignoreGpt;
}
/** /**
* Getter for the expiration value. * Getter for the expiration value.
* @return the value * @return the value

View File

@ -1,21 +1,16 @@
package hirs.attestationca.portal.page.controllers; package hirs.attestationca.portal.page.controllers;
import hirs.appraiser.Appraiser;
import hirs.appraiser.SupplyChainAppraiser;
import hirs.attestationca.portal.model.PolicyPageModel; import hirs.attestationca.portal.model.PolicyPageModel;
import static hirs.attestationca.portal.page.Page.POLICY;
import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageController;
import hirs.attestationca.portal.page.PageMessages; import hirs.attestationca.portal.page.PageMessages;
import hirs.attestationca.portal.page.params.NoPageParams; import hirs.attestationca.portal.page.params.NoPageParams;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import static org.apache.logging.log4j.LogManager.getLogger;
import org.apache.logging.log4j.Logger;
import hirs.appraiser.Appraiser;
import hirs.appraiser.SupplyChainAppraiser;
import hirs.data.persist.SupplyChainPolicy; import hirs.data.persist.SupplyChainPolicy;
import hirs.persist.AppraiserManager; import hirs.persist.AppraiserManager;
import hirs.persist.PolicyManager; import hirs.persist.PolicyManager;
import hirs.persist.PolicyManagerException; import hirs.persist.PolicyManagerException;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
@ -26,6 +21,13 @@ import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.RedirectView; import org.springframework.web.servlet.view.RedirectView;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import static hirs.attestationca.portal.page.Page.POLICY;
import static org.apache.logging.log4j.LogManager.getLogger;
/** /**
* Controller for the Policy page. * Controller for the Policy page.
*/ */
@ -471,6 +473,7 @@ public class PolicyPageController extends PageController<NoPageParams> {
// set the policy option and create success message // set the policy option and create success message
if (firmwareValidationOptionEnabled) { if (firmwareValidationOptionEnabled) {
policy.setFirmwareValidationEnabled(true); policy.setFirmwareValidationEnabled(true);
policy.setIgnoreGptEnabled(true);
successMessage = "Firmware validation enabled"; successMessage = "Firmware validation enabled";
} else { } else {
policy.setFirmwareValidationEnabled(false); policy.setFirmwareValidationEnabled(false);
@ -593,6 +596,57 @@ public class PolicyPageController extends PageController<NoPageParams> {
return redirectToSelf(new NoPageParams(), model, attr); return redirectToSelf(new NoPageParams(), model, attr);
} }
/**
* Updates the ignore GPT 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-gpt-ignore", method = RequestMethod.POST)
public RedirectView updateIgnoreGptEvents(@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 ignoreGptOptionEnabled = ppModel.getIgnoreGpt()
.equalsIgnoreCase(ENABLED_CHECKED_PARAMETER_VALUE);
try {
SupplyChainPolicy policy = getDefaultPolicyAndSetInModel(ppModel, model);
//If Ignore TBoot is enabled without firmware, disallow change
if (ignoreGptOptionEnabled && !policy.isFirmwareValidationEnabled()) {
handleUserError(model, messages,
"Ignore TBoot can not be "
+ "enabled without Firmware Validation policy enabled.");
return redirectToSelf(new NoPageParams(), model, attr);
}
// set the policy option and create success message
if (ignoreGptOptionEnabled) {
policy.getPcrPolicy().setEnableIgnoreGpt(true);
successMessage = "Ignore GPT enabled";
} else {
policy.getPcrPolicy().setEnableIgnoreGpt(false);
successMessage = "Ignore GPT disabled";
}
savePolicyAndApplySuccessMessage(ppModel, model, messages, successMessage, policy);
} catch (PolicyManagerException e) {
handlePolicyManagerUpdateError(model, messages, e,
"Error changing ACA GPT 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, private void handlePolicyManagerUpdateError(final Map<String, Object> model,
final PageMessages messages, final PageMessages messages,
final PolicyManagerException e, final PolicyManagerException e,

View File

@ -100,6 +100,18 @@
</my:editor> </my:editor>
</li> </li>
</form:form> </form:form>
<form:form method="POST" modelAttribute="initialData" action="policy/update-gpt-ignore">
<li>Ignore GPT PCRs Entry: ${initialData.enableIgnoreGpt ? 'Enabled' : 'Disabled'}
<my:editor id="ignoreGptPolicyEditor" label="Edit Settings">
<div class="radio">
<label><input id="gptTop" type="radio" name="ignoreGpt" ${initialData.enableIgnoreGpt ? 'checked' : ''} value="checked"/> Ignore GPT enabled</label>
</div>
<div class="radio">
<label><input id="gptBot" type="radio" name="ignoreGpt" ${initialData.enableIgnoreGpt ? '' : 'checked'} value="unchecked"/> Ignore GPT disabled</label>
</div>
</my:editor>
</li>
</form:form>
</ul> </ul>
</li> </li>
</div> </div>

View File

@ -1,10 +1,5 @@
package hirs.data.persist; package hirs.data.persist;
import javax.persistence.Column;
import javax.persistence.Entity;
import static org.apache.logging.log4j.LogManager.getLogger;
import hirs.data.persist.tpm.PcrComposite; import hirs.data.persist.tpm.PcrComposite;
import hirs.data.persist.tpm.PcrInfoShort; import hirs.data.persist.tpm.PcrInfoShort;
import hirs.data.persist.tpm.PcrSelection; import hirs.data.persist.tpm.PcrSelection;
@ -12,10 +7,14 @@ import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.binary.Hex;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import javax.persistence.Column;
import javax.persistence.Entity;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Arrays; import java.util.Arrays;
import static org.apache.logging.log4j.LogManager.getLogger;
/** /**
* The class handles the flags that ignore certain PCRs for validation. * The class handles the flags that ignore certain PCRs for validation.
*/ */
@ -24,12 +23,14 @@ public final class PCRPolicy extends Policy {
private static final Logger LOGGER = getLogger(PCRPolicy.class); private static final Logger LOGGER = getLogger(PCRPolicy.class);
private static final int NUM_TO_SKIP = 1;
// PCR 10 // PCR 10
private static final int IMA_PCR = 10; private static final int IMA_PCR = 10;
// PCR 17-19 // PCR 17-19
private static final int TBOOT_PCR = 17; 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; private static final int NUM_OF_TBOOT_PCR = 3;
// PCR 5
private static final int GPT_PCR = 5;
@Column(nullable = false) @Column(nullable = false)
private boolean enableIgnoreIma = false; private boolean enableIgnoreIma = false;
@ -37,6 +38,8 @@ public final class PCRPolicy extends Policy {
private boolean enableIgnoretBoot = false; private boolean enableIgnoretBoot = false;
@Column(nullable = false) @Column(nullable = false)
private boolean linuxOs = false; private boolean linuxOs = false;
@Column(nullable = false)
private boolean enableIgnoreGpt = true;
private String[] baselinePcrs; private String[] baselinePcrs;
@ -73,7 +76,7 @@ public final class PCRPolicy extends Policy {
for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) { for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) {
if (enableIgnoreIma && i == IMA_PCR) { if (enableIgnoreIma && i == IMA_PCR) {
LOGGER.info("PCR Policy IMA Ignore enabled."); LOGGER.info("PCR Policy IMA Ignore enabled.");
i += NUM_OF_IMA_PCR; i += NUM_TO_SKIP;
} }
if (enableIgnoretBoot && i == TBOOT_PCR) { if (enableIgnoretBoot && i == TBOOT_PCR) {
@ -81,6 +84,11 @@ public final class PCRPolicy extends Policy {
i += NUM_OF_TBOOT_PCR; i += NUM_OF_TBOOT_PCR;
} }
if (enableIgnoreGpt && i == GPT_PCR) {
LOGGER.info("PCR Policy GPT Ignore enabled.");
i += NUM_TO_SKIP;
}
if (!baselinePcrs[i].equals(storedPcrs[i])) { if (!baselinePcrs[i].equals(storedPcrs[i])) {
sb.append(String.format(failureMsg, i)); sb.append(String.format(failureMsg, i));
} }
@ -183,6 +191,22 @@ public final class PCRPolicy extends Policy {
this.enableIgnoretBoot = enableIgnoretBoot; this.enableIgnoretBoot = enableIgnoretBoot;
} }
/**
* Getter for the GPT ignore flag.
* @return true if GPT is to be ignored.
*/
public boolean isEnableIgnoreGpt() {
return enableIgnoreGpt;
}
/**
* Setter for the GPT ignore flag.
* @param enableIgnoreGpt true if GPT is to be ignored.
*/
public void setEnableIgnoreGpt(final boolean enableIgnoreGpt) {
this.enableIgnoreGpt = enableIgnoreGpt;
}
/** /**
* Getter for a flag to indicate the type of OS. * Getter for a flag to indicate the type of OS.
* @return true if the system is linux. * @return true if the system is linux.

View File

@ -205,6 +205,23 @@ public class SupplyChainPolicy extends Policy {
this.pcrPolicy.setEnableIgnoretBoot(enableIgnoreTboot); this.pcrPolicy.setEnableIgnoretBoot(enableIgnoreTboot);
} }
/**
* Returns whether or not to validate the ignore GPT on the device.
*
* @return whether or not to validate the ignore GPT
*/
public boolean isIgnoreGptEnabled() {
return this.pcrPolicy.isEnableIgnoreGpt();
}
/**
* Sets whether or not validate the ignore GPT on the device.
* @param enableIgnoreGpt whether or not to validate the ignore GPT
*/
public void setIgnoreGptEnabled(final boolean enableIgnoreGpt) {
this.pcrPolicy.setEnableIgnoreGpt(enableIgnoreGpt);
}
/** /**
* Returns whether or not to allow expired credentials and certificates to be considered * Returns whether or not to allow expired credentials and certificates to be considered
* valid if their supply chain is otherwise verified. * valid if their supply chain is otherwise verified.