Merge pull request #398 from nsacyber/issue-395

[#395] Front end changes for new TPM Events page
This commit is contained in:
chubtub 2022-02-24 14:14:59 -05:00 committed by GitHub
commit 3c8bc02dfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 774 additions and 130 deletions

View File

@ -1006,14 +1006,15 @@ public abstract class AbstractAttestationCertificateAuthority
rdr = referenceDigestManager.saveRecord(dbObj);
} // right now this will not deal with updating
if (this.referenceEventManager.getValuesByRecordId(rdr).isEmpty()) {
if (this.referenceEventManager.getValuesByRimId(dbSupport).isEmpty()) {
try {
TCGEventLog logProcessor = new TCGEventLog(dbSupport.getRimBytes());
ReferenceDigestValue rdv;
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
rdv = new ReferenceDigestValue(rdr.getId(), tpe.getPcrIndex(),
rdv = new ReferenceDigestValue(dbSupport.getAssociatedRim(),
dbSupport.getId(), manufacturer, model, tpe.getPcrIndex(),
tpe.getEventDigestStr(), tpe.getEventTypeStr(),
false, false);
false, false, tpe.getEventContent());
this.referenceEventManager.saveValue(rdv);
}
} catch (CertificateException cEx) {
@ -1045,25 +1046,22 @@ public abstract class AbstractAttestationCertificateAuthority
}
}
} else if (dbSupport.isSwidSupplemental() && !dbSupport.isProcessed()) {
if (rdr != null) {
try {
TCGEventLog logProcessor = new TCGEventLog(dbSupport.getRimBytes());
ReferenceDigestValue rdv;
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
rdv = new ReferenceDigestValue(rdr.getId(), tpe.getPcrIndex(),
rdv = new ReferenceDigestValue(dbSupport.getAssociatedRim(),
dbSupport.getId(), manufacturer, model, tpe.getPcrIndex(),
tpe.getEventDigestStr(), tpe.getEventTypeStr(),
false, false);
false, false, tpe.getEventContent());
this.referenceEventManager.saveValue(rdv);
}
dbSupport.setProcessed(true);
this.referenceManifestManager.update(dbSupport);
} catch (CertificateException cEx) {
LOG.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOG.error(noSaEx);
} catch (IOException ioEx) {
LOG.error(ioEx);
}
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -9,7 +9,6 @@ import hirs.data.persist.Device;
import hirs.data.persist.DeviceInfoReport;
import hirs.data.persist.EventLogMeasurements;
import hirs.data.persist.PCRPolicy;
import hirs.data.persist.ReferenceDigestRecord;
import hirs.data.persist.ReferenceDigestValue;
import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.SupplyChainPolicy;
@ -390,7 +389,6 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
BaseReferenceManifest baseReferenceManifest = null;
ReferenceManifest supportReferenceManifest = null;
EventLogMeasurements measurement = null;
ReferenceDigestRecord digestRecord = null;
baseReferenceManifests = BaseReferenceManifest.select(referenceManifestManager)
.byModel(model).getRIMs();
@ -532,7 +530,6 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
// vs baseline tcg event log
// find the measurement
TCGEventLog tcgMeasurementLog;
digestRecord = this.referenceDigestManager.getRecord(manufacturer, model);
LinkedList<TpmPcrEvent> tpmPcrEvents = new LinkedList<>();
List<ReferenceDigestValue> eventValue;
HashMap<String, ReferenceDigestValue> eventValueMap = new HashMap<>();
@ -540,7 +537,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
if (measurement.getPlatformManufacturer().equals(manufacturer)) {
tcgMeasurementLog = new TCGEventLog(measurement.getRimBytes());
eventValue = this.referenceEventManager
.getValuesByRecordId(digestRecord);
.getValuesByRimId(supportReferenceManifest);
for (ReferenceDigestValue rdv : eventValue) {
eventValueMap.put(rdv.getDigestValue(), rdv);
}

View File

@ -54,6 +54,10 @@ public enum Page {
*/
RIM_DETAILS("Reference Integrity Manifest Details",
"", null, true, false, null, null),
/**
* Page to display RIM event digest table.
*/
RIM_DATABASE("RIM Database", "ic_important_devices", "first"),
/**
* Page that manages Attestation CA Policy.
*/

View File

@ -7,7 +7,6 @@ import hirs.attestationca.portal.page.params.ReferenceManifestDetailsPageParams;
import hirs.attestationca.service.SupplyChainValidationServiceImpl;
import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.EventLogMeasurements;
import hirs.data.persist.ReferenceDigestRecord;
import hirs.data.persist.ReferenceDigestValue;
import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.SupportReferenceManifest;
@ -118,9 +117,6 @@ public class ReferenceManifestDetailsPageController
LOGGER.error(uuidError, iaEx);
} catch (Exception ioEx) {
LOGGER.error(ioEx);
for (StackTraceElement ste : ioEx.getStackTrace()) {
LOGGER.error(ste.toString());
}
}
if (data.isEmpty()) {
String notFoundMessage = "Unable to find RIM with ID: " + params.getId();
@ -522,7 +518,6 @@ public class ReferenceManifestDetailsPageController
BaseReferenceManifest base = null;
List<SupportReferenceManifest> supports = new ArrayList<>();
SupportReferenceManifest baseSupport = null;
List<ReferenceDigestRecord> digestRecords = new LinkedList<>();
data.put("supportFilename", "Blank");
data.put("supportId", "");
@ -532,9 +527,8 @@ public class ReferenceManifestDetailsPageController
data.put("validationResult", measurements.getOverallValidationResult());
data.put("swidBase", true);
List<ReferenceDigestValue> eventValues = new ArrayList<>();
if (measurements.getDeviceName() != null) {
digestRecords = referenceDigestManager
.getRecordsByDeviceName(measurements.getDeviceName());
supports.addAll(SupportReferenceManifest
.select(referenceManifestManager)
.byDeviceName(measurements
@ -558,18 +552,15 @@ public class ReferenceManifestDetailsPageController
if (base != null) {
data.put("associatedRim", base.getId());
}
eventValues.addAll(referenceEventManager.getValuesByRimId(base));
}
}
TCGEventLog measurementLog = new TCGEventLog(measurements.getRimBytes());
List<ReferenceDigestValue> eventValue = new ArrayList<>();
Map<String, ReferenceDigestValue> eventValueMap = new HashMap<>();
if (!digestRecords.isEmpty()) {
for (ReferenceDigestRecord rdr : digestRecords) {
eventValue.addAll(referenceEventManager
.getValuesByRecordId(rdr));
}
for (ReferenceDigestValue rdv : eventValue) {
for (ReferenceDigestValue rdv : eventValues) {
eventValueMap.put(rdv.getDigestValue(), rdv);
}
for (TpmPcrEvent measurementEvent : measurementLog.getEventList()) {
@ -577,7 +568,6 @@ public class ReferenceManifestDetailsPageController
livelogEvents.add(measurementEvent);
}
}
}
if (!supports.isEmpty()) {
Map<String, List<TpmPcrEvent>> baselineLogEvents = new HashMap<>();

View File

@ -10,14 +10,17 @@ import hirs.attestationca.portal.page.PageController;
import hirs.attestationca.portal.page.PageMessages;
import hirs.attestationca.portal.page.params.NoPageParams;
import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.EventLogMeasurements;
import hirs.data.persist.ReferenceDigestValue;
import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.SupportReferenceManifest;
import hirs.data.persist.SwidResource;
import hirs.data.persist.certificate.Certificate;
import hirs.persist.CriteriaModifier;
import hirs.persist.DBManagerException;
import hirs.persist.ReferenceEventManager;
import hirs.persist.ReferenceManifestManager;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.tpm.eventlog.TpmPcrEvent;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.logging.log4j.LogManager;
@ -43,6 +46,7 @@ import java.io.IOException;
import java.net.URISyntaxException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@ -70,6 +74,7 @@ public class ReferenceManifestPageController
private final BiosDateValidator biosValidator;
private final ReferenceManifestManager referenceManifestManager;
private final ReferenceEventManager referenceEventManager;
private static final Logger LOGGER
= LogManager.getLogger(ReferenceManifestPageController.class);
@ -119,12 +124,15 @@ public class ReferenceManifestPageController
* Constructor providing the Page's display and routing specification.
*
* @param referenceManifestManager the reference manifest manager
* @param referenceEventManager this is the reference event manager
*/
@Autowired
public ReferenceManifestPageController(
final ReferenceManifestManager referenceManifestManager) {
final ReferenceManifestManager referenceManifestManager,
final ReferenceEventManager referenceEventManager) {
super(Page.REFERENCE_MANIFESTS);
this.referenceManifestManager = referenceManifestManager;
this.referenceEventManager = referenceEventManager;
this.biosValidator = new BiosDateValidator(BIOS_RELEASE_DATE_FORMAT);
}
@ -174,6 +182,29 @@ public class ReferenceManifestPageController
referenceManifestManager,
input, orderColumnName, criteriaModifier);
SupportReferenceManifest support;
// List<ReferenceDigestValue> events;
// for (ReferenceManifest rim : records) {
// if (rim instanceof SupportReferenceManifest) {
// support = (SupportReferenceManifest) rim;
// events = referenceEventManager.getValuesByRimId(support);
//
// for (ReferenceDigestValue rdv : events) {
// // the selector isn't giving me what I want
// if (support.getPlatformManufacturer() != null) {
// rdv.setManufacturer(support.getPlatformManufacturer());
// }
// if (support.getPlatformModel() != null) {
// rdv.setModel(support.getPlatformModel());
// }
// if (support.getAssociatedRim() != null) {
// rdv.setBaseRimId(support.getAssociatedRim());
// }
// referenceEventManager.updateRecord(rdv);
// }
// }
// }
LOGGER.debug("Returning list of size: " + records.size());
return new DataTableResponse<>(records, input);
}
@ -208,34 +239,42 @@ public class ReferenceManifestPageController
//Parse reference manifests
ReferenceManifest rim = parseRIM(file, supportRIM, messages);
// store first then update
ReferenceManifest referenceManifest = storeManifest(file.getOriginalFilename(),
messages,
rim,
supportRIM);
//Store only if it was parsed
if (rim != null) {
if (supportRIM) {
// look for associated base/support
// if I am the support rim, my hash is in the meta data of the swidtag
Set<BaseReferenceManifest> rims = BaseReferenceManifest
.select(referenceManifestManager).getRIMs();
support = (SupportReferenceManifest) rim;
// update information for associated support rim
for (BaseReferenceManifest dbRim : rims) {
for (SwidResource swid : dbRim.parseResource()) {
if (swid.getName().equals(rim.getFileName())) {
support.setSwidTagVersion(dbRim.getSwidTagVersion());
support.setPlatformManufacturer(dbRim.getPlatformManufacturer());
support.setPlatformModel(dbRim.getPlatformModel());
support.setTagId(dbRim.getTagId());
support.setAssociatedRim(dbRim.getId());
support.setUpdated(true);
for (BaseReferenceManifest bRim : rims) {
for (SwidResource swid : bRim.parseResource()) {
if (support.getHexDecHash().equals(swid.getHashValue())) {
updateSupportRimInfo(bRim, support);
referenceManifestManager.update(support);
}
}
if (support.isUpdated()) {
for (ReferenceDigestValue rdv : referenceEventManager
.getValuesByRimId(support)) {
rdv.updateInfo(support);
referenceEventManager.updateRecord(rdv);
}
break;
}
}
}
} else {
base = (BaseReferenceManifest) rim;
base = (BaseReferenceManifest) referenceManifest;
// the base can find the support rim by the meta data hash
for (SwidResource swid : base.parseResource()) {
support = SupportReferenceManifest.select(referenceManifestManager)
.byFileName(swid.getName()).getRIM();
.byHexDecHash(swid.getHashValue()).getRIM();
if (support != null) {
base.setAssociatedRim(support.getId());
if (support.isUpdated()) {
@ -243,39 +282,20 @@ public class ReferenceManifestPageController
// instead of finding it, it is uptodate but still search
break;
} else {
support.setSwidTagVersion(base.getSwidTagVersion());
support.setPlatformManufacturer(base.getPlatformManufacturer());
support.setPlatformModel(base.getPlatformModel());
support.setTagId(base.getTagId());
support.setUpdated(true);
updateSupportRimInfo(base, support);
updateTpmEvents(support);
try {
referenceManifestManager.update(support);
} catch (DBManagerException dbmEx) {
LOGGER.error(String.format("Couldn't update Support RIM "
+ "%s with associated UUID %s", rim.getTagId(),
support.getId()), dbmEx);
LOGGER.warn("Failed to update Support RIM");
}
}
}
}
for (EventLogMeasurements liveLog : EventLogMeasurements
.select(referenceManifestManager).getRIMs()) {
if (liveLog.getPlatformManufacturer().equals(base.getPlatformManufacturer())
&& liveLog.getPlatformModel().equals(base.getPlatformModel())) {
rim.setEventLogHash(liveLog.getEventLogHash());
break;
}
}
}
storeManifest(file.getOriginalFilename(),
messages,
rim,
supportRIM);
}
}
//Add messages to the model
model.put(MESSAGES_ATTRIBUTE, messages);
@ -314,6 +334,17 @@ public class ReferenceManifestPageController
String deleteCompletedMessage = "RIM successfully deleted";
messages.addInfo(deleteCompletedMessage);
LOGGER.info(deleteCompletedMessage);
// if support rim, update associated events
if (referenceManifest instanceof SupportReferenceManifest) {
List<ReferenceDigestValue> rdvs = referenceEventManager
.getValuesByRimId(referenceManifest);
for (ReferenceDigestValue rdv : rdvs) {
rdv.archive("Support RIM was deleted");
referenceEventManager.updateRecord(rdv);
}
}
}
} catch (IllegalArgumentException ex) {
String uuidError = "Failed to parse ID from: " + id;
@ -496,7 +527,7 @@ public class ReferenceManifestPageController
* @param supportRim boolean flag indicating if this is a support RIM
* process.
*/
private void storeManifest(
private ReferenceManifest storeManifest(
final String fileName,
final PageMessages messages,
final ReferenceManifest referenceManifest,
@ -539,25 +570,26 @@ public class ReferenceManifestPageController
+ "failed (%s): ", fileName);
messages.addError(failMessage + e.getMessage());
LOGGER.error(failMessage, e);
return;
return null;
}
try {
// save the new certificate if no match is found
if (existingManifest == null) {
referenceManifestManager.save(referenceManifest);
saveTpmEvents(referenceManifestManager.save(referenceManifest));
final String successMsg = String.format("RIM successfully uploaded (%s): ",
fileName);
messages.addSuccess(successMsg);
LOGGER.info(successMsg);
return;
return referenceManifest;
}
} catch (DBManagerException dbmEx) {
final String failMessage = String.format("Storing RIM failed (%s): ", fileName);
messages.addError(failMessage + dbmEx.getMessage());
LOGGER.error(failMessage, dbmEx);
return;
return null;
}
try {
@ -572,12 +604,98 @@ public class ReferenceManifestPageController
= String.format("Pre-existing RIM found and unarchived (%s): ", fileName);
messages.addSuccess(successMsg);
LOGGER.info(successMsg);
return existingManifest;
}
} catch (DBManagerException dbmEx) {
final String failMessage = String.format("Found an identical pre-existing RIM in the "
+ "archive, but failed to unarchive it (%s): ", fileName);
messages.addError(failMessage + dbmEx.getMessage());
LOGGER.error(failMessage, dbmEx);
return null;
}
return referenceManifest;
}
private void updateSupportRimInfo(final BaseReferenceManifest dbBaseRim,
final SupportReferenceManifest supportRim) {
// I have to assume the baseRim is from the database
// Updating the id values, manufacturer, model
if (supportRim != null) {
supportRim.setSwidTagVersion(dbBaseRim.getSwidTagVersion());
supportRim.setPlatformManufacturer(dbBaseRim.getPlatformManufacturer());
supportRim.setPlatformModel(dbBaseRim.getPlatformModel());
supportRim.setTagId(dbBaseRim.getTagId());
supportRim.setAssociatedRim(dbBaseRim.getId());
supportRim.setUpdated(true);
}
}
private void updateTpmEvents(final ReferenceManifest referenceManifest) {
String manufacturer;
String model;
if (referenceManifest.getPlatformManufacturer() == null) {
manufacturer = "";
} else {
manufacturer = referenceManifest.getPlatformManufacturer();
}
if (referenceManifest.getPlatformModel() == null) {
model = "";
} else {
model = referenceManifest.getPlatformModel();
}
List<ReferenceDigestValue> rdvs = referenceEventManager
.getValuesByRimId(referenceManifest);
for (ReferenceDigestValue rdv : rdvs) {
rdv.setModel(model);
rdv.setManufacturer(manufacturer);
rdv.setBaseRimId(referenceManifest.getAssociatedRim());
referenceEventManager.updateRecord(rdv);
}
}
private void saveTpmEvents(final ReferenceManifest referenceManifest) {
SupportReferenceManifest dbSupport;
String manufacturer;
String model;
if (referenceManifest instanceof SupportReferenceManifest) {
dbSupport = (SupportReferenceManifest) referenceManifest;
} else {
return;
}
TCGEventLog logProcessor = null;
if (dbSupport.getPlatformManufacturer() == null) {
manufacturer = "";
} else {
manufacturer = dbSupport.getPlatformManufacturer();
}
if (dbSupport.getPlatformModel() == null) {
model = "";
} else {
model = dbSupport.getPlatformModel();
}
try {
logProcessor = new TCGEventLog(dbSupport.getRimBytes());
ReferenceDigestValue rdv;
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
rdv = new ReferenceDigestValue(dbSupport.getAssociatedRim(),
dbSupport.getId(), manufacturer,
model, tpe.getPcrIndex(),
tpe.getEventDigestStr(), tpe.getEventTypeStr(),
false, false, tpe.getEventContent());
this.referenceEventManager.saveValue(rdv);
}
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,186 @@
package hirs.attestationca.portal.page.controllers;
import hirs.FilteredRecordsList;
import hirs.attestationca.portal.datatables.DataTableInput;
import hirs.attestationca.portal.datatables.DataTableResponse;
import hirs.attestationca.portal.datatables.OrderedListQueryDataTableAdapter;
import hirs.attestationca.portal.page.Page;
import hirs.attestationca.portal.page.PageController;
import hirs.attestationca.portal.page.params.NoPageParams;
import hirs.data.persist.ReferenceDigestValue;
import hirs.data.persist.SupportReferenceManifest;
import hirs.data.persist.certificate.Certificate;
import hirs.persist.CriteriaModifier;
import hirs.persist.DBManagerException;
import hirs.persist.DBReferenceDigestManager;
import hirs.persist.DBReferenceEventManager;
import hirs.persist.DBReferenceManifestManager;
import hirs.persist.ReferenceDigestManager;
import hirs.persist.ReferenceEventManager;
import hirs.persist.ReferenceManifestManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
/**
* Controller for the TPM Events page.
*/
@Controller
@RequestMapping("/rim-database")
public class RimDatabasePageController
extends PageController<NoPageParams> {
private static final String BIOS_RELEASE_DATE_FORMAT = "yyyy-MM-dd";
private final BiosDateValidator biosValidator;
private final ReferenceManifestManager referenceManifestManager;
private final ReferenceDigestManager referenceDigestManager;
private final ReferenceEventManager referenceEventManager;
private static final Logger LOGGER
= LogManager.getLogger(RimDatabasePageController.class);
/**
* This class was created for the purposes of avoiding findbugs message: As
* the JavaDoc states, DateFormats are inherently unsafe for multi-threaded
* use. The detector has found a call to an instance of DateFormat that has
* been obtained via a static field. This looks suspicious.
* <p>
* This class can have uses elsewhere but for now it will remain here.
*/
private static final class BiosDateValidator {
private final String dateFormat;
/**
* Default constructor that sets the format to parse against.
*
* @param dateFormat
*/
public BiosDateValidator(final String dateFormat) {
this.dateFormat = dateFormat;
}
/**
* Validates a date by attempting to parse based on format provided.
*
* @param date string of the given date
* @return true if the format matches
*/
public boolean isValid(final String date) {
DateFormat validFormat = new SimpleDateFormat(this.dateFormat);
boolean result = true;
validFormat.setLenient(false);
try {
validFormat.parse(date);
} catch (ParseException pEx) {
result = false;
}
return result;
}
}
/**
* Constructor providing the Page's display and routing specification.
*
* @param referenceManifestManager the ReferenceManifestManager object
* @param referenceDigestManager the ReferenceDigestManager object
* @param referenceEventManager the referenceEventManager object
*/
@Autowired
public RimDatabasePageController(
final DBReferenceManifestManager referenceManifestManager,
final DBReferenceDigestManager referenceDigestManager,
final DBReferenceEventManager referenceEventManager) {
super(Page.RIM_DATABASE);
this.referenceManifestManager = referenceManifestManager;
this.referenceDigestManager = referenceDigestManager;
this.referenceEventManager = referenceEventManager;
this.biosValidator = new BiosDateValidator(BIOS_RELEASE_DATE_FORMAT);
}
/**
* Returns the filePath 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.
* @return the filePath for the view and data model for the page.
*/
@Override
public ModelAndView initPage(final NoPageParams params,
final Model model) {
return getBaseModelAndView();
}
/**
* Returns the list of TPM Events using the data table input for paging, ordering,
* and filtering.
*
* @param input the data tables input
* @return the data tables response, including the result set and paging
* information
*/
@ResponseBody
@RequestMapping(value = "/list",
produces = MediaType.APPLICATION_JSON_VALUE,
method = RequestMethod.GET)
public DataTableResponse<ReferenceDigestValue> getTableData(
final DataTableInput input) {
LOGGER.info("Handling request for summary list: " + input);
String orderColumnName = input.getOrderColumnName();
LOGGER.info("Ordering on column: " + orderColumnName);
// check that the alert is not archived and that it is in the specified report
CriteriaModifier criteriaModifier = new CriteriaModifier() {
@Override
public void modify(final Criteria criteria) {
criteria.add(Restrictions.isNull(Certificate.ARCHIVE_FIELD));
}
};
LOGGER.info("Querying with the following datatableinput: " + input.toString());
FilteredRecordsList<ReferenceDigestValue> referenceDigestValues =
OrderedListQueryDataTableAdapter.getOrderedList(
ReferenceDigestValue.class,
referenceEventManager,
input, orderColumnName, criteriaModifier);
SupportReferenceManifest support;
for (ReferenceDigestValue rdv : referenceDigestValues) {
// We are updating the base rim ID field if necessary and
if (rdv.getBaseRimId() == null) {
support = SupportReferenceManifest.select(referenceManifestManager)
.byEntityId(rdv.getSupportRimId()).getRIM();
if (support != null) {
rdv.setBaseRimId(support.getAssociatedRim());
try {
referenceEventManager.updateRecord(rdv);
} catch (DBManagerException e) {
LOGGER.error("Failed to update TPM Event with Base RIM ID");
LOGGER.error(rdv);
}
}
}
}
return new DataTableResponse<>(referenceDigestValues, input);
}
}

View File

@ -67,6 +67,10 @@
<a href="${portal}/devices"><img src="${icons}/ic_devices_black_24dp.png" /> Devices</a>
</h3>
<h4>View devices covered by this CA for supply chain validation.</h4>
<h3>
<a href="${portal}/rim-database"><img src="${icons}/ic_devices_black_24dp.png" /> RIM Database</a>
</h3>
<h4>View a list of TPM events </h4>
</div>
</div>
</div>

View File

@ -0,0 +1,75 @@
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%-- JSP TAGS --%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@taglib prefix="my" tagdir="/WEB-INF/tags"%>
<%-- CONTENT --%>
<my:page>
<jsp:attribute name="script">
<script type="text/javascript" src="${lib}/jquery.spring-friendly/jquery.spring-friendly.js"></script>
</jsp:attribute>
<jsp:attribute name="pageHeaderTitle">RIM Database</jsp:attribute>
<jsp:body>
<br/>
<div class="aca-data-table">
<table id="digestValueTable" class="display" width="100%">
<thead>
<tr>
<th>Manufacturer</th>
<th>Model</th>
<th>Event Type</th>
<th>PCR Index</th>
<th>Digest Value</th>
<th>Base RIM</th>
<th>Support RIM</th>
</tr>
</thead>
</table>
</div>
<script>
$(document).ready(function() {
var url = pagePath +'/list';
var columns = [
{data: 'manufacturer',
orderable: true,
searchable:false},
{data: 'model',
orderable: false,
searchable:false},
{data: 'eventType',
orderable: false,
searchable:false,},
{data: 'pcrIndex',
orderable: true,
searchable:false},
{data: 'digestValue',
orderable: false,
searchable:false},
{data: 'baseRimId',
orderable: false,
searchable: false,
render: function(data, type, full, meta) {
return rimDetailsLink(full.baseRimId);
}
},
{data: 'supportRimId',
orderable: false,
searchable: false,
render: function(data, type, full, meta) {
return rimDetailsLink(full.supportRimId);
}
}
];
//Set data tables
setDataTables("#digestValueTable", url, columns);
});
</script>
</jsp:body>
</my:page>

View File

@ -1,11 +1,16 @@
package hirs.data.persist;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bouncycastle.util.Arrays;
import org.hibernate.annotations.Type;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Objects;
import java.util.UUID;
@ -14,70 +19,144 @@ import java.util.UUID;
* Digest Value, Event Type, index, RIM Tagid
*/
@Entity
public class ReferenceDigestValue extends AbstractEntity {
@Table(name = "ReferenceDigestValue")
@XmlRootElement(name = "ReferenceDigestValue")
@XmlAccessorType(XmlAccessType.FIELD)
@Access(AccessType.FIELD)
public class ReferenceDigestValue extends ArchivableEntity {
private static final Logger LOGGER = LogManager.getLogger(ReferenceDigestValue.class);
@Type(type = "uuid-char")
@Column
private UUID digestRecordId;
private UUID baseRimId;
@Type(type = "uuid-char")
@Column
private UUID supportRimId;
@Column(nullable = false)
private String manufacturer;
@Column(nullable = false)
private String model;
@Column(nullable = false)
private int pcrIndex;
@Column(nullable = false)
private String digestValue;
@Column(nullable = false)
private String eventType;
@Column(columnDefinition = "blob", nullable = true)
private byte[] contentBlob;
@Column(nullable = false)
private boolean matchFail;
@Column(nullable = false)
private boolean patched = false;
/**
* Default Constructor.
* Default constructor necessary for Hibernate.
*/
public ReferenceDigestValue() {
protected ReferenceDigestValue() {
super();
this.digestRecordId = UUID.randomUUID();
this.baseRimId = null;
this.supportRimId = null;
this.manufacturer = "";
this.model = "";
this.pcrIndex = -1;
this.digestValue = "";
this.eventType = "";
this.matchFail = false;
this.patched = false;
this.contentBlob = null;
}
/**
* Default Constructor with parameters for all associated data.
* @param digestRecordId the UUID of the associated record
* @param baseRimId the UUID of the associated record
* @param supportRimId the UUID of the associated record
* @param manufacturer associated creator for this information
* @param model the specific device type
* @param pcrIndex the event number
* @param digestValue the key digest value
* @param eventType the event type to store
* @param matchFail the status of the baseline check
* @param patched the status of the value being updated to to patch
* @param contentBlob the data value of the content
*/
public ReferenceDigestValue(final UUID digestRecordId, final int pcrIndex,
final String digestValue, final String eventType,
final boolean matchFail, final boolean patched) {
this.digestRecordId = digestRecordId;
public ReferenceDigestValue(final UUID baseRimId, final UUID supportRimId,
final String manufacturer, final String model,
final int pcrIndex, final String digestValue,
final String eventType, final boolean matchFail,
final boolean patched, final byte[] contentBlob) {
this.baseRimId = baseRimId;
this.supportRimId = supportRimId;
this.manufacturer = manufacturer;
this.model = model;
this.pcrIndex = pcrIndex;
this.digestValue = digestValue;
this.eventType = eventType;
this.matchFail = matchFail;
this.patched = patched;
this.contentBlob = Arrays.clone(contentBlob);
}
/**
* Getter for the digest record UUID.
* @return the string of the UUID
*/
public UUID getDigestRecordId() {
return digestRecordId;
public UUID getBaseRimId() {
return baseRimId;
}
/**
* Setter for the digest record UUID.
* @param digestRecordId the value to store
* @param baseRimId the value to store
*/
public void setDigestRecordId(final UUID digestRecordId) {
this.digestRecordId = digestRecordId;
public void setBaseRimId(final UUID baseRimId) {
this.baseRimId = baseRimId;
}
/**
* Getter for the digest record UUID.
* @return the string of the UUID
*/
public UUID getSupportRimId() {
return supportRimId;
}
/**
* Setter for the digest record UUID.
* @param supportRimId the value to store
*/
public void setSupportRimId(final UUID supportRimId) {
this.supportRimId = supportRimId;
}
/**
* Getter for the manufacturer value.
* @return the stored value
*/
public String getManufacturer() {
return manufacturer;
}
/**
* Setter for the manufacturer value.
* @param manufacturer the value to store
*/
public void setManufacturer(final String manufacturer) {
this.manufacturer = manufacturer;
}
/**
* Getter for the model value.
* @return the stored value
*/
public String getModel() {
return model;
}
/**
* Setter for the model value.
* @param model the value to store
*/
public void setModel(final String model) {
this.model = model;
}
/**
@ -160,6 +239,36 @@ public class ReferenceDigestValue extends AbstractEntity {
this.patched = patched;
}
/**
* Getter for the byte array of event values.
* @return a clone of the byte array
*/
public byte[] getContentBlob() {
return contentBlob.clone();
}
/**
* Setter for the byte array of values.
* @param contentBlob non-null array.
*/
public void setContentBlob(final byte[] contentBlob) {
if (contentBlob != null) {
this.contentBlob = contentBlob.clone();
}
}
/**
* Helper method to update the attributes of this object.
* @param support the associated RIM.
*/
public void updateInfo(final SupportReferenceManifest support) {
if (support != null && support.getId().equals(getSupportRimId())) {
setBaseRimId(support.getAssociatedRim());
setManufacturer(support.getPlatformManufacturer());
setModel(support.getPlatformModel());
}
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
@ -171,13 +280,14 @@ public class ReferenceDigestValue extends AbstractEntity {
ReferenceDigestValue that = (ReferenceDigestValue) obj;
return pcrIndex == that.pcrIndex && matchFail == that.matchFail
&& Objects.equals(digestValue, that.digestValue)
&& Objects.equals(digestRecordId, that.digestRecordId)
&& Objects.equals(baseRimId, that.baseRimId)
&& Objects.equals(supportRimId, that.supportRimId)
&& Objects.equals(eventType, that.eventType);
}
@Override
public int hashCode() {
int result = Objects.hash(pcrIndex, digestValue, digestRecordId,
int result = Objects.hash(pcrIndex, digestValue, manufacturer, model,
eventType, matchFail, patched);
return result;
}
@ -187,7 +297,7 @@ public class ReferenceDigestValue extends AbstractEntity {
* @return a string
*/
public String toString() {
return String.format("ReferenceDigestValue: {%d, %s, %s, %b}",
pcrIndex, digestValue, eventType, matchFail);
return String.format("ReferenceDigestValue: {%s, %d, %s, %s, %b}",
model, pcrIndex, digestValue, eventType, matchFail);
}
}

View File

@ -35,6 +35,7 @@ import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
@ -766,6 +767,12 @@ public abstract class AbstractDbManager<T> implements CrudManager<T> {
searchClass = this.clazz;
}
if (searchableColumns != null) {
LOGGER.info(searchClass.getName() + " querying for "
+ Arrays.toString(searchableColumns.entrySet().toArray())
+ " with search strings \"" + search + "\"");
}
//Object that will store query values
FilteredRecordsList<T> aqr = new FilteredRecordsList<>();
@ -786,8 +793,9 @@ public abstract class AbstractDbManager<T> implements CrudManager<T> {
Long recordsFiltered = totalResultCount;
Conjunction and = Restrictions.conjunction();
if (totalResultCount != 0) {
LOGGER.info("Total result count greater than 0");
//Builds the search criteria from all of the searchable columns
if (searchableColumns != null) {
if (searchableColumns != null && !searchableColumns.isEmpty()) {
// Search for all words in all searchable columns
String[] searchWords = search.split(" ");
for (String word : searchWords) {
@ -804,10 +812,16 @@ public abstract class AbstractDbManager<T> implements CrudManager<T> {
}
}
LOGGER.info("Search columns filtered");
//Retrieves a count of all the records after being filtered
criteria.setProjection(Projections.countDistinct("id"))
.add(and);
try {
LOGGER.info("Get unique result from criteria object");
recordsFiltered = (Long) criteria.uniqueResult();
} catch (HibernateException e) {
LOGGER.error(e.getMessage());
}
}
if (recordsFiltered != 0) {
@ -867,6 +881,7 @@ public abstract class AbstractDbManager<T> implements CrudManager<T> {
}
throw e;
}
LOGGER.info(searchClass.getName() + " found " + aqr.getRecordsTotal() + " records");
return aqr;
}

View File

@ -1,7 +1,10 @@
package hirs.persist;
import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.ReferenceDigestRecord;
import hirs.data.persist.ReferenceDigestValue;
import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.SupportReferenceManifest;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Session;
@ -10,7 +13,9 @@ import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
@ -30,6 +35,7 @@ public class DBReferenceEventManager extends DBManager<ReferenceDigestValue>
public DBReferenceEventManager(final SessionFactory sessionFactory) {
super(ReferenceDigestValue.class, sessionFactory);
}
@Override
public ReferenceDigestValue saveValue(final ReferenceDigestValue referenceDigestValue) {
LOGGER.debug("saving event digest value: {}", referenceDigestValue);
@ -48,7 +54,7 @@ public class DBReferenceEventManager extends DBManager<ReferenceDigestValue>
return null;
}
if (referenceDigestValue.getDigestRecordId() == null
if (referenceDigestValue.getSupportRimId() == null
|| referenceDigestValue.getDigestValue() == null
|| referenceDigestValue.getPcrIndex() == -1) {
LOGGER.error("No reference to get record from db {}", referenceDigestValue);
@ -62,8 +68,8 @@ public class DBReferenceEventManager extends DBManager<ReferenceDigestValue>
LOGGER.debug("retrieving referenceDigestValue from db");
tx = session.beginTransaction();
dbRecord = (ReferenceDigestValue) session.createCriteria(ReferenceDigestValue.class)
.add(Restrictions.eq("digestRecordId",
referenceDigestValue.getDigestRecordId()))
.add(Restrictions.eq("supportRimId",
referenceDigestValue.getSupportRimId()))
.add(Restrictions.eq("digestValue",
referenceDigestValue.getDigestValue()))
.add(Restrictions.eq("eventNumber",
@ -82,6 +88,18 @@ public class DBReferenceEventManager extends DBManager<ReferenceDigestValue>
return dbRecord;
}
@Override
public final Set<ReferenceDigestValue> getEventList() throws DeviceManagerException {
LOGGER.debug("getting ReferenceDigestValue list");
try {
final List<ReferenceDigestValue> events = super.getList(ReferenceDigestValue.class);
return new HashSet<>(events);
} catch (DBManagerException e) {
throw new DeviceManagerException(e);
}
}
@Override
public ReferenceDigestValue getValueById(final ReferenceDigestValue referenceDigestValue) {
LOGGER.debug("Getting record for {}", referenceDigestValue);
@ -118,24 +136,108 @@ public class DBReferenceEventManager extends DBManager<ReferenceDigestValue>
}
@Override
public List<ReferenceDigestValue> getValuesByRecordId(
final ReferenceDigestRecord referenceDigestRecord) {
LOGGER.debug("Getting digest values for {}", referenceDigestRecord);
if (referenceDigestRecord == null) {
LOGGER.error("null referenceDigestRecord argument");
throw new NullPointerException("null referenceDigestRecord");
}
if (referenceDigestRecord.getId() == null) {
LOGGER.error("null referenceDigestRecord ID argument");
throw new NullPointerException("null referenceDigestRecord ID");
public List<ReferenceDigestValue> getValueByManufacturer(final String manufacturer) {
if (manufacturer == null) {
LOGGER.error("null manufacturer argument");
throw new NullPointerException("null manufacturer parameter");
}
List<ReferenceDigestValue> dbDigestValues = new ArrayList<>();
UUID uuid = referenceDigestRecord.getId();
try {
List<ReferenceDigestValue> dbTempList = super.getList(ReferenceDigestValue.class);
for (ReferenceDigestValue rdv : dbTempList) {
if (rdv.getDigestRecordId().equals(uuid)) {
if (rdv.getManufacturer().equals(manufacturer)) {
dbDigestValues.add(rdv);
}
}
} catch (DBManagerException dbMEx) {
throw new RuntimeException(dbMEx);
}
return dbDigestValues;
}
@Override
public List<ReferenceDigestValue> getValueByModel(final String model) {
if (model == null) {
LOGGER.error("null model argument");
throw new NullPointerException("null model parameter");
}
List<ReferenceDigestValue> dbDigestValues = new ArrayList<>();
try {
List<ReferenceDigestValue> dbTempList = super.getList(ReferenceDigestValue.class);
for (ReferenceDigestValue rdv : dbTempList) {
if (rdv.getModel().equals(model)) {
dbDigestValues.add(rdv);
}
}
} catch (DBManagerException dbMEx) {
throw new RuntimeException(dbMEx);
}
return dbDigestValues;
}
@Override
public List<ReferenceDigestValue> getValueByManufacturerModel(
final String manufacturer, final String model) {
if (model == null) {
LOGGER.error("null model argument");
throw new NullPointerException("null model parameter");
}
if (manufacturer == null) {
LOGGER.error("null manufacturer argument");
throw new NullPointerException("null manufacturer parameter");
}
List<ReferenceDigestValue> dbDigestValues = new ArrayList<>();
try {
List<ReferenceDigestValue> dbTempList = super.getList(ReferenceDigestValue.class);
for (ReferenceDigestValue rdv : dbTempList) {
if (rdv.getManufacturer().equals(manufacturer)
&& rdv.getModel().equals(model)) {
dbDigestValues.add(rdv);
}
}
} catch (DBManagerException dbMEx) {
throw new RuntimeException(dbMEx);
}
return dbDigestValues;
}
@Override
public List<ReferenceDigestValue> getValuesByRecordId(
final ReferenceDigestRecord referenceDigestRecord) {
List<ReferenceDigestValue> dbDigestValues = new ArrayList<>(0);
return dbDigestValues;
}
@Override
public List<ReferenceDigestValue> getValuesByRimId(
final ReferenceManifest referenceManifest) {
LOGGER.debug("Getting digest values for {}", referenceManifest);
if (referenceManifest == null) {
LOGGER.error("null referenceManifest argument");
throw new NullPointerException("null referenceManifest");
}
if (referenceManifest.getId() == null) {
LOGGER.error("null referenceManifest ID argument");
throw new NullPointerException("null referenceManifest ID");
}
List<ReferenceDigestValue> dbDigestValues = new ArrayList<>();
UUID uuid = referenceManifest.getId();
UUID rdvUuid = UUID.randomUUID();
try {
final List<ReferenceDigestValue> dbTempList
= super.getList(ReferenceDigestValue.class);
for (ReferenceDigestValue rdv : dbTempList) {
if (referenceManifest instanceof BaseReferenceManifest) {
rdvUuid = rdv.getBaseRimId();
} else if (referenceManifest instanceof SupportReferenceManifest) {
rdvUuid = rdv.getSupportRimId();
}
if (rdvUuid.equals(uuid)) {
dbDigestValues.add(rdv);
}
}
@ -155,7 +257,8 @@ public class DBReferenceEventManager extends DBManager<ReferenceDigestValue>
List<ReferenceDigestValue> dbDigestValues = new ArrayList<>();
try {
List<ReferenceDigestValue> dbTempList = super.getList(ReferenceDigestValue.class);
final List<ReferenceDigestValue> dbTempList
= super.getList(ReferenceDigestValue.class);
for (ReferenceDigestValue rdv : dbTempList) {
if (rdv.getEventType().equals(eventType)) {
dbDigestValues.add(rdv);

View File

@ -10,7 +10,7 @@ import java.util.UUID;
* This class facilitates the persistence of {@link hirs.data.persist.ReferenceDigestRecord}s
* including storage, retrieval, and deletion.
*/
public interface ReferenceDigestManager {
public interface ReferenceDigestManager extends OrderedListQuerier<ReferenceDigestRecord> {
/**
* Persists a new Reference Digest.

View File

@ -2,14 +2,16 @@ package hirs.persist;
import hirs.data.persist.ReferenceDigestRecord;
import hirs.data.persist.ReferenceDigestValue;
import hirs.data.persist.ReferenceManifest;
import java.util.List;
import java.util.Set;
/**
* This class facilitates the persistence of {@link hirs.data.persist.ReferenceDigestValue}s
* including storage, retrieval, and deletion.
*/
public interface ReferenceEventManager {
public interface ReferenceEventManager extends OrderedListQuerier<ReferenceDigestValue> {
/**
* Persists a new Reference Digest value.
*
@ -34,6 +36,31 @@ public interface ReferenceEventManager {
*/
ReferenceDigestValue getValueById(ReferenceDigestValue referenceDigestValue);
/**
* Persists a new Reference Digest Value.
*
* @param manufacturer the string value to search for
* @return the persisted ReferenceDigestValue
*/
List<ReferenceDigestValue> getValueByManufacturer(String manufacturer);
/**
* Persists a new Reference Digest.
*
* @param model the string value to search for
* @return the persisted ReferenceDigestValue
*/
List<ReferenceDigestValue> getValueByModel(String model);
/**
* Persists a new Reference Digest.
*
* @param manufacturer the string value to search for
* @param model the string value to search for
* @return the persisted ReferenceDigestValue
*/
List<ReferenceDigestValue> getValueByManufacturerModel(String manufacturer, String model);
/**
* Persists a new Reference Digest value.
*
@ -42,6 +69,14 @@ public interface ReferenceEventManager {
*/
List<ReferenceDigestValue> getValuesByRecordId(ReferenceDigestRecord referenceDigestRecord);
/**
* Persists a new Reference Digest value.
*
* @param referenceManifest the referenceManifest
* @return the persisted list of ReferenceDigestValue
*/
List<ReferenceDigestValue> getValuesByRimId(ReferenceManifest referenceManifest);
/**
* Persists a new Reference Digest value.
*
@ -50,6 +85,15 @@ public interface ReferenceEventManager {
*/
List<ReferenceDigestValue> getValueByEventType(String eventType);
/**
* Returns a list of all <code>ReferenceDigestValue</code>s that are ordered by a column
* and direction (ASC, DESC) that is provided by the user. This method
* helps support the server-side processing in the JQuery DataTables.
*
* @return FilteredRecordsList object with fields for DataTables
*/
Set<ReferenceDigestValue> getEventList();
/**
* Updates an existing ReferenceDigestRecord.
* @param referenceDigestValue the Reference Event update