mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-04-07 11:26:51 +00:00
This is an initial commit with changes that add new classes for digest reference matching.
This commit is contained in:
parent
9134e2ab9d
commit
53cb300063
@ -12,6 +12,7 @@ import hirs.data.persist.BaseReferenceManifest;
|
||||
import hirs.data.persist.EventLogMeasurements;
|
||||
import hirs.data.persist.Device;
|
||||
import hirs.data.persist.DeviceInfoReport;
|
||||
import hirs.data.persist.ReferenceDigestRecord;
|
||||
import hirs.data.persist.ReferenceManifest;
|
||||
import hirs.data.persist.SupplyChainPolicy;
|
||||
import hirs.data.persist.SupportReferenceManifest;
|
||||
@ -28,6 +29,7 @@ import hirs.data.persist.certificate.IssuedAttestationCertificate;
|
||||
import hirs.data.persist.certificate.PlatformCredential;
|
||||
import hirs.data.service.DeviceRegister;
|
||||
import hirs.persist.CertificateManager;
|
||||
import hirs.persist.ReferenceDigestManager;
|
||||
import hirs.persist.ReferenceManifestManager;
|
||||
import hirs.persist.DBManager;
|
||||
import hirs.persist.DeviceManager;
|
||||
@ -169,6 +171,7 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
private final DeviceRegister deviceRegister;
|
||||
private final DeviceManager deviceManager;
|
||||
private final DBManager<TPM2ProvisionerState> tpm2ProvisionerStateDBManager;
|
||||
private final ReferenceDigestManager referenceDigestManager;
|
||||
private String tpmQuoteHash = "";
|
||||
private String tpmQuoteSignature = "";
|
||||
private String pcrValues;
|
||||
@ -185,6 +188,7 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
* @param validDays the number of days issued certs are valid
|
||||
* @param deviceManager the device manager
|
||||
* @param tpm2ProvisionerStateDBManager the DBManager for persisting provisioner state
|
||||
* @param referenceDigestManager the reference digest manager
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:parameternumber")
|
||||
public AbstractAttestationCertificateAuthority(
|
||||
@ -195,7 +199,8 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
final ReferenceManifestManager referenceManifestManager,
|
||||
final DeviceRegister deviceRegister, final int validDays,
|
||||
final DeviceManager deviceManager,
|
||||
final DBManager<TPM2ProvisionerState> tpm2ProvisionerStateDBManager) {
|
||||
final DBManager<TPM2ProvisionerState> tpm2ProvisionerStateDBManager,
|
||||
final ReferenceDigestManager referenceDigestManager) {
|
||||
this.supplyChainValidationService = supplyChainValidationService;
|
||||
this.privateKey = privateKey;
|
||||
this.acaCertificate = acaCertificate;
|
||||
@ -206,6 +211,7 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
this.validDays = validDays;
|
||||
this.deviceManager = deviceManager;
|
||||
this.tpm2ProvisionerStateDBManager = tpm2ProvisionerStateDBManager;
|
||||
this.referenceDigestManager = referenceDigestManager;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -841,6 +847,15 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
support.resetCreateTime();
|
||||
this.referenceManifestManager.update(support);
|
||||
}
|
||||
|
||||
// this is where we update or create the log
|
||||
ReferenceDigestRecord rdr = new ReferenceDigestRecord(support,
|
||||
hw.getManufacturer(), hw.getProductName());
|
||||
|
||||
|
||||
referenceDigestManager.saveRecord(rdr);
|
||||
|
||||
|
||||
} catch (IOException ioEx) {
|
||||
LOG.error(ioEx);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package hirs.attestationca.configuration;
|
||||
|
||||
import hirs.persist.DBReferenceDigestManager;
|
||||
import hirs.persist.ReferenceDigestManager;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
@ -252,6 +254,16 @@ public class AttestationCertificateAuthorityConfiguration extends WebMvcConfigur
|
||||
return new DBReferenceManifestManager(sessionFactory.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link ReferenceDigestManager} ready to use.
|
||||
*
|
||||
* @return {@link ReferenceDigestManager}
|
||||
*/
|
||||
@Bean
|
||||
public ReferenceDigestManager referenceDigestManager() {
|
||||
return new DBReferenceDigestManager(sessionFactory.getObject());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(final ResourceHandlerRegistry resourceHandlerRegistry) {
|
||||
resourceHandlerRegistry.addResourceHandler("/client-files/**")
|
||||
|
@ -1,6 +1,7 @@
|
||||
package hirs.attestationca.rest;
|
||||
|
||||
import hirs.persist.DBManager;
|
||||
import hirs.persist.ReferenceDigestManager;
|
||||
import hirs.persist.TPM2ProvisionerState;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -42,6 +43,7 @@ public class RestfulAttestationCertificateAuthority
|
||||
* @param validDays the number of days issued certs are valid
|
||||
* @param deviceManager the device manager
|
||||
* @param tpm2ProvisionerStateDBManager the DBManager for persisting provisioner state
|
||||
* @param referenceDigestManager the reference digest manager
|
||||
*/
|
||||
@SuppressWarnings({ "checkstyle:parameternumber" })
|
||||
@Autowired
|
||||
@ -54,11 +56,12 @@ public class RestfulAttestationCertificateAuthority
|
||||
final DeviceRegister deviceRegister,
|
||||
final DeviceManager deviceManager,
|
||||
final DBManager<TPM2ProvisionerState> tpm2ProvisionerStateDBManager,
|
||||
final ReferenceDigestManager referenceDigestManager,
|
||||
@Value("${aca.certificates.validity}") final int validDays) {
|
||||
super(supplyChainValidationService, privateKey, acaCertificate, structConverter,
|
||||
certificateManager, referenceManifestManager,
|
||||
deviceRegister, validDays, deviceManager,
|
||||
tpm2ProvisionerStateDBManager);
|
||||
tpm2ProvisionerStateDBManager, referenceDigestManager);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -133,7 +133,7 @@ public class AbstractAttestationCertificateAuthorityTest {
|
||||
public void setup() {
|
||||
aca = new AbstractAttestationCertificateAuthority(null, keyPair.getPrivate(),
|
||||
null, null, null, null, null, 1,
|
||||
null, null) {
|
||||
null, null, null) {
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import hirs.persist.AppraiserManager;
|
||||
import hirs.persist.CrudManager;
|
||||
import hirs.persist.DBAppraiserManager;
|
||||
import hirs.persist.DBCertificateManager;
|
||||
import hirs.persist.DBReferenceDigestManager;
|
||||
import hirs.persist.DBReferenceManifestManager;
|
||||
import hirs.persist.DBDeviceGroupManager;
|
||||
import hirs.persist.DBDeviceManager;
|
||||
@ -71,6 +72,16 @@ public class PersistenceConfiguration {
|
||||
return new DBReferenceManifestManager(sessionFactory.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link DBReferenceDigestManager} ready to use.
|
||||
*
|
||||
* @return {@link DBReferenceDigestManager}
|
||||
*/
|
||||
@Bean
|
||||
public DBReferenceDigestManager referenceDigestManager() {
|
||||
return new DBReferenceDigestManager(sessionFactory.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link AppraiserManager} ready to use.
|
||||
*
|
||||
|
@ -1,10 +1,11 @@
|
||||
package hirs.data.persist;
|
||||
|
||||
import org.bouncycastle.util.Arrays;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* This class will represent an entry a table that'll be associated
|
||||
@ -15,38 +16,89 @@ import java.util.List;
|
||||
@Table(name = "ReferenceDigestRecord")
|
||||
public class ReferenceDigestRecord extends ArchivableEntity {
|
||||
|
||||
@Column
|
||||
private UUID supportRim;
|
||||
@Column(nullable = false)
|
||||
private String manufacturer;
|
||||
@Column(nullable = false)
|
||||
private String model;
|
||||
@Column(columnDefinition = "blob", nullable = false)
|
||||
@Column(columnDefinition = "blob", nullable = true)
|
||||
private byte[] valueBlob;
|
||||
|
||||
// NOTE: when this works, and do a show tables to give to Lawrence
|
||||
private List<ReferenceDigestValue> associatedDigests = new ArrayList<>();
|
||||
@Column
|
||||
private boolean supportLoaded;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*/
|
||||
protected ReferenceDigestRecord() {
|
||||
super();
|
||||
this.manufacturer = null;
|
||||
this.model = null;
|
||||
// I wonder if this will throw and error
|
||||
this.supportRim = UUID.randomUUID();
|
||||
this.manufacturer = "";
|
||||
this.model = "";
|
||||
this.valueBlob = null;
|
||||
this.supportLoaded = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor with parameters.
|
||||
* @param supportRim link to the source of data
|
||||
* @param manufacturer device manufacturer
|
||||
* @param model device model
|
||||
* @param valueBlob the data values of the event.
|
||||
*/
|
||||
public ReferenceDigestRecord(final String manufacturer,
|
||||
public ReferenceDigestRecord(final UUID supportRim,
|
||||
final String manufacturer,
|
||||
final String model,
|
||||
final byte[] valueBlob) {
|
||||
super();
|
||||
// need to put up nullable entries
|
||||
this.supportRim = supportRim;
|
||||
this.manufacturer = manufacturer;
|
||||
this.model = model;
|
||||
this.valueBlob = valueBlob.clone();
|
||||
this.valueBlob = Arrays.clone(valueBlob);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor with parameters specitic to a RIM object.
|
||||
* @param referenceManifest rim object to use.
|
||||
* @param manufacturer device manufacturer
|
||||
* @param model device model
|
||||
*/
|
||||
public ReferenceDigestRecord(final ReferenceManifest referenceManifest,
|
||||
final String manufacturer,
|
||||
final String model) {
|
||||
super();
|
||||
if (referenceManifest instanceof SupportReferenceManifest) {
|
||||
this.supportRim = referenceManifest.getId();
|
||||
this.supportLoaded = true;
|
||||
SupportReferenceManifest srm = (SupportReferenceManifest) referenceManifest;
|
||||
this.valueBlob = Arrays.clone(srm.getRimBytes());
|
||||
} else if (referenceManifest != null) {
|
||||
// the assumption is that there is a support RIM.
|
||||
this.supportRim = referenceManifest.getAssociatedRim();
|
||||
// I will just test for loaded and if true but blob is empty, pull
|
||||
// that information later and update the object
|
||||
}
|
||||
|
||||
this.manufacturer = manufacturer;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the linked source for the data.
|
||||
* @return UUID of the source
|
||||
*/
|
||||
public UUID getSupportRim() {
|
||||
return supportRim;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the linked source for the data.
|
||||
* @param supportRim UUID of the source
|
||||
*/
|
||||
public void setSupportRim(final UUID supportRim) {
|
||||
this.supportRim = supportRim;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,4 +150,14 @@ public class ReferenceDigestRecord extends ArchivableEntity {
|
||||
this.valueBlob = valueBlob.clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The string value representative of this class.
|
||||
* @return manufacturer and model for this record
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s%n%s -> %s",
|
||||
super.toString(), this.manufacturer, this.model);
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,10 @@ public class ReferenceDigestValue {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe add the match fail status to the device object: eventNumber, digest value
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default Constructor with a parameter for the data.
|
||||
* @param data event data
|
||||
@ -31,6 +35,7 @@ public class ReferenceDigestValue {
|
||||
this.chunk = data.clone();
|
||||
int i = 0;
|
||||
this.eventNumber = data[i];
|
||||
// look to using the Digest class
|
||||
this.digestValue = String.valueOf(data[++i]);
|
||||
this.eventType = String.valueOf(data[++i]);
|
||||
this.tagId = String.valueOf(data[++i]);
|
||||
|
@ -4,10 +4,8 @@ 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
|
||||
@ -27,27 +25,51 @@ public class DBReferenceDigestManager extends DBManager<ReferenceDigestRecord>
|
||||
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())
|
||||
)
|
||||
);
|
||||
public ReferenceDigestRecord saveRecord(final ReferenceDigestRecord referenceDigestRecord) {
|
||||
LOGGER.debug("saving state: {}", referenceDigestRecord);
|
||||
try {
|
||||
return save(referenceDigestRecord);
|
||||
} catch (DBManagerException dbMEx) {
|
||||
throw new RuntimeException(dbMEx);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReferenceDigestRecord getRecord(final ReferenceDigestRecord referenceDigestRecord) {
|
||||
LOGGER.debug("Getting record for {}", referenceDigestRecord);
|
||||
if (referenceDigestRecord == null) {
|
||||
LOGGER.error("null referenceDigestRecord argument");
|
||||
throw new NullPointerException("null referenceDigestRecord");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReferenceDigestRecord> getRecordsByManufacturer(
|
||||
final ReferenceDigestRecord referenceDigestRecord) {
|
||||
LOGGER.debug("Getting records by manufacturer for {}", referenceDigestRecord);
|
||||
if (referenceDigestRecord == null) {
|
||||
LOGGER.error("null referenceDigestRecord argument");
|
||||
throw new NullPointerException("null referenceDigestRecord");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReferenceDigestRecord> getRecordsByModel(
|
||||
final ReferenceDigestRecord referenceDigestRecord) {
|
||||
LOGGER.debug("Getting records by model for {}", referenceDigestRecord);
|
||||
if (referenceDigestRecord == null) {
|
||||
LOGGER.error("null referenceDigestRecord argument");
|
||||
throw new NullPointerException("null referenceDigestRecord");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateRecord(final ReferenceDigestRecord referenceDigestRecord) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,7 +78,8 @@ public class DBReferenceDigestManager extends DBManager<ReferenceDigestRecord>
|
||||
* @param referenceDigestRecord the referenceDigestRecord to delete
|
||||
* @return true if deletion was successful, false otherwise
|
||||
*/
|
||||
public boolean deleteReferenceManifest(final ReferenceDigestRecord referenceDigestRecord) {
|
||||
@Override
|
||||
public boolean deleteRecord(final ReferenceDigestRecord referenceDigestRecord) {
|
||||
LOGGER.info(String.format("Deleting reference to %s/%s",
|
||||
referenceDigestRecord.getManufacturer(), referenceDigestRecord.getModel()));
|
||||
return delete(referenceDigestRecord);
|
||||
|
@ -154,6 +154,19 @@ public class PersistenceConfiguration {
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link ReferenceDigestManager} ready to use.
|
||||
*
|
||||
* @return {@link ReferenceDigestManager}
|
||||
*/
|
||||
@Bean
|
||||
public ReferenceDigestManager referenceDigestManager() {
|
||||
DBReferenceDigestManager manager
|
||||
= new DBReferenceDigestManager(sessionFactory.getObject());
|
||||
setDbManagerRetrySettings(manager);
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link DeviceStateManager} ready to use.
|
||||
*
|
||||
|
@ -3,13 +3,13 @@ package hirs.persist;
|
||||
|
||||
import hirs.data.persist.ReferenceDigestRecord;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class facilitates the persistence of {@link hirs.data.persist.ReferenceDigestRecord}s
|
||||
* including storage, retrieval, and deletion.
|
||||
*/
|
||||
public interface ReferenceDigestManager extends OrderedListQuerier<ReferenceDigestRecord> {
|
||||
public interface ReferenceDigestManager {
|
||||
|
||||
/**
|
||||
* Persists a new Reference Digest.
|
||||
@ -17,28 +17,45 @@ public interface ReferenceDigestManager extends OrderedListQuerier<ReferenceDige
|
||||
* @param referenceDigestRecord the ReferenceDigestRecord
|
||||
* @return the persisted ReferenceDigestRecord
|
||||
*/
|
||||
ReferenceDigestRecord save(ReferenceDigestRecord referenceDigestRecord);
|
||||
ReferenceDigestRecord saveRecord(ReferenceDigestRecord referenceDigestRecord);
|
||||
|
||||
/**
|
||||
* Persists a new Reference Digest.
|
||||
*
|
||||
* @param referenceDigestRecord the ReferenceDigestRecord
|
||||
* @return the persisted ReferenceDigestRecord
|
||||
*/
|
||||
ReferenceDigestRecord getRecord(ReferenceDigestRecord referenceDigestRecord);
|
||||
|
||||
/**
|
||||
* Persists a new Reference Digest.
|
||||
*
|
||||
* @param referenceDigestRecord the ReferenceDigestRecord
|
||||
* @return the persisted ReferenceDigestRecord
|
||||
*/
|
||||
List<ReferenceDigestRecord> getRecordsByManufacturer(
|
||||
ReferenceDigestRecord referenceDigestRecord);
|
||||
|
||||
/**
|
||||
* Persists a new Reference Digest.
|
||||
*
|
||||
* @param referenceDigestRecord the ReferenceDigestRecord
|
||||
* @return the persisted ReferenceDigestRecord
|
||||
*/
|
||||
List<ReferenceDigestRecord> getRecordsByModel(ReferenceDigestRecord referenceDigestRecord);
|
||||
|
||||
/**
|
||||
* Updates an existing ReferenceDigestRecord.
|
||||
* @param referenceDigestRecord the Reference Digest update
|
||||
* @return status of successful update
|
||||
*/
|
||||
void update(ReferenceDigestRecord referenceDigestRecord);
|
||||
boolean updateRecord(ReferenceDigestRecord referenceDigestRecord);
|
||||
|
||||
/**
|
||||
* Retrieve Reference Digest according to the given {@link ReferenceDigestSelector}.
|
||||
* Delete the given record.
|
||||
*
|
||||
* @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
|
||||
* @param referenceDigestRecord the digest record delete
|
||||
* @return true if the deletion succeeded, false otherwise.
|
||||
*/
|
||||
boolean delete(ReferenceDigestRecord referenceDigestRecord);
|
||||
boolean deleteRecord(ReferenceDigestRecord referenceDigestRecord);
|
||||
}
|
||||
|
@ -1,209 +0,0 @@
|
||||
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