Merge pull request #456 from nsacyber/issue-453

[#453] ReferenceDigestValues refactor
This commit is contained in:
Cyrus 2022-03-22 12:42:25 -04:00 committed by GitHub
commit 6093400994
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 450 additions and 308 deletions

View File

@ -43,7 +43,7 @@ war.dependsOn copyVersion
ext.configDir = new File(projectDir, 'config')
ext.checkstyleConfigDir = "$configDir/checkstyle"
checkstyle {
toolVersion = '5.7'
toolVersion = '8.10.1'
configFile = checkstyleConfigFile
configProperties.put('basedir', checkstyleConfigDir)
ignoreFailures = false

View File

@ -12,7 +12,6 @@ import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.Device;
import hirs.data.persist.DeviceInfoReport;
import hirs.data.persist.EventLogMeasurements;
import hirs.data.persist.ReferenceDigestRecord;
import hirs.data.persist.ReferenceDigestValue;
import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.SupplyChainPolicy;
@ -94,12 +93,15 @@ import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -926,8 +928,7 @@ public abstract class AbstractAttestationCertificateAuthority
listOfSavedRims.add(dbBaseRim);
}
generateDigestRecords(hw.getManufacturer(), hw.getProductName(),
dv.getNw().getHostname());
generateDigestRecords(hw.getManufacturer(), hw.getProductName());
if (dv.hasLivelog()) {
LOG.info("Device sent bios measurement log...");
@ -938,31 +939,38 @@ public abstract class AbstractAttestationCertificateAuthority
dv.getLivelog().toByteArray());
// find previous version.
measurements = EventLogMeasurements.select(referenceManifestManager)
.byHexDecHash(temp.getHexDecHash()).includeArchived().getRIM();
if (measurements == null) {
measurements = temp;
measurements.setPlatformManufacturer(dv.getHw().getManufacturer());
measurements.setPlatformModel(dv.getHw().getProductName());
measurements.setTagId(tagId);
measurements.setDeviceName(dv.getNw().getHostname());
this.referenceManifestManager.save(measurements);
}
// now save the hash to the base and support rims associated
for (ReferenceManifest rim : listOfSavedRims) {
if (rim != null) {
rim.setEventLogHash(temp.getHexDecHash());
this.referenceManifestManager.update(rim);
}
.byDeviceName(dv.getNw().getHostname())
.includeArchived()
.getRIM();
if (measurements != null) {
// Find previous log and delete it
referenceManifestManager.deleteReferenceManifest(measurements);
}
for (BaseReferenceManifest baseRim : BaseReferenceManifest
.select(referenceManifestManager).getRIMs()) {
if (baseRim.getPlatformManufacturer().equals(dv.getHw().getManufacturer())
&& baseRim.getPlatformModel().equals(dv.getHw().getProductName())) {
baseRim.setEventLogHash(temp.getHexDecHash());
this.referenceManifestManager.update(baseRim);
}
}
BaseReferenceManifest baseRim = BaseReferenceManifest
.select(referenceManifestManager)
.byManufacturerModelBase(dv.getHw().getManufacturer(),
dv.getHw().getProductName())
.getRIM();
measurements = temp;
measurements.setPlatformManufacturer(dv.getHw().getManufacturer());
measurements.setPlatformModel(dv.getHw().getProductName());
measurements.setTagId(tagId);
measurements.setDeviceName(dv.getNw().getHostname());
measurements.setAssociatedRim(baseRim.getAssociatedRim());
this.referenceManifestManager.save(measurements);
// pull the base versions of the swidtag and rimel and set the
// event log hash for use during provision
SupportReferenceManifest sBaseRim = SupportReferenceManifest
.select(referenceManifestManager)
.byEntityId(baseRim.getAssociatedRim())
.getRIM();
baseRim.setEventLogHash(temp.getHexDecHash());
sBaseRim.setEventLogHash(temp.getHexDecHash());
referenceManifestManager.update(baseRim);
referenceManifestManager.update(sBaseRim);
} catch (IOException ioEx) {
LOG.error(ioEx);
}
@ -990,84 +998,105 @@ public abstract class AbstractAttestationCertificateAuthority
return dvReport;
}
private boolean generateDigestRecords(final String manufacturer, final String model,
final String deviceName) {
List<ReferenceDigestValue> rdValues;
private boolean generateDigestRecords(final String manufacturer, final String model) {
List<ReferenceDigestValue> rdValues = new LinkedList<>();
SupportReferenceManifest baseSupportRim = null;
List<SupportReferenceManifest> supplementalRims = new ArrayList<>();
List<SupportReferenceManifest> patchRims = new ArrayList<>();
Set<SupportReferenceManifest> dbSupportRims = SupportReferenceManifest
.select(referenceManifestManager).byManufacturer(manufacturer).getRIMs();
.select(referenceManifestManager)
.byManufacturerModel(manufacturer, model).getRIMs();
List<ReferenceDigestValue> sourcedValues = referenceEventManager
.getValueByManufacturerModel(manufacturer, model);
Map<String, ReferenceDigestValue> digestValueMap = new HashMap<>();
sourcedValues.stream().forEach((rdv) -> {
digestValueMap.put(rdv.getDigestValue(), rdv);
});
for (SupportReferenceManifest dbSupport : dbSupportRims) {
if (dbSupport.getPlatformModel().equals(model)) {
ReferenceDigestRecord dbObj = new ReferenceDigestRecord(dbSupport,
manufacturer, model);
dbObj.setDeviceName(deviceName);
// this is where we update or create the log
ReferenceDigestRecord rdr = this.referenceDigestManager.getRecord(dbObj);
if (dbSupport.isBaseSupport()) {
// Handle baseline digest records
if (rdr == null) {
// doesn't exist, store
rdr = referenceDigestManager.saveRecord(dbObj);
} // right now this will not deal with updating
if (dbSupport.isSwidPatch()) {
patchRims.add(dbSupport);
} else if (dbSupport.isSwidSupplemental()) {
supplementalRims.add(dbSupport);
} else {
// we have a base support rim (verify this is getting set)
baseSupportRim = dbSupport;
}
}
if (this.referenceEventManager.getValuesByRimId(dbSupport).isEmpty()) {
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 cEx) {
LOG.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOG.error(noSaEx);
} catch (IOException ioEx) {
LOG.error(ioEx);
}
}
} else if (dbSupport.isSwidPatch()) {
if (rdr != null) {
// have to have something to patch
try {
rdValues = this.referenceEventManager.getValuesByRecordId(rdr);
TCGEventLog logProcessor = new TCGEventLog(dbSupport.getRimBytes());
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
LOG.error(tpe);
}
for (ReferenceDigestValue rdv : rdValues) {
LOG.error(rdv);
}
} catch (CertificateException cEx) {
LOG.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOG.error(noSaEx);
} catch (IOException ioEx) {
LOG.error(ioEx);
}
}
} else if (dbSupport.isSwidSupplemental() && !dbSupport.isProcessed()) {
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();
if (baseSupportRim != null
&& referenceEventManager.getValuesByRimId(baseSupportRim).isEmpty()) {
try {
TCGEventLog logProcessor = new TCGEventLog(baseSupportRim.getRimBytes());
ReferenceDigestValue rdv;
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
rdv = new ReferenceDigestValue(baseSupportRim.getAssociatedRim(),
baseSupportRim.getId(), manufacturer, model, tpe.getPcrIndex(),
tpe.getEventDigestStr(), tpe.getEventTypeStr(),
false, false, true, tpe.getEventContent());
rdValues.add(rdv);
}
// since I have the base already I don't have to care about the backward
// linkage
for (SupportReferenceManifest supplemental : supplementalRims) {
logProcessor = new TCGEventLog(supplemental.getRimBytes());
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
// all RDVs will have the same base rim
rdv = new ReferenceDigestValue(baseSupportRim.getAssociatedRim(),
supplemental.getId(), manufacturer, model, tpe.getPcrIndex(),
tpe.getEventDigestStr(), tpe.getEventTypeStr(),
false, false, true, tpe.getEventContent());
rdValues.add(rdv);
}
}
// Save all supplemental values
ReferenceDigestValue tempRdv;
for (ReferenceDigestValue subRdv : rdValues) {
// check if the value already exists
if (digestValueMap.containsKey(subRdv.getDigestValue())) {
tempRdv = digestValueMap.get(subRdv.getDigestValue());
if (tempRdv.getPcrIndex() != subRdv.getPcrIndex()
&& !tempRdv.getEventType().equals(subRdv.getEventType())) {
referenceEventManager.saveValue(subRdv);
} else {
// will this be a problem down the line?
referenceEventManager.updateEvent(subRdv);
}
} else {
referenceEventManager.saveValue(subRdv);
}
digestValueMap.put(subRdv.getDigestValue(), subRdv);
}
// if a patch value doesn't exist, error?
ReferenceDigestValue dbRdv;
String patchedValue;
for (SupportReferenceManifest patch : patchRims) {
logProcessor = new TCGEventLog(patch.getRimBytes());
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
patchedValue = tpe.getEventDigestStr();
dbRdv = digestValueMap.get(patchedValue);
if (dbRdv == null) {
LOG.error(String.format("Patching value does not exist (%s)",
patchedValue));
} else {
/**
* Until we get patch examples, this is WIP
*/
dbRdv.setPatched(true);
}
}
}
} catch (CertificateException cEx) {
LOG.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOG.error(noSaEx);
} catch (IOException ioEx) {
LOG.error(ioEx);
}
}

