mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-22 14:22:29 +00:00
Merge pull request #301 from nsacyber/rimel-delete-details
[#280] Base/Support RIM display enhancements
This commit is contained in:
commit
88f68d4139
@ -302,7 +302,6 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
// update the validation result in the device
|
||||
device.setSupplyChainStatus(summary.getOverallValidationResult());
|
||||
deviceManager.updateDevice(device);
|
||||
LOG.error("This is the device id? {} ", device.getId());
|
||||
// check if supply chain validation succeeded.
|
||||
// If it did not, do not provide the IdentityResponseEnvelope
|
||||
if (summary.getOverallValidationResult() == AppraisalStatus.Status.PASS) {
|
||||
@ -590,7 +589,9 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
LOG.error("Supply chain validation did not succeed. "
|
||||
+ "Firmware Quote Validation failed. Result is: "
|
||||
+ validationResult);
|
||||
return new byte[]{};
|
||||
ProvisionerTpm2.CertificateResponse response = ProvisionerTpm2.CertificateResponse
|
||||
.newBuilder().setCertificate(ByteString.EMPTY).build();
|
||||
return response.toByteArray();
|
||||
}
|
||||
} else {
|
||||
LOG.error("Could not process credential request. Invalid nonce provided: "
|
||||
@ -723,7 +724,7 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
}
|
||||
|
||||
// Get TPM info, currently unimplemented
|
||||
TPMInfo tpm = new TPMInfo();
|
||||
TPMInfo tpm;
|
||||
try {
|
||||
tpm = new TPMInfo(DeviceInfoReport.NOT_SPECIFIED,
|
||||
(short) 0,
|
||||
|
@ -6,10 +6,13 @@ import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
import hirs.data.persist.BaseReferenceManifest;
|
||||
import hirs.data.persist.SupportReferenceManifest;
|
||||
import hirs.data.persist.TPMMeasurementRecord;
|
||||
import hirs.data.persist.SwidResource;
|
||||
import hirs.data.persist.PCRPolicy;
|
||||
import hirs.data.persist.ArchivableEntity;
|
||||
import hirs.tpm.eventlog.TCGEventLog;
|
||||
import hirs.validation.SupplyChainCredentialValidator;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@ -324,24 +327,40 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
AppraisalStatus fwStatus = null;
|
||||
String manufacturer = device.getDeviceInfo()
|
||||
.getHardwareInfo().getManufacturer();
|
||||
String model = device.getDeviceInfo().getHardwareInfo().getProductName();
|
||||
ReferenceManifest baseRim = null;
|
||||
Set<ReferenceManifest> rims = ReferenceManifest
|
||||
.select(referenceManifestManager).getRIMs();
|
||||
|
||||
ReferenceManifest rim = ReferenceManifest.select(
|
||||
this.referenceManifestManager)
|
||||
.byManufacturer(manufacturer)
|
||||
.getRIM();
|
||||
for (ReferenceManifest rim : rims) {
|
||||
if (rim instanceof BaseReferenceManifest
|
||||
&& rim.getPlatformManufacturer().equals(manufacturer)) {
|
||||
baseRim = rim;
|
||||
}
|
||||
}
|
||||
|
||||
fwStatus = new AppraisalStatus(PASS,
|
||||
SupplyChainCredentialValidator.FIRMWARE_VALID);
|
||||
if (rim == null) {
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
String.format("Firmware validation failed: "
|
||||
+ "No associated RIM file could be found for %s",
|
||||
manufacturer));
|
||||
} else {
|
||||
List<SwidResource> swids = rim.parseResource();
|
||||
if (baseRim != null) {
|
||||
BaseReferenceManifest bRim = (BaseReferenceManifest) baseRim;
|
||||
List<SwidResource> swids = bRim.parseResource();
|
||||
TCGEventLog logProcessor;
|
||||
for (SwidResource swid : swids) {
|
||||
baseline = swid.getPcrValues()
|
||||
.toArray(new String[swid.getPcrValues().size()]);
|
||||
ReferenceManifest dbRim = ReferenceManifest.select(
|
||||
referenceManifestManager).byFileName(swid.getName()).getRIM();
|
||||
|
||||
if (dbRim != null) {
|
||||
try {
|
||||
logProcessor = new TCGEventLog(dbRim.getRimBytes());
|
||||
baseline = logProcessor.getExpectedPCRValues();
|
||||
} catch (CertificateException cEx) {
|
||||
LOGGER.error(cEx);
|
||||
} catch (NoSuchAlgorithmException noSaEx) {
|
||||
LOGGER.error(noSaEx);
|
||||
} catch (IOException ioEx) {
|
||||
LOGGER.error(ioEx);
|
||||
}
|
||||
}
|
||||
}
|
||||
pcrPolicy.setBaselinePcrs(baseline);
|
||||
|
||||
@ -386,10 +405,15 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
fwStatus = new AppraisalStatus(FAIL, "Associated Issued Attestation"
|
||||
+ " Certificate can not be found.");
|
||||
}
|
||||
} else {
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
String.format("Firmware validation failed: "
|
||||
+ "No associated RIM file could be found for %s:%s",
|
||||
manufacturer, model));
|
||||
}
|
||||
|
||||
return buildValidationRecord(SupplyChainValidation.ValidationType.FIRMWARE,
|
||||
fwStatus.getAppStatus(), fwStatus.getMessage(), rim, level);
|
||||
fwStatus.getAppStatus(), fwStatus.getMessage(), baseRim, level);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -409,6 +433,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
Level level = Level.ERROR;
|
||||
AppraisalStatus fwStatus = new AppraisalStatus(FAIL,
|
||||
SupplyChainCredentialValidator.FIRMWARE_VALID);
|
||||
SupportReferenceManifest sRim = null;
|
||||
|
||||
// check if the policy is enabled
|
||||
if (policy.isFirmwareValidationEnabled()) {
|
||||
@ -416,43 +441,49 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
String manufacturer = device.getDeviceInfo()
|
||||
.getHardwareInfo().getManufacturer();
|
||||
|
||||
// need to get pcrs
|
||||
ReferenceManifest rim = ReferenceManifest.select(
|
||||
this.referenceManifestManager)
|
||||
.byManufacturer(manufacturer)
|
||||
.getRIM();
|
||||
if (rim == null) {
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
String.format("Firmware Quote validation failed: "
|
||||
+ "No associated RIM file could be found for %s",
|
||||
manufacturer));
|
||||
} else {
|
||||
List<SwidResource> swids = rim.parseResource();
|
||||
for (SwidResource swid : swids) {
|
||||
baseline = swid.getPcrValues()
|
||||
.toArray(new String[swid.getPcrValues().size()]);
|
||||
try {
|
||||
// need to get pcrs
|
||||
Set<ReferenceManifest> rims = ReferenceManifest.select(
|
||||
this.referenceManifestManager).getRIMs();
|
||||
for (ReferenceManifest r : rims) {
|
||||
if (r instanceof SupportReferenceManifest
|
||||
&& r.getPlatformManufacturer().equals(manufacturer)) {
|
||||
sRim = (SupportReferenceManifest) r;
|
||||
}
|
||||
}
|
||||
|
||||
String pcrContent = new String(device.getDeviceInfo().getTPMInfo().getPcrValues());
|
||||
String[] storedPcrs = buildStoredPcrs(pcrContent, baseline[0].length());
|
||||
PCRPolicy pcrPolicy = policy.getPcrPolicy();
|
||||
pcrPolicy.setBaselinePcrs(baseline);
|
||||
// grab the quote
|
||||
byte[] hash = device.getDeviceInfo().getTPMInfo().getTpmQuoteHash();
|
||||
if (pcrPolicy.validateQuote(hash, storedPcrs)) {
|
||||
level = Level.INFO;
|
||||
fwStatus = new AppraisalStatus(PASS,
|
||||
SupplyChainCredentialValidator.FIRMWARE_VALID);
|
||||
fwStatus.setMessage("Firmware validation of TPM Quote successful.");
|
||||
|
||||
if (sRim == null) {
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
String.format("Firmware Quote validation failed: "
|
||||
+ "No associated RIM file could be found for %s",
|
||||
manufacturer));
|
||||
} else {
|
||||
fwStatus.setMessage("Firmware validation of TPM Quote failed.");
|
||||
baseline = sRim.getExpectedPCRList();
|
||||
String pcrContent = new String(device.getDeviceInfo()
|
||||
.getTPMInfo().getPcrValues());
|
||||
String[] storedPcrs = buildStoredPcrs(pcrContent, baseline[0].length());
|
||||
PCRPolicy pcrPolicy = policy.getPcrPolicy();
|
||||
pcrPolicy.setBaselinePcrs(baseline);
|
||||
// grab the quote
|
||||
byte[] hash = device.getDeviceInfo().getTPMInfo().getTpmQuoteHash();
|
||||
if (pcrPolicy.validateQuote(hash, storedPcrs)) {
|
||||
level = Level.INFO;
|
||||
fwStatus = new AppraisalStatus(PASS,
|
||||
SupplyChainCredentialValidator.FIRMWARE_VALID);
|
||||
fwStatus.setMessage("Firmware validation of TPM Quote successful.");
|
||||
|
||||
} else {
|
||||
fwStatus.setMessage("Firmware validation of TPM Quote failed."
|
||||
+ "\nPCR hash and Quote hash do not match.");
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LOGGER.error(ex);
|
||||
}
|
||||
|
||||
quoteScv = buildValidationRecord(SupplyChainValidation
|
||||
.ValidationType.FIRMWARE,
|
||||
fwStatus.getAppStatus(), fwStatus.getMessage(), rim, level);
|
||||
fwStatus.getAppStatus(), fwStatus.getMessage(), sRim, level);
|
||||
|
||||
// Generate validation summary, save it, and return it.
|
||||
List<SupplyChainValidation> validations = new ArrayList<>();
|
||||
|
@ -27,7 +27,7 @@ public final class DataTableResponse<T> {
|
||||
|
||||
/**
|
||||
* 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)
|
||||
*/
|
||||
public DataTableResponse(final FilteredRecordsList<T> recordList,
|
||||
|
@ -1,6 +1,8 @@
|
||||
package hirs.attestationca.portal.page.controllers;
|
||||
|
||||
import hirs.data.persist.BaseReferenceManifest;
|
||||
import hirs.data.persist.ReferenceManifest;
|
||||
import hirs.data.persist.SupportReferenceManifest;
|
||||
import hirs.data.persist.SwidResource;
|
||||
import hirs.persist.ReferenceManifestManager;
|
||||
import hirs.tpm.eventlog.TCGEventLog;
|
||||
@ -8,18 +10,17 @@ import hirs.attestationca.portal.page.Page;
|
||||
import hirs.attestationca.portal.page.PageController;
|
||||
import hirs.attestationca.portal.page.PageMessages;
|
||||
import hirs.attestationca.portal.page.params.ReferenceManifestDetailsPageParams;
|
||||
|
||||
import java.io.IOException;
|
||||
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.cert.CertificateException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -53,15 +54,16 @@ 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 model The data model for the request. Can contain data from
|
||||
* redirect.
|
||||
* @param model The data model for the request. Can contain data from
|
||||
* redirect.
|
||||
* @return the path for the view and data model for the page.
|
||||
*/
|
||||
@Override
|
||||
public ModelAndView initPage(final ReferenceManifestDetailsPageParams params,
|
||||
final Model model) {
|
||||
final Model model) {
|
||||
// get the basic information to render the page
|
||||
ModelAndView mav = getBaseModelAndView();
|
||||
PageMessages messages = new PageMessages();
|
||||
@ -104,84 +106,117 @@ public class ReferenceManifestDetailsPageController
|
||||
* This method takes the place of an entire class for a string builder.
|
||||
* Gathers all information and returns it for displays.
|
||||
*
|
||||
* @param uuid database reference for the requested RIM.
|
||||
* @param uuid database reference for the requested RIM.
|
||||
* @param referenceManifestManager the reference manifest manager.
|
||||
* @return mapping of the RIM information from the database.
|
||||
* @throws java.io.IOException error for reading file bytes.
|
||||
* @throws java.io.IOException error for reading file bytes.
|
||||
* @throws NoSuchAlgorithmException If an unknown Algorithm is encountered.
|
||||
* @throws CertificateException if a certificate doesn't parse.
|
||||
* @throws CertificateException if a certificate doesn't parse.
|
||||
*/
|
||||
public static HashMap<String, Object> getRimDetailInfo(final UUID uuid,
|
||||
final ReferenceManifestManager referenceManifestManager) throws IOException,
|
||||
CertificateException, NoSuchAlgorithmException {
|
||||
final ReferenceManifestManager referenceManifestManager) throws IOException,
|
||||
CertificateException, NoSuchAlgorithmException {
|
||||
HashMap<String, Object> data = new HashMap<>();
|
||||
|
||||
ReferenceManifest rim = ReferenceManifest
|
||||
.select(referenceManifestManager)
|
||||
.byEntityId(uuid).getRIM();
|
||||
|
||||
if (rim != null) {
|
||||
if (rim instanceof BaseReferenceManifest) {
|
||||
BaseReferenceManifest bRim = (BaseReferenceManifest) rim;
|
||||
// Software Identity
|
||||
data.put("swidName", rim.getSwidName());
|
||||
data.put("swidVersion", rim.getSwidVersion());
|
||||
data.put("swidCorpus", Boolean.toString(rim.isSwidCorpus()));
|
||||
data.put("swidPatch", Boolean.toString(rim.isSwidPatch()));
|
||||
data.put("swidSupplemental", Boolean.toString(
|
||||
rim.isSwidSupplemental()));
|
||||
data.put("swidName", bRim.getSwidName());
|
||||
data.put("swidVersion", bRim.getSwidVersion());
|
||||
data.put("swidTagVersion", bRim.getSwidTagVersion());
|
||||
if (bRim.isSwidCorpus() == 1) {
|
||||
data.put("swidCorpus", "True");
|
||||
} else {
|
||||
data.put("swidCorpus", "False");
|
||||
}
|
||||
if (bRim.isSwidPatch() == 1) {
|
||||
data.put("swidPatch", "True");
|
||||
} else {
|
||||
data.put("swidPatch", "False");
|
||||
}
|
||||
if (bRim.isSwidSupplemental() == 1) {
|
||||
data.put("swidSupplemental", "True");
|
||||
} else {
|
||||
data.put("swidSupplemental", "False");
|
||||
}
|
||||
data.put("swidTagId", rim.getTagId());
|
||||
// Entity
|
||||
data.put("entityName", rim.getEntityName());
|
||||
data.put("entityRegId", rim.getEntityRegId());
|
||||
data.put("entityRole", rim.getEntityRole());
|
||||
data.put("entityThumbprint", rim.getEntityThumbprint());
|
||||
data.put("entityName", bRim.getEntityName());
|
||||
data.put("entityRegId", bRim.getEntityRegId());
|
||||
data.put("entityRole", bRim.getEntityRole());
|
||||
data.put("entityThumbprint", bRim.getEntityThumbprint());
|
||||
// Link
|
||||
data.put("linkHref", rim.getLinkHref());
|
||||
data.put("linkRel", rim.getLinkRel());
|
||||
data.put("linkHref", bRim.getLinkHref());
|
||||
data.put("linkRel", bRim.getLinkRel());
|
||||
data.put("supportRimId", "");
|
||||
data.put("supportRimTagId", "");
|
||||
data.put("platformManufacturer", bRim.getPlatformManufacturer());
|
||||
data.put("platformManufacturerId", bRim.getPlatformManufacturerId());
|
||||
data.put("platformModel", bRim.getPlatformModel());
|
||||
data.put("platformVersion", bRim.getPlatformVersion());
|
||||
data.put("payloadType", bRim.getPayloadType());
|
||||
data.put("colloquialVersion", bRim.getColloquialVersion());
|
||||
data.put("edition", bRim.getEdition());
|
||||
data.put("product", bRim.getProduct());
|
||||
data.put("revision", bRim.getRevision());
|
||||
data.put("bindingSpec", bRim.getBindingSpec());
|
||||
data.put("bindingSpecVersion", bRim.getBindingSpecVersion());
|
||||
data.put("pcUriGlobal", bRim.getPcURIGlobal());
|
||||
data.put("pcUriLocal", bRim.getPcURILocal());
|
||||
data.put("rimLinkHash", bRim.getRimLinkHash());
|
||||
data.put("rimType", bRim.getRimType());
|
||||
|
||||
data.put("platformManufacturer", rim.getPlatformManufacturer());
|
||||
data.put("platformManufacturerId", rim.getPlatformManufacturerId());
|
||||
data.put("platformModel", rim.getPlatformModel());
|
||||
data.put("platformVersion", rim.getPlatformVersion());
|
||||
data.put("firmwareVersion", rim.getFirmwareVersion());
|
||||
data.put("payloadType", rim.getPayloadType());
|
||||
data.put("colloquialVersion", rim.getColloquialVersion());
|
||||
data.put("edition", rim.getEdition());
|
||||
data.put("product", rim.getProduct());
|
||||
data.put("revision", rim.getRevision());
|
||||
data.put("bindingSpec", rim.getBindingSpec());
|
||||
data.put("bindingSpecVersion", rim.getBindingSpecVersion());
|
||||
data.put("pcUriGlobal", rim.getPcURIGlobal());
|
||||
data.put("pcUriLocal", rim.getPcURILocal());
|
||||
data.put("rimLinkHash", rim.getRimLinkHash());
|
||||
|
||||
// checkout later
|
||||
data.put("rimType", rim.getRimType());
|
||||
List<SwidResource> resources = rim.parseResource();
|
||||
List<SwidResource> resources = bRim.parseResource();
|
||||
String resourceFilename = null;
|
||||
TCGEventLog logProcessor;
|
||||
|
||||
try {
|
||||
for (SwidResource swidRes : resources) {
|
||||
resourceFilename = swidRes.getName();
|
||||
Path logPath = Paths.get(String.format("%s/%s",
|
||||
SwidResource.RESOURCE_UPLOAD_FOLDER,
|
||||
resourceFilename));
|
||||
if (Files.exists(logPath)) {
|
||||
logProcessor = new TCGEventLog(
|
||||
Files.readAllBytes(logPath));
|
||||
swidRes.setPcrValues(Arrays.asList(
|
||||
logProcessor.getExpectedPCRValues()));
|
||||
} else {
|
||||
swidRes.setPcrValues(new ArrayList<>());
|
||||
// going to have to pull the filename and grab that from the DB
|
||||
// to get the id to make the link
|
||||
for (SwidResource swidRes : resources) {
|
||||
resourceFilename = swidRes.getName();
|
||||
ReferenceManifest dbRim = ReferenceManifest.select(
|
||||
referenceManifestManager).byFileName(resourceFilename).getRIM();
|
||||
|
||||
if (dbRim != null) {
|
||||
logProcessor = new TCGEventLog(dbRim.getRimBytes());
|
||||
swidRes.setPcrValues(Arrays.asList(
|
||||
logProcessor.getExpectedPCRValues()));
|
||||
|
||||
if (bRim.getAssociatedRim() == null) {
|
||||
bRim.setAssociatedRim(dbRim.getId());
|
||||
}
|
||||
} else {
|
||||
swidRes.setPcrValues(new ArrayList<>());
|
||||
}
|
||||
} catch (NoSuchFileException nsfEx) {
|
||||
LOGGER.error(String.format("File Not found!: %s",
|
||||
resourceFilename));
|
||||
LOGGER.error(nsfEx);
|
||||
}
|
||||
|
||||
data.put("associatedRim", bRim.getAssociatedRim());
|
||||
data.put("swidFiles", resources);
|
||||
} else if (rim instanceof SupportReferenceManifest) {
|
||||
SupportReferenceManifest sRim = (SupportReferenceManifest) rim;
|
||||
|
||||
if (sRim.getAssociatedRim() == null) {
|
||||
Set<ReferenceManifest> rims = ReferenceManifest
|
||||
.select(referenceManifestManager).getRIMs();
|
||||
for (ReferenceManifest dbRim : rims) {
|
||||
if (dbRim instanceof BaseReferenceManifest
|
||||
&& dbRim.getTagId().equals(sRim.getTagId())) {
|
||||
sRim.setAssociatedRim(dbRim.getId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
data.put("baseRim", sRim.getTagId());
|
||||
data.put("associatedRim", sRim.getAssociatedRim());
|
||||
data.put("rimType", sRim.getRimType());
|
||||
data.put("tagId", sRim.getTagId());
|
||||
|
||||
TCGEventLog logProcessor = new TCGEventLog(sRim.getRimBytes());
|
||||
data.put("events", logProcessor.getEventList());
|
||||
} else {
|
||||
LOGGER.error(String.format("Unable to find Reference Integrity "
|
||||
+ "Manifest with ID: %s", uuid));
|
||||
|
@ -10,6 +10,8 @@ import hirs.FilteredRecordsList;
|
||||
import hirs.attestationca.portal.datatables.OrderedListQueryDataTableAdapter;
|
||||
import hirs.attestationca.portal.page.PageMessages;
|
||||
import hirs.attestationca.portal.page.params.NoPageParams;
|
||||
import hirs.data.persist.BaseReferenceManifest;
|
||||
import hirs.data.persist.SupportReferenceManifest;
|
||||
import hirs.persist.DBManagerException;
|
||||
import hirs.persist.ReferenceManifestManager;
|
||||
import hirs.persist.CriteriaModifier;
|
||||
@ -22,14 +24,10 @@ import java.net.URISyntaxException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
@ -189,42 +187,64 @@ public class ReferenceManifestPageController
|
||||
final RedirectAttributes attr) throws URISyntaxException, Exception {
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
PageMessages messages = new PageMessages();
|
||||
List<MultipartFile> rims = new ArrayList<>();
|
||||
String fileName;
|
||||
Path filePath;
|
||||
Pattern pattern;
|
||||
Matcher matcher;
|
||||
boolean supportRIM = false;
|
||||
|
||||
// loop through the files
|
||||
for (MultipartFile file : files) {
|
||||
fileName = file.getOriginalFilename();
|
||||
Pattern pattern = Pattern.compile(LOG_FILE_PATTERN);
|
||||
Matcher matcher = pattern.matcher(fileName);
|
||||
if (matcher.matches()) {
|
||||
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);
|
||||
}
|
||||
pattern = Pattern.compile(LOG_FILE_PATTERN);
|
||||
matcher = pattern.matcher(fileName);
|
||||
supportRIM = matcher.matches();
|
||||
|
||||
Files.write(filePath, file.getBytes());
|
||||
|
||||
String uploadCompletedMessage = String.format(
|
||||
"%s successfully uploaded", file.getOriginalFilename());
|
||||
messages.addSuccess(uploadCompletedMessage);
|
||||
LOGGER.info(uploadCompletedMessage);
|
||||
} else {
|
||||
// assume it is a swid tag, processing below will throw and error
|
||||
// if it is not.
|
||||
rims.add(file);
|
||||
}
|
||||
}
|
||||
|
||||
for (MultipartFile file : rims) {
|
||||
//Parse reference manifests
|
||||
ReferenceManifest rim = parseRIM(file, 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
|
||||
for (ReferenceManifest element : rims) {
|
||||
if (supportRIM) {
|
||||
if (element instanceof BaseReferenceManifest) {
|
||||
BaseReferenceManifest bRim = (BaseReferenceManifest) element;
|
||||
for (SwidResource swid : bRim.parseResource()) {
|
||||
if (swid.getName().equals(rim.getFileName())) {
|
||||
rim.setSwidTagVersion(bRim.getSwidTagVersion());
|
||||
rim.setPlatformManufacturer(bRim.getPlatformManufacturer());
|
||||
rim.setPlatformModel(bRim.getPlatformModel());
|
||||
rim.setTagId(bRim.getTagId());
|
||||
rim.setAssociatedRim(bRim.getId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BaseReferenceManifest bRim = (BaseReferenceManifest) rim;
|
||||
for (SwidResource swid : bRim.parseResource()) {
|
||||
if (element instanceof SupportReferenceManifest) {
|
||||
SupportReferenceManifest sRim = (SupportReferenceManifest) element;
|
||||
if (swid.getName().equals(sRim.getFileName())) {
|
||||
sRim.setPlatformManufacturer(bRim.getPlatformManufacturer());
|
||||
sRim.setPlatformModel(bRim.getPlatformModel());
|
||||
sRim.setSwidTagVersion(bRim.getSwidTagVersion());
|
||||
sRim.setTagId(bRim.getTagId());
|
||||
rim.setAssociatedRim(sRim.getId());
|
||||
try {
|
||||
referenceManifestManager.update(sRim);
|
||||
} catch (DBManagerException dbmEx) {
|
||||
LOGGER.error(String.format("Couldn't update Support RIM "
|
||||
+ "%s with associated UUID %s", rim.getTagId(),
|
||||
sRim.getId()), dbmEx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Store only if it was parsed
|
||||
if (rim != null) {
|
||||
@ -313,11 +333,18 @@ public class ReferenceManifestPageController
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
} else {
|
||||
StringBuilder fileName = new StringBuilder("filename=\"");
|
||||
fileName.append(referenceManifest.getSwidName());
|
||||
fileName.append("_[");
|
||||
fileName.append(referenceManifest.getRimHash());
|
||||
fileName.append("]");
|
||||
fileName.append(".swidTag\"");
|
||||
if (referenceManifest.getRimType().equals(ReferenceManifest.BASE_RIM)) {
|
||||
BaseReferenceManifest bRim = (BaseReferenceManifest) referenceManifest;
|
||||
fileName.append(bRim.getSwidName());
|
||||
fileName.append("_[");
|
||||
fileName.append(referenceManifest.getRimHash());
|
||||
fileName.append("]");
|
||||
fileName.append(".swidTag\"");
|
||||
} else {
|
||||
// this needs to be updated for support rims
|
||||
SupportReferenceManifest bRim = (SupportReferenceManifest) referenceManifest;
|
||||
fileName.append(bRim.getFileName());
|
||||
}
|
||||
|
||||
// Set filename for download.
|
||||
response.setHeader("Content-Disposition", "attachment;" + fileName);
|
||||
@ -360,7 +387,7 @@ public class ReferenceManifestPageController
|
||||
* @return a single or collection of reference manifest files.
|
||||
*/
|
||||
private ReferenceManifest parseRIM(
|
||||
final MultipartFile file,
|
||||
final MultipartFile file, final boolean supportRIM,
|
||||
final PageMessages messages) {
|
||||
|
||||
byte[] fileBytes;
|
||||
@ -378,7 +405,11 @@ public class ReferenceManifestPageController
|
||||
}
|
||||
|
||||
try {
|
||||
return new ReferenceManifest(fileBytes);
|
||||
if (supportRIM) {
|
||||
return new SupportReferenceManifest(fileName, fileBytes);
|
||||
} else {
|
||||
return new BaseReferenceManifest(fileName, fileBytes);
|
||||
}
|
||||
// the this is a List<Object> is object is a JaxBElement that can
|
||||
// be matched up to the QName
|
||||
} catch (IOException ioEx) {
|
||||
|
@ -30,6 +30,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tag ID</th>
|
||||
<th>Type</th>
|
||||
<th>Manufacturer</th>
|
||||
<th>Model</th>
|
||||
<th>Version</th>
|
||||
@ -44,9 +45,10 @@
|
||||
var url = pagePath +'/list';
|
||||
var columns = [
|
||||
{data: 'tagId'},
|
||||
{data: 'rimType'},
|
||||
{data: 'platformManufacturer'},
|
||||
{data: 'platformModel'},
|
||||
{data: 'firmwareVersion'},
|
||||
{data: 'swidTagVersion'},
|
||||
{
|
||||
data: 'id',
|
||||
orderable: false,
|
||||
|
@ -8,184 +8,288 @@
|
||||
<my:page>
|
||||
<jsp:attribute name="style">
|
||||
<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 name="pageHeaderTitle">
|
||||
Reference Integrity Manifest
|
||||
${initialData.rimType} Reference Integrity Manifest
|
||||
<a href="${portal}/reference-manifests/download?id=${param.id}">
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download Certificate">
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download ${initialData.rimType} RIM">
|
||||
</a>
|
||||
</jsp:attribute>
|
||||
<jsp:body>
|
||||
|
||||
<div id="certificate-details-page" class="container-fluid">
|
||||
<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: <span>${initialData.swidName}</span></div>
|
||||
<div>SWID Version: <span>${initialData.swidVersion}</span></div>
|
||||
<div>SWID Tag ID: <span>${initialData.swidTagId}</span></div>
|
||||
<div>SWID Tag Version: <span></span></div>
|
||||
<c:if test="${initialData.swidCorpus}">
|
||||
<div>SWID Corpus: <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: <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: <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: <span>${initialData.entityName}</span></div>
|
||||
<c:if test="${not empty initialData.entityRegId}">
|
||||
<div>Entity Reg ID: <span>${initialData.entityRegId}</span></div>
|
||||
</c:if>
|
||||
<div>Entity Role: <span>${initialData.entityRole}</span></div>
|
||||
<div>Entity Thumbprint: <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: <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: <span>${initialData.platformManufacturerId}</span></div>
|
||||
<div>Platform Manufacturer: <span>${initialData.platformManufacturer}</span></div>
|
||||
<div>Platform Model: <span>${initialData.platformModel}</span></div>
|
||||
<c:if test="${not empty initialData.platformVersion}">
|
||||
<div>Platform Version: <span>${initialData.platformVersion}</span></div>
|
||||
</c:if>
|
||||
<div>Colloquial Version: <span>${initialData.colloquialVersion}</span></div>
|
||||
<div>Edition: <span>${initialData.edition}</span></div>
|
||||
<div>Product: <span>${initialData.product}</span></div>
|
||||
<div>Revision: <span>${initialData.revision}</span></div>
|
||||
|
||||
<c:if test="${not empty initialData.payloadType}">
|
||||
<div>Payload Type: <span>${initialData.payloadType}</span></div>
|
||||
</c:if>
|
||||
<c:if test="${not empty initialData.firmwareVersion}">
|
||||
<div>Firmware Version: <span>${initialData.firmwareVersion}</span></div>
|
||||
</c:if>
|
||||
<div>Binding Spec: <span>${initialData.bindingSpec}</span></div>
|
||||
<div>Binding Spec Version: <span>${initialData.bindingSpecVersion}</span></div>
|
||||
<c:if test="${not empty initiaData.pcUriGlobal}">
|
||||
<div>PC URI Global: <span>${initialData.pcUriGlobal}</span></div>
|
||||
</c:if>
|
||||
<c:if test="${not empty initiaData.pcUriLocal}">
|
||||
<div>PC URI Local: <span>${initialData.pcUriLocal}</span></div>
|
||||
</c:if>
|
||||
<div>Rim Link Hash: <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
|
||||
<c:choose>
|
||||
<c:when test="${initialData.rimType=='Support'}">
|
||||
<div class="row">
|
||||
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Base RIM</span></div>
|
||||
<div id="baseRim" class="col col-md-8">
|
||||
<c:choose>
|
||||
<c:when test="${not empty initialData.associatedRim}">
|
||||
<a href="${portal}/rim-details?id=${initialData.associatedRim}">
|
||||
${initialData.tagId}
|
||||
</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">
|
||||
${resource.getName()}
|
||||
</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>
|
||||
<c:forEach items="${resource.getPcrMap()}" var="pcrValue">
|
||||
<div id="componentIdentifier" class="row">
|
||||
<div>
|
||||
<span>${pcrValue.key}</span>
|
||||
<span style="overflow-wrap: break-word">${pcrValue.value}</span>
|
||||
</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>
|
||||
</div>
|
||||
<div id="tableDivTag">
|
||||
<input type="text" id="eventInput" onkeyup="eventSearch()" placeholder="Search for text..." /><br />
|
||||
<table id="eventLog">
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th>Event #</th>
|
||||
<th>PCR Index</th>
|
||||
<th style="width: 20%">Event Type</th>
|
||||
<th>Digest</th>
|
||||
<th style="width: 50%">Event Content</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<c:if test="${not empty initialData.events}">
|
||||
<c:set var="count" value="1" scope="page"/>
|
||||
<c:forEach items="${initialData.events}" var="event">
|
||||
<tr>
|
||||
<td style="width: 75px">${count}</td>
|
||||
<td class="pcrCell">PCR${event.getPcrIndex()}</td>
|
||||
<td>${event.getEventTypeStr()}</td>
|
||||
<td class="digestCell">${event.getEventDigestStr()}</td>
|
||||
<td title="${event.getEventContentStr()}"><div style="height: 50px; overflow: auto">${event.getEventContentStr()}</div></td>
|
||||
</tr>
|
||||
<c:set var="count" value="${count + 1}" scope="page"/>
|
||||
</c:forEach>
|
||||
</c:if>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-a col-md-offset-1"><span class="colHeader">${initialData.events.size()} entries</span></div>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<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: <span>${initialData.swidName}</span></div>
|
||||
<div>SWID Version: <span>${initialData.swidVersion}</span></div>
|
||||
<div>SWID Tag ID: <span>${initialData.swidTagId}</span></div>
|
||||
<div>SWID Tag Version: <span>${initialData.swidTagVersion}</span></div>
|
||||
<c:if test="${initialData.swidCorpus}">
|
||||
<div>SWID Corpus: <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: <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: <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: <span>${initialData.entityName}</span></div>
|
||||
<c:if test="${not empty initialData.entityRegId}">
|
||||
<div>Entity Reg ID: <span>${initialData.entityRegId}</span></div>
|
||||
</c:if>
|
||||
<div>Entity Role: <span>${initialData.entityRole}</span></div>
|
||||
<div>Entity Thumbprint: <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: <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: <span>${initialData.platformManufacturerId}</span></div>
|
||||
<div>Platform Manufacturer: <span>${initialData.platformManufacturer}</span></div>
|
||||
<div>Platform Model: <span>${initialData.platformModel}</span></div>
|
||||
<c:if test="${not empty initialData.platformVersion}">
|
||||
<div>Platform Version: <span>${initialData.platformVersion}</span></div>
|
||||
</c:if>
|
||||
<div>Colloquial Version: <span>${initialData.colloquialVersion}</span></div>
|
||||
<div>Edition: <span>${initialData.edition}</span></div>
|
||||
<div>Product: <span>${initialData.product}</span></div>
|
||||
<div>Revision: <span>${initialData.revision}</span></div>
|
||||
|
||||
<c:if test="${not empty initialData.payloadType}">
|
||||
<div>Payload Type: <span>${initialData.payloadType}</span></div>
|
||||
</c:if>
|
||||
<div>Binding Spec: <span>${initialData.bindingSpec}</span></div>
|
||||
<div>Binding Spec Version: <span>${initialData.bindingSpecVersion}</span></div>
|
||||
<c:if test="${not empty initiaData.pcUriGlobal}">
|
||||
<div>PC URI Global: <span>${initialData.pcUriGlobal}</span></div>
|
||||
</c:if>
|
||||
<c:if test="${not empty initiaData.pcUriLocal}">
|
||||
<div>PC URI Local: <span>${initialData.pcUriLocal}</span></div>
|
||||
</c:if>
|
||||
<div>Rim Link Hash: <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>
|
||||
<c:forEach items="${resource.getPcrMap()}" var="pcrValue">
|
||||
<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>
|
||||
</c:forEach>
|
||||
</div>
|
||||
</div>
|
||||
</c:if>
|
||||
</div>
|
||||
</div>
|
||||
</c:if>
|
||||
</div>
|
||||
</c:when>
|
||||
<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:forEach>
|
||||
</div>
|
||||
</c:if>
|
||||
</div>
|
||||
</c:when>
|
||||
<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:forEach>
|
||||
</div>
|
||||
</c:if>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</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";
|
||||
}
|
||||
}
|
||||
}
|
||||
window.onload = function() {
|
||||
// Constant retrieved from server-side via JSP
|
||||
var maxRows = 11;
|
||||
|
||||
var table = document.getElementById('eventLog');
|
||||
var wrapper = table.parentNode;
|
||||
var rowsInTable = table.rows.length;
|
||||
var height = 0;
|
||||
if (rowsInTable > maxRows) {
|
||||
for (var i = 0; i < maxRows; i++) {
|
||||
height += table.rows[i].clientHeight;
|
||||
}
|
||||
wrapper.style.height = height + "px";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</jsp:body>
|
||||
</my:page>
|
||||
|
@ -16,6 +16,7 @@
|
||||
font-weight: bold;
|
||||
margin: auto 0;
|
||||
}
|
||||
|
||||
#platformID {
|
||||
display: inline;
|
||||
}
|
||||
@ -62,4 +63,4 @@
|
||||
margin: 4px 2px;
|
||||
cursor: pointer;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
#eventInput {
|
||||
width: 100%;
|
||||
font-size: 16px; /* Increase font-size */
|
||||
padding: 12px 20px 12px 40px; /* Add some padding */
|
||||
border: 1px solid #ddd; /* Add a grey border */
|
||||
margin-bottom: 12px; /* Add some space below the input */
|
||||
}
|
||||
|
||||
#tableDivTag {
|
||||
padding-top: 5px;
|
||||
padding-left: 125px;
|
||||
padding-right: 150px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
#eventLog {
|
||||
border-collapse: collapse; /* Collapse borders */
|
||||
width: 100%;
|
||||
border: 1px solid #ddd; /* Add a grey border */
|
||||
font-size: 14px; /* Increase font-size */
|
||||
}
|
||||
|
||||
#eventLog th, #eventLog td {
|
||||
text-align: left; /* Left-align text */
|
||||
padding: 10px; /* Add padding */
|
||||
}
|
||||
|
||||
#eventLog tr {
|
||||
/* Add a bottom border to all table rows */
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
#eventLog tr.header, #eventLog tr:hover {
|
||||
/* Add a grey background color to the table header and on hover */
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.dataCell {
|
||||
display: table-cell;
|
||||
padding: 2px 15px 2px 15px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
width: auto;
|
||||
max-width: 1px;
|
||||
}
|
||||
|
||||
.digestCell {
|
||||
max-width: 200px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.pcrCell {
|
||||
max-width: 50px;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package hirs.attestationca.portal.page.controllers;
|
||||
|
||||
import hirs.data.persist.BaseReferenceManifest;
|
||||
import hirs.data.persist.ReferenceManifest;
|
||||
import hirs.persist.DBReferenceManifestManager;
|
||||
import hirs.attestationca.portal.page.Page;
|
||||
@ -52,7 +53,7 @@ public class ReferenceManifestDetailsPageControllerTest extends PageControllerTe
|
||||
} catch (URISyntaxException 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);
|
||||
}
|
||||
|
||||
|
@ -522,8 +522,8 @@ string CommandTpm2::createNvWriteCommandArgs(const string& nvIndex,
|
||||
/**
|
||||
* Method to get a quote (signed pcr selection) from the TPM 2.0 device.
|
||||
*
|
||||
* @param akLocation location of an activated AK pair
|
||||
* @param pcrSelection selection of pcrs to sign
|
||||
* @param nonce blob provided by the ACA when the Identity Claim Request
|
||||
* @param pcr_election selection of pcrs to sign
|
||||
*/
|
||||
string CommandTpm2::getQuote(const string& pcr_selection,
|
||||
const string& nonce) {
|
||||
|
@ -0,0 +1,765 @@
|
||||
package hirs.data.persist;
|
||||
|
||||
import hirs.persist.DBReferenceManifestManager;
|
||||
import hirs.utils.xjc.BaseElement;
|
||||
import hirs.utils.xjc.Directory;
|
||||
import hirs.utils.xjc.FilesystemItem;
|
||||
import hirs.utils.xjc.Meta;
|
||||
import hirs.utils.xjc.ResourceCollection;
|
||||
import hirs.utils.xjc.SoftwareIdentity;
|
||||
import hirs.utils.xjc.SoftwareMeta;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.UnmarshalException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.validation.Schema;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
public class BaseReferenceManifest extends ReferenceManifest {
|
||||
private static final Logger LOGGER = LogManager.getLogger(BaseReferenceManifest.class);
|
||||
|
||||
private static JAXBContext jaxbContext;
|
||||
|
||||
@Column
|
||||
private String swidName = null;
|
||||
@Column
|
||||
private String swidVersion = null;
|
||||
@Column
|
||||
private int swidCorpus = 0;
|
||||
@Column
|
||||
private int swidPatch = 0;
|
||||
@Column
|
||||
private int swidSupplemental = 0;
|
||||
@Column
|
||||
private String colloquialVersion = null;
|
||||
@Column
|
||||
private String product = null;
|
||||
@Column
|
||||
private String revision = null;
|
||||
@Column
|
||||
private String edition = null;
|
||||
@Column
|
||||
private String rimLinkHash = null;
|
||||
@Column
|
||||
private String bindingSpec = null;
|
||||
@Column
|
||||
private String bindingSpecVersion = null;
|
||||
@Column
|
||||
private String platformVersion = null;
|
||||
@Column
|
||||
private String payloadType = null;
|
||||
@Column
|
||||
private String pcURIGlobal = null;
|
||||
@Column
|
||||
private String pcURILocal = null;
|
||||
|
||||
private String entityName = null;
|
||||
private String entityRegId = null;
|
||||
private String entityRole = null;
|
||||
private String entityThumbprint = null;
|
||||
private String linkHref = null;
|
||||
private String linkRel = null;
|
||||
|
||||
/**
|
||||
* Support constructor for the RIM object.
|
||||
*
|
||||
* @param fileName - string representation of the uploaded file.
|
||||
* @param rimBytes - the file content of the uploaded file.
|
||||
* @throws IOException - thrown if the file is invalid.
|
||||
*/
|
||||
public BaseReferenceManifest(final String fileName, final byte[] rimBytes) throws IOException {
|
||||
this(rimBytes);
|
||||
this.setFileName(fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main constructor for the RIM object. This takes in a byte array of a
|
||||
* valid swidtag file and parses the information.
|
||||
*
|
||||
* @param rimBytes byte array representation of the RIM
|
||||
* @throws IOException if unable to unmarshal the string
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:AvoidInlineConditionals")
|
||||
public BaseReferenceManifest(final byte[] rimBytes) throws IOException {
|
||||
super(rimBytes);
|
||||
this.setRimType(BASE_RIM);
|
||||
SoftwareIdentity si = validateSwidTag(new ByteArrayInputStream(rimBytes));
|
||||
|
||||
// begin parsing valid swid tag
|
||||
if (si != null) {
|
||||
setTagId(si.getTagId());
|
||||
this.swidName = si.getName();
|
||||
this.swidCorpus = si.isCorpus() ? 1 : 0;
|
||||
this.swidPatch = si.isPatch() ? 1 : 0;
|
||||
this.swidSupplemental = si.isSupplemental() ? 1 : 0;
|
||||
this.swidVersion = si.getVersion();
|
||||
if (si.getTagVersion() != null) {
|
||||
this.setSwidTagVersion(si.getTagVersion().toString());
|
||||
}
|
||||
|
||||
for (Object object : si.getEntityOrEvidenceOrLink()) {
|
||||
if (object instanceof JAXBElement) {
|
||||
JAXBElement element = (JAXBElement) object;
|
||||
String elementName = element.getName().getLocalPart();
|
||||
switch (elementName) {
|
||||
case "Meta":
|
||||
parseSoftwareMeta((SoftwareMeta) element.getValue());
|
||||
break;
|
||||
case "Entity":
|
||||
hirs.utils.xjc.Entity entity
|
||||
= (hirs.utils.xjc.Entity) element.getValue();
|
||||
if (entity != null) {
|
||||
this.entityName = entity.getName();
|
||||
this.entityRegId = entity.getRegid();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String role : entity.getRole()) {
|
||||
sb.append(String.format("%s%n", role));
|
||||
}
|
||||
this.entityRole = sb.toString();
|
||||
this.entityThumbprint = entity.getThumbprint();
|
||||
}
|
||||
break;
|
||||
case "Link":
|
||||
hirs.utils.xjc.Link link
|
||||
= (hirs.utils.xjc.Link) element.getValue();
|
||||
if (link != null) {
|
||||
this.linkHref = link.getHref();
|
||||
this.linkRel = link.getRel();
|
||||
}
|
||||
break;
|
||||
case "Payload":
|
||||
parseResource((ResourceCollection) element.getValue());
|
||||
break;
|
||||
case "Signature":
|
||||
// left blank for a followup issue enhancement
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor necessary for Hibernate.
|
||||
*/
|
||||
protected BaseReferenceManifest() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method and code is pulled and adopted from the TCG Tool. Since this
|
||||
* is taking in an file stored in memory through http, this was changed from
|
||||
* a file to a stream as the input.
|
||||
*
|
||||
* @param fileStream stream of the swidtag file.
|
||||
* @return a {@link SoftwareIdentity} object
|
||||
* @throws IOException Thrown by the unmarhsallSwidTag method.
|
||||
*/
|
||||
private SoftwareIdentity validateSwidTag(final InputStream fileStream) throws IOException {
|
||||
JAXBElement jaxbe = unmarshallSwidTag(fileStream);
|
||||
SoftwareIdentity swidTag = (SoftwareIdentity) jaxbe.getValue();
|
||||
|
||||
LOGGER.info(String.format("SWID Tag found: %nname: %s;%ntagId: %s%n%s",
|
||||
swidTag.getName(), swidTag.getTagId(), SCHEMA_STATEMENT));
|
||||
return swidTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that is used to parse a specific element of the SwidTag
|
||||
* based on an already established and stored byte array.
|
||||
*
|
||||
* @param elementName string of an xml tag in the file.
|
||||
* @return the object value of the element, if it exists
|
||||
*/
|
||||
private BaseElement getBaseElementFromBytes(final String elementName) {
|
||||
BaseElement baseElement = null;
|
||||
|
||||
if (getRimBytes() != null && elementName != null) {
|
||||
try {
|
||||
SoftwareIdentity si = validateSwidTag(new ByteArrayInputStream(getRimBytes()));
|
||||
JAXBElement element;
|
||||
for (Object object : si.getEntityOrEvidenceOrLink()) {
|
||||
if (object instanceof JAXBElement) {
|
||||
element = (JAXBElement) object;
|
||||
if (element.getName().getLocalPart().equals(elementName)) {
|
||||
// found the element
|
||||
baseElement = (BaseElement) element.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IOException ioEx) {
|
||||
LOGGER.error("Failed to parse Swid Tag bytes.", ioEx);
|
||||
}
|
||||
}
|
||||
|
||||
return baseElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default method for parsing the payload element.
|
||||
*
|
||||
* @return a collection of payload objects.
|
||||
*/
|
||||
public final List<SwidResource> parseResource() {
|
||||
return parseResource((ResourceCollection) this.getBaseElementFromBytes("Payload"));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method parses the payload method of a {@link ResourceCollection}.
|
||||
*
|
||||
* @param rc Resource Collection object.
|
||||
* @return a collection of payload objects.
|
||||
*/
|
||||
public final List<SwidResource> parseResource(final ResourceCollection rc) {
|
||||
List<SwidResource> resources = new ArrayList<>();
|
||||
|
||||
try {
|
||||
if (rc != null) {
|
||||
for (Meta meta : rc.getDirectoryOrFileOrProcess()) {
|
||||
if (meta != null) {
|
||||
if (meta instanceof Directory) {
|
||||
Directory directory = (Directory) meta;
|
||||
for (FilesystemItem fsi : directory.getDirectoryOrFile()) {
|
||||
if (fsi != null) {
|
||||
resources.add(new SwidResource(
|
||||
(hirs.utils.xjc.File) fsi, null));
|
||||
}
|
||||
}
|
||||
} else if (meta instanceof hirs.utils.xjc.File) {
|
||||
resources.add(new SwidResource((hirs.utils.xjc.File) meta, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ClassCastException ccEx) {
|
||||
LOGGER.error(ccEx);
|
||||
LOGGER.error("At this time, the code does not support the "
|
||||
+ "particular formatting of this SwidTag's Payload.");
|
||||
}
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method unmarshalls the swidtag found at [path] and validates it
|
||||
* according to the schema.
|
||||
*
|
||||
* @param stream to the input swidtag
|
||||
* @return the SoftwareIdentity element at the root of the swidtag
|
||||
* @throws IOException if the swidtag cannot be unmarshalled or validated
|
||||
*/
|
||||
private JAXBElement unmarshallSwidTag(final InputStream stream) throws IOException {
|
||||
JAXBElement jaxbe = null;
|
||||
Schema schema;
|
||||
|
||||
try {
|
||||
schema = DBReferenceManifestManager.getSchemaObject();
|
||||
if (jaxbContext == null) {
|
||||
jaxbContext = JAXBContext.newInstance(SCHEMA_PACKAGE);
|
||||
}
|
||||
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
|
||||
unmarshaller.setSchema(schema);
|
||||
jaxbe = (JAXBElement) unmarshaller.unmarshal(stream);
|
||||
} catch (UnmarshalException umEx) {
|
||||
LOGGER.error(String.format("Error validating swidtag file!%n%s%n%s",
|
||||
umEx.getMessage(), umEx.toString()));
|
||||
for (StackTraceElement ste : umEx.getStackTrace()) {
|
||||
LOGGER.error(ste.toString());
|
||||
}
|
||||
} catch (IllegalArgumentException iaEx) {
|
||||
LOGGER.error("Input file empty.");
|
||||
} catch (JAXBException jaxEx) {
|
||||
for (StackTraceElement ste : jaxEx.getStackTrace()) {
|
||||
LOGGER.error(ste.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (jaxbe != null) {
|
||||
return jaxbe;
|
||||
} else {
|
||||
throw new IOException("Invalid Base RIM, swidtag format expected.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a helper method that parses the SoftwareMeta tag and stores the
|
||||
* information in the class fields.
|
||||
*
|
||||
* @param softwareMeta The object to parse.
|
||||
*/
|
||||
private void parseSoftwareMeta(final SoftwareMeta softwareMeta) {
|
||||
if (softwareMeta != null) {
|
||||
for (Map.Entry<QName, String> entry
|
||||
: softwareMeta.getOtherAttributes().entrySet()) {
|
||||
switch (entry.getKey().getLocalPart()) {
|
||||
case "colloquialVersion":
|
||||
this.colloquialVersion = entry.getValue();
|
||||
break;
|
||||
case "product":
|
||||
this.product = entry.getValue();
|
||||
break;
|
||||
case "revision":
|
||||
this.revision = entry.getValue();
|
||||
break;
|
||||
case "edition":
|
||||
this.edition = entry.getValue();
|
||||
break;
|
||||
case "rimLinkHash":
|
||||
this.rimLinkHash = entry.getValue();
|
||||
break;
|
||||
case "bindingSpec":
|
||||
this.bindingSpec = entry.getValue();
|
||||
break;
|
||||
case "bindingSpecVersion":
|
||||
this.bindingSpecVersion = entry.getValue();
|
||||
break;
|
||||
case "platformManufacturerId":
|
||||
this.setPlatformManufacturerId(entry.getValue());
|
||||
break;
|
||||
case "platformModel":
|
||||
this.setPlatformModel(entry.getValue());
|
||||
break;
|
||||
case "platformManufacturerStr":
|
||||
this.setPlatformManufacturer(entry.getValue());
|
||||
break;
|
||||
case "platformVersion":
|
||||
this.platformVersion = entry.getValue();
|
||||
break;
|
||||
case "payloadType":
|
||||
this.payloadType = entry.getValue();
|
||||
break;
|
||||
case "pcURIGlobal":
|
||||
this.pcURIGlobal = entry.getValue();
|
||||
break;
|
||||
case "pcURILocal":
|
||||
this.pcURILocal = entry.getValue();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the SWID name parameter.
|
||||
*
|
||||
* @return string representation of the SWID name
|
||||
*/
|
||||
public String getSwidName() {
|
||||
return swidName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the SWID name parameter.
|
||||
*
|
||||
* @param swidName string of the name
|
||||
*/
|
||||
public void setSwidName(final String swidName) {
|
||||
this.swidName = swidName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the SWID version.
|
||||
*
|
||||
* @return string of the version number
|
||||
*/
|
||||
public String getSwidVersion() {
|
||||
return swidVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the SWID version.
|
||||
*
|
||||
* @param swidVersion string of the version
|
||||
*/
|
||||
public void setSwidVersion(final String swidVersion) {
|
||||
this.swidVersion = swidVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the corpus flag.
|
||||
*
|
||||
* @return int flag for corpus
|
||||
*/
|
||||
public int isSwidCorpus() {
|
||||
return swidCorpus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the corpus flag.
|
||||
*
|
||||
* @param swidCorpus int value
|
||||
*/
|
||||
public void setSwidCorpus(final int swidCorpus) {
|
||||
this.swidCorpus = swidCorpus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the patch flag.
|
||||
*
|
||||
* @return int flag for the patch flag
|
||||
*/
|
||||
public int isSwidPatch() {
|
||||
return swidPatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the patch flag.
|
||||
*
|
||||
* @param swidPatch int value
|
||||
*/
|
||||
public void setSwidPatch(final int swidPatch) {
|
||||
this.swidPatch = swidPatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the supplemental flag.
|
||||
*
|
||||
* @return int flag for the supplemental flag
|
||||
*/
|
||||
public int isSwidSupplemental() {
|
||||
return swidSupplemental;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the supplemental flag.
|
||||
*
|
||||
* @param swidSupplemental int value
|
||||
*/
|
||||
public void setSwidSupplemental(final int swidSupplemental) {
|
||||
this.swidSupplemental = swidSupplemental;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Entity Name.
|
||||
*
|
||||
* @return string of the entity name.
|
||||
*/
|
||||
public String getEntityName() {
|
||||
return entityName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Entity Name.
|
||||
*
|
||||
* @param entityName string of the entity name.
|
||||
*/
|
||||
public void setEntityName(final String entityName) {
|
||||
this.entityName = entityName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Entity Reg ID.
|
||||
*
|
||||
* @return string of the entity reg id.
|
||||
*/
|
||||
public String getEntityRegId() {
|
||||
return entityRegId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Entity Reg ID.
|
||||
*
|
||||
* @param entityRegId string of the entity reg id.
|
||||
*/
|
||||
public void setEntityRegId(final String entityRegId) {
|
||||
this.entityRegId = entityRegId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Entity Role.
|
||||
*
|
||||
* @return string of the entity role.
|
||||
*/
|
||||
public String getEntityRole() {
|
||||
return entityRole;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Entity Role.
|
||||
*
|
||||
* @param entityRole string of the entity role .
|
||||
*/
|
||||
public void setEntityRole(final String entityRole) {
|
||||
this.entityRole = entityRole;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Entity thumbprint.
|
||||
*
|
||||
* @return string of the entity thumbprint.
|
||||
*/
|
||||
public String getEntityThumbprint() {
|
||||
return entityThumbprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Entity Thumbprint.
|
||||
*
|
||||
* @param entityThumbprint string of the entity thumbprint.
|
||||
*/
|
||||
public void setEntityThumbprint(final String entityThumbprint) {
|
||||
this.entityThumbprint = entityThumbprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Link Href.
|
||||
*
|
||||
* @return string of the link href.
|
||||
*/
|
||||
public String getLinkHref() {
|
||||
return linkHref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Link href.
|
||||
*
|
||||
* @param linkHref in string representation.
|
||||
*/
|
||||
public void setLinkHref(final String linkHref) {
|
||||
this.linkHref = linkHref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Link Rel.
|
||||
*
|
||||
* @return string of the link rel
|
||||
*/
|
||||
public String getLinkRel() {
|
||||
return linkRel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Link Rel.
|
||||
*
|
||||
* @param linkRel in string representation.
|
||||
*/
|
||||
public void setLinkRel(final String linkRel) {
|
||||
this.linkRel = linkRel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for Colloquial Version.
|
||||
*
|
||||
* @return string of the colloquial version.
|
||||
*/
|
||||
public String getColloquialVersion() {
|
||||
return colloquialVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for Colloquial Version.
|
||||
*
|
||||
* @param colloquialVersion in string representation.
|
||||
*/
|
||||
public void setColloquialVersion(final String colloquialVersion) {
|
||||
this.colloquialVersion = colloquialVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for Product.
|
||||
*
|
||||
* @return string of the product information
|
||||
*/
|
||||
public String getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Product.
|
||||
*
|
||||
* @param product in string representation.
|
||||
*/
|
||||
public void setProduct(final String product) {
|
||||
this.product = product;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Revision string.
|
||||
*
|
||||
* @return string of revision information.
|
||||
*/
|
||||
public String getRevision() {
|
||||
return revision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Revision.
|
||||
*
|
||||
* @param revision in string representation.
|
||||
*/
|
||||
public void setRevision(final String revision) {
|
||||
this.revision = revision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Edition.
|
||||
*
|
||||
* @return string of edition information.
|
||||
*/
|
||||
public String getEdition() {
|
||||
return edition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Edition string.
|
||||
*
|
||||
* @param edition in string representation.
|
||||
*/
|
||||
public void setEdition(final String edition) {
|
||||
this.edition = edition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the RIM Link Hash.
|
||||
*
|
||||
* @return string of the RIM link hash.
|
||||
*/
|
||||
public String getRimLinkHash() {
|
||||
return rimLinkHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the RIM link hash.
|
||||
*
|
||||
* @param rimLinkHash in string representation.
|
||||
*/
|
||||
public void setRimLinkHash(final String rimLinkHash) {
|
||||
this.rimLinkHash = rimLinkHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Binding Spec.
|
||||
*
|
||||
* @return string of Binding spec.
|
||||
*/
|
||||
public String getBindingSpec() {
|
||||
return bindingSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Binding Spec.
|
||||
*
|
||||
* @param bindingSpec in string representation.
|
||||
*/
|
||||
public void setBindingSpec(final String bindingSpec) {
|
||||
this.bindingSpec = bindingSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Binding Spec Version.
|
||||
*
|
||||
* @return string of binding spec version.
|
||||
*/
|
||||
public String getBindingSpecVersion() {
|
||||
return bindingSpecVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the binding spec version.
|
||||
*
|
||||
* @param bindingSpecVersion in string representation.
|
||||
*/
|
||||
public void setBindingSpecVersion(final String bindingSpecVersion) {
|
||||
this.bindingSpecVersion = bindingSpecVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Platform Version.
|
||||
*
|
||||
* @return string of platform version.
|
||||
*/
|
||||
public String getPlatformVersion() {
|
||||
return platformVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Platform Version.
|
||||
*
|
||||
* @param platformVersion in string representation.
|
||||
*/
|
||||
public void setPlatformVersion(final String platformVersion) {
|
||||
this.platformVersion = platformVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Payload Type.
|
||||
*
|
||||
* @return string of payload type.
|
||||
*/
|
||||
public String getPayloadType() {
|
||||
return payloadType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Payload type.
|
||||
*
|
||||
* @param payloadType in string representation.
|
||||
*/
|
||||
public void setPayloadType(final String payloadType) {
|
||||
this.payloadType = payloadType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the PC URI Global.
|
||||
*
|
||||
* @return string of Pc URI Global.
|
||||
*/
|
||||
public String getPcURIGlobal() {
|
||||
return pcURIGlobal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the PC URI Global.
|
||||
*
|
||||
* @param pcURIGlobal in string representation.
|
||||
*/
|
||||
public void setPcURIGlobal(final String pcURIGlobal) {
|
||||
this.pcURIGlobal = pcURIGlobal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the PC URI Local.
|
||||
*
|
||||
* @return string of PC URI Local.
|
||||
*/
|
||||
public String getPcURILocal() {
|
||||
return pcURILocal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the PC URI Local.
|
||||
*
|
||||
* @param pcURILocal in string representation.
|
||||
*/
|
||||
public void setPcURILocal(final String pcURILocal) {
|
||||
this.pcURILocal = pcURILocal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("ReferenceManifest{swidName=%s,"
|
||||
+ "platformManufacturer=%s,"
|
||||
+ " platformModel=%s,"
|
||||
+ "tagId=%s, rimHash=%d}",
|
||||
swidName, this.getPlatformManufacturer(),
|
||||
this.getPlatformModel(), getTagId(), this.getRimHash());
|
||||
}
|
||||
}
|
@ -120,6 +120,12 @@ public final class PCRPolicy extends Policy {
|
||||
tpmQuote, pcrComposite);
|
||||
|
||||
try {
|
||||
/**
|
||||
* The calculated string is being used in the contains method
|
||||
* because the TPM Quote's hash isn't just for PCR values,
|
||||
* it contains the calculated digest of the PCRs, along with
|
||||
* other information.
|
||||
*/
|
||||
String calculatedString = Hex.encodeHexString(
|
||||
pcrInfoShort.getCalculatedDigest());
|
||||
validated = quoteString.contains(calculatedString);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,122 @@
|
||||
package hirs.data.persist;
|
||||
|
||||
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.Logger;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
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.
|
||||
*/
|
||||
@Entity
|
||||
public class SupportReferenceManifest extends ReferenceManifest {
|
||||
private static final Logger LOGGER = LogManager.getLogger(SupportReferenceManifest.class);
|
||||
|
||||
@Column
|
||||
@JsonIgnore
|
||||
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
|
||||
* valid swidtag file and parses the information.
|
||||
*
|
||||
* @param rimBytes byte array representation of the RIM
|
||||
* @throws IOException if unable to unmarshal the string
|
||||
*/
|
||||
public SupportReferenceManifest(final byte[] rimBytes) throws IOException {
|
||||
super(rimBytes);
|
||||
this.setRimType(SUPPORT_RIM);
|
||||
this.pcrHash = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor necessary for Hibernate.
|
||||
*/
|
||||
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() {
|
||||
return pcrHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the PCR Hash.
|
||||
* @param pcrHash hash in int form
|
||||
*/
|
||||
public void setPcrHash(final int pcrHash) {
|
||||
this.pcrHash = pcrHash;
|
||||
}
|
||||
}
|
@ -1075,7 +1075,7 @@ public abstract class Certificate extends ArchivableEntity {
|
||||
*/
|
||||
@JsonIgnore
|
||||
public byte[] getRawBytes() {
|
||||
if (null != this.certificateBytes) {
|
||||
if (this.certificateBytes != null) {
|
||||
return this.certificateBytes.clone();
|
||||
}
|
||||
return null;
|
||||
|
@ -28,6 +28,7 @@ public abstract class ReferenceManifestSelector<ReferenceManifest> {
|
||||
private static final String PLATFORM_MANUFACTURER_ID = "platformManufacturerId";
|
||||
private static final String PLATFORM_MODEL = "platformModel";
|
||||
private static final String RIM_TYPE_FIELD = "rimType";
|
||||
private static final String RIM_FILENAME_FIELD = "fileName";
|
||||
|
||||
private final ReferenceManifestManager referenceManifestManager;
|
||||
|
||||
@ -116,6 +117,16 @@ public abstract class ReferenceManifestSelector<ReferenceManifest> {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the file name of the object to grab.
|
||||
* @param fileName the name of the file associated with the rim
|
||||
* @return instance of the manifest in relation to the filename.
|
||||
*/
|
||||
public ReferenceManifestSelector byFileName(final String fileName) {
|
||||
setFieldValue(RIM_FILENAME_FIELD, fileName);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the RIM Type to match.
|
||||
* @param rimType the type of rim
|
||||
@ -124,7 +135,7 @@ public abstract class ReferenceManifestSelector<ReferenceManifest> {
|
||||
public ReferenceManifestSelector byRimType(final String rimType) {
|
||||
setFieldValue(RIM_TYPE_FIELD, rimType);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a field name and value to match.
|
||||
@ -171,11 +182,11 @@ public abstract class ReferenceManifestSelector<ReferenceManifest> {
|
||||
* @return a matching RIM or null if none is found
|
||||
*/
|
||||
public hirs.data.persist.ReferenceManifest getRIM() {
|
||||
Set<hirs.data.persist.ReferenceManifest> certs = execute();
|
||||
if (certs.isEmpty()) {
|
||||
Set<hirs.data.persist.ReferenceManifest> rims = execute();
|
||||
if (rims.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return certs.iterator().next();
|
||||
return rims.iterator().next();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,6 +77,7 @@ public final class TCGEventLog {
|
||||
private boolean bEvent = false;
|
||||
/** Event Output Flag use. */
|
||||
private boolean bCryptoAgile = false;
|
||||
|
||||
/**
|
||||
* Default blank object constructor.
|
||||
*/
|
||||
@ -251,10 +252,12 @@ public final class TCGEventLog {
|
||||
public String[] getExpectedPCRValues() {
|
||||
String[] pcrs = new String[PCR_COUNT];
|
||||
for (int i = 0; i < PCR_COUNT; i++) {
|
||||
pcrs[i] = HexUtils.byteArrayToHexString(pcrList[i]);
|
||||
pcrs[i] = Hex.encodeHexString(pcrList[i]);
|
||||
}
|
||||
return pcrs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a flag which is set if the event log follows the "Crypto Agile" Format Type.
|
||||
* A false implies the type is SHA1 format.
|
||||
@ -263,6 +266,7 @@ public final class TCGEventLog {
|
||||
public boolean isCryptoAgile() {
|
||||
return bCryptoAgile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of event found in the Event Log.
|
||||
* @return an arraylist of event.
|
||||
@ -270,6 +274,7 @@ public final class TCGEventLog {
|
||||
public ArrayList<TpmPcrEvent> getEventList() {
|
||||
return eventList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single PCR value given an index (PCR Number).
|
||||
*
|
||||
@ -286,7 +291,7 @@ public final class TCGEventLog {
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (TpmPcrEvent event:eventList) {
|
||||
for (TpmPcrEvent event : eventList) {
|
||||
sb.append(event.toString(bEvent, bHexEvent, bContent));
|
||||
}
|
||||
sb.append("Event Log processing completed.\n");
|
||||
|
@ -2,6 +2,7 @@ package hirs.tpm.eventlog;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
@ -25,51 +26,82 @@ import hirs.tpm.eventlog.uefi.UefiConstants;
|
||||
import hirs.tpm.eventlog.uefi.UefiFirmware;
|
||||
import hirs.tpm.eventlog.uefi.UefiVariable;
|
||||
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.
|
||||
* TCG_PCR_EVENT is used when the Event log uses the SHA1 Format as described in the
|
||||
* TCG Platform Firmware Profile (PFP) specification.
|
||||
* typedef struct {
|
||||
* TCG_PCRINDEX PCRIndex; //PCR Index value that either
|
||||
* //matches the PCRIndex of a
|
||||
* //previous extend operation or
|
||||
* //indicates that this Event Log
|
||||
* //entry is not associated with
|
||||
* //an extend operation
|
||||
* TCG_EVENTTYPE EventType; //See Log event types defined in toStrng()
|
||||
* TCG_DIGEST digest; //The hash of the event data
|
||||
* UINT32 EventSize; //Size of the event data
|
||||
* UINT8 Event[EventSize]; //The event data
|
||||
* TCG_PCRINDEX PCRIndex; //PCR Index value that either
|
||||
* //matches the PCRIndex of a
|
||||
* //previous extend operation or
|
||||
* //indicates that this Event Log
|
||||
* //entry is not associated with
|
||||
* //an extend operation
|
||||
* TCG_EVENTTYPE EventType; //See Log event types defined in toStrng()
|
||||
* TCG_DIGEST digest; //The hash of the event data
|
||||
* UINT32 EventSize; //Size of the event data
|
||||
* UINT8 Event[EventSize]; //The event data
|
||||
* } TCG_PCR_EVENT;
|
||||
*/
|
||||
public class TpmPcrEvent {
|
||||
/** 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;
|
||||
/** 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 Logger LOGGER = LogManager.getLogger(TpmPcrEvent.class);
|
||||
/**
|
||||
* Indent Offset.
|
||||
*/
|
||||
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.
|
||||
@ -104,6 +136,14 @@ public class TpmPcrEvent {
|
||||
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.
|
||||
*
|
||||
@ -122,22 +162,25 @@ public class TpmPcrEvent {
|
||||
return pcrIndex;
|
||||
}
|
||||
|
||||
/** Sets the Log Format for this TCG Event.
|
||||
* 1 = SHA1 Format, 2 = Crypto Agile format.
|
||||
* @param format indicates log format.
|
||||
*/
|
||||
protected void setLogFormat(final int format) {
|
||||
logFormat = format;
|
||||
}
|
||||
/**
|
||||
* Sets the Log Format for this TCG Event.
|
||||
* 1 = SHA1 Format, 2 = Crypto Agile format.
|
||||
*
|
||||
* @param format indicates log format.
|
||||
*/
|
||||
protected void setLogFormat(final int format) {
|
||||
logFormat = format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Log Format for this TCG Event.
|
||||
* 1 = SHA1 Format, 2 = Crypto Agile format.
|
||||
* @return number representing the format.
|
||||
*/
|
||||
public int getLogFormat() {
|
||||
return logFormat;
|
||||
}
|
||||
/**
|
||||
* Gets the Log Format for this TCG Event.
|
||||
* 1 = SHA1 Format, 2 = Crypto Agile format.
|
||||
*
|
||||
* @return number representing the format.
|
||||
*/
|
||||
public int getLogFormat() {
|
||||
return logFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the EventType.
|
||||
@ -157,6 +200,14 @@ public class TpmPcrEvent {
|
||||
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.
|
||||
* only updated if the event is a TCG_EfiSpecIdEvent.
|
||||
@ -176,6 +227,7 @@ public class TpmPcrEvent {
|
||||
public String getSpecErrataVersion() {
|
||||
return errata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the event data after processing.
|
||||
*
|
||||
@ -189,11 +241,13 @@ public class TpmPcrEvent {
|
||||
/**
|
||||
* Gets the Event Data (no event content) for the event.
|
||||
* event log format.
|
||||
*
|
||||
* @return byte array holding the event structure.
|
||||
*/
|
||||
public byte[] getEvent() {
|
||||
return java.util.Arrays.copyOf(event, event.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the event content after processing.
|
||||
*
|
||||
@ -201,17 +255,168 @@ public class TpmPcrEvent {
|
||||
*/
|
||||
protected void setEventContent(final byte[] eventData) {
|
||||
eventContent = new byte[eventData.length];
|
||||
evPostCode = new EvPostCode(eventContent);
|
||||
System.arraycopy(eventData, 0, eventContent, 0, eventData.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the event Content Data (not the entire event structure).
|
||||
*
|
||||
* @return byte array holding the events content field
|
||||
*/
|
||||
public byte[] getEventContent() {
|
||||
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 cleanTextContent(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Digest Length.
|
||||
* Also the number of bytes expected within each PCR.
|
||||
@ -233,25 +438,26 @@ public class TpmPcrEvent {
|
||||
|
||||
/**
|
||||
* 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 eventNumber event position within the event log.
|
||||
* @param eventNumber event position within the event log.
|
||||
* @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 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)
|
||||
throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||
public String processEvent(final byte[] event, final byte[] eventContent, final int eventNumber)
|
||||
throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||
int eventID = (int) eventType;
|
||||
description += "Event# " + eventNumber + ": ";
|
||||
description += "Index PCR[" + getPcrIndex() + "]\n";
|
||||
description += "Event Type: 0x" + Long.toHexString(eventType) + " " + eventString(eventID);
|
||||
description += "\n";
|
||||
if (logFormat == 1) { // Digest
|
||||
description += "digest (SHA-1): " + HexUtils.byteArrayToHexString(this.digest);
|
||||
description += "digest (SHA-1): " + Hex.encodeHexString(this.digest);
|
||||
} else {
|
||||
description += "digest (SHA256): " + HexUtils.byteArrayToHexString(this.digest);
|
||||
description += "digest (SHA256): " + Hex.encodeHexString(this.digest);
|
||||
}
|
||||
if (eventID != UefiConstants.SIZE_4) {
|
||||
description += "\n";
|
||||
@ -268,11 +474,11 @@ public class TpmPcrEvent {
|
||||
switch (eventID) {
|
||||
case EvConstants.EV_PREBOOT_CERT:
|
||||
description += " EV_PREBOOT_CERT" + "\n";
|
||||
break;
|
||||
break;
|
||||
case EvConstants.EV_POST_CODE:
|
||||
EvPostCode postCode = new EvPostCode(eventContent);
|
||||
description += "Event Content:\n" + postCode.toString();
|
||||
break;
|
||||
description += "Event Content:\n" + postCode.toString();
|
||||
break;
|
||||
case EvConstants.EV_UNUSED:
|
||||
break;
|
||||
case EvConstants.EV_NO_ACTION:
|
||||
@ -286,15 +492,15 @@ public class TpmPcrEvent {
|
||||
break;
|
||||
case EvConstants.EV_SEPARATOR:
|
||||
if (EvPostCode.isAscii(eventContent)) {
|
||||
String seperatorEventData = new String(eventContent, StandardCharsets.UTF_8);
|
||||
if (!this.isEmpty(eventContent)) {
|
||||
description += "Seperator event content = " + seperatorEventData;
|
||||
String separatorEventData = new String(eventContent, StandardCharsets.UTF_8);
|
||||
if (!this.isBlank(eventContent)) {
|
||||
description += "Separator event content = " + separatorEventData;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EvConstants.EV_ACTION:
|
||||
description += "Event Content:\n"
|
||||
+ new String(eventContent, StandardCharsets.UTF_8);
|
||||
+ new String(eventContent, StandardCharsets.UTF_8);
|
||||
break;
|
||||
case EvConstants.EV_EVENT_TAG:
|
||||
EvEventTag eventTag = new EvEventTag(eventContent);
|
||||
@ -315,7 +521,7 @@ public class TpmPcrEvent {
|
||||
case EvConstants.EV_TABLE_OF_DEVICES:
|
||||
break;
|
||||
case EvConstants.EV_COMPACT_HASH:
|
||||
EvCompactHash compactHash = new EvCompactHash(eventContent);
|
||||
EvCompactHash compactHash = new EvCompactHash(eventContent);
|
||||
description += "Event Content:\n" + compactHash.toString();
|
||||
break;
|
||||
case EvConstants.EV_IPL:
|
||||
@ -338,7 +544,7 @@ public class TpmPcrEvent {
|
||||
UefiVariable efiVar = new UefiVariable(eventContent);
|
||||
String efiVarDescription = efiVar.toString().replace("\n", "\n ");
|
||||
description += "Event Content:\n " + efiVarDescription.substring(0,
|
||||
efiVarDescription.length() - INDENT_3);
|
||||
efiVarDescription.length() - INDENT_3);
|
||||
break;
|
||||
case EvConstants.EV_EFI_VARIABLE_BOOT:
|
||||
description += "Event Content:\n" + new UefiVariable(eventContent).toString();
|
||||
@ -361,7 +567,7 @@ public class TpmPcrEvent {
|
||||
break;
|
||||
case EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB:
|
||||
description += "Event Content:\n"
|
||||
+ new UefiFirmware(eventContent).toString();
|
||||
+ new UefiFirmware(eventContent).toString();
|
||||
break;
|
||||
case EvConstants.EV_EFI_HANDOFF_TABLES:
|
||||
EvEfiHandoffTable efiTable = new EvEfiHandoffTable(eventContent);
|
||||
@ -372,7 +578,8 @@ public class TpmPcrEvent {
|
||||
case EvConstants.EV_EFI_VARIABLE_AUTHORITY:
|
||||
description += "Event Content:\n" + new UefiVariable(eventContent).toString();
|
||||
break;
|
||||
default: description += " Unknown Event found" + "\n";
|
||||
default:
|
||||
description += " Unknown Event found" + "\n";
|
||||
}
|
||||
return description;
|
||||
}
|
||||
@ -380,152 +587,177 @@ public class TpmPcrEvent {
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param event 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) {
|
||||
return "EV_PREBOOT_CERT";
|
||||
} else if (event == EvConstants.EV_POST_CODE) {
|
||||
return "EV_POST_CODE";
|
||||
} else if (event == EvConstants.EV_UNUSED) {
|
||||
return "EV_Unused";
|
||||
} else if (event == EvConstants.EV_NO_ACTION) {
|
||||
return "EV_NO_ACTION";
|
||||
} else if (event == EvConstants.EV_SEPARATOR) {
|
||||
return "EV_SEPARATOR";
|
||||
} else if (event == EvConstants.EV_ACTION) {
|
||||
return "EV_ACTION";
|
||||
} else if (event == EvConstants.EV_EVENT_TAG) {
|
||||
return "EV_EVENT_TAG";
|
||||
} else if (event == EvConstants.EV_S_CRTM_CONTENTS) {
|
||||
return "EV_S_CRTM_CONTENTS";
|
||||
} else if (event == EvConstants.EV_S_CRTM_VERSION) {
|
||||
return "EV_S_CRTM_VERSION";
|
||||
} else if (event == EvConstants.EV_CPU_MICROCODE) {
|
||||
return "EV_CPU_MICROCODE";
|
||||
} else if (event == EvConstants.EV_PLATFORM_CONFIG_FLAGS) {
|
||||
return "EV_PLATFORM_CONFIG_FLAGS ";
|
||||
} else if (event == EvConstants.EV_TABLE_OF_DEVICES) {
|
||||
return "EV_TABLE_OF_DEVICES";
|
||||
} else if (event == EvConstants.EV_COMPACT_HASH) {
|
||||
return "EV_COMPACT_HASH";
|
||||
} else if (event == EvConstants.EV_IPL) {
|
||||
return "EV_IPL";
|
||||
} else if (event == EvConstants.EV_IPL_PARTITION_DATA) {
|
||||
return "EV_IPL_PARTITION_DATA";
|
||||
} else if (event == EvConstants.EV_NONHOST_CODE) {
|
||||
return "EV_NONHOST_CODE";
|
||||
} else if (event == EvConstants.EV_NONHOST_CONFIG) {
|
||||
return "EV_NONHOST_CONFIG";
|
||||
} else if (event == EvConstants.EV_NONHOST_INFO) {
|
||||
return "EV_NONHOST_INFO";
|
||||
} else if (event == EvConstants.EV_EV_OMIT_BOOT_DEVICES_EVENTS) {
|
||||
return "EV_EV_OMIT_BOOT_DEVICES_EVENTS";
|
||||
} else if (event == EvConstants.EV_EFI_EVENT_BASE) {
|
||||
return "EV_EFI_EVENT_BASE";
|
||||
} else if (event == EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG) {
|
||||
return "EV_EFI_VARIABLE_DRIVER_CONFIG";
|
||||
} else if (event == EvConstants.EV_EFI_VARIABLE_BOOT) {
|
||||
return "EV_EFI_VARIABLE_BOOT";
|
||||
} else if (event == EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION) {
|
||||
return "EV_EFI_BOOT_SERVICES_APPLICATION";
|
||||
} else if (event == EvConstants.EV_EFI_BOOT_SERVICES_DRIVER) {
|
||||
return "EV_EFI_BOOT_SERVICES_DRIVER";
|
||||
} else if (event == EvConstants.EV_EFI_RUNTIME_SERVICES_DRIVER) {
|
||||
return "EV_EFI_RUNTIME_SERVICES_DRIVER";
|
||||
} else if (event == EvConstants.EV_EFI_GPT_EVENT) {
|
||||
return "EV_EFI_GPT_EVENT";
|
||||
} else if (event == EvConstants.EV_EFI_ACTION) {
|
||||
return "EV_EFI_ACTION";
|
||||
} else if (event == EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB) {
|
||||
return "EV_EFI_PLATFORM_FIRMWARE_BLOB";
|
||||
} else if (event == EvConstants.EV_EFI_HANDOFF_TABLES) {
|
||||
return "EV_EFI_HANDOFF_TABLES";
|
||||
} else if (event == EvConstants.EV_EFI_HCRTM_EVENT) {
|
||||
return "EV_EFI_HCRTM_EVENT";
|
||||
} else if (event == EvConstants.EV_EFI_VARIABLE_AUTHORITY) {
|
||||
return "EV_EFI_VARIABLE_AUTHORITY";
|
||||
} else {
|
||||
return "Unknown Event ID " + event + " encountered";
|
||||
}
|
||||
}
|
||||
if (event == EvConstants.EV_PREBOOT_CERT) {
|
||||
return "EV_PREBOOT_CERT";
|
||||
} else if (event == EvConstants.EV_POST_CODE) {
|
||||
return "EV_POST_CODE";
|
||||
} else if (event == EvConstants.EV_UNUSED) {
|
||||
return "EV_Unused";
|
||||
} else if (event == EvConstants.EV_NO_ACTION) {
|
||||
return "EV_NO_ACTION";
|
||||
} else if (event == EvConstants.EV_SEPARATOR) {
|
||||
return "EV_SEPARATOR";
|
||||
} else if (event == EvConstants.EV_ACTION) {
|
||||
return "EV_ACTION";
|
||||
} else if (event == EvConstants.EV_EVENT_TAG) {
|
||||
return "EV_EVENT_TAG";
|
||||
} else if (event == EvConstants.EV_S_CRTM_CONTENTS) {
|
||||
return "EV_S_CRTM_CONTENTS";
|
||||
} else if (event == EvConstants.EV_S_CRTM_VERSION) {
|
||||
return "EV_S_CRTM_VERSION";
|
||||
} else if (event == EvConstants.EV_CPU_MICROCODE) {
|
||||
return "EV_CPU_MICROCODE";
|
||||
} else if (event == EvConstants.EV_PLATFORM_CONFIG_FLAGS) {
|
||||
return "EV_PLATFORM_CONFIG_FLAGS ";
|
||||
} else if (event == EvConstants.EV_TABLE_OF_DEVICES) {
|
||||
return "EV_TABLE_OF_DEVICES";
|
||||
} else if (event == EvConstants.EV_COMPACT_HASH) {
|
||||
return "EV_COMPACT_HASH";
|
||||
} else if (event == EvConstants.EV_IPL) {
|
||||
return "EV_IPL";
|
||||
} else if (event == EvConstants.EV_IPL_PARTITION_DATA) {
|
||||
return "EV_IPL_PARTITION_DATA";
|
||||
} else if (event == EvConstants.EV_NONHOST_CODE) {
|
||||
return "EV_NONHOST_CODE";
|
||||
} else if (event == EvConstants.EV_NONHOST_CONFIG) {
|
||||
return "EV_NONHOST_CONFIG";
|
||||
} else if (event == EvConstants.EV_NONHOST_INFO) {
|
||||
return "EV_NONHOST_INFO";
|
||||
} else if (event == EvConstants.EV_EV_OMIT_BOOT_DEVICES_EVENTS) {
|
||||
return "EV_EV_OMIT_BOOT_DEVICES_EVENTS";
|
||||
} else if (event == EvConstants.EV_EFI_EVENT_BASE) {
|
||||
return "EV_EFI_EVENT_BASE";
|
||||
} else if (event == EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG) {
|
||||
return "EV_EFI_VARIABLE_DRIVER_CONFIG";
|
||||
} else if (event == EvConstants.EV_EFI_VARIABLE_BOOT) {
|
||||
return "EV_EFI_VARIABLE_BOOT";
|
||||
} else if (event == EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION) {
|
||||
return "EV_EFI_BOOT_SERVICES_APPLICATION";
|
||||
} else if (event == EvConstants.EV_EFI_BOOT_SERVICES_DRIVER) {
|
||||
return "EV_EFI_BOOT_SERVICES_DRIVER";
|
||||
} else if (event == EvConstants.EV_EFI_RUNTIME_SERVICES_DRIVER) {
|
||||
return "EV_EFI_RUNTIME_SERVICES_DRIVER";
|
||||
} else if (event == EvConstants.EV_EFI_GPT_EVENT) {
|
||||
return "EV_EFI_GPT_EVENT";
|
||||
} else if (event == EvConstants.EV_EFI_ACTION) {
|
||||
return "EV_EFI_ACTION";
|
||||
} else if (event == EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB) {
|
||||
return "EV_EFI_PLATFORM_FIRMWARE_BLOB";
|
||||
} else if (event == EvConstants.EV_EFI_HANDOFF_TABLES) {
|
||||
return "EV_EFI_HANDOFF_TABLES";
|
||||
} else if (event == EvConstants.EV_EFI_HCRTM_EVENT) {
|
||||
return "EV_EFI_HCRTM_EVENT";
|
||||
} else if (event == EvConstants.EV_EFI_VARIABLE_AUTHORITY) {
|
||||
return "EV_EFI_VARIABLE_AUTHORITY";
|
||||
} else {
|
||||
return "Unknown Event ID " + event + " encountered";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Human readable output of a check of input against the current event hash.
|
||||
* @return human readable string.
|
||||
*/
|
||||
private String eventHashCheck() {
|
||||
String result = "";
|
||||
if (logFormat == 1) {
|
||||
if (Arrays.equals(this.digest, eventDataSha1hash)) { result
|
||||
+= "Event digest matched hash of the event data " + "\n";
|
||||
} else {
|
||||
result += "Event digest DID NOT match the hash of the event data :"
|
||||
+ HexUtils.byteArrayToHexString(getEventDigest()) + "\n";
|
||||
}
|
||||
/**
|
||||
* Human readable output of a check of input against the current event hash.
|
||||
*
|
||||
* @return human readable string.
|
||||
*/
|
||||
private String eventHashCheck() {
|
||||
String result = "";
|
||||
if (logFormat == 1) {
|
||||
if (Arrays.equals(this.digest, eventDataSha1hash)) {
|
||||
result
|
||||
+= "Event digest matched hash of the event data " + "\n";
|
||||
} else {
|
||||
if (Arrays.equals(this.digest, eventDataSha256hash)) {
|
||||
result += "Event digest matched hash of the event data " + "\n";
|
||||
} else {
|
||||
result += "Event digest DID NOT match the hash of the event data :"
|
||||
+ HexUtils.byteArrayToHexString(getEventDigest()) + "\n";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
result += "Event digest DID NOT match the hash of the event data :"
|
||||
+ Hex.encodeHexString(getEventDigest()) + "\n";
|
||||
}
|
||||
} else {
|
||||
if (Arrays.equals(this.digest, eventDataSha256hash)) {
|
||||
result += "Event digest matched hash of the event data " + "\n";
|
||||
} else {
|
||||
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.
|
||||
* @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++) {
|
||||
if (array[i] != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Checks a byte array for all zeros.
|
||||
*
|
||||
* @param array holds data to check.
|
||||
* @return true of all zeros are found.
|
||||
*/
|
||||
public boolean isBlank(final byte[] array) {
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
if (array[i] != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Human readable string representing the contents of the Event Log.
|
||||
* @return Description of the log.
|
||||
*/
|
||||
public String toString() {
|
||||
/**
|
||||
* Human readable string representing the contents of the Event Log.
|
||||
*
|
||||
* @return Description of the log.
|
||||
*/
|
||||
public String toString() {
|
||||
return description + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Human readable string representing the contents of the Event Log.
|
||||
* @param bEvent event Flag.
|
||||
* @param bContent content flag.
|
||||
* @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();
|
||||
if (bEvent) {
|
||||
sb.append(description);
|
||||
}
|
||||
if (bHexEvent) {
|
||||
if (bEvent || bContent) {
|
||||
sb.append("\n");
|
||||
}
|
||||
byte[] eventData = getEvent();
|
||||
sb.append("Event (Hex no Content) (" + eventData.length + " bytes): "
|
||||
+ HexUtils.byteArrayToHexString(eventData));
|
||||
}
|
||||
if (bContent) {
|
||||
byte[] evContent = getEventContent();
|
||||
if (bEvent) {
|
||||
sb.append("\n");
|
||||
}
|
||||
sb.append("Event content (Hex) (" + evContent.length + " bytes): "
|
||||
+ HexUtils.byteArrayToHexString(evContent));
|
||||
}
|
||||
/**
|
||||
* Human readable string representing the contents of the Event Log.
|
||||
*
|
||||
* @param bEvent event Flag.
|
||||
* @param bContent content flag.
|
||||
* @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();
|
||||
if (bEvent) {
|
||||
sb.append(description);
|
||||
}
|
||||
if (bHexEvent) {
|
||||
if (bEvent || bContent) {
|
||||
sb.append("\n");
|
||||
}
|
||||
byte[] eventData = getEvent();
|
||||
sb.append("Event (Hex no Content) (" + eventData.length + " bytes): "
|
||||
+ Hex.encodeHexString(eventData));
|
||||
}
|
||||
if (bContent) {
|
||||
byte[] evContent = getEventContent();
|
||||
if (bEvent) {
|
||||
sb.append("\n");
|
||||
}
|
||||
sb.append("Event content (Hex) (" + evContent.length + " bytes): "
|
||||
+ Hex.encodeHexString(evContent));
|
||||
}
|
||||
return sb.toString() + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove bad visual value text.
|
||||
* @param text content to operate over.
|
||||
* @return cleared string
|
||||
*/
|
||||
public String cleanTextContent(final String text) {
|
||||
String result;
|
||||
// strips off all non-ASCII characters
|
||||
result = text.replaceAll("[^\\x00-\\x7F]", "");
|
||||
|
||||
// erases all the ASCII control characters
|
||||
result = result.replaceAll("[\\p{Cntrl}&&[^\r\n\t]]", "");
|
||||
|
||||
// removes non-printable characters from Unicode
|
||||
result = result.replaceAll("\\p{C}", "");
|
||||
|
||||
return result.trim();
|
||||
}
|
||||
}
|
||||
|
@ -34,19 +34,18 @@ public class EvPostCode {
|
||||
public EvPostCode(final byte[] postCode) {
|
||||
// 2 ways post code has been implemented, check for the ascii string first
|
||||
if (isAscii(postCode)) {
|
||||
String info = new String(postCode, StandardCharsets.UTF_8);
|
||||
codeInfo = info;
|
||||
codeInfo = new String(postCode, StandardCharsets.UTF_8);
|
||||
bisString = true;
|
||||
} else {
|
||||
blob = new UefiFirmware(postCode);
|
||||
}
|
||||
} else {
|
||||
blob = new UefiFirmware(postCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the UEFI Defined Firmware Blob information.
|
||||
* @return UEFI Defined Firmware Blob information.
|
||||
*/
|
||||
public UefiFirmware getfirmwareBlob() {
|
||||
public UefiFirmware getFirmwareBlob() {
|
||||
return blob;
|
||||
}
|
||||
|
||||
@ -75,12 +74,11 @@ public class EvPostCode {
|
||||
* @return true if byte array is a string.
|
||||
*/
|
||||
public static boolean isAscii(final byte[] postCode) {
|
||||
boolean bisAscii = true;
|
||||
for (byte b : postCode) {
|
||||
if (!Character.isDefined(b)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return bisAscii;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1,73 +1,90 @@
|
||||
package hirs.tpm.eventlog.uefi;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
|
||||
/**
|
||||
* Class to process the PFP defined UEFI_PLATFORM_FIRMWARE_BLOB structure.
|
||||
*
|
||||
* <p>
|
||||
* typedef struct tdUEFI_PLATFORM_FIRMWARE_BLOB {
|
||||
* UEFI_PHYSICAL_ADDRESS BlobBase;
|
||||
* UINT64 BlobLength;
|
||||
* UEFI_PHYSICAL_ADDRESS BlobBase;
|
||||
* UINT64 BlobLength;
|
||||
* } UEFI_PLATFORM_FIRMWARE_BLOB;
|
||||
*/
|
||||
public class UefiFirmware {
|
||||
private boolean berror = false;
|
||||
/** byte array holding the firmwares physical address. */
|
||||
private byte[] physicalAddress = null;
|
||||
/** byte array holding the uefi address length. */
|
||||
private byte[] addressLength = null;
|
||||
/** uefi physical address. */
|
||||
private int blobAddress = 0;
|
||||
/** uefi address length. */
|
||||
private int blobLength = 0;
|
||||
private boolean bError = false;
|
||||
/**
|
||||
* byte array holding the firmwares physical address.
|
||||
*/
|
||||
private byte[] physicalAddress = null;
|
||||
/**
|
||||
* byte array holding the uefi address length.
|
||||
*/
|
||||
private byte[] addressLength = null;
|
||||
/**
|
||||
* uefi physical address.
|
||||
*/
|
||||
private int blobAddress = 0;
|
||||
/**
|
||||
* uefi address length.
|
||||
*/
|
||||
private int blobLength = 0;
|
||||
|
||||
/**
|
||||
* UefiFirmware constructor.
|
||||
* @param blob byte array holding a Firmware Blob.
|
||||
*/
|
||||
public UefiFirmware(final byte[] blob) {
|
||||
if (blob.length != UefiConstants.SIZE_16) {
|
||||
berror = true;
|
||||
} else {
|
||||
physicalAddress = new byte[UefiConstants.SIZE_8];
|
||||
addressLength = new byte[UefiConstants.SIZE_8];
|
||||
System.arraycopy(blob, 0, physicalAddress, 0, UefiConstants.SIZE_8);
|
||||
System.arraycopy(blob, UefiConstants.SIZE_8, addressLength, 0, UefiConstants.SIZE_8);
|
||||
byte[] lelength = HexUtils.leReverseByte(addressLength);
|
||||
BigInteger bigIntLength = new BigInteger(lelength);
|
||||
blobLength = bigIntLength.intValue();
|
||||
byte[]leAddress = HexUtils.leReverseByte(physicalAddress);
|
||||
BigInteger bigIntAddress = new BigInteger(leAddress);
|
||||
blobAddress = bigIntAddress.intValue();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the uefi firmware blobs physical address.
|
||||
* @return uefi firmware address.
|
||||
*/
|
||||
public int getPhysicalAddress() {
|
||||
return blobAddress;
|
||||
}
|
||||
/**
|
||||
* Returns the length of the blobs physical address.
|
||||
* @return length of the address.
|
||||
*/
|
||||
public int getBlobLength() {
|
||||
return blobLength;
|
||||
}
|
||||
/**
|
||||
* Returns a description of the firmware blobs location.
|
||||
* @return a description of the the firmware blobs location.
|
||||
*/
|
||||
public String toString() {
|
||||
String blobInfo = "";
|
||||
if (!berror) {
|
||||
blobInfo += " Platform Firwmare Blob Address = " + Integer.toHexString(blobAddress);
|
||||
blobInfo += " length = " + blobLength;
|
||||
} else {
|
||||
blobInfo += " Invalid Firmware Blob event encountered";
|
||||
}
|
||||
return blobInfo;
|
||||
}
|
||||
/**
|
||||
* UefiFirmware constructor.
|
||||
*
|
||||
* @param blob byte array holding a Firmware Blob.
|
||||
*/
|
||||
public UefiFirmware(final byte[] blob) {
|
||||
if (blob.length != UefiConstants.SIZE_16) {
|
||||
bError = true;
|
||||
} else {
|
||||
physicalAddress = new byte[UefiConstants.SIZE_8];
|
||||
addressLength = new byte[UefiConstants.SIZE_8];
|
||||
System.arraycopy(blob, 0, physicalAddress, 0, UefiConstants.SIZE_8);
|
||||
System.arraycopy(blob, UefiConstants.SIZE_8, addressLength, 0, UefiConstants.SIZE_8);
|
||||
byte[] lelength = HexUtils.leReverseByte(addressLength);
|
||||
BigInteger bigIntLength = new BigInteger(lelength);
|
||||
blobLength = bigIntLength.intValue();
|
||||
byte[] leAddress = HexUtils.leReverseByte(physicalAddress);
|
||||
BigInteger bigIntAddress = new BigInteger(leAddress);
|
||||
blobAddress = bigIntAddress.intValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the uefi firmware blobs physical address.
|
||||
*
|
||||
* @return uefi firmware address.
|
||||
*/
|
||||
public int getPhysicalAddress() {
|
||||
return blobAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the blobs physical address.
|
||||
*
|
||||
* @return length of the address.
|
||||
*/
|
||||
public int getBlobLength() {
|
||||
return blobLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a description of the firmware blobs location.
|
||||
*
|
||||
* @return a description of the the firmware blobs location.
|
||||
*/
|
||||
public String toString() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -26,145 +26,147 @@ final class Main {
|
||||
private static byte[] eventLog = null;
|
||||
private static boolean bContentFlag, bEventFlag, bHexEvent, bHexFlag, bPcrFlag = false;
|
||||
|
||||
/**
|
||||
* Main Constructor.
|
||||
* @param args command line parameters.
|
||||
*/
|
||||
public static void main(final String[] args) {
|
||||
commander = new Commander(args);
|
||||
if (!commander.getValidityFlag()) {
|
||||
System.out.print("Program exiting without processs due to issues with"
|
||||
+ " parameters provided.");
|
||||
System.exit(1);
|
||||
}
|
||||
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");
|
||||
/**
|
||||
* Main Constructor.
|
||||
*
|
||||
* @param args command line parameters.
|
||||
*/
|
||||
public static void main(final String[] args) {
|
||||
commander = new Commander(args);
|
||||
if (!commander.getValidityFlag()) {
|
||||
System.out.print("Program exiting without processs due to issues with"
|
||||
+ " parameters provided.");
|
||||
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");
|
||||
if (commander.hasArguments()) {
|
||||
if (commander.getDoneFlag()) {
|
||||
System.exit(0);
|
||||
}
|
||||
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 (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);
|
||||
}
|
||||
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) {
|
||||
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");
|
||||
if (!bHexFlag) {
|
||||
writeOut("\n----------------- End PCR Values ----------------- \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++)
|
||||
|| commander.getEventNumber() == -1) {
|
||||
|| commander.getEventNumber() == -1) {
|
||||
if ((commander.getPcrNumber() == event.getPcrIndex())
|
||||
|| commander.getPcrNumber() == -1) {
|
||||
if (bHexFlag) {
|
||||
if (bEventFlag || bHexEvent) {
|
||||
writeOut(HexUtils.byteArrayToHexString(event.getEvent()) + "\n");
|
||||
}
|
||||
if (bContentFlag) {
|
||||
writeOut(HexUtils.byteArrayToHexString(event.getEventContent())
|
||||
+ "\n");
|
||||
}
|
||||
if (bEventFlag || bHexEvent) {
|
||||
writeOut(HexUtils.byteArrayToHexString(event.getEvent()) + "\n");
|
||||
}
|
||||
if (bContentFlag) {
|
||||
writeOut(HexUtils.byteArrayToHexString(event.getEventContent())
|
||||
+ "\n");
|
||||
}
|
||||
} 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.
|
||||
* @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
|
||||
*/
|
||||
public static byte[] openLog(final String fileName) {
|
||||
@ -186,10 +188,10 @@ commander = new Commander(args);
|
||||
Path path = Paths.get(fName);
|
||||
rawLog = Files.readAllBytes(path);
|
||||
if (!bHexFlag) {
|
||||
writeOut("tcg_eventlog_tool is opening file:" + path + "\n");
|
||||
writeOut("tcg_eventlog_tool is opening file:" + path + "\n");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String error = "Error reading event Log File: " + e.toString();
|
||||
String error = "Error reading event Log File: " + e.toString();
|
||||
if (bDefault) {
|
||||
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.
|
||||
*
|
||||
* @param 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.
|
||||
* Uses the Events digest field for comparisons.
|
||||
*
|
||||
* @param logFileName1 Log file to use as a reference.
|
||||
* @param logFileName2 Log file to compare to the reference.
|
||||
* @return A sting containing human readable results.
|
||||
@ -232,12 +236,12 @@ commander = new Commander(args);
|
||||
try {
|
||||
eventLog1 = new TCGEventLog(evLog);
|
||||
} catch (Exception e) {
|
||||
sb.append("\nError processing event log " + logFileName1 + " : " + e.getMessage());
|
||||
sb.append("\nError processing event log " + logFileName1 + " : " + e.getMessage());
|
||||
return sb.toString();
|
||||
}
|
||||
try {
|
||||
eventLog2 = new TCGEventLog(evLog2);
|
||||
ArrayList<TpmPcrEvent> errors = diffEventLogs(eventLog1.getEventList(),
|
||||
ArrayList<TpmPcrEvent> errors = diffEventLogs(eventLog1.getEventList(),
|
||||
eventLog2.getEventList(), commander.getPcrNumber());
|
||||
if (errors.isEmpty() && !bHexFlag) {
|
||||
sb.append("\nEvent Log " + logFileName1 + " MATCHED EventLog " + logFileName2);
|
||||
@ -245,8 +249,8 @@ commander = new Commander(args);
|
||||
if (!errors.isEmpty() && !bHexFlag) {
|
||||
sb.append("\nEvent Log " + logFileName1
|
||||
+ " 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) {
|
||||
if (bHexFlag) {
|
||||
if (bEventFlag || bHexEvent) {
|
||||
@ -254,51 +258,53 @@ commander = new Commander(args);
|
||||
}
|
||||
if (bContentFlag) {
|
||||
sb.append(HexUtils.byteArrayToHexString(error.getEventContent())
|
||||
+ "\n");
|
||||
+ "\n");
|
||||
}
|
||||
} else {
|
||||
sb.append(error.toString(bEventFlag, bContentFlag, bHexEvent) + "\n");
|
||||
}
|
||||
} else {
|
||||
sb.append(error.toString(bEventFlag, bContentFlag, bHexEvent) + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException i) {
|
||||
System.out.print("IO error processing Event Log " + commander.getInFileName()
|
||||
+ "\nError was " + i.toString());
|
||||
+ "\nError was " + i.toString());
|
||||
System.exit(1);
|
||||
} catch (CertificateException c) {
|
||||
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);
|
||||
} catch (NoSuchAlgorithmException a) {
|
||||
System.out.print("Algorithm error processing Event Log " + commander.getInFileName()
|
||||
+ "\nError was " + a.toString());
|
||||
System.exit(1);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this event log against a second event log.
|
||||
* 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.
|
||||
* @param eventList initial events.
|
||||
* did no match the second. Return value is null if all events matched.
|
||||
*
|
||||
* @param eventList initial events.
|
||||
* @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.
|
||||
*/
|
||||
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>();
|
||||
for (TpmPcrEvent event2 : eventList2) {
|
||||
if (pcr >= 0) {
|
||||
if (event2.getPcrIndex() == pcr) {
|
||||
if (!digestMatch(eventList, event2)) {
|
||||
results.add(event2);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!digestMatch(eventList, event2)) {
|
||||
results.add(event2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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.
|
||||
*
|
||||
* @param eventLog The Reference Event log.
|
||||
* @param event single event to match.
|
||||
* @param event single event to match.
|
||||
* @return
|
||||
*/
|
||||
private static boolean digestMatch(final ArrayList<TpmPcrEvent> eventLog,
|
||||
|
Loading…
Reference in New Issue
Block a user