diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java index d2366bee..8a3361b9 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java @@ -9,28 +9,32 @@ import hirs.attestationca.exceptions.UnexpectedServerException; import hirs.attestationca.service.SupplyChainValidationService; import hirs.data.persist.AppraisalStatus; import hirs.data.persist.BaseReferenceManifest; -import hirs.data.persist.EventLogMeasurements; import hirs.data.persist.Device; import hirs.data.persist.DeviceInfoReport; +import hirs.data.persist.EventLogMeasurements; +import hirs.data.persist.ReferenceDigestRecord; +import hirs.data.persist.ReferenceDigestValue; import hirs.data.persist.ReferenceManifest; import hirs.data.persist.SupplyChainPolicy; +import hirs.data.persist.SupplyChainValidationSummary; import hirs.data.persist.SupportReferenceManifest; import hirs.data.persist.SwidResource; -import hirs.data.persist.info.FirmwareInfo; -import hirs.data.persist.info.HardwareInfo; -import hirs.data.persist.info.NetworkInfo; -import hirs.data.persist.info.OSInfo; -import hirs.data.persist.SupplyChainValidationSummary; -import hirs.data.persist.info.TPMInfo; import hirs.data.persist.certificate.Certificate; import hirs.data.persist.certificate.EndorsementCredential; import hirs.data.persist.certificate.IssuedAttestationCertificate; import hirs.data.persist.certificate.PlatformCredential; +import hirs.data.persist.info.FirmwareInfo; +import hirs.data.persist.info.HardwareInfo; +import hirs.data.persist.info.NetworkInfo; +import hirs.data.persist.info.OSInfo; +import hirs.data.persist.info.TPMInfo; import hirs.data.service.DeviceRegister; import hirs.persist.CertificateManager; -import hirs.persist.ReferenceManifestManager; import hirs.persist.DBManager; import hirs.persist.DeviceManager; +import hirs.persist.ReferenceDigestManager; +import hirs.persist.ReferenceEventManager; +import hirs.persist.ReferenceManifestManager; import hirs.persist.TPM2ProvisionerState; import hirs.structs.converters.SimpleStructBuilder; import hirs.structs.converters.StructConverter; @@ -42,6 +46,8 @@ import hirs.structs.elements.tpm.IdentityProof; import hirs.structs.elements.tpm.IdentityRequest; import hirs.structs.elements.tpm.SymmetricKey; import hirs.structs.elements.tpm.SymmetricKeyParams; +import hirs.tpm.eventlog.TCGEventLog; +import hirs.tpm.eventlog.TpmPcrEvent; import hirs.utils.HexUtils; import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang3.ArrayUtils; @@ -169,6 +175,8 @@ public abstract class AbstractAttestationCertificateAuthority private final DeviceRegister deviceRegister; private final DeviceManager deviceManager; private final DBManager tpm2ProvisionerStateDBManager; + private final ReferenceDigestManager referenceDigestManager; + private final ReferenceEventManager referenceEventManager; private String tpmQuoteHash = ""; private String tpmQuoteSignature = ""; private String pcrValues; @@ -185,6 +193,8 @@ 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 + * @param referenceEventManager the reference event manager */ @SuppressWarnings("checkstyle:parameternumber") public AbstractAttestationCertificateAuthority( @@ -195,7 +205,9 @@ 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, + final ReferenceEventManager referenceEventManager) { this.supplyChainValidationService = supplyChainValidationService; this.privateKey = privateKey; this.acaCertificate = acaCertificate; @@ -206,6 +218,8 @@ public abstract class AbstractAttestationCertificateAuthority this.validDays = validDays; this.deviceManager = deviceManager; this.tpm2ProvisionerStateDBManager = tpm2ProvisionerStateDBManager; + this.referenceDigestManager = referenceDigestManager; + this.referenceEventManager = referenceEventManager; } /** @@ -841,6 +855,34 @@ public abstract class AbstractAttestationCertificateAuthority support.resetCreateTime(); this.referenceManifestManager.update(support); } + + ReferenceDigestRecord dbObj = new ReferenceDigestRecord(support, + hw.getManufacturer(), hw.getProductName()); + // this is where we update or create the log + ReferenceDigestRecord rdr = this.referenceDigestManager.getRecord(dbObj); + + // Handle baseline digest records + // is there already a baseline? + if (rdr == null) { + // doesn't exist, store + rdr = referenceDigestManager.saveRecord(dbObj); + } // right now this will not deal with updating + + if (this.referenceEventManager.getValuesByRecordId(rdr).isEmpty()) { + try { + TCGEventLog logProcessor = new TCGEventLog(support.getRimBytes()); + ReferenceDigestValue rdv; + for (TpmPcrEvent tpe : logProcessor.getEventList()) { + rdv = new ReferenceDigestValue(rdr.getId(), tpe.getEventNumber(), + tpe.getEventDigestStr(), tpe.getEventTypeStr(), false); + this.referenceEventManager.saveValue(rdv); + } + } catch (CertificateException cEx) { + LOG.error(cEx); + } catch (NoSuchAlgorithmException noSaEx) { + LOG.error(noSaEx); + } + } } 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..3b604f71 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,19 @@ package hirs.attestationca.configuration; +import hirs.persist.DBDeviceGroupManager; +import hirs.persist.DBDeviceManager; +import hirs.persist.DBReferenceDigestManager; +import hirs.persist.DBReferenceEventManager; +import hirs.persist.DBReferenceManifestManager; +import hirs.persist.DeviceGroupManager; +import hirs.persist.DeviceManager; +import hirs.persist.HibernateConfiguration; +import hirs.persist.ReferenceDigestManager; +import hirs.persist.ReferenceEventManager; +import hirs.persist.ReferenceManifestManager; +import hirs.structs.converters.SimpleStructConverter; +import hirs.structs.converters.StructConverter; +import hirs.utils.LogConfigurationUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -31,16 +45,6 @@ import java.security.KeyStoreException; import java.security.PrivateKey; import java.security.Security; import java.security.cert.X509Certificate; -import hirs.persist.DBDeviceGroupManager; -import hirs.persist.DBDeviceManager; -import hirs.persist.DeviceGroupManager; -import hirs.persist.DeviceManager; -import hirs.persist.ReferenceManifestManager; -import hirs.persist.DBReferenceManifestManager; -import hirs.persist.HibernateConfiguration; -import hirs.structs.converters.SimpleStructConverter; -import hirs.structs.converters.StructConverter; -import hirs.utils.LogConfigurationUtil; /** * Provides application context configuration for the Attestation Certificate @@ -252,6 +256,26 @@ 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()); + } + + /** + * Creates a {@link ReferenceEventManager} ready to use. + * + * @return {@link ReferenceEventManager} + */ + @Bean + public ReferenceEventManager referenceEventManager() { + return new DBReferenceEventManager(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..4e31119f 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/rest/RestfulAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/rest/RestfulAttestationCertificateAuthority.java @@ -1,7 +1,16 @@ package hirs.attestationca.rest; +import hirs.attestationca.AbstractAttestationCertificateAuthority; +import hirs.attestationca.service.SupplyChainValidationService; +import hirs.data.service.DeviceRegister; +import hirs.persist.CertificateManager; import hirs.persist.DBManager; +import hirs.persist.DeviceManager; +import hirs.persist.ReferenceDigestManager; +import hirs.persist.ReferenceEventManager; +import hirs.persist.ReferenceManifestManager; import hirs.persist.TPM2ProvisionerState; +import hirs.structs.converters.StructConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; @@ -13,13 +22,6 @@ import org.springframework.web.bind.annotation.RestController; import java.security.PrivateKey; import java.security.cert.X509Certificate; -import hirs.attestationca.AbstractAttestationCertificateAuthority; -import hirs.attestationca.service.SupplyChainValidationService; -import hirs.data.service.DeviceRegister; -import hirs.persist.CertificateManager; -import hirs.persist.ReferenceManifestManager; -import hirs.persist.DeviceManager; -import hirs.structs.converters.StructConverter; /** * Restful implementation of the {@link hirs.attestationca.AttestationCertificateAuthority}. @@ -42,6 +44,8 @@ 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 + * @param referenceEventManager the reference event manager */ @SuppressWarnings({ "checkstyle:parameternumber" }) @Autowired @@ -54,11 +58,13 @@ public class RestfulAttestationCertificateAuthority final DeviceRegister deviceRegister, final DeviceManager deviceManager, final DBManager tpm2ProvisionerStateDBManager, + final ReferenceDigestManager referenceDigestManager, + final ReferenceEventManager referenceEventManager, @Value("${aca.certificates.validity}") final int validDays) { super(supplyChainValidationService, privateKey, acaCertificate, structConverter, certificateManager, referenceManifestManager, deviceRegister, validDays, deviceManager, - tpm2ProvisionerStateDBManager); + tpm2ProvisionerStateDBManager, referenceDigestManager, referenceEventManager); } /* diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/AbstractAttestationCertificateAuthorityTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/AbstractAttestationCertificateAuthorityTest.java index 5e5ade23..d51547a0 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/AbstractAttestationCertificateAuthorityTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/AbstractAttestationCertificateAuthorityTest.java @@ -2,6 +2,17 @@ package hirs.attestationca; import com.google.protobuf.ByteString; import hirs.data.persist.certificate.PlatformCredential; +import hirs.structs.converters.StructConverter; +import hirs.structs.elements.aca.SymmetricAttestation; +import hirs.structs.elements.tpm.AsymmetricKeyParams; +import hirs.structs.elements.tpm.AsymmetricPublicKey; +import hirs.structs.elements.tpm.EncryptionScheme; +import hirs.structs.elements.tpm.IdentityProof; +import hirs.structs.elements.tpm.IdentityRequest; +import hirs.structs.elements.tpm.StorePubKey; +import hirs.structs.elements.tpm.SymmetricKey; +import hirs.structs.elements.tpm.SymmetricKeyParams; +import hirs.structs.elements.tpm.SymmetricSubParams; import hirs.utils.HexUtils; import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang3.ArrayUtils; @@ -42,18 +53,6 @@ import java.security.spec.MGF1ParameterSpec; import java.util.Calendar; import java.util.HashSet; -import hirs.structs.converters.StructConverter; -import hirs.structs.elements.aca.SymmetricAttestation; -import hirs.structs.elements.tpm.AsymmetricKeyParams; -import hirs.structs.elements.tpm.AsymmetricPublicKey; -import hirs.structs.elements.tpm.EncryptionScheme; -import hirs.structs.elements.tpm.IdentityProof; -import hirs.structs.elements.tpm.IdentityRequest; -import hirs.structs.elements.tpm.StorePubKey; -import hirs.structs.elements.tpm.SymmetricKey; -import hirs.structs.elements.tpm.SymmetricKeyParams; -import hirs.structs.elements.tpm.SymmetricSubParams; - import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -133,7 +132,7 @@ public class AbstractAttestationCertificateAuthorityTest { public void setup() { aca = new AbstractAttestationCertificateAuthority(null, keyPair.getPrivate(), null, null, null, null, null, 1, - null, 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..f051b1a1 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,11 +5,13 @@ import hirs.persist.AppraiserManager; import hirs.persist.CrudManager; import hirs.persist.DBAppraiserManager; import hirs.persist.DBCertificateManager; -import hirs.persist.DBReferenceManifestManager; import hirs.persist.DBDeviceGroupManager; import hirs.persist.DBDeviceManager; import hirs.persist.DBManager; import hirs.persist.DBPolicyManager; +import hirs.persist.DBReferenceDigestManager; +import hirs.persist.DBReferenceEventManager; +import hirs.persist.DBReferenceManifestManager; import hirs.persist.DeviceGroupManager; import hirs.persist.DeviceManager; import hirs.persist.HibernateConfiguration; @@ -71,6 +73,26 @@ 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 DBReferenceEventManager} ready to use. + * + * @return {@link DBReferenceEventManager} + */ + @Bean + public DBReferenceEventManager referenceEventManager() { + return new DBReferenceEventManager(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 new file mode 100644 index 00000000..ee24e340 --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestRecord.java @@ -0,0 +1,164 @@ +package hirs.data.persist; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bouncycastle.util.Arrays; +import org.hibernate.annotations.Type; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import java.util.UUID; + +/** + * 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 { + + private static final Logger LOGGER = LogManager.getLogger(ReferenceDigestRecord.class); + + @Type(type = "uuid-char") + @Column + private UUID supportRim; + @Column(nullable = false) + private String manufacturer; + @Column(nullable = false) + private String model; + @Column(columnDefinition = "blob", nullable = true) + private byte[] valueBlob; + + /** + * Default Constructor. + */ + protected ReferenceDigestRecord() { + super(); + this.supportRim = UUID.randomUUID(); + this.manufacturer = ""; + this.model = ""; + this.valueBlob = null; + } + + /** + * 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 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 = Arrays.clone(valueBlob); + } + + /** + * Default constructor with parameters specific 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(); + 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; + } + + /** + * 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(); + } + } + + /** + * The string value representative of this class. + * @return manufacturer and model for this record + */ + @Override + public String toString() { + return String.format("ReferenceDigestRecord: %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 new file mode 100644 index 00000000..385a05c1 --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/data/persist/ReferenceDigestValue.java @@ -0,0 +1,170 @@ +package hirs.data.persist; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.hibernate.annotations.Type; + +import javax.persistence.Column; +import javax.persistence.Entity; +import java.util.Objects; +import java.util.UUID; + +/** + * This class represents that actual entry in the Support RIM. + * Digest Value, Event Type, index, RIM Tagid + */ +@Entity +public class ReferenceDigestValue extends AbstractEntity { + + private static final Logger LOGGER = LogManager.getLogger(ReferenceDigestValue.class); + @Type(type = "uuid-char") + @Column + private UUID digestRecordId; + @Column(nullable = false) + private int eventNumber; + @Column(nullable = false) + private String digestValue; + @Column(nullable = false) + private String eventType; + @Column(nullable = false) + private boolean matchFail; + + /** + * Default Constructor. + */ + public ReferenceDigestValue() { + super(); + this.digestRecordId = UUID.randomUUID(); + this.eventNumber = -1; + this.digestValue = ""; + this.eventType = ""; + this.matchFail = false; + } + + /** + * Default Constructor with parameters for all associated data. + * @param digestRecordId the UUID of the associated record + * @param eventNumber the event number + * @param digestValue the key digest value + * @param eventType the event type to store + * @param matchFail the status of the baseline check + */ + public ReferenceDigestValue(final UUID digestRecordId, final int eventNumber, + final String digestValue, final String eventType, + final boolean matchFail) { + this.digestRecordId = digestRecordId; + this.eventNumber = eventNumber; + this.digestValue = digestValue; + this.eventType = eventType; + this.matchFail = matchFail; + } + + /** + * Getter for the digest record UUID. + * @return the string of the UUID + */ + public UUID getDigestRecordId() { + return digestRecordId; + } + + /** + * Setter for the digest record UUID. + * @param digestRecordId the value to store + */ + public void setDigestRecordId(final UUID digestRecordId) { + this.digestRecordId = digestRecordId; + } + + /** + * Getter for the event number. + * @return the stored value + */ + public int getEventNumber() { + return eventNumber; + } + + /** + * Setter for the event number. + * @param eventNumber the value to store + */ + public void setEventNumber(final int eventNumber) { + this.eventNumber = eventNumber; + } + + /** + * Getter for the digest value. + * @return the stored value + */ + public String getDigestValue() { + return digestValue; + } + + /** + * Setter for the digest value. + * @param digestValue the value to store + */ + public void setDigestValue(final String digestValue) { + this.digestValue = digestValue; + } + + /** + * Getter for the event type value. + * @return the stored value + */ + public String getEventType() { + return eventType; + } + + /** + * Setter for the event type. + * @param eventType the value to store + */ + public void setEventType(final String eventType) { + this.eventType = eventType; + } + + /** + * Getter for the status of the match fail. + * @return the value of the status + */ + public boolean isMatchFail() { + return matchFail; + } + + /** + * Setter for the status of a match fail. + * @param matchFail the value to store + */ + public void setMatchFail(final boolean matchFail) { + 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(digestRecordId, that.digestRecordId) + && Objects.equals(eventType, that.eventType); + } + + @Override + public int hashCode() { + int result = Objects.hash(eventNumber, digestValue, digestRecordId, eventType, matchFail); + return result; + } + + /** + * Returns a string of the classes fields. + * @return a string + */ + public String toString() { + return String.format("ReferenceDigestValue: {%d, %b}", eventNumber, matchFail); + } +} diff --git a/HIRS_Utils/src/main/java/hirs/persist/DBReferenceDigestManager.java b/HIRS_Utils/src/main/java/hirs/persist/DBReferenceDigestManager.java new file mode 100644 index 00000000..7ab13f5c --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/persist/DBReferenceDigestManager.java @@ -0,0 +1,227 @@ +package hirs.persist; + +import hirs.data.persist.ReferenceDigestRecord; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.criterion.Restrictions; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * This class is used to persist and retrieve {@link hirs.data.persist.ReferenceDigestRecord}s into + * and from the database. + */ +public class DBReferenceDigestManager extends DBManager + 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); + } + + @Override + public ReferenceDigestRecord saveRecord(final ReferenceDigestRecord referenceDigestRecord) { + LOGGER.debug("saving digest record: {}", 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"); + return null; + } + + if (referenceDigestRecord.getManufacturer() == null + || referenceDigestRecord.getModel() == null) { + LOGGER.error("No reference to get record from db {}", referenceDigestRecord); + return null; + } + + ReferenceDigestRecord dbRecord = null; + Transaction tx = null; + Session session = getFactory().getCurrentSession(); + try { + LOGGER.debug("retrieving referenceDigestRecord from db"); + tx = session.beginTransaction(); + dbRecord = (ReferenceDigestRecord) session.createCriteria(ReferenceDigestRecord.class) + .add(Restrictions.eq("manufacturer", + referenceDigestRecord.getManufacturer())).add(Restrictions.eq("model", + referenceDigestRecord.getModel())).uniqueResult(); + tx.commit(); + } catch (Exception ex) { + final String msg = "unable to retrieve object"; + LOGGER.error(msg, ex); + if (tx != null) { + LOGGER.debug("rolling back transaction"); + tx.rollback(); + } + throw new DBManagerException(msg, ex); + } + return dbRecord; + } + + @Override + public ReferenceDigestRecord getRecordById(final ReferenceDigestRecord referenceDigestRecord) { + LOGGER.debug("Getting record for {}", referenceDigestRecord); + if (referenceDigestRecord == null) { + LOGGER.error("null referenceDigestRecord argument"); + return null; + } + + if (referenceDigestRecord.getId() == null) { + LOGGER.error("No id to get record from db {}", referenceDigestRecord); + return null; + } + + ReferenceDigestRecord dbRecord; + Transaction tx = null; + Session session = getFactory().getCurrentSession(); + try { + LOGGER.debug("retrieving referenceDigestRecord from db"); + tx = session.beginTransaction(); + dbRecord = (ReferenceDigestRecord) session.createCriteria(ReferenceDigestRecord.class) + .add(Restrictions.eq("id", + referenceDigestRecord.getId())).uniqueResult(); + tx.commit(); + } catch (Exception ex) { + final String msg = "unable to retrieve object"; + LOGGER.error(msg, ex); + if (tx != null) { + LOGGER.debug("rolling back transaction"); + tx.rollback(); + } + throw new DBManagerException(msg, ex); + } + return dbRecord; + } + + @Override + public ReferenceDigestRecord getRecordBySupportId(final UUID supportId) { + LOGGER.debug("Getting record for {}", supportId); + if (supportId == null) { + LOGGER.error("null supportId argument"); + return null; + } + + ReferenceDigestRecord dbRecord; + Transaction tx = null; + Session session = getFactory().getCurrentSession(); + try { + LOGGER.debug("retrieving referenceDigestRecord from db"); + tx = session.beginTransaction(); + dbRecord = (ReferenceDigestRecord) session.createCriteria(ReferenceDigestRecord.class) + .add(Restrictions.eq("supportRim", supportId)).uniqueResult(); + tx.commit(); + } catch (Exception ex) { + final String msg = "unable to retrieve object"; + LOGGER.error(msg, ex); + if (tx != null) { + LOGGER.debug("rolling back transaction"); + tx.rollback(); + } + throw new DBManagerException(msg, ex); + } + return dbRecord; + } + + @Override + public List 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"); + } + if (referenceDigestRecord.getManufacturer() == null) { + LOGGER.error("null referenceDigestRecord manufacturer argument"); + throw new NullPointerException("null referenceDigestRecord manufacturer"); + } + + List dbRecords = new ArrayList<>(); + String manufacturer = referenceDigestRecord.getManufacturer(); + try { + List dbTempList = super.getList(ReferenceDigestRecord.class); + for (ReferenceDigestRecord rdr : dbTempList) { + if (rdr.getManufacturer().equals(manufacturer)) { + dbRecords.add(rdr); + } + } + } catch (DBManagerException dbMEx) { + throw new RuntimeException(dbMEx); + } + return dbRecords; + } + + @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"); + } + if (referenceDigestRecord.getModel() == null) { + LOGGER.error("null referenceDigestRecord model argument"); + throw new NullPointerException("null referenceDigestRecord model"); + } + + List dbRecords = new ArrayList<>(); + String model = referenceDigestRecord.getModel(); + try { + List dbTempList = super.getList(ReferenceDigestRecord.class); + for (ReferenceDigestRecord rdr : dbTempList) { + if (rdr.getModel().equals(model)) { + dbRecords.add(rdr); + } + } + } catch (DBManagerException dbMEx) { + throw new RuntimeException(dbMEx); + } + return dbRecords; + } + + @Override + public void updateRecord(final ReferenceDigestRecord referenceDigestRecord) { + try { + super.update(referenceDigestRecord); + } catch (DBManagerException dbMEx) { + throw new RuntimeException(dbMEx); + } + } + + /** + * Remove a ReferenceDigestRecord from the database. + * + * @param referenceDigestRecord the referenceDigestRecord to delete + * @return true if deletion was successful, false otherwise + */ + @Override + public boolean deleteRecord(final ReferenceDigestRecord referenceDigestRecord) { + boolean result = false; + LOGGER.info(String.format("Deleting reference to %s/%s", + referenceDigestRecord.getManufacturer(), referenceDigestRecord.getModel())); + try { + result = super.delete(referenceDigestRecord); + } catch (DBManagerException dbMEx) { + throw new RuntimeException(dbMEx); + } + return result; + } +} diff --git a/HIRS_Utils/src/main/java/hirs/persist/DBReferenceEventManager.java b/HIRS_Utils/src/main/java/hirs/persist/DBReferenceEventManager.java new file mode 100644 index 00000000..52b5d740 --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/persist/DBReferenceEventManager.java @@ -0,0 +1,191 @@ +package hirs.persist; + +import hirs.data.persist.ReferenceDigestRecord; +import hirs.data.persist.ReferenceDigestValue; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.criterion.Restrictions; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * This class is used to persist and retrieve {@link hirs.data.persist.ReferenceDigestValue}s into + * and from the database. + */ +public class DBReferenceEventManager extends DBManager + implements ReferenceEventManager { + + private static final Logger LOGGER = LogManager.getLogger(DBReferenceDigestManager.class); + + /** + * Default Constructor. + * + * @param sessionFactory session factory used to access database connections + */ + public DBReferenceEventManager(final SessionFactory sessionFactory) { + super(ReferenceDigestValue.class, sessionFactory); + } + @Override + public ReferenceDigestValue saveValue(final ReferenceDigestValue referenceDigestValue) { + LOGGER.debug("saving event digest value: {}", referenceDigestValue); + try { + return save(referenceDigestValue); + } catch (DBManagerException dbMEx) { + throw new RuntimeException(dbMEx); + } + } + + @Override + public ReferenceDigestValue getValue(final ReferenceDigestValue referenceDigestValue) { + LOGGER.debug("Getting record for {}", referenceDigestValue); + if (referenceDigestValue == null) { + LOGGER.error("null referenceDigestValue argument"); + return null; + } + + if (referenceDigestValue.getDigestRecordId() == null + || referenceDigestValue.getDigestValue() == null + || referenceDigestValue.getEventNumber() == -1) { + LOGGER.error("No reference to get record from db {}", referenceDigestValue); + return null; + } + + ReferenceDigestValue dbRecord; + Transaction tx = null; + Session session = getFactory().getCurrentSession(); + try { + LOGGER.debug("retrieving referenceDigestValue from db"); + tx = session.beginTransaction(); + dbRecord = (ReferenceDigestValue) session.createCriteria(ReferenceDigestValue.class) + .add(Restrictions.eq("digestRecordId", + referenceDigestValue.getDigestRecordId())) + .add(Restrictions.eq("digestValue", + referenceDigestValue.getDigestValue())) + .add(Restrictions.eq("eventNumber", + referenceDigestValue.getEventNumber())) + .uniqueResult(); + tx.commit(); + } catch (Exception ex) { + final String msg = "unable to retrieve object"; + LOGGER.error(msg, ex); + if (tx != null) { + LOGGER.debug("rolling back transaction"); + tx.rollback(); + } + throw new DBManagerException(msg, ex); + } + return dbRecord; + } + + @Override + public ReferenceDigestValue getValueById(final ReferenceDigestValue referenceDigestValue) { + LOGGER.debug("Getting record for {}", referenceDigestValue); + if (referenceDigestValue == null) { + LOGGER.error("null referenceDigestValue argument"); + return null; + } + + if (referenceDigestValue.getId() == null) { + LOGGER.error("No reference to get record from db {}", referenceDigestValue); + return null; + } + + ReferenceDigestValue dbRecord; + Transaction tx = null; + Session session = getFactory().getCurrentSession(); + try { + LOGGER.debug("retrieving referenceDigestValue from db"); + tx = session.beginTransaction(); + dbRecord = (ReferenceDigestValue) session.createCriteria(ReferenceDigestValue.class) + .add(Restrictions.eq("id", + referenceDigestValue.getId())).uniqueResult(); + tx.commit(); + } catch (Exception ex) { + final String msg = "unable to retrieve object"; + LOGGER.error(msg, ex); + if (tx != null) { + LOGGER.debug("rolling back transaction"); + tx.rollback(); + } + throw new DBManagerException(msg, ex); + } + return dbRecord; + } + + @Override + public List getValuesByRecordId( + final ReferenceDigestRecord referenceDigestRecord) { + LOGGER.debug("Getting digest values for {}", referenceDigestRecord); + if (referenceDigestRecord == null) { + LOGGER.error("null referenceDigestRecord argument"); + throw new NullPointerException("null referenceDigestRecord"); + } + if (referenceDigestRecord.getId() == null) { + LOGGER.error("null referenceDigestRecord ID argument"); + throw new NullPointerException("null referenceDigestRecord ID"); + } + + List dbDigestValues = new ArrayList<>(); + UUID uuid = referenceDigestRecord.getId(); + try { + List dbTempList = super.getList(ReferenceDigestValue.class); + for (ReferenceDigestValue rdv : dbTempList) { + if (rdv.getDigestRecordId().equals(uuid)) { + dbDigestValues.add(rdv); + } + } + } catch (DBManagerException dbMEx) { + throw new RuntimeException(dbMEx); + } + return dbDigestValues; + } + + @Override + public List getValueByEventType(final String eventType) { + LOGGER.debug("Getting digest values for event type: {}", eventType); + if (eventType == null) { + LOGGER.error("null event type argument"); + throw new NullPointerException("null event type"); + } + + List dbDigestValues = new ArrayList<>(); + try { + List dbTempList = super.getList(ReferenceDigestValue.class); + for (ReferenceDigestValue rdv : dbTempList) { + if (rdv.getEventType().equals(eventType)) { + dbDigestValues.add(rdv); + } + } + } catch (DBManagerException dbMEx) { + throw new RuntimeException(dbMEx); + } + return dbDigestValues; + } + + @Override + public void updateRecord(final ReferenceDigestValue referenceDigestValue) { + try { + super.update(referenceDigestValue); + } catch (DBManagerException dbMEx) { + throw new RuntimeException(dbMEx); + } + } + + @Override + public boolean deleteRecord(final ReferenceDigestValue referenceDigestValue) { + boolean result; + LOGGER.info(String.format("Deleting reference to %s", + referenceDigestValue.getId())); + try { + result = super.delete(referenceDigestValue); + } catch (DBManagerException dbMEx) { + throw new RuntimeException(dbMEx); + } + return result; + } +} diff --git a/HIRS_Utils/src/main/java/hirs/persist/PersistenceConfiguration.java b/HIRS_Utils/src/main/java/hirs/persist/PersistenceConfiguration.java index 4c1da996..408687d1 100644 --- a/HIRS_Utils/src/main/java/hirs/persist/PersistenceConfiguration.java +++ b/HIRS_Utils/src/main/java/hirs/persist/PersistenceConfiguration.java @@ -154,6 +154,32 @@ 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 ReferenceEventManager} ready to use. + * + * @return {@link ReferenceEventManager} + */ + @Bean + public ReferenceEventManager referenceEventManager() { + DBReferenceEventManager manager + = new DBReferenceEventManager(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 new file mode 100644 index 00000000..d858782c --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/persist/ReferenceDigestManager.java @@ -0,0 +1,77 @@ + +package hirs.persist; + +import hirs.data.persist.ReferenceDigestRecord; + +import java.util.List; +import java.util.UUID; + +/** + * This class facilitates the persistence of {@link hirs.data.persist.ReferenceDigestRecord}s + * including storage, retrieval, and deletion. + */ +public interface ReferenceDigestManager { + + /** + * Persists a new Reference Digest. + * + * @param referenceDigestRecord the ReferenceDigestRecord + * @return the persisted 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 + */ + ReferenceDigestRecord getRecordById(ReferenceDigestRecord referenceDigestRecord); + + /** + * Persists a new Reference Digest. + * + * @param supportId the support RIM UUID + * @return the persisted ReferenceDigestRecord + */ + ReferenceDigestRecord getRecordBySupportId(UUID supportId); + + /** + * Persists a new Reference Digest. + * + * @param referenceDigestRecord the ReferenceDigestRecord + * @return the persisted ReferenceDigestRecord + */ + List 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 + */ + void updateRecord(ReferenceDigestRecord referenceDigestRecord); + + /** + * Delete the given record. + * + * @param referenceDigestRecord the digest record delete + * @return true if the deletion succeeded, false otherwise. + */ + boolean deleteRecord(ReferenceDigestRecord referenceDigestRecord); +} diff --git a/HIRS_Utils/src/main/java/hirs/persist/ReferenceEventManager.java b/HIRS_Utils/src/main/java/hirs/persist/ReferenceEventManager.java new file mode 100644 index 00000000..89c02ebc --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/persist/ReferenceEventManager.java @@ -0,0 +1,66 @@ +package hirs.persist; + +import hirs.data.persist.ReferenceDigestRecord; +import hirs.data.persist.ReferenceDigestValue; + +import java.util.List; + +/** + * This class facilitates the persistence of {@link hirs.data.persist.ReferenceDigestValue}s + * including storage, retrieval, and deletion. + */ +public interface ReferenceEventManager { + /** + * Persists a new Reference Digest value. + * + * @param referenceDigestValue the ReferenceDigestValue + * @return the persisted ReferenceDigestValue + */ + ReferenceDigestValue saveValue(ReferenceDigestValue referenceDigestValue); + + /** + * Persists a new Reference Digest value. + * + * @param referenceDigestValue the ReferenceDigestValue + * @return the persisted ReferenceDigestValue + */ + ReferenceDigestValue getValue(ReferenceDigestValue referenceDigestValue); + + /** + * Persists a new Reference Digest value. + * + * @param referenceDigestValue the ReferenceDigestValue + * @return the persisted ReferenceDigestValue + */ + ReferenceDigestValue getValueById(ReferenceDigestValue referenceDigestValue); + + /** + * Persists a new Reference Digest value. + * + * @param referenceDigestRecord the ReferenceDigestRecord + * @return the persisted list of ReferenceDigestValue + */ + List getValuesByRecordId(ReferenceDigestRecord referenceDigestRecord); + + /** + * Persists a new Reference Digest value. + * + * @param eventType the event type to look for + * @return the persisted list of ReferenceDigestValue + */ + List getValueByEventType(String eventType); + + /** + * Updates an existing ReferenceDigestRecord. + * @param referenceDigestValue the Reference Event update + */ + void updateRecord(ReferenceDigestValue referenceDigestValue); + + /** + * Delete the given value. + * + * @param referenceDigestValue the digest record delete + * @return true if the deletion succeeded, false otherwise. + */ + boolean deleteRecord(ReferenceDigestValue referenceDigestValue); +} diff --git a/HIRS_Utils/src/main/java/hirs/persist/ReferenceManifestSelector.java b/HIRS_Utils/src/main/java/hirs/persist/ReferenceManifestSelector.java index 4b6ae6dd..3b363e35 100644 --- a/HIRS_Utils/src/main/java/hirs/persist/ReferenceManifestSelector.java +++ b/HIRS_Utils/src/main/java/hirs/persist/ReferenceManifestSelector.java @@ -22,7 +22,7 @@ import java.util.UUID; * with a {@link ReferenceManifestManager}. To make use of this object, * use (some ReferenceManifest).select(ReferenceManifestManager). * - * @param the type of Reference Integrity Manifest that will be retrived. + * @param the type of Reference Integrity Manifest that will be retrieved. */ public abstract class ReferenceManifestSelector { /**