mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-04-07 11:26:51 +00:00
This adds the additional classes
This commit is contained in:
parent
19aa3c27a1
commit
accbc422e7
@ -0,0 +1,101 @@
|
||||
package hirs.data.persist;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class will represent an entry a table that'll be associated
|
||||
* with the manufacturer and model with all digest values,
|
||||
* Event Type, index, RIM Tagid.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "ReferenceDigestRecord")
|
||||
public class ReferenceDigestRecord extends ArchivableEntity {
|
||||
|
||||
@Column(nullable = false)
|
||||
private String manufacturer;
|
||||
@Column(nullable = false)
|
||||
private String model;
|
||||
@Column(columnDefinition = "blob", nullable = false)
|
||||
private byte[] valueBlob;
|
||||
|
||||
// NOTE: when this works, and do a show tables to give to Lawrence
|
||||
private List<ReferenceDigestValue> associatedDigests = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*/
|
||||
protected ReferenceDigestRecord() {
|
||||
super();
|
||||
this.manufacturer = null;
|
||||
this.model = null;
|
||||
this.valueBlob = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor with parameters.
|
||||
* @param manufacturer device manufacturer
|
||||
* @param model device model
|
||||
* @param valueBlob the data values of the event.
|
||||
*/
|
||||
public ReferenceDigestRecord(final String manufacturer,
|
||||
final String model,
|
||||
final byte[] valueBlob) {
|
||||
this.manufacturer = manufacturer;
|
||||
this.model = model;
|
||||
this.valueBlob = valueBlob.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the manufacturer associated.
|
||||
* @return the string of the manufacturer
|
||||
*/
|
||||
public String getManufacturer() {
|
||||
return manufacturer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the manufacturer associated.
|
||||
* @param manufacturer the string of the manufacturer
|
||||
*/
|
||||
public void setManufacturer(final String manufacturer) {
|
||||
this.manufacturer = manufacturer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the model associated.
|
||||
* @return the string of the model
|
||||
*/
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the model associated.
|
||||
* @param model the string of the model
|
||||
*/
|
||||
public void setModel(final String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the byte array of event values.
|
||||
* @return a clone of the byte array
|
||||
*/
|
||||
public byte[] getValueBlob() {
|
||||
return valueBlob.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the byte array of values.
|
||||
* @param valueBlob non-null array.
|
||||
*/
|
||||
public void setValueBlob(final byte[] valueBlob) {
|
||||
if (valueBlob != null) {
|
||||
this.valueBlob = valueBlob.clone();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package hirs.data.persist;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* This class represents that actual entry in the Support RIM.
|
||||
* Digest Value, Event Type, index, RIM Tagid
|
||||
*/
|
||||
public class ReferenceDigestValue {
|
||||
|
||||
private int eventNumber;
|
||||
private String digestValue;
|
||||
private String eventType;
|
||||
private String tagId;
|
||||
private boolean matchFail;
|
||||
private byte[] chunk;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*/
|
||||
public ReferenceDigestValue() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Constructor with a parameter for the data.
|
||||
* @param data event data
|
||||
*/
|
||||
public ReferenceDigestValue(final byte[] data) {
|
||||
this.chunk = data.clone();
|
||||
int i = 0;
|
||||
this.eventNumber = data[i];
|
||||
this.digestValue = String.valueOf(data[++i]);
|
||||
this.eventType = String.valueOf(data[++i]);
|
||||
this.tagId = String.valueOf(data[++i]);
|
||||
this.matchFail = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Constructor with parameters for all associated data.
|
||||
* @param eventNumber the event number
|
||||
* @param digestValue the key digest value
|
||||
* @param eventType the event type
|
||||
* @param tagId the tag id
|
||||
* @param matchFail the status of the baseline check
|
||||
*/
|
||||
public ReferenceDigestValue(final int eventNumber, final String digestValue,
|
||||
final String eventType, final String tagId, final boolean matchFail) {
|
||||
this.eventNumber = eventNumber;
|
||||
this.digestValue = digestValue;
|
||||
this.eventType = eventType;
|
||||
this.tagId = tagId;
|
||||
this.matchFail = matchFail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ReferenceDigestValue that = (ReferenceDigestValue) obj;
|
||||
return eventNumber == that.eventNumber && matchFail == that.matchFail
|
||||
&& Objects.equals(digestValue, that.digestValue)
|
||||
&& Objects.equals(eventType, that.eventType)
|
||||
&& Objects.equals(tagId, that.tagId) && Arrays.equals(chunk, that.chunk);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("MagicNumber")
|
||||
public int hashCode() {
|
||||
int result = Objects.hash(eventNumber, digestValue, eventType, tagId, matchFail);
|
||||
result = 31 * result + Arrays.hashCode(chunk);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package hirs.persist;
|
||||
|
||||
import hirs.data.persist.ReferenceDigestRecord;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.hibernate.SessionFactory;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class is used to persist and retrieve {@link hirs.data.persist.ReferenceDigestRecord}s into
|
||||
* and from the database.
|
||||
*/
|
||||
public class DBReferenceDigestManager extends DBManager<ReferenceDigestRecord>
|
||||
implements ReferenceDigestManager {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(DBReferenceDigestManager.class);
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param sessionFactory session factory used to access database connections
|
||||
*/
|
||||
public DBReferenceDigestManager(final SessionFactory sessionFactory) {
|
||||
super(ReferenceDigestRecord.class, sessionFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method does not need to be used directly as it is used by
|
||||
* {@link ReferenceManifestSelector}'s get* methods. Regardless, it may be
|
||||
* used to retrieve ReferenceManifest by other code in this package, given a
|
||||
* configured ReferenceManifestSelector.
|
||||
*
|
||||
* @param referenceDigestSelector a configured
|
||||
* {@link ReferenceDigestSelector} to use for querying
|
||||
* @return the resulting set of ReferenceManifest, possibly empty
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends ReferenceDigestRecord> Set<T> get(
|
||||
final ReferenceDigestSelector referenceDigestSelector) {
|
||||
LOGGER.info("Getting the full set of Reference Digest Records.");
|
||||
return new HashSet<>(
|
||||
(List<T>) getWithCriteria(
|
||||
referenceDigestSelector.getReferenceDigestClass(),
|
||||
Collections.singleton(referenceDigestSelector.getCriterion())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a ReferenceDigestRecord from the database.
|
||||
*
|
||||
* @param referenceDigestRecord the referenceDigestRecord to delete
|
||||
* @return true if deletion was successful, false otherwise
|
||||
*/
|
||||
public boolean deleteReferenceManifest(final ReferenceDigestRecord referenceDigestRecord) {
|
||||
LOGGER.info(String.format("Deleting reference to %s/%s",
|
||||
referenceDigestRecord.getManufacturer(), referenceDigestRecord.getModel()));
|
||||
return delete(referenceDigestRecord);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
|
||||
package hirs.persist;
|
||||
|
||||
import hirs.data.persist.ReferenceDigestRecord;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class facilitates the persistence of {@link hirs.data.persist.ReferenceDigestRecord}s
|
||||
* including storage, retrieval, and deletion.
|
||||
*/
|
||||
public interface ReferenceDigestManager extends OrderedListQuerier<ReferenceDigestRecord> {
|
||||
|
||||
/**
|
||||
* Persists a new Reference Digest.
|
||||
*
|
||||
* @param referenceDigestRecord the ReferenceDigestRecord
|
||||
* @return the persisted ReferenceDigestRecord
|
||||
*/
|
||||
ReferenceDigestRecord save(ReferenceDigestRecord referenceDigestRecord);
|
||||
|
||||
/**
|
||||
* Updates an existing ReferenceDigestRecord.
|
||||
* @param referenceDigestRecord the Reference Digest update
|
||||
*/
|
||||
void update(ReferenceDigestRecord referenceDigestRecord);
|
||||
|
||||
/**
|
||||
* Retrieve Reference Digest according to the given {@link ReferenceDigestSelector}.
|
||||
*
|
||||
* @param <T> the type of reference digest that will be retrieved
|
||||
* @param referenceDigestSelector a {@link ReferenceDigestSelector} to use for querying
|
||||
* @return a Set of matching RIMs, which may be empty
|
||||
*/
|
||||
<T extends ReferenceDigestRecord> Set<T> get(ReferenceDigestSelector referenceDigestSelector);
|
||||
|
||||
/**
|
||||
* Delete the given RIM.
|
||||
*
|
||||
* @param referenceDigestRecord the RIM to delete
|
||||
* @return true if the deletion succeeded, false otherwise.
|
||||
*/
|
||||
boolean delete(ReferenceDigestRecord referenceDigestRecord);
|
||||
}
|
@ -0,0 +1,209 @@
|
||||
package hirs.persist;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import hirs.data.persist.ReferenceDigestRecord;
|
||||
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 RIMs in conjunction
|
||||
* with a {@link ReferenceDigestManager}. To make use of this object,
|
||||
* use (some ReferenceManifest).select(ReferenceManifestManager).
|
||||
*
|
||||
* @param <T> the type of Reference Integrity Manifest that will be retrieved.
|
||||
*/
|
||||
public abstract class ReferenceDigestSelector<T extends ReferenceDigestRecord> {
|
||||
/**
|
||||
* String representing the database field for the manufacturer.
|
||||
*/
|
||||
public static final String PLATFORM_MANUFACTURER = "manufacturer";
|
||||
/**
|
||||
* String representing the database field for the manufacturer id.
|
||||
*/
|
||||
public static final String PLATFORM_MODEL = "model";
|
||||
|
||||
private final ReferenceDigestManager referenceDigestManager;
|
||||
private final Class<T> referenceTypeClass;
|
||||
|
||||
private final Map<String, Object> fieldValueSelections;
|
||||
private boolean excludeArchivedRims;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param referenceDigestManager the RIM manager to be used to retrieve RIMs
|
||||
* @param referenceTypeClass the type of Reference Manifest to process.
|
||||
*/
|
||||
public ReferenceDigestSelector(final ReferenceDigestManager referenceDigestManager,
|
||||
final Class<T> referenceTypeClass) {
|
||||
this(referenceDigestManager, referenceTypeClass, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Constructor for the Selector.
|
||||
*
|
||||
* @param referenceDigestManager the RIM manager to be used to retrieve RIMs
|
||||
* @param referenceTypeClass the type of Reference Manifest to process.
|
||||
* @param excludeArchivedRims true if excluding archived RIMs
|
||||
*/
|
||||
public ReferenceDigestSelector(final ReferenceDigestManager referenceDigestManager,
|
||||
final Class<T> referenceTypeClass,
|
||||
final boolean excludeArchivedRims) {
|
||||
Preconditions.checkArgument(
|
||||
referenceDigestManager != null,
|
||||
"reference manifest manager cannot be null"
|
||||
);
|
||||
|
||||
Preconditions.checkArgument(
|
||||
referenceTypeClass != null,
|
||||
"type cannot be null"
|
||||
);
|
||||
|
||||
this.referenceDigestManager = referenceDigestManager;
|
||||
this.referenceTypeClass = referenceTypeClass;
|
||||
this.excludeArchivedRims = excludeArchivedRims;
|
||||
this.fieldValueSelections = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the entity id that rims must have to be considered as matching.
|
||||
*
|
||||
* @param manufacturer the UUID to query
|
||||
* @return this instance (for chaining further calls)
|
||||
*/
|
||||
public ReferenceDigestSelector<T> byManufacturer(final String manufacturer) {
|
||||
setFieldValue(PLATFORM_MANUFACTURER, manufacturer);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the hash code of the bytes that rim must match.
|
||||
*
|
||||
* @param model the hash code of the bytes to query for
|
||||
* @return this instance (for chaining further calls)
|
||||
*/
|
||||
public ReferenceDigestSelector<T> byModel(final String model) {
|
||||
setFieldValue(PLATFORM_MODEL, model);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.ReferenceDigestRecord}. 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 digest record or null if none is found
|
||||
*/
|
||||
public T getDigestRecord() {
|
||||
Set<T> rims = execute();
|
||||
if (rims.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return rims.iterator().next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the result set as a set of
|
||||
* {@link hirs.data.persist.ReferenceDigestRecord}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 RIMs, possibly empty
|
||||
*/
|
||||
public Set<T> getDigestRecords() {
|
||||
return Collections.unmodifiableSet(new HashSet<>(execute()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the criterion that can be used to query for rims matching the
|
||||
* configuration of this {@link hirs.persist.ReferenceDigestSelector}.
|
||||
*
|
||||
* @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.excludeArchivedRims) {
|
||||
conj.add(Restrictions.isNull(Certificate.ARCHIVE_FIELD));
|
||||
}
|
||||
|
||||
return conj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the rim class that this instance will query
|
||||
*/
|
||||
public Class<T> getReferenceDigestClass() {
|
||||
return this.referenceTypeClass;
|
||||
}
|
||||
|
||||
// construct and execute query
|
||||
private Set<T> execute() {
|
||||
Set<T> results = this.referenceDigestManager.get(this);
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the selector to query for archived and unarchived rims.
|
||||
*
|
||||
* @return the selector
|
||||
*/
|
||||
public ReferenceDigestSelector<T> includeArchived() {
|
||||
this.excludeArchivedRims = false;
|
||||
return this;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user