diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java index d2366bee..c0be411f 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java @@ -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 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 tpm2ProvisionerStateDBManager) { + final DBManager 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); } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/configuration/AttestationCertificateAuthorityConfiguration.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/configuration/AttestationCertificateAuthorityConfiguration.java index 48f07eea..f207eeb0 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/configuration/AttestationCertificateAuthorityConfiguration.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/configuration/AttestationCertificateAuthorityConfiguration.java @@ -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/**") diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/rest/RestfulAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/rest/RestfulAttestationCertificateAuthority.java index 254cfd3a..6b48e8bd 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/rest/RestfulAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/rest/RestfulAttestationCertificateAuthority.java @@ -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 tpm2ProvisionerStateDBManager, + final ReferenceDigestManager referenceDigestManager, @Value("${aca.certificates.validity}") final int validDays) { super(supplyChainValidationService, privateKey, acaCertificate, structConverter, certificateManager, referenceManifestManager, deviceRegister, validDays, deviceManager, - tpm2ProvisionerStateDBManager); + tpm2ProvisionerStateDBManager, referenceDigestManager); } /* diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/AbstractAttestationCertificateAuthorityTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/AbstractAttestationCertificateAuthorityTest.java index 5e5ade23..1ba111f1 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/AbstractAttestationCertificateAuthorityTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/AbstractAttestationCertificateAuthorityTest.java @@ -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) { }; } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/persistence/PersistenceConfiguration.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/persistence/PersistenceConfiguration.java index 78caad4a..75556c06 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/persistence/PersistenceConfiguration.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/persistence/PersistenceConfiguration.java @@ -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. * diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestRecord.java b/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestRecord.java index 3a2e4b1c..3a8a5286 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestRecord.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestRecord.java @@ -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 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); + } } diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestValue.java b/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestValue.java index aa095815..322171ac 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestValue.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestValue.java @@ -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]); diff --git a/HIRS_Utils/src/main/java/hirs/persist/DBReferenceDigestManager.java b/HIRS_Utils/src/main/java/hirs/persist/DBReferenceDigestManager.java index 057db95f..f692f2d3 100644 --- a/HIRS_Utils/src/main/java/hirs/persist/DBReferenceDigestManager.java +++ b/HIRS_Utils/src/main/java/hirs/persist/DBReferenceDigestManager.java @@ -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 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 Set get( - final ReferenceDigestSelector referenceDigestSelector) { - LOGGER.info("Getting the full set of Reference Digest Records."); - return new HashSet<>( - (List) 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 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 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 * @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); diff --git a/HIRS_Utils/src/main/java/hirs/persist/PersistenceConfiguration.java b/HIRS_Utils/src/main/java/hirs/persist/PersistenceConfiguration.java index 4c1da996..bd6f19f4 100644 --- a/HIRS_Utils/src/main/java/hirs/persist/PersistenceConfiguration.java +++ b/HIRS_Utils/src/main/java/hirs/persist/PersistenceConfiguration.java @@ -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. * diff --git a/HIRS_Utils/src/main/java/hirs/persist/ReferenceDigestManager.java b/HIRS_Utils/src/main/java/hirs/persist/ReferenceDigestManager.java index cbd0d03b..aef06272 100644 --- a/HIRS_Utils/src/main/java/hirs/persist/ReferenceDigestManager.java +++ b/HIRS_Utils/src/main/java/hirs/persist/ReferenceDigestManager.java @@ -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 { +public interface ReferenceDigestManager { /** * Persists a new Reference Digest. @@ -17,28 +17,45 @@ public interface ReferenceDigestManager extends OrderedListQuerier getRecordsByManufacturer( + ReferenceDigestRecord referenceDigestRecord); + + /** + * Persists a new Reference Digest. + * + * @param referenceDigestRecord the ReferenceDigestRecord + * @return the persisted ReferenceDigestRecord + */ + List 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 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 - */ - Set 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); } diff --git a/HIRS_Utils/src/main/java/hirs/persist/ReferenceDigestSelector.java b/HIRS_Utils/src/main/java/hirs/persist/ReferenceDigestSelector.java deleted file mode 100644 index 99e09891..00000000 --- a/HIRS_Utils/src/main/java/hirs/persist/ReferenceDigestSelector.java +++ /dev/null @@ -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 the type of Reference Integrity Manifest that will be retrieved. - */ -public abstract class ReferenceDigestSelector { - /** - * 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 referenceTypeClass; - - private final Map 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 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 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 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 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 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 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 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 getReferenceDigestClass() { - return this.referenceTypeClass; - } - - // construct and execute query - private Set execute() { - Set results = this.referenceDigestManager.get(this); - return results; - } - - /** - * Configures the selector to query for archived and unarchived rims. - * - * @return the selector - */ - public ReferenceDigestSelector includeArchived() { - this.excludeArchivedRims = false; - return this; - } -}