View File

@ -537,7 +537,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
if (measurement.getPlatformManufacturer().equals(manufacturer)) {
tcgMeasurementLog = new TCGEventLog(measurement.getRimBytes());
eventValue = this.referenceEventManager
.getValuesByRimId(supportReferenceManifest);
.getValuesByRimId(baseReferenceManifest);
for (ReferenceDigestValue rdv : eventValue) {
eventValueMap.put(rdv.getDigestValue(), rdv);
}
@ -621,7 +621,10 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
try {
Set<SupportReferenceManifest> supportRims = SupportReferenceManifest
.select(this.referenceManifestManager)
.byDeviceName(deviceName).getRIMs();
.byManufacturerModel(
device.getDeviceInfo().getHardwareInfo().getManufacturer(),
device.getDeviceInfo().getHardwareInfo().getProductName())
.getRIMs();
for (SupportReferenceManifest support : supportRims) {
if (support.isBaseSupport()) {
sRim = support;

View File

@ -77,7 +77,7 @@ ext.configDir = new File(projectDir, 'config')
ext.checkstyleConfigDir = "$configDir/checkstyle"
checkstyle {
toolVersion = '5.7'
toolVersion = '8.10.1'
configFile = checkstyleConfigFile
configProperties.put('basedir', checkstyleConfigDir)
ignoreFailures = false

View File

@ -71,7 +71,7 @@ public abstract class PageController<P extends PageParams> {
* @return the path for the view and data model for the page.
*/
@RequestMapping
public abstract ModelAndView initPage(@ModelAttribute final P params, final Model model);
public abstract ModelAndView initPage(@ModelAttribute P params, Model model);
/**
* Creates a generic ModelAndView containing this page's configuration and

View File

@ -4,6 +4,7 @@ import hirs.attestationca.portal.page.PageController;
import hirs.attestationca.portal.page.PageMessages;
import hirs.attestationca.portal.page.params.CertificateDetailsPageParams;
import hirs.attestationca.portal.util.CertificateStringMapBuilder;
import hirs.persist.CertificateManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
@ -12,12 +13,11 @@ import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.io.IOException;
import java.util.HashMap;
import java.util.UUID;
import static hirs.attestationca.portal.page.Page.CERTIFICATE_DETAILS;
import hirs.persist.CertificateManager;
import java.io.IOException;
/**
* Controller for the Certificate Details page.
@ -76,7 +76,7 @@ public class CertificateDetailsPageController extends PageController<Certificate
try {
String type = params.getType().toLowerCase();
UUID uuid = UUID.fromString(params.getId());
switch(type) {
switch (type) {
case "certificateauthority":
data.putAll(CertificateStringMapBuilder.getCertificateAuthorityInformation(
uuid, certificateManager));

View File

@ -51,6 +51,7 @@ import java.security.cert.CertificateException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@ -96,7 +97,7 @@ public class ReferenceManifestPageController
*
* @param dateFormat
*/
public BiosDateValidator(final String dateFormat) {
BiosDateValidator(final String dateFormat) {
this.dateFormat = dateFormat;
}
@ -183,29 +184,6 @@ 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);
}
@ -229,8 +207,8 @@ public class ReferenceManifestPageController
Pattern logPattern = Pattern.compile(LOG_FILE_PATTERN);
Matcher matcher;
boolean supportRIM = false;
BaseReferenceManifest base;
SupportReferenceManifest support;
List<BaseReferenceManifest> baseRims = new ArrayList<>();
List<SupportReferenceManifest> supportRims = new ArrayList<>();
// loop through the files
for (MultipartFile file : files) {
@ -239,64 +217,50 @@ public class ReferenceManifestPageController
supportRIM = matcher.matches();
//Parse reference manifests
ReferenceManifest rim = parseRIM(file, supportRIM, messages);
parseRIM(file, supportRIM, messages, baseRims, supportRims);
}
baseRims.stream().forEach((rim) -> {
LOGGER.info(String.format("Storing swidtag %s", rim.getFileName()));
storeManifest(messages, rim, false);
});
supportRims.stream().forEach((rim) -> {
LOGGER.info(String.format("Storing event log %s", rim.getFileName()));
storeManifest(messages, rim, false);
});
for (ReferenceManifest rim : baseRims) {
// 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 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) referenceManifest;
// the base can find the support rim by the meta data hash
for (SwidResource swid : base.parseResource()) {
support = SupportReferenceManifest.select(referenceManifestManager)
.byHexDecHash(swid.getHashValue()).getRIM();
if (support != null) {
base.setAssociatedRim(support.getId());
if (support.isUpdated()) {
// this is separate because I want to break if we found it
// instead of finding it, it is uptodate but still search
break;
} else {
updateSupportRimInfo(base, support);
updateTpmEvents(support);
try {
referenceManifestManager.update(support);
} catch (DBManagerException dbmEx) {
LOGGER.warn("Failed to update Support RIM");
}
}
}
}
}
storeManifest(messages, rim, false);
}
for (ReferenceManifest rim : supportRims) {
// store the rimels
storeManifest(messages, rim, true);
}
// Prep a map to associated the swidtag payload hash to the swidtag.
// pass it in to update support rims that either were uploaded
// or already exist
// create a map of the supports rims in case an uploaded swidtag
// isn't one to one with the uploaded support rims.
Map<String, SupportReferenceManifest> updatedSupportRims
= updateSupportRimInfo(generatePayloadHashMap(baseRims));
// look for missing uploaded support rims
for (SupportReferenceManifest support : supportRims) {
if (!updatedSupportRims.containsKey(support.getHexDecHash())) {
// Make sure we are getting the db version of the file
updatedSupportRims.put(support.getHexDecHash(),
SupportReferenceManifest
.select(referenceManifestManager)
.byHexDecHash(support.getHexDecHash())
.getRIM());
}
}
// pass in the updated support rims
// and either update or add the events
processTpmEvents(new ArrayList<SupportReferenceManifest>(updatedSupportRims.values()));
//Add messages to the model
model.put(MESSAGES_ATTRIBUTE, messages);
@ -343,7 +307,7 @@ public class ReferenceManifestPageController
for (ReferenceDigestValue rdv : rdvs) {
rdv.archive("Support RIM was deleted");
referenceEventManager.updateRecord(rdv);
referenceEventManager.updateEvent(rdv);
}
}
}
@ -485,15 +449,19 @@ public class ReferenceManifestPageController
* object.
*
* @param file the provide user file via browser.
* @param supportRIM matcher result
* @param messages the object that handles displaying information to the
* user.
* @param baseRims object to store multiple files
* @param supportRims object to store multiple files
* @return a single or collection of reference manifest files.
*/
private ReferenceManifest parseRIM(
private void parseRIM(
final MultipartFile file, final boolean supportRIM,
final PageMessages messages) {
final PageMessages messages, final List<BaseReferenceManifest> baseRims,
final List<SupportReferenceManifest> supportRims) {
byte[] fileBytes;
byte[] fileBytes = new byte[0];
String fileName = file.getOriginalFilename();
// build the manifest from the uploaded bytes
@ -504,43 +472,37 @@ public class ReferenceManifestPageController
= String.format("Failed to read uploaded file (%s): ", fileName);
LOGGER.error(failMessage, e);
messages.addError(failMessage + e.getMessage());
return null;
}
try {
if (supportRIM) {
return new SupportReferenceManifest(fileName, fileBytes);
supportRims.add(new SupportReferenceManifest(fileName, fileBytes));
} else {
return new BaseReferenceManifest(fileName, fileBytes);
baseRims.add(new BaseReferenceManifest(fileName, fileBytes));
}
// the this is a List<Object> is object is a JaxBElement that can
// be matched up to the QName
} catch (IOException ioEx) {
final String failMessage
= String.format("Failed to parse uploaded file (%s): ", fileName);
LOGGER.error(failMessage, ioEx);
messages.addError(failMessage + ioEx.getMessage());
return null;
}
}
/**
* Stores the {@link ReferenceManifest} objects.
*
* @param fileName name of the file given
* @param messages message object for user display of statuses
* @param referenceManifest the object to store
* @param supportRim boolean flag indicating if this is a support RIM
* process.
*/
private ReferenceManifest storeManifest(
final String fileName,
private void storeManifest(
final PageMessages messages,
final ReferenceManifest referenceManifest,
final boolean supportRim) {
ReferenceManifest existingManifest;
ReferenceManifest existingManifest = null;
String fileName = referenceManifest.getFileName();
MessageDigest digest = null;
String rimHash = "";
try {
@ -576,32 +538,29 @@ public class ReferenceManifestPageController
+ "failed (%s): ", fileName);
messages.addError(failMessage + e.getMessage());
LOGGER.error(failMessage, e);
return null;
}
try {
// save the new certificate if no match is found
if (existingManifest == null) {
saveTpmEvents(referenceManifestManager.save(referenceManifest));
referenceManifestManager.save(referenceManifest);
final String successMsg = String.format("RIM successfully uploaded (%s): ",
fileName);
messages.addSuccess(successMsg);
LOGGER.info(successMsg);
return referenceManifest;
}
} catch (DBManagerException dbmEx) {
final String failMessage = String.format("Storing RIM failed (%s): ", fileName);
final String failMessage = String.format("Storing RIM failed (%s): ",
fileName);
messages.addError(failMessage + dbmEx.getMessage());
LOGGER.error(failMessage, dbmEx);
return null;
}
try {
// if an identical RIM is archived, update the existing RIM to
// unarchive it and change the creation date
if (existingManifest.isArchived()) {
if (existingManifest != null && existingManifest.isArchived()) {
existingManifest.restore();
existingManifest.resetCreateTime();
referenceManifestManager.update(existingManifest);
@ -610,98 +569,124 @@ 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);
private Map<String, BaseReferenceManifest> generatePayloadHashMap(
final List<BaseReferenceManifest> uploadedBaseRims) {
BaseReferenceManifest dbBaseRim;
HashMap<String, BaseReferenceManifest> tempMap = new HashMap<>();
for (BaseReferenceManifest base : uploadedBaseRims) {
// this is done to make sure we have the version with the UUID
dbBaseRim = BaseReferenceManifest.select(referenceManifestManager)
.byBase64Hash(base.getBase64Hash()).getRIM();
if (dbBaseRim != null) {
for (SwidResource swid : dbBaseRim.parseResource()) {
tempMap.put(swid.getHashValue(), dbBaseRim);
}
}
}
return tempMap;
}
private Map<String, SupportReferenceManifest> updateSupportRimInfo(
final Map<String, BaseReferenceManifest> dbBaseRims) {
BaseReferenceManifest dbBaseRim;
SupportReferenceManifest supportRim;
Map<String, SupportReferenceManifest> updatedSupportRims = new HashMap<>();
List<String> hashValues = new LinkedList<>(dbBaseRims.keySet());
for (String supportHash : hashValues) {
supportRim = SupportReferenceManifest.select(referenceManifestManager)
.byHexDecHash(supportHash).getRIM();
// I have to assume the baseRim is from the database
// Updating the id values, manufacturer, model
if (supportRim != null && !supportRim.isUpdated()) {
dbBaseRim = dbBaseRims.get(supportHash);
supportRim.setSwidTagVersion(dbBaseRim.getSwidTagVersion());
supportRim.setPlatformManufacturer(dbBaseRim.getPlatformManufacturer());
supportRim.setPlatformModel(dbBaseRim.getPlatformModel());
supportRim.setTagId(dbBaseRim.getTagId());
supportRim.setAssociatedRim(dbBaseRim.getId());
supportRim.setUpdated(true);
referenceManifestManager.update(supportRim);
updatedSupportRims.put(supportHash, supportRim);
}
}
return updatedSupportRims;
}
/**
* If the support rim is a supplemental or base, this method looks for the
* original oem base rim to associate with each event.
* @param supportRim assumed db object
* @return reference to the base rim
*/
private ReferenceManifest findBaseRim(final SupportReferenceManifest supportRim) {
if (supportRim != null && (supportRim.getId() != null
&& !supportRim.getId().toString().equals(""))) {
Set<BaseReferenceManifest> baseRims = BaseReferenceManifest
.select(referenceManifestManager)
.byManufacturerModel(supportRim.getPlatformManufacturer(),
supportRim.getPlatformModel()).getRIMs();
for (BaseReferenceManifest base : baseRims) {
if (base.isBase()) {
// there should be only one
return base;
}
}
}
return null;
}
private void processTpmEvents(final List<SupportReferenceManifest> dbSupportRims) {
boolean updated = true;
List<ReferenceDigestValue> tpmEvents;
TCGEventLog logProcessor = null;
ReferenceManifest baseRim;
for (SupportReferenceManifest dbSupport : dbSupportRims) {
// So first we'll have to pull values based on support rim
// get by support rim id NEXT
tpmEvents = referenceEventManager.getValuesByRimId(dbSupport);
baseRim = findBaseRim(dbSupport);
if (tpmEvents.isEmpty()) {
ReferenceDigestValue rdv;
try {
logProcessor = new TCGEventLog(dbSupport.getRimBytes());
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
rdv = new ReferenceDigestValue(baseRim.getId(),
dbSupport.getId(), dbSupport.getPlatformManufacturer(),
dbSupport.getPlatformModel(), tpe.getPcrIndex(),
tpe.getEventDigestStr(), tpe.getEventTypeStr(),
false, false, updated, tpe.getEventContent());
this.referenceEventManager.saveValue(rdv);
}
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
for (ReferenceDigestValue rdv : tpmEvents) {
if (!rdv.isUpdated()) {
rdv.updateInfo(dbSupport, baseRim.getId());
this.referenceEventManager.updateEvent(rdv);
}
}
}
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -70,7 +70,7 @@ public class RimDatabasePageController
*
* @param dateFormat
*/
public BiosDateValidator(final String dateFormat) {
BiosDateValidator(final String dateFormat) {
this.dateFormat = dateFormat;
}
@ -172,7 +172,7 @@ public class RimDatabasePageController
if (support != null) {
rdv.setBaseRimId(support.getAssociatedRim());
try {
referenceEventManager.updateRecord(rdv);
referenceEventManager.updateEvent(rdv);
} catch (DBManagerException e) {
LOGGER.error("Failed to update TPM Event with Base RIM ID");
LOGGER.error(rdv);

View File

@ -24,8 +24,7 @@ public final class PciIds {
* This pci ids file can be in different places on different distributions.
*/
public static final List<String> PCI_IDS_PATH =
Collections.unmodifiableList(new Vector<String>()
{
Collections.unmodifiableList(new Vector<String>() {
private static final long serialVersionUID = 1L;
{
add("/usr/share/hwdata/pci.ids");

View File

@ -1,8 +1,8 @@
package hirs.data.persist;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import java.util.Date;
/**
* An abstract archivable entity that can be deleted.
@ -13,7 +13,7 @@ public abstract class ArchivableEntity extends AbstractEntity {
/**
* Defining the size of a message field for error display.
*/
public static final int MAX_MESSAGE_LENGTH = 1200;
public static final int MAX_MESSAGE_LENGTH = 2400;
@Column(name = "archived_time")
private Date archivedTime;

View File

@ -121,6 +121,35 @@ public class BaseReferenceManifest extends ReferenceManifest {
return this;
}
/**
* Specify the platform manufacturer/model that rims must have to be considered
* as matching.
* @param manufacturer string for the manufacturer
* @param model string for the model
* @return this instance
*/
public Selector byManufacturerModel(final String manufacturer, final String model) {
setFieldValue(PLATFORM_MANUFACTURER, manufacturer);
setFieldValue(PLATFORM_MODEL, model);
return this;
}
/**
* Specify the platform manufacturer/model/base flag that rims must have to be considered
* as matching.
* @param manufacturer string for the manufacturer
* @param model string for the model
* @return this instance
*/
public Selector byManufacturerModelBase(final String manufacturer, final String model) {
setFieldValue(PLATFORM_MANUFACTURER, manufacturer);
setFieldValue(PLATFORM_MODEL, model);
setFieldValue("swidPatch", false);
setFieldValue("swidSupplemental", false);
//setFieldValue("", false); //corpus?
return this;
}
/**
* Specify the device name that rims must have to be considered
* as matching.
@ -492,6 +521,15 @@ public class BaseReferenceManifest extends ReferenceManifest {
this.swidCorpus = swidCorpus;
}
/**
* The assumed requirement for being the initial swidtag.
* @return flag for the status
*/
public boolean isBase() {
return !this.isSwidPatch() && !this.isSwidSupplemental()
&& (this.isSwidCorpus() == 0);
}
/**
* Getter for the Entity Name.
*

View File

@ -47,6 +47,8 @@ public class ReferenceDigestValue extends ArchivableEntity {
private boolean matchFail;
@Column(nullable = false)
private boolean patched = false;
@Column(nullable = false)
private boolean updated = false;
/**
* Default constructor necessary for Hibernate.
@ -62,6 +64,7 @@ public class ReferenceDigestValue extends ArchivableEntity {
this.eventType = "";
this.matchFail = false;
this.patched = false;
this.updated = false;
this.contentBlob = null;
}
@ -75,14 +78,16 @@ public class ReferenceDigestValue extends ArchivableEntity {
* @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 patched the status of the value being updated to patch
* @param updated the status of the value being updated with info
* @param contentBlob the data value of the content
*/
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) {
final boolean patched, final boolean updated,
final byte[] contentBlob) {
this.baseRimId = baseRimId;
this.supportRimId = supportRimId;
this.manufacturer = manufacturer;
@ -92,6 +97,7 @@ public class ReferenceDigestValue extends ArchivableEntity {
this.eventType = eventType;
this.matchFail = matchFail;
this.patched = patched;
this.updated = updated;
this.contentBlob = Arrays.clone(contentBlob);
}
@ -239,6 +245,22 @@ public class ReferenceDigestValue extends ArchivableEntity {
this.patched = patched;
}
/**
* Getter for the status of the updated state.
* @return updated flag
*/
public boolean isUpdated() {
return updated;
}
/**
* Setter for the status of the updated state.
* @param updated the flag to set
*/
public void setUpdated(final boolean updated) {
this.updated = updated;
}
/**
* Getter for the byte array of event values.
* @return a clone of the byte array
@ -260,12 +282,19 @@ public class ReferenceDigestValue extends ArchivableEntity {
/**
* Helper method to update the attributes of this object.
* @param support the associated RIM.
* @param baseRimId the main id to update
*/
public void updateInfo(final SupportReferenceManifest support) {
if (support != null && support.getId().equals(getSupportRimId())) {
setBaseRimId(support.getAssociatedRim());
public void updateInfo(final SupportReferenceManifest support, final UUID baseRimId) {
if (support != null) {
setBaseRimId(baseRimId);
setManufacturer(support.getPlatformManufacturer());
setModel(support.getPlatformModel());
setUpdated(true);
if (support.isSwidPatch()) {
// come back to this later, how does this get
// identified to be patched
setPatched(true);
}
}
}
@ -288,7 +317,7 @@ public class ReferenceDigestValue extends ArchivableEntity {
@Override
public int hashCode() {
int result = Objects.hash(pcrIndex, digestValue, manufacturer, model,
eventType, matchFail, patched);
eventType, matchFail, patched, updated);
return result;
}
@ -297,7 +326,8 @@ public class ReferenceDigestValue extends ArchivableEntity {
* @return a string
*/
public String toString() {
return String.format("ReferenceDigestValue: {%s, %d, %s, %s, %b}",
model, pcrIndex, digestValue, eventType, matchFail);
return String.format("ReferenceDigestValue: {%s, %d, %s, %s, "
+ "matchFail - %b, updated - %b, patched - %b}",
model, pcrIndex, digestValue, eventType, matchFail, updated, patched);
}
}

View File

@ -58,6 +58,19 @@ public class SupportReferenceManifest extends ReferenceManifest {
return this;
}
/**
* Specify the platform model that rims must have to be considered
* as matching.
* @param manufacturer string for the manufacturer
* @param model string for the model
* @return this instance
*/
public Selector byManufacturerModel(final String manufacturer, final String model) {
setFieldValue(PLATFORM_MANUFACTURER, manufacturer);
setFieldValue(PLATFORM_MODEL, model);
return this;
}
/**
* Specify the device name that rims must have to be considered
* as matching.

View File

@ -135,6 +135,35 @@ public class DBReferenceEventManager extends DBManager<ReferenceDigestValue>
return dbRecord;
}
@Override
public ReferenceDigestValue getValueByDigest(final String eventDigest) {
if (eventDigest == null) {
LOGGER.error("null event digest argument");
throw new NullPointerException("null event digest argument");
}
ReferenceDigestValue dbRecord;
Transaction tx = null;
Session session = getFactory().getCurrentSession();
try {
LOGGER.debug("retrieving referenceDigestValue from db");
tx = session.beginTransaction();
dbRecord = (ReferenceDigestValue) session.createCriteria(ReferenceDigestValue.class)
.add(Restrictions.eq("digestValue",
eventDigest)).uniqueResult();
tx.commit();
} catch (Exception ex) {
final String msg = "unable to retrieve object";
LOGGER.error(msg, ex);
if (tx != null) {
LOGGER.debug("rolling back transaction");
tx.rollback();
}
throw new DBManagerException(msg, ex);
}
return dbRecord;
}
@Override
public List<ReferenceDigestValue> getValueByManufacturer(final String manufacturer) {
if (manufacturer == null) {
@ -271,7 +300,7 @@ public class DBReferenceEventManager extends DBManager<ReferenceDigestValue>
}
@Override
public void updateRecord(final ReferenceDigestValue referenceDigestValue) {
public void updateEvent(final ReferenceDigestValue referenceDigestValue) {
try {
super.update(referenceDigestValue);
} catch (DBManagerException dbMEx) {
@ -280,7 +309,7 @@ public class DBReferenceEventManager extends DBManager<ReferenceDigestValue>
}
@Override
public boolean deleteRecord(final ReferenceDigestValue referenceDigestValue) {
public boolean deleteEvent(final ReferenceDigestValue referenceDigestValue) {
boolean result;
LOGGER.info(String.format("Deleting reference to %s",
referenceDigestValue.getId()));

View File

@ -36,6 +36,14 @@ public interface ReferenceEventManager extends OrderedListQuerier<ReferenceDiges
*/
ReferenceDigestValue getValueById(ReferenceDigestValue referenceDigestValue);
/**
* Gets a value associated with the passed in digest.
*
* @param eventDigest the ReferenceDigestValue
* @return the persisted ReferenceDigestValue
*/
ReferenceDigestValue getValueByDigest(String eventDigest);
/**
* Persists a new Reference Digest Value.
*
@ -98,7 +106,7 @@ public interface ReferenceEventManager extends OrderedListQuerier<ReferenceDiges
* Updates an existing ReferenceDigestRecord.
* @param referenceDigestValue the Reference Event update
*/
void updateRecord(ReferenceDigestValue referenceDigestValue);
void updateEvent(ReferenceDigestValue referenceDigestValue);
/**
* Delete the given value.
@ -106,5 +114,5 @@ public interface ReferenceEventManager extends OrderedListQuerier<ReferenceDiges
* @param referenceDigestValue the digest record delete
* @return true if the deletion succeeded, false otherwise.
*/
boolean deleteRecord(ReferenceDigestValue referenceDigestValue);
boolean deleteEvent(ReferenceDigestValue referenceDigestValue);
}

View File

@ -41,4 +41,12 @@ public interface ReferenceManifestManager extends OrderedListQuerier<ReferenceMa
* @return true if the deletion succeeded, false otherwise.
*/
boolean delete(ReferenceManifest referenceManifest);
/**
* Remove a ReferenceManifest from the database.
*
* @param referenceManifest the referenceManifest to delete
* @return true if deletion was successful, false otherwise
*/
boolean deleteReferenceManifest(ReferenceManifest referenceManifest);
}