Merge pull request #250 from nsacyber/issue-249

[#249 ] TCG Event Logs - tcg_eventlog_tool
This commit is contained in:
iadgovuser26 2020-06-10 17:15:25 -04:00 committed by GitHub
commit 5809cfa6be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 1544 additions and 544 deletions

View File

@ -3,7 +3,7 @@ package hirs.attestationca.portal.page.controllers;
import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.SwidResource;
import hirs.persist.ReferenceManifestManager;
import hirs.tpm.eventlog.TCGEventLogProcessor;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.attestationca.portal.page.Page;
import hirs.attestationca.portal.page.PageController;
import hirs.attestationca.portal.page.PageMessages;
@ -157,7 +157,7 @@ public class ReferenceManifestDetailsPageController
data.put("rimType", rim.getRimType());
List<SwidResource> resources = rim.parseResource();
String resourceFilename = null;
TCGEventLogProcessor logProcessor = new TCGEventLogProcessor();
TCGEventLog logProcessor = new TCGEventLog();
try {
for (SwidResource swidRes : resources) {
@ -166,7 +166,7 @@ public class ReferenceManifestDetailsPageController
SwidResource.RESOURCE_UPLOAD_FOLDER,
resourceFilename));
if (Files.exists(logPath)) {
logProcessor = new TCGEventLogProcessor(
logProcessor = new TCGEventLog(
Files.readAllBytes(logPath));
swidRes.setPcrValues(Arrays.asList(
logProcessor.getExpectedPCRValues()));

View File

@ -3,7 +3,7 @@ package hirs.data.persist;
import com.google.common.base.Preconditions;
import hirs.data.persist.baseline.TpmWhiteListBaseline;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.tpm.eventlog.TCGEventLogProcessor;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.utils.xjc.File;
import java.io.IOException;
import java.util.Map;
@ -217,14 +217,14 @@ public class SwidResource {
*
*/
private void parsePcrValues() {
TCGEventLogProcessor logProcessor = new TCGEventLogProcessor();
TCGEventLog logProcessor = new TCGEventLog();
try {
Path logPath = Paths.get(String.format("%s/%s",
SwidResource.RESOURCE_UPLOAD_FOLDER,
this.getName()));
if (Files.exists(logPath)) {
logProcessor = new TCGEventLogProcessor(
logProcessor = new TCGEventLog(
Files.readAllBytes(logPath));
}
this.setPcrValues(Arrays.asList(

View File

@ -614,7 +614,7 @@ public class TPMBaselineGenerator {
// Device info records will start with the field name of the device info to set
try {
TPMBaselineFields field =
TPMBaselineFields.valueOf(dataArray[0].toLowerCase());
TPMBaselineFields.valueOf(dataArray[0].toUpperCase());
fieldMap.put(field, StringEscapeUtils.unescapeCsv(dataArray[1]));
} catch (IllegalArgumentException e) {
// Wasn't in the list of fields, treat it as a measurement record

View File

@ -1,11 +0,0 @@
package hirs.tpm.eventlog;
/**
* Class to handle the "Crypto Agile" Format for TCG Event Logs as defined in
* the TCG Platform Firmware Profile (PFP). The Format can provide multiple
* digests with different algorithm, however currently on SHA256 is supported.
* All other are currently ignored.
*/
public class CryptoAgileEventLog {
}

View File

@ -1,11 +0,0 @@
package hirs.tpm.eventlog;
/**
* Class to handle the "SHA1" Format for TCG Event Logs. "SHA1" Format is
* defined in the TCG Platform Firmware Profile (PFP). This is to support older
* versions of UEFI Firmware or OS that create logs with SHA1.
*/
public class SHA1EventLog {
}

View File

@ -1,113 +1,134 @@
package hirs.tpm.eventlog;
import hirs.data.persist.AbstractDigest;
import hirs.tpm.eventlog.uefi.UefiConstants;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import hirs.data.persist.AbstractDigest;
import hirs.data.persist.Digest;
import hirs.data.persist.TPMMeasurementRecord;
import hirs.data.persist.baseline.TpmWhiteListBaseline;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.tpm.eventlog.events.EvConstants;
import hirs.tpm.eventlog.uefi.UefiConstants;
import hirs.utils.HexUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* Class for handling different formats of TCG Event logs.
*/
public final class TCGEventLog {
private static final Logger LOGGER
= LogManager.getLogger(TCGEventLog.class);
/**
* Init value for SHA 256 values.
*/
/** Logger. */
private static final Logger LOGGER = LogManager.getLogger(TCGEventLog.class);
/** Name of the hash algorithm used to process the Event Log, default is SHA256. */
private String algorithm = "TPM_ALG_SHA256";
/** Parsed event log array. */
private static final int SIG_OFFSET = 32;
/** TEV_NO_ACTION signature size. */
private static final int SIG_SIZE = 16;
/** Initial value for SHA 256 values.*/
public static final String INIT_SHA256_LIST = "00000000000000000000000000"
+ "00000000000000000000000000000000000000";
/**
* Init value for SHA 1 values.
*/
/** Initial value for SHA 1 values. */
public static final String INIT_SHA1_LIST = "0000000000000000000000000000000000000000";
/**
* PFP defined EV_NO_ACTION identifier.
*/
/** PFP defined EV_NO_ACTION identifier. */
public static final int NO_ACTION_EVENT = 0x00000003;
/**
* String value of SHA1 hash.
*/
/** String value of SHA1 hash.*/
public static final String HASH_STRING = "SHA1";
/**
* String value of SHA256 hash.
*/
/** String value of SHA256 hash. */
public static final String HASH256_STRING = "SHA-256";
/**
* Each PCR bank holds 24 registers.
*/
/** Each PCR bank holds 24 registers. */
public static final int PCR_COUNT = 24;
/**
* 2 dimensional array holding the PCR values.
*/
private final byte[][] pcrList;
/**
* List of parsed events within the log.
*/
private final ArrayList<TpmPcrEvent> eventList = new ArrayList<>();
/** 2 dimensional array holding the PCR values. */
private byte[][] pcrList;
/** List of parsed events within the log. */
private ArrayList<TpmPcrEvent> eventList = new ArrayList<>();
/** Length of PCR. Indicates which hash algorithm is used. */
private int pcrLength;
/** Name of hash algorithm. */
private String hashType;
/** Initial Value to use. */
private String initValue;
/** Content Output Flag use. */
private boolean bContent = false;
/** Event Output Flag use. */
private boolean bHexEvent = false;
/** Event Output Flag use. */
private boolean bEvent = false;
/**
* Default blank object constructor.
*/
public TCGEventLog() {
this.pcrList = new byte[PCR_COUNT][UefiConstants.SIZE_20];
this.pcrList = new byte[PCR_COUNT][EvConstants.SHA1_LENGTH];
initValue = INIT_SHA1_LIST;
pcrLength = UefiConstants.SIZE_20;
pcrLength = EvConstants.SHA1_LENGTH;
hashType = HASH_STRING;
algorithm = "TPM_ALG_SHA1";
initPcrList();
}
/**
* Default constructor for just the rawlog that'll set up SHA1 Log.
* @param rawlog data for the event log file
* @throws IOException IO Stream for the event log
* @throws CertificateException certificate exception
* @throws NoSuchAlgorithmException no such alogirthm exception
* Simple constructor for Event Log.
* @param rawlog data for the event log file.
* @throws NoSuchAlgorithmException if an unknown algorithm is encountered.
* @throws CertificateException if a certificate in the log cannot be parsed.
* @throws IOException IO Stream if event cannot be parsed.
*/
public TCGEventLog(final byte[] rawlog) throws IOException,
CertificateException, NoSuchAlgorithmException {
this(rawlog, UefiConstants.SIZE_20, HASH_STRING, INIT_SHA1_LIST);
public TCGEventLog(final byte[] rawlog)
throws CertificateException, NoSuchAlgorithmException, IOException {
this(rawlog, false, false, false);
}
/**
* Default constructor for specific log.
* @param rawlog data for the event log file
* @param pcrLength determined by SHA1 or 256
* @param hashType the type of algorithm
* @param initValue the default blank value
* @throws IOException IO Stream for the event log
* @throws CertificateException certificate exception
* @throws NoSuchAlgorithmException no such alogirthm exception
* Default constructor for just the rawlog that'll set up SHA1 Log.
* @param rawlog data for the event log file.
* @param bEventFlag if true provides human readable event descriptions.
* @param bContentFlag if true provides hex output for Content in the description.
* @param bHexEventFlag if true provides hex event structure in the description.
* @throws NoSuchAlgorithmException if an unknown algorithm is encountered.
* @throws CertificateException if a certificate in the log cannot be parsed.
* @throws IOException IO Stream if event cannot be parsed.
*/
public TCGEventLog(final byte[] rawlog, final int pcrLength,
final String hashType, final String initValue) throws IOException,
CertificateException, NoSuchAlgorithmException {
this.pcrLength = pcrLength;
public TCGEventLog(final byte[] rawlog, final boolean bEventFlag,
final boolean bContentFlag, final boolean bHexEventFlag)
throws CertificateException, NoSuchAlgorithmException, IOException {
boolean bCryptoAgile = isLogCrytoAgile(rawlog);
if (bCryptoAgile) {
initValue = INIT_SHA256_LIST;
algorithm = "TPM_ALG_SHA256";
hashType = HASH256_STRING;
pcrLength = EvConstants.SHA256_LENGTH;
} else {
initValue = INIT_SHA1_LIST;
hashType = HASH_STRING;
algorithm = "TPM_ALG_SHA1";
pcrLength = EvConstants.SHA1_LENGTH;
}
this.pcrList = new byte[PCR_COUNT][pcrLength];
this.hashType = hashType;
this.initValue = initValue;
int eventNumber = 0;
bContent = bContentFlag;
bEvent = bEventFlag;
bHexEvent = bHexEventFlag;
ByteArrayInputStream is = new ByteArrayInputStream(rawlog);
// Process the 1st entry as a SHA1 format (per the spec)
eventList.add(new TpmPcrEvent1(is));
eventList.add(new TpmPcrEvent1(is, eventNumber++));
// put all events into an event list for further processing
while (is.available() > 0) {
if (hashType.compareToIgnoreCase(HASH_STRING) == 0) {
eventList.add(new TpmPcrEvent1(is));
if (bCryptoAgile) {
eventList.add(new TpmPcrEvent2(is, eventNumber++));
} else {
eventList.add(new TpmPcrEvent2(is));
eventList.add(new TpmPcrEvent1(is, eventNumber++));
}
}
calculatePcrValues();
@ -128,6 +149,34 @@ public final class TCGEventLog {
}
}
/**
* Creates a TPM baseline using the expected PCR Values.
* Expected PCR Values were Calculated from the EventLog (RIM Support file).
*
* @param name name to call the TPM Baseline
* @return whitelist baseline
*/
public TpmWhiteListBaseline createTPMBaseline(final String name) {
TpmWhiteListBaseline baseline = new TpmWhiteListBaseline(name);
TPMMeasurementRecord record;
String pcrValue;
for (int i = 0; i < PCR_COUNT; i++) {
if (algorithm.compareToIgnoreCase("TPM_ALG_SHA1") == 0) { // Log Was SHA1 Format
pcrValue = getExpectedPCRValue(i);
byte[] hexValue = HexUtils.hexStringToByteArray(pcrValue);
final Digest hash = new Digest(DigestAlgorithm.SHA1, hexValue);
record = new TPMMeasurementRecord(i, hash);
} else { // Log was Crypto Agile, currently assumes SHA256
pcrValue = getExpectedPCRValue(i);
byte[] hexValue = HexUtils.hexStringToByteArray(pcrValue);
final Digest hash = new Digest(DigestAlgorithm.SHA256, hexValue);
record = new TPMMeasurementRecord(i, hash);
}
baseline.addToBaseline(record);
}
return baseline;
}
/**
* Calculates the "Expected Values for TPM PCRs based upon Event digests in the Event Log.
* Uses the algorithm and eventList passed into the constructor,
@ -152,11 +201,11 @@ public final class TCGEventLog {
}
}
/**hjmmm I'll h
/**
* Extends a hash with a hash of new data.
*
* @param currentValue value to extend
* @param newEvent value to extend with
* @param newEvent value to extend with
* @return new hash resultant hash
* @throws NoSuchAlgorithmException if hash algorithm not supported
*/
@ -178,34 +227,82 @@ public final class TCGEventLog {
/**
* Returns all 24 PCR values for display purposes.
*
* @return Returns an array of strings representing the expected hash values
* for all 24 PCRs
* @return Returns an array of strings representing the expected hash values for all 24 PCRs
*/
public String[] getExpectedPCRValues() {
String[] pcrs = new String[PCR_COUNT];
for (int i = 0; i < PCR_COUNT; i++) {
pcrs[i] = Hex.encodeHexString(pcrList[i]);
pcrs[i] = HexUtils.byteArrayToHexString(pcrList[i]);
}
return pcrs;
}
/**
* Returns a list of event found in the Event Log.
* @return an arraylist of event.
*/
public ArrayList<TpmPcrEvent> getEventList() {
return eventList;
}
/**
* Returns a single PCR value given an index (PCR Number).
*
* @param index pcr index
* @return String representing the PCR contents
*/
public String getExpectedPCRString(final int index) {
return Hex.encodeHexString(pcrList[index]);
public String getExpectedPCRValue(final int index) {
return HexUtils.byteArrayToHexString(pcrList[index]);
}
/**
* Returns a single PCR value given an index (PCR Number).
*
* @param index pcr index.
* @return byte array of the pcr contents.
* Human readable string representing the contents of the Event Log.
* @return Description of the log.
*/
public byte[] getExpectedPCRBytes(final int index) {
return pcrList[index];
public String toString() {
StringBuilder sb = new StringBuilder();
for (TpmPcrEvent event:eventList) {
sb.append(event.toString(bEvent, bHexEvent, bContent));
}
sb.append("Event Log processing completed.\n");
return sb.toString();
}
/**
* Returns the TCG Algorithm Registry defined string for the Digest Algorithm
* used in the event log.
* @return TCG Defined Algorithm name
*/
public String getEventLogHashAlgorithm() {
return algorithm;
}
/**
* Returns the TCG Algorithm Registry defined ID for the Digest Algorithm
* used in the event log.
* @return TCG Defined Algorithm name
*/
public int getEventLogHashAlgorithmID() {
return TcgTpmtHa.tcgAlgStringtoId(algorithm);
}
/**
* Determines if an event is an EfiSpecIdEvent indicating that the log format is crypto agile.
* The EfiSpecIdEvent should be the first event in the TCG TPM Event Log.
*
* @param log The Event Log
* @return true if EfiSpecIDEvent is found and indicates that the format is crypto agile
* @throws UnsupportedEncodingException if parsing error occurs.
*/
private boolean isLogCrytoAgile(final byte[] log) throws UnsupportedEncodingException {
byte[] eType = new byte[UefiConstants.SIZE_4];
System.arraycopy(log, UefiConstants.SIZE_4, eType, 0, UefiConstants.SIZE_4);
byte[] eventType = HexUtils.leReverseByte(eType);
int eventID = new BigInteger(eventType).intValue();
if (eventID != TCGEventLog.NO_ACTION_EVENT) {
return false;
} // Event Type should be EV_NO_ACTION
byte[] signature = new byte[SIG_SIZE];
System.arraycopy(log, SIG_OFFSET, signature, 0, SIG_SIZE); // should be "Spec ID Event03"
String sig = new String(signature, "UTF-8").substring(0, SIG_SIZE - 1); // remove null char
return sig.equals("Spec ID Event03");
}
}

View File

@ -1,152 +0,0 @@
package hirs.tpm.eventlog;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import hirs.data.persist.TPMMeasurementRecord;
import hirs.data.persist.baseline.TpmWhiteListBaseline;
import hirs.utils.HexUtils;
import hirs.data.persist.Digest;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.tpm.eventlog.uefi.UefiConstants;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import org.apache.commons.codec.DecoderException;
/**
* Class for parsing a TCG EventLogs (both SHA1 and Crypto Agile Formats).
* Also produces a TPM Baseline using he digests within the event log.
* Constructor parses the input byte array into a List of TpmPcrEvents.
*/
public class TCGEventLogProcessor {
/**
* Name of the hash algorithm used to process the Event Log, default is SHA256.
*/
private String algorithm = "TPM_ALG_SHA256";
/**
* Parsed event log array.
*/
private TCGEventLog tcgLog = null;
/**
* EV_NO_ACTION signature offset.
*/
private static final int SIG_OFFSET = 32;
/**
* TEV_NO_ACTION signature size.
*/
private static final int SIG_SIZE = 16;
/**
* Default Constructor.
*/
public TCGEventLogProcessor() {
tcgLog = new TCGEventLog();
}
/**
* Constructor.
*
* @param rawLog the byte array holding the contents of the TCG Event Log
* @throws IOException if there is a parsing error
* @throws CertificateException certificate exception
* @throws NoSuchAlgorithmException no such alogirthm exception
*/
public TCGEventLogProcessor(final byte[] rawLog) throws IOException,
CertificateException, NoSuchAlgorithmException {
if (isLogCrytoAgile(rawLog)) {
tcgLog = new TCGEventLog(rawLog, UefiConstants.SIZE_32,
TCGEventLog.HASH256_STRING, TCGEventLog.INIT_SHA256_LIST);
} else {
tcgLog = new TCGEventLog(rawLog);
algorithm = "TPM_ALG_SHA1";
}
}
/**
* Returns all 24 PCR values for display purposes.
*
* @return Returns an array of strings representing the expected hash values for all 24 PCRs
*/
public String[] getExpectedPCRValues() {
return tcgLog.getExpectedPCRValues();
}
/**
* Returns a single PCR value given an index (PCR Number).
*
* @param index the PCR index
* @return String representing the PCR contents
*/
public String getExpectedPCRValue(final int index) {
return tcgLog.getExpectedPCRString(index);
}
/**
* Returns the TCG Algorithm Registry defined string for the Digest Algorithm
* used in the event log.
* @return TCG Defined Algorithm name
*/
public String getEventLogHashAlgorithm() {
return algorithm;
}
/**
* Returns the TCG Algorithm Registry defined ID for the Digest Algorithm
* used in the event log.
* @return TCG Defined Algorithm name
*/
public int getEventLogHashAlgorithmID() {
return TcgTpmtHa.tcgAlgStringtoId(algorithm);
}
/**
* Creates a TPM baseline using the expected PCR Values.
* Expected PCR Values were Calculated from the EventLog (RIM Support file).
*
* @param name name to call the TPM Baseline
* @return whitelist baseline
* @throws DecoderException hex string problem.
*/
public TpmWhiteListBaseline createTPMBaseline(final String name) throws DecoderException {
TpmWhiteListBaseline baseline = new TpmWhiteListBaseline(name);
TPMMeasurementRecord record;
for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) {
if (algorithm.compareToIgnoreCase("TPM_ALG_SHA1") == 0) { // Log Was SHA1 Format
record = new TPMMeasurementRecord(i,
new Digest(DigestAlgorithm.SHA1,
tcgLog.getExpectedPCRBytes(i)));
} else { // Log was Crypto Agile, currently assumes SHA256
record = new TPMMeasurementRecord(i,
new Digest(DigestAlgorithm.SHA256,
tcgLog.getExpectedPCRBytes(i)));
}
baseline.addToBaseline(record);
}
return baseline;
}
/**
* Determines if an event is an EfiSpecIdEvent indicating that the log format is crypto agile.
* The EfiSpecIdEvent should be the first event in the TCG TPM Event Log.
*
* @param log The Event Log
* @return true if EfiSpecIDEvent is found and indicates that the format is crypto agile
* @throws UnsupportedEncodingException if parsing error occurs.
*/
public boolean isLogCrytoAgile(final byte[] log) throws UnsupportedEncodingException {
byte[] eType = new byte[Integer.BYTES];
System.arraycopy(log, Integer.BYTES, eType, 0, Integer.BYTES);
byte[] eventType = HexUtils.leReverseByte(eType);
int eventID = new BigInteger(eventType).intValue();
if (eventID != TCGEventLog.NO_ACTION_EVENT) {
return false;
} // Event Type should be EV_NO_ACTION
byte[] signature = new byte[SIG_SIZE];
System.arraycopy(log, SIG_OFFSET, signature, 0, SIG_SIZE); // should be "Spec ID Event03"
String sig = new String(signature, "UTF-8").substring(0, SIG_SIZE - 1); // remove null char
return sig.equals("Spec ID Event03");
}
}

View File

@ -21,6 +21,7 @@ import hirs.tpm.eventlog.events.EvNoAction;
import hirs.tpm.eventlog.events.EvPostCode;
import hirs.tpm.eventlog.events.EvSCrtmContents;
import hirs.tpm.eventlog.events.EvSCrtmVersion;
import hirs.tpm.eventlog.uefi.UefiConstants;
import hirs.tpm.eventlog.uefi.UefiFirmware;
import hirs.tpm.eventlog.uefi.UefiVariable;
import hirs.utils.HexUtils;
@ -51,28 +52,24 @@ public class TpmPcrEvent {
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 Number. */
private int eventNumber = 1;
/** Index. */
private int index = -1;
/** Event Contents flag. */
private boolean bEvContent = false;
/** Event hash for SHA1 event logs. */
private byte[] eventDataSha1hash;
/** Event hash for Crypto Agile events. */
private byte[] eventDataSha256hash;
/** Signature extension mask.*/
private static final long SIGN_MASK = 0x00000000FFFFFFFFL;
/** Mask used to remove upper values from a long. */
private static final long INT_MASK = 0x000000007FFFFFFFL;
/** Indent Offset. */
private static final int INDENT_3 = 3;
/**
* Constructor.
@ -148,7 +145,7 @@ public class TpmPcrEvent {
* @param type byte array holding the PFP defined log event type
*/
protected void setEventType(final byte[] type) {
eventType = new BigInteger(HexUtils.leReverseByte(type)).longValue();
eventType = new BigInteger(1, HexUtils.leReverseByte(type)).longValue();
}
/**
@ -179,7 +176,24 @@ public class TpmPcrEvent {
public String getSpecErrataVersion() {
return errata;
}
/**
* Sets the event data after processing.
*
* @param eventData The PFP defined event content
*/
protected void setEventData(final byte[] eventData) {
event = new byte[eventData.length];
System.arraycopy(eventData, 0, event, 0, eventData.length);
}
/**
* 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.
*
@ -187,13 +201,11 @@ public class TpmPcrEvent {
*/
protected void setEventContent(final byte[] eventData) {
eventContent = new byte[eventData.length];
System.arraycopy(eventContent, 0, eventData, 0, eventData.length);
System.arraycopy(eventData, 0, eventContent, 0, eventData.length);
}
/**
* Gets the length of number of bytes in a PCR for the event.
* event log format.
*
* Gets the event Content Data (not the entire event structure).
* @return byte array holding the events content field
*/
public byte[] getEventContent() {
@ -223,23 +235,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 eventContent the byte array holding the event content.
* @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 NoSuchAlgorithmException if an event contains an unsupported algorithm.
* @throws IOException if the event cannot be parsed.
*/
public String processEvent(final byte[] event, final byte[] eventContent)
public String processEvent(final byte[] event, final byte[] eventContent, final int eventNumber)
throws CertificateException, NoSuchAlgorithmException, IOException {
String description = "";
int eventID = (int) eventType;
description += "Event# " + eventNumber++ + ": ";
description += "Index PCR[" + this.index + "]\n";
description += "Event Type: 0x" + this.eventType + " " + eventString(eventID);
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) + "\n";
description += "digest (SHA-1): " + HexUtils.byteArrayToHexString(this.digest);
} else {
description += "digest (SHA256): " + HexUtils.byteArrayToHexString(this.digest) + "\n";
description += "digest (SHA256): " + HexUtils.byteArrayToHexString(this.digest);
}
if (eventID != UefiConstants.SIZE_4) {
description += "\n";
}
// Calculate both the SHA1 and SHA256 on the event since this will equal the digest
// field of about half the log messages.
@ -256,7 +271,7 @@ public class TpmPcrEvent {
break;
case EvConstants.EV_POST_CODE:
EvPostCode postCode = new EvPostCode(eventContent);
description += "Event Content:\n" + postCode.toString() + "\n";
description += "Event Content:\n" + postCode.toString();
break;
case EvConstants.EV_UNUSED:
break;
@ -273,45 +288,39 @@ public class TpmPcrEvent {
if (EvPostCode.isAscii(eventContent)) {
String seperatorEventData = new String(eventContent, StandardCharsets.UTF_8);
if (!this.isEmpty(eventContent)) {
description += "Seperator event content = " + seperatorEventData + "\n";
description += "Seperator event content = " + seperatorEventData;
}
}
description += eventHashCheck();
break;
case EvConstants.EV_ACTION:
description += "Event Content:\n"
+ new String(eventContent, StandardCharsets.UTF_8) + "\n";
description += eventHashCheck();
+ new String(eventContent, StandardCharsets.UTF_8);
break;
case EvConstants.EV_EVENT_TAG:
EvEventTag eventTag = new EvEventTag(eventContent);
description += eventTag.toString() + "\n";
description += eventHashCheck();
description += eventTag.toString();
break;
case EvConstants.EV_S_CRTM_CONTENTS:
EvSCrtmContents sCrtmContents = new EvSCrtmContents(eventContent);
description += "Event Content:\n " + sCrtmContents.toString() + "\n";
description += "Event Content:\n " + sCrtmContents.toString();
break;
case EvConstants.EV_S_CRTM_VERSION:
EvSCrtmVersion sCrtmVersion = new EvSCrtmVersion(eventContent);
description += "Event Content:\n" + sCrtmVersion.toString() + "\n";
description += eventHashCheck();
description += "Event Content:\n" + sCrtmVersion.toString();
break;
case EvConstants.EV_CPU_MICROCODE:
break;
case EvConstants.EV_PLATFORM_CONFIG_FLAGS:
description += eventHashCheck();
break;
case EvConstants.EV_TABLE_OF_DEVICES:
break;
case EvConstants.EV_COMPACT_HASH:
EvCompactHash compactHash = new EvCompactHash(eventContent);
description += "Event Content:\n" + compactHash.toString() + "\n";
description += eventHashCheck();
description += "Event Content:\n" + compactHash.toString();
break;
case EvConstants.EV_IPL:
EvIPL ipl = new EvIPL(eventContent);
description += "Event Content:\n" + ipl.toString() + "\n";
description += "Event Content:\n" + ipl.toString();
break;
case EvConstants.EV_IPL_PARTITION_DATA:
break;
@ -327,12 +336,12 @@ public class TpmPcrEvent {
break;
case EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG:
UefiVariable efiVar = new UefiVariable(eventContent);
description += "Event Content:\n" + efiVar.toString();
description += eventHashCheck();
String efiVarDescription = efiVar.toString().replace("\n", "\n ");
description += "Event Content:\n " + efiVarDescription.substring(0,
efiVarDescription.length() - INDENT_3);
break;
case EvConstants.EV_EFI_VARIABLE_BOOT:
description += "Event Content:\n" + new UefiVariable(eventContent).toString();
description += eventHashCheck();
break;
case EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION:
EvEfiBootServicesApp bootServices = new EvEfiBootServicesApp(eventContent);
@ -346,15 +355,13 @@ public class TpmPcrEvent {
break;
case EvConstants.EV_EFI_GPT_EVENT:
description += "Event Content:\n" + new EvEfiGptPartition(eventContent).toString();
description += eventHashCheck();
break;
case EvConstants.EV_EFI_ACTION:
description += new String(eventContent, StandardCharsets.UTF_8) + "\n";
description += eventHashCheck();
description += new String(eventContent, StandardCharsets.UTF_8);
break;
case EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB:
description += "Event Content:\n"
+ new UefiFirmware(eventContent).toString() + "\n";
+ new UefiFirmware(eventContent).toString();
break;
case EvConstants.EV_EFI_HANDOFF_TABLES:
EvEfiHandoffTable efiTable = new EvEfiHandoffTable(eventContent);
@ -367,11 +374,6 @@ public class TpmPcrEvent {
break;
default: description += " Unknown Event found" + "\n";
}
if (bEvContent) {
description += "Event content (Hex) (" + event.length + "): "
+ HexUtils.byteArrayToHexString(eventContent) + "\n\n";
}
return description;
}
@ -382,62 +384,73 @@ public class TpmPcrEvent {
* @return TCG defined String that represents the event id
*/
private static String eventString(final long event) {
String evString = "";
long tmpEvent = event;
Long longEvent = Long.valueOf(tmpEvent & SIGN_MASK); // Remove signed extension
Long intEvent = Long.valueOf(tmpEvent & INT_MASK); // truncate to an int value
// Check to see if value is larger than an int, if it is then truncate the value
if (longEvent.longValue() > (long) Integer.MAX_VALUE) {
switch (intEvent.intValue()) {
case EvConstants.EV_EFI_EVENT_BASE: evString = "EV_EFI_EVENT_BASE"; break;
case EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG:
evString = "EV_EFI_VARIABLE_DRIVER_CONFIG"; break;
case EvConstants.EV_EFI_VARIABLE_BOOT:
evString = "EV_EFI_VARIABLE_BOOT"; break;
case EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION:
evString = "EV_EFI_BOOT_SERVICES_APPLICATION"; break;
case EvConstants.EV_EFI_BOOT_SERVICES_DRIVER:
evString = "EV_EFI_BOOT_SERVICES_DRIVER"; break;
case EvConstants.EV_EFI_RUNTIME_SERVICES_DRIVER:
evString = "EV_EFI_RUNTIME_SERVICES_DRIVER"; break;
case EvConstants.EV_EFI_GPT_EVENT: evString = "EV_EFI_GPT_EVENT"; break;
case EvConstants.EV_EFI_ACTION: evString = "EV_EFI_ACTION"; break;
case EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB:
evString = "EV_EFI_PLATFORM_FIRMWARE_BLOB"; break;
case EvConstants.EV_EFI_HANDOFF_TABLES: evString = "EV_EFI_HANDOFF_TABLES"; break;
case EvConstants.EV_EFI_HCRTM_EVENT: evString = "EV_EFI_HCRTM_EVENT"; break;
case EvConstants.EV_EFI_VARIABLE_AUTHORITY:
evString = "EV_EFI_VARIABLE_AUTHORITY"; break;
default: evString = "Unknown Event ID " + event + " encountered";
}
} else {
switch (intEvent.intValue()) {
case EvConstants.EV_PREBOOT_CERT: evString = "EV_PREBOOT_CERT"; break;
case EvConstants.EV_POST_CODE: evString = "EV_POST_CODE"; break;
case EvConstants.EV_UNUSED: evString = "EV_Unused"; break;
case EvConstants.EV_NO_ACTION: evString = "EV_NO_ACTION"; break;
case EvConstants.EV_SEPARATOR: evString = "EV_SEPARATOR"; break;
case EvConstants.EV_ACTION: evString = "EV_ACTION"; break;
case EvConstants.EV_EVENT_TAG: evString = "EV_EVENT_TAG"; break;
case EvConstants.EV_S_CRTM_CONTENTS: evString = "EV_S_CRTM_CONTENTS"; break;
case EvConstants.EV_S_CRTM_VERSION: evString = "EV_S_CRTM_VERSION"; break;
case EvConstants.EV_CPU_MICROCODE: evString = "EV_CPU_MICROCODE"; break;
case EvConstants.EV_PLATFORM_CONFIG_FLAGS: evString = "EV_PLATFORM_CONFIG_FLAGS ";
break;
case EvConstants.EV_TABLE_OF_DEVICES: evString = "EV_TABLE_OF_DEVICES"; break;
case EvConstants.EV_COMPACT_HASH: evString = "EV_COMPACT_HASH"; break;
case EvConstants.EV_IPL: evString = "EV_IPL"; break;
case EvConstants.EV_IPL_PARTITION_DATA: evString = "EV_IPL_PARTITION_DATA"; break;
case EvConstants.EV_NONHOST_CODE: evString = "EV_NONHOST_CODE"; break;
case EvConstants.EV_NONHOST_CONFIG: evString = "EV_NONHOST_CONFIG"; break;
case EvConstants.EV_NONHOST_INFO: evString = "EV_NONHOST_INFO"; break;
case EvConstants.EV_EV_OMIT_BOOT_DEVICES_EVENTS:
evString = "EV_EV_OMIT_BOOT_DEVICES_EVENTS"; break;
default: evString = "Unknown Event ID " + event + " encountered";
}
}
return evString;
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.
@ -476,4 +489,43 @@ public class TpmPcrEvent {
}
return true;
}
/**
* 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));
}
return sb.toString() + "\n";
}
}

View File

@ -32,12 +32,13 @@ public class TpmPcrEvent1 extends TpmPcrEvent {
* Constructor.
*
* @param is ByteArrayInputStream holding the TCG Log event.
* @param eventNumber event position within the event log.
* @throws IOException if an error occurs in parsing the event.
* @throws NoSuchAlgorithmException if an undefined algorithm is encountered.
* @throws CertificateException If a certificate within an event can't be processed.
*/
public TpmPcrEvent1(final ByteArrayInputStream is) throws IOException, CertificateException,
NoSuchAlgorithmException {
public TpmPcrEvent1(final ByteArrayInputStream is, final int eventNumber)
throws IOException, CertificateException, NoSuchAlgorithmException {
super(is);
setDigestLength(EvConstants.SHA1_LENGTH);
setLogFormat(1);
@ -75,8 +76,9 @@ public class TpmPcrEvent1 extends TpmPcrEvent {
offset += eventDigest.length;
System.arraycopy(rawEventSize, 0, event, offset, rawEventSize.length);
offset += rawEventSize.length;
setEventData(event);
//System.arraycopy(eventContent, 0, event, offset, eventContent.length);
this.processEvent(event, eventContent);
this.processEvent(event, eventContent, eventNumber);
}
}
}

View File

@ -67,12 +67,13 @@ public class TpmPcrEvent2 extends TpmPcrEvent {
* Constructor.
*
* @param is ByteArrayInputStream holding the TCG Log event
* @param eventNumber event position within the event log.
* @throws IOException if an error occurs in parsing the event
* @throws NoSuchAlgorithmException if an undefined algorithm is encountered.
* @throws NoSuchAlgorithmException if an undefined algorithm is encountered.
* @throws CertificateException If a certificate within an event can't be processed.
*/
public TpmPcrEvent2(final ByteArrayInputStream is) throws IOException, CertificateException,
NoSuchAlgorithmException {
public TpmPcrEvent2(final ByteArrayInputStream is, final int eventNumber)
throws IOException, CertificateException, NoSuchAlgorithmException {
super(is);
setDigestLength(EvConstants.SHA256_LENGTH);
setLogFormat(2);
@ -124,7 +125,8 @@ public class TpmPcrEvent2 extends TpmPcrEvent {
System.arraycopy(rawEventSize, 0, event, offset, rawEventSize.length);
offset += rawEventSize.length;
//System.arraycopy(eventContent, 0, event, offset, eventContent.length);
this.processEvent(event, eventContent);
setEventData(event);
this.processEvent(event, eventContent, eventNumber);
}
}

View File

@ -122,11 +122,11 @@ public class EvEfiBootServicesApp {
info += " Image physical address: " + HexUtils.byteArrayToHexString(physicalAddress);
info += " Image length = " + imageLength;
info += " Image link time address: " + HexUtils.byteArrayToHexString(physicalAddress);
info += " Device path length = " + devicePathLength + "\n";
info += " Device path length = " + devicePathLength;
if (devicePathValid) {
info += devPath.toString();
info += "\n" + devPath.toString();
} else {
info += " Error processing device path" + "\n";
info += "\n Error processing device path" + "\n";
}
return info;
}

View File

@ -119,7 +119,10 @@ public class EvEfiGptPartition {
partitionInfo.append("GPT Header Signature = " + headerStr + " : Number of Paritions = "
+ numberOfPartitions + "\n");
for (int i = 0; i < numberOfPartitions; i++) {
partitionInfo.append("Partition " + i + " information\n");
if (i > 0) {
partitionInfo.append("\n");
}
partitionInfo.append(" Partition " + i + " information\n");
partitionInfo.append(partitionList.get(i).toString());
}
return partitionInfo.toString();

View File

@ -101,7 +101,7 @@ public class EvEfiHandoffTable {
tableInfo.append(" UEFI industry standard table type = "
+ currentGuid.getVendorTableReference() + "\n");
tableInfo.append(" VendorTable " + i + " address: "
+ HexUtils.byteArrayToHexString(vendorTables.get(i)) + "\n");
+ HexUtils.byteArrayToHexString(vendorTables.get(i)));
}
return tableInfo.toString();
}

View File

@ -169,7 +169,7 @@ public class EvEfiSpecIdEvent {
String specInfo = "";
if (signature == "Spec ID Event#") {
specInfo += "Platform Profile Specification version = " + vMaj + "." + vMin
+ " using errata version" + errata + "\n";
+ " using errata version" + errata;
} else {
specInfo = "EV_NO_ACTION event named " + signature
+ " ecncountered but support for processing it has not been added to this application";

View File

@ -66,13 +66,13 @@ public class EvNoAction {
if (bSpecIDEvent) {
specInfo += " Signature = Spec ID Event03 : ";
if (specIDEvent.isCryptoAgile()) {
specInfo += "Log format is Crypto Agile \n";
specInfo += "Log format is Crypto Agile\n";
} else {
specInfo += "Log format is SHA 1 (NOT Crypto Agile) \n";
specInfo += "Log format is SHA 1 (NOT Crypto Agile)\n";
}
specInfo += " Platform Profile Specification version = "
+ specIDEvent.getVersionMajor() + "." + specIDEvent.getVersionMinor()
+ " using errata version " + specIDEvent.getErrata() + "\n";
}
+ " using errata version " + specIDEvent.getErrata();
} else {
specInfo = "EV_NO_ACTION event named " + signature
+ " encountered but support for processing it has not been added to this application.\n";

View File

@ -31,6 +31,7 @@ public String toString() {
for (int i = 0; i < bootOrder.length; i++) {
orderList.append(String.format("Boot %04d", (int) bootOrder[i]));
}
//orderList.append("\n");
return orderList.toString();
}
}

View File

@ -53,6 +53,8 @@ public final class UefiConstants {
public static final int OFFSET_3 = 3;
/** 4 byte offset. */
public static final int OFFSET_4 = 4;
/** 5 byte offset. */
public static final int OFFSET_5 = 5;
/** 6 byte offset. */
public static final int OFFSET_6 = 4;
/** 8 byte offset. */
@ -89,6 +91,8 @@ public final class UefiConstants {
public static final int DEV_MEDIA = 0x04;
/** Device Type Hardware. */
public static final int DEV_BIOS = 0x05;
/** Device Sub-Type USV. */
public static final int DEV_SUB_USB = 0x05;
/** Device Sub-Type Sata. */
public static final int DEV_SUB_SATA = 0x12;
/** Device Sub-Type nvm. */

View File

@ -84,26 +84,24 @@ public class UefiDevicePath {
*/
private String processDevPath(final byte[] path) throws UnsupportedEncodingException {
StringBuilder pInfo = new StringBuilder();
String devicePathInfo = "";
int devLength = 0, pathOffset = 0;
int devLength = 0, pathOffset = 0, devCount = 0;
while (true) {
Byte devPath = Byte.valueOf(path[pathOffset]);
if ((devPath.intValue() == UefiConstants.TERMINATOR)
|| (devPath.intValue() == UefiConstants.END_FLAG)) {
break;
}
devicePathInfo = processDev(path, pathOffset);
if (devicePathInfo.contains("Unknown Device Path")) {
if (devCount++ > 0) {
pInfo.append("\n");
}
pInfo.append(processDev(path, pathOffset));
devLength = path[pathOffset + UefiConstants.OFFSET_3] * UefiConstants.SIZE_256
+ path[pathOffset + UefiConstants.OFFSET_2];
pathOffset = pathOffset + devLength;
if (pathOffset >= path.length) {
break;
}
pInfo.append(devicePathInfo);
devLength = path[pathOffset + UefiConstants.OFFSET_3] * UefiConstants.SIZE_256
+ path[pathOffset + UefiConstants.OFFSET_2];
pathOffset = pathOffset + devLength;
if (pathOffset >= path.length) {
break;
}
}
}
}
return pInfo.toString();
}
@ -120,6 +118,7 @@ public class UefiDevicePath {
throws UnsupportedEncodingException {
String devInfo = " ";
int devPath = path[offset];
byte unknownSubType = path[offset + UefiConstants.OFFSET_1];
switch (path[0 + offset]) {
case UefiConstants.DEV_HW: type = "Hardware Device Path";
if (devPath == UefiConstants.DEVPATH_HARWARE) {
@ -132,9 +131,12 @@ public class UefiDevicePath {
case UefiConstants.DEV_MSG: type = "Messaging Device Path";
if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEV_SUB_SATA) {
devInfo += type + ": " + sataSubType(path, offset);
}
if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEV_SUB_NVM) {
} else if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEV_SUB_NVM) {
devInfo += type + ": " + nvmSubType(path, offset);
} else if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEV_SUB_USB) {
devInfo += type + ": " + usbSubType(path, offset);
} else {
devInfo += "UEFI Messaging Device Path Type " + Integer.valueOf(unknownSubType);
}
break;
case UefiConstants.DEV_MEDIA: type = "Media Device Path";
@ -148,6 +150,8 @@ public class UefiDevicePath {
devInfo += type + ": " + piwgFirmVolFile(path, offset);
} else if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEVPATH_PWIG_VOL) {
devInfo += type + ": " + piwgFirmVolPath(path, offset);
} else {
devInfo += "UEFI Media Device Path Type " + Integer.valueOf(unknownSubType);
}
break;
case UefiConstants.DEV_BIOS: type = "BIOS Device Path";
@ -155,11 +159,10 @@ public class UefiDevicePath {
break;
case UefiConstants.TERMINATOR: devInfo += "End of Hardware Device Path";
break;
default: type = "Unknown Device Path";
devInfo = type;
default:
devInfo += "UEFI Device Path Type " + Integer.valueOf(unknownSubType);
}
devInfo += "\n";
return devInfo;
return devInfo;
}
/**
@ -241,12 +244,12 @@ private String hardDriveSubType(final byte[] path, final int offset) {
subType += HexUtils.byteArrayToHexString(partnumber);
byte[] data = new byte[UefiConstants.SIZE_8];
System.arraycopy(path, UefiConstants.OFFSET_8 + offset, data, 0, UefiConstants.SIZE_8);
subType += "Partition Start = " + HexUtils.byteArrayToHexString(data);
subType += " Partition Start = " + HexUtils.byteArrayToHexString(data);
System.arraycopy(path, UefiConstants.OFFSET_16 + offset, data, 0, UefiConstants.SIZE_8);
subType += "Partition Size = " + HexUtils.byteArrayToHexString(data);
subType += " Partition Size = " + HexUtils.byteArrayToHexString(data);
byte[] signature = new byte[UefiConstants.SIZE_16];
System.arraycopy(path, UefiConstants.OFFSET_24 + offset, signature, 0, UefiConstants.SIZE_16);
subType += "Partition Signature = ";
subType += "\n Partition Signature = ";
if (path[UefiConstants.OFFSET_41 + offset] == UefiConstants.DRIVE_SIG_NONE) {
subType += "None";
} else if (path[UefiConstants.OFFSET_41 + offset] == UefiConstants.DRIVE_SIG_32BIT) {
@ -257,13 +260,13 @@ private String hardDriveSubType(final byte[] path, final int offset) {
} else {
subType += "invalid partition signature type";
}
subType += "Partition Format = ";
subType += " Partition Format = ";
if (path[UefiConstants.OFFSET_40 + offset] == UefiConstants.DRIVE_TYPE_PC_AT) {
subType += "PC-AT compatible legacy MBR";
subType += " PC-AT compatible legacy MBR";
} else if (path[UefiConstants.OFFSET_40 + offset] == UefiConstants.DRIVE_TYPE_GPT) {
subType += "GUID Partition Table";
subType += " GUID Partition Table";
} else {
subType += "Invalid partition table type";
subType += " Invalid partition table type";
}
return subType;
}
@ -318,7 +321,27 @@ private String vendorSubType(final byte[] path, final int offset) {
}
/**
* Returns nvm device info.
* Returns USB device info.
* UEFI Specification, Version 2.8.
* @param path
* @param offset
* @return USB device info.
*/
private String usbSubType(final byte[] path, final int offset) {
subType = " USB ";
subType += " port = " + Integer.valueOf(path[offset + UefiConstants.OFFSET_4]);
subType += " interface = " + Integer.valueOf(path[offset + UefiConstants.OFFSET_5]);
byte[] lengthBytes = new byte[UefiConstants.SIZE_2];
System.arraycopy(path, UefiConstants.OFFSET_2 + offset, lengthBytes, 0, UefiConstants.SIZE_2);
int subTypeLength = HexUtils.leReverseInt(lengthBytes);
byte[] usbData = new byte[subTypeLength];
System.arraycopy(path, UefiConstants.OFFSET_4 + offset, usbData, 0, subTypeLength);
// Todo add further USB processing ...
return subType;
}
/**
* Returns NVM device info.
* UEFI Specification, Version 2.8.
* Name space Identifier (NSID) and IEEE Extended Unique Identifier (EUI-64):
* See Links to UEFI Related Documents

View File

@ -63,7 +63,7 @@ public int getBlobLength() {
public String toString() {
String blobInfo = "";
if (!berror) {
blobInfo += " Platform Firwmare Blob Address = " + blobAddress;
blobInfo += " Platform Firwmare Blob Address = " + Integer.toHexString(blobAddress);
blobInfo += " length = " + blobLength;
} else {
blobInfo += " Invalid Firmware Blob event encountered";

View File

@ -91,7 +91,7 @@ public String toString() {
partitionInfo += " Partition Name : " + partitionName + "\n";
partitionInfo += " Partition Type GUID : " + partitionTypeGUID.toString() + "\n";
partitionInfo += " Unique Partition GUID : " + uniquePartitionGUID.toStringNoLookup() + "\n";
partitionInfo += " Attributes : " + attributes + "\n";
partitionInfo += " Attributes : " + attributes;
return partitionInfo;
}

View File

@ -43,11 +43,11 @@ public int getSecurBootVariable() {
public String toString() {
if (!berror) {
if (secureBootVar == 1) {
info += " Secure Boot is enabled \n";
info += " Secure Boot is enabled ";
} else if (secureBootVar == 0) {
info += " Secure Boot is NOT enabled \n";
info += " Secure Boot is NOT enabled ";
} else {
info += " Unkown State: Secure Variable is undefined \n";
info += " Unkown State: Secure Variable is undefined ";
}
}
return info;

View File

@ -175,7 +175,7 @@ public String toString() {
} else {
if (signatureType.getVendorTableReference().equals("EFI_CERT_SHA256_GUID")) {
sigInfo += "UEFI Signature Owner = " + efiGuid.toString() + "\n";
sigInfo += "Binary Hash = " + HexUtils.byteArrayToHexString(binaryHash) + "\n";
sigInfo += " Binary Hash = " + HexUtils.byteArrayToHexString(binaryHash) + "\n";
} else {
sigInfo += "UEFI Signature Owner = " + efiGuid.toString() + "\n";
sigInfo += cert.toString();

View File

@ -136,11 +136,15 @@ private void processSigList(final byte[] data)
public String toString() {
StringBuilder efiVariable = new StringBuilder();
efiVariable.append("UEFI Variable Name:" + varName + "\n");
efiVariable.append("UEFI_GUID = " + getEfiVarGuid().toString() + "\n");
efiVariable.append("UEFI Variable Contents => " + "\n");
efiVariable.append("UEFI_GUID = " + getEfiVarGuid().toString() + "\n ");
if (varName != "") {
efiVariable.append("UEFI Variable Contents => " + "\n ");
}
String tmpName = varName;
if (varName.contains("Boot00")) {
tmpName = "Boot00";
} else {
tmpName = varName;
}
switch (tmpName) {
case "Shim": efiVariable.append(printCert(uefiVaribelData, 0)); break;
@ -149,6 +153,11 @@ public String toString() {
case "BootOrder": efiVariable.append(booto.toString()); break;
case "SecureBoot": efiVariable.append(sb.toString()); break;
default:
if (!tmpName.isEmpty()) {
efiVariable.append("Data not provided for UEFI variable named " + tmpName + " ");
} else {
efiVariable.append("Data not provided ");
}
}
for (int i = 0; i < certSuperList.size(); i++) {
efiVariable.append(certSuperList.get(i).toString());
@ -173,7 +182,7 @@ public String printCert(final byte[] data, final int offset) {
UefiX509Cert cert = new UefiX509Cert(certData);
certInfo = cert.toString();
} catch (Exception e) {
certInfo = "Error Processing Certificate : " + e.getMessage() + "\n";
certInfo = "Error Processing Certificate : " + e.getMessage();
}
return (certInfo);
}

View File

@ -74,14 +74,14 @@ public String getSHA1FingerPrint() {
public String toString() {
X509Certificate x509Cert = (X509Certificate) cert;
String certData = "";
certData += "Certificate Serial Number = "
certData += " Certificate Serial Number = "
+ x509Cert.getSerialNumber().toString(UefiConstants.SIZE_16) + "\n";
certData += "Subject DN = " + x509Cert.getSubjectDN() + "\n";
certData += "Issuer DN = " + x509Cert.getIssuerDN() + "\n";
certData += "Not Before Date = " + x509Cert.getNotBefore() + "\n";
certData += "Not After Date = " + x509Cert.getNotAfter() + "\n";
certData += "Signature Algorithm = " + x509Cert.getSigAlgName() + "\n";
certData += "SHA1 Fingerprint = " + getSHA1FingerPrint() + "\n";
certData += " Subject DN = " + x509Cert.getSubjectDN() + "\n";
certData += " Issuer DN = " + x509Cert.getIssuerDN() + "\n";
certData += " Not Before Date = " + x509Cert.getNotBefore() + "\n";
certData += " Not After Date = " + x509Cert.getNotAfter() + "\n";
certData += " Signature Algorithm = " + x509Cert.getSigAlgName() + "\n";
certData += " SHA1 Fingerprint = " + getSHA1FingerPrint() + "\n";
return certData;
}
}

View File

@ -2,39 +2,40 @@ package hirs.tpm.eventlog;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Arrays;
//import java.util.List;
//import java.util.Set;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
//import org.hibernate.Session;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/*
import org.junit.Test;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
*/
import hirs.data.persist.SpringPersistenceTest;
//import hirs.data.persist.Baseline;
//import hirs.data.persist.Digest;
//import hirs.data.persist.SpringPersistenceTest;
//import hirs.data.persist.TpmWhiteListBaseline;
//import hirs.utils.HexUtils;
/**
* Class for testing TCG Event Log processing.
*/
public class TCGEventLogProcessorTest extends SpringPersistenceTest {
//public class TCGEventLogTest extends SpringPersistenceTest {
public class TCGEventLogTest {
private static final String DEFAULT_EVENT_LOG = "/tcgeventlog/TpmLog.bin";
private static final String DEFAULT_EXPECTED_PCRS = "/tcgeventlog/TpmLogExpectedPcrs.txt";
private static final String SHA1_EVENT_LOG = "/tcgeventlog/TpmLogSHA1.bin";
private static final String SHA1_EXPECTED_PCRS = "/tcgeventlog/TpmLogSHA1ExpectedPcrs.txt";
private static final Logger LOGGER
= LogManager.getLogger(TCGEventLogProcessorTest.class);
= LogManager.getLogger(TCGEventLogTest.class);
/**
* Initializes a <code>SessionFactory</code>. The factory is used for an in-memory database that
@ -88,8 +89,8 @@ public class TCGEventLogProcessorTest extends SpringPersistenceTest {
boolean testPass = true;
log = this.getClass().getResourceAsStream(DEFAULT_EVENT_LOG);
byte[] rawLogBytes = IOUtils.toByteArray(log);
TCGEventLogProcessor tlp = new TCGEventLogProcessor(rawLogBytes);
String[] pcrFromLog = tlp.getExpectedPCRValues();
TCGEventLog evlog = new TCGEventLog(rawLogBytes, false, false, false);
String[] pcrFromLog = evlog.getExpectedPCRValues();
pcrs = this.getClass().getResourceAsStream(DEFAULT_EXPECTED_PCRS);
Object[] pcrObj = IOUtils.readLines(pcrs).toArray();
String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class);
@ -102,12 +103,12 @@ public class TCGEventLogProcessorTest extends SpringPersistenceTest {
}
Assert.assertTrue(testPass);
// Test 2 get an individual PCR
String pcr3 = tlp.getExpectedPCRValue(3);
String pcr3 = evlog.getExpectedPCRValue(3);
Assert.assertEquals(pcr3, pcrFromLog[3]);
// Test 3 check the Algorithm Identifiers used in the log
String algStr = tlp.getEventLogHashAlgorithm();
String algStr = evlog.getEventLogHashAlgorithm();
Assert.assertEquals(algStr, "TPM_ALG_SHA256");
int id = tlp.getEventLogHashAlgorithmID();
int id = evlog.getEventLogHashAlgorithmID();
Assert.assertEquals(id, TcgTpmtHa.TPM_ALG_SHA256);
LOGGER.debug("OK. Parsing of a Crypto Agile Format Success");
}
@ -126,8 +127,8 @@ public class TCGEventLogProcessorTest extends SpringPersistenceTest {
boolean testPass = true;
log = this.getClass().getResourceAsStream(SHA1_EVENT_LOG);
byte[] rawLogBytes = IOUtils.toByteArray(log);
TCGEventLogProcessor tlp = new TCGEventLogProcessor(rawLogBytes);
String[] pcrFromLog = tlp.getExpectedPCRValues();
TCGEventLog evlog = new TCGEventLog(rawLogBytes, false, false, false);
String[] pcrFromLog = evlog.getExpectedPCRValues();
pcrs = this.getClass().getResourceAsStream(SHA1_EXPECTED_PCRS);
Object[] pcrObj = IOUtils.readLines(pcrs).toArray();
String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class);
@ -140,12 +141,12 @@ public class TCGEventLogProcessorTest extends SpringPersistenceTest {
}
Assert.assertTrue(testPass);
// Test 2 get an individual PCR
String pcr0 = tlp.getExpectedPCRValue(0);
String pcr0 = evlog.getExpectedPCRValue(0);
Assert.assertEquals(pcr0, pcrFromLog[0]);
// Test 3 check the Algorithm Identifiers used in the log
String algStr = tlp.getEventLogHashAlgorithm();
String algStr = evlog.getEventLogHashAlgorithm();
Assert.assertEquals(algStr, "TPM_ALG_SHA1");
int id = tlp.getEventLogHashAlgorithmID();
int id = evlog.getEventLogHashAlgorithmID();
Assert.assertEquals(id, TcgTpmtHa.TPM_ALG_SHA1);
LOGGER.debug("OK. Parsing of a SHA1 formatted TCG Event Log Success");
}
@ -178,7 +179,7 @@ public class TCGEventLogProcessorTest extends SpringPersistenceTest {
String pcrValue = HexUtils.byteArrayToHexString(digest.getDigest());
if (pcrFromLog[i].compareToIgnoreCase(pcrValue) != 0) {
testPass = false;
LOGGER.error("\ttestTPMBaselineCreate error with PCR " + i);
LOGGER.error("\testTPMBaselineCreate error with PCR " + i);
}
}
}

View File

@ -13,7 +13,7 @@ import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import hirs.tpm.eventlog.TCGEventLogProcessorTest;
import hirs.tpm.eventlog.TCGEventLogTest;
import hirs.utils.HexUtils;
import hirs.tpm.eventlog.uefi.UefiGuid;
import hirs.tpm.eventlog.uefi.UefiPartition;
@ -31,7 +31,7 @@ public class TCGEventLogEventsTest {
private static final String EVENT_HANDOFF_TABLES = "/tcgeventlog/events/EvHandoffTables.txt";
private static final String UEFI_POST_CODE = "/tcgeventlog/events/EvPostCode.txt";
private static final Logger LOGGER
= LogManager.getLogger(TCGEventLogProcessorTest.class);
= LogManager.getLogger(TCGEventLogTest.class);
/**
* Initializes a <code>SessionFactory</code>.

View File

@ -1,43 +1,42 @@
manufacturer,U.S.A
BIOSVENDOR,HirsBIOS
productName,The best product
version,0.6.9
systemSerialNumber,8_8
chassisserialnumber,9_9
baseboardserialnumber,ABC123
tpmMake,Infineon
tpmVersionMajor,1
tpmVersionMinor,2
tpmVersionRevMajor,3
tpmVersionRevMinor,4
0,76abf677781fcb983da780a08fe46920ebb1a058
1,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
2,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
3,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
4,5289e89800f19805192a20fbbc712d18361d3d45
5,7e39b3da2fbbe3a36798ead5e877a7ea60d00db2
6,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
BiOsRelEAseDAtE,04/25/2014
7,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
8,0000000000000000000000000000000000000000
9,0000000000000000000000000000000000000000
10,d917a32ee75f2d7cad093ca1dd8a8a981a3f3832
11,0000000000000000000000000000000000000000
12,0000000000000000000000000000000000000000
13,0000000000000000000000000000000000000000
14,0000000000000000000000000000000000000000
15,0000000000000000000000000000000000000000
16,0000000000000000000000000000000000000000
17,ffffffffffffffffffffffffffffffffffffffff
18,ffffffffffffffffffffffffffffffffffffffff
19,ffffffffffffffffffffffffffffffffffffffff
20,ffffffffffffffffffffffffffffffffffffffff
21,ffffffffffffffffffffffffffffffffffffffff
22,ffffffffffffffffffffffffffffffffffffffff
23,0000000000000000000000000000000000000000
biosversion,abc
osName,Linux
osVersion,3.10.0-123.el7.x86_64
distribution,CentOS
distributionRelease,7.0.1406
manufacturer,U.S.A
BIOS_VENDOR,HirsBIOS
PRODUCT_NAME,The best product
VERSION,0.6.9
SYSTEM_SERIAL_NUMBER,8_8
CHASSIS_SERIAL_NUMBER,9_9
BASEBOARD_SERIAL_NUMBER,ABC123
TPM_MAKE,Infineon
TPM_VERSION_MAJOR,1
TPM_VERSION_MINOR,2
TPM_VERSION_REV_MAJOR,3
TPM_VERSION_REV_MINOR,4
0,76abf677781fcb983da780a08fe46920ebb1a058
1,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
2,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
3,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
4,5289e89800f19805192a20fbbc712d18361d3d45
5,7e39b3da2fbbe3a36798ead5e877a7ea60d00db2
6,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
BIOS_RELEASE_DATE,04/25/2014
7,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
8,0000000000000000000000000000000000000000
9,0000000000000000000000000000000000000000
10,d917a32ee75f2d7cad093ca1dd8a8a981a3f3832
11,0000000000000000000000000000000000000000
12,0000000000000000000000000000000000000000
13,0000000000000000000000000000000000000000
14,0000000000000000000000000000000000000000
15,0000000000000000000000000000000000000000
16,0000000000000000000000000000000000000000
17,ffffffffffffffffffffffffffffffffffffffff
18,ffffffffffffffffffffffffffffffffffffffff
19,ffffffffffffffffffffffffffffffffffffffff
20,ffffffffffffffffffffffffffffffffffffffff
21,ffffffffffffffffffffffffffffffffffffffff
22,ffffffffffffffffffffffffffffffffffffffff
23,0000000000000000000000000000000000000000
BIOS_VERSION,abc
OS_NAME,Linux
OS_VERSION,3.10.0-123.el7.x86_64
DISTRIBUTION,CentOS
DISTRIBUTION_RELEASE,7.0.1406

1 manufacturer U.S.A
2 BIOSVENDOR BIOS_VENDOR HirsBIOS
3 productName PRODUCT_NAME The best product
4 version VERSION 0.6.9
5 systemSerialNumber SYSTEM_SERIAL_NUMBER 8_8
6 chassisserialnumber CHASSIS_SERIAL_NUMBER 9_9
7 baseboardserialnumber BASEBOARD_SERIAL_NUMBER ABC123
8 tpmMake TPM_MAKE Infineon
9 tpmVersionMajor TPM_VERSION_MAJOR 1
10 tpmVersionMinor TPM_VERSION_MINOR 2
11 tpmVersionRevMajor TPM_VERSION_REV_MAJOR 3
12 tpmVersionRevMinor TPM_VERSION_REV_MINOR 4
13 0 76abf677781fcb983da780a08fe46920ebb1a058
14 1 3a3f780f11a4b49969fcaa80cd6e3957c33b2275
15 2 3a3f780f11a4b49969fcaa80cd6e3957c33b2275
16 3 3a3f780f11a4b49969fcaa80cd6e3957c33b2275
17 4 5289e89800f19805192a20fbbc712d18361d3d45
18 5 7e39b3da2fbbe3a36798ead5e877a7ea60d00db2
19 6 3a3f780f11a4b49969fcaa80cd6e3957c33b2275
20 BiOsRelEAseDAtE BIOS_RELEASE_DATE 04/25/2014
21 7 3a3f780f11a4b49969fcaa80cd6e3957c33b2275
22 8 0000000000000000000000000000000000000000
23 9 0000000000000000000000000000000000000000
24 10 d917a32ee75f2d7cad093ca1dd8a8a981a3f3832
25 11 0000000000000000000000000000000000000000
26 12 0000000000000000000000000000000000000000
27 13 0000000000000000000000000000000000000000
28 14 0000000000000000000000000000000000000000
29 15 0000000000000000000000000000000000000000
30 16 0000000000000000000000000000000000000000
31 17 ffffffffffffffffffffffffffffffffffffffff
32 18 ffffffffffffffffffffffffffffffffffffffff
33 19 ffffffffffffffffffffffffffffffffffffffff
34 20 ffffffffffffffffffffffffffffffffffffffff
35 21 ffffffffffffffffffffffffffffffffffffffff
36 22 ffffffffffffffffffffffffffffffffffffffff
37 23 0000000000000000000000000000000000000000
38 biosversion BIOS_VERSION abc
39 osName OS_NAME Linux
40 osVersion OS_VERSION 3.10.0-123.el7.x86_64
41 distribution DISTRIBUTION CentOS
42 distributionRelease DISTRIBUTION_RELEASE 7.0.1406

View File

@ -1,28 +1,27 @@
manufacturer,U.S.A
0,76abf677781fcb983da780a08fe46920ebb1a058
1,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
2,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
3,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
4,5289e89800f19805192a20fbbc712d18361d3d45
5,7e39b3da2fbbe3a36798ead5e877a7ea60d00db2
6,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
osEversion,3.10.0-123.el7.x86_64
7,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
8,0000000000000000000000000000000000000000
9,0000000000000000000000000000000000000000
10,d917a32ee75f2d7cad093ca1dd8a8a981a3f3832
11,0000000000000000000000000000000000000000
12,0000000000000000000000000000000000000000
13,0000000000000000000000000000000000000000
14,0000000000000000000000000000000000000000
15,0000000000000000000000000000000000000000
16,0000000000000000000000000000000000000000
17,ffffffffffffffffffffffffffffffffffffffff
18,ffffffffffffffffffffffffffffffffffffffff
19,ffffffffffffffffffffffffffffffffffffffff
20,ffffffffffffffffffffffffffffffffffffffff
21,ffffffffffffffffffffffffffffffffffffffff
22,ffffffffffffffffffffffffffffffffffffffff
23,0000000000000000000000000000000000000000
distributionRelease,7.0.1406
manufacturer,U.S.A
0,76abf677781fcb983da780a08fe46920ebb1a058
1,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
2,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
3,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
4,5289e89800f19805192a20fbbc712d18361d3d45
5,7e39b3da2fbbe3a36798ead5e877a7ea60d00db2
6,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
OS_VERSION,3.10.0-123.el7.x86_64
7,3a3f780f11a4b49969fcaa80cd6e3957c33b2275
8,0000000000000000000000000000000000000000
9,0000000000000000000000000000000000000000
10,d917a32ee75f2d7cad093ca1dd8a8a981a3f3832
11,0000000000000000000000000000000000000000
12,0000000000000000000000000000000000000000
13,0000000000000000000000000000000000000000
14,0000000000000000000000000000000000000000
15,0000000000000000000000000000000000000000
16,0000000000000000000000000000000000000000
17,ffffffffffffffffffffffffffffffffffffffff
18,ffffffffffffffffffffffffffffffffffffffff
19,ffffffffffffffffffffffffffffffffffffffff
20,ffffffffffffffffffffffffffffffffffffffff
21,ffffffffffffffffffffffffffffffffffffffff
22,ffffffffffffffffffffffffffffffffffffffff
23,0000000000000000000000000000000000000000
DISTRIBUTION_RELEASE,7.0.1406

1 manufacturer U.S.A
2 0 76abf677781fcb983da780a08fe46920ebb1a058
3 1 3a3f780f11a4b49969fcaa80cd6e3957c33b2275
4 2 3a3f780f11a4b49969fcaa80cd6e3957c33b2275
5 3 3a3f780f11a4b49969fcaa80cd6e3957c33b2275
6 4 5289e89800f19805192a20fbbc712d18361d3d45
7 5 7e39b3da2fbbe3a36798ead5e877a7ea60d00db2
8 6 3a3f780f11a4b49969fcaa80cd6e3957c33b2275
9 osEversion OS_VERSION 3.10.0-123.el7.x86_64
10 7 3a3f780f11a4b49969fcaa80cd6e3957c33b2275
11 8 0000000000000000000000000000000000000000
12 9 0000000000000000000000000000000000000000
13 10 d917a32ee75f2d7cad093ca1dd8a8a981a3f3832
14 11 0000000000000000000000000000000000000000
15 12 0000000000000000000000000000000000000000
16 13 0000000000000000000000000000000000000000
17 14 0000000000000000000000000000000000000000
18 15 0000000000000000000000000000000000000000
19 16 0000000000000000000000000000000000000000
20 17 ffffffffffffffffffffffffffffffffffffffff
21 18 ffffffffffffffffffffffffffffffffffffffff
22 19 ffffffffffffffffffffffffffffffffffffffff
23 20 ffffffffffffffffffffffffffffffffffffffff
24 21 ffffffffffffffffffffffffffffffffffffffff
25 22 ffffffffffffffffffffffffffffffffffffffff
26 23 0000000000000000000000000000000000000000
27 distributionRelease DISTRIBUTION_RELEASE 7.0.1406

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SoftwareIdentity xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true">
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<ns2:SoftwareIdentity xmlns:ns2="http://standards.iso.org/iso/19770/-2/2015/schema.xsd" xmlns="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true">
<Signature>
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
@ -9,34 +9,26 @@
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>jfwo1CF30jTNX7m/j85Avnt0EedV/QJIsRUZnaOY+Dg=</DigestValue>
<DigestValue>gLCM4kz8qvB6JkV+yDnv3KzqEloiSsBik2OeyBOSw/A=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>VqUHbt1UqkxlLHVkTOlQs54KWjv5IPKzSCxrsPb8kGjaj5XjHkc1Z/h88znIIMTdCLcyrKgNEXS4
9EHI9nn9LmwXEd/ozKWd8adu6wLdxKj6uIfd0HaCLFrVlnf/b16xO9AW6wp5pLmXwoFi7zBXXJrn
F9MDKy55mXkxb/Z5RUC3IKqsoz+EuKjs6d+yhtb1EQtpJD2dZj23+VjMH4gXxEerDNR1PiPhma/i
QMFa1hwSO7AuasYPy0WCRIgrJ5ZL5x2ZoaSIdE2TsCqnStVL+KLZeMWNCqw4k89hsuELW7Azrl57
Vm2qzPok0svrB1K4QyZdyK2bnG1QY3Fip5Jdmg==</SignatureValue>
<SignatureValue>a+kmQfOSpSaMnazRJIOq2349Iuskpan4vh0N4dobjJ8Tb3lPjf97YiqgFsoSm5uydOPXs/lkN51g
Ox9CCBZ2bquDuuBPpAq5IQ3wZ28G+DYzva+pz7EHKge3gIRzMKjCyDx4bjn+3GUeg+A4KNHNcUfi
qkDVi3245/4IC/nIzm6a+3qVqsYH4mLqp1yO/Xbuqvkc5X0GobGIO6EOhXxuBii6O7GGv+cIVp3v
Xdd9zIwFVedeqeYextz5EDzDNHittmtNd+KEl0N3/45aXGDiRFiuiNy/sf7KR+wutbwJV7RlaDN7
QEaanCXCs6h5PehTh8EDEE9atceBS7IBje0dtw==</SignatureValue>
<KeyInfo>
<X509Data>
<X509SubjectName>CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US</X509SubjectName>
<X509Certificate>MIIDYTCCAkmgAwIBAgIJAPB+r6VBhBn4MA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAlVTMQsw
CQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxEjAQBgNVBAMM
CUV4YW1wbGVDQTAeFw0yMDAyMTAxODE1MzRaFw0yOTEyMTkxODE1MzRaMFwxCzAJBgNVBAYTAlVT
MQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNV
BAMMEmV4YW1wbGUuUklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1
lWGkSRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44/nBaccZD
OjdfIxIUCMfwhGXjxCaqZbgTucNsExDnu4arTGraoAwzHg0cVLiKT/Cxj9NL4dcMgxRXsPdHfXb0
923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY
2hq+z82x/rqwr2hmyizD6FpFSyIABPEMPfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0
Hh4mNFSKD4pP41VSKY1nus83mdkuukPy5o0CAwEAAaMvMC0wCQYDVR0TBAIwADALBgNVHQ8EBAMC
BsAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAGuJ+dasb3/Mb7TBJ1Oe
al5ISq8d2LQD5ke5qnjgSQWKXfQ9fcUy3dWnt3Oked/i8B/Tyk3jCdTZJU3J3iRNgTqFfMLP8rU1
w2tPYBjjuPKiiK4YRBHPxtFxPdOL1BPmL4ZzNs33Lv6H0m4aff9p6QpMclX5b/CRjl+80JWRLiLj
U3B0CejZB9dJrPr9SBaC31cDoeTpja9Cl86ip7KkqrZZIYeMuNF6ucWyWtjrW2kr3UhmEy8x/6y4
KigsK8sBwmNv4N2Pu3RppeIcpjYj5NVA1hwRA4eeMgJp2u+urm3l1oo1UNX1HsSSBHp1Owc9zZLm
07Pl8T46kpIA4sroCAU=</X509Certificate>
</X509Data>
<KeyName>2fdeb8e7d030a2209daa01861a964fedecf2bcc1</KeyName>
<KeyValue>
<RSAKeyValue>
<Modulus>p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx
xkM6N18jEhQIx/CEZePEJqpluBO5w2wTEOe7hqtMatqgDDMeDRxUuIpP8LGP00vh1wyDFFew90d9
dvT3bcLvFh3a3ap9bTm6aBqPup5CXpzrwIU2wZfgkDytYVBm+8bHkMaUrgpNyM+5BAg2zl/Fqw0q
otjaGr7PzbH+urCvaGbKLMPoWkVLIgAE8Qw98HTfoYSFHC7VYQySrzIinaOBFSgViR72kHemH2lW
jDQeHiY0VIoPik/jVVIpjWe6zzeZ2S66Q/LmjQ==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
</SoftwareIdentity>
</ns2:SoftwareIdentity>

1
tools/tcglp/VERSION Normal file
View File

@ -0,0 +1 @@
1.0

157
tools/tcglp/build.gradle Normal file
View File

@ -0,0 +1,157 @@
task wrapper(type: Wrapper) {
gradleVersion = '2.10'
}
allprojects {
task addPlugins << {
delete './build/plugins'
mkdir './build/plugins'
if (project.hasProperty('pluginDir')) {
if (pluginDir?.trim()) {
copy {
from "$pluginDir"
into 'build/plugins'
include '*.jar'
include '**/*.jar'
}
}
}
}
task copyVersion() {
doLast {
if (project.hasProperty('displayVersion')) {
String resourceDir="${buildDir}/resources/main"
println "setting app version file contents of: ${displayVersion} to ${resourceDir}"
new File(resourceDir, "VERSION").write("$displayVersion")
}
}
}
group = 'hirs'
version = file("$rootDir/VERSION").text.trim() + "-SNAPSHOT"
}
subprojects {
apply plugin: 'java'
apply plugin: 'maven-publish'
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-Werror"
}
repositories {
mavenCentral()
}
test {
testLogging {
exceptionFormat = 'full'
}
}
tasks.withType(Test) {
useTestNG() {
includeGroups = project.ext.includeGroups.split()
excludeGroups = project.ext.excludeGroups.split()
}
afterSuite { desc, result ->
if (desc.parent == null) {
logger.lifecycle("${result.successfulTestCount}/${result.testCount} tests passed")
}
}
}
tasks.withType(FindBugs) {
reports {
xml.enabled = false
html.enabled = true
}
}
tasks.withType(Pmd) {
reports {
xml.enabled = false
html.enabled = true
}
}
publishing {
repositories {
if(findProperty("env") != null && findProperty("env") == "CI") {
maven {
url "$rootDir/librepo"
}
} else {
mavenLocal()
}
}
}
// Global checkstyle file
ext.checkstyleConfigFile = new File(rootDir, "/config/checkstyle/sun_checks.xml")
// Version definitions of all of the libraries we're using. They're defined
// here to ensure that all projects are using the same versions of common
// dependencies:
ext.libs = [
bouncy_castle: 'org.bouncycastle:bcmail-jdk15on:1.59',
checkstyle: 'com.puppycrawl.tools:checkstyle:8.10.1',
commons_cli: 'commons-cli:commons-cli:1.2',
commons_codec: 'commons-codec:commons-codec:1.9',
commons_csv: 'org.apache.commons:commons-csv:1.4',
commons_exec: 'org.apache.commons:commons-exec:1.3',
commons_http: 'commons-httpclient:commons-httpclient:3.1',
commons_io: 'commons-io:commons-io:2.4',
commons_lang: 'org.apache.commons:commons-lang3:3.3.2',
commons_upload:'commons-fileupload:commons-fileupload:1.3.1',
commons_valid: 'commons-validator:commons-validator:1.4.0',
findbugs: 'com.google.code.findbugs:findbugs:3.0.0',
gson: 'com.google.code.gson:gson:2.2.4',
guava: 'com.google.guava:guava:18.0',
hibernate: [ 'org.hibernate.common:hibernate-commons-annotations:4.0.4.Final',
'org.hibernate:hibernate-core:4.3.11.Final',
'org.hibernate:hibernate-hikaricp:4.3.11.Final'],
hikari: 'com.zaxxer:HikariCP:2.4.1',
hsqldb: 'org.hsqldb:hsqldb:2.3.2',
http: 'org.apache.httpcomponents:httpclient:4.5',
jackson: [ 'com.fasterxml.jackson.core:jackson-core:2.6.3',
'com.fasterxml.jackson.core:jackson-databind:2.6.3',
'com.fasterxml.jackson.core:jackson-annotations:2.6.3'],
jadira_usertype: 'org.jadira.usertype:usertype.core:4.0.0.GA',
jcommander: 'com.beust:jcommander:1.35',
joda_time: 'joda-time:joda-time:2.9.4',
jstl: [ 'org.apache.taglibs:taglibs-standard-impl:1.2.5',
'org.apache.taglibs:taglibs-standard-spec:1.2.5'],
log4j2: [ 'org.apache.logging.log4j:log4j-api:2.8.1',
'org.apache.logging.log4j:log4j-core:2.8.1',
'org.apache.logging.log4j:log4j-slf4j-impl:2.8.1'],
log4j2_web: 'org.apache.logging.log4j:log4j-web:2.8.1',
log_bridge: 'org.apache.logging.log4j:log4j-jcl:2.8.1',
mockito: 'org.mockito:mockito-all:1.10.19',
mariadb: 'org.mariadb.jdbc:mariadb-java-client:2.2.1',
minimal_json: 'com.eclipsesource.minimal-json:minimal-json:0.9.5',
pci_ids: 'com.github.marandus:pci-ids:0.3',
pmd: 'net.sourceforge.pmd:pmd:5.1.1',
powermock: [ 'org.powermock:powermock-core:1.6.3',
'org.powermock:powermock-api-mockito:1.6.3',
'org.powermock:powermock-module-testng:1.6.3' ],
protobuf_java: 'com.google.protobuf:protobuf-java:3.4.0',
reflections: 'org.reflections:reflections:0.9.9-RC1',
servlet_api: 'javax.servlet:servlet-api:2.5',
slf4j: 'org.slf4j:slf4j-api:1.7.13',
spring_core: ['org.springframework:spring-aop:4.2.3.RELEASE',
'org.springframework:spring-beans:4.2.3.RELEASE',
'org.springframework:spring-context:4.2.3.RELEASE',
'org.springframework:spring-expression:4.2.3.RELEASE',
'org.springframework:spring-orm:4.2.3.RELEASE'],
spring_msg: 'org.springframework:spring-messaging:4.2.3.RELEASE',
spring_plugin: 'org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE',
spring_retry: 'org.springframework.retry:spring-retry:1.2.0.RELEASE',
spring_test: 'org.springframework:spring-test:4.2.3.RELEASE',
spring_web: 'org.springframework:spring-web:4.2.3.RELEASE',
spring_webmvc: 'org.springframework:spring-webmvc:4.2.3.RELEASE',
testng: 'org.testng:testng:6.8.8',
xml_rpc_client: 'org.apache.xmlrpc:xmlrpc-client:3.1.3',
]
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,6 @@
#Thu Sep 13 15:33:27 EDT 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=gradle-4.5.1-all.zip

160
tools/tcglp/gradlew vendored Executable file
View File

@ -0,0 +1,160 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

View File

@ -0,0 +1,389 @@
package hirs.tcg_eventlog_tool;
import java.io.File;
import java.io.IOException;
import java.nio.file.InvalidPathException;
/**
* Commander is a class that handles the command line arguments for the
* TCG Log Parser (tcg_eventlotool).
*/
public class Commander {
private static final String COMMAND_PREFIX = "-";
private static final String FULL_COMMAND_PREFIX = "--";
private static final String ALL_STRING = "all";
private static final String CONTENT_STRING = "contenthex";
private static final String DIFF_STRING = "diff";
private static final String EVENTIDS_STRING = "event";
private static final String FILE_STRING = "file";
private static final String HELP_STRING = "help";
private static final String EVENTHEX_STRING = "eventhex";
private static final String HEX_STRING = "hex";
private static final String OUTPUT_STRING = "output";
private static final String PCR_STRING = "pcr";
private static final String VERIFY_STRING = "Verify";
private static final String VERSION_STRING = "version";
private static final String VERSION_NUMBER = "1.0";
private boolean hasArguments = false;
private boolean bAll = false;
private boolean bContentHex = false;
private boolean bDiff = false;
private boolean bEventIds = false;
private boolean bFile = false;
private boolean bEventHex = false;
private boolean bHex = false;
private boolean bOutput = false;
private boolean bPCRs = false;
private boolean bVerify = false;
private String inFile = "";
private String inFile2 = "";
private String outFile = "";
private String eventFilter = "";
private String pcrFilter = "";
private int pcrNumber = -1;
private int eventNumber = -1;
/**
* The main constructor for the Commander class
*
* @param args
*/
public Commander(final String[] args) {
hasArguments = args.length > 0;
if (hasArguments) {
parseArguments(args);
} else {
printHelp("");
}
}
/**
* This method is called if an empty Commander was created, and later gets
* args. Will be used by the main constructor.
*
* @param args
*/
public final void parseArguments(final String[] args) {
String tempValue;
for (int i = 0; i < args.length; i++) {
tempValue = args[i];
switch (tempValue) {
case FULL_COMMAND_PREFIX + ALL_STRING:
case COMMAND_PREFIX + "a":
bAll = true;
break;
case FULL_COMMAND_PREFIX + CONTENT_STRING:
case FULL_COMMAND_PREFIX + EVENTIDS_STRING:
case COMMAND_PREFIX + "e":
if (i<args.length-1) { // Check for a filter following the -e on the command line
if (!args[i+1].startsWith("-")) {
eventFilter=args[i+++1];
eventNumber = new Integer(eventFilter).intValue();
}
}
bEventIds = true;
break;
case COMMAND_PREFIX + "ec":
bContentHex = true;
break;
case FULL_COMMAND_PREFIX + EVENTHEX_STRING:
case COMMAND_PREFIX + "ex":
bEventHex = true;
break;
case FULL_COMMAND_PREFIX + DIFF_STRING:
case COMMAND_PREFIX + "d":
if ((args.length < i+3)||(args[i+1].charAt(0)=='-')||(args[i+2].charAt(0)=='-')){
System.out.print("tcg_eventlog_tool command line error: 2 or 3 parameters needed for -diff.\n");
System.out.print("usage: elt -d logFile1 logFile2 pcr#");
System.exit(0);
} else {
inFile = args[i+++1];
inFile2 = args[i+++1];
if (args.length>i+1) {
if (!args[i+1].contains("-")) { // pcr filter provided
eventFilter = args[i+++1];
eventNumber = new Integer(eventFilter).intValue();
}
}
bDiff = true;
}
break;
case FULL_COMMAND_PREFIX + FILE_STRING:
case COMMAND_PREFIX + "f":
bFile = true;
inFile = args[++i];
break;
case FULL_COMMAND_PREFIX + OUTPUT_STRING:
case COMMAND_PREFIX + "o":
if (i<args.length-1) { // Check for a filter following the -p on the command line
if (!args[i+1].startsWith("-")) {
outFile=args[i+++1];
} else {
System.out.print("no output file specified with -o option");
System.exit (1);
}
}
bOutput = true;
break;
case FULL_COMMAND_PREFIX + PCR_STRING:
case COMMAND_PREFIX + "p":
if (i<args.length-1) { // Check for a filter following the -p on the command line
if (!args[i+1].startsWith("-")) {
pcrFilter=args[i+++1];
pcrNumber = new Integer(pcrFilter).intValue();
}
}
bPCRs = true;
break;
case FULL_COMMAND_PREFIX + VERSION_STRING:
case COMMAND_PREFIX + "v":
System.out.print("TCG Event Log Parser version " + VERSION_NUMBER);
System.exit (0);
break;
case FULL_COMMAND_PREFIX + VERIFY_STRING:
case COMMAND_PREFIX + "V":
bVerify = true;
break;
case FULL_COMMAND_PREFIX + HEX_STRING:
case COMMAND_PREFIX + "x":
bHex = true;
break;
case FULL_COMMAND_PREFIX + HELP_STRING:
case COMMAND_PREFIX + "h":
default:
printHelp("");
}
}
}
/**
* Getter for the property that indicates if something was given at the commandline.
*
* @return true if any arguments were passed in.
*/
public final boolean hasArguments() {
return hasArguments;
}
/**
* Getter for the input All flag.
* @return true if the All flag was set.
*/
public final boolean getAllFlag() {
return bAll;
}
/**
* Getter for the input associated with the PCR flag.
* @return true if the PCR Flag was set.
*/
public final boolean getPCRFlag() {
return bPCRs;
}
/**
* Getter for the input associated with the Event flag.
* @return true if the Event Flag was set.
*/
public final boolean getContentFlag() {
return bContentHex;
}
/**
* Getter for the input associated with the Event Hex flag.
* @return true if the Hex Flag was set.
*/
public final boolean getEventHexFlag() {
return bEventHex;
}
/**
* Getter for the input associated with the Hex flag.
* @return true if the Hex Flag was set.
*/
public final boolean getHexFlag() {
return bHex;
}
/**
* Getter for the input associated with the EventIds flag.
* @return true of EventIds Falg was set.
*/
public final boolean getEventIdsFlag() {
return bEventIds;
}
/**
* Getter for the input associated with the File flag.
* @return true if File Flage was set.
*/
public final boolean getFileFlag() {
return bFile;
}
/**
* Getter for the input associated with the diff flag.
* @return
*/
public final boolean getDiffFlag() {
return bDiff;
}
/**
* Getter for the input associated with the Verify flag.
* @return
*/
public final boolean getVerifyFile() {
return bVerify;
}
/**
* Returns the name of the input file, if provided.
* @return name of the input file.
*/
public final String getInFileName() {
return inFile;
}
/**
* Returns the name of the 2nd input file, if provided.
* @return name of the 2nd input file.
*/
public final String getInFile2Name() {
return inFile2;
}
/**
* Returns the name of the 2nd input file, if provided.
* @return name of the 2nd input file.
*/
public final String getEventFilter() {
return eventFilter;
}
/**
* Returns the name of the 2nd input file, if provided.
* @return name of the 2nd input file.
*/
public final int getEventNumber() {
return eventNumber;
}
/**
* Getter for the input associated with the Output flag.
* @return true if the Output flag was set.
*/
public final boolean getOutputFlag() {
return bOutput;
}
/**
* Returns the name of the output file, if provided.
* @return name of the output file.
*/
public final String getOutputFileName() {
return outFile;
}
/**
* Returns the name of the 2nd input file, if provided.
* @return name of the 2nd input file.
*/
public final String getPcrFilter() {
return pcrFilter;
}
/**
* Returns the name of the 2nd input file, if provided.
* @return name of the 2nd input file.
*/
public final int getPcrNumber() {
return pcrNumber;
}
/**
* This method is used to inform the user of the allowed functionality of
* the program.
*/
private void printHelp(String message) {
StringBuilder sb = new StringBuilder();
String os = System.getProperty("os.name").toLowerCase();
if (message != null && !message.isEmpty()) {
sb.append(String.format("ERROR: %s\n\n", message));
}
sb.append("\nTCG Log Parser ");
if (os.compareToIgnoreCase("linux")==0) {
sb.append("Usage: sh elt.sh [OPTION]...-f [FILE]...\n");
} else {
sb.append("Usage: ./elt.ps1 [OPTION]...-f [FILE]...\n");
}
sb.append("Options:\n"
+ " -f\t--file\t\t Use specific Event Log file. "
+ "\n\t\t\t Following parameter MUST be a path and file name."
+ "\n\t\t\t The local Event Log file will be used if this option is not present."
+ "\n\t\t\t Note: Access to the local Event Log may require admin privileges.\n"
+ " -e\t--event\t\t Display event descriptions (including event content) in human readable form. "
+ "\n\t\t\t Following optional parameter is a single pcr id used to filter"
+ " the output."
+ "\n\t\t\t All events will be displayed if the optional parameter is not provided.\n"
+ " -ec\t--contenthex\t Displays event content"
+ " in eventhex format when -event is used.\n"
+ " -ex\t--eventhex\t Displays event in hex format when -event is used"
+ " when -event is used.\n"
+ " -d\t--diff\t\t Compares two TCG Event Logs and outputs a list of events"
+ " of the second log that differred.\n"
+ " -o\t--output\t Output to a file. "
+ "\n\t\t\t Following parameter MUST be a relative path and file name.\n"
+ " -p\t--pcr\t\t Output expected PCR value calculated from the "
+ "TCG Log (for PCR Replay)."
+ "\n\t\t\t Following parameter MAY be a PCR number used to specify a single pcr."
+ "\n\t\t\t No following parameters will display all PCRs.\n"
+ " -v\t--version\t Parser Version.\n"
// + " -V\t--Verify\t Attempts to verify the log file against values on the local device."
+ " -x\t--hex\t\t Displays output in hex format."
+ "\n\t\t\t Use -e -ec and -ex options to filter output."
+ "\n\t\t\t All output will be human readble form if this parameter is not present.\n"
+ "\n");
if (os.compareToIgnoreCase("linux")==0) {
sb.append("\nIf no FILE parameter is provided then the standard Linux TCGEventLog path "
+ "\n(/sys/kernel/security/tpm0/binary_bios_measurements) is used."
+"\n Note admin privileges may be required (e.g. use sudo when running the script).\n"
+"All OPTIONS must be seperated by a space delimiter, no concatenation"
+ " of OPTIONS is currently supported.\n"
+"\nExamples: (run from the script directory)\n"
+"1. Display all events from the binary_bios_measurements.bin test pattern:\n"
+" sh elt.sh -f ../test/testdata/binary_bios_measurements_Dell_Fedora30.bin -e\n"
+"2. Display only the event with an index of 0 (e.g event that extend PCR 0):\n"
+" sh scripts/elt.sh -f "
+ "../test/testdata/binary_bios_measurements_Dell_Fedora30.bin -p 0\n"
);
} else { //windows
sb.append("\nIf no FILE parameter is provided then the "
+ "standard Windows TCGEventLog path (C:\\Windows\\Logs\\MeasuredBoot) is used"
+"\n Note admin privileges may be required (e.g. run as Administrator).\n"
+"All OPTIONS must be seperated by a space delimiter, "
+ "no concatenation of OPTIONS is currently supported.\n"
+"\nExamples:(run from the script directory)\n"
+"1. Display all events from the binary_bios_measurements.bin test pattern:\n"
+" ./elt.ps1 -f "
+ "..\\test\\testdata\\binary_bios_measurements_Dell_Fedora30.bin -e\n"
+"2. Display only the event with an index of 0 (e.g event that extend PCR 0):\n"
+" ./elt.ps1 -f "
+ "..\\test\\testdata\\binary_bios_measurements_Dell_Fedora30.bin -p 0\n"
);
}
System.out.println(sb.toString());
System.exit(1);
}
/**
* Checks that the file given to create a new swidtag is a valid path.
* @param filepath
* @return
*/
public static boolean isValidPath(String filepath) {
try {
System.out.println("Checking for a valid creation path...");
File file = new File(filepath);
file.createNewFile();
} catch (IOException | InvalidPathException | NullPointerException ex) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,277 @@
package hirs.tcg_eventlog_tool;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.tpm.eventlog.TpmPcrEvent;
import hirs.utils.HexUtils;
/**
* Command-line application for processing TCG Event Logs.
* Input arg: path to *.tcglp file
*
*/
public class Main {
private static Commander commander = null;
static FileOutputStream outputStream = null;
static byte[] eventLog = null;
static boolean bContentFlag, bEventFlag, bHexEvent, bHexFlag, bPcrFlag, bOutFile = false;
public static void main(String[] args) {
commander = new Commander(args);
if (commander.hasArguments()) {
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.getAllFlag()) {
System.out.print("All option is not yet implemented");
System.exit(1);
}
if (commander.getContentFlag()) {
bContentFlag = true;
}
if (commander.getDiffFlag()) {
bEventFlag = true;
if(commander.getHexFlag()) {
bHexFlag=bHexEvent = bContentFlag = 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);
// Check for pcr flag
if (bPcrFlag) {
String[] pcrs = evLog.getExpectedPCRValues();
int count = 0;
if(!commander.getHexFlag()) {
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) {
for (TpmPcrEvent event: evLog.getEventList()) {
if ((commander.getEventNumber() == event.getPcrIndex())|| commander.getEventNumber() == -1) {
if(bHexFlag) {
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");
}
}
}
}
} catch (Exception e) {
System.out.print("Error processing Event Log " + commander.getInFileName()
+ "\nError was "+ e.toString());
System.exit(1);
}
}
/**
* Opens a TCG Event log file
* @param fileName Name of the log file. Will use a OS specific default file if none is supplied.
* @param os the name os of the current system
* @return a byte array holding the entire log
*/
public static byte[] openLog(String fileName) {
String os = System.getProperty("os.name").toLowerCase();
byte[] rawLog=null;
boolean bDefault = false;
try {
if (fileName == "") {
if (os.compareToIgnoreCase("linux")==0) { // need to find Windows path
fileName = "/sys/kernel/security/tpm0/binary_bios_measurements";
bDefault = true;
writeOut("Local Event Log being used: "+fileName +"\n");
}
}
Path path = Paths.get(fileName);
rawLog = Files.readAllBytes(path);
if(!commander.getHexFlag()) {
writeOut("TPM Event Log parser opening file:"+ path +"\n\n");
}
} catch (Exception e) {
String error = "Error reading event Log File: " + e.toString();
if (bDefault) {
error += "\nTry using the -f option to specify an Event Log File";
}
writeOut(error);
System.exit(1);
}
return rawLog;
}
/**
* Write data out to the system and/or a file.
* @param data
*/
private static void writeOut(String data) {
try {
data = data.replaceAll("[^\\P{C}\t\r\n]", ""); // remove any null characters that seem to upset text editors
if(commander.getOutputFlag()) {
outputStream.write(data.getBytes()); // Write to an output file
} else {
System.out.print(data); // output to the console
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 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 refernce.
* @return A sting containing human readable results.
*/
public static String compareLogs (String LogFileName1, String LogFileName2) {
TCGEventLog eventLog = null, eventLog2 = null;
byte[] evLog = openLog(LogFileName1);
byte[] evLog2 = openLog(LogFileName2);
StringBuilder sb = new StringBuilder();
try {
eventLog = new TCGEventLog(evLog);
} catch (Exception e) {
sb.append("Error processing event log " + LogFileName1 + " : " + e.getMessage());
return sb.toString();
} try {
eventLog2 = new TCGEventLog(evLog2);
ArrayList<TpmPcrEvent> errors = diffEventLogs(eventLog.getEventList(),
eventLog2.getEventList(), commander.getPcrNumber() );
if (errors.isEmpty() && !bHexFlag) {
sb.append("Event Log " + LogFileName1 + " MATCHED EventLog "+ LogFileName2);
} else {
if (!errors.isEmpty() && !bHexFlag) {
sb.append("Event Log " + LogFileName1
+ " did NOT match EventLog " + LogFileName2 + "\n");
sb.append("There were " + errors.size() + " event mismatches: \n\n");
}
for (TpmPcrEvent error : errors ) {
if(bHexFlag) {
if(bEventFlag || bHexEvent) {
writeOut(HexUtils.byteArrayToHexString(error.getEvent())+ "\n");
}
if(bContentFlag) {
writeOut(HexUtils.byteArrayToHexString(error.getEventContent())+ "\n");
}
}
else {
writeOut(error.toString(bEventFlag, bContentFlag, bHexEvent) + "\n");
}
}
}
} catch (Exception e) {
writeOut("Error processing event log " + LogFileName2 + " : " + e.getMessage());
}
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
* @param eventList2 events to compare against
* @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(ArrayList<TpmPcrEvent> eventList,
ArrayList<TpmPcrEvent> eventList2, 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;
}
/**
* 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.
* @return
*/
private static boolean digestMatch(final ArrayList<TpmPcrEvent> eventLog, final TpmPcrEvent event) {
boolean matchFound = false;
for (TpmPcrEvent event2 : eventLog) {
if((event.getPcrIndex() == event2.getPcrIndex())
&& (Arrays.equals(event.getEventDigest(), event2.getEventDigest()))) {
matchFound = true;
}
}
return matchFound;
}
}