mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-30 01:39:05 +00:00
* 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:
parent
1448b35e5e
commit
6a62002b05
@ -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,74 +315,73 @@ 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: "
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
int imaValue = IMA_TEN;
|
||||
String pcrNum;
|
||||
String pcrValue;
|
||||
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;
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
//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++) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
//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"
|
||||
+ " Certificate can not be found.");
|
||||
|
@ -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{"
|
||||
|
@ -36,29 +36,30 @@ 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
|
||||
*/
|
||||
@ -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);
|
||||
@ -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,11 +149,12 @@ 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
|
||||
*/
|
||||
@ -160,7 +163,6 @@ public class PolicyPageController extends PageController<NoPageParams> {
|
||||
final RedirectAttributes attr)
|
||||
throws URISyntaxException {
|
||||
|
||||
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
PageMessages messages = new PageMessages();
|
||||
String successMessage;
|
||||
@ -170,7 +172,6 @@ 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)) {
|
||||
@ -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);
|
||||
@ -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
|
||||
*/
|
||||
@ -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,6 +309,108 @@ 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,
|
||||
@ -322,9 +428,9 @@ public class PolicyPageController extends PageController<NoPageParams> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -62,6 +62,7 @@
|
||||
</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>
|
||||
</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>
|
||||
|
@ -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;
|
||||
|
144
HIRS_Utils/src/main/java/hirs/data/persist/PCRPolicy.java
Normal file
144
HIRS_Utils/src/main/java/hirs/data/persist/PCRPolicy.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
121
HIRS_Utils/src/test/java/hirs/data/persist/PCRPolicyTest.java
Normal file
121
HIRS_Utils/src/test/java/hirs/data/persist/PCRPolicyTest.java
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user