This commit has some changes to how patch and supplemental are handled. It adds some flags to the Record and Value objects to note that data has been processed so that multiple entries aren't created.

This commit is contained in:
Cyrus 2021-04-13 07:45:52 -04:00
parent 6d435f9783
commit e70e019c6b
6 changed files with 189 additions and 93 deletions

View File

@ -97,6 +97,7 @@ import java.security.spec.RSAPublicKeySpec;
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;
@ -824,8 +825,8 @@ public abstract class AbstractAttestationCertificateAuthority
} catch (IOException ioEx) {
LOG.error(ioEx);
} catch (Exception ex) {
LOG.error(String.format("Failed to load support rim: ", messageDigest.digest(
logFile.toByteArray())));
LOG.error(String.format("Failed to load support rim: %s", messageDigest.digest(
logFile.toByteArray()).toString()));
}
}
} else {
@ -903,56 +904,7 @@ public abstract class AbstractAttestationCertificateAuthority
LOG.warn("Device did not send swid tag file...");
}
Set<SupportReferenceManifest> dbSupportRims = SupportReferenceManifest
.select(referenceManifestManager).getRIMs();
for (SupportReferenceManifest dbSupport : dbSupportRims) {
/**
* Because the log file we get isn't promised to be the baseline support rim.
* If it is a patch of supplemental we have to check that the baseline
* has been done
* and those entries can't become the baseline
*
* However, we don't know which log file is what until we link them to a swidtag
*/
if (!dbSupport.isSwidPatch() && !dbSupport.isSwidSupplemental()) {
ReferenceDigestRecord dbObj = new ReferenceDigestRecord(dbSupport,
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(dbSupport.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 e) {
e.printStackTrace();
}
}
} else {
// what to do about patch and supplemental
LOG.error(String.format("%s is a patch? %b", dbSupport.getFileName(),
dbSupport.isSwidPatch()));
LOG.error(String.format("%s is a supplemental? %b", dbSupport.getFileName(),
dbSupport.isSwidSupplemental()));
}
}
generateDigestRecords(hw.getManufacturer(), hw.getProductName());
if (dv.hasLivelog()) {
LOG.info("Device sent bios measurement log...");
@ -999,6 +951,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) {
/**
* Because the log file we get isn't promised to be the baseline support rim.
* If it is a patch of supplemental we have to check that the baseline
* has been done
* and those entries can't become the baseline
*
* However, we don't know which log file is what until we link them to a swidtag
*/
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 = null;

View File

@ -306,17 +306,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;
}
}
}

View File

@ -411,20 +411,20 @@
</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/>
<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>
@ -455,7 +455,9 @@
</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>

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

@ -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.
@ -219,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

@ -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) {