Merge remote-tracking branch 'origin/digest-implement-final' into fm-validation-pass-link

This commit is contained in:
Cyrus 2021-06-08 22:19:52 -04:00
commit 218002a3c2
15 changed files with 482 additions and 275 deletions

View File

@ -14,7 +14,6 @@ import hirs.data.persist.DeviceInfoReport;
import hirs.data.persist.EventLogMeasurements; import hirs.data.persist.EventLogMeasurements;
import hirs.data.persist.ReferenceDigestRecord; import hirs.data.persist.ReferenceDigestRecord;
import hirs.data.persist.ReferenceDigestValue; import hirs.data.persist.ReferenceDigestValue;
import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.SupplyChainPolicy; import hirs.data.persist.SupplyChainPolicy;
import hirs.data.persist.SupplyChainValidationSummary; import hirs.data.persist.SupplyChainValidationSummary;
import hirs.data.persist.SupportReferenceManifest; import hirs.data.persist.SupportReferenceManifest;
@ -94,6 +93,7 @@ import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.security.spec.MGF1ParameterSpec; import java.security.spec.MGF1ParameterSpec;
import java.security.spec.RSAPublicKeySpec; import java.security.spec.RSAPublicKeySpec;
import java.util.Base64;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
@ -680,7 +680,6 @@ public abstract class AbstractAttestationCertificateAuthority
for (String line : lines) { for (String line : lines) {
if (!line.isEmpty() if (!line.isEmpty()
&& !line.contains(TPM_SIGNATURE_ALG)) { && !line.contains(TPM_SIGNATURE_ALG)) {
LOG.error(line);
pcrs[counter++] = line.split(":")[1].trim(); pcrs[counter++] = line.split(":")[1].trim();
} }
} }
@ -776,7 +775,7 @@ public abstract class AbstractAttestationCertificateAuthority
dv.getHw().getManufacturer(), dv.getHw().getManufacturer(),
dv.getHw().getProductName()); dv.getHw().getProductName());
BaseReferenceManifest dbBaseRim = null; BaseReferenceManifest dbBaseRim = null;
ReferenceManifest support; SupportReferenceManifest support;
EventLogMeasurements measurements; EventLogMeasurements measurements;
String tagId = ""; String tagId = "";
String fileName = ""; String fileName = "";
@ -788,11 +787,9 @@ public abstract class AbstractAttestationCertificateAuthority
for (ByteString logFile : dv.getLogfileList()) { for (ByteString logFile : dv.getLogfileList()) {
try { try {
support = SupportReferenceManifest.select(referenceManifestManager) support = SupportReferenceManifest.select(referenceManifestManager)
.includeArchived() .byHexDecHash(Hex.encodeHexString(messageDigest.digest(
.byHashCode(Hex.encodeHexString(messageDigest.digest( logFile.toByteArray()))).includeArchived()
logFile.toByteArray())))
.getRIM(); .getRIM();
if (support == null) { if (support == null) {
support = new SupportReferenceManifest( support = new SupportReferenceManifest(
String.format("%s.rimel", String.format("%s.rimel",
@ -804,8 +801,9 @@ public abstract class AbstractAttestationCertificateAuthority
support.setPlatformManufacturer(dv.getHw().getManufacturer()); support.setPlatformManufacturer(dv.getHw().getManufacturer());
support.setPlatformModel(dv.getHw().getProductName()); support.setPlatformModel(dv.getHw().getProductName());
support.setFileName(String.format("%s_[%s].rimel", defaultClientName, support.setFileName(String.format("%s_[%s].rimel", defaultClientName,
support.getRimHash().substring( support.getHexDecHash().substring(
support.getRimHash().length() - NUM_OF_VARIABLES))); support.getHexDecHash().length() - NUM_OF_VARIABLES)));
support.setDeviceName(dv.getNw().getHostname());
this.referenceManifestManager.save(support); this.referenceManifestManager.save(support);
} else { } else {
LOG.info("Client provided Support RIM already loaded in database."); LOG.info("Client provided Support RIM already loaded in database.");
@ -828,53 +826,19 @@ public abstract class AbstractAttestationCertificateAuthority
if (dv.getSwidfileCount() > 0) { if (dv.getSwidfileCount() > 0) {
for (ByteString swidFile : dv.getSwidfileList()) { for (ByteString swidFile : dv.getSwidfileList()) {
fileName = "";
try { try {
dbBaseRim = BaseReferenceManifest.select(referenceManifestManager) dbBaseRim = BaseReferenceManifest.select(referenceManifestManager)
.byBase64Hash(Base64.getEncoder()
.encodeToString(messageDigest
.digest(swidFile.toByteArray())))
.includeArchived() .includeArchived()
.byHashCode(Hex.encodeHexString(messageDigest.digest(
swidFile.toByteArray())))
.getRIM(); .getRIM();
if (dbBaseRim == null) { if (dbBaseRim == null) {
dbBaseRim = new BaseReferenceManifest( dbBaseRim = new BaseReferenceManifest(
String.format("%s.swidtag", String.format("%s.swidtag",
defaultClientName), defaultClientName),
swidFile.toByteArray()); swidFile.toByteArray());
dbBaseRim.setDeviceName(dv.getNw().getHostname());
// 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(".");
fileName = swid.getName().substring(0, dotIndex);
dbBaseRim = new BaseReferenceManifest(
String.format("%s.swidtag",
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); this.referenceManifestManager.save(dbBaseRim);
} else { } else {
LOG.info("Client provided Base RIM already loaded in database."); LOG.info("Client provided Base RIM already loaded in database.");
@ -888,7 +852,6 @@ public abstract class AbstractAttestationCertificateAuthority
this.referenceManifestManager.update(dbBaseRim); this.referenceManifestManager.update(dbBaseRim);
} }
} }
} catch (IOException ioEx) { } catch (IOException ioEx) {
LOG.error(ioEx); LOG.error(ioEx);
} }
@ -897,16 +860,56 @@ public abstract class AbstractAttestationCertificateAuthority
LOG.warn("Device did not send swid tag file..."); LOG.warn("Device did not send swid tag file...");
} }
generateDigestRecords(hw.getManufacturer(), hw.getProductName()); //update Support RIMs and Base RIMs.
for (ByteString swidFile : dv.getSwidfileList()) {
dbBaseRim = BaseReferenceManifest.select(referenceManifestManager)
.byBase64Hash(Base64.getEncoder().encodeToString(messageDigest.digest(
swidFile.toByteArray()))).includeArchived()
.getRIM();
// 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(".");
fileName = swid.getName().substring(0, dotIndex);
dbBaseRim.setFileName(String.format("%s.swidtag",
fileName));
}
// now update support rim
SupportReferenceManifest dbSupport = SupportReferenceManifest
.select(referenceManifestManager)
.byHexDecHash(swid.getHashValue()).getRIM();
if (dbSupport != null) {
dbSupport.setFileName(swid.getName());
dbSupport.setSwidTagVersion(dbBaseRim.getSwidTagVersion());
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);
dbSupport.setAssociatedRim(dbBaseRim.getId());
this.referenceManifestManager.update(dbSupport);
}
}
this.referenceManifestManager.update(dbBaseRim);
}
generateDigestRecords(hw.getManufacturer(), hw.getProductName(),
dv.getNw().getHostname());
if (dv.hasLivelog()) { if (dv.hasLivelog()) {
LOG.info("Device sent bios measurement log..."); LOG.info("Device sent bios measurement log...");
fileName = String.format("%s.measurement", fileName = String.format("%s.measurement",
defaultClientName); dv.getNw().getHostname());
try { try {
// find previous version. If it exists, delete it // find previous version. If it exists, delete it
measurements = EventLogMeasurements.select(referenceManifestManager) measurements = EventLogMeasurements.select(referenceManifestManager)
.byManufacturer(dv.getHw().getManufacturer()) .byDeviceName(dv.getNw().getHostname())
.includeArchived().getRIM(); .includeArchived().getRIM();
if (measurements != null) { if (measurements != null) {
LOG.info("Previous bios measurement log found and being replaced..."); LOG.info("Previous bios measurement log found and being replaced...");
@ -917,6 +920,7 @@ public abstract class AbstractAttestationCertificateAuthority
measurements.setPlatformManufacturer(dv.getHw().getManufacturer()); measurements.setPlatformManufacturer(dv.getHw().getManufacturer());
measurements.setPlatformModel(dv.getHw().getProductName()); measurements.setPlatformModel(dv.getHw().getProductName());
measurements.setTagId(tagId); measurements.setTagId(tagId);
measurements.setDeviceName(dv.getNw().getHostname());
this.referenceManifestManager.save(measurements); this.referenceManifestManager.save(measurements);
} catch (IOException ioEx) { } catch (IOException ioEx) {
LOG.error(ioEx); LOG.error(ioEx);
@ -944,7 +948,8 @@ public abstract class AbstractAttestationCertificateAuthority
return dvReport; return dvReport;
} }
private boolean generateDigestRecords(final String manufacturer, final String model) { private boolean generateDigestRecords(final String manufacturer, final String model,
final String deviceName) {
List<ReferenceDigestValue> rdValues; List<ReferenceDigestValue> rdValues;
Set<SupportReferenceManifest> dbSupportRims = SupportReferenceManifest Set<SupportReferenceManifest> dbSupportRims = SupportReferenceManifest
.select(referenceManifestManager).byManufacturer(manufacturer).getRIMs(); .select(referenceManifestManager).byManufacturer(manufacturer).getRIMs();
@ -953,6 +958,7 @@ public abstract class AbstractAttestationCertificateAuthority
if (dbSupport.getPlatformModel().equals(model)) { if (dbSupport.getPlatformModel().equals(model)) {
ReferenceDigestRecord dbObj = new ReferenceDigestRecord(dbSupport, ReferenceDigestRecord dbObj = new ReferenceDigestRecord(dbSupport,
manufacturer, model); manufacturer, model);
dbObj.setDeviceName(deviceName);
// this is where we update or create the log // this is where we update or create the log
ReferenceDigestRecord rdr = this.referenceDigestManager.getRecord(dbObj); ReferenceDigestRecord rdr = this.referenceDigestManager.getRecord(dbObj);
if (dbSupport.isBaseSupport()) { if (dbSupport.isBaseSupport()) {

View File

@ -370,28 +370,30 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
String model = device.getDeviceInfo() String model = device.getDeviceInfo()
.getHardwareInfo().getProductName(); .getHardwareInfo().getProductName();
ReferenceManifest validationObject = null; ReferenceManifest validationObject = null;
ReferenceManifest baseReferenceManifest = null; Set<BaseReferenceManifest> baseReferenceManifests = null;
BaseReferenceManifest baseReferenceManifest = null;
ReferenceManifest supportReferenceManifest = null; ReferenceManifest supportReferenceManifest = null;
ReferenceManifest measurement = null; ReferenceManifest measurement = null;
ReferenceDigestRecord digestRecord = null; ReferenceDigestRecord digestRecord = null;
baseReferenceManifest = BaseReferenceManifest.select(referenceManifestManager) baseReferenceManifests = BaseReferenceManifest.select(referenceManifestManager)
.byManufacturer(manufacturer).getRIM(); .byDeviceName(device.getDeviceInfo().getNetworkInfo().getHostname()).getRIMs();
supportReferenceManifest = SupportReferenceManifest.select(referenceManifestManager)
.byManufacturer(manufacturer).getRIM();
measurement = EventLogMeasurements.select(referenceManifestManager) measurement = EventLogMeasurements.select(referenceManifestManager)
.byManufacturer(manufacturer).includeArchived().getRIM(); .byManufacturer(manufacturer).includeArchived().getRIM();
for (BaseReferenceManifest bRim : baseReferenceManifests) {
if (!bRim.isSwidSupplemental() && !bRim.isSwidPatch()) {
baseReferenceManifest = bRim;
}
}
validationObject = baseReferenceManifest; validationObject = baseReferenceManifest;
String failedString = ""; String failedString = "";
if (baseReferenceManifest == null) { if (baseReferenceManifest == null) {
failedString = "Base Reference Integrity Manifest\n"; failedString = "Base Reference Integrity Manifest\n";
passed = false; passed = false;
} }
if (supportReferenceManifest == null) {
failedString += "Support Reference Integrity Manifest\n";
passed = false;
}
if (measurement == null) { if (measurement == null) {
failedString += "Bios measurement"; failedString += "Bios measurement";
passed = false; passed = false;
@ -409,13 +411,23 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
new ByteArrayInputStream(baseReferenceManifest.getRimBytes())); new ByteArrayInputStream(baseReferenceManifest.getRimBytes()));
for (SwidResource swidRes : resources) { for (SwidResource swidRes : resources) {
if (swidRes.getName().equals(supportReferenceManifest.getFileName())) { supportReferenceManifest = SupportReferenceManifest.select(referenceManifestManager)
.byHexDecHash(swidRes.getHashValue()).getRIM();
if (supportReferenceManifest != null
&& swidRes.getName().equals(supportReferenceManifest.getFileName())) {
referenceManifestValidator.validateSupportRimHash( referenceManifestValidator.validateSupportRimHash(
supportReferenceManifest.getRimBytes(), swidRes.getHashValue()); supportReferenceManifest.getRimBytes(), swidRes.getHashValue());
} else {
supportReferenceManifest = null;
} }
} }
if (supportReferenceManifest == null) {
fwStatus = new AppraisalStatus(FAIL,
"Support Reference Integrity Manifest can not be found\n");
passed = false;
}
if (!referenceManifestValidator.isSignatureValid()) { if (passed && !referenceManifestValidator.isSignatureValid()) {
passed = false; passed = false;
fwStatus = new AppraisalStatus(FAIL, fwStatus = new AppraisalStatus(FAIL,
"Firmware validation failed: Signature validation " "Firmware validation failed: Signature validation "
@ -432,7 +444,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
if (passed) { if (passed) {
TCGEventLog logProcessor; TCGEventLog logProcessor;
try { try {
logProcessor = new TCGEventLog(supportReferenceManifest.getRimBytes()); logProcessor = new TCGEventLog(measurement.getRimBytes());
baseline = logProcessor.getExpectedPCRValues(); baseline = logProcessor.getExpectedPCRValues();
} catch (CertificateException cEx) { } catch (CertificateException cEx) {
LOGGER.error(cEx); LOGGER.error(cEx);
@ -471,7 +483,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
} else { } else {
StringBuilder sb = pcrPolicy.validatePcrs(storedPcrs); StringBuilder sb = pcrPolicy.validatePcrs(storedPcrs);
if (sb.length() > 0) { if (sb.length() > 0) {
validationObject = supportReferenceManifest; validationObject = baseReferenceManifest;
level = Level.ERROR; level = Level.ERROR;
fwStatus = new AppraisalStatus(FAIL, sb.toString()); fwStatus = new AppraisalStatus(FAIL, sb.toString());
} else { } else {
@ -512,9 +524,11 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
if (!tpmPcrEvents.isEmpty()) { if (!tpmPcrEvents.isEmpty()) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
validationObject = measurement; validationObject = measurement;
sb.append(String.format("%d digest(s) were not found:%n",
tpmPcrEvents.size()));
for (TpmPcrEvent tpe : tpmPcrEvents) { for (TpmPcrEvent tpe : tpmPcrEvents) {
sb.append(String.format("Event %s - %s%n", sb.append(String.format("PCR Index %d - %s%n",
tpe.getEventNumber(), tpe.getPcrIndex(),
tpe.getEventTypeStr())); tpe.getEventTypeStr()));
} }
if (fwStatus.getAppStatus().equals(FAIL)) { if (fwStatus.getAppStatus().equals(FAIL)) {

View File

@ -6,12 +6,16 @@ import hirs.attestationca.portal.page.PageMessages;
import hirs.attestationca.portal.page.params.ReferenceManifestDetailsPageParams; import hirs.attestationca.portal.page.params.ReferenceManifestDetailsPageParams;
import hirs.data.persist.BaseReferenceManifest; import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.EventLogMeasurements; import hirs.data.persist.EventLogMeasurements;
import hirs.data.persist.ReferenceDigestRecord;
import hirs.data.persist.ReferenceDigestValue;
import hirs.data.persist.ReferenceManifest; import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.SupportReferenceManifest; import hirs.data.persist.SupportReferenceManifest;
import hirs.data.persist.SwidResource; import hirs.data.persist.SwidResource;
import hirs.data.persist.certificate.CertificateAuthorityCredential; import hirs.data.persist.certificate.CertificateAuthorityCredential;
import hirs.persist.CertificateManager; import hirs.persist.CertificateManager;
import hirs.persist.DBManagerException; import hirs.persist.DBManagerException;
import hirs.persist.ReferenceDigestManager;
import hirs.persist.ReferenceEventManager;
import hirs.persist.ReferenceManifestManager; import hirs.persist.ReferenceManifestManager;
import hirs.tpm.eventlog.TCGEventLog; import hirs.tpm.eventlog.TCGEventLog;
import hirs.tpm.eventlog.TpmPcrEvent; import hirs.tpm.eventlog.TpmPcrEvent;
@ -28,10 +32,12 @@ import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -44,6 +50,8 @@ public class ReferenceManifestDetailsPageController
extends PageController<ReferenceManifestDetailsPageParams> { extends PageController<ReferenceManifestDetailsPageParams> {
private final ReferenceManifestManager referenceManifestManager; private final ReferenceManifestManager referenceManifestManager;
private final ReferenceDigestManager referenceDigestManager;
private final ReferenceEventManager referenceEventManager;
private final CertificateManager certificateManager; private final CertificateManager certificateManager;
private static final ReferenceManifestValidator RIM_VALIDATOR private static final ReferenceManifestValidator RIM_VALIDATOR
= new ReferenceManifestValidator(); = new ReferenceManifestValidator();
@ -54,14 +62,20 @@ public class ReferenceManifestDetailsPageController
* Constructor providing the Page's display and routing specification. * Constructor providing the Page's display and routing specification.
* *
* @param referenceManifestManager the reference manifest manager. * @param referenceManifestManager the reference manifest manager.
* @param referenceDigestManager the reference digest manager.
* @param referenceEventManager the reference event manager.
* @param certificateManager the certificate manager. * @param certificateManager the certificate manager.
*/ */
@Autowired @Autowired
public ReferenceManifestDetailsPageController( public ReferenceManifestDetailsPageController(
final ReferenceManifestManager referenceManifestManager, final ReferenceManifestManager referenceManifestManager,
final ReferenceDigestManager referenceDigestManager,
final ReferenceEventManager referenceEventManager,
final CertificateManager certificateManager) { final CertificateManager certificateManager) {
super(Page.RIM_DETAILS); super(Page.RIM_DETAILS);
this.referenceManifestManager = referenceManifestManager; this.referenceManifestManager = referenceManifestManager;
this.referenceDigestManager = referenceDigestManager;
this.referenceEventManager = referenceEventManager;
this.certificateManager = certificateManager; this.certificateManager = certificateManager;
} }
@ -87,12 +101,13 @@ public class ReferenceManifestDetailsPageController
if (params.getId() == null) { if (params.getId() == null) {
String typeError = "ID was not provided"; String typeError = "ID was not provided";
messages.addError(typeError); messages.addError(typeError);
LOGGER.error(typeError); LOGGER.debug(typeError);
mav.addObject(MESSAGES_ATTRIBUTE, messages); mav.addObject(MESSAGES_ATTRIBUTE, messages);
} else { } else {
try { try {
UUID uuid = UUID.fromString(params.getId()); UUID uuid = UUID.fromString(params.getId());
data.putAll(getRimDetailInfo(uuid, referenceManifestManager, certificateManager)); data.putAll(getRimDetailInfo(uuid, referenceManifestManager,
referenceDigestManager, referenceEventManager, certificateManager));
} catch (IllegalArgumentException iaEx) { } catch (IllegalArgumentException iaEx) {
String uuidError = "Failed to parse ID from: " + params.getId(); String uuidError = "Failed to parse ID from: " + params.getId();
messages.addError(uuidError); messages.addError(uuidError);
@ -100,7 +115,7 @@ public class ReferenceManifestDetailsPageController
} catch (Exception ioEx) { } catch (Exception ioEx) {
LOGGER.error(ioEx); LOGGER.error(ioEx);
for (StackTraceElement ste : ioEx.getStackTrace()) { for (StackTraceElement ste : ioEx.getStackTrace()) {
LOGGER.debug(ste.toString()); LOGGER.error(ste.toString());
} }
} }
if (data.isEmpty()) { if (data.isEmpty()) {
@ -123,6 +138,8 @@ public class ReferenceManifestDetailsPageController
* *
* @param uuid database reference for the requested RIM. * @param uuid database reference for the requested RIM.
* @param referenceManifestManager the reference manifest manager. * @param referenceManifestManager the reference manifest manager.
* @param referenceDigestManager the reference digest manager.
* @param referenceEventManager the reference event manager.
* @param certificateManager the certificate manager. * @param certificateManager the certificate manager.
* @return mapping of the RIM information from the database. * @return mapping of the RIM information from the database.
* @throws java.io.IOException error for reading file bytes. * @throws java.io.IOException error for reading file bytes.
@ -131,6 +148,8 @@ public class ReferenceManifestDetailsPageController
*/ */
public static HashMap<String, Object> getRimDetailInfo(final UUID uuid, public static HashMap<String, Object> getRimDetailInfo(final UUID uuid,
final ReferenceManifestManager referenceManifestManager, final ReferenceManifestManager referenceManifestManager,
final ReferenceDigestManager referenceDigestManager,
final ReferenceEventManager referenceEventManager,
final CertificateManager certificateManager) throws IOException, final CertificateManager certificateManager) throws IOException,
CertificateException, NoSuchAlgorithmException { CertificateException, NoSuchAlgorithmException {
HashMap<String, Object> data = new HashMap<>(); HashMap<String, Object> data = new HashMap<>();
@ -153,7 +172,8 @@ public class ReferenceManifestDetailsPageController
.byEntityId(uuid).getRIM(); .byEntityId(uuid).getRIM();
if (bios != null) { if (bios != null) {
data.putAll(getMeasurementsRimInfo(bios, referenceManifestManager)); data.putAll(getMeasurementsRimInfo(bios, referenceManifestManager,
referenceDigestManager, referenceEventManager));
} }
return data; return data;
@ -232,8 +252,11 @@ public class ReferenceManifestDetailsPageController
boolean hashLinked = false; boolean hashLinked = false;
if (baseRim.getRimLinkHash() != null) { if (baseRim.getRimLinkHash() != null) {
ReferenceManifest rim = BaseReferenceManifest.select(referenceManifestManager) ReferenceManifest rim = BaseReferenceManifest.select(referenceManifestManager)
.byHashCode(baseRim.getRimLinkHash()).getRIM(); .byBase64Hash(baseRim.getRimLinkHash()).getRIM();
hashLinked = (rim != null); hashLinked = (rim != null);
if (hashLinked) {
data.put("rimLinkId", rim.getId());
}
} }
data.put("linkHashValid", hashLinked); data.put("linkHashValid", hashLinked);
data.put("rimType", baseRim.getRimType()); data.put("rimType", baseRim.getRimType());
@ -318,7 +341,8 @@ public class ReferenceManifestDetailsPageController
.select(referenceManifestManager) .select(referenceManifestManager)
.byRimType(ReferenceManifest.BASE_RIM).getRIMs(); .byRimType(ReferenceManifest.BASE_RIM).getRIMs();
for (BaseReferenceManifest baseRim : baseRims) { for (BaseReferenceManifest baseRim : baseRims) {
if (baseRim != null && baseRim.getAssociatedRim().equals(support.getId())) { if (baseRim != null && baseRim.getAssociatedRim() != null
&& baseRim.getAssociatedRim().equals(support.getId())) {
support.setAssociatedRim(baseRim.getId()); support.setAssociatedRim(baseRim.getId());
try { try {
referenceManifestManager.update(support); referenceManifestManager.update(support);
@ -457,6 +481,8 @@ public class ReferenceManifestDetailsPageController
* *
* @param measurements established ReferenceManifest Type. * @param measurements established ReferenceManifest Type.
* @param referenceManifestManager the reference manifest manager. * @param referenceManifestManager the reference manifest manager.
* @param referenceDigestManager the reference digest manager.
* @param referenceEventManager the reference event manager.
* @return mapping of the RIM information from the database. * @return mapping of the RIM information from the database.
* @throws java.io.IOException error for reading file bytes. * @throws java.io.IOException error for reading file bytes.
* @throws NoSuchAlgorithmException If an unknown Algorithm is encountered. * @throws NoSuchAlgorithmException If an unknown Algorithm is encountered.
@ -464,56 +490,102 @@ public class ReferenceManifestDetailsPageController
*/ */
private static HashMap<String, Object> getMeasurementsRimInfo( private static HashMap<String, Object> getMeasurementsRimInfo(
final EventLogMeasurements measurements, final EventLogMeasurements measurements,
final ReferenceManifestManager referenceManifestManager) final ReferenceManifestManager referenceManifestManager,
final ReferenceDigestManager referenceDigestManager,
final ReferenceEventManager referenceEventManager)
throws IOException, CertificateException, NoSuchAlgorithmException { throws IOException, CertificateException, NoSuchAlgorithmException {
HashMap<String, Object> data = new HashMap<>(); HashMap<String, Object> data = new HashMap<>();
LinkedList<TpmPcrEvent> supportEvents = new LinkedList<>();
LinkedList<TpmPcrEvent> livelogEvents = new LinkedList<>(); LinkedList<TpmPcrEvent> livelogEvents = new LinkedList<>();
BaseReferenceManifest base = null; BaseReferenceManifest base = null;
SupportReferenceManifest support = null; List<SupportReferenceManifest> supports = new ArrayList<>();
TCGEventLog supportLog = null; SupportReferenceManifest baseSupport = null;
List<ReferenceDigestRecord> digestRecords = new LinkedList<>();
data.put("supportFilename", "Blank"); data.put("supportFilename", "Blank");
data.put("supportId", ""); data.put("supportId", "");
data.put("tagId", measurements.getTagId());
data.put("baseId", ""); data.put("baseId", "");
data.put("rimType", measurements.getRimType()); data.put("rimType", measurements.getRimType());
data.put("hostName", measurements.getDeviceName());
if (measurements.getPlatformManufacturer() != null) { if (measurements.getDeviceName() != null) {
support = SupportReferenceManifest digestRecords = referenceDigestManager
.getRecordsByDeviceName(measurements.getDeviceName());
supports.addAll(SupportReferenceManifest
.select(referenceManifestManager) .select(referenceManifestManager)
.byManufacturer(measurements .byDeviceName(measurements
.getPlatformManufacturer()).getRIM(); .getDeviceName()).getRIMs());
for (SupportReferenceManifest support : supports) {
if (support != null) { if (support.isBaseSupport()) {
supportLog = new TCGEventLog(support.getRimBytes()); baseSupport = support;
data.put("supportFilename", support.getFileName()); }
data.put("supportId", support.getId());
} }
base = BaseReferenceManifest if (baseSupport != null) {
.select(referenceManifestManager) data.put("supportFilename", baseSupport.getFileName());
.byManufacturer(measurements data.put("supportId", baseSupport.getId());
.getPlatformManufacturer()).getRIM();
if (base != null) { base = BaseReferenceManifest
data.put("baseId", base.getId()); .select(referenceManifestManager)
.byEntityId(baseSupport.getAssociatedRim())
.getRIM();
data.put("tagId", baseSupport.getTagId());
if (base != null) {
data.put("baseId", base.getId());
}
} }
} }
TCGEventLog measurementLog = new TCGEventLog(measurements.getRimBytes()); TCGEventLog measurementLog = new TCGEventLog(measurements.getRimBytes());
if (supportLog != null) { List<ReferenceDigestValue> eventValue = new ArrayList<>();
TpmPcrEvent measurementEvent; Map<String, ReferenceDigestValue> eventValueMap = new HashMap<>();
for (TpmPcrEvent tpe : supportLog.getEventList()) { if (!digestRecords.isEmpty()) {
measurementEvent = measurementLog.getEventByNumber(tpe.getEventNumber()); for (ReferenceDigestRecord rdr : digestRecords) {
if (!tpe.eventCompare(measurementEvent)) { eventValue.addAll(referenceEventManager
supportEvents.add(tpe); .getValuesByRecordId(rdr));
}
for (ReferenceDigestValue rdv : eventValue) {
eventValueMap.put(rdv.getDigestValue(), rdv);
}
for (TpmPcrEvent measurementEvent : measurementLog.getEventList()) {
if (!eventValueMap.containsKey(measurementEvent.getEventDigestStr())) {
livelogEvents.add(measurementEvent); livelogEvents.add(measurementEvent);
} }
} }
} }
data.put("supportEvents", supportEvents); if (!supports.isEmpty()) {
Map<String, List<TpmPcrEvent>> baselineLogEvents = new HashMap<>();
List<TpmPcrEvent> matchedEvents = null;
List<TpmPcrEvent> combinedBaselines = new LinkedList<>();
for (SupportReferenceManifest support : supports) {
combinedBaselines.addAll(support.getEventLog());
}
String bootVariable;
String variablePrefix = "Variable Name:";
String variableSuffix = "UEFI_GUID";
for (TpmPcrEvent tpe : livelogEvents) {
matchedEvents = new ArrayList<>();
for (TpmPcrEvent tpmPcrEvent : combinedBaselines) {
if (tpmPcrEvent.getEventType() == tpe.getEventType()) {
if (tpe.getEventContentStr().contains(variablePrefix)) {
bootVariable = tpe.getEventContentStr().substring((
tpe.getEventContentStr().indexOf(variablePrefix)
+ variablePrefix.length()),
tpe.getEventContentStr().indexOf(variableSuffix));
if (tpmPcrEvent.getEventContentStr().contains(bootVariable)) {
matchedEvents.add(tpmPcrEvent);
}
} else {
matchedEvents.add(tpmPcrEvent);
}
}
}
baselineLogEvents.put(tpe.getEventDigestStr(), matchedEvents);
}
data.put("eventTypeMap", baselineLogEvents);
}
data.put("livelogEvents", livelogEvents); data.put("livelogEvents", livelogEvents);
return data; return data;

View File

@ -1,40 +1,26 @@
package hirs.attestationca.portal.page.controllers; package hirs.attestationca.portal.page.controllers;
import hirs.FilteredRecordsList;
import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableInput;
import hirs.attestationca.portal.datatables.DataTableResponse; import hirs.attestationca.portal.datatables.DataTableResponse;
import hirs.attestationca.portal.datatables.OrderedListQueryDataTableAdapter;
import hirs.attestationca.portal.page.Page; import hirs.attestationca.portal.page.Page;
import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageController;
import hirs.FilteredRecordsList;
import hirs.attestationca.portal.datatables.OrderedListQueryDataTableAdapter;
import hirs.attestationca.portal.page.PageMessages; import hirs.attestationca.portal.page.PageMessages;
import hirs.attestationca.portal.page.params.NoPageParams; import hirs.attestationca.portal.page.params.NoPageParams;
import hirs.data.persist.BaseReferenceManifest; import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.SupportReferenceManifest;
import hirs.persist.DBManagerException;
import hirs.persist.ReferenceManifestManager;
import hirs.persist.CriteriaModifier;
import hirs.data.persist.ReferenceManifest; import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.SupportReferenceManifest;
import hirs.data.persist.SwidResource; import hirs.data.persist.SwidResource;
import hirs.data.persist.certificate.Certificate; import hirs.data.persist.certificate.Certificate;
import java.io.IOException; import hirs.persist.CriteriaModifier;
import java.net.URISyntaxException; import hirs.persist.DBManagerException;
import hirs.persist.ReferenceManifestManager;
import java.text.DateFormat; import org.apache.commons.codec.binary.Base64;
import java.text.ParseException; import org.apache.commons.codec.binary.Hex;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.hibernate.Criteria; import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -50,6 +36,21 @@ import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.RedirectView; import org.springframework.web.servlet.view.RedirectView;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URISyntaxException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
* Controller for the Reference Manifest page. * Controller for the Reference Manifest page.
*/ */
@ -437,19 +438,34 @@ public class ReferenceManifestPageController
ReferenceManifest existingManifest; ReferenceManifest existingManifest;
MessageDigest digest = null;
String rimHash = "";
try {
digest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException noSaEx) {
LOGGER.error(noSaEx);
}
// look for existing manifest in the database // look for existing manifest in the database
try { try {
if (supportRim) { if (supportRim) {
if (digest != null) {
rimHash = Hex.encodeHexString(
digest.digest(referenceManifest.getRimBytes()));
}
existingManifest = SupportReferenceManifest existingManifest = SupportReferenceManifest
.select(referenceManifestManager) .select(referenceManifestManager)
.byHexDecHash(rimHash)
.includeArchived() .includeArchived()
.byHashCode(referenceManifest.getRimHash())
.getRIM(); .getRIM();
} else { } else {
if (digest != null) {
rimHash = Base64.encodeBase64String(
digest.digest(referenceManifest.getRimBytes()));
}
existingManifest = BaseReferenceManifest existingManifest = BaseReferenceManifest
.select(referenceManifestManager) .select(referenceManifestManager).byBase64Hash(rimHash)
.includeArchived() .includeArchived()
.byHashCode(referenceManifest.getRimHash())
.getRIM(); .getRIM();
} }
} catch (DBManagerException e) { } catch (DBManagerException e) {

View File

@ -241,6 +241,10 @@
<div class="row"> <div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Base/Support</span></div> <div class="col-md-1 col-md-offset-1"><span class="colHeader">Base/Support</span></div>
<div id="measurements" class="col col-md-8"> <div id="measurements" class="col col-md-8">
<c:if test="${not empty initialData.hostName}">
<div><span>${initialData.hostName}</span>
</div>
</c:if>
<c:if test="${not empty initialData.tagId}"> <c:if test="${not empty initialData.tagId}">
<div>Base:&nbsp;<span><a href="${portal}/rim-details?id=${initialData.baseId}">${initialData.tagId}</a></span> <div>Base:&nbsp;<span><a href="${portal}/rim-details?id=${initialData.baseId}">${initialData.tagId}</a></span>
</div> </div>
@ -253,60 +257,47 @@
</div> </div>
<br /> <br />
<div class="row" style="margin: auto 260px auto 125px"> <div class="row" style="margin: auto 260px auto 125px">
<div class="panel panel-default" style="flex: 1">
<div class="panel-heading">Support</div>
<c:if test="${not empty initialData.supportEvents}">
<c:forEach items="${initialData.supportEvents}" var="sEvent">
<div class="event-element">
<div class="event-data">
<div class="data-label">Event#:</div>
<div class="data-value">${sEvent.getEventNumber()+1}</div>
</div>
<div class="event-data">
<div class="data-label">PCR Index:</div>
<div class="data-value">${sEvent.getPcrIndex()}</div>
</div>
<div class="event-data">
<div class="data-label">Digest:</div>
<div class="data-value">${sEvent.getEventDigestStr()}</div>
</div>
<div class="event-data">
<div class="data-label">Content:</div>
<div class="data-value">${sEvent.getEventContentStr()}</div>
</div>
</div>
</c:forEach>
</c:if>
</div>
<div class="panel panel-default" style="flex: 1"> <div class="panel panel-default" style="flex: 1">
<div class="panel-heading">Client Log</div> <div class="panel-heading">Client Log</div>
<c:if test="${not empty initialData.livelogEvents}"> <c:if test="${not empty initialData.livelogEvents}">
<c:set var="iterator" value="0" scope="page"/>
<c:forEach items="${initialData.livelogEvents}" var="lEvent"> <c:forEach items="${initialData.livelogEvents}" var="lEvent">
<div class="event-element"> <div>
<div class="event-data"> <div style="display: flex; background: lightgray;">
<div class="data-label">Event#:</div> <div style="display: flex 1; margin: auto 1rem auto 1rem">Failed<br />Digest:</div>
<div class="data-value">${lEvent.getEventNumber()+1}</div> <div style="display: flex 2; margin: 2px auto 2px 25px">
</div> ${lEvent.getEventDigestStr()}<br />${lEvent.getEventContentStr()}
<div class="event-data"> </div>
<div class="data-label">PCR Index:</div>
<div class="data-value">${lEvent.getPcrIndex()}</div>
</div>
<div class="event-data">
<div class="data-label">Digest:</div>
<div class="data-value">${lEvent.getEventDigestStr()}</div>
</div>
<div class="event-data">
<div class="data-label">Content:</div>
<div class="data-value">${lEvent.getEventContentStr()}</div>
</div> </div>
</div> </div>
<div style="display: flex;">
<div class="mappedButton">
Baseline Events of Type:<br />
<a role="button" data-toggle="collapse" href="#eventContent${iterator}">${lEvent.getEventTypeString()}</a>
</div>
<div id="eventContent${iterator}" class="panel-collapse collapse in" style="flex: 2">
<c:forEach items="${initialData.eventTypeMap}" var="mappedDigest">
<c:if test="${mappedDigest.key == lEvent.getEventDigestStr()}">
<c:set var="event" value="${mappedDigest.value}" scope="page"/>
<c:forEach items="${mappedDigest.value}" var="event">
<div class="mappedOverhead">
<div><span class="mappedData">PCR Index:</span> ${event.getPcrIndex()}</div>
<div><span class="mappedData">Digest:</span> ${event.getEventDigestStr()}</div>
<div><span class="mappedData">Event Content:</span> ${event.getEventContentStr()}</div>
</div>
</c:forEach>
</c:if>
</c:forEach>
</div>
</div>
<c:set var="iterator" value="${iterator+1}" scope="page"/>
</c:forEach> </c:forEach>
</c:if> </c:if>
</div> </div>
</div> </div>
</div> </div>
</c:when> </c:when>
<c:otherwise> <c:when test="${initialData.rimType=='Base'}">
<div class="row"> <div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Software Identity</span></div> <div class="col-md-1 col-md-offset-1"><span class="colHeader">Software Identity</span></div>
<div id="softwareIdentity" class="col col-md-8"> <div id="softwareIdentity" class="col col-md-8">
@ -343,7 +334,17 @@
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Link</span></div> <div class="col-md-1 col-md-offset-1"><span class="colHeader">Link</span></div>
<div id="link" class="col col-md-8"> <div id="link" class="col col-md-8">
<c:if test="${not empty initialData.linkHref}"> <c:if test="${not empty initialData.linkHref}">
<div><span><a href="${portal}/rim-details?id=${initialData.linkHrefLink}" rel="${initialData.linkRel}">${initialData.linkHref}</a></span> <div>
<span>
<c:choose>
<c:when test="${initialData.linkRel=='requires'}">
<a href="${portal}/rim-details?id=${initialData.linkHrefLink}" rel="${initialData.linkRel}">${initialData.linkHref}</a>
</c:when>
<c:otherwise>
<a href="${initialData.linkHref}" rel="${initialData.linkRel}">${initialData.linkHref}</a>
</c:otherwise>
</c:choose>
</span>
</div> </div>
<div>Rel:&nbsp;<span>${initialData.linkRel}</span> <div>Rel:&nbsp;<span>${initialData.linkRel}</span>
</div> </div>
@ -375,7 +376,15 @@
<c:if test="${not empty initialData.pcUriLocal}"> <c:if test="${not empty initialData.pcUriLocal}">
<div>PC URI Local:&nbsp;<span>${initialData.pcUriLocal}</span></div> <div>PC URI Local:&nbsp;<span>${initialData.pcUriLocal}</span></div>
</c:if> </c:if>
<div>Rim Link Hash:&nbsp;<span>${initialData.rimLinkHash}</span> <c:choose>
<c:when test="${not empty initialData.rimLinkId}">
<div>Rim Link Hash:&nbsp;<span><a href="${portal}/rim-details?id=${initialData.rimLinkId}">${initialData.rimLinkHash}</a></span>
</c:when>
<c:otherwise>
<div>Rim Link Hash:&nbsp;<span>${initialData.rimLinkHash}</span>
</c:otherwise>
</c:choose>
<c:if test="${not empty initialData.rimLinkHash}">
<span> <span>
<c:choose> <c:choose>
<c:when test="${initialData.linkHashValid}"> <c:when test="${initialData.linkHashValid}">
@ -386,6 +395,7 @@
</c:otherwise> </c:otherwise>
</c:choose> </c:choose>
</span> </span>
</c:if>
</div> </div>
</div> </div>
</div> </div>
@ -531,6 +541,8 @@
</div> </div>
</div> </div>
</div> </div>
</c:when>
<c:otherwise>
</c:otherwise> </c:otherwise>
</c:choose> </c:choose>
</div> </div>

View File

@ -81,4 +81,28 @@
.data-value { .data-value {
flex: 5 flex: 5
}
.mappedType {
display: flex 1;
padding: 1rem;
width: 20rem;
font-weight: bold
}
.mappedOverhead {
display: flex;
flex-direction: column;
padding: 1rem;
}
.mappedData {
font-weight: bold;
}
.mappedButton {
display: flex 1;
padding: 1rem;
width: 20rem;
font-weight: bold;
} }

View File

@ -1,5 +1,6 @@
package hirs.data.persist; package hirs.data.persist;
import com.fasterxml.jackson.annotation.JsonIgnore;
import hirs.persist.DBReferenceManifestManager; import hirs.persist.DBReferenceManifestManager;
import hirs.persist.ReferenceManifestManager; import hirs.persist.ReferenceManifestManager;
import hirs.persist.ReferenceManifestSelector; import hirs.persist.ReferenceManifestSelector;
@ -25,7 +26,10 @@ import javax.xml.validation.Schema;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -35,9 +39,16 @@ import java.util.Map;
@Entity @Entity
public class BaseReferenceManifest extends ReferenceManifest { public class BaseReferenceManifest extends ReferenceManifest {
private static final Logger LOGGER = LogManager.getLogger(BaseReferenceManifest.class); private static final Logger LOGGER = LogManager.getLogger(BaseReferenceManifest.class);
/**
* Holds the name of the 'base64Hash' field.
*/
public static final String BASE_64_HASH_FIELD = "base64Hash";
private static JAXBContext jaxbContext; private static JAXBContext jaxbContext;
@Column
@JsonIgnore
private String base64Hash = "";
@Column @Column
private String swidName = null; private String swidName = null;
@Column @Column
@ -100,24 +111,23 @@ public class BaseReferenceManifest extends ReferenceManifest {
} }
/** /**
* Specify the platform manufacturer id that rims must have to be considered * Specify the device name that rims must have to be considered
* as matching. * as matching.
* @param manufacturerId string for the id of the manufacturer * @param deviceName string for the deviceName
* @return this instance * @return this instance
*/ */
public Selector byManufacturerId(final String manufacturerId) { public Selector byDeviceName(final String deviceName) {
setFieldValue(PLATFORM_MANUFACTURER_ID, manufacturerId); setFieldValue("deviceName", deviceName);
return this; return this;
} }
/** /**
* Specify the platform model that rims must have to be considered * Specify the RIM hash associated with the base RIM.
* as matching. * @param base64Hash the hash of the file associated with the rim
* @param model string for the model
* @return this instance * @return this instance
*/ */
public Selector byModel(final String model) { public Selector byBase64Hash(final String base64Hash) {
setFieldValue(PLATFORM_MODEL, model); setFieldValue(BASE_64_HASH_FIELD, base64Hash);
return this; return this;
} }
} }
@ -148,6 +158,16 @@ public class BaseReferenceManifest extends ReferenceManifest {
this.setFileName(""); this.setFileName("");
SoftwareIdentity si = validateSwidTag(new ByteArrayInputStream(rimBytes)); SoftwareIdentity si = validateSwidTag(new ByteArrayInputStream(rimBytes));
MessageDigest digest = null;
this.base64Hash = "";
try {
digest = MessageDigest.getInstance("SHA-256");
this.base64Hash = Base64.getEncoder().encodeToString(
digest.digest(rimBytes));
} catch (NoSuchAlgorithmException noSaEx) {
LOGGER.error(noSaEx);
}
// begin parsing valid swid tag // begin parsing valid swid tag
if (si != null) { if (si != null) {
setTagId(si.getTagId()); setTagId(si.getTagId());
@ -757,6 +777,15 @@ public class BaseReferenceManifest extends ReferenceManifest {
this.pcURILocal = pcURILocal; this.pcURILocal = pcURILocal;
} }
/**
* Getter for the Reference Integrity Manifest hash value.
*
* @return int representation of the hash value
*/
public String getBase64Hash() {
return base64Hash;
}
@Override @Override
public String toString() { public String toString() {
return String.format("ReferenceManifest{swidName=%s," return String.format("ReferenceManifest{swidName=%s,"
@ -764,6 +793,6 @@ public class BaseReferenceManifest extends ReferenceManifest {
+ " platformModel=%s," + " platformModel=%s,"
+ "tagId=%s, rimHash=%s}", + "tagId=%s, rimHash=%s}",
swidName, this.getPlatformManufacturer(), swidName, this.getPlatformManufacturer(),
this.getPlatformModel(), getTagId(), this.getRimHash()); this.getPlatformModel(), getTagId(), this.getBase64Hash());
} }
} }

View File

@ -58,24 +58,13 @@ public class EventLogMeasurements extends ReferenceManifest {
} }
/** /**
* Specify the platform manufacturer id that rims must have to be considered * Specify the device name that rims must have to be considered
* as matching. * as matching.
* @param manufacturerId string for the id of the manufacturer * @param deviceName string for the deviceName
* @return this instance * @return this instance
*/ */
public Selector byManufacturerId(final String manufacturerId) { public Selector byDeviceName(final String deviceName) {
setFieldValue(PLATFORM_MANUFACTURER_ID, manufacturerId); setFieldValue("deviceName", deviceName);
return this;
}
/**
* Specify the platform model that rims must have to be considered
* as matching.
* @param model string for the model
* @return this instance
*/
public Selector byModel(final String model) {
setFieldValue(PLATFORM_MODEL, model);
return this; return this;
} }
} }

View File

@ -28,6 +28,8 @@ public class ReferenceDigestRecord extends ArchivableEntity {
private String manufacturer; private String manufacturer;
@Column(nullable = false) @Column(nullable = false)
private String model; private String model;
@Column(nullable = false)
private String deviceName;
@Column(columnDefinition = "blob", nullable = true) @Column(columnDefinition = "blob", nullable = true)
private byte[] valueBlob; private byte[] valueBlob;
@ -134,6 +136,22 @@ public class ReferenceDigestRecord extends ArchivableEntity {
this.model = model; this.model = model;
} }
/**
* Getter for the deviceName associated.
* @return the string of the deviceName
*/
public String getDeviceName() {
return deviceName;
}
/**
* Setter for the deviceName associated.
* @param deviceName the string of the model
*/
public void setDeviceName(final String deviceName) {
this.deviceName = deviceName;
}
/** /**
* Getter for the byte array of event values. * Getter for the byte array of event values.
* @return a clone of the byte array * @return a clone of the byte array
@ -158,7 +176,7 @@ public class ReferenceDigestRecord extends ArchivableEntity {
*/ */
@Override @Override
public String toString() { public String toString() {
return String.format("ReferenceDigestRecord: %s%n%s -> %s", return String.format("ReferenceDigestRecord: %s%n%s::%s::%s",
super.toString(), this.manufacturer, this.model); super.toString(), this.manufacturer, this.model, this.deviceName);
} }
} }

View File

@ -2,7 +2,6 @@ package hirs.data.persist;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import org.apache.commons.codec.binary.Hex;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.hibernate.annotations.Type; import org.hibernate.annotations.Type;
@ -16,8 +15,6 @@ import javax.xml.XMLConstants;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays; import java.util.Arrays;
import java.util.UUID; import java.util.UUID;
@ -64,13 +61,6 @@ public abstract class ReferenceManifest extends ArchivableEntity {
private static final Logger LOGGER = LogManager.getLogger(ReferenceManifest.class); private static final Logger LOGGER = LogManager.getLogger(ReferenceManifest.class);
/**
* Holds the name of the 'rimHash' field.
*/
public static final String RIM_HASH_FIELD = "rimHash";
@Column(nullable = false)
@JsonIgnore
private final String rimHash;
@Column(columnDefinition = "blob", nullable = false) @Column(columnDefinition = "blob", nullable = false)
@JsonIgnore @JsonIgnore
private byte[] rimBytes; private byte[] rimBytes;
@ -97,6 +87,9 @@ public abstract class ReferenceManifest extends ArchivableEntity {
@Type(type = "uuid-char") @Type(type = "uuid-char")
@Column @Column
private UUID associatedRim; private UUID associatedRim;
@Column
@JsonIgnore
private String deviceName;
/** /**
* Default constructor necessary for Hibernate. * Default constructor necessary for Hibernate.
@ -104,7 +97,6 @@ public abstract class ReferenceManifest extends ArchivableEntity {
protected ReferenceManifest() { protected ReferenceManifest() {
super(); super();
this.rimBytes = null; this.rimBytes = null;
this.rimHash = "";
this.rimType = null; this.rimType = null;
this.platformManufacturer = null; this.platformManufacturer = null;
this.platformManufacturerId = null; this.platformManufacturerId = null;
@ -126,19 +118,6 @@ public abstract class ReferenceManifest extends ArchivableEntity {
"Cannot construct a RIM from an empty byte array"); "Cannot construct a RIM from an empty byte array");
this.rimBytes = rimBytes.clone(); this.rimBytes = rimBytes.clone();
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));
}
} }
/** /**
@ -212,7 +191,7 @@ public abstract class ReferenceManifest extends ArchivableEntity {
} }
/** /**
* Getter for the RIM Type (Primary, Supplemental, Patch). * Getter for the RIM Type (Base, Support, Measurement).
* *
* @return string for the RIM Type * @return string for the RIM Type
*/ */
@ -335,6 +314,22 @@ public abstract class ReferenceManifest extends ArchivableEntity {
this.associatedRim = associatedRim; this.associatedRim = associatedRim;
} }
/**
* Getter for the Device Name.
* @return string value of the device associated with this log.
*/
public String getDeviceName() {
return deviceName;
}
/**
* Setter for the Device Name.
* @param deviceName new value to assign.
*/
public void setDeviceName(final String deviceName) {
this.deviceName = deviceName;
}
/** /**
* Getter for the Reference Integrity Manifest as a byte array. * Getter for the Reference Integrity Manifest as a byte array.
* *
@ -348,15 +343,6 @@ public abstract class ReferenceManifest extends ArchivableEntity {
return null; return null;
} }
/**
* Getter for the Reference Integrity Manifest hash value.
*
* @return int representation of the hash value
*/
public String getRimHash() {
return rimHash;
}
@Override @Override
public int hashCode() { public int hashCode() {
return Arrays.hashCode(this.rimBytes); return Arrays.hashCode(this.rimBytes);
@ -374,8 +360,7 @@ public abstract class ReferenceManifest extends ArchivableEntity {
return false; return false;
} }
ReferenceManifest that = (ReferenceManifest) object; ReferenceManifest that = (ReferenceManifest) object;
return rimHash == that.rimHash return Arrays.equals(rimBytes, that.rimBytes)
&& Arrays.equals(rimBytes, that.rimBytes)
&& rimType.equals(that.rimType) && rimType.equals(that.rimType)
&& tagId.equals(that.tagId) && tagId.equals(that.tagId)
&& platformManufacturer.equals(that.platformManufacturer) && platformManufacturer.equals(that.platformManufacturer)
@ -387,8 +372,7 @@ public abstract class ReferenceManifest extends ArchivableEntity {
@Override @Override
public String toString() { public String toString() {
return String.format("Filename->%s%nPlatform Manufacturer->%s%n" return String.format("Filename->%s%nPlatform Manufacturer->%s%n"
+ "Platform Model->%s%nRIM Type->%s%nRIM Hash->%s", this.getFileName(), + "Platform Model->%s%nRIM Type->%s%nRIM", this.getFileName(),
this.platformManufacturer, this.platformModel, this.getRimType(), this.platformManufacturer, this.platformModel, this.getRimType());
this.getRimHash());
} }
} }

View File

@ -5,12 +5,14 @@ import hirs.persist.ReferenceManifestManager;
import hirs.persist.ReferenceManifestSelector; import hirs.persist.ReferenceManifestSelector;
import hirs.tpm.eventlog.TCGEventLog; import hirs.tpm.eventlog.TCGEventLog;
import hirs.tpm.eventlog.TpmPcrEvent; import hirs.tpm.eventlog.TpmPcrEvent;
import org.apache.commons.codec.binary.Hex;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import java.io.IOException; import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.util.ArrayList; import java.util.ArrayList;
@ -23,7 +25,14 @@ import java.util.Collection;
@Entity @Entity
public class SupportReferenceManifest extends ReferenceManifest { public class SupportReferenceManifest extends ReferenceManifest {
private static final Logger LOGGER = LogManager.getLogger(SupportReferenceManifest.class); private static final Logger LOGGER = LogManager.getLogger(SupportReferenceManifest.class);
/**
* Holds the name of the 'hexDecHash' field.
*/
public static final String HEX_DEC_HASH_FIELD = "hexDecHash";
@Column
@JsonIgnore
private String hexDecHash = "";
@Column @Column
@JsonIgnore @JsonIgnore
private int pcrHash = 0; private int pcrHash = 0;
@ -60,24 +69,13 @@ public class SupportReferenceManifest extends ReferenceManifest {
} }
/** /**
* Specify the platform manufacturer id that rims must have to be considered * Specify the device name that rims must have to be considered
* as matching. * as matching.
* @param manufacturerId string for the id of the manufacturer * @param deviceName string for the deviceName
* @return this instance * @return this instance
*/ */
public Selector byManufacturerId(final String manufacturerId) { public Selector byDeviceName(final String deviceName) {
setFieldValue(PLATFORM_MANUFACTURER_ID, manufacturerId); setFieldValue("deviceName", deviceName);
return this;
}
/**
* Specify the platform model that rims must have to be considered
* as matching.
* @param model string for the model
* @return this instance
*/
public Selector byModel(final String model) {
setFieldValue(PLATFORM_MODEL, model);
return this; return this;
} }
@ -93,11 +91,11 @@ public class SupportReferenceManifest extends ReferenceManifest {
/** /**
* Specify the RIM hash associated with the support RIM. * Specify the RIM hash associated with the support RIM.
* @param rimHash the hash of the file associated with the rim * @param hexDecHash the hash of the file associated with the rim
* @return this instance * @return this instance
*/ */
public Selector byRimHash(final String rimHash) { public Selector byHexDecHash(final String hexDecHash) {
setFieldValue(RIM_HASH_FIELD, rimHash); setFieldValue(HEX_DEC_HASH_FIELD, hexDecHash);
return this; return this;
} }
} }
@ -116,6 +114,15 @@ public class SupportReferenceManifest extends ReferenceManifest {
this.setFileName(fileName); this.setFileName(fileName);
this.setRimType(SUPPORT_RIM); this.setRimType(SUPPORT_RIM);
this.pcrHash = 0; this.pcrHash = 0;
MessageDigest digest = null;
this.hexDecHash = "";
try {
digest = MessageDigest.getInstance("SHA-256");
this.hexDecHash = Hex.encodeHexString(
digest.digest(rimBytes));
} catch (NoSuchAlgorithmException noSaEx) {
LOGGER.error(noSaEx);
}
} }
/** /**
@ -246,4 +253,13 @@ public class SupportReferenceManifest extends ReferenceManifest {
public boolean isBaseSupport() { public boolean isBaseSupport() {
return !this.isSwidSupplemental() && !this.isSwidPatch(); return !this.isSwidSupplemental() && !this.isSwidPatch();
} }
/**
* Getter for the Reference Integrity Manifest hash value.
*
* @return int representation of the hash value
*/
public String getHexDecHash() {
return hexDecHash;
}
} }

View File

@ -108,6 +108,28 @@ public class DBReferenceDigestManager extends DBManager<ReferenceDigestRecord>
return dbRecord; return dbRecord;
} }
@Override
public List<ReferenceDigestRecord> getRecordsByDeviceName(final String deviceName) {
LOGGER.debug("Getting record for {}", deviceName);
if (deviceName == null) {
LOGGER.error("No deviceName to get record from db");
return null;
}
List<ReferenceDigestRecord> dbRecords = new ArrayList<>();
try {
List<ReferenceDigestRecord> dbTempList = super.getList(ReferenceDigestRecord.class);
for (ReferenceDigestRecord rdr : dbTempList) {
if (rdr.getDeviceName().equals(deviceName)) {
dbRecords.add(rdr);
}
}
} catch (DBManagerException dbMEx) {
throw new RuntimeException(dbMEx);
}
return dbRecords;
}
@Override @Override
public ReferenceDigestRecord getRecordById(final ReferenceDigestRecord referenceDigestRecord) { public ReferenceDigestRecord getRecordById(final ReferenceDigestRecord referenceDigestRecord) {
LOGGER.debug("Getting record for {}", referenceDigestRecord); LOGGER.debug("Getting record for {}", referenceDigestRecord);

View File

@ -37,6 +37,14 @@ public interface ReferenceDigestManager {
*/ */
ReferenceDigestRecord getRecord(String manufacturer, String model); ReferenceDigestRecord getRecord(String manufacturer, String model);
/**
* Persists a new Reference Digest.
*
* @param deviceName the string of the network hostname
* @return the persisted ReferenceDigestRecord list
*/
List<ReferenceDigestRecord> getRecordsByDeviceName(String deviceName);
/** /**
* Persists a new Reference Digest. * Persists a new Reference Digest.
* *

View File

@ -97,17 +97,6 @@ public abstract class ReferenceManifestSelector<T extends ReferenceManifest> {
return this; return this;
} }
/**
* Specify the hash code of the bytes that rim must match.
*
* @param rimHash the hash code of the bytes to query for
* @return this instance (for chaining further calls)
*/
public ReferenceManifestSelector<T> byHashCode(final String rimHash) {
setFieldValue(hirs.data.persist.ReferenceManifest.RIM_HASH_FIELD, rimHash);
return this;
}
/** /**
* Specify the file name of the object to grab. * Specify the file name of the object to grab.
* @param fileName the name of the file associated with the rim * @param fileName the name of the file associated with the rim

View File

@ -1,17 +1,7 @@
package hirs.tpm.eventlog; package hirs.tpm.eventlog;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import hirs.tpm.eventlog.events.EvConstants;
import hirs.tpm.eventlog.events.EvCompactHash; import hirs.tpm.eventlog.events.EvCompactHash;
import hirs.tpm.eventlog.events.EvConstants;
import hirs.tpm.eventlog.events.EvEfiBootServicesApp; import hirs.tpm.eventlog.events.EvEfiBootServicesApp;
import hirs.tpm.eventlog.events.EvEfiGptPartition; import hirs.tpm.eventlog.events.EvEfiGptPartition;
import hirs.tpm.eventlog.events.EvEfiHandoffTable; import hirs.tpm.eventlog.events.EvEfiHandoffTable;
@ -30,6 +20,16 @@ import org.apache.commons.codec.binary.Hex;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Arrays;
/** /**
* Class to process a TCG_PCR_EVENT. * Class to process a TCG_PCR_EVENT.
* TCG_PCR_EVENT is used when the Event log uses the SHA1 Format as described in the * TCG_PCR_EVENT is used when the Event log uses the SHA1 Format as described in the
@ -211,6 +211,14 @@ public class TpmPcrEvent {
return String.format("0x%s %s", Long.toHexString(eventType), eventString((int) eventType)); return String.format("0x%s %s", Long.toHexString(eventType), eventString((int) eventType));
} }
/**
* Returns a formatted string of the type for the event minus the byte code.
* @return a string formatted to be human readable
*/
public String getEventTypeString() {
return eventString((int) eventType);
}
/** /**
* Returns the version of the TCG Log Event specification pertaining to the log. * Returns the version of the TCG Log Event specification pertaining to the log.
* only updated if the event is a TCG_EfiSpecIdEvent. * only updated if the event is a TCG_EfiSpecIdEvent.