mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-21 13:57:56 +00:00
Updated code allows the tpm event table to be searched and information
updated when the swidtag is added.
This commit is contained in:
parent
ea6bb48d06
commit
035efad9d2
@ -10,13 +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.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;
|
||||
@ -42,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;
|
||||
@ -69,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);
|
||||
|
||||
@ -118,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);
|
||||
}
|
||||
|
||||
@ -173,6 +182,29 @@ public class ReferenceManifestPageController
|
||||
referenceManifestManager,
|
||||
input, orderColumnName, criteriaModifier);
|
||||
|
||||
SupportReferenceManifest support;
|
||||
Set<ReferenceDigestValue> events;
|
||||
for (ReferenceManifest rim : records) {
|
||||
if (rim instanceof SupportReferenceManifest) {
|
||||
support = (SupportReferenceManifest) rim;
|
||||
events = ReferenceDigestValue
|
||||
.select(referenceEventManager)
|
||||
.bySupportRim(support.getId()).getDigestValues();
|
||||
for (ReferenceDigestValue rdv : events) {
|
||||
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);
|
||||
}
|
||||
@ -247,6 +279,8 @@ public class ReferenceManifestPageController
|
||||
support.setPlatformModel(base.getPlatformModel());
|
||||
support.setTagId(base.getTagId());
|
||||
support.setUpdated(true);
|
||||
|
||||
// add in update code for the events based on support id
|
||||
try {
|
||||
referenceManifestManager.update(support);
|
||||
} catch (DBManagerException dbmEx) {
|
||||
@ -535,7 +569,7 @@ public class ReferenceManifestPageController
|
||||
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);
|
||||
@ -557,6 +591,7 @@ public class ReferenceManifestPageController
|
||||
existingManifest.restore();
|
||||
existingManifest.resetCreateTime();
|
||||
referenceManifestManager.update(existingManifest);
|
||||
saveTpmEvents(existingManifest);
|
||||
|
||||
final String successMsg
|
||||
= String.format("Pre-existing RIM found and unarchived (%s): ", fileName);
|
||||
@ -570,4 +605,45 @@ public class ReferenceManifestPageController
|
||||
LOGGER.error(failMessage, dbmEx);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package hirs.data.persist;
|
||||
|
||||
import hirs.persist.ReferenceEventManager;
|
||||
import hirs.persist.ReferenceEventSelector;
|
||||
import org.bouncycastle.util.Arrays;
|
||||
import org.hibernate.annotations.Type;
|
||||
|
||||
@ -48,6 +50,67 @@ public class ReferenceDigestValue extends ArchivableEntity {
|
||||
@Column(nullable = false)
|
||||
private boolean patched = false;
|
||||
|
||||
/**
|
||||
* This class enables the retrieval of ReferenceDigestValue by their attributes.
|
||||
*/
|
||||
public static class Selector extends ReferenceEventSelector<ReferenceDigestValue> {
|
||||
/**
|
||||
* Construct a new ReferenceEventSelector that will
|
||||
* use the given (@link ReferenceEventManager}
|
||||
* to retrieve one or may ReferenceDigestValue.
|
||||
*
|
||||
* @param referenceEventManager the reference event manager to be used to retrieve
|
||||
* reference event.
|
||||
*/
|
||||
public Selector(final ReferenceEventManager referenceEventManager) {
|
||||
super(referenceEventManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the base rim id that rims must have to be considered
|
||||
* as matching.
|
||||
* @param baseRimId identifier for the support rim
|
||||
* @return this instance
|
||||
*/
|
||||
public Selector byBaseRim(final UUID baseRimId) {
|
||||
setFieldValue("baseRimId", baseRimId);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the support rim id that rims must have to be considered
|
||||
* as matching.
|
||||
* @param supportRimId identifier for the support rim
|
||||
* @return this instance
|
||||
*/
|
||||
public Selector bySupportRim(final UUID supportRimId) {
|
||||
setFieldValue("supportRimId", supportRimId);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the platform manufacturer that rims must have to be considered
|
||||
* as matching.
|
||||
* @param manufacturer string for the manufacturer
|
||||
* @return this instance
|
||||
*/
|
||||
public Selector byManufacturer(final String manufacturer) {
|
||||
setFieldValue("manufacturer", manufacturer);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the platform model that rims must have to be considered
|
||||
* as matching.
|
||||
* @param model string for the model
|
||||
* @return this instance
|
||||
*/
|
||||
public Selector byModel(final String model) {
|
||||
setFieldValue("model", model);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor necessary for Hibernate.
|
||||
*/
|
||||
@ -95,6 +158,17 @@ public class ReferenceDigestValue extends ArchivableEntity {
|
||||
this.contentBlob = Arrays.clone(contentBlob);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Selector for use in retrieving ReferenceDigestValue.
|
||||
*
|
||||
* @param eventManager the ReferenceEventManager to be used to retrieve
|
||||
* persisted tpm events
|
||||
* @return a Selector instance to use for retrieving tpm events
|
||||
*/
|
||||
public static Selector select(final ReferenceEventManager eventManager) {
|
||||
return new Selector(eventManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the digest record UUID.
|
||||
* @return the string of the UUID
|
||||
@ -275,7 +349,7 @@ public class ReferenceDigestValue extends ArchivableEntity {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = Objects.hash(pcrIndex, digestValue, baseRimId, supportRimId,
|
||||
int result = Objects.hash(pcrIndex, digestValue, manufacturer, model,
|
||||
eventType, matchFail, patched);
|
||||
return result;
|
||||
}
|
||||
@ -285,7 +359,7 @@ public class ReferenceDigestValue extends ArchivableEntity {
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package hirs.persist;
|
||||
|
||||
import hirs.FilteredRecordsList;
|
||||
import hirs.data.persist.BaseReferenceManifest;
|
||||
import hirs.data.persist.ReferenceDigestRecord;
|
||||
import hirs.data.persist.ReferenceDigestValue;
|
||||
@ -8,16 +7,15 @@ 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.Criteria;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -90,6 +88,18 @@ public class DBReferenceEventManager extends DBManager<ReferenceDigestValue>
|
||||
return dbRecord;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Set<ReferenceDigestValue> getEventList() throws DeviceManagerException {
|
||||
LOGGER.debug("getting ReferenceDigestValue list");
|
||||
|
||||
try {
|
||||
final List<ReferenceDigestValue> events = super.getList(ReferenceDigestValue.class);
|
||||
return new HashSet<>(events);
|
||||
} catch (DBManagerException e) {
|
||||
throw new DeviceManagerException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReferenceDigestValue getValueById(final ReferenceDigestValue referenceDigestValue) {
|
||||
LOGGER.debug("Getting record for {}", referenceDigestValue);
|
||||
@ -258,53 +268,6 @@ public class DBReferenceEventManager extends DBManager<ReferenceDigestValue>
|
||||
return dbDigestValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all <code>Device</code>s that are ordered by a column
|
||||
* and direction (ASC, DESC) that is provided by the user. This method
|
||||
* helps support the server-side processing in the JQuery DataTables.
|
||||
*
|
||||
* @param columnToOrder Column to be ordered
|
||||
* @param ascending direction of sort
|
||||
* @param firstResult starting point of first result in set
|
||||
* @param maxResults total number we want returned for display in table
|
||||
* @param search string of criteria to be matched to visible columns
|
||||
*
|
||||
* @return FilteredRecordsList object with fields for DataTables
|
||||
*/
|
||||
@Override
|
||||
public final FilteredRecordsList<ReferenceDigestValue> getOrderedDigestValueList(
|
||||
final String columnToOrder,
|
||||
final boolean ascending, final int firstResult,
|
||||
final int maxResults, final String search) {
|
||||
if (columnToOrder == null) {
|
||||
LOGGER.debug("null object argument");
|
||||
throw new NullPointerException("object");
|
||||
}
|
||||
|
||||
//Maps object types and their ability to be searched by Hibernate
|
||||
//without modification
|
||||
Map<String, Boolean> searchableColumns = new HashMap<>();
|
||||
searchableColumns.put("name", true);
|
||||
searchableColumns.put("group.name", true);
|
||||
searchableColumns.put("last_report_timestamp", false);
|
||||
|
||||
CriteriaModifier modifier = new CriteriaModifier() {
|
||||
@Override
|
||||
public void modify(final Criteria criteria) {
|
||||
criteria.createAlias("valueGroup", "group");
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
LOGGER.debug("Getting baseline list");
|
||||
return super.getOrderedList(ReferenceDigestValue.class, columnToOrder, ascending,
|
||||
firstResult,
|
||||
maxResults, search, searchableColumns, modifier);
|
||||
} catch (DBManagerException e) {
|
||||
throw new AlertManagerException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRecord(final ReferenceDigestValue referenceDigestValue) {
|
||||
try {
|
||||
|
@ -1,11 +1,11 @@
|
||||
package hirs.persist;
|
||||
|
||||
import hirs.FilteredRecordsList;
|
||||
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
|
||||
@ -90,17 +90,9 @@ public interface ReferenceEventManager extends OrderedListQuerier<ReferenceDiges
|
||||
* and direction (ASC, DESC) that is provided by the user. This method
|
||||
* helps support the server-side processing in the JQuery DataTables.
|
||||
*
|
||||
* @param columnToOrder Column to be ordered
|
||||
* @param ascending direction of sort
|
||||
* @param firstResult starting point of first result in set
|
||||
* @param maxResults total number we want returned for display in table
|
||||
* @param search string of criteria to be matched to visible columns
|
||||
*
|
||||
* @return FilteredRecordsList object with fields for DataTables
|
||||
*/
|
||||
FilteredRecordsList<ReferenceDigestValue> getOrderedDigestValueList(
|
||||
String columnToOrder, boolean ascending, int firstResult,
|
||||
int maxResults, String search);
|
||||
Set<ReferenceDigestValue> getEventList();
|
||||
|
||||
/**
|
||||
* Updates an existing ReferenceDigestRecord.
|
||||
|
@ -0,0 +1,157 @@
|
||||
package hirs.persist;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import hirs.data.persist.certificate.Certificate;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hibernate.criterion.Conjunction;
|
||||
import org.hibernate.criterion.Criterion;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class is used to select one or many TPM Events in conjunction
|
||||
* with a {@link hirs.persist.ReferenceEventManager}. To make use of this object,
|
||||
* use (some ReferenceDigestValue).select(ReferenceEventManager).
|
||||
*
|
||||
* @param <ReferenceDigestValue> the type of DB Object that will be retrieved.
|
||||
*/
|
||||
public abstract class ReferenceEventSelector<ReferenceDigestValue> {
|
||||
private static final String RIM_TYPE_FIELD = "rimType";
|
||||
private static final String DIGEST_VALUE_FIELD = "digestValue";
|
||||
|
||||
private final ReferenceEventManager referenceEventManager;
|
||||
|
||||
private final Map<String, Object> fieldValueSelections;
|
||||
private boolean excludeArchivedValues;
|
||||
|
||||
|
||||
/**
|
||||
* Standard Constructor for the Selector.
|
||||
*
|
||||
* @param referenceEventManager the RIM manager to be used to retrieve RIMs
|
||||
*/
|
||||
public ReferenceEventSelector(final ReferenceEventManager referenceEventManager) {
|
||||
this(referenceEventManager, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Constructor for the Selector.
|
||||
*
|
||||
* @param referenceEventManager the RIM manager to be used to retrieve RIMs
|
||||
* @param excludeArchivedValues true if excluding archived RIMs
|
||||
*/
|
||||
public ReferenceEventSelector(final ReferenceEventManager referenceEventManager,
|
||||
final boolean excludeArchivedValues) {
|
||||
Preconditions.checkArgument(
|
||||
referenceEventManager != null,
|
||||
"reference event manager cannot be null"
|
||||
);
|
||||
|
||||
this.referenceEventManager = referenceEventManager;
|
||||
this.excludeArchivedValues = excludeArchivedValues;
|
||||
this.fieldValueSelections = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a field name and value to match.
|
||||
*
|
||||
* @param name the field name to query
|
||||
* @param value the value to query
|
||||
*/
|
||||
protected void setFieldValue(final String name, final Object value) {
|
||||
Object valueToAssign = value;
|
||||
|
||||
Preconditions.checkArgument(
|
||||
value != null,
|
||||
String.format("field value (%s) cannot be null.", name)
|
||||
);
|
||||
|
||||
if (value instanceof String) {
|
||||
Preconditions.checkArgument(
|
||||
StringUtils.isNotEmpty((String) value),
|
||||
"field value cannot be empty."
|
||||
);
|
||||
}
|
||||
|
||||
if (value instanceof byte[]) {
|
||||
byte[] valueBytes = (byte[]) value;
|
||||
|
||||
Preconditions.checkArgument(
|
||||
ArrayUtils.isNotEmpty(valueBytes),
|
||||
String.format("field value (%s) cannot be empty.", name)
|
||||
);
|
||||
|
||||
valueToAssign = Arrays.copyOf(valueBytes, valueBytes.length);
|
||||
}
|
||||
|
||||
fieldValueSelections.put(name, valueToAssign);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the result set as a single
|
||||
* {@link hirs.data.persist.ReferenceDigestValue}. This method is best used
|
||||
* when selecting on a unique attribute. If the result set contains more
|
||||
* than one RIM, one is chosen arbitrarily and returned. If no matching RIMs
|
||||
* are found, this method returns null.
|
||||
*
|
||||
* @return a matching ReferenceDigestValue or null if none is found
|
||||
*/
|
||||
public hirs.data.persist.ReferenceDigestValue getDigestValue() {
|
||||
Set<hirs.data.persist.ReferenceDigestValue> events = getDigestValues();
|
||||
if (events.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return events.iterator().next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the result set as a set of
|
||||
* {@link hirs.data.persist.ReferenceDigestValue}s. This method is best used
|
||||
* when selecting on non-unique attributes. ReferenceManifests are populated
|
||||
* into the set in no specific order. If no matching certificates are found,
|
||||
* the returned Set will be empty.
|
||||
*
|
||||
* @return a Set of matching ReferenceDigestValues, possibly empty
|
||||
*/
|
||||
public Set<hirs.data.persist.ReferenceDigestValue> getDigestValues() {
|
||||
return Collections.unmodifiableSet(new HashSet<hirs.data.persist.ReferenceDigestValue>(
|
||||
this.referenceEventManager.getEventList()));
|
||||
}
|
||||
/**
|
||||
* Construct the criterion that can be used to query for rims matching the
|
||||
* configuration of this {@link ReferenceEventSelector}.
|
||||
*
|
||||
* @return a Criterion that can be used to query for rims matching the
|
||||
* configuration of this instance
|
||||
*/
|
||||
Criterion getCriterion() {
|
||||
Conjunction conj = new Conjunction();
|
||||
|
||||
for (Map.Entry<String, Object> fieldValueEntry : fieldValueSelections.entrySet()) {
|
||||
conj.add(Restrictions.eq(fieldValueEntry.getKey(), fieldValueEntry.getValue()));
|
||||
}
|
||||
|
||||
if (this.excludeArchivedValues) {
|
||||
conj.add(Restrictions.isNull(Certificate.ARCHIVE_FIELD));
|
||||
}
|
||||
|
||||
return conj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the selector to query for archived and unarchived rims.
|
||||
*
|
||||
* @return the selector
|
||||
*/
|
||||
public ReferenceEventSelector includeArchived() {
|
||||
this.excludeArchivedValues = false;
|
||||
return this;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user