Updated the code to correctly include the supplemental digestvalues in

the firmware validation.
This commit is contained in:
Cyrus 2022-03-16 09:06:04 -04:00
parent acfe67a546
commit d4c35e09ab
12 changed files with 151 additions and 91 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;
@ -992,82 +994,104 @@ public abstract class AbstractAttestationCertificateAuthority
private boolean generateDigestRecords(final String manufacturer, final String model,
final String deviceName) {
List<ReferenceDigestValue> rdValues;
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();
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.getPlatformModel().equals(model)) { // need to verify model is good enough
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 (referenceEventManager.getValuesByRimId(baseSupportRim).isEmpty()
&& baseSupportRim != null) {
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, 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, 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 {
// I need to know what is being patched before I can finish this
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);
}

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

@ -95,7 +95,7 @@ public class ReferenceManifestPageController
*
* @param dateFormat
*/
public BiosDateValidator(final String dateFormat) {
BiosDateValidator(final String dateFormat) {
this.dateFormat = dateFormat;
}
@ -264,7 +264,7 @@ public class ReferenceManifestPageController
for (ReferenceDigestValue rdv : referenceEventManager
.getValuesByRimId(support)) {
rdv.updateInfo(support);
referenceEventManager.updateRecord(rdv);
referenceEventManager.updateEvent(rdv);
}
break;
}
@ -342,7 +342,7 @@ public class ReferenceManifestPageController
for (ReferenceDigestValue rdv : rdvs) {
rdv.archive("Support RIM was deleted");
referenceEventManager.updateRecord(rdv);
referenceEventManager.updateEvent(rdv);
}
}
}
@ -654,7 +654,7 @@ public class ReferenceManifestPageController
rdv.setModel(model);
rdv.setManufacturer(manufacturer);
rdv.setBaseRimId(referenceManifest.getAssociatedRim());
referenceEventManager.updateRecord(rdv);
referenceEventManager.updateEvent(rdv);
}
}

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

@ -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);
}