Merge pull request #352 from nsacyber/event-digest-update

[#343] Event digest update (UI)
This commit is contained in:
Cyrus 2021-04-23 08:45:13 -04:00 committed by GitHub
commit c7fb94d7b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 630 additions and 394 deletions

View File

@ -94,10 +94,10 @@ import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -707,13 +707,16 @@ public abstract class AbstractAttestationCertificateAuthority
return (RSAPublicKey) assemblePublicKey(modulus);
}
private static final int NUM_OF_VARIABLES = 5;
/**
* Converts a protobuf DeviceInfo object to a HIRS Utils DeviceInfoReport object.
* @param claim the protobuf serialized identity claim containing the device info
* @return a HIRS Utils DeviceInfoReport representation of device info
*/
@SuppressWarnings("methodlength")
private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) {
private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim claim)
throws NoSuchAlgorithmException {
ProvisionerTpm2.DeviceInfo dv = claim.getDv();
// Get network info
@ -769,53 +772,123 @@ public abstract class AbstractAttestationCertificateAuthority
}
// check for RIM Base and Support files, if they don't exists in the database, load them
String clientName = String.format("%s_%s",
String defaultClientName = String.format("%s_%s",
dv.getHw().getManufacturer(),
dv.getHw().getProductName());
ReferenceManifest dbBaseRim = null;
BaseReferenceManifest dbBaseRim = null;
ReferenceManifest support;
EventLogMeasurements measurements;
String tagId = "";
String fileName = "";
Pattern pattern = Pattern.compile("([^\\s]+(\\.(?i)(rimpcr|rimel|bin|log))$)");
Matcher matcher;
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
if (dv.getLogfileCount() > 0) {
for (ByteString logFile : dv.getLogfileList()) {
try {
support = SupportReferenceManifest.select(referenceManifestManager)
.includeArchived()
.byHashCode(Hex.encodeHexString(messageDigest.digest(
logFile.toByteArray())))
.getRIM();
if (support == null) {
support = new SupportReferenceManifest(
String.format("%s.rimel",
defaultClientName),
logFile.toByteArray());
// this is a validity check
new TCGEventLog(support.getRimBytes());
// no issues, continue
support.setPlatformManufacturer(dv.getHw().getManufacturer());
support.setPlatformModel(dv.getHw().getProductName());
support.setFileName(String.format("%s_[%s].rimel", defaultClientName,
support.getRimHash().substring(
support.getRimHash().length() - NUM_OF_VARIABLES)));
this.referenceManifestManager.save(support);
} else {
LOG.info("Client provided Support RIM already loaded in database.");
if (support.isArchived()) {
support.restore();
support.resetCreateTime();
this.referenceManifestManager.update(support);
}
}
} catch (IOException ioEx) {
LOG.error(ioEx);
} catch (Exception ex) {
LOG.error(String.format("Failed to load support rim: %s", messageDigest.digest(
logFile.toByteArray()).toString()));
}
}
} else {
LOG.warn("Device did not send support RIM file...");
}
if (dv.getSwidfileCount() > 0) {
for (ByteString swidFile : dv.getSwidfileList()) {
fileName = "";
try {
dbBaseRim = BaseReferenceManifest.select(referenceManifestManager)
.includeArchived()
.byHashCode(Arrays.hashCode(swidFile.toByteArray()))
.byHashCode(Hex.encodeHexString(messageDigest.digest(
swidFile.toByteArray())))
.getRIM();
if (dbBaseRim == null) {
dbBaseRim = new BaseReferenceManifest(
String.format("%s.swidtag",
clientName),
defaultClientName),
swidFile.toByteArray());
BaseReferenceManifest base = (BaseReferenceManifest) dbBaseRim;
for (SwidResource swid : base.parseResource()) {
// get file name to use
for (SwidResource swid : dbBaseRim.parseResource()) {
matcher = pattern.matcher(swid.getName());
if (matcher.matches()) {
//found the file name
int dotIndex = swid.getName().lastIndexOf(".");
clientName = swid.getName().substring(0, dotIndex);
fileName = swid.getName().substring(0, dotIndex);
dbBaseRim = new BaseReferenceManifest(
String.format("%s.swidtag",
clientName),
fileName),
swidFile.toByteArray());
}
// now update support rim
SupportReferenceManifest dbSupport = SupportReferenceManifest
.select(referenceManifestManager)
.byRimHash(swid.getHashValue()).getRIM();
if (dbSupport != null && !dbSupport.isUpdated()) {
dbSupport.setFileName(swid.getName());
dbSupport.setSwidTagVersion(dbBaseRim.getSwidTagVersion());
// I might create a get for the bytes of the swidtag file
// so that I can set that instead of the rim ID
dbSupport.setTagId(dbBaseRim.getTagId());
dbSupport.setSwidTagVersion(dbBaseRim.getSwidTagVersion());
dbSupport.setSwidVersion(dbBaseRim.getSwidVersion());
dbSupport.setSwidPatch(dbBaseRim.isSwidPatch());
dbSupport.setSwidSupplemental(dbBaseRim.isSwidSupplemental());
dbBaseRim.setAssociatedRim(dbSupport.getId());
dbSupport.setUpdated(true);
this.referenceManifestManager.update(dbSupport);
break;
}
}
this.referenceManifestManager.save(dbBaseRim);
} else {
LOG.info("Client provided Base RIM already loaded in database.");
dbBaseRim.restore();
dbBaseRim.resetCreateTime();
this.referenceManifestManager.update(dbBaseRim);
/**
* Leaving this as is for now, however can there be a condition
* in which the provisioner sends swidtags without support rims?
*/
if (dbBaseRim.isArchived()) {
dbBaseRim.restore();
dbBaseRim.resetCreateTime();
this.referenceManifestManager.update(dbBaseRim);
}
}
tagId = dbBaseRim.getTagId();
} catch (IOException ioEx) {
LOG.error(ioEx);
}
@ -824,92 +897,27 @@ public abstract class AbstractAttestationCertificateAuthority
LOG.warn("Device did not send swid tag file...");
}
if (dv.getLogfileCount() > 0) {
for (ByteString logFile : dv.getLogfileList()) {
try {
support = SupportReferenceManifest.select(referenceManifestManager)
.includeArchived()
.byHashCode(Arrays.hashCode(logFile.toByteArray()))
.getRIM();
if (support == null) {
support = new SupportReferenceManifest(
String.format("%s.rimel",
clientName),
logFile.toByteArray());
support.setPlatformManufacturer(dv.getHw().getManufacturer());
support.setPlatformModel(dv.getHw().getProductName());
support.setTagId(tagId);
this.referenceManifestManager.save(support);
} else {
LOG.info("Client provided Support RIM already loaded in database.");
if (dbBaseRim != null) {
support.setPlatformManufacturer(dbBaseRim.getPlatformManufacturer());
support.setPlatformModel(dbBaseRim.getPlatformModel());
support.setSwidTagVersion(dbBaseRim.getSwidTagVersion());
support.setAssociatedRim(dbBaseRim.getId());
support.setTagId(dbBaseRim.getTagId());
}
support.restore();
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);
}
}
} else {
LOG.warn("Device did not send support RIM file...");
}
generateDigestRecords(hw.getManufacturer(), hw.getProductName());
if (dv.hasLivelog()) {
LOG.info("Device sent bios measurement log...");
fileName = String.format("%s.measurement",
clientName);
defaultClientName);
try {
// find previous version. If it exists, delete it
support = EventLogMeasurements.select(referenceManifestManager)
measurements = EventLogMeasurements.select(referenceManifestManager)
.byManufacturer(dv.getHw().getManufacturer())
.includeArchived().getRIM();
if (support != null) {
if (measurements != null) {
LOG.info("Previous bios measurement log found and being replaced...");
this.referenceManifestManager.delete(support);
this.referenceManifestManager.delete(measurements);
}
support = new EventLogMeasurements(fileName,
measurements = new EventLogMeasurements(fileName,
dv.getLivelog().toByteArray());
support.setPlatformManufacturer(dv.getHw().getManufacturer());
support.setPlatformModel(dv.getHw().getProductName());
support.setTagId(tagId);
this.referenceManifestManager.save(support);
measurements.setPlatformManufacturer(dv.getHw().getManufacturer());
measurements.setPlatformModel(dv.getHw().getProductName());
measurements.setTagId(tagId);
this.referenceManifestManager.save(measurements);
} catch (IOException ioEx) {
LOG.error(ioEx);
}
@ -936,8 +944,96 @@ public abstract class AbstractAttestationCertificateAuthority
return dvReport;
}
private boolean generateDigestRecords(final String manufacturer, final String model) {
List<ReferenceDigestValue> rdValues;
Set<SupportReferenceManifest> dbSupportRims = SupportReferenceManifest
.select(referenceManifestManager).byManufacturer(manufacturer).getRIMs();
for (SupportReferenceManifest dbSupport : dbSupportRims) {
if (dbSupport.getPlatformModel().equals(model)) {
ReferenceDigestRecord dbObj = new ReferenceDigestRecord(dbSupport,
manufacturer, model);
// this is where we update or create the log
ReferenceDigestRecord rdr = this.referenceDigestManager.getRecord(dbObj);
if (dbSupport.isBaseSupport()) {
// Handle baseline digest records
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(dbSupport.getRimBytes());
ReferenceDigestValue rdv;
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
rdv = new ReferenceDigestValue(rdr.getId(), tpe.getPcrIndex(),
tpe.getEventDigestStr(), tpe.getEventTypeStr(),
false, false);
this.referenceEventManager.saveValue(rdv);
}
} catch (CertificateException cEx) {
LOG.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOG.error(noSaEx);
} catch (IOException ioEx) {
LOG.error(ioEx);
}
}
} else if (dbSupport.isSwidPatch()) {
if (rdr != null) {
// have to have something to patch
try {
rdValues = this.referenceEventManager.getValuesByRecordId(rdr);
TCGEventLog logProcessor = new TCGEventLog(dbSupport.getRimBytes());
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
LOG.error(tpe);
}
for (ReferenceDigestValue rdv : rdValues) {
LOG.error(rdv);
}
} catch (CertificateException cEx) {
LOG.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOG.error(noSaEx);
} catch (IOException ioEx) {
LOG.error(ioEx);
}
}
} else if (dbSupport.isSwidSupplemental() && !dbSupport.isProcessed()) {
try {
TCGEventLog logProcessor = new TCGEventLog(dbSupport.getRimBytes());
ReferenceDigestValue rdv;
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
rdv = new ReferenceDigestValue(rdr.getId(), tpe.getPcrIndex(),
tpe.getEventDigestStr(), tpe.getEventTypeStr(),
false, false);
this.referenceEventManager.saveValue(rdv);
}
dbSupport.setProcessed(true);
this.referenceManifestManager.update(dbSupport);
} catch (CertificateException cEx) {
LOG.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOG.error(noSaEx);
} catch (IOException ioEx) {
LOG.error(ioEx);
}
}
}
}
return true;
}
private Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) {
DeviceInfoReport deviceInfoReport = parseDeviceInfo(claim);
DeviceInfoReport deviceInfoReport = null;
try {
deviceInfoReport = parseDeviceInfo(claim);
} catch (NoSuchAlgorithmException noSaEx) {
LOG.error(noSaEx);
}
if (deviceInfoReport == null) {
LOG.error("Failed to deserialize Device Info Report");

View File

@ -9,6 +9,8 @@ import hirs.data.persist.Device;
import hirs.data.persist.DeviceInfoReport;
import hirs.data.persist.EventLogMeasurements;
import hirs.data.persist.PCRPolicy;
import hirs.data.persist.ReferenceDigestRecord;
import hirs.data.persist.ReferenceDigestValue;
import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.SupplyChainPolicy;
import hirs.data.persist.SupplyChainValidation;
@ -26,6 +28,8 @@ import hirs.persist.CrudManager;
import hirs.persist.DBManagerException;
import hirs.persist.PersistenceConfiguration;
import hirs.persist.PolicyManager;
import hirs.persist.ReferenceDigestManager;
import hirs.persist.ReferenceEventManager;
import hirs.persist.ReferenceManifestManager;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.tpm.eventlog.TpmPcrEvent;
@ -76,6 +80,8 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
private PolicyManager policyManager;
private AppraiserManager appraiserManager;
private ReferenceManifestManager referenceManifestManager;
private ReferenceDigestManager referenceDigestManager;
private ReferenceEventManager referenceEventManager;
private CertificateManager certificateManager;
private CredentialValidator supplyChainCredentialValidator;
private CrudManager<SupplyChainValidationSummary> supplyChainValidatorSummaryManager;
@ -92,20 +98,27 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
* @param referenceManifestManager the RIM manager
* @param supplyChainValidatorSummaryManager the summary manager
* @param supplyChainCredentialValidator the credential validator
* @param referenceDigestManager the digest manager
* @param referenceEventManager the even manager
*/
@Autowired
@SuppressWarnings("ParameterNumberCheck")
public SupplyChainValidationServiceImpl(
final PolicyManager policyManager, final AppraiserManager appraiserManager,
final CertificateManager certificateManager,
final ReferenceManifestManager referenceManifestManager,
final CrudManager<SupplyChainValidationSummary> supplyChainValidatorSummaryManager,
final CredentialValidator supplyChainCredentialValidator) {
final CredentialValidator supplyChainCredentialValidator,
final ReferenceDigestManager referenceDigestManager,
final ReferenceEventManager referenceEventManager) {
this.policyManager = policyManager;
this.appraiserManager = appraiserManager;
this.certificateManager = certificateManager;
this.referenceManifestManager = referenceManifestManager;
this.supplyChainValidatorSummaryManager = supplyChainValidatorSummaryManager;
this.supplyChainCredentialValidator = supplyChainCredentialValidator;
this.referenceDigestManager = referenceDigestManager;
this.referenceEventManager = referenceEventManager;
}
/**
@ -354,10 +367,13 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
AppraisalStatus fwStatus = null;
String manufacturer = device.getDeviceInfo()
.getHardwareInfo().getManufacturer();
String model = device.getDeviceInfo()
.getHardwareInfo().getProductName();
ReferenceManifest validationObject = null;
ReferenceManifest baseReferenceManifest = null;
ReferenceManifest supportReferenceManifest = null;
ReferenceManifest measurement = null;
ReferenceDigestRecord digestRecord = null;
baseReferenceManifest = BaseReferenceManifest.select(referenceManifestManager)
.byManufacturer(manufacturer).getRIM();
@ -465,18 +481,22 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
// part 2 of firmware validation check: bios measurements
// vs baseline tcg event log
// find the measurement
TCGEventLog tcgEventLog;
TCGEventLog tcgMeasurementLog;
digestRecord = this.referenceDigestManager.getRecord(manufacturer, model);
LinkedList<TpmPcrEvent> tpmPcrEvents = new LinkedList<>();
List<ReferenceDigestValue> eventValue;
HashMap<String, ReferenceDigestValue> eventValueMap = new HashMap<>();
try {
if (measurement.getPlatformManufacturer().equals(manufacturer)) {
tcgMeasurementLog = new TCGEventLog(measurement.getRimBytes());
tcgEventLog = new TCGEventLog(
supportReferenceManifest.getRimBytes());
for (TpmPcrEvent tpe : tcgEventLog.getEventList()) {
if (!tpe.eventCompare(
tcgMeasurementLog.getEventByNumber(
tpe.getEventNumber()))) {
eventValue = this.referenceEventManager
.getValuesByRecordId(digestRecord);
for (ReferenceDigestValue rdv : eventValue) {
eventValueMap.put(rdv.getDigestValue(), rdv);
}
for (TpmPcrEvent tpe : tcgMeasurementLog.getEventList()) {
if (!eventValueMap.containsKey(tpe.getEventDigestStr())) {
tpmPcrEvents.add(tpe);
}
}
@ -536,6 +556,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
AppraisalStatus fwStatus = new AppraisalStatus(FAIL,
SupplyChainCredentialValidator.FIRMWARE_VALID);
SupportReferenceManifest sRim = null;
EventLogMeasurements eventLog = null;
// check if the policy is enabled
if (policy.isFirmwareValidationEnabled()) {
@ -547,17 +568,25 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
sRim = SupportReferenceManifest.select(
this.referenceManifestManager)
.byManufacturer(manufacturer).getRIM();
eventLog = EventLogMeasurements
.select(this.referenceManifestManager)
.byManufacturer(manufacturer).getRIM();
if (sRim == null) {
fwStatus = new AppraisalStatus(FAIL,
String.format("Firmware Quote validation failed: "
+ "No associated RIM file could be found for %s",
+ "No associated Support RIM file "
+ "could be found for %s",
manufacturer));
} else if (eventLog == null) {
fwStatus = new AppraisalStatus(FAIL,
String.format("Firmware Quote validation failed: "
+ "No associated Client Log file "
+ "could be found for %s",
manufacturer));
} else {
baseline = sRim.getExpectedPCRList();
String pcrContent = new String(device.getDeviceInfo()
.getTPMInfo().getPcrValues());
String[] storedPcrs = buildStoredPcrs(pcrContent, baseline[0].length());
String[] storedPcrs = eventLog.getExpectedPCRList();
PCRPolicy pcrPolicy = policy.getPcrPolicy();
pcrPolicy.setBaselinePcrs(baseline);
// grab the quote

View File

@ -23,6 +23,8 @@ import hirs.persist.DBDeviceManager;
import hirs.persist.DeviceGroupManager;
import hirs.persist.DeviceManager;
import hirs.persist.PolicyManager;
import hirs.persist.ReferenceDigestManager;
import hirs.persist.ReferenceEventManager;
import hirs.validation.CredentialValidator;
import hirs.validation.SupplyChainCredentialValidator;
import org.mockito.ArgumentCaptor;
@ -87,6 +89,12 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest
@Mock
private CrudManager<SupplyChainValidationSummary> supplyChainValidationSummaryDBManager;
@Mock
private ReferenceDigestManager referenceDigestManager;
@Mock
private ReferenceEventManager referenceEventManager;
@InjectMocks
private SupplyChainValidationServiceImpl service;
@ -400,7 +408,9 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest
realCertMan,
null,
supplyChainValidationSummaryDBManager,
supplyChainCredentialValidator
supplyChainCredentialValidator,
referenceDigestManager,
referenceEventManager
);
CertificateAuthorityCredential globalSignCaCert = new CertificateAuthorityCredential(
@ -460,7 +470,9 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest
realCertMan,
null,
supplyChainValidationSummaryDBManager,
supplyChainCredentialValidator
supplyChainCredentialValidator,
referenceDigestManager,
referenceEventManager
);
CertificateAuthorityCredential rootCa = new CertificateAuthorityCredential(
@ -506,7 +518,9 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest
realCertMan,
null,
supplyChainValidationSummaryDBManager,
supplyChainCredentialValidator
supplyChainCredentialValidator,
referenceDigestManager,
referenceEventManager
);
EndorsementCredential endorsementCredential = new EndorsementCredential(
@ -542,7 +556,9 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest
realCertMan,
null,
supplyChainValidationSummaryDBManager,
supplyChainCredentialValidator
supplyChainCredentialValidator,
referenceDigestManager,
referenceEventManager
);
CertificateAuthorityCredential globalSignCaCert = new CertificateAuthorityCredential(
@ -602,7 +618,9 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest
realCertMan,
null,
supplyChainValidationSummaryDBManager,
supplyChainCredentialValidator
supplyChainCredentialValidator,
referenceDigestManager,
referenceEventManager
);
CertificateAuthorityCredential intelCa = new CertificateAuthorityCredential(
@ -648,7 +666,9 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest
realCertMan,
null,
supplyChainValidationSummaryDBManager,
supplyChainCredentialValidator
supplyChainCredentialValidator,
referenceDigestManager,
referenceEventManager
);
CertificateAuthorityCredential globalSignCaCert = new CertificateAuthorityCredential(
@ -699,7 +719,9 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest
realCertMan,
null,
supplyChainValidationSummaryDBManager,
new SupplyChainCredentialValidator()
new SupplyChainCredentialValidator(),
referenceDigestManager,
referenceEventManager
);
CertificateAuthorityCredential stmEkRootCa = new CertificateAuthorityCredential(

View File

@ -1,5 +1,9 @@
package hirs.attestationca.portal.page.controllers;
import hirs.attestationca.portal.page.Page;
import hirs.attestationca.portal.page.PageController;
import hirs.attestationca.portal.page.PageMessages;
import hirs.attestationca.portal.page.params.ReferenceManifestDetailsPageParams;
import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.EventLogMeasurements;
import hirs.data.persist.ReferenceManifest;
@ -10,23 +14,6 @@ import hirs.persist.CertificateManager;
import hirs.persist.DBManagerException;
import hirs.persist.ReferenceManifestManager;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.attestationca.portal.page.Page;
import hirs.attestationca.portal.page.PageController;
import hirs.attestationca.portal.page.PageMessages;
import hirs.attestationca.portal.page.params.ReferenceManifestDetailsPageParams;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
import hirs.tpm.eventlog.TpmPcrEvent;
import hirs.utils.ReferenceManifestValidator;
import org.apache.logging.log4j.LogManager;
@ -37,6 +24,17 @@ import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
* Controller for the Reference Manifest Details page.
*/
@ -101,7 +99,9 @@ public class ReferenceManifestDetailsPageController
LOGGER.error(uuidError, iaEx);
} catch (Exception ioEx) {
LOGGER.error(ioEx);
LOGGER.trace(ioEx);
for (StackTraceElement ste : ioEx.getStackTrace()) {
LOGGER.debug(ste.toString());
}
}
if (data.isEmpty()) {
String notFoundMessage = "Unable to find RIM with ID: " + params.getId();
@ -187,12 +187,12 @@ public class ReferenceManifestDetailsPageController
} else {
data.put("swidCorpus", "False");
}
if (baseRim.isSwidPatch() == 1) {
if (baseRim.isSwidPatch()) {
data.put("swidPatch", "True");
} else {
data.put("swidPatch", "False");
}
if (baseRim.isSwidSupplemental() == 1) {
if (baseRim.isSwidSupplemental()) {
data.put("swidSupplemental", "True");
} else {
data.put("swidSupplemental", "False");
@ -205,9 +205,16 @@ public class ReferenceManifestDetailsPageController
data.put("entityThumbprint", baseRim.getEntityThumbprint());
// Link
data.put("linkHref", baseRim.getLinkHref());
for (BaseReferenceManifest bRim : BaseReferenceManifest
.select(referenceManifestManager).getRIMs()) {
if (baseRim.getLinkHref().contains(bRim.getTagId())) {
data.put("linkHrefLink", bRim.getId().toString());
break;
} else {
data.put("linkHrefLink", "");
}
}
data.put("linkRel", baseRim.getLinkRel());
data.put("supportRimId", "");
data.put("supportRimTagId", "");
data.put("platformManufacturer", baseRim.getPlatformManufacturer());
data.put("platformManufacturerId", baseRim.getPlatformManufacturerId());
data.put("platformModel", baseRim.getPlatformModel());
@ -222,11 +229,18 @@ public class ReferenceManifestDetailsPageController
data.put("pcUriGlobal", baseRim.getPcURIGlobal());
data.put("pcUriLocal", baseRim.getPcURILocal());
data.put("rimLinkHash", baseRim.getRimLinkHash());
boolean hashLinked = false;
if (baseRim.getRimLinkHash() != null) {
ReferenceManifest rim = BaseReferenceManifest.select(referenceManifestManager)
.byHashCode(baseRim.getRimLinkHash()).getRIM();
hashLinked = (rim != null);
}
data.put("linkHashValid", hashLinked);
data.put("rimType", baseRim.getRimType());
List<SwidResource> resources = baseRim.parseResource();
TCGEventLog logProcessor = null;
ReferenceManifest support = null;
SupportReferenceManifest support = null;
if (baseRim.getAssociatedRim() == null) {
support = SupportReferenceManifest.select(referenceManifestManager)
@ -234,12 +248,10 @@ public class ReferenceManifestDetailsPageController
.getRIM();
if (support != null) {
baseRim.setAssociatedRim(support.getId());
logProcessor = new TCGEventLog(support.getRimBytes());
}
} else {
support = SupportReferenceManifest.select(referenceManifestManager)
.byEntityId(baseRim.getAssociatedRim()).getRIM();
logProcessor = new TCGEventLog(support.getRimBytes());
}
// going to have to pull the filename and grab that from the DB
// to get the id to make the link
@ -253,16 +265,16 @@ public class ReferenceManifestDetailsPageController
} else {
data.put("supportRimHashValid", false);
}
swidRes.setPcrValues(Arrays.asList(
logProcessor.getExpectedPCRValues()));
break;
} else {
swidRes.setPcrValues(new ArrayList<>());
}
}
data.put("associatedRim", baseRim.getAssociatedRim());
data.put("swidFiles", resources);
if (support != null && (!baseRim.isSwidSupplemental()
&& !baseRim.isSwidPatch())) {
data.put("pcrList", support.getExpectedPCRList());
}
RIM_VALIDATOR.validateXmlSignature(new ByteArrayInputStream(baseRim.getRimBytes()));
data.put("signatureValid", RIM_VALIDATOR.isSignatureValid());
@ -301,17 +313,19 @@ public class ReferenceManifestDetailsPageController
HashMap<String, Object> data = new HashMap<>();
EventLogMeasurements measurements = null;
if (support.getAssociatedRim() == null
&& (support.getPlatformManufacturer() != null
&& !support.getPlatformManufacturer().isEmpty())) {
ReferenceManifest baseRim = BaseReferenceManifest.select(referenceManifestManager)
.byManufacturer(support.getPlatformManufacturer()).getRIM();
if (baseRim != null) {
support.setAssociatedRim(baseRim.getId());
try {
referenceManifestManager.update(support);
} catch (DBManagerException ex) {
LOGGER.error("Failed to update Support RIM", ex);
if (support.getAssociatedRim() == null) {
Set<BaseReferenceManifest> baseRims = BaseReferenceManifest
.select(referenceManifestManager)
.byRimType(ReferenceManifest.BASE_RIM).getRIMs();
for (BaseReferenceManifest baseRim : baseRims) {
if (baseRim != null && baseRim.getAssociatedRim().equals(support.getId())) {
support.setAssociatedRim(baseRim.getId());
try {
referenceManifestManager.update(support);
} catch (DBManagerException ex) {
LOGGER.error("Failed to update Support RIM", ex);
}
break;
}
}
}
@ -324,6 +338,18 @@ public class ReferenceManifestDetailsPageController
.byManufacturer(support.getPlatformManufacturer()).getRIM();
}
if (support.isSwidPatch()) {
data.put("swidPatch", "True");
} else {
data.put("swidPatch", "False");
}
if (support.isSwidSupplemental()) {
data.put("swidSupplemental", "True");
} else {
data.put("swidSupplemental", "False");
}
data.put("swidBase", (!support.isSwidPatch()
&& !support.isSwidSupplemental()));
data.put("baseRim", support.getTagId());
data.put("associatedRim", support.getAssociatedRim());
data.put("rimType", support.getRimType());
@ -348,14 +374,20 @@ public class ReferenceManifestDetailsPageController
TCGEventLog measurementsProcess;
if (measurements != null) {
measurementsProcess = new TCGEventLog((measurements.getRimBytes()));
HashMap<String, TpmPcrEvent> digestMap = new HashMap<>();
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
if (!tpe.eventCompare(
measurementsProcess.getEventByNumber(
tpe.getEventNumber()))) {
digestMap.put(tpe.getEventDigestStr(), tpe);
if (!support.isSwidSupplemental()
&& !tpe.eventCompare(
measurementsProcess.getEventByNumber(
tpe.getEventNumber()))) {
tpe.setError(true);
}
tpmPcrEvents.add(tpe);
}
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
tpe.setError(!digestMap.containsKey(tpe.getEventDigestStr()));
}
data.put("events", tpmPcrEvents);
} else {
data.put("events", logProcessor.getEventList());

View File

@ -41,6 +41,24 @@
</c:choose>
</div>
</div>
<c:if test="${not initialData.swidBase}">
<div class="row">
<div class="col-md-1 col-md-offset-1">
<span class="colHeader">RIM Type</span>
</div>
<div id="baseRim" class="col col-md-8">
<c:if test="${initialData.swidCorpus}">
<div>SWID Corpus</div>
</c:if>
<c:if test="${initialData.swidPatch}">
<div>SWID Patch</div>
</c:if>
<c:if test="${initialData.swidSupplemental}">
<div>SWID Supplemental</div>
</c:if>
</div>
</div>
</c:if>
<div class="row">
<div class="col-md-1 col-md-offset-1">
<span class="colRimHeader">
@ -57,7 +75,7 @@
<ul>
<c:if test="${initialData.crtm || initialData.bootManager || initialData.osLoader || initialData.osKernel}">
<li>PC Client Boot path</li>
</c:if>
</c:if>
<ul>
<c:if test="${initialData.crtm}">
<li>Software Core Root of Trust for Measurement (SRTM)</li>
@ -70,7 +88,7 @@
</c:if>
<c:if test="${initialData.osKernel}">
<li>OS Kernel</li>
</c:if>
</c:if>
</ul>
<c:if test="${initialData.acpiTables || initialData.smbiosTables || initialData.gptTable || initialData.defaultBootDevice}">
<li>Device Configuration</li>
@ -90,7 +108,7 @@
</c:if>
<c:if test="${initialData.defaultBootDevice}">
<li>Default boot device</li>
</c:if>
</c:if>
</ul>
<c:if test="${initialData.secureBoot || initialData.pk || initialData.kek || initialData.sigDb || initialData.forbiddenDbx}">
<li>Secure Boot Variables</li>
@ -110,7 +128,7 @@
</c:if>
<c:if test="${initialData.forbiddenDbx}">
<li>Forbidden Signatures Database (dbx)</li>
</c:if>
</c:if>
</ul>
</ul>
</ul>
@ -134,7 +152,6 @@
<li>OS Kernel</li>
</c:if>
</ul>
<c:if test="${not initialData.acpiTables || not initialData.smbiosTables || not initialData.gptTable || not initialData.bootOrder || not initialData.defaultBootDevice}">
<li>Device Configuration</li>
</c:if>
@ -173,7 +190,7 @@
</c:if>
<c:if test="${not initialData.forbiddenDbx}">
<li>Forbidden Signatures Database (dbx)</li>
</c:if>
</c:if>
</ul>
</ul>
</ul>
@ -326,7 +343,7 @@
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Link</span></div>
<div id="link" class="col col-md-8">
<c:if test="${not empty initialData.linkHref}">
<div><span><a href="${initialData.linkHref}" rel="${initialData.linkRel}">${initialData.linkHref}</a></span>
<div><span><a href="${portal}/rim-details?id=${initialData.linkHrefLink}" rel="${initialData.linkRel}">${initialData.linkHref}</a></span>
</div>
<div>Rel:&nbsp;<span>${initialData.linkRel}</span>
</div>
@ -352,13 +369,24 @@
</c:if>
<div>Binding Spec:&nbsp;<span>${initialData.bindingSpec}</span></div>
<div>Binding Spec Version:&nbsp;<span>${initialData.bindingSpecVersion}</span></div>
<c:if test="${not empty initiaData.pcUriGlobal}">
<c:if test="${not empty initialData.pcUriGlobal}">
<div>PC URI Global:&nbsp;<span>${initialData.pcUriGlobal}</span></div>
</c:if>
<c:if test="${not empty initiaData.pcUriLocal}">
<c:if test="${not empty initialData.pcUriLocal}">
<div>PC URI Local:&nbsp;<span>${initialData.pcUriLocal}</span></div>
</c:if>
<div>Rim Link Hash:&nbsp;<span>${initialData.rimLinkHash}</span></div>
<div>Rim Link Hash:&nbsp;<span>${initialData.rimLinkHash}</span>
<span>
<c:choose>
<c:when test="${initialData.linkHashValid}">
<img src="${passIcon}" title="SWID Tag exist.">
</c:when>
<c:otherwise>
<img src="${failIcon}" title="SWID Tag doesn't exist.">
</c:otherwise>
</c:choose>
</span>
</div>
</div>
</div>
<div class="row">
@ -409,26 +437,27 @@
</c:choose>
</span>
</div>
<div class="component col col-md-10">
<span class="fieldHeader">File Size:</span>
<span class="fieldValue">${resource.getSize()}</span><br/>
<span class="fieldHeader">Hash:</span>
<span class="fieldValue" style="overflow-wrap: break-word">${resource.getHashValue()}</span><br/>
<c:if test="${not empty resource.getRimFormat()}">
<span class="fieldHeader">RIM Format:</span>
<span class="fieldValue">${resource.getRimFormat()}</span><br/>
</c:if>
<c:if test="${not empty resource.getRimType()}">
<span class="fieldHeader">RIM Type:</span>
<span class="fieldValue">${resource.getRimType()}</span><br/>
</c:if>
<c:if test="${not empty resource.getRimUriGlobal()}">
<span class="fieldHeader">URI Global:</span>
<span class="fieldValue">${resource.getRimUriGlobal()}</span><br/>
</c:if>
</div>
<c:choose>
<c:when test="${not empty resource.getPcrValues()}">
<c:when test="${not empty initialData.pcrList}">
<div class="component col col-md-10">
<span class="fieldHeader">File Size:</span>
<span class="fieldValue">${resource.getSize()}</span><br/>
<span class="fieldHeader">Hash:</span>
<span class="fieldValue" style="overflow-wrap: break-word">${resource.getHashValue()}</span><br/>
<c:if test="${not empty resource.getRimFormat()}">
<span class="fieldHeader">RIM Format:</span>
<span class="fieldValue">${resource.getRimFormat()}</span><br/>
</c:if>
<c:if test="${not empty resource.getRimType()}">
<span class="fieldHeader">RIM Type:</span>
<span class="fieldValue">${resource.getRimType()}</span><br/>
</c:if>
<c:if test="${not empty resource.getRimUriGlobal()}">
<span class="fieldHeader">URI Global:</span>
<span class="fieldValue">${resource.getRimUriGlobal()}</span><br/>
</c:if>
<c:if test="${not empty resource.getPcrValues()}">
<div class="panel-body">
<div class="component" role="tab" id="pcrValues">
<a role="button" data-toggle="collapse" data-parent="#directorycollapse" class="collapsed"
@ -438,24 +467,28 @@
</div>
<div id="pcrscollapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingThree" aria-expanded="true">
<div>
<c:forEach items="${resource.getPcrMap()}" var="pcrValue">
<c:set var="count" value="0" scope="page"/>
<c:forEach items="${initialData.pcrList}" var="pcrValue">
<div id="componentIdentifier" class="row">
<div>
<span>${pcrValue.key}</span>
<span style="overflow-wrap: break-word">${pcrValue.value}</span>
<span>PCR ${count} - </span>
<span style="overflow-wrap: break-word">${pcrValue}</span>
</div>
</div>
<c:set var="count" value="${count + 1}" scope="page"/>
</c:forEach>
</div>
</div>
</div>
</c:if>
</div>
</c:when>
<c:otherwise>
<c:if test="${not initialData.swidPatch and not initialData.swidSupplemental}">
<div class="component col col-md-10" style="color: red; padding-left: 20px">Support RIM file named ${resource.getName()} was not imported via the Reference Integrity Manifest page.</div>
</c:if>
</c:otherwise>
</c:choose>
</div>
</div>
</div>
</c:forEach>

View File

@ -160,7 +160,7 @@ int provision() {
= provisioner.sendAttestationCertificateRequest(certificateRequest);
if (akCertificateByteString == "") {
cout << "----> Provisioning failed.";
cout << "----> Provisioning the quote failed.";
cout << "Please refer to the Attestation CA for details." << endl;
return 0;
}

View File

@ -41,14 +41,8 @@ public class BaseReferenceManifest extends ReferenceManifest {
@Column
private String swidName = null;
@Column
private String swidVersion = null;
@Column
private int swidCorpus = 0;
@Column
private int swidPatch = 0;
@Column
private int swidSupplemental = 0;
@Column
private String colloquialVersion = null;
@Column
private String product = null;
@ -159,9 +153,9 @@ public class BaseReferenceManifest extends ReferenceManifest {
setTagId(si.getTagId());
this.swidName = si.getName();
this.swidCorpus = si.isCorpus() ? 1 : 0;
this.swidPatch = si.isPatch() ? 1 : 0;
this.swidSupplemental = si.isSupplemental() ? 1 : 0;
this.swidVersion = si.getVersion();
this.setSwidPatch(si.isPatch());
this.setSwidSupplemental(si.isSupplemental());
this.setSwidVersion(si.getVersion());
if (si.getTagVersion() != null) {
this.setSwidTagVersion(si.getTagVersion().toString());
}
@ -439,24 +433,6 @@ public class BaseReferenceManifest extends ReferenceManifest {
this.swidName = swidName;
}
/**
* Getter for the SWID version.
*
* @return string of the version number
*/
public String getSwidVersion() {
return swidVersion;
}
/**
* Setter for the SWID version.
*
* @param swidVersion string of the version
*/
public void setSwidVersion(final String swidVersion) {
this.swidVersion = swidVersion;
}
/**
* Getter for the corpus flag.
*
@ -475,42 +451,6 @@ public class BaseReferenceManifest extends ReferenceManifest {
this.swidCorpus = swidCorpus;
}
/**
* Getter for the patch flag.
*
* @return int flag for the patch flag
*/
public int isSwidPatch() {
return swidPatch;
}
/**
* Setter for the patch flag.
*
* @param swidPatch int value
*/
public void setSwidPatch(final int swidPatch) {
this.swidPatch = swidPatch;
}
/**
* Getter for the supplemental flag.
*
* @return int flag for the supplemental flag
*/
public int isSwidSupplemental() {
return swidSupplemental;
}
/**
* Setter for the supplemental flag.
*
* @param swidSupplemental int value
*/
public void setSwidSupplemental(final int swidSupplemental) {
this.swidSupplemental = swidSupplemental;
}
/**
* Getter for the Entity Name.
*
@ -822,7 +762,7 @@ public class BaseReferenceManifest extends ReferenceManifest {
return String.format("ReferenceManifest{swidName=%s,"
+ "platformManufacturer=%s,"
+ " platformModel=%s,"
+ "tagId=%s, rimHash=%d}",
+ "tagId=%s, rimHash=%s}",
swidName, this.getPlatformManufacturer(),
this.getPlatformModel(), getTagId(), this.getRimHash());
}

View File

@ -21,13 +21,15 @@ public class ReferenceDigestValue extends AbstractEntity {
@Column
private UUID digestRecordId;
@Column(nullable = false)
private int eventNumber;
private int pcrIndex;
@Column(nullable = false)
private String digestValue;
@Column(nullable = false)
private String eventType;
@Column(nullable = false)
private boolean matchFail;
@Column(nullable = false)
private boolean patched = false;
/**
* Default Constructor.
@ -35,28 +37,31 @@ public class ReferenceDigestValue extends AbstractEntity {
public ReferenceDigestValue() {
super();
this.digestRecordId = UUID.randomUUID();
this.eventNumber = -1;
this.pcrIndex = -1;
this.digestValue = "";
this.eventType = "";
this.matchFail = false;
this.patched = false;
}
/**
* Default Constructor with parameters for all associated data.
* @param digestRecordId the UUID of the associated record
* @param eventNumber the event number
* @param pcrIndex the event number
* @param digestValue the key digest value
* @param eventType the event type to store
* @param matchFail the status of the baseline check
* @param patched the status of the value being updated to to patch
*/
public ReferenceDigestValue(final UUID digestRecordId, final int eventNumber,
public ReferenceDigestValue(final UUID digestRecordId, final int pcrIndex,
final String digestValue, final String eventType,
final boolean matchFail) {
final boolean matchFail, final boolean patched) {
this.digestRecordId = digestRecordId;
this.eventNumber = eventNumber;
this.pcrIndex = pcrIndex;
this.digestValue = digestValue;
this.eventType = eventType;
this.matchFail = matchFail;
this.patched = patched;
}
/**
@ -79,16 +84,16 @@ public class ReferenceDigestValue extends AbstractEntity {
* Getter for the event number.
* @return the stored value
*/
public int getEventNumber() {
return eventNumber;
public int getPcrIndex() {
return pcrIndex;
}
/**
* Setter for the event number.
* @param eventNumber the value to store
* @param pcrIndex the value to store
*/
public void setEventNumber(final int eventNumber) {
this.eventNumber = eventNumber;
public void setPcrIndex(final int pcrIndex) {
this.pcrIndex = pcrIndex;
}
/**
@ -139,6 +144,22 @@ public class ReferenceDigestValue extends AbstractEntity {
this.matchFail = matchFail;
}
/**
* Getter for the status of the patched state.
* @return patched flag
*/
public boolean isPatched() {
return patched;
}
/**
* Setter for the status of the patched state.
* @param patched the flag to set
*/
public void setPatched(final boolean patched) {
this.patched = patched;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
@ -148,7 +169,7 @@ public class ReferenceDigestValue extends AbstractEntity {
return false;
}
ReferenceDigestValue that = (ReferenceDigestValue) obj;
return eventNumber == that.eventNumber && matchFail == that.matchFail
return pcrIndex == that.pcrIndex && matchFail == that.matchFail
&& Objects.equals(digestValue, that.digestValue)
&& Objects.equals(digestRecordId, that.digestRecordId)
&& Objects.equals(eventType, that.eventType);
@ -156,7 +177,8 @@ public class ReferenceDigestValue extends AbstractEntity {
@Override
public int hashCode() {
int result = Objects.hash(eventNumber, digestValue, digestRecordId, eventType, matchFail);
int result = Objects.hash(pcrIndex, digestValue, digestRecordId,
eventType, matchFail, patched);
return result;
}
@ -165,6 +187,7 @@ public class ReferenceDigestValue extends AbstractEntity {
* @return a string
*/
public String toString() {
return String.format("ReferenceDigestValue: {%d, %b}", eventNumber, matchFail);
return String.format("ReferenceDigestValue: {%d, %s, %s, %b}",
pcrIndex, digestValue, eventType, matchFail);
}
}

View File

@ -1,23 +1,25 @@
package hirs.data.persist;
import java.util.Arrays;
import java.util.UUID;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.base.Preconditions;
import org.apache.commons.codec.binary.Hex;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.annotations.Type;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.xml.XMLConstants;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.UUID;
/**
* This class represents the Reference Integrity Manifest object that will be
@ -68,7 +70,7 @@ public abstract class ReferenceManifest extends ArchivableEntity {
public static final String RIM_HASH_FIELD = "rimHash";
@Column(nullable = false)
@JsonIgnore
private final int rimHash;
private final String rimHash;
@Column(columnDefinition = "blob", nullable = false)
@JsonIgnore
private byte[] rimBytes;
@ -77,12 +79,18 @@ public abstract class ReferenceManifest extends ArchivableEntity {
@Column
private String tagId = null;
@Column
private boolean swidPatch = false;
@Column
private boolean swidSupplemental = false;
@Column
private String platformManufacturer = null;
@Column
private String platformManufacturerId = null;
@Column
private String swidTagVersion = null;
@Column
private String swidVersion = null;
@Column
private String platformModel = null;
@Column(nullable = false)
private String fileName = null;
@ -96,7 +104,7 @@ public abstract class ReferenceManifest extends ArchivableEntity {
protected ReferenceManifest() {
super();
this.rimBytes = null;
this.rimHash = 0;
this.rimHash = "";
this.rimType = null;
this.platformManufacturer = null;
this.platformManufacturerId = null;
@ -118,7 +126,19 @@ public abstract class ReferenceManifest extends ArchivableEntity {
"Cannot construct a RIM from an empty byte array");
this.rimBytes = rimBytes.clone();
this.rimHash = Arrays.hashCode(this.rimBytes);
MessageDigest digest = null;
try {
digest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException noSaEx) {
LOGGER.error(noSaEx);
}
if (digest == null) {
this.rimHash = "";
} else {
this.rimHash = Hex.encodeHexString(
digest.digest(rimBytes));
}
}
/**
@ -227,6 +247,24 @@ public abstract class ReferenceManifest extends ArchivableEntity {
this.swidTagVersion = swidTagVersion;
}
/**
* Getter for the SWID version.
*
* @return string of the version number
*/
public String getSwidVersion() {
return swidVersion;
}
/**
* Setter for the SWID version.
*
* @param swidVersion string of the version
*/
public void setSwidVersion(final String swidVersion) {
this.swidVersion = swidVersion;
}
/**
* Getter for the RIM Tag ID.
*
@ -245,6 +283,42 @@ public abstract class ReferenceManifest extends ArchivableEntity {
this.tagId = tagId;
}
/**
* Getter for the patch flag.
*
* @return int flag for the patch flag
*/
public boolean isSwidPatch() {
return swidPatch;
}
/**
* Setter for the patch flag.
*
* @param swidPatch int value
*/
public void setSwidPatch(final boolean swidPatch) {
this.swidPatch = swidPatch;
}
/**
* Getter for the supplemental flag.
*
* @return int flag for the supplemental flag
*/
public boolean isSwidSupplemental() {
return swidSupplemental;
}
/**
* Setter for the supplemental flag.
*
* @param swidSupplemental int value
*/
public void setSwidSupplemental(final boolean swidSupplemental) {
this.swidSupplemental = swidSupplemental;
}
/**
* Getter for the associated RIM DB ID.
* @return UUID for the rim
@ -279,13 +353,13 @@ public abstract class ReferenceManifest extends ArchivableEntity {
*
* @return int representation of the hash value
*/
public int getRimHash() {
public String getRimHash() {
return rimHash;
}
@Override
public int hashCode() {
return getRimHash();
return Arrays.hashCode(this.rimBytes);
}
@Override
@ -313,7 +387,8 @@ public abstract class ReferenceManifest extends ArchivableEntity {
@Override
public String toString() {
return String.format("Filename->%s%nPlatform Manufacturer->%s%n"
+ "Platform Model->%s%nRIM Type->%s", this.getFileName(),
this.platformManufacturer, this.platformModel, this.getRimType());
+ "Platform Model->%s%nRIM Type->%s%nRIM Hash->%s", this.getFileName(),
this.platformManufacturer, this.platformModel, this.getRimType(),
this.getRimHash());
}
}

View File

@ -29,6 +29,8 @@ public class SupportReferenceManifest extends ReferenceManifest {
private int pcrHash = 0;
@Column
private boolean updated = false;
@Column
private boolean processed = false;
/**
* This class enables the retrieval of SupportReferenceManifest by their attributes.
@ -78,6 +80,26 @@ public class SupportReferenceManifest extends ReferenceManifest {
setFieldValue(PLATFORM_MODEL, model);
return this;
}
/**
* Specify the file name that rims should have.
* @param fileName the name of the file associated with the rim
* @return this instance
*/
public Selector byFileName(final String fileName) {
setFieldValue(RIM_FILENAME_FIELD, fileName);
return this;
}
/**
* Specify the RIM hash associated with the support RIM.
* @param rimHash the hash of the file associated with the rim
* @return this instance
*/
public Selector byRimHash(final String rimHash) {
setFieldValue(RIM_HASH_FIELD, rimHash);
return this;
}
}
/**
@ -199,4 +221,29 @@ public class SupportReferenceManifest extends ReferenceManifest {
public void setUpdated(final boolean updated) {
this.updated = updated;
}
/**
* Flag method on the status of supplemental processed.
* @return status of the flag
*/
public boolean isProcessed() {
return processed;
}
/**
* Setter for the processed flag.
* @param processed status flag
*/
public void setProcessed(final boolean processed) {
this.processed = processed;
}
/**
* This is a method to indicate whether or not this support
* rim is a base log file.
* @return flag for base.
*/
public boolean isBaseSupport() {
return !this.isSwidSupplemental() && !this.isSwidPatch();
}
}

View File

@ -3,27 +3,14 @@ package hirs.data.persist;
import com.google.common.base.Preconditions;
import hirs.data.persist.baseline.TpmWhiteListBaseline;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.utils.xjc.File;
import java.io.IOException;
import java.util.Map;
import java.util.List;
import java.util.LinkedHashMap;
import java.util.Collections;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.text.DecimalFormat;
import java.util.Arrays;
import javax.xml.namespace.QName;
import org.apache.commons.codec.DecoderException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.xml.namespace.QName;
import java.math.BigInteger;
import java.util.Map;
/**
* This object is used to represent the content of a Swid Tags Directory
* section.
@ -32,20 +19,8 @@ public class SwidResource {
private static final Logger LOGGER = LogManager.getLogger(SwidResource.class);
private static final String CATALINA_HOME = System.getProperty("catalina.base");
private static final String TOMCAT_UPLOAD_DIRECTORY
= "/webapps/HIRS_AttestationCAPortal/upload/";
/**
* String holder for location for storing binaries.
*/
public static final String RESOURCE_UPLOAD_FOLDER
= CATALINA_HOME + TOMCAT_UPLOAD_DIRECTORY;
private String name, size;
private String rimFormat, rimType, rimUriGlobal, hashValue;
private List<String> pcrValues;
private TpmWhiteListBaseline tpmWhiteList;
private DigestAlgorithm digest = DigestAlgorithm.SHA1;
private boolean validFileSize = false;
@ -60,7 +35,6 @@ public class SwidResource {
rimType = null;
rimUriGlobal = null;
hashValue = null;
pcrValues = null;
}
/**
@ -102,23 +76,7 @@ public class SwidResource {
}
this.digest = digest;
parsePcrValues();
tpmWhiteList = new TpmWhiteListBaseline(this.name);
if (!pcrValues.isEmpty()) {
int i = 0;
for (String pcr : pcrValues) {
if (this.digest == null) {
// determine by length of pcr value
this.digest = AbstractDigest.getDigestAlgorithm(pcr);
}
try {
tpmWhiteList.addToBaseline(
new TPMMeasurementRecord(i++, pcr));
} catch (DecoderException deEx) {
LOGGER.error(deEx);
}
}
}
}
/**
@ -175,24 +133,6 @@ public class SwidResource {
return hashValue;
}
/**
* Getter for the list of PCR Values.
*
* @return an unmodifiable list
*/
public List<String> getPcrValues() {
return Collections.unmodifiableList(pcrValues);
}
/**
* Setter for the list of associated PCR Values.
*
* @param pcrValues a collection of PCRs
*/
public void setPcrValues(final List<String> pcrValues) {
this.pcrValues = pcrValues;
}
/**
* flag for if the file sizes match with the swidtag.
* @return true if they match
@ -200,51 +140,4 @@ public class SwidResource {
public boolean isValidFileSize() {
return validFileSize;
}
/**
* Getter for a generated map of the PCR values.
*
* @return mapping of PCR# to the actual value.
*/
public LinkedHashMap<String, String> getPcrMap() {
LinkedHashMap<String, String> innerMap = new LinkedHashMap<>();
DecimalFormat df = new DecimalFormat("00");
if (!this.pcrValues.isEmpty()) {
long iterate = 0;
String pcrNum;
for (String string : this.pcrValues) {
pcrNum = df.format(iterate++);
innerMap.put(String.format("PCR%s:", pcrNum), string);
}
}
return innerMap;
}
private void parsePcrValues() {
TCGEventLog logProcessor = new TCGEventLog();
try {
Path logPath = Paths.get(String.format("%s/%s",
SwidResource.RESOURCE_UPLOAD_FOLDER,
this.getName()));
if (Files.exists(logPath)) {
logProcessor = new TCGEventLog(
Files.readAllBytes(logPath));
}
this.setPcrValues(Arrays.asList(
logProcessor.getExpectedPCRValues()));
} catch (NoSuchFileException nsfEx) {
LOGGER.error(String.format("File Not found!: %s",
this.getName()));
LOGGER.error(nsfEx);
} catch (IOException ioEx) {
LOGGER.error(ioEx);
} catch (CertificateException cEx) {
LOGGER.error(cEx);
} catch (NoSuchAlgorithmException naEx) {
LOGGER.error(naEx);
}
}
}

View File

@ -77,6 +77,37 @@ public class DBReferenceDigestManager extends DBManager<ReferenceDigestRecord>
return dbRecord;
}
@Override
public ReferenceDigestRecord getRecord(final String manufacturer, final String model) {
LOGGER.debug("Getting record for {} ~ {}", manufacturer, model);
if (manufacturer == null || model == null) {
LOGGER.error("No reference to get record from db {} ~ {}", manufacturer, model);
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",
manufacturer)).add(Restrictions.eq("model",
model)).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);

View File

@ -50,7 +50,7 @@ public class DBReferenceEventManager extends DBManager<ReferenceDigestValue>
if (referenceDigestValue.getDigestRecordId() == null
|| referenceDigestValue.getDigestValue() == null
|| referenceDigestValue.getEventNumber() == -1) {
|| referenceDigestValue.getPcrIndex() == -1) {
LOGGER.error("No reference to get record from db {}", referenceDigestValue);
return null;
}
@ -67,7 +67,7 @@ public class DBReferenceEventManager extends DBManager<ReferenceDigestValue>
.add(Restrictions.eq("digestValue",
referenceDigestValue.getDigestValue()))
.add(Restrictions.eq("eventNumber",
referenceDigestValue.getEventNumber()))
referenceDigestValue.getPcrIndex()))
.uniqueResult();
tx.commit();
} catch (Exception ex) {

View File

@ -28,6 +28,15 @@ public interface ReferenceDigestManager {
*/
ReferenceDigestRecord getRecord(ReferenceDigestRecord referenceDigestRecord);
/**
* Persists a new Reference Digest.
*
* @param manufacturer the string of the manufacturer
* @param model the string of the model
* @return the persisted ReferenceDigestRecord
*/
ReferenceDigestRecord getRecord(String manufacturer, String model);
/**
* Persists a new Reference Digest.
*

View File

@ -37,8 +37,11 @@ public abstract class ReferenceManifestSelector<T extends ReferenceManifest> {
* String representing the database field for the model.
*/
public static final String PLATFORM_MODEL = "platformModel";
/**
* String representing the database field for the filename.
*/
public static final String RIM_FILENAME_FIELD = "fileName";
private static final String RIM_TYPE_FIELD = "rimType";
private static final String RIM_FILENAME_FIELD = "fileName";
private final ReferenceManifestManager referenceManifestManager;
private final Class<T> referenceTypeClass;
@ -100,7 +103,7 @@ public abstract class ReferenceManifestSelector<T extends ReferenceManifest> {
* @param rimHash the hash code of the bytes to query for
* @return this instance (for chaining further calls)
*/
public ReferenceManifestSelector<T> byHashCode(final int rimHash) {
public ReferenceManifestSelector<T> byHashCode(final String rimHash) {
setFieldValue(hirs.data.persist.ReferenceManifest.RIM_HASH_FIELD, rimHash);
return this;
}

View File

@ -123,7 +123,10 @@
<property name="max" value="100"/>
</module>
<module name="MethodLength"/>
<module name="ParameterNumber"/>
<module name="ParameterNumber">
<property name="max" value="10"/>
<property name="tokens" value="METHOD_DEF"/>
</module>
<!-- Checks for whitespace -->