This branch takes the validated status of a failed event log matching from the bios measurements on the client and displays what failed on the support RIM page and the fail validation icon, if log mismatch, links to a bios measurments page that displays the events that didn't match next to baseline.

This commit is contained in:
Cyrus 2020-10-22 13:32:30 -04:00
parent 3df6eff549
commit d7ade70b5c
4 changed files with 325 additions and 103 deletions

View File

@ -332,6 +332,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
AppraisalStatus fwStatus = null;
String manufacturer = device.getDeviceInfo()
.getHardwareInfo().getManufacturer();
ReferenceManifest validationObject = null;
ReferenceManifest baseReferenceManifest = null;
ReferenceManifest supportReferenceManifest = null;
ReferenceManifest measurement = null;
@ -343,6 +344,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
measurement = BiosMeasurements.select(referenceManifestManager)
.byManufacturer(manufacturer).includeArchived().getRIM();
validationObject = baseReferenceManifest;
String failedString = "";
if (baseReferenceManifest == null) {
failedString = "Base Reference Integrity Manifest%n";
@ -401,6 +403,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
} else {
StringBuilder sb = pcrPolicy.validatePcrs(storedPcrs);
if (sb.length() > 0) {
validationObject = supportReferenceManifest;
level = Level.ERROR;
fwStatus = new AppraisalStatus(FAIL, sb.toString());
} else {
@ -436,6 +439,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
if (!tpmPcrEvents.isEmpty()) {
StringBuilder sb = new StringBuilder();
validationObject = measurement;
for (TpmPcrEvent tpe : tpmPcrEvents) {
sb.append(String.format("Event %s - %s%n",
tpe.getEventNumber(),
@ -458,7 +462,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
}
return buildValidationRecord(SupplyChainValidation.ValidationType.FIRMWARE,
fwStatus.getAppStatus(), fwStatus.getMessage(), baseReferenceManifest, level);
fwStatus.getAppStatus(), fwStatus.getMessage(), validationObject, level);
}
/**

View File

@ -1,6 +1,7 @@
package hirs.attestationca.portal.page.controllers;
import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.BiosMeasurements;
import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.SupportReferenceManifest;
import hirs.data.persist.SwidResource;
@ -17,10 +18,13 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.UUID;
import hirs.tpm.eventlog.TpmPcrEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
@ -113,117 +117,253 @@ public class ReferenceManifestDetailsPageController
* @throws NoSuchAlgorithmException If an unknown Algorithm is encountered.
* @throws CertificateException if a certificate doesn't parse.
*/
public static HashMap<String, Object> getRimDetailInfo(final UUID uuid,
final ReferenceManifestManager referenceManifestManager) throws IOException,
private HashMap<String, Object> getRimDetailInfo(
final UUID uuid,
final ReferenceManifestManager referenceManifestManager) throws IOException,
CertificateException, NoSuchAlgorithmException {
HashMap<String, Object> data = new HashMap<>();
ReferenceManifest rim = BaseReferenceManifest
.select(referenceManifestManager)
BaseReferenceManifest bRim = BaseReferenceManifest.select(referenceManifestManager)
.byEntityId(uuid).getRIM();
if (rim instanceof BaseReferenceManifest) {
BaseReferenceManifest bRim = (BaseReferenceManifest) rim;
// Software Identity
data.put("swidName", bRim.getSwidName());
data.put("swidVersion", bRim.getSwidVersion());
data.put("swidTagVersion", bRim.getSwidTagVersion());
if (bRim.isSwidCorpus() == 1) {
data.put("swidCorpus", "True");
} else {
data.put("swidCorpus", "False");
}
if (bRim.isSwidPatch() == 1) {
data.put("swidPatch", "True");
} else {
data.put("swidPatch", "False");
}
if (bRim.isSwidSupplemental() == 1) {
data.put("swidSupplemental", "True");
} else {
data.put("swidSupplemental", "False");
}
data.put("swidTagId", rim.getTagId());
// Entity
data.put("entityName", bRim.getEntityName());
data.put("entityRegId", bRim.getEntityRegId());
data.put("entityRole", bRim.getEntityRole());
data.put("entityThumbprint", bRim.getEntityThumbprint());
// Link
data.put("linkHref", bRim.getLinkHref());
data.put("linkRel", bRim.getLinkRel());
data.put("supportRimId", "");
data.put("supportRimTagId", "");
data.put("platformManufacturer", bRim.getPlatformManufacturer());
data.put("platformManufacturerId", bRim.getPlatformManufacturerId());
data.put("platformModel", bRim.getPlatformModel());
data.put("platformVersion", bRim.getPlatformVersion());
data.put("payloadType", bRim.getPayloadType());
data.put("colloquialVersion", bRim.getColloquialVersion());
data.put("edition", bRim.getEdition());
data.put("product", bRim.getProduct());
data.put("revision", bRim.getRevision());
data.put("bindingSpec", bRim.getBindingSpec());
data.put("bindingSpecVersion", bRim.getBindingSpecVersion());
data.put("pcUriGlobal", bRim.getPcURIGlobal());
data.put("pcUriLocal", bRim.getPcURILocal());
data.put("rimLinkHash", bRim.getRimLinkHash());
data.put("rimType", bRim.getRimType());
if (bRim != null) {
data.putAll(getBaseRimInfo(bRim, referenceManifestManager));
}
List<SwidResource> resources = bRim.parseResource();
TCGEventLog logProcessor = null;
ReferenceManifest support = null;
SupportReferenceManifest sRim = SupportReferenceManifest.select(referenceManifestManager)
.byEntityId(uuid).getRIM();
if (bRim.getAssociatedRim() == null) {
support = SupportReferenceManifest.select(referenceManifestManager)
.byManufacturer(bRim.getPlatformManufacturer())
.getRIM();
if (support != null) {
bRim.setAssociatedRim(support.getId());
logProcessor = new TCGEventLog(support.getRimBytes());
}
}
// going to have to pull the filename and grab that from the DB
// to get the id to make the link
for (SwidResource swidRes : resources) {
if (support != null && swidRes.getName()
.equals(support.getFileName())) {
swidRes.setPcrValues(Arrays.asList(
logProcessor.getExpectedPCRValues()));
break;
} else {
swidRes.setPcrValues(new ArrayList<>());
}
}
if (sRim != null) {
data.putAll(getSupportRimInfo(sRim, referenceManifestManager));
}
data.put("associatedRim", bRim.getAssociatedRim());
data.put("swidFiles", resources);
} else {
SupportReferenceManifest sRim = SupportReferenceManifest
.select(referenceManifestManager)
.byEntityId(uuid).getRIM();
BiosMeasurements bios = BiosMeasurements.select(referenceManifestManager)
.byEntityId(uuid).getRIM();
if (sRim.getAssociatedRim() == null) {
ReferenceManifest baseRim = BaseReferenceManifest.select(referenceManifestManager)
.byManufacturer(sRim.getPlatformManufacturer()).getRIM();
if (baseRim != null) {
sRim.setAssociatedRim(baseRim.getId());
try {
referenceManifestManager.update(sRim);
} catch (DBManagerException ex) {
LOGGER.error("Failed to update Support RIM", ex);
}
}
}
data.put("baseRim", sRim.getTagId());
data.put("associatedRim", sRim.getAssociatedRim());
data.put("rimType", sRim.getRimType());
data.put("tagId", sRim.getTagId());
TCGEventLog logProcessor = new TCGEventLog(sRim.getRimBytes());
data.put("events", logProcessor.getEventList());
if (bios != null) {
data.putAll(getMeasurementsRimInfo(bios, referenceManifestManager));
}
return data;
}
/**
* This method takes the place of an entire class for a string builder.
* Gathers all information and returns it for displays.
*
* @param baseRim established ReferenceManifest Type.
* @param referenceManifestManager the reference manifest manager.
* @return mapping of the RIM information from the database.
* @throws java.io.IOException error for reading file bytes.
* @throws NoSuchAlgorithmException If an unknown Algorithm is encountered.
* @throws CertificateException if a certificate doesn't parse.
*/
private HashMap<String, Object> getBaseRimInfo(
final BaseReferenceManifest baseRim,
final ReferenceManifestManager referenceManifestManager)
throws IOException, CertificateException, NoSuchAlgorithmException {
HashMap<String, Object> data = new HashMap<>();
// Software Identity
data.put("swidName", baseRim.getSwidName());
data.put("swidVersion", baseRim.getSwidVersion());
data.put("swidTagVersion", baseRim.getSwidTagVersion());
if (baseRim.isSwidCorpus() == 1) {
data.put("swidCorpus", "True");
} else {
data.put("swidCorpus", "False");
}
if (baseRim.isSwidPatch() == 1) {
data.put("swidPatch", "True");
} else {
data.put("swidPatch", "False");
}
if (baseRim.isSwidSupplemental() == 1) {
data.put("swidSupplemental", "True");
} else {
data.put("swidSupplemental", "False");
}
data.put("swidTagId", baseRim.getTagId());
// Entity
data.put("entityName", baseRim.getEntityName());
data.put("entityRegId", baseRim.getEntityRegId());
data.put("entityRole", baseRim.getEntityRole());
data.put("entityThumbprint", baseRim.getEntityThumbprint());
// Link
data.put("linkHref", baseRim.getLinkHref());
data.put("linkRel", baseRim.getLinkRel());
data.put("supportRimId", "");
data.put("supportRimTagId", "");
data.put("platformManufacturer", baseRim.getPlatformManufacturer());
data.put("platformManufacturerId", baseRim.getPlatformManufacturerId());
data.put("platformModel", baseRim.getPlatformModel());
data.put("platformVersion", baseRim.getPlatformVersion());
data.put("payloadType", baseRim.getPayloadType());
data.put("colloquialVersion", baseRim.getColloquialVersion());
data.put("edition", baseRim.getEdition());
data.put("product", baseRim.getProduct());
data.put("revision", baseRim.getRevision());
data.put("bindingSpec", baseRim.getBindingSpec());
data.put("bindingSpecVersion", baseRim.getBindingSpecVersion());
data.put("pcUriGlobal", baseRim.getPcURIGlobal());
data.put("pcUriLocal", baseRim.getPcURILocal());
data.put("rimLinkHash", baseRim.getRimLinkHash());
data.put("rimType", baseRim.getRimType());
List<SwidResource> resources = baseRim.parseResource();
TCGEventLog logProcessor = null;
ReferenceManifest support = null;
if (baseRim.getAssociatedRim() == null) {
support = SupportReferenceManifest.select(referenceManifestManager)
.byManufacturer(baseRim.getPlatformManufacturer())
.getRIM();
if (support != null) {
baseRim.setAssociatedRim(support.getId());
logProcessor = new TCGEventLog(support.getRimBytes());
}
}
// going to have to pull the filename and grab that from the DB
// to get the id to make the link
for (SwidResource swidRes : resources) {
if (support != null && swidRes.getName()
.equals(support.getFileName())) {
swidRes.setPcrValues(Arrays.asList(
logProcessor.getExpectedPCRValues()));
break;
} else {
swidRes.setPcrValues(new ArrayList<>());
}
}
data.put("associatedRim", baseRim.getAssociatedRim());
data.put("swidFiles", resources);
return data;
}
/**
* This method takes the place of an entire class for a string builder.
* Gathers all information and returns it for displays.
*
* @param support established ReferenceManifest Type.
* @param referenceManifestManager the reference manifest manager.
* @return mapping of the RIM information from the database.
* @throws java.io.IOException error for reading file bytes.
* @throws NoSuchAlgorithmException If an unknown Algorithm is encountered.
* @throws CertificateException if a certificate doesn't parse.
*/
private HashMap<String, Object> getSupportRimInfo(
final SupportReferenceManifest support,
final ReferenceManifestManager referenceManifestManager)
throws IOException, CertificateException, NoSuchAlgorithmException {
HashMap<String, Object> data = new HashMap<>();
if (support.getAssociatedRim() == null) {
ReferenceManifest baseRim = BaseReferenceManifest.select(referenceManifestManager)
.byManufacturer(support.getPlatformManufacturer()).getRIM();
if (baseRim != null) {
support.setAssociatedRim(baseRim.getId());
try {
referenceManifestManager.update(support);
} catch (DBManagerException ex) {
LOGGER.error("Failed to update Support RIM", ex);
}
}
}
data.put("baseRim", support.getTagId());
data.put("associatedRim", support.getAssociatedRim());
data.put("rimType", support.getRimType());
data.put("tagId", support.getTagId());
TCGEventLog logProcessor = new TCGEventLog(support.getRimBytes());
BiosMeasurements measurements = BiosMeasurements.select(referenceManifestManager)
.byManufacturer(support.getPlatformManufacturer()).getRIM();
LinkedList<TpmPcrEvent> tpmPcrEvents = new LinkedList<>();
TCGEventLog measurementsProcess;
if (measurements != null) {
measurementsProcess = new TCGEventLog((measurements.getRimBytes()));
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
if (!tpe.eventCompare(
measurementsProcess.getEventByNumber(
tpe.getEventNumber()))) {
tpe.setError(true);
}
tpmPcrEvents.add(tpe);
}
}
data.put("events", tpmPcrEvents);
return data;
}
/**
* This method takes the place of an entire class for a string builder.
* Gathers all information and returns it for displays.
*
* @param measurements established ReferenceManifest Type.
* @param referenceManifestManager the reference manifest manager.
* @return mapping of the RIM information from the database.
* @throws java.io.IOException error for reading file bytes.
* @throws NoSuchAlgorithmException If an unknown Algorithm is encountered.
* @throws CertificateException if a certificate doesn't parse.
*/
private HashMap<String, Object> getMeasurementsRimInfo(
final BiosMeasurements measurements,
final ReferenceManifestManager referenceManifestManager)
throws IOException, CertificateException, NoSuchAlgorithmException {
HashMap<String, Object> data = new HashMap<>();
LinkedList<TpmPcrEvent> supportEvents = new LinkedList<>();
LinkedList<TpmPcrEvent> livelogEvents = new LinkedList<>();
data.put("supportFilename", "Blank");
data.put("supportId", "");
data.put("tagId", measurements.getTagId());
data.put("baseId", "");
data.put("rimType", measurements.getRimType());
TCGEventLog supportLog = null;
SupportReferenceManifest support = SupportReferenceManifest
.select(referenceManifestManager)
.byManufacturer(measurements
.getPlatformManufacturer()).getRIM();
if (support != null) {
supportLog = new TCGEventLog(support.getRimBytes());
data.put("supportFilename", support.getFileName());
data.put("supportId", support.getId());
}
BaseReferenceManifest base = BaseReferenceManifest
.select(referenceManifestManager)
.byManufacturer(measurements
.getPlatformManufacturer()).getRIM();
if (base != null) {
data.put("baseId", base.getId());
}
TCGEventLog measurementLog = new TCGEventLog(measurements.getRimBytes());
if (supportLog != null) {
TpmPcrEvent measurementEvent;
for (TpmPcrEvent tpe : supportLog.getEventList()) {
measurementEvent = measurementLog.getEventByNumber(tpe.getEventNumber());
if (!tpe.eventCompare(measurementEvent)) {
supportEvents.add(tpe);
livelogEvents.add(measurementEvent);
}
}
}
data.put("supportEvents", supportEvents);
data.put("livelogEvents", livelogEvents);
for (Map.Entry<String, Object> entry : data.entrySet()) {
LOGGER.error(String.format("%s -> %s", entry.getKey(),
String.valueOf(entry.getValue())));
}
return data;
}
}

View File

@ -51,7 +51,14 @@
<c:if test="${not empty initialData.events}">
<c:set var="count" value="1" scope="page"/>
<c:forEach items="${initialData.events}" var="event">
<tr>
<c:choose>
<c:when test="${event.isError()}">
<tr style="background: tomato">
</c:when>
<c:otherwise>
<tr>
</c:otherwise>
</c:choose>
<td style="width: 75px">${count}</td>
<td class="pcrCell">PCR${event.getPcrIndex()}</td>
<td>${event.getEventTypeStr()}</td>
@ -66,6 +73,60 @@
</div>
<div class="col-md-a col-md-offset-1"><span class="colHeader">${initialData.events.size()} entries</span></div>
</c:when>
<c:when test="${initialData.rimType=='Measurement'}">
<div style="display: inline">
<div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Base/Support</span></div>
<div id="measurements" class="col col-md-8">
<c:if test="${not empty initialData.tagId}">
<div>Base:&nbsp;<span><a href="${portal}/rim-details?id=${initialData.baseId}">${initialData.tagId}</a></span>
</div>
</c:if>
<c:if test="${not empty initialData.supportId}">
<div>Support:&nbsp;<span><a href="${portal}/rim-details?id=${initialData.supportId}">${initialData.supportFilename}</a></span>
</div>
</c:if>
</div>
</div>
<br />
<div class="col-md-offset-1">
<div class="panel panel-default" style="width: 45%; display: inline-block; float: left; margin-right: 10px; word-wrap: break-word;">
<div class="panel-heading">Support</div>
<c:if test="${not empty initialData.supportEvents}">
<c:forEach items="${initialData.supportEvents}" var="sEvent">
<div class="panel-body">
<div style="background: lightgrey"><span class="fieldHeader">Event#:</span>
<span class="fieldValue">${sEvent.getEventNumber()}</span></div>
<span class="fieldHeader">PCR Index:</span>
<span class="fieldValue">${sEvent.getPcrIndex()}</span><br />
<span class="fieldHeader">Digest:</span>
<span class="fieldValue">${sEvent.getEventDigestStr()}</span><br />
<span class="fieldHeader">Content:</span>
<span class="fieldValue">${sEvent.getEventContentStr()}</span><br />
</div>
</c:forEach>
</c:if>
</div>
<div class="panel panel-default" style="width: 45%; display: inline-block; word-wrap: break-word;">
<div class="panel-heading">Client Log</div>
<c:if test="${not empty initialData.livelogEvents}">
<c:forEach items="${initialData.livelogEvents}" var="lEvent">
<div class="panel-body">
<div style="background: lightgrey"><span class="fieldHeader">Event#:</span>
<span class="fieldValue">${lEvent.getEventNumber()}</span></div>
<span class="fieldHeader">PCR Index:</span>
<span class="fieldValue">${lEvent.getPcrIndex()}</span><br />
<span class="fieldHeader">Digest:</span>
<span class="fieldValue">${lEvent.getEventDigestStr()}</span><br />
<span class="fieldHeader">Content:</span>
<span class="fieldValue">${lEvent.getEventContentStr()}</span><br />
</div>
</c:forEach>
</c:if>
</div>
</div>
</div>
</c:when>
<c:otherwise>
<div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Software Identity</span></div>
@ -275,7 +336,7 @@
}
}
}
window.onload = function() {
window.onload = function () {
// Constant retrieved from server-side via JSP
var maxRows = 11;

View File

@ -104,6 +104,7 @@ public class TpmPcrEvent {
private byte[] eventDataSha256hash;
private EvPostCode evPostCode;
private int eventNumber;
private boolean error = false;
/**
* Constructor.
@ -733,6 +734,22 @@ public class TpmPcrEvent {
return true;
}
/**
* Getter for error.
* @return there
*/
public boolean isError() {
return error;
}
/**
* Setter for error.
* @param error parameter
*/
public void setError(final boolean error) {
this.error = error;
}
/**
* Human readable string representing the contents of the Event Log.
*