This commit adds functionality to display tpm even log information to the support RIM display page. Outstanding issues to implement: 1) add link to base from support RIM, 2) make event table scrollable

This commit is contained in:
Cyrus 2020-09-24 09:58:10 -04:00
parent 39cfaa5fac
commit 3636782987
17 changed files with 1208 additions and 715 deletions

View File

@ -9,6 +9,7 @@ import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.TPMMeasurementRecord; import hirs.data.persist.TPMMeasurementRecord;
import hirs.data.persist.SwidResource; import hirs.data.persist.SwidResource;
import hirs.data.persist.PCRPolicy; import hirs.data.persist.PCRPolicy;
@ -335,13 +336,9 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
fwStatus = new AppraisalStatus(PASS, fwStatus = new AppraisalStatus(PASS,
SupplyChainCredentialValidator.FIRMWARE_VALID); SupplyChainCredentialValidator.FIRMWARE_VALID);
if (rim == null) { if (rim instanceof BaseReferenceManifest) {
fwStatus = new AppraisalStatus(FAIL, BaseReferenceManifest bRim = (BaseReferenceManifest) rim;
String.format("Firmware validation failed: " List<SwidResource> swids = bRim.parseResource();
+ "No associated RIM file could be found for %s",
manufacturer));
} else {
List<SwidResource> swids = rim.parseResource();
for (SwidResource swid : swids) { for (SwidResource swid : swids) {
baseline = swid.getPcrValues() baseline = swid.getPcrValues()
.toArray(new String[swid.getPcrValues().size()]); .toArray(new String[swid.getPcrValues().size()]);
@ -413,6 +410,11 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
fwStatus = new AppraisalStatus(FAIL, "Associated Issued Attestation" fwStatus = new AppraisalStatus(FAIL, "Associated Issued Attestation"
+ " Certificate can not be found."); + " Certificate can not be found.");
} }
} else {
fwStatus = new AppraisalStatus(FAIL,
String.format("Firmware validation failed: "
+ "No associated RIM file could be found for %s",
manufacturer));
} }
return buildValidationRecord(SupplyChainValidation.ValidationType.FIRMWARE, return buildValidationRecord(SupplyChainValidation.ValidationType.FIRMWARE,

View File

@ -6,5 +6,4 @@
<suppressions> <suppressions>
<suppress checks="MagicNumber" files=".*[/\\]src[/\\]test[/\\]+" /> <suppress checks="MagicNumber" files=".*[/\\]src[/\\]test[/\\]+" />
<suppress checks="AvoidInlineConditionals" files=".*[/\\]src[/\\]test[/\\]+" />
</suppressions> </suppressions>

View File

@ -27,7 +27,7 @@ public final class DataTableResponse<T> {
/** /**
* Builds a data table response using a FilteredRecordList. * Builds a data table response using a FilteredRecordList.
* @param recordList the filtered recordd list * @param recordList the filtered record list
* @param inputQuery the data table input (used for draw) * @param inputQuery the data table input (used for draw)
*/ */
public DataTableResponse(final FilteredRecordsList<T> recordList, public DataTableResponse(final FilteredRecordsList<T> recordList,

View File

@ -1,7 +1,10 @@
package hirs.attestationca.portal.page.controllers; package hirs.attestationca.portal.page.controllers;
import hirs.data.persist.BaseReferenceManifest;
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.persist.DBManagerException;
import hirs.persist.ReferenceManifestManager; import hirs.persist.ReferenceManifestManager;
import hirs.tpm.eventlog.TCGEventLog; import hirs.tpm.eventlog.TCGEventLog;
import hirs.attestationca.portal.page.Page; import hirs.attestationca.portal.page.Page;
@ -10,9 +13,6 @@ import hirs.attestationca.portal.page.PageMessages;
import hirs.attestationca.portal.page.params.ReferenceManifestDetailsPageParams; import hirs.attestationca.portal.page.params.ReferenceManifestDetailsPageParams;
import java.io.IOException; import java.io.IOException;
import java.nio.file.NoSuchFileException; import java.nio.file.NoSuchFileException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.util.Arrays; import java.util.Arrays;
@ -20,6 +20,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.UUID; import java.util.UUID;
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.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -53,6 +54,7 @@ public class ReferenceManifestDetailsPageController
} }
/** /**
* Returns the filePath for the view and the data model for the page.
* *
* @param params The object to map url parameters into. * @param params The object to map url parameters into.
* @param model The data model for the request. Can contain data from * @param model The data model for the request. Can contain data from
@ -120,72 +122,75 @@ public class ReferenceManifestDetailsPageController
.select(referenceManifestManager) .select(referenceManifestManager)
.byEntityId(uuid).getRIM(); .byEntityId(uuid).getRIM();
if (rim != null) { if (rim instanceof BaseReferenceManifest) {
BaseReferenceManifest bRim = (BaseReferenceManifest) rim;
// Software Identity // Software Identity
data.put("swidName", rim.getSwidName()); data.put("swidName", bRim.getSwidName());
data.put("swidVersion", rim.getSwidVersion()); data.put("swidVersion", bRim.getSwidVersion());
if (rim.isSwidCorpus() == 1) { if (bRim.isSwidCorpus() == 1) {
data.put("swidCorpus", "True"); data.put("swidCorpus", "True");
} else { } else {
data.put("swidCorpus", "False"); data.put("swidCorpus", "False");
} }
if (rim.isSwidPatch() == 1) { if (bRim.isSwidPatch() == 1) {
data.put("swidPatch", "True"); data.put("swidPatch", "True");
} else { } else {
data.put("swidPatch", "False"); data.put("swidPatch", "False");
} }
if (rim.isSwidSupplemental() == 1) { if (bRim.isSwidSupplemental() == 1) {
data.put("swidSupplemental", "True"); data.put("swidSupplemental", "True");
} else { } else {
data.put("swidSupplemental", "False"); data.put("swidSupplemental", "False");
} }
// data.put("swidCorpus", (rim.isSwidCorpus() == 1) ? "True" : "False");
// data.put("swidPatch", (rim.isSwidPatch() == 1) ? "True" : "False");
// data.put("swidSupplemental", (rim.isSwidSupplemental() == 1) ? "True" : "False");
data.put("swidTagId", rim.getTagId()); data.put("swidTagId", rim.getTagId());
// Entity // Entity
data.put("entityName", rim.getEntityName()); data.put("entityName", bRim.getEntityName());
data.put("entityRegId", rim.getEntityRegId()); data.put("entityRegId", bRim.getEntityRegId());
data.put("entityRole", rim.getEntityRole()); data.put("entityRole", bRim.getEntityRole());
data.put("entityThumbprint", rim.getEntityThumbprint()); data.put("entityThumbprint", bRim.getEntityThumbprint());
// Link // Link
data.put("linkHref", rim.getLinkHref()); data.put("linkHref", bRim.getLinkHref());
data.put("linkRel", rim.getLinkRel()); data.put("linkRel", bRim.getLinkRel());
data.put("supportBaseRimId", ""); data.put("supportBaseRimId", "");
data.put("supportBaseRimTagId", ""); data.put("supportBaseRimTagId", "");
data.put("platformManufacturer", rim.getPlatformManufacturer()); data.put("platformManufacturer", bRim.getPlatformManufacturer());
data.put("platformManufacturerId", rim.getPlatformManufacturerId()); data.put("platformManufacturerId", bRim.getPlatformManufacturerId());
data.put("platformModel", rim.getPlatformModel()); data.put("platformModel", bRim.getPlatformModel());
data.put("platformVersion", rim.getPlatformVersion()); data.put("platformVersion", bRim.getPlatformVersion());
data.put("firmwareVersion", rim.getFirmwareVersion()); data.put("firmwareVersion", bRim.getFirmwareVersion());
data.put("payloadType", rim.getPayloadType()); data.put("payloadType", bRim.getPayloadType());
data.put("colloquialVersion", rim.getColloquialVersion()); data.put("colloquialVersion", bRim.getColloquialVersion());
data.put("edition", rim.getEdition()); data.put("edition", bRim.getEdition());
data.put("product", rim.getProduct()); data.put("product", bRim.getProduct());
data.put("revision", rim.getRevision()); data.put("revision", bRim.getRevision());
data.put("bindingSpec", rim.getBindingSpec()); data.put("bindingSpec", bRim.getBindingSpec());
data.put("bindingSpecVersion", rim.getBindingSpecVersion()); data.put("bindingSpecVersion", bRim.getBindingSpecVersion());
data.put("pcUriGlobal", rim.getPcURIGlobal()); data.put("pcUriGlobal", bRim.getPcURIGlobal());
data.put("pcUriLocal", rim.getPcURILocal()); data.put("pcUriLocal", bRim.getPcURILocal());
data.put("rimLinkHash", rim.getRimLinkHash()); data.put("rimLinkHash", bRim.getRimLinkHash());
data.put("rimType", bRim.getRimType());
data.put("associatedRim", bRim.getAssociatedRim());
// checkout later List<SwidResource> resources = bRim.parseResource();
data.put("rimType", rim.getRimType());
List<SwidResource> resources = rim.parseResource();
String resourceFilename = null; String resourceFilename = null;
TCGEventLog logProcessor; TCGEventLog logProcessor;
// going to have to pull the filename and grab that from the DB
// to get the id to make the link
try { try {
for (SwidResource swidRes : resources) { for (SwidResource swidRes : resources) {
resourceFilename = swidRes.getName(); resourceFilename = swidRes.getName();
Path logPath = Paths.get(String.format("%s/%s", ReferenceManifest dbRim = ReferenceManifest.select(
SwidResource.RESOURCE_UPLOAD_FOLDER, referenceManifestManager).byFileName(resourceFilename).getRIM();
resourceFilename));
if (Files.exists(logPath)) { if (dbRim != null) {
logProcessor = new TCGEventLog( logProcessor = new TCGEventLog(dbRim.getRimBytes());
Files.readAllBytes(logPath));
swidRes.setPcrValues(Arrays.asList( swidRes.setPcrValues(Arrays.asList(
logProcessor.getExpectedPCRValues())); logProcessor.getExpectedPCRValues()));
if (bRim.getAssociatedRim() == null) {
bRim.setAssociatedRim(dbRim.getId());
}
} else { } else {
swidRes.setPcrValues(new ArrayList<>()); swidRes.setPcrValues(new ArrayList<>());
} }
@ -194,12 +199,23 @@ public class ReferenceManifestDetailsPageController
LOGGER.error(String.format("File Not found!: %s", LOGGER.error(String.format("File Not found!: %s",
resourceFilename)); resourceFilename));
LOGGER.error(nsfEx); LOGGER.error(nsfEx);
} catch (DBManagerException dbmEx) {
LOGGER.error(dbmEx);
} }
data.put("associatedRim", bRim.getAssociatedRim());
data.put("swidFiles", resources); data.put("swidFiles", resources);
} else if (rim instanceof SupportReferenceManifest) {
SupportReferenceManifest sRim = (SupportReferenceManifest) rim;
data.put("baseRim", sRim.getFileName());
data.put("associatedRim", sRim.getAssociatedRim());
data.put("rimType", sRim.getRimType());
TCGEventLog logProcessor = new TCGEventLog(sRim.getRimBytes());
data.put("events", logProcessor.getEventList());
} else { } else {
LOGGER.error(String.format("Unable to find Reference Integrity " LOGGER.error(String.format("Unable to find Reference Integrity "
+ "Manifest with ID: %s", uuid)); + "Manifest with ID: %s", uuid));
} }
return data; return data;

View File

@ -26,10 +26,9 @@ import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -202,27 +201,54 @@ public class ReferenceManifestPageController
matcher = pattern.matcher(fileName); matcher = pattern.matcher(fileName);
supportRIM = matcher.matches(); supportRIM = matcher.matches();
if (supportRIM) {
filePath = Paths.get(String.format("%s/%s",
SwidResource.RESOURCE_UPLOAD_FOLDER,
file.getOriginalFilename()));
if (Files.notExists(Paths.get(SwidResource.RESOURCE_UPLOAD_FOLDER))) {
Files.createDirectory(Paths.get(SwidResource.RESOURCE_UPLOAD_FOLDER));
}
if (Files.notExists(filePath)) {
Files.createFile(filePath);
}
Files.write(filePath, file.getBytes());
String uploadCompletedMessage = String.format(
"%s successfully uploaded", file.getOriginalFilename());
messages.addSuccess(uploadCompletedMessage);
LOGGER.info(uploadCompletedMessage);
}
//Parse reference manifests //Parse reference manifests
ReferenceManifest rim = parseRIM(file, supportRIM, messages); ReferenceManifest rim = parseRIM(file, supportRIM, messages);
// look for associated base/support
Set<ReferenceManifest> rims = ReferenceManifest
.select(referenceManifestManager).getRIMs();
// update information for associated support rims
if (supportRIM) {
for (ReferenceManifest element : rims) {
if (element instanceof BaseReferenceManifest) {
BaseReferenceManifest bRim = (BaseReferenceManifest) element;
for (SwidResource swid : bRim.parseResource()) {
if (swid.getName().equals(rim.getFileName())) {
rim.setFirmwareVersion(swid.getSize());
rim.setPlatformManufacturer(element.getPlatformManufacturer());
rim.setPlatformModel(element.getPlatformModel());
rim.setTagId(element.getTagId());
rim.setAssociatedRim(element.getId());
break;
}
}
}
}
} else {
BaseReferenceManifest bRim = (BaseReferenceManifest) rim;
for (SwidResource swid : bRim.parseResource()) {
for (ReferenceManifest element : rims) {
if (element instanceof SupportReferenceManifest) {
SupportReferenceManifest sRim = (SupportReferenceManifest) element;
if (swid.getName().equals(sRim.getFileName())) {
sRim.setPlatformManufacturer(bRim.getPlatformManufacturer());
sRim.setPlatformModel(bRim.getPlatformModel());
sRim.setFirmwareVersion(swid.getSize());
sRim.setTagId(bRim.getTagId());
rim.setAssociatedRim(sRim.getId());
try {
referenceManifestManager.update(sRim);
} catch (DBManagerException dbmEx) {
LOGGER.error(String.format("Couldn't update Base RIM %s with "
+ "associated UUID %s", rim.getTagId(),
sRim.getId()), dbmEx);
}
break;
}
}
}
}
}
//Store only if it was parsed //Store only if it was parsed
if (rim != null) { if (rim != null) {
@ -320,6 +346,8 @@ public class ReferenceManifestPageController
fileName.append(".swidTag\""); fileName.append(".swidTag\"");
} else { } else {
// this needs to be updated for support rims // this needs to be updated for support rims
SupportReferenceManifest bRim = (SupportReferenceManifest) referenceManifest;
fileName.append(bRim.getFileName());
} }
// Set filename for download. // Set filename for download.
@ -382,9 +410,9 @@ public class ReferenceManifestPageController
try { try {
if (supportRIM) { if (supportRIM) {
return new SupportReferenceManifest(fileBytes); return new SupportReferenceManifest(fileName, fileBytes);
} else { } else {
return new BaseReferenceManifest(fileBytes); return new BaseReferenceManifest(fileName, fileBytes);
} }
// the this is a List<Object> is object is a JaxBElement that can // the this is a List<Object> is object is a JaxBElement that can
// be matched up to the QName // be matched up to the QName

View File

@ -8,6 +8,7 @@
<my:page> <my:page>
<jsp:attribute name="style"> <jsp:attribute name="style">
<link type="text/css" rel="stylesheet" href="${common}/certificate_details.css"/> <link type="text/css" rel="stylesheet" href="${common}/certificate_details.css"/>
<link type="text/css" rel="stylesheet" href="${common}/rim_details.css"/>
</jsp:attribute> </jsp:attribute>
<jsp:attribute name="pageHeaderTitle"> <jsp:attribute name="pageHeaderTitle">
${initialData.rimType} Reference Integrity Manifest ${initialData.rimType} Reference Integrity Manifest
@ -17,192 +18,267 @@
</jsp:attribute> </jsp:attribute>
<jsp:body> <jsp:body>
<div id="certificate-details-page" class="container-fluid"> <div id="certificate-details-page" class="container-fluid">
<div class="row"> <c:choose>
<c:if test="${initialData.swidSupplemental=='True'}"> <c:when test="${initialData.rimType=='Support'}">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Base RIM</span></div> <div class="row">
<div id="baseRim" class="col col-md-8"> <div class="col-md-1 col-md-offset-1"><span class="colHeader">Base RIM</span></div>
<c:choose> <div id="baseRim" class="col col-md-8">
<c:when test="${not empty initialData.supportBaseRimTagId}"> <c:choose>
<a href="${portal}/rim-details?id=${initialData.supportBaseRimId}"> <c:when test="${not empty initialData.associatedRim}">
${initialData.supportBaseRimTagId} <a href="${portal}/rim-details?id=${initialData.associatedRim}">
</a> ${initialData.associatedRim}
<!-- Event Number, Event Type, Digest (hex), Event Content -->
</c:when>
<c:otherwise>
<div class="component col col-md-10" style="color: red; padding-left: 20px">Base RIM not uploaded from the ACA RIM Page</div>
</c:otherwise>
</c:choose>
</div>
</c:if>
</div>
<div class="row">
<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>SWID Name:&nbsp;<span>${initialData.swidName}</span></div>
<div>SWID Version:&nbsp;<span>${initialData.swidVersion}</span></div>
<div>SWID Tag ID:&nbsp;<span>${initialData.swidTagId}</span></div>
<div>SWID Tag Version:&nbsp;<span></span></div>
<c:if test="${initialData.swidCorpus}">
<div>SWID Corpus:&nbsp;<span><img src="${icons}/ic_checkbox_marked_circle_black_green_24dp.png" title="Corpus Flag"></span>
</div>
</c:if>
<c:if test="${initialData.swidPatch}">
<div>SWID Patch:&nbsp;<span><img src="${icons}/ic_checkbox_marked_circle_black_green_24dp.png" title="Patch Flag"></span>
</div>
</c:if>
<c:if test="${initialData.swidSupplemental}">
<div>SWID Supplemental:&nbsp;<span><img src="${icons}/ic_checkbox_marked_circle_black_green_24dp.png" title="Supplemental Flag"></span>
</div>
</c:if>
</div>
</div>
<div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Entity</span></div>
<div id="entity" class="col col-md-8">
<div>Entity Name:&nbsp;<span>${initialData.entityName}</span></div>
<c:if test="${not empty initialData.entityRegId}">
<div>Entity Reg ID:&nbsp;<span>${initialData.entityRegId}</span></div>
</c:if>
<div>Entity Role:&nbsp;<span>${initialData.entityRole}</span></div>
<div>Entity Thumbprint:&nbsp;<span>${initialData.entityThumbprint}</span></div>
</div>
</div>
<div class="row">
<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>
<div>Rel:&nbsp;<span>${initialData.linkRel}</span>
</div>
</c:if>
</div>
</div>
<div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Meta</span></div>
<div id="link" class="col col-md-8">
<div>Platform Manufacturer ID:&nbsp;<span>${initialData.platformManufacturerId}</span></div>
<div>Platform Manufacturer:&nbsp;<span>${initialData.platformManufacturer}</span></div>
<div>Platform Model:&nbsp;<span>${initialData.platformModel}</span></div>
<c:if test="${not empty initialData.platformVersion}">
<div>Platform Version:&nbsp;<span>${initialData.platformVersion}</span></div>
</c:if>
<div>Colloquial Version:&nbsp;<span>${initialData.colloquialVersion}</span></div>
<div>Edition:&nbsp;<span>${initialData.edition}</span></div>
<div>Product:&nbsp;<span>${initialData.product}</span></div>
<div>Revision:&nbsp;<span>${initialData.revision}</span></div>
<c:if test="${not empty initialData.payloadType}">
<div>Payload Type:&nbsp;<span>${initialData.payloadType}</span></div>
</c:if>
<c:if test="${not empty initialData.firmwareVersion}">
<div>Firmware Version:&nbsp;<span>${initialData.firmwareVersion}</span></div>
</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}">
<div>PC URI Global:&nbsp;<span>${initialData.pcUriGlobal}</span></div>
</c:if>
<c:if test="${not empty initiaData.pcUriLocal}">
<div>PC URI Local:&nbsp;<span>${initialData.pcUriLocal}</span></div>
</c:if>
<div>Rim Link Hash:&nbsp;<span>${initialData.rimLinkHash}</span></div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Payload/Support RIM(s)</span></div>
<div id="platformConfiguration" class="col col-md-8">
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#platformConfiguration" class="collapsed"
href="#directorycollapse" aria-expanded="true" aria-controls="directorycollapse">
Directory
</a>
</h4>
</div>
<div id="directorycollapse" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne" aria-expanded="true">
<div class="panel-body">
<div class="panel-heading" role="tab" id="headingThree">
<h3 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#directorycollapse" class="collapsed"
href="#filescollapse" aria-expanded="false" aria-controls="filescollapse">
Files
</a> </a>
</h3> <!-- Event Number, Event Type, Digest (hex), Event Content -->
</div> </c:when>
<div id="filescollapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingThree" aria-expanded="true"> <c:otherwise>
<c:if test="${not empty initialData.swidFiles}"> <div class="component col col-md-10" style="color: red; padding-left: 20px">Base RIM not uploaded from the ACA RIM Page</div>
<div id="componentIdentifier" class="row"> </c:otherwise>
<c:forEach items="${initialData.swidFiles}" var="resource"> </c:choose>
<div class="component col col-md-10" style="padding-left: 20px"> </div>
<div class="panel panel-default"> </div>
<div class="panel-heading"> <div id="tableDivTag">
<span data-toggle="tooltip" data-placement="top" title="Resource File"> <input type="text" id="eventInput" onkeyup="eventSearch()" placeholder="Search for text..." /><br />
${resource.getName()} <table id="eventLog">
</span> <thead>
</div> <tr class="header">
<c:choose> <th style="width: 5%">Event #</th>
<c:when test="${not empty resource.getPcrValues()}"> <th style="width: 10%">PCR Index</th>
<div class="component col col-md-10"> <th style="width: 20%">Event Type</th>
<span class="fieldHeader">File Size:</span> <th style="width: 20%">Digest</th>
<span class="fieldValue">${resource.getSize()}</span><br/> <th style="width: 50%">Event Content</th>
<span class="fieldHeader">Hash:</span> </tr>
<span class="fieldValue" style="overflow-wrap: break-word">${resource.getHashValue()}</span><br/> </thead>
<c:if test="${not empty resource.getRimFormat()}"> <tbody>
<span class="fieldHeader">RIM Format:</span> <c:if test="${not empty initialData.events}">
<span class="fieldValue">${resource.getRimFormat()}</span><br/> <c:set var="count" value="1" scope="page"/>
</c:if> <c:forEach items="${initialData.events}" var="event">
<c:if test="${not empty resource.getRimType()}"> <tr>
<span class="fieldHeader">RIM Type:</span> <td>${count}</td>
<span class="fieldValue">${resource.getRimType()}</span><br/> <td>${event.getPcrIndex()}</td>
</c:if> <td>${event.getEventTypeStr()}</td>
<c:if test="${not empty resource.getRimUriGlobal()}"> <td>${event.getEventDigestStr()}</td>
<span class="fieldHeader">URI Global:</span> <td>${event.getEventContentStr()}</td>
<span class="fieldValue">${resource.getRimUriGlobal()}</span><br/> </tr>
</c:if> <c:set var="count" value="${count + 1}" scope="page"/>
<c:if test="${not empty resource.getPcrValues()}"> <!-- not status.last ? <hr/> : <br/> -->
<div class="panel-body"> </c:forEach>
<div class="component" role="tab" id="pcrValues"> </c:if>
<a role="button" data-toggle="collapse" data-parent="#directorycollapse" class="collapsed" </tbody>
href="#pcrscollapse" aria-expanded="false" aria-controls="pcrscollapse"> </table>
Expected PCR Values </div>
</a> </c:when>
</div> <c:otherwise>
<div id="pcrscollapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingThree" aria-expanded="true"> <div class="row">
<div> <div class="col-md-1 col-md-offset-1"><span class="colHeader">Software Identity</span></div>
<c:forEach items="${resource.getPcrMap()}" var="pcrValue"> <div id="softwareIdentity" class="col col-md-8">
<div id="componentIdentifier" class="row"> <div>SWID Name:&nbsp;<span>${initialData.swidName}</span></div>
<div>SWID Version:&nbsp;<span>${initialData.swidVersion}</span></div>
<div>SWID Tag ID:&nbsp;<span>${initialData.swidTagId}</span></div>
<div>SWID Tag Version:&nbsp;<span></span></div>
<c:if test="${initialData.swidCorpus}">
<div>SWID Corpus:&nbsp;<span><img src="${icons}/ic_checkbox_marked_circle_black_green_24dp.png" title="Corpus Flag"></span>
</div>
</c:if>
<c:if test="${initialData.swidPatch}">
<div>SWID Patch:&nbsp;<span><img src="${icons}/ic_checkbox_marked_circle_black_green_24dp.png" title="Patch Flag"></span>
</div>
</c:if>
<c:if test="${initialData.swidSupplemental}">
<div>SWID Supplemental:&nbsp;<span><img src="${icons}/ic_checkbox_marked_circle_black_green_24dp.png" title="Supplemental Flag"></span>
</div>
</c:if>
</div>
</div>
<div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Entity</span></div>
<div id="entity" class="col col-md-8">
<div>Entity Name:&nbsp;<span>${initialData.entityName}</span></div>
<c:if test="${not empty initialData.entityRegId}">
<div>Entity Reg ID:&nbsp;<span>${initialData.entityRegId}</span></div>
</c:if>
<div>Entity Role:&nbsp;<span>${initialData.entityRole}</span></div>
<div>Entity Thumbprint:&nbsp;<span>${initialData.entityThumbprint}</span></div>
</div>
</div>
<div class="row">
<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>
<div>Rel:&nbsp;<span>${initialData.linkRel}</span>
</div>
</c:if>
</div>
</div>
<div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Meta</span></div>
<div id="link" class="col col-md-8">
<div>Platform Manufacturer ID:&nbsp;<span>${initialData.platformManufacturerId}</span></div>
<div>Platform Manufacturer:&nbsp;<span>${initialData.platformManufacturer}</span></div>
<div>Platform Model:&nbsp;<span>${initialData.platformModel}</span></div>
<c:if test="${not empty initialData.platformVersion}">
<div>Platform Version:&nbsp;<span>${initialData.platformVersion}</span></div>
</c:if>
<div>Colloquial Version:&nbsp;<span>${initialData.colloquialVersion}</span></div>
<div>Edition:&nbsp;<span>${initialData.edition}</span></div>
<div>Product:&nbsp;<span>${initialData.product}</span></div>
<div>Revision:&nbsp;<span>${initialData.revision}</span></div>
<c:if test="${not empty initialData.payloadType}">
<div>Payload Type:&nbsp;<span>${initialData.payloadType}</span></div>
</c:if>
<c:if test="${not empty initialData.firmwareVersion}">
<div>Firmware Version:&nbsp;<span>${initialData.firmwareVersion}</span></div>
</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}">
<div>PC URI Global:&nbsp;<span>${initialData.pcUriGlobal}</span></div>
</c:if>
<c:if test="${not empty initiaData.pcUriLocal}">
<div>PC URI Local:&nbsp;<span>${initialData.pcUriLocal}</span></div>
</c:if>
<div>Rim Link Hash:&nbsp;<span>${initialData.rimLinkHash}</span></div>
</div>
</div>
<div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Payload/Support RIM(s)</span></div>
<div id="platformConfiguration" class="col col-md-8">
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#platformConfiguration" class="collapsed"
href="#directorycollapse" aria-expanded="true" aria-controls="directorycollapse">
Directory
</a>
</h4>
</div>
<div id="directorycollapse" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne" aria-expanded="true">
<div class="panel-body">
<div class="panel-heading" role="tab" id="headingThree">
<h3 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#directorycollapse" class="collapsed"
href="#filescollapse" aria-expanded="false" aria-controls="filescollapse">
Files
</a>
</h3>
</div>
<div id="filescollapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingThree" aria-expanded="true">
<c:if test="${not empty initialData.swidFiles}">
<div id="componentIdentifier" class="row">
<c:forEach items="${initialData.swidFiles}" var="resource">
<div class="component col col-md-10" style="padding-left: 20px">
<div class="panel panel-default">
<div class="panel-heading">
<span data-toggle="tooltip" data-placement="top" title="Resource File">
<c:choose>
<c:when test="${not empty initialData.associatedRim}">
<a href="${portal}/rim-details?id=${initialData.associatedRim}">${resource.getName()}</a>
</c:when>
<c:otherwise>
${resource.getName()}
</c:otherwise>
</c:choose>
</span>
</div>
<c:choose>
<c:when test="${not empty resource.getPcrValues()}">
<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"
href="#pcrscollapse" aria-expanded="false" aria-controls="pcrscollapse">
Expected PCR Values
</a>
</div>
<div id="pcrscollapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingThree" aria-expanded="true">
<div> <div>
<span>${pcrValue.key}</span> <c:forEach items="${resource.getPcrMap()}" var="pcrValue">
<span style="overflow-wrap: break-word">${pcrValue.value}</span> <div id="componentIdentifier" class="row">
<div>
<span>${pcrValue.key}</span>
<span style="overflow-wrap: break-word">${pcrValue.value}</span>
</div>
</div>
</c:forEach>
</div> </div>
</div> </div>
</c:forEach> </div>
</div> </c:if>
</div> </div>
</div> </c:when>
</c:if> <c:otherwise>
<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:otherwise>
</c:choose>
</div> </div>
</c:when> </div>
<c:otherwise> </c:forEach>
<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:otherwise>
</c:choose>
</div> </div>
</div> </c:if>
</c:forEach> </div>
</div>
</c:if>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </c:otherwise>
</div> </c:choose>
</div> </div>
</div> </div>
</div> </div>
<script>
function eventSearch() {
// Declare variables
var input, filter, table, tr, td, i, txtValue, txtFound;
input = document.getElementById("eventInput");
filter = input.value.toUpperCase();
table = document.getElementById("eventLog");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
txtFound = false;
tds = tr[i].getElementsByTagName("td");
for (j = 0; j < tds.length; j++) {
td = tds[j];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
txtFound = true;
break;
} else {
txtFound = false;
}
}
}
if (txtFound) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
</script>
</jsp:body> </jsp:body>
</my:page> </my:page>

View File

@ -16,6 +16,7 @@
font-weight: bold; font-weight: bold;
margin: auto 0; margin: auto 0;
} }
#platformID { #platformID {
display: inline; display: inline;
} }

View File

@ -1,5 +1,6 @@
package hirs.attestationca.portal.page.controllers; package hirs.attestationca.portal.page.controllers;
import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.ReferenceManifest; import hirs.data.persist.ReferenceManifest;
import hirs.persist.DBReferenceManifestManager; import hirs.persist.DBReferenceManifestManager;
import hirs.attestationca.portal.page.Page; import hirs.attestationca.portal.page.Page;
@ -52,7 +53,7 @@ public class ReferenceManifestDetailsPageControllerTest extends PageControllerTe
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
throw new IOException("Could not resolve path URI", e); throw new IOException("Could not resolve path URI", e);
} }
referenceManifest = new ReferenceManifest(Files.readAllBytes(fPath)); referenceManifest = new BaseReferenceManifest(Files.readAllBytes(fPath));
referenceManifestManager.save(referenceManifest); referenceManifestManager.save(referenceManifest);
} }

View File

@ -12,6 +12,7 @@ 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.xml.bind.JAXBContext; import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException; import javax.xml.bind.JAXBException;
@ -26,6 +27,10 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/**
*
*/
@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);
@ -35,14 +40,12 @@ public class BaseReferenceManifest extends ReferenceManifest {
private String swidName = null; private String swidName = null;
@Column @Column
private String swidVersion = null; private String swidVersion = null;
@Column(nullable = false)
private int swidCorpus = 0;
@Column(nullable = false)
private int swidPatch = 0;
@Column(nullable = false)
private int swidSupplemental = 0;
@Column @Column
private String firmwareVersion = null; private int swidCorpus = 0;
@Column
private int swidPatch = 0;
@Column
private int swidSupplemental = 0;
@Column @Column
private String colloquialVersion = null; private String colloquialVersion = null;
@Column @Column
@ -74,10 +77,11 @@ public class BaseReferenceManifest extends ReferenceManifest {
private String linkRel = null; private String linkRel = null;
/** /**
* Support constructor for the RIM object.
* *
* @param fileName * @param fileName - string representation of the uploaded file.
* @param rimBytes * @param rimBytes - the file content of the uploaded file.
* @throws IOException * @throws IOException - thrown if the file is invalid.
*/ */
public BaseReferenceManifest(final String fileName, final byte[] rimBytes) throws IOException { public BaseReferenceManifest(final String fileName, final byte[] rimBytes) throws IOException {
this(rimBytes); this(rimBytes);
@ -440,24 +444,6 @@ public class BaseReferenceManifest extends ReferenceManifest {
this.swidSupplemental = swidSupplemental; this.swidSupplemental = swidSupplemental;
} }
/**
* Getter for the firmware version info.
*
* @return string for the firmware version
*/
public String getFirmwareVersion() {
return firmwareVersion;
}
/**
* Setter for the firmware version info.
*
* @param firmwareVersion passed in firmware version
*/
public void setFirmwareVersion(final String firmwareVersion) {
this.firmwareVersion = firmwareVersion;
}
/** /**
* Getter for the Entity Name. * Getter for the Entity Name.
* *
@ -769,8 +755,8 @@ public class BaseReferenceManifest extends ReferenceManifest {
return String.format("ReferenceManifest{swidName=%s," return String.format("ReferenceManifest{swidName=%s,"
+ "platformManufacturer=%s," + "platformManufacturer=%s,"
+ " platformModel=%s," + " platformModel=%s,"
+ "firmwareVersion=%s, firmwareVersion=%s, rimHash=%d}", + "tagId=%s, rimHash=%d}",
swidName, this.getPlatformManufacturer(), swidName, this.getPlatformManufacturer(),
this.getPlatformModel(), firmwareVersion, getTagId(), this.getRimHash()); this.getPlatformModel(), getTagId(), this.getRimHash());
} }
} }

View File

@ -1,6 +1,7 @@
package hirs.data.persist; package hirs.data.persist;
import java.util.Arrays; import java.util.Arrays;
import java.util.UUID;
import javax.persistence.Access; import javax.persistence.Access;
import javax.persistence.AccessType; import javax.persistence.AccessType;
import javax.persistence.Column; import javax.persistence.Column;
@ -12,6 +13,8 @@ import hirs.persist.ReferenceManifestManager;
import hirs.persist.ReferenceManifestSelector; import hirs.persist.ReferenceManifestSelector;
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 javax.persistence.Table; import javax.persistence.Table;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
@ -28,7 +31,13 @@ import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
@Access(AccessType.FIELD) @Access(AccessType.FIELD)
public abstract class ReferenceManifest extends ArchivableEntity { public abstract class ReferenceManifest extends ArchivableEntity {
/**
* String for display of a Base RIM.
*/
public static final String BASE_RIM = "Base"; public static final String BASE_RIM = "Base";
/**
* String for display of a Support RIM.
*/
public static final String SUPPORT_RIM = "Support"; public static final String SUPPORT_RIM = "Support";
/** /**
@ -69,12 +78,6 @@ public abstract class ReferenceManifest extends ArchivableEntity {
public Selector(final ReferenceManifestManager referenceManifestManager) { public Selector(final ReferenceManifestManager referenceManifestManager) {
super(referenceManifestManager); super(referenceManifestManager);
} }
/**
* Specify a manufacturer that certificates must have to be considered as matching.
* @param rimType the manufacturer to query, not empty or null
* @return this instance (for chaining further calls)
*/
} }
/** /**
@ -96,9 +99,14 @@ public abstract class ReferenceManifest extends ArchivableEntity {
@Column @Column
private String platformManufacturerId = null; private String platformManufacturerId = null;
@Column @Column
private String firmwareVersion = null;
@Column
private String platformModel = null; private String platformModel = null;
@Column(nullable = false) @Column(nullable = false)
private String fileName = null; private String fileName = null;
@Type(type = "uuid-char")
@Column
private UUID associatedRim;
/** /**
* Get a Selector for use in retrieving ReferenceManifest. * Get a Selector for use in retrieving ReferenceManifest.
@ -119,8 +127,18 @@ public abstract class ReferenceManifest extends ArchivableEntity {
this.rimBytes = null; this.rimBytes = null;
this.rimHash = 0; this.rimHash = 0;
this.rimType = null; this.rimType = null;
this.platformManufacturer = null;
this.platformManufacturerId = null;
this.platformModel = null;
this.fileName = BASE_RIM;
this.tagId = null;
this.associatedRim = null;
} }
/**
* Default constructor for ingesting the bytes of the file content.
* @param rimBytes - file contents.
*/
public ReferenceManifest(final byte[] rimBytes) { public ReferenceManifest(final byte[] rimBytes) {
Preconditions.checkArgument(rimBytes != null, Preconditions.checkArgument(rimBytes != null,
"Cannot construct a RIM from a null byte array"); "Cannot construct a RIM from a null byte array");
@ -238,6 +256,40 @@ public abstract class ReferenceManifest extends ArchivableEntity {
this.tagId = tagId; this.tagId = tagId;
} }
/**
* Getter for the firmware version info.
*
* @return string for the firmware version
*/
public String getFirmwareVersion() {
return firmwareVersion;
}
/**
* Setter for the firmware version info.
*
* @param firmwareVersion passed in firmware version
*/
public void setFirmwareVersion(final String firmwareVersion) {
this.firmwareVersion = firmwareVersion;
}
/**
* Getter for the associated RIM DB ID.
* @return UUID for the rim
*/
public UUID getAssociatedRim() {
return associatedRim;
}
/**
* Setter for the associated RIM DB ID.
* @param associatedRim UUID for the rim
*/
public void setAssociatedRim(final UUID associatedRim) {
this.associatedRim = associatedRim;
}
/** /**
* Getter for the Reference Integrity Manifest as a byte array. * Getter for the Reference Integrity Manifest as a byte array.
* *
@ -264,4 +316,26 @@ public abstract class ReferenceManifest extends ArchivableEntity {
public int hashCode() { public int hashCode() {
return getRimHash(); return getRimHash();
} }
@Override
public boolean equals(final Object object) {
if (this == object) {
return true;
}
if (object == null || getClass() != object.getClass()) {
return false;
}
if (!super.equals(object)) {
return false;
}
ReferenceManifest that = (ReferenceManifest) object;
return rimHash == that.rimHash
&& Arrays.equals(rimBytes, that.rimBytes)
&& rimType.equals(that.rimType)
&& tagId.equals(that.tagId)
&& platformManufacturer.equals(that.platformManufacturer)
&& platformManufacturerId.equals(that.platformManufacturerId)
&& platformModel.equals(that.platformModel)
&& fileName.equals(that.fileName);
}
} }

View File

@ -1,21 +1,45 @@
package hirs.data.persist; package hirs.data.persist;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.tpm.eventlog.TpmPcrEvent;
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 java.io.IOException; import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/** /**
* Sub class that will just focus on PCR Values and Events * Sub class that will just focus on PCR Values and Events.
*/ */
@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);
@Column(nullable = false) @Column
@JsonIgnore @JsonIgnore
private int pcrHash; private int pcrHash = 0;
/**
* Support constructor for the RIM object.
*
* @param fileName - string representation of the uploaded file.
* @param rimBytes byte array representation of the RIM
* @throws IOException if unable to unmarshal the string
*/
public SupportReferenceManifest(final String fileName,
final byte[] rimBytes) throws IOException {
this(rimBytes);
this.setRimType(SUPPORT_RIM);
this.setFileName(fileName);
}
/** /**
* Main constructor for the RIM object. This takes in a byte array of a * Main constructor for the RIM object. This takes in a byte array of a
@ -27,19 +51,71 @@ public class SupportReferenceManifest extends ReferenceManifest {
public SupportReferenceManifest(final byte[] rimBytes) throws IOException { public SupportReferenceManifest(final byte[] rimBytes) throws IOException {
super(rimBytes); super(rimBytes);
this.setRimType(SUPPORT_RIM); this.setRimType(SUPPORT_RIM);
this.pcrHash = 0;
} }
/** /**
* Default constructor necessary for Hibernate. * Default constructor necessary for Hibernate.
*/ */
protected SupportReferenceManifest() { protected SupportReferenceManifest() {
super();
this.pcrHash = 0;
} }
/**
* Getter method for the expected PCR values contained within the support
* RIM.
* @return a string array of the pcr values.
*/
public String[] getExpectedPCRList() {
try {
TCGEventLog logProcessor = new TCGEventLog(this.getRimBytes());
this.pcrHash = Arrays.hashCode(logProcessor.getExpectedPCRValues());
return logProcessor.getExpectedPCRValues();
} catch (CertificateException cEx) {
LOGGER.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOGGER.error(noSaEx);
} catch (IOException ioEx) {
LOGGER.error(ioEx);
}
return new String[0];
}
/**
* Getter method for the event log that should be present in the support RIM.
*
* @return list of TPM PCR Events for display
*/
public List<TpmPcrEvent> getEventLog() {
TCGEventLog logProcessor = null;
try {
logProcessor = new TCGEventLog(this.getRimBytes());
return Collections.unmodifiableList(logProcessor.getEventList());
} catch (CertificateException cEx) {
LOGGER.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOGGER.error(noSaEx);
} catch (IOException ioEx) {
LOGGER.error(ioEx);
}
return new ArrayList<>();
}
/**
* Getter for the PCR Hash contained in the support RIM.
* @return hash in int form
*/
public int getPcrHash() { public int getPcrHash() {
return pcrHash; return pcrHash;
} }
/**
* Setter for the PCR Hash.
* @param pcrHash hash in int form
*/
public void setPcrHash(final int pcrHash) { public void setPcrHash(final int pcrHash) {
this.pcrHash = pcrHash; this.pcrHash = pcrHash;
} }

View File

@ -118,11 +118,11 @@ public abstract class ReferenceManifestSelector<ReferenceManifest> {
} }
/** /**
* Specif 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
* @return * @return instance of the manifest in relation to the filename.
*/ */
public ReferenceManifestSelector byFileName(final int fileName) { public ReferenceManifestSelector byFileName(final String fileName) {
setFieldValue(RIM_FILENAME_FIELD, fileName); setFieldValue(RIM_FILENAME_FIELD, fileName);
return this; return this;
} }

View File

@ -252,7 +252,7 @@ public final class TCGEventLog {
public String[] getExpectedPCRValues() { public String[] getExpectedPCRValues() {
String[] pcrs = new String[PCR_COUNT]; String[] pcrs = new String[PCR_COUNT];
for (int i = 0; i < PCR_COUNT; i++) { for (int i = 0; i < PCR_COUNT; i++) {
pcrs[i] = HexUtils.byteArrayToHexString(pcrList[i]); pcrs[i] = Hex.encodeHexString(pcrList[i]);
} }
return pcrs; return pcrs;
} }

View File

@ -2,6 +2,7 @@ package hirs.tpm.eventlog;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
@ -25,51 +26,82 @@ import hirs.tpm.eventlog.uefi.UefiConstants;
import hirs.tpm.eventlog.uefi.UefiFirmware; import hirs.tpm.eventlog.uefi.UefiFirmware;
import hirs.tpm.eventlog.uefi.UefiVariable; import hirs.tpm.eventlog.uefi.UefiVariable;
import hirs.utils.HexUtils; import hirs.utils.HexUtils;
import org.apache.commons.codec.binary.Hex;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/** /**
* 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
* TCG Platform Firmware Profile (PFP) specification. * TCG Platform Firmware Profile (PFP) specification.
* typedef struct { * typedef struct {
* TCG_PCRINDEX PCRIndex; //PCR Index value that either * TCG_PCRINDEX PCRIndex; //PCR Index value that either
* //matches the PCRIndex of a * //matches the PCRIndex of a
* //previous extend operation or * //previous extend operation or
* //indicates that this Event Log * //indicates that this Event Log
* //entry is not associated with * //entry is not associated with
* //an extend operation * //an extend operation
* TCG_EVENTTYPE EventType; //See Log event types defined in toStrng() * TCG_EVENTTYPE EventType; //See Log event types defined in toStrng()
* TCG_DIGEST digest; //The hash of the event data * TCG_DIGEST digest; //The hash of the event data
* UINT32 EventSize; //Size of the event data * UINT32 EventSize; //Size of the event data
* UINT8 Event[EventSize]; //The event data * UINT8 Event[EventSize]; //The event data
* } TCG_PCR_EVENT; * } TCG_PCR_EVENT;
*/ */
public class TpmPcrEvent { public class TpmPcrEvent {
/** Log format. SHA1=1, Crytpo agile=2. */ private static final Logger LOGGER = LogManager.getLogger(TpmPcrEvent.class);
private int logFormat = -1; /**
/** PCR index. */ * Indent Offset.
private int pcrIndex = -1; */
/** Event Type (long). */
private long eventType = 0;
/** Event digest. */
private byte[] digest = null;
/** Even data (no content). */
private byte[] event;
/** Even content data. */
private byte[] eventContent;
/** TCG Event Log spec version. */
private String version = "Unknown";
/** TCG Event Log errata version. */
private String errata = "Unknown";
/** Description for toString support. */
private String description = "";
/** Length (in bytes) of a pcr. */
private int digestLength = 0;
/** Event hash for SHA1 event logs. */
private byte[] eventDataSha1hash;
/** Event hash for Crypto Agile events. */
private byte[] eventDataSha256hash;
/** Indent Offset. */
private static final int INDENT_3 = 3; private static final int INDENT_3 = 3;
/**
* Log format. SHA1=1, Crytpo agile=2.
*/
private int logFormat = -1;
/**
* PCR index.
*/
private int pcrIndex = -1;
/**
* Event Type (long).
*/
private long eventType = 0;
/**
* Event digest.
*/
private byte[] digest = null;
/**
* Event data (no content).
*/
private byte[] event;
/**
* Event content data.
*/
private byte[] eventContent;
/**
* TCG Event Log spec version.
*/
private String version = "Unknown";
/**
* TCG Event Log errata version.
*/
private String errata = "Unknown";
/**
* Description for toString support.
*/
private String description = "";
/**
* Length (in bytes) of a pcr.
*/
private int digestLength = 0;
/**
* Event hash for SHA1 event logs.
*/
private byte[] eventDataSha1hash;
/**
* Event hash for Crypto Agile events.
*/
private byte[] eventDataSha256hash;
private EvPostCode evPostCode;
/** /**
* Constructor. * Constructor.
@ -104,6 +136,14 @@ public class TpmPcrEvent {
return digestCopy; return digestCopy;
} }
/**
* Returns a hex representation of the event digest.
* @return hex string
*/
public String getEventDigestStr() {
return Hex.encodeHexString(this.digest);
}
/** /**
* Sets the event PCR index value from a TCG Event. * Sets the event PCR index value from a TCG Event.
* *
@ -122,22 +162,25 @@ public class TpmPcrEvent {
return pcrIndex; return pcrIndex;
} }
/** Sets the Log Format for this TCG Event. /**
* 1 = SHA1 Format, 2 = Crypto Agile format. * Sets the Log Format for this TCG Event.
* @param format indicates log format. * 1 = SHA1 Format, 2 = Crypto Agile format.
*/ *
protected void setLogFormat(final int format) { * @param format indicates log format.
logFormat = format; */
} protected void setLogFormat(final int format) {
logFormat = format;
}
/** /**
* Gets the Log Format for this TCG Event. * Gets the Log Format for this TCG Event.
* 1 = SHA1 Format, 2 = Crypto Agile format. * 1 = SHA1 Format, 2 = Crypto Agile format.
* @return number representing the format. *
*/ * @return number representing the format.
public int getLogFormat() { */
return logFormat; public int getLogFormat() {
} return logFormat;
}
/** /**
* Sets the EventType. * Sets the EventType.
@ -157,6 +200,14 @@ public class TpmPcrEvent {
return eventType; return eventType;
} }
/**
* Returns a formatted string of the type for the event.
* @return a string formatted to be human readable
*/
public String getEventTypeStr() {
return String.format("0x%s %s", Long.toHexString(eventType), 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.
@ -190,11 +241,13 @@ public class TpmPcrEvent {
/** /**
* Gets the Event Data (no event content) for the event. * Gets the Event Data (no event content) for the event.
* event log format. * event log format.
*
* @return byte array holding the event structure. * @return byte array holding the event structure.
*/ */
public byte[] getEvent() { public byte[] getEvent() {
return java.util.Arrays.copyOf(event, event.length); return java.util.Arrays.copyOf(event, event.length);
} }
/** /**
* Sets the event content after processing. * Sets the event content after processing.
* *
@ -202,17 +255,168 @@ public class TpmPcrEvent {
*/ */
protected void setEventContent(final byte[] eventData) { protected void setEventContent(final byte[] eventData) {
eventContent = new byte[eventData.length]; eventContent = new byte[eventData.length];
evPostCode = new EvPostCode(eventContent);
System.arraycopy(eventData, 0, eventContent, 0, eventData.length); System.arraycopy(eventData, 0, eventContent, 0, eventData.length);
} }
/** /**
* Gets the event Content Data (not the entire event structure). * Gets the event Content Data (not the entire event structure).
*
* @return byte array holding the events content field * @return byte array holding the events content field
*/ */
public byte[] getEventContent() { public byte[] getEventContent() {
return java.util.Arrays.copyOf(eventContent, eventContent.length); return java.util.Arrays.copyOf(eventContent, eventContent.length);
} }
/**
* A getter that parses the content based on the type and returns the proper string
* value for the content.
* @return an appended string of human readable data
*/
public String getEventContentStr() {
StringBuilder sb = new StringBuilder();
switch ((int) this.eventType) {
case EvConstants.EV_PREBOOT_CERT:
sb.append(" EV_PREBOOT_CERT");
break;
case EvConstants.EV_POST_CODE:
sb.append(new EvPostCode(eventContent).toString());
break;
case EvConstants.EV_UNUSED:
break;
case EvConstants.EV_NO_ACTION:
EvNoAction noAction = null;
try {
noAction = new EvNoAction(eventContent);
sb.append(noAction.toString());
if (noAction.isSpecIDEvent()) {
// this should be in the constructor
EvEfiSpecIdEvent specID = noAction.getEvEfiSpecIdEvent();
version = String.format("%s.%s",
specID.getVersionMajor(),
specID.getVersionMinor());
errata = specID.getErrata();
}
} catch (UnsupportedEncodingException ueEx) {
LOGGER.error(ueEx);
sb.append(ueEx.toString());
}
break;
case EvConstants.EV_SEPARATOR:
if (EvPostCode.isAscii(eventContent)
&& !this.isBlank(eventContent)) {
sb.append(String.format("Separator event content = %s",
new String(eventContent, StandardCharsets.UTF_8)));
}
break;
case EvConstants.EV_EVENT_TAG:
sb.append(new EvEventTag(eventContent).toString());
break;
case EvConstants.EV_S_CRTM_CONTENTS:
sb.append(new EvSCrtmContents(eventContent).toString());
break;
case EvConstants.EV_S_CRTM_VERSION:
try {
sb.append(new EvSCrtmVersion(eventContent).toString());
} catch (UnsupportedEncodingException ueEx) {
LOGGER.error(ueEx);
sb.append(ueEx.toString());
}
break;
case EvConstants.EV_CPU_MICROCODE:
case EvConstants.EV_PLATFORM_CONFIG_FLAGS:
case EvConstants.EV_TABLE_OF_DEVICES:
break;
case EvConstants.EV_COMPACT_HASH:
try {
sb.append(new EvCompactHash(eventContent).toString());
} catch (UnsupportedEncodingException ueEx) {
LOGGER.error(ueEx);
sb.append(ueEx.toString());
}
break;
case EvConstants.EV_IPL:
sb.append(new EvIPL(eventContent).toString());
break;
case EvConstants.EV_IPL_PARTITION_DATA:
case EvConstants.EV_NONHOST_CODE:
case EvConstants.EV_NONHOST_CONFIG:
case EvConstants.EV_NONHOST_INFO:
case EvConstants.EV_EV_OMIT_BOOT_DEVICES_EVENTS:
case EvConstants.EV_EFI_EVENT_BASE:
break;
case EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG:
UefiVariable efiVar = null;
try {
efiVar = new UefiVariable(eventContent);
String efiVarDescription = efiVar.toString().replace("\n", "\n ");
sb.append(efiVarDescription.substring(0,
efiVarDescription.length() - INDENT_3));
} catch (CertificateException cEx) {
LOGGER.error(cEx);
sb.append(cEx.toString());
} catch (NoSuchAlgorithmException noSaEx) {
LOGGER.error(noSaEx);
sb.append(noSaEx.toString());
} catch (IOException ioEx) {
LOGGER.error(ioEx);
sb.append(ioEx.toString());
}
break;
case EvConstants.EV_EFI_VARIABLE_BOOT:
case EvConstants.EV_EFI_VARIABLE_AUTHORITY:
try {
sb.append(new UefiVariable(eventContent).toString());
} catch (CertificateException cEx) {
LOGGER.error(cEx);
sb.append(cEx.toString());
} catch (NoSuchAlgorithmException noSaEx) {
LOGGER.error(noSaEx);
sb.append(noSaEx.toString());
} catch (IOException ioEx) {
LOGGER.error(ioEx);
sb.append(ioEx.toString());
}
break;
case EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION:
case EvConstants.EV_EFI_BOOT_SERVICES_DRIVER: // same as EV_EFI_BOOT_SERVICES_APP
try {
sb.append(new EvEfiBootServicesApp(eventContent).toString());
} catch (UnsupportedEncodingException ueEx) {
LOGGER.error(ueEx);
sb.append(ueEx.toString());
}
break;
case EvConstants.EV_EFI_RUNTIME_SERVICES_DRIVER:
break;
case EvConstants.EV_EFI_GPT_EVENT:
try {
sb.append(new EvEfiGptPartition(eventContent).toString());
} catch (UnsupportedEncodingException ueEx) {
LOGGER.error(ueEx);
sb.append(ueEx.toString());
}
break;
case EvConstants.EV_EFI_ACTION:
case EvConstants.EV_ACTION:
sb.append(new String(eventContent, StandardCharsets.UTF_8));
break;
case EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB:
sb.append(new UefiFirmware(eventContent).toString());
break;
case EvConstants.EV_EFI_HANDOFF_TABLES:
sb.append(new EvEfiHandoffTable(eventContent).toString());
break;
case EvConstants.EV_EFI_HCRTM_EVENT:
break;
default:
sb.append("Unknown Event found\n");
}
return sb.toString();
}
/** /**
* Sets the Digest Length. * Sets the Digest Length.
* Also the number of bytes expected within each PCR. * Also the number of bytes expected within each PCR.
@ -234,25 +438,26 @@ public class TpmPcrEvent {
/** /**
* Parses the event content and creates a human readable description of each event. * Parses the event content and creates a human readable description of each event.
* @param event the byte array holding the event data. *
* @param event the byte array holding the event data.
* @param eventContent the byte array holding the event content. * @param eventContent the byte array holding the event content.
* @param eventNumber event position within the event log. * @param eventNumber event position within the event log.
* @return String description of the event. * @return String description of the event.
* @throws CertificateException if the event contains an event that cannot be processed. * @throws CertificateException if the event contains an event that cannot be processed.
* @throws NoSuchAlgorithmException if an event contains an unsupported algorithm. * @throws NoSuchAlgorithmException if an event contains an unsupported algorithm.
* @throws IOException if the event cannot be parsed. * @throws IOException if the event cannot be parsed.
*/ */
public String processEvent(final byte[] event, final byte[] eventContent, final int eventNumber) public String processEvent(final byte[] event, final byte[] eventContent, final int eventNumber)
throws CertificateException, NoSuchAlgorithmException, IOException { throws CertificateException, NoSuchAlgorithmException, IOException {
int eventID = (int) eventType; int eventID = (int) eventType;
description += "Event# " + eventNumber + ": "; description += "Event# " + eventNumber + ": ";
description += "Index PCR[" + getPcrIndex() + "]\n"; description += "Index PCR[" + getPcrIndex() + "]\n";
description += "Event Type: 0x" + Long.toHexString(eventType) + " " + eventString(eventID); description += "Event Type: 0x" + Long.toHexString(eventType) + " " + eventString(eventID);
description += "\n"; description += "\n";
if (logFormat == 1) { // Digest if (logFormat == 1) { // Digest
description += "digest (SHA-1): " + HexUtils.byteArrayToHexString(this.digest); description += "digest (SHA-1): " + Hex.encodeHexString(this.digest);
} else { } else {
description += "digest (SHA256): " + HexUtils.byteArrayToHexString(this.digest); description += "digest (SHA256): " + Hex.encodeHexString(this.digest);
} }
if (eventID != UefiConstants.SIZE_4) { if (eventID != UefiConstants.SIZE_4) {
description += "\n"; description += "\n";
@ -269,11 +474,11 @@ public class TpmPcrEvent {
switch (eventID) { switch (eventID) {
case EvConstants.EV_PREBOOT_CERT: case EvConstants.EV_PREBOOT_CERT:
description += " EV_PREBOOT_CERT" + "\n"; description += " EV_PREBOOT_CERT" + "\n";
break; break;
case EvConstants.EV_POST_CODE: case EvConstants.EV_POST_CODE:
EvPostCode postCode = new EvPostCode(eventContent); EvPostCode postCode = new EvPostCode(eventContent);
description += "Event Content:\n" + postCode.toString(); description += "Event Content:\n" + postCode.toString();
break; break;
case EvConstants.EV_UNUSED: case EvConstants.EV_UNUSED:
break; break;
case EvConstants.EV_NO_ACTION: case EvConstants.EV_NO_ACTION:
@ -287,15 +492,15 @@ public class TpmPcrEvent {
break; break;
case EvConstants.EV_SEPARATOR: case EvConstants.EV_SEPARATOR:
if (EvPostCode.isAscii(eventContent)) { if (EvPostCode.isAscii(eventContent)) {
String seperatorEventData = new String(eventContent, StandardCharsets.UTF_8); String separatorEventData = new String(eventContent, StandardCharsets.UTF_8);
if (!this.isEmpty(eventContent)) { if (!this.isBlank(eventContent)) {
description += "Seperator event content = " + seperatorEventData; description += "Separator event content = " + separatorEventData;
} }
} }
break; break;
case EvConstants.EV_ACTION: case EvConstants.EV_ACTION:
description += "Event Content:\n" description += "Event Content:\n"
+ new String(eventContent, StandardCharsets.UTF_8); + new String(eventContent, StandardCharsets.UTF_8);
break; break;
case EvConstants.EV_EVENT_TAG: case EvConstants.EV_EVENT_TAG:
EvEventTag eventTag = new EvEventTag(eventContent); EvEventTag eventTag = new EvEventTag(eventContent);
@ -316,7 +521,7 @@ public class TpmPcrEvent {
case EvConstants.EV_TABLE_OF_DEVICES: case EvConstants.EV_TABLE_OF_DEVICES:
break; break;
case EvConstants.EV_COMPACT_HASH: case EvConstants.EV_COMPACT_HASH:
EvCompactHash compactHash = new EvCompactHash(eventContent); EvCompactHash compactHash = new EvCompactHash(eventContent);
description += "Event Content:\n" + compactHash.toString(); description += "Event Content:\n" + compactHash.toString();
break; break;
case EvConstants.EV_IPL: case EvConstants.EV_IPL:
@ -339,7 +544,7 @@ public class TpmPcrEvent {
UefiVariable efiVar = new UefiVariable(eventContent); UefiVariable efiVar = new UefiVariable(eventContent);
String efiVarDescription = efiVar.toString().replace("\n", "\n "); String efiVarDescription = efiVar.toString().replace("\n", "\n ");
description += "Event Content:\n " + efiVarDescription.substring(0, description += "Event Content:\n " + efiVarDescription.substring(0,
efiVarDescription.length() - INDENT_3); efiVarDescription.length() - INDENT_3);
break; break;
case EvConstants.EV_EFI_VARIABLE_BOOT: case EvConstants.EV_EFI_VARIABLE_BOOT:
description += "Event Content:\n" + new UefiVariable(eventContent).toString(); description += "Event Content:\n" + new UefiVariable(eventContent).toString();
@ -362,7 +567,7 @@ public class TpmPcrEvent {
break; break;
case EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB: case EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB:
description += "Event Content:\n" description += "Event Content:\n"
+ new UefiFirmware(eventContent).toString(); + new UefiFirmware(eventContent).toString();
break; break;
case EvConstants.EV_EFI_HANDOFF_TABLES: case EvConstants.EV_EFI_HANDOFF_TABLES:
EvEfiHandoffTable efiTable = new EvEfiHandoffTable(eventContent); EvEfiHandoffTable efiTable = new EvEfiHandoffTable(eventContent);
@ -373,7 +578,8 @@ public class TpmPcrEvent {
case EvConstants.EV_EFI_VARIABLE_AUTHORITY: case EvConstants.EV_EFI_VARIABLE_AUTHORITY:
description += "Event Content:\n" + new UefiVariable(eventContent).toString(); description += "Event Content:\n" + new UefiVariable(eventContent).toString();
break; break;
default: description += " Unknown Event found" + "\n"; default:
description += " Unknown Event found" + "\n";
} }
return description; return description;
} }
@ -381,152 +587,158 @@ public class TpmPcrEvent {
/** /**
* Converts the Event ID into a String As defined in the TCG PC Client FW Profile. * Converts the Event ID into a String As defined in the TCG PC Client FW Profile.
* Event IDs have values larger than an integer,so a Long is used hold the value. * Event IDs have values larger than an integer,so a Long is used hold the value.
*
* @param event the event id. * @param event the event id.
* @return TCG defined String that represents the event id * @return TCG defined String that represents the event id
*/ */
private static String eventString(final long event) { private static String eventString(final long event) {
if (event == EvConstants.EV_PREBOOT_CERT) { if (event == EvConstants.EV_PREBOOT_CERT) {
return "EV_PREBOOT_CERT"; return "EV_PREBOOT_CERT";
} else if (event == EvConstants.EV_POST_CODE) { } else if (event == EvConstants.EV_POST_CODE) {
return "EV_POST_CODE"; return "EV_POST_CODE";
} else if (event == EvConstants.EV_UNUSED) { } else if (event == EvConstants.EV_UNUSED) {
return "EV_Unused"; return "EV_Unused";
} else if (event == EvConstants.EV_NO_ACTION) { } else if (event == EvConstants.EV_NO_ACTION) {
return "EV_NO_ACTION"; return "EV_NO_ACTION";
} else if (event == EvConstants.EV_SEPARATOR) { } else if (event == EvConstants.EV_SEPARATOR) {
return "EV_SEPARATOR"; return "EV_SEPARATOR";
} else if (event == EvConstants.EV_ACTION) { } else if (event == EvConstants.EV_ACTION) {
return "EV_ACTION"; return "EV_ACTION";
} else if (event == EvConstants.EV_EVENT_TAG) { } else if (event == EvConstants.EV_EVENT_TAG) {
return "EV_EVENT_TAG"; return "EV_EVENT_TAG";
} else if (event == EvConstants.EV_S_CRTM_CONTENTS) { } else if (event == EvConstants.EV_S_CRTM_CONTENTS) {
return "EV_S_CRTM_CONTENTS"; return "EV_S_CRTM_CONTENTS";
} else if (event == EvConstants.EV_S_CRTM_VERSION) { } else if (event == EvConstants.EV_S_CRTM_VERSION) {
return "EV_S_CRTM_VERSION"; return "EV_S_CRTM_VERSION";
} else if (event == EvConstants.EV_CPU_MICROCODE) { } else if (event == EvConstants.EV_CPU_MICROCODE) {
return "EV_CPU_MICROCODE"; return "EV_CPU_MICROCODE";
} else if (event == EvConstants.EV_PLATFORM_CONFIG_FLAGS) { } else if (event == EvConstants.EV_PLATFORM_CONFIG_FLAGS) {
return "EV_PLATFORM_CONFIG_FLAGS "; return "EV_PLATFORM_CONFIG_FLAGS ";
} else if (event == EvConstants.EV_TABLE_OF_DEVICES) { } else if (event == EvConstants.EV_TABLE_OF_DEVICES) {
return "EV_TABLE_OF_DEVICES"; return "EV_TABLE_OF_DEVICES";
} else if (event == EvConstants.EV_COMPACT_HASH) { } else if (event == EvConstants.EV_COMPACT_HASH) {
return "EV_COMPACT_HASH"; return "EV_COMPACT_HASH";
} else if (event == EvConstants.EV_IPL) { } else if (event == EvConstants.EV_IPL) {
return "EV_IPL"; return "EV_IPL";
} else if (event == EvConstants.EV_IPL_PARTITION_DATA) { } else if (event == EvConstants.EV_IPL_PARTITION_DATA) {
return "EV_IPL_PARTITION_DATA"; return "EV_IPL_PARTITION_DATA";
} else if (event == EvConstants.EV_NONHOST_CODE) { } else if (event == EvConstants.EV_NONHOST_CODE) {
return "EV_NONHOST_CODE"; return "EV_NONHOST_CODE";
} else if (event == EvConstants.EV_NONHOST_CONFIG) { } else if (event == EvConstants.EV_NONHOST_CONFIG) {
return "EV_NONHOST_CONFIG"; return "EV_NONHOST_CONFIG";
} else if (event == EvConstants.EV_NONHOST_INFO) { } else if (event == EvConstants.EV_NONHOST_INFO) {
return "EV_NONHOST_INFO"; return "EV_NONHOST_INFO";
} else if (event == EvConstants.EV_EV_OMIT_BOOT_DEVICES_EVENTS) { } else if (event == EvConstants.EV_EV_OMIT_BOOT_DEVICES_EVENTS) {
return "EV_EV_OMIT_BOOT_DEVICES_EVENTS"; return "EV_EV_OMIT_BOOT_DEVICES_EVENTS";
} else if (event == EvConstants.EV_EFI_EVENT_BASE) { } else if (event == EvConstants.EV_EFI_EVENT_BASE) {
return "EV_EFI_EVENT_BASE"; return "EV_EFI_EVENT_BASE";
} else if (event == EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG) { } else if (event == EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG) {
return "EV_EFI_VARIABLE_DRIVER_CONFIG"; return "EV_EFI_VARIABLE_DRIVER_CONFIG";
} else if (event == EvConstants.EV_EFI_VARIABLE_BOOT) { } else if (event == EvConstants.EV_EFI_VARIABLE_BOOT) {
return "EV_EFI_VARIABLE_BOOT"; return "EV_EFI_VARIABLE_BOOT";
} else if (event == EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION) { } else if (event == EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION) {
return "EV_EFI_BOOT_SERVICES_APPLICATION"; return "EV_EFI_BOOT_SERVICES_APPLICATION";
} else if (event == EvConstants.EV_EFI_BOOT_SERVICES_DRIVER) { } else if (event == EvConstants.EV_EFI_BOOT_SERVICES_DRIVER) {
return "EV_EFI_BOOT_SERVICES_DRIVER"; return "EV_EFI_BOOT_SERVICES_DRIVER";
} else if (event == EvConstants.EV_EFI_RUNTIME_SERVICES_DRIVER) { } else if (event == EvConstants.EV_EFI_RUNTIME_SERVICES_DRIVER) {
return "EV_EFI_RUNTIME_SERVICES_DRIVER"; return "EV_EFI_RUNTIME_SERVICES_DRIVER";
} else if (event == EvConstants.EV_EFI_GPT_EVENT) { } else if (event == EvConstants.EV_EFI_GPT_EVENT) {
return "EV_EFI_GPT_EVENT"; return "EV_EFI_GPT_EVENT";
} else if (event == EvConstants.EV_EFI_ACTION) { } else if (event == EvConstants.EV_EFI_ACTION) {
return "EV_EFI_ACTION"; return "EV_EFI_ACTION";
} else if (event == EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB) { } else if (event == EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB) {
return "EV_EFI_PLATFORM_FIRMWARE_BLOB"; return "EV_EFI_PLATFORM_FIRMWARE_BLOB";
} else if (event == EvConstants.EV_EFI_HANDOFF_TABLES) { } else if (event == EvConstants.EV_EFI_HANDOFF_TABLES) {
return "EV_EFI_HANDOFF_TABLES"; return "EV_EFI_HANDOFF_TABLES";
} else if (event == EvConstants.EV_EFI_HCRTM_EVENT) { } else if (event == EvConstants.EV_EFI_HCRTM_EVENT) {
return "EV_EFI_HCRTM_EVENT"; return "EV_EFI_HCRTM_EVENT";
} else if (event == EvConstants.EV_EFI_VARIABLE_AUTHORITY) { } else if (event == EvConstants.EV_EFI_VARIABLE_AUTHORITY) {
return "EV_EFI_VARIABLE_AUTHORITY"; return "EV_EFI_VARIABLE_AUTHORITY";
} else { } else {
return "Unknown Event ID " + event + " encountered"; return "Unknown Event ID " + event + " encountered";
} }
} }
/** /**
* Human readable output of a check of input against the current event hash. * Human readable output of a check of input against the current event hash.
* @return human readable string. *
*/ * @return human readable string.
private String eventHashCheck() { */
String result = ""; private String eventHashCheck() {
if (logFormat == 1) { String result = "";
if (Arrays.equals(this.digest, eventDataSha1hash)) { result if (logFormat == 1) {
+= "Event digest matched hash of the event data " + "\n"; if (Arrays.equals(this.digest, eventDataSha1hash)) {
} else { result
result += "Event digest DID NOT match the hash of the event data :" += "Event digest matched hash of the event data " + "\n";
+ HexUtils.byteArrayToHexString(getEventDigest()) + "\n";
}
} else { } else {
if (Arrays.equals(this.digest, eventDataSha256hash)) { result += "Event digest DID NOT match the hash of the event data :"
result += "Event digest matched hash of the event data " + "\n"; + Hex.encodeHexString(getEventDigest()) + "\n";
} else { }
result += "Event digest DID NOT match the hash of the event data :" } else {
+ HexUtils.byteArrayToHexString(getEventDigest()) + "\n"; if (Arrays.equals(this.digest, eventDataSha256hash)) {
} result += "Event digest matched hash of the event data " + "\n";
} } else {
return result; result += "Event digest DID NOT match the hash of the event data :"
} + Hex.encodeHexString(getEventDigest()) + "\n";
}
}
return result;
}
/** /**
* Checks a byte array for all zeros. * Checks a byte array for all zeros.
* @param array holds data to check. *
* @return true of all zeros are found. * @param array holds data to check.
*/ * @return true of all zeros are found.
public boolean isEmpty(final byte[] array) { */
for (int i = 0; i < array.length; i++) { public boolean isBlank(final byte[] array) {
if (array[i] != 0) { for (int i = 0; i < array.length; i++) {
return false; if (array[i] != 0) {
} return false;
} }
return true; }
} return true;
}
/** /**
* Human readable string representing the contents of the Event Log. * Human readable string representing the contents of the Event Log.
* @return Description of the log. *
*/ * @return Description of the log.
public String toString() { */
public String toString() {
return description + "\n"; return description + "\n";
} }
/** /**
* Human readable string representing the contents of the Event Log. * Human readable string representing the contents of the Event Log.
* @param bEvent event Flag. *
* @param bContent content flag. * @param bEvent event Flag.
* @param bHexEvent hex event flag. * @param bContent content flag.
* @return Description of the log. * @param bHexEvent hex event flag.
*/ * @return Description of the log.
public String toString(final boolean bEvent, final boolean bContent, final boolean bHexEvent) { */
StringBuilder sb = new StringBuilder(); public String toString(final boolean bEvent, final boolean bContent, final boolean bHexEvent) {
if (bEvent) { StringBuilder sb = new StringBuilder();
sb.append(description); if (bEvent) {
} sb.append(description);
if (bHexEvent) { }
if (bEvent || bContent) { if (bHexEvent) {
sb.append("\n"); if (bEvent || bContent) {
} sb.append("\n");
byte[] eventData = getEvent(); }
sb.append("Event (Hex no Content) (" + eventData.length + " bytes): " byte[] eventData = getEvent();
+ HexUtils.byteArrayToHexString(eventData)); sb.append("Event (Hex no Content) (" + eventData.length + " bytes): "
} + Hex.encodeHexString(eventData));
if (bContent) { }
byte[] evContent = getEventContent(); if (bContent) {
if (bEvent) { byte[] evContent = getEventContent();
sb.append("\n"); if (bEvent) {
} sb.append("\n");
sb.append("Event content (Hex) (" + evContent.length + " bytes): " }
+ HexUtils.byteArrayToHexString(evContent)); sb.append("Event content (Hex) (" + evContent.length + " bytes): "
} + Hex.encodeHexString(evContent));
}
return sb.toString() + "\n"; return sb.toString() + "\n";
} }
} }

View File

@ -34,19 +34,18 @@ public class EvPostCode {
public EvPostCode(final byte[] postCode) { public EvPostCode(final byte[] postCode) {
// 2 ways post code has been implemented, check for the ascii string first // 2 ways post code has been implemented, check for the ascii string first
if (isAscii(postCode)) { if (isAscii(postCode)) {
String info = new String(postCode, StandardCharsets.UTF_8); codeInfo = new String(postCode, StandardCharsets.UTF_8);
codeInfo = info;
bisString = true; bisString = true;
} else { } else {
blob = new UefiFirmware(postCode); blob = new UefiFirmware(postCode);
} }
} }
/** /**
* Returns the UEFI Defined Firmware Blob information. * Returns the UEFI Defined Firmware Blob information.
* @return UEFI Defined Firmware Blob information. * @return UEFI Defined Firmware Blob information.
*/ */
public UefiFirmware getfirmwareBlob() { public UefiFirmware getFirmwareBlob() {
return blob; return blob;
} }
@ -75,12 +74,11 @@ public class EvPostCode {
* @return true if byte array is a string. * @return true if byte array is a string.
*/ */
public static boolean isAscii(final byte[] postCode) { public static boolean isAscii(final byte[] postCode) {
boolean bisAscii = true;
for (byte b : postCode) { for (byte b : postCode) {
if (!Character.isDefined(b)) { if (!Character.isDefined(b)) {
return false; return false;
} }
} }
return bisAscii; return true;
} }
} }

View File

@ -1,73 +1,90 @@
package hirs.tpm.eventlog.uefi; package hirs.tpm.eventlog.uefi;
import java.math.BigInteger; import java.math.BigInteger;
import hirs.utils.HexUtils; import hirs.utils.HexUtils;
/** /**
* Class to process the PFP defined UEFI_PLATFORM_FIRMWARE_BLOB structure. * Class to process the PFP defined UEFI_PLATFORM_FIRMWARE_BLOB structure.
* * <p>
* typedef struct tdUEFI_PLATFORM_FIRMWARE_BLOB { * typedef struct tdUEFI_PLATFORM_FIRMWARE_BLOB {
* UEFI_PHYSICAL_ADDRESS BlobBase; * UEFI_PHYSICAL_ADDRESS BlobBase;
* UINT64 BlobLength; * UINT64 BlobLength;
* } UEFI_PLATFORM_FIRMWARE_BLOB; * } UEFI_PLATFORM_FIRMWARE_BLOB;
*/ */
public class UefiFirmware { public class UefiFirmware {
private boolean berror = false; private boolean bError = false;
/** byte array holding the firmwares physical address. */ /**
private byte[] physicalAddress = null; * byte array holding the firmwares physical address.
/** byte array holding the uefi address length. */ */
private byte[] addressLength = null; private byte[] physicalAddress = null;
/** uefi physical address. */ /**
private int blobAddress = 0; * byte array holding the uefi address length.
/** uefi address length. */ */
private int blobLength = 0; private byte[] addressLength = null;
/**
* uefi physical address.
*/
private int blobAddress = 0;
/**
* uefi address length.
*/
private int blobLength = 0;
/** /**
* UefiFirmware constructor. * UefiFirmware constructor.
* @param blob byte array holding a Firmware Blob. *
*/ * @param blob byte array holding a Firmware Blob.
public UefiFirmware(final byte[] blob) { */
if (blob.length != UefiConstants.SIZE_16) { public UefiFirmware(final byte[] blob) {
berror = true; if (blob.length != UefiConstants.SIZE_16) {
} else { bError = true;
physicalAddress = new byte[UefiConstants.SIZE_8]; } else {
addressLength = new byte[UefiConstants.SIZE_8]; physicalAddress = new byte[UefiConstants.SIZE_8];
System.arraycopy(blob, 0, physicalAddress, 0, UefiConstants.SIZE_8); addressLength = new byte[UefiConstants.SIZE_8];
System.arraycopy(blob, UefiConstants.SIZE_8, addressLength, 0, UefiConstants.SIZE_8); System.arraycopy(blob, 0, physicalAddress, 0, UefiConstants.SIZE_8);
byte[] lelength = HexUtils.leReverseByte(addressLength); System.arraycopy(blob, UefiConstants.SIZE_8, addressLength, 0, UefiConstants.SIZE_8);
BigInteger bigIntLength = new BigInteger(lelength); byte[] lelength = HexUtils.leReverseByte(addressLength);
blobLength = bigIntLength.intValue(); BigInteger bigIntLength = new BigInteger(lelength);
byte[]leAddress = HexUtils.leReverseByte(physicalAddress); blobLength = bigIntLength.intValue();
BigInteger bigIntAddress = new BigInteger(leAddress); byte[] leAddress = HexUtils.leReverseByte(physicalAddress);
blobAddress = bigIntAddress.intValue(); BigInteger bigIntAddress = new BigInteger(leAddress);
} blobAddress = bigIntAddress.intValue();
} }
/** }
* Returns the uefi firmware blobs physical address.
* @return uefi firmware address. /**
*/ * Returns the uefi firmware blobs physical address.
public int getPhysicalAddress() { *
return blobAddress; * @return uefi firmware address.
} */
/** public int getPhysicalAddress() {
* Returns the length of the blobs physical address. return blobAddress;
* @return length of the address. }
*/
public int getBlobLength() { /**
return blobLength; * Returns the length of the blobs physical address.
} *
/** * @return length of the address.
* Returns a description of the firmware blobs location. */
* @return a description of the the firmware blobs location. public int getBlobLength() {
*/ return blobLength;
public String toString() { }
String blobInfo = "";
if (!berror) { /**
blobInfo += " Platform Firwmare Blob Address = " + Integer.toHexString(blobAddress); * Returns a description of the firmware blobs location.
blobInfo += " length = " + blobLength; *
} else { * @return a description of the the firmware blobs location.
blobInfo += " Invalid Firmware Blob event encountered"; */
} public String toString() {
return blobInfo; StringBuilder blobInfo = new StringBuilder();
} if (!bError) {
blobInfo.append(String.format(" Platform Firmware Blob Address = %s",
Integer.toHexString(blobAddress)));
blobInfo.append(String.format(" length = %d", blobLength));
} else {
blobInfo.append(" Invalid Firmware Blob event encountered");
}
return blobInfo.toString();
}
} }

View File

@ -26,145 +26,147 @@ final class Main {
private static byte[] eventLog = null; private static byte[] eventLog = null;
private static boolean bContentFlag, bEventFlag, bHexEvent, bHexFlag, bPcrFlag = false; private static boolean bContentFlag, bEventFlag, bHexEvent, bHexFlag, bPcrFlag = false;
/** /**
* Main Constructor. * Main Constructor.
* @param args command line parameters. *
*/ * @param args command line parameters.
public static void main(final String[] args) { */
commander = new Commander(args); public static void main(final String[] args) {
if (!commander.getValidityFlag()) { commander = new Commander(args);
System.out.print("Program exiting without processs due to issues with" if (!commander.getValidityFlag()) {
+ " parameters provided."); System.out.print("Program exiting without processs due to issues with"
System.exit(1); + " parameters provided.");
}
if (commander.hasArguments()) {
if (commander.getDoneFlag()) {
System.exit(0);
}
if (commander.getHelpFlag()) {
commander.printHelp("");
System.exit(0);
}
if (commander.getOutputFlag()) {
try {
outputStream = new FileOutputStream(commander.getOutputFileName());
} catch (FileNotFoundException e) {
System.out.print("Error opening output file" + commander.getOutputFileName()
+ "\nError was " + e.getMessage());
System.exit(1);
}
}
if (commander.getFileFlag()) {
eventLog = openLog(commander.getInFileName());
}
if (commander.getContentFlag()) {
bContentFlag = true;
}
if (commander.getDiffFlag()) {
bEventFlag = true;
String results = compareLogs(commander.getInFileName(),
commander.getInFile2Name());
writeOut(results);
System.exit(0);
}
if (commander.getEventIdsFlag()) {
bEventFlag = true;
}
if (commander.getEventHexFlag()) {
bHexEvent = true;
}
if (commander.getPCRFlag()) {
bPcrFlag = true;
}
if (commander.getVerifyFile()) {
System.out.print("Verify option is not yet implemented");
System.exit(1); System.exit(1);
} }
if (commander.getHexFlag()) { if (commander.hasArguments()) {
bHexFlag = true; if (commander.getDoneFlag()) {
} System.exit(0);
} else {
System.out.print("Nothing to do: No Parameters provided.");
System.exit(1);
} // End commander processing
try {
if (eventLog == null) {
eventLog = openLog("");
}
// Main Event processing
TCGEventLog evLog = new TCGEventLog(eventLog, bEventFlag, bContentFlag, bHexEvent);
if (bPcrFlag) {
String[] pcrs = evLog.getExpectedPCRValues();
int count = 0;
if (!bHexFlag) {
writeOut("Expected Platform Configuration Register (PCR) values"
+ " derived from the Event Log: \n\n");
} }
for (String pcr: pcrs) { if (commander.getHelpFlag()) {
if (count++ == commander.getPcrNumber() || (commander.getPcrNumber() == -1)) { commander.printHelp("");
if (bHexFlag) { System.exit(0);
writeOut(pcr.toString() + "\n"); }
} else { if (commander.getOutputFlag()) {
writeOut(" pcr " + (count - 1) + " = " + pcr.toString() + "\n"); try {
outputStream = new FileOutputStream(commander.getOutputFileName());
} catch (FileNotFoundException e) {
System.out.print("Error opening output file" + commander.getOutputFileName()
+ "\nError was " + e.getMessage());
System.exit(1);
}
}
if (commander.getFileFlag()) {
eventLog = openLog(commander.getInFileName());
}
if (commander.getContentFlag()) {
bContentFlag = true;
}
if (commander.getDiffFlag()) {
bEventFlag = true;
String results = compareLogs(commander.getInFileName(),
commander.getInFile2Name());
writeOut(results);
System.exit(0);
}
if (commander.getEventIdsFlag()) {
bEventFlag = true;
}
if (commander.getEventHexFlag()) {
bHexEvent = true;
}
if (commander.getPCRFlag()) {
bPcrFlag = true;
}
if (commander.getVerifyFile()) {
System.out.print("Verify option is not yet implemented");
System.exit(1);
}
if (commander.getHexFlag()) {
bHexFlag = true;
}
} else {
System.out.print("Nothing to do: No Parameters provided.");
System.exit(1);
} // End commander processing
try {
if (eventLog == null) {
eventLog = openLog("");
}
// Main Event processing
TCGEventLog evLog = new TCGEventLog(eventLog, bEventFlag, bContentFlag, bHexEvent);
if (bPcrFlag) {
String[] pcrs = evLog.getExpectedPCRValues();
int count = 0;
if (!bHexFlag) {
writeOut("Expected Platform Configuration Register (PCR) values"
+ " derived from the Event Log: \n\n");
}
for (String pcr : pcrs) {
if (count++ == commander.getPcrNumber() || (commander.getPcrNumber() == -1)) {
if (bHexFlag) {
writeOut(pcr.toString() + "\n");
} else {
writeOut(" pcr " + (count - 1) + " = " + pcr.toString() + "\n");
}
} }
} }
} if (!bHexFlag) {
if (!bHexFlag) { writeOut("\n----------------- End PCR Values ----------------- \n\n");
writeOut("\n----------------- End PCR Values ----------------- \n\n");
}
}
// General event log output
if (bEventFlag) {
if (!bHexFlag) {
if (evLog.isCryptoAgile()) {
writeOut("\nEvent Log follows the \"Crypto Agile\" format and has "
+ evLog.getEventList().size() + " events:\n\n");
} else {
writeOut("\nEvent Log follows the \"SHA1\" format and has "
+ evLog.getEventList().size() + " events:\n\n");
} }
} }
int eventCount = 0;
for (TpmPcrEvent event: evLog.getEventList()) { // General event log output
if (bEventFlag) {
if (!bHexFlag) {
if (evLog.isCryptoAgile()) {
writeOut("\nEvent Log follows the \"Crypto Agile\" format and has "
+ evLog.getEventList().size() + " events:\n\n");
} else {
writeOut("\nEvent Log follows the \"SHA1\" format and has "
+ evLog.getEventList().size() + " events:\n\n");
}
}
int eventCount = 0;
for (TpmPcrEvent event : evLog.getEventList()) {
if ((commander.getEventNumber() == eventCount++) if ((commander.getEventNumber() == eventCount++)
|| commander.getEventNumber() == -1) { || commander.getEventNumber() == -1) {
if ((commander.getPcrNumber() == event.getPcrIndex()) if ((commander.getPcrNumber() == event.getPcrIndex())
|| commander.getPcrNumber() == -1) { || commander.getPcrNumber() == -1) {
if (bHexFlag) { if (bHexFlag) {
if (bEventFlag || bHexEvent) { if (bEventFlag || bHexEvent) {
writeOut(HexUtils.byteArrayToHexString(event.getEvent()) + "\n"); writeOut(HexUtils.byteArrayToHexString(event.getEvent()) + "\n");
} }
if (bContentFlag) { if (bContentFlag) {
writeOut(HexUtils.byteArrayToHexString(event.getEventContent()) writeOut(HexUtils.byteArrayToHexString(event.getEventContent())
+ "\n"); + "\n");
} }
} else { } else {
writeOut(event.toString(bEventFlag, bContentFlag, bHexEvent) + "\n"); writeOut(event.toString(bEventFlag, bContentFlag, bHexEvent) + "\n");
} }
} }
}
} }
} }
} catch (IOException i) {
System.out.print("IO error processing Event Log " + commander.getInFileName()
+ "\nError was " + i.toString());
System.exit(1);
} catch (CertificateException c) {
System.out.print("Certificate error processing Event Log " + commander.getInFileName()
+ "\nError was " + c.toString());
System.exit(1);
} catch (NoSuchAlgorithmException a) {
System.out.print("Algorithm error processing Event Log " + commander.getInFileName()
+ "\nError was " + a.toString());
System.exit(1);
} }
} catch (IOException i) {
System.out.print("IO error processing Event Log " + commander.getInFileName()
+ "\nError was " + i.toString());
System.exit(1);
} catch (CertificateException c) {
System.out.print("Certificate error processing Event Log " + commander.getInFileName()
+ "\nError was " + c.toString());
System.exit(1);
} catch (NoSuchAlgorithmException a) {
System.out.print("Algorithm error processing Event Log " + commander.getInFileName()
+ "\nError was " + a.toString());
System.exit(1);
} }
}
/** /**
* Opens a TCG Event log file. * Opens a TCG Event log file.
* @param fileName Name of the log file. Will use a OS specific default. *
* @param fileName Name of the log file. Will use a OS specific default.
* @return a byte array holding the entire log * @return a byte array holding the entire log
*/ */
public static byte[] openLog(final String fileName) { public static byte[] openLog(final String fileName) {
@ -186,10 +188,10 @@ commander = new Commander(args);
Path path = Paths.get(fName); Path path = Paths.get(fName);
rawLog = Files.readAllBytes(path); rawLog = Files.readAllBytes(path);
if (!bHexFlag) { if (!bHexFlag) {
writeOut("tcg_eventlog_tool is opening file:" + path + "\n"); writeOut("tcg_eventlog_tool is opening file:" + path + "\n");
} }
} catch (Exception e) { } catch (Exception e) {
String error = "Error reading event Log File: " + e.toString(); String error = "Error reading event Log File: " + e.toString();
if (bDefault) { if (bDefault) {
error += "\nTry using the -f option to specify an Event Log File"; error += "\nTry using the -f option to specify an Event Log File";
} }
@ -201,6 +203,7 @@ commander = new Commander(args);
/** /**
* Write data out to the system and/or a file. * Write data out to the system and/or a file.
*
* @param data * @param data
*/ */
private static void writeOut(final String data) { private static void writeOut(final String data) {
@ -219,6 +222,7 @@ commander = new Commander(args);
/** /**
* Compares 2 Event Logs and returns a string based upon the results. * Compares 2 Event Logs and returns a string based upon the results.
* Uses the Events digest field for comparisons. * Uses the Events digest field for comparisons.
*
* @param logFileName1 Log file to use as a reference. * @param logFileName1 Log file to use as a reference.
* @param logFileName2 Log file to compare to the reference. * @param logFileName2 Log file to compare to the reference.
* @return A sting containing human readable results. * @return A sting containing human readable results.
@ -232,12 +236,12 @@ commander = new Commander(args);
try { try {
eventLog1 = new TCGEventLog(evLog); eventLog1 = new TCGEventLog(evLog);
} catch (Exception e) { } catch (Exception e) {
sb.append("\nError processing event log " + logFileName1 + " : " + e.getMessage()); sb.append("\nError processing event log " + logFileName1 + " : " + e.getMessage());
return sb.toString(); return sb.toString();
} }
try { try {
eventLog2 = new TCGEventLog(evLog2); eventLog2 = new TCGEventLog(evLog2);
ArrayList<TpmPcrEvent> errors = diffEventLogs(eventLog1.getEventList(), ArrayList<TpmPcrEvent> errors = diffEventLogs(eventLog1.getEventList(),
eventLog2.getEventList(), commander.getPcrNumber()); eventLog2.getEventList(), commander.getPcrNumber());
if (errors.isEmpty() && !bHexFlag) { if (errors.isEmpty() && !bHexFlag) {
sb.append("\nEvent Log " + logFileName1 + " MATCHED EventLog " + logFileName2); sb.append("\nEvent Log " + logFileName1 + " MATCHED EventLog " + logFileName2);
@ -245,8 +249,8 @@ commander = new Commander(args);
if (!errors.isEmpty() && !bHexFlag) { if (!errors.isEmpty() && !bHexFlag) {
sb.append("\nEvent Log " + logFileName1 sb.append("\nEvent Log " + logFileName1
+ " did NOT match EventLog " + logFileName2 + "\n"); + " did NOT match EventLog " + logFileName2 + "\n");
sb.append("There were " + errors.size() + " event mismatches: \n\n"); sb.append("There were " + errors.size() + " event mismatches: \n\n");
} }
for (TpmPcrEvent error : errors) { for (TpmPcrEvent error : errors) {
if (bHexFlag) { if (bHexFlag) {
if (bEventFlag || bHexEvent) { if (bEventFlag || bHexEvent) {
@ -254,51 +258,53 @@ commander = new Commander(args);
} }
if (bContentFlag) { if (bContentFlag) {
sb.append(HexUtils.byteArrayToHexString(error.getEventContent()) sb.append(HexUtils.byteArrayToHexString(error.getEventContent())
+ "\n"); + "\n");
} }
} else { } else {
sb.append(error.toString(bEventFlag, bContentFlag, bHexEvent) + "\n"); sb.append(error.toString(bEventFlag, bContentFlag, bHexEvent) + "\n");
} }
} }
} }
} catch (IOException i) { } catch (IOException i) {
System.out.print("IO error processing Event Log " + commander.getInFileName() System.out.print("IO error processing Event Log " + commander.getInFileName()
+ "\nError was " + i.toString()); + "\nError was " + i.toString());
System.exit(1); System.exit(1);
} catch (CertificateException c) { } catch (CertificateException c) {
System.out.print("Certificate error processing Event Log " + commander.getInFileName() System.out.print("Certificate error processing Event Log " + commander.getInFileName()
+ "\nError was " + c.toString()); + "\nError was " + c.toString());
System.exit(1);
} catch (NoSuchAlgorithmException a) {
System.out.print("Algorithm error processing Event Log " + commander.getInFileName()
+ "\nError was " + a.toString());
System.exit(1); System.exit(1);
} catch (NoSuchAlgorithmException a) {
System.out.print("Algorithm error processing Event Log " + commander.getInFileName()
+ "\nError was " + a.toString());
System.exit(1);
} }
return sb.toString(); return sb.toString();
} }
/** /**
* Compare this event log against a second event log. * Compare this event log against a second event log.
* Returns a String Array of event descriptions in which the digests from the first * Returns a String Array of event descriptions in which the digests from the first
* did no match the second. Return value is null if all events matched. * did no match the second. Return value is null if all events matched.
* @param eventList initial events. *
* @param eventList initial events.
* @param eventList2 events to compare against. * @param eventList2 events to compare against.
* @param pcr used as a filter. Use -1 to check all pcrs. * @param pcr used as a filter. Use -1 to check all pcrs.
* @return array list of strings. Null of no events mismatched. * @return array list of strings. Null of no events mismatched.
*/ */
public static ArrayList<TpmPcrEvent> diffEventLogs(final ArrayList<TpmPcrEvent> eventList, public static ArrayList<TpmPcrEvent> diffEventLogs(final ArrayList<TpmPcrEvent> eventList,
final ArrayList<TpmPcrEvent> eventList2, final int pcr) { final ArrayList<TpmPcrEvent> eventList2, final int pcr) {
ArrayList<TpmPcrEvent> results = new ArrayList<TpmPcrEvent>(); ArrayList<TpmPcrEvent> results = new ArrayList<TpmPcrEvent>();
for (TpmPcrEvent event2 : eventList2) { for (TpmPcrEvent event2 : eventList2) {
if (pcr >= 0) { if (pcr >= 0) {
if (event2.getPcrIndex() == pcr) { if (event2.getPcrIndex() == pcr) {
if (!digestMatch(eventList, event2)) { if (!digestMatch(eventList, event2)) {
results.add(event2); results.add(event2);
} }
} }
} else { } else {
if (!digestMatch(eventList, event2)) { if (!digestMatch(eventList, event2)) {
results.add(event2); results.add(event2);
} }
} }
} }
return results; return results;
@ -306,8 +312,9 @@ commander = new Commander(args);
/** /**
* Checks a digest from a single event against all digests with the same index in an Event Log. * Checks a digest from a single event against all digests with the same index in an Event Log.
*
* @param eventLog The Reference Event log. * @param eventLog The Reference Event log.
* @param event single event to match. * @param event single event to match.
* @return * @return
*/ */
private static boolean digestMatch(final ArrayList<TpmPcrEvent> eventLog, private static boolean digestMatch(final ArrayList<TpmPcrEvent> eventLog,