diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java index 82f9570b..8beb735d 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java @@ -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(), - tpe.getEventDigestStr(), tpe.getEventTypeStr(), - false, false); - 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); + try { + TCGEventLog 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(); } } } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java index 43321504..8cd0f816 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -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 tpmPcrEvents = new LinkedList<>(); List eventValue; HashMap 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); } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/Page.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/Page.java index 64ca8f5e..8b6a0efa 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/Page.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/Page.java @@ -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. */ diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java index 1931e62a..83365ca2 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java @@ -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 supports = new ArrayList<>(); SupportReferenceManifest baseSupport = null; - List 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 eventValues = new ArrayList<>(); if (measurements.getDeviceName() != null) { - digestRecords = referenceDigestManager - .getRecordsByDeviceName(measurements.getDeviceName()); supports.addAll(SupportReferenceManifest .select(referenceManifestManager) .byDeviceName(measurements @@ -558,24 +552,20 @@ public class ReferenceManifestDetailsPageController if (base != null) { data.put("associatedRim", base.getId()); } + + eventValues.addAll(referenceEventManager.getValuesByRimId(base)); } } TCGEventLog measurementLog = new TCGEventLog(measurements.getRimBytes()); - List eventValue = new ArrayList<>(); Map eventValueMap = new HashMap<>(); - if (!digestRecords.isEmpty()) { - for (ReferenceDigestRecord rdr : digestRecords) { - eventValue.addAll(referenceEventManager - .getValuesByRecordId(rdr)); - } - for (ReferenceDigestValue rdv : eventValue) { - eventValueMap.put(rdv.getDigestValue(), rdv); - } - for (TpmPcrEvent measurementEvent : measurementLog.getEventList()) { - if (!eventValueMap.containsKey(measurementEvent.getEventDigestStr())) { - livelogEvents.add(measurementEvent); - } + + for (ReferenceDigestValue rdv : eventValues) { + eventValueMap.put(rdv.getDigestValue(), rdv); + } + for (TpmPcrEvent measurementEvent : measurementLog.getEventList()) { + if (!eventValueMap.containsKey(measurementEvent.getEventDigestStr())) { + livelogEvents.add(measurementEvent); } } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java index ae46811e..59165131 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java @@ -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 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 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); - break; + 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,36 +282,17 @@ 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); } } @@ -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 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 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(); } } } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java new file mode 100644 index 00000000..0036e96d --- /dev/null +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java @@ -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 { + + 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. + *

+ * 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 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 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); + } +} diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/index.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/index.jsp index 5fdd2f58..366a3e0a 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/index.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/index.jsp @@ -67,6 +67,10 @@ Devices

View devices covered by this CA for supply chain validation.

+

+ RIM Database +

+

View a list of TPM events

diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/rim-database.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/rim-database.jsp new file mode 100644 index 00000000..ba060c2d --- /dev/null +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/rim-database.jsp @@ -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 --%> + + + + + + RIM Database + + +
+
+ + + + + + + + + + + + +
ManufacturerModelEvent TypePCR IndexDigest ValueBase RIMSupport RIM
+
+ + +
+
diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestValue.java b/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestValue.java index 37379ac0..9eb217c2 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestValue.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestValue.java @@ -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); } } diff --git a/HIRS_Utils/src/main/java/hirs/persist/AbstractDbManager.java b/HIRS_Utils/src/main/java/hirs/persist/AbstractDbManager.java index f2250720..2af0dd90 100644 --- a/HIRS_Utils/src/main/java/hirs/persist/AbstractDbManager.java +++ b/HIRS_Utils/src/main/java/hirs/persist/AbstractDbManager.java @@ -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 implements CrudManager { 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 aqr = new FilteredRecordsList<>(); @@ -786,8 +793,9 @@ public abstract class AbstractDbManager implements CrudManager { 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 implements CrudManager { } } + LOGGER.info("Search columns filtered"); //Retrieves a count of all the records after being filtered criteria.setProjection(Projections.countDistinct("id")) .add(and); - recordsFiltered = (Long) criteria.uniqueResult(); + 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 implements CrudManager { } throw e; } + LOGGER.info(searchClass.getName() + " found " + aqr.getRecordsTotal() + " records"); return aqr; } diff --git a/HIRS_Utils/src/main/java/hirs/persist/DBReferenceEventManager.java b/HIRS_Utils/src/main/java/hirs/persist/DBReferenceEventManager.java index f742ca59..21cfa0ae 100644 --- a/HIRS_Utils/src/main/java/hirs/persist/DBReferenceEventManager.java +++ b/HIRS_Utils/src/main/java/hirs/persist/DBReferenceEventManager.java @@ -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 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 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 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 return dbRecord; } + @Override + public final Set getEventList() throws DeviceManagerException { + LOGGER.debug("getting ReferenceDigestValue list"); + + try { + final List 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 } @Override - public List 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 getValueByManufacturer(final String manufacturer) { + if (manufacturer == null) { + LOGGER.error("null manufacturer argument"); + throw new NullPointerException("null manufacturer parameter"); } List dbDigestValues = new ArrayList<>(); - UUID uuid = referenceDigestRecord.getId(); try { List 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 getValueByModel(final String model) { + if (model == null) { + LOGGER.error("null model argument"); + throw new NullPointerException("null model parameter"); + } + + List dbDigestValues = new ArrayList<>(); + try { + List 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 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 dbDigestValues = new ArrayList<>(); + try { + List 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 getValuesByRecordId( + final ReferenceDigestRecord referenceDigestRecord) { + List dbDigestValues = new ArrayList<>(0); + + return dbDigestValues; + } + + @Override + public List 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 dbDigestValues = new ArrayList<>(); + UUID uuid = referenceManifest.getId(); + UUID rdvUuid = UUID.randomUUID(); + try { + final List 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 List dbDigestValues = new ArrayList<>(); try { - List dbTempList = super.getList(ReferenceDigestValue.class); + final List dbTempList + = super.getList(ReferenceDigestValue.class); for (ReferenceDigestValue rdv : dbTempList) { if (rdv.getEventType().equals(eventType)) { dbDigestValues.add(rdv); diff --git a/HIRS_Utils/src/main/java/hirs/persist/ReferenceDigestManager.java b/HIRS_Utils/src/main/java/hirs/persist/ReferenceDigestManager.java index 83b4d67a..33717457 100644 --- a/HIRS_Utils/src/main/java/hirs/persist/ReferenceDigestManager.java +++ b/HIRS_Utils/src/main/java/hirs/persist/ReferenceDigestManager.java @@ -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 { /** * Persists a new Reference Digest. diff --git a/HIRS_Utils/src/main/java/hirs/persist/ReferenceEventManager.java b/HIRS_Utils/src/main/java/hirs/persist/ReferenceEventManager.java index 89c02ebc..93c8534e 100644 --- a/HIRS_Utils/src/main/java/hirs/persist/ReferenceEventManager.java +++ b/HIRS_Utils/src/main/java/hirs/persist/ReferenceEventManager.java @@ -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 { /** * 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 getValueByManufacturer(String manufacturer); + + /** + * Persists a new Reference Digest. + * + * @param model the string value to search for + * @return the persisted ReferenceDigestValue + */ + List 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 getValueByManufacturerModel(String manufacturer, String model); + /** * Persists a new Reference Digest value. * @@ -42,6 +69,14 @@ public interface ReferenceEventManager { */ List getValuesByRecordId(ReferenceDigestRecord referenceDigestRecord); + /** + * Persists a new Reference Digest value. + * + * @param referenceManifest the referenceManifest + * @return the persisted list of ReferenceDigestValue + */ + List getValuesByRimId(ReferenceManifest referenceManifest); + /** * Persists a new Reference Digest value. * @@ -50,6 +85,15 @@ public interface ReferenceEventManager { */ List getValueByEventType(String eventType); + /** + * Returns a list of all ReferenceDigestValues 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 getEventList(); + /** * Updates an existing ReferenceDigestRecord. * @param referenceDigestValue the Reference Event update