mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-02-21 18:06:42 +00:00
Merge branch 'issue-249' into issue-252
This commit is contained in:
commit
56552898da
@ -3,7 +3,7 @@ package hirs.attestationca.portal.page.controllers;
|
|||||||
import hirs.data.persist.ReferenceManifest;
|
import hirs.data.persist.ReferenceManifest;
|
||||||
import hirs.data.persist.SwidResource;
|
import hirs.data.persist.SwidResource;
|
||||||
import hirs.persist.ReferenceManifestManager;
|
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.Page;
|
||||||
import hirs.attestationca.portal.page.PageController;
|
import hirs.attestationca.portal.page.PageController;
|
||||||
import hirs.attestationca.portal.page.PageMessages;
|
import hirs.attestationca.portal.page.PageMessages;
|
||||||
@ -157,7 +157,7 @@ public class ReferenceManifestDetailsPageController
|
|||||||
data.put("rimType", rim.getRimType());
|
data.put("rimType", rim.getRimType());
|
||||||
List<SwidResource> resources = rim.parseResource();
|
List<SwidResource> resources = rim.parseResource();
|
||||||
String resourceFilename = null;
|
String resourceFilename = null;
|
||||||
TCGEventLogProcessor logProcessor = new TCGEventLogProcessor();
|
TCGEventLog logProcessor = new TCGEventLog();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (SwidResource swidRes : resources) {
|
for (SwidResource swidRes : resources) {
|
||||||
@ -166,7 +166,7 @@ public class ReferenceManifestDetailsPageController
|
|||||||
SwidResource.RESOURCE_UPLOAD_FOLDER,
|
SwidResource.RESOURCE_UPLOAD_FOLDER,
|
||||||
resourceFilename));
|
resourceFilename));
|
||||||
if (Files.exists(logPath)) {
|
if (Files.exists(logPath)) {
|
||||||
logProcessor = new TCGEventLogProcessor(
|
logProcessor = new TCGEventLog(
|
||||||
Files.readAllBytes(logPath));
|
Files.readAllBytes(logPath));
|
||||||
swidRes.setPcrValues(Arrays.asList(
|
swidRes.setPcrValues(Arrays.asList(
|
||||||
logProcessor.getExpectedPCRValues()));
|
logProcessor.getExpectedPCRValues()));
|
||||||
|
@ -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 {
|
|
||||||
|
|
||||||
}
|
|
@ -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 {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -2,11 +2,19 @@ package hirs.tpm.eventlog;
|
|||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import hirs.data.persist.Digest;
|
||||||
|
import hirs.data.persist.DigestAlgorithm;
|
||||||
|
import hirs.data.persist.TPMMeasurementRecord;
|
||||||
|
import hirs.data.persist.TpmWhiteListBaseline;
|
||||||
import hirs.tpm.eventlog.events.EvConstants;
|
import hirs.tpm.eventlog.events.EvConstants;
|
||||||
|
import hirs.tpm.eventlog.uefi.UefiConstants;
|
||||||
import hirs.utils.HexUtils;
|
import hirs.utils.HexUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,7 +23,12 @@ import hirs.utils.HexUtils;
|
|||||||
public final class TCGEventLog {
|
public final class TCGEventLog {
|
||||||
|
|
||||||
// private static final Logger LOGGER = (Logger) LogManager.getLogger(TCGEventLog.class);
|
// private static final Logger 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.*/
|
/** Initial value for SHA 256 values.*/
|
||||||
public static final String INIT_SHA256_LIST = "00000000000000000000000000"
|
public static final String INIT_SHA256_LIST = "00000000000000000000000000"
|
||||||
+ "00000000000000000000000000000000000000";
|
+ "00000000000000000000000000000000000000";
|
||||||
@ -39,7 +52,12 @@ public final class TCGEventLog {
|
|||||||
private String hashType;
|
private String hashType;
|
||||||
/** Initial Value to use. */
|
/** Initial Value to use. */
|
||||||
private String initValue;
|
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.
|
* Default blank object constructor.
|
||||||
*/
|
*/
|
||||||
@ -47,47 +65,64 @@ public final class TCGEventLog {
|
|||||||
this.pcrList = new byte[PCR_COUNT][EvConstants.SHA1_LENGTH];
|
this.pcrList = new byte[PCR_COUNT][EvConstants.SHA1_LENGTH];
|
||||||
initValue = INIT_SHA1_LIST;
|
initValue = INIT_SHA1_LIST;
|
||||||
pcrLength = EvConstants.SHA1_LENGTH;
|
pcrLength = EvConstants.SHA1_LENGTH;
|
||||||
|
hashType = HASH_STRING;
|
||||||
|
algorithm = "TPM_ALG_SHA1";
|
||||||
initPcrList();
|
initPcrList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor for just the rawlog that'll set up SHA1 Log.
|
* Simple constructor for Event Log.
|
||||||
* @param rawlog data for the event log file.
|
* @param rawlog data for the event log file.
|
||||||
* @throws NoSuchAlgorithmException if an unknown algorithm is encountered.
|
* @throws NoSuchAlgorithmException if an unknown algorithm is encountered.
|
||||||
* @throws CertificateException if a certificate in the log cannot be parsed.
|
* @throws CertificateException if a certificate in the log cannot be parsed.
|
||||||
* @throws IOException IO Stream if event cannot be parsed.
|
* @throws IOException IO Stream if event cannot be parsed.
|
||||||
*/
|
*/
|
||||||
public TCGEventLog(final byte[] rawlog) throws CertificateException, NoSuchAlgorithmException,
|
public TCGEventLog(final byte[] rawlog)
|
||||||
IOException {
|
throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||||
this(rawlog, EvConstants.SHA1_LENGTH, HASH_STRING, INIT_SHA1_LIST);
|
this(rawlog, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor for specific log.
|
* Default constructor for just the rawlog that'll set up SHA1 Log.
|
||||||
* @param rawlog data for the event log file
|
* @param rawlog data for the event log file.
|
||||||
* @param pLength determined by SHA1 or 256
|
* @param bEventFlag if true provides human readable event descriptions.
|
||||||
* @param hType the type of algorithm
|
* @param bContentFlag if true provides hex output for Content in the description.
|
||||||
* @param iValue the default blank value.
|
* @param bHexEventFlag if true provides hex event structure in the description.
|
||||||
* @throws IOException IO Stream for the event log
|
|
||||||
* @throws NoSuchAlgorithmException if an unknown algorithm is encountered.
|
* @throws NoSuchAlgorithmException if an unknown algorithm is encountered.
|
||||||
* @throws CertificateException f a certificate in the log cannot be parsed.
|
* @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 pLength, final String hType,
|
public TCGEventLog(final byte[] rawlog, final boolean bEventFlag,
|
||||||
final String iValue) throws IOException, CertificateException,
|
final boolean bContentFlag, final boolean bHexEventFlag)
|
||||||
NoSuchAlgorithmException {
|
throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||||
pcrLength = pLength;
|
|
||||||
|
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.pcrList = new byte[PCR_COUNT][pcrLength];
|
||||||
hashType = hType;
|
int eventNumber = 0;
|
||||||
initValue = iValue;
|
bContent = bContentFlag;
|
||||||
|
bEvent = bEventFlag;
|
||||||
|
bHexEvent = bHexEventFlag;
|
||||||
ByteArrayInputStream is = new ByteArrayInputStream(rawlog);
|
ByteArrayInputStream is = new ByteArrayInputStream(rawlog);
|
||||||
// Process the 1st entry as a SHA1 format (per the spec)
|
// 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
|
// put all events into an event list for further processing
|
||||||
|
|
||||||
while (is.available() > 0) {
|
while (is.available() > 0) {
|
||||||
if (hashType.compareToIgnoreCase(HASH_STRING) == 0) {
|
if (bCryptoAgile) {
|
||||||
eventList.add(new TpmPcrEvent1(is));
|
eventList.add(new TpmPcrEvent2(is, eventNumber++));
|
||||||
} else {
|
} else {
|
||||||
eventList.add(new TpmPcrEvent2(is));
|
eventList.add(new TpmPcrEvent1(is, eventNumber++));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
calculatePcrValues();
|
calculatePcrValues();
|
||||||
@ -104,6 +139,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.
|
* Calculates the "Expected Values for TPM PCRs based upon Event digests in the Event Log.
|
||||||
* Uses the algorithm and eventList passed into the constructor,
|
* Uses the algorithm and eventList passed into the constructor,
|
||||||
@ -157,6 +220,13 @@ public final class TCGEventLog {
|
|||||||
return pcrs;
|
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).
|
* Returns a single PCR value given an index (PCR Number).
|
||||||
*
|
*
|
||||||
@ -167,4 +237,55 @@ public final class TCGEventLog {
|
|||||||
return HexUtils.byteArrayToHexString(pcrList[index]);
|
return HexUtils.byteArrayToHexString(pcrList[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Human readable string representing the contents of the Event Log.
|
||||||
|
* @return Description of the log.
|
||||||
|
*/
|
||||||
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,147 +0,0 @@
|
|||||||
package hirs.tpm.eventlog;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
|
|
||||||
import hirs.data.persist.TPMMeasurementRecord;
|
|
||||||
import hirs.data.persist.TpmWhiteListBaseline;
|
|
||||||
import hirs.tpm.eventlog.events.EvConstants;
|
|
||||||
import hirs.tpm.eventlog.uefi.UefiConstants;
|
|
||||||
import hirs.utils.HexUtils;
|
|
||||||
import hirs.data.persist.Digest;
|
|
||||||
import hirs.data.persist.DigestAlgorithm;;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
/** Number of PCRs in a TPM PCR Bank. */
|
|
||||||
private static final int PCR_COUNT = 24;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default Constructor.
|
|
||||||
*/
|
|
||||||
public TCGEventLogProcessor() {
|
|
||||||
tcgLog = new TCGEventLog();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param rawLog the byte array holding the contents of the TCG Event Log.
|
|
||||||
* @throws IOException IO Stream for the event log.
|
|
||||||
* @throws NoSuchAlgorithmException if an unknown algorithm is encountered.
|
|
||||||
* @throws CertificateException f a certificate in the log cannot be parsed.
|
|
||||||
*/
|
|
||||||
public TCGEventLogProcessor(final byte[] rawLog) throws IOException, CertificateException,
|
|
||||||
NoSuchAlgorithmException {
|
|
||||||
if (isLogCrytoAgile(rawLog)) {
|
|
||||||
tcgLog = new TCGEventLog(rawLog, EvConstants.SHA256_LENGTH,
|
|
||||||
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.getExpectedPCRValue(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
|
|
||||||
*/
|
|
||||||
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 = tcgLog.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 = tcgLog.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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[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");
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,6 +21,7 @@ import hirs.tpm.eventlog.events.EvNoAction;
|
|||||||
import hirs.tpm.eventlog.events.EvPostCode;
|
import hirs.tpm.eventlog.events.EvPostCode;
|
||||||
import hirs.tpm.eventlog.events.EvSCrtmContents;
|
import hirs.tpm.eventlog.events.EvSCrtmContents;
|
||||||
import hirs.tpm.eventlog.events.EvSCrtmVersion;
|
import hirs.tpm.eventlog.events.EvSCrtmVersion;
|
||||||
|
import hirs.tpm.eventlog.uefi.UefiConstants;
|
||||||
import hirs.tpm.eventlog.uefi.UefiFirmware;
|
import hirs.tpm.eventlog.uefi.UefiFirmware;
|
||||||
import hirs.tpm.eventlog.uefi.UefiVariable;
|
import hirs.tpm.eventlog.uefi.UefiVariable;
|
||||||
import hirs.utils.HexUtils;
|
import hirs.utils.HexUtils;
|
||||||
@ -51,28 +52,24 @@ public class TpmPcrEvent {
|
|||||||
private long eventType = 0;
|
private long eventType = 0;
|
||||||
/** Event digest. */
|
/** Event digest. */
|
||||||
private byte[] digest = null;
|
private byte[] digest = null;
|
||||||
|
/** Even data (no content). */
|
||||||
|
private byte[] event;
|
||||||
/** Even content data. */
|
/** Even content data. */
|
||||||
private byte[] eventContent;
|
private byte[] eventContent;
|
||||||
/** TCG Event Log spec version. */
|
/** TCG Event Log spec version. */
|
||||||
private String version = "Unknown";
|
private String version = "Unknown";
|
||||||
/** TCG Event Log errata version. */
|
/** TCG Event Log errata version. */
|
||||||
private String errata = "Unknown";
|
private String errata = "Unknown";
|
||||||
|
/** Description for toString support. */
|
||||||
|
private String description = "";
|
||||||
/** Length (in bytes) of a pcr. */
|
/** Length (in bytes) of a pcr. */
|
||||||
private int digestLength = 0;
|
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. */
|
/** Event hash for SHA1 event logs. */
|
||||||
private byte[] eventDataSha1hash;
|
private byte[] eventDataSha1hash;
|
||||||
/** Event hash for Crypto Agile events. */
|
/** Event hash for Crypto Agile events. */
|
||||||
private byte[] eventDataSha256hash;
|
private byte[] eventDataSha256hash;
|
||||||
/** Signature extension mask.*/
|
/** Indent Offset. */
|
||||||
private static final long SIGN_MASK = 0x00000000FFFFFFFFL;
|
private static final int INDENT_3 = 3;
|
||||||
/** Mask used to remove upper values from a long. */
|
|
||||||
private static final long INT_MASK = 0x000000007FFFFFFFL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@ -148,7 +145,7 @@ public class TpmPcrEvent {
|
|||||||
* @param type byte array holding the PFP defined log event type
|
* @param type byte array holding the PFP defined log event type
|
||||||
*/
|
*/
|
||||||
protected void setEventType(final byte[] 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() {
|
public String getSpecErrataVersion() {
|
||||||
return errata;
|
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.
|
* Sets the event content after processing.
|
||||||
*
|
*
|
||||||
@ -187,13 +201,11 @@ public class TpmPcrEvent {
|
|||||||
*/
|
*/
|
||||||
protected void setEventContent(final byte[] eventData) {
|
protected void setEventContent(final byte[] eventData) {
|
||||||
eventContent = new byte[eventData.length];
|
eventContent = new byte[eventData.length];
|
||||||
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.
|
* Gets the event Content Data (not the entire event structure).
|
||||||
* event log format.
|
|
||||||
*
|
|
||||||
* @return byte array holding the events content field
|
* @return byte array holding the events content field
|
||||||
*/
|
*/
|
||||||
public byte[] getEventContent() {
|
public byte[] getEventContent() {
|
||||||
@ -223,23 +235,26 @@ public class TpmPcrEvent {
|
|||||||
* Parses the event content and creates a human readable description of each event.
|
* Parses the event content and creates a human readable description of each event.
|
||||||
* @param event the byte array holding the event data.
|
* @param event the byte array holding the event data.
|
||||||
* @param eventContent the byte array holding the event content.
|
* @param eventContent the byte array holding the event content.
|
||||||
|
* @param eventNumber event position within the event log.
|
||||||
* @return String description of the event.
|
* @return String description of the event.
|
||||||
* @throws CertificateException if the event contains an event that cannot be processed.
|
* @throws CertificateException if the event contains an event that cannot be processed.
|
||||||
* @throws NoSuchAlgorithmException if an event contains an unsupported algorithm.
|
* @throws NoSuchAlgorithmException if an event contains an unsupported algorithm.
|
||||||
* @throws IOException if the event cannot be parsed.
|
* @throws IOException if the event cannot be parsed.
|
||||||
*/
|
*/
|
||||||
public String processEvent(final byte[] event, final byte[] eventContent)
|
public String processEvent(final byte[] event, final byte[] eventContent, final int eventNumber)
|
||||||
throws CertificateException, NoSuchAlgorithmException, IOException {
|
throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||||
String description = "";
|
|
||||||
int eventID = (int) eventType;
|
int eventID = (int) eventType;
|
||||||
description += "Event# " + eventNumber++ + ": ";
|
description += "Event# " + eventNumber + ": ";
|
||||||
description += "Index PCR[" + this.index + "]\n";
|
description += "Index PCR[" + getPcrIndex() + "]\n";
|
||||||
description += "Event Type: 0x" + this.eventType + " " + eventString(eventID);
|
description += "Event Type: 0x" + Long.toHexString(eventType) + " " + eventString(eventID);
|
||||||
description += "\n";
|
description += "\n";
|
||||||
if (logFormat == 1) { // Digest
|
if (logFormat == 1) { // Digest
|
||||||
description += "digest (SHA-1): " + HexUtils.byteArrayToHexString(this.digest) + "\n";
|
description += "digest (SHA-1): " + HexUtils.byteArrayToHexString(this.digest);
|
||||||
} else {
|
} 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
|
// Calculate both the SHA1 and SHA256 on the event since this will equal the digest
|
||||||
// field of about half the log messages.
|
// field of about half the log messages.
|
||||||
@ -256,7 +271,7 @@ public class TpmPcrEvent {
|
|||||||
break;
|
break;
|
||||||
case EvConstants.EV_POST_CODE:
|
case EvConstants.EV_POST_CODE:
|
||||||
EvPostCode postCode = new EvPostCode(eventContent);
|
EvPostCode postCode = new EvPostCode(eventContent);
|
||||||
description += "Event Content:\n" + postCode.toString() + "\n";
|
description += "Event Content:\n" + postCode.toString();
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_UNUSED:
|
case EvConstants.EV_UNUSED:
|
||||||
break;
|
break;
|
||||||
@ -273,45 +288,39 @@ public class TpmPcrEvent {
|
|||||||
if (EvPostCode.isAscii(eventContent)) {
|
if (EvPostCode.isAscii(eventContent)) {
|
||||||
String seperatorEventData = new String(eventContent, StandardCharsets.UTF_8);
|
String seperatorEventData = new String(eventContent, StandardCharsets.UTF_8);
|
||||||
if (!this.isEmpty(eventContent)) {
|
if (!this.isEmpty(eventContent)) {
|
||||||
description += "Seperator event content = " + seperatorEventData + "\n";
|
description += "Seperator event content = " + seperatorEventData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
description += eventHashCheck();
|
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_ACTION:
|
case EvConstants.EV_ACTION:
|
||||||
description += "Event Content:\n"
|
description += "Event Content:\n"
|
||||||
+ new String(eventContent, StandardCharsets.UTF_8) + "\n";
|
+ new String(eventContent, StandardCharsets.UTF_8);
|
||||||
description += eventHashCheck();
|
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_EVENT_TAG:
|
case EvConstants.EV_EVENT_TAG:
|
||||||
EvEventTag eventTag = new EvEventTag(eventContent);
|
EvEventTag eventTag = new EvEventTag(eventContent);
|
||||||
description += eventTag.toString() + "\n";
|
description += eventTag.toString();
|
||||||
description += eventHashCheck();
|
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_S_CRTM_CONTENTS:
|
case EvConstants.EV_S_CRTM_CONTENTS:
|
||||||
EvSCrtmContents sCrtmContents = new EvSCrtmContents(eventContent);
|
EvSCrtmContents sCrtmContents = new EvSCrtmContents(eventContent);
|
||||||
description += "Event Content:\n " + sCrtmContents.toString() + "\n";
|
description += "Event Content:\n " + sCrtmContents.toString();
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_S_CRTM_VERSION:
|
case EvConstants.EV_S_CRTM_VERSION:
|
||||||
EvSCrtmVersion sCrtmVersion = new EvSCrtmVersion(eventContent);
|
EvSCrtmVersion sCrtmVersion = new EvSCrtmVersion(eventContent);
|
||||||
description += "Event Content:\n" + sCrtmVersion.toString() + "\n";
|
description += "Event Content:\n" + sCrtmVersion.toString();
|
||||||
description += eventHashCheck();
|
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_CPU_MICROCODE:
|
case EvConstants.EV_CPU_MICROCODE:
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_PLATFORM_CONFIG_FLAGS:
|
case EvConstants.EV_PLATFORM_CONFIG_FLAGS:
|
||||||
description += eventHashCheck();
|
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_TABLE_OF_DEVICES:
|
case EvConstants.EV_TABLE_OF_DEVICES:
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_COMPACT_HASH:
|
case EvConstants.EV_COMPACT_HASH:
|
||||||
EvCompactHash compactHash = new EvCompactHash(eventContent);
|
EvCompactHash compactHash = new EvCompactHash(eventContent);
|
||||||
description += "Event Content:\n" + compactHash.toString() + "\n";
|
description += "Event Content:\n" + compactHash.toString();
|
||||||
description += eventHashCheck();
|
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_IPL:
|
case EvConstants.EV_IPL:
|
||||||
EvIPL ipl = new EvIPL(eventContent);
|
EvIPL ipl = new EvIPL(eventContent);
|
||||||
description += "Event Content:\n" + ipl.toString() + "\n";
|
description += "Event Content:\n" + ipl.toString();
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_IPL_PARTITION_DATA:
|
case EvConstants.EV_IPL_PARTITION_DATA:
|
||||||
break;
|
break;
|
||||||
@ -327,12 +336,12 @@ public class TpmPcrEvent {
|
|||||||
break;
|
break;
|
||||||
case EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG:
|
case EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG:
|
||||||
UefiVariable efiVar = new UefiVariable(eventContent);
|
UefiVariable efiVar = new UefiVariable(eventContent);
|
||||||
description += "Event Content:\n" + efiVar.toString();
|
String efiVarDescription = efiVar.toString().replace("\n", "\n ");
|
||||||
description += eventHashCheck();
|
description += "Event Content:\n " + efiVarDescription.substring(0,
|
||||||
|
efiVarDescription.length() - INDENT_3);
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_EFI_VARIABLE_BOOT:
|
case EvConstants.EV_EFI_VARIABLE_BOOT:
|
||||||
description += "Event Content:\n" + new UefiVariable(eventContent).toString();
|
description += "Event Content:\n" + new UefiVariable(eventContent).toString();
|
||||||
description += eventHashCheck();
|
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION:
|
case EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION:
|
||||||
EvEfiBootServicesApp bootServices = new EvEfiBootServicesApp(eventContent);
|
EvEfiBootServicesApp bootServices = new EvEfiBootServicesApp(eventContent);
|
||||||
@ -346,15 +355,13 @@ public class TpmPcrEvent {
|
|||||||
break;
|
break;
|
||||||
case EvConstants.EV_EFI_GPT_EVENT:
|
case EvConstants.EV_EFI_GPT_EVENT:
|
||||||
description += "Event Content:\n" + new EvEfiGptPartition(eventContent).toString();
|
description += "Event Content:\n" + new EvEfiGptPartition(eventContent).toString();
|
||||||
description += eventHashCheck();
|
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_EFI_ACTION:
|
case EvConstants.EV_EFI_ACTION:
|
||||||
description += new String(eventContent, StandardCharsets.UTF_8) + "\n";
|
description += new String(eventContent, StandardCharsets.UTF_8);
|
||||||
description += eventHashCheck();
|
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB:
|
case EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB:
|
||||||
description += "Event Content:\n"
|
description += "Event Content:\n"
|
||||||
+ new UefiFirmware(eventContent).toString() + "\n";
|
+ new UefiFirmware(eventContent).toString();
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_EFI_HANDOFF_TABLES:
|
case EvConstants.EV_EFI_HANDOFF_TABLES:
|
||||||
EvEfiHandoffTable efiTable = new EvEfiHandoffTable(eventContent);
|
EvEfiHandoffTable efiTable = new EvEfiHandoffTable(eventContent);
|
||||||
@ -367,11 +374,6 @@ public class TpmPcrEvent {
|
|||||||
break;
|
break;
|
||||||
default: description += " Unknown Event found" + "\n";
|
default: description += " Unknown Event found" + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bEvContent) {
|
|
||||||
description += "Event content (Hex) (" + event.length + "): "
|
|
||||||
+ HexUtils.byteArrayToHexString(eventContent) + "\n\n";
|
|
||||||
}
|
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,62 +384,73 @@ public class TpmPcrEvent {
|
|||||||
* @return TCG defined String that represents the event id
|
* @return TCG defined String that represents the event id
|
||||||
*/
|
*/
|
||||||
private static String eventString(final long event) {
|
private static String eventString(final long event) {
|
||||||
String evString = "";
|
|
||||||
long tmpEvent = event;
|
if (event == EvConstants.EV_PREBOOT_CERT) {
|
||||||
Long longEvent = Long.valueOf(tmpEvent & SIGN_MASK); // Remove signed extension
|
return "EV_PREBOOT_CERT";
|
||||||
Long intEvent = Long.valueOf(tmpEvent & INT_MASK); // truncate to an int value
|
} else if (event == EvConstants.EV_POST_CODE) {
|
||||||
// Check to see if value is larger than an int, if it is then truncate the value
|
return "EV_POST_CODE";
|
||||||
if (longEvent.longValue() > (long) Integer.MAX_VALUE) {
|
} else if (event == EvConstants.EV_UNUSED) {
|
||||||
switch (intEvent.intValue()) {
|
return "EV_Unused";
|
||||||
case EvConstants.EV_EFI_EVENT_BASE: evString = "EV_EFI_EVENT_BASE"; break;
|
} else if (event == EvConstants.EV_NO_ACTION) {
|
||||||
case EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG:
|
return "EV_NO_ACTION";
|
||||||
evString = "EV_EFI_VARIABLE_DRIVER_CONFIG"; break;
|
} else if (event == EvConstants.EV_SEPARATOR) {
|
||||||
case EvConstants.EV_EFI_VARIABLE_BOOT:
|
return "EV_SEPARATOR";
|
||||||
evString = "EV_EFI_VARIABLE_BOOT"; break;
|
} else if (event == EvConstants.EV_ACTION) {
|
||||||
case EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION:
|
return "EV_ACTION";
|
||||||
evString = "EV_EFI_BOOT_SERVICES_APPLICATION"; break;
|
} else if (event == EvConstants.EV_EVENT_TAG) {
|
||||||
case EvConstants.EV_EFI_BOOT_SERVICES_DRIVER:
|
return "EV_EVENT_TAG";
|
||||||
evString = "EV_EFI_BOOT_SERVICES_DRIVER"; break;
|
} else if (event == EvConstants.EV_S_CRTM_CONTENTS) {
|
||||||
case EvConstants.EV_EFI_RUNTIME_SERVICES_DRIVER:
|
return "EV_S_CRTM_CONTENTS";
|
||||||
evString = "EV_EFI_RUNTIME_SERVICES_DRIVER"; break;
|
} else if (event == EvConstants.EV_S_CRTM_VERSION) {
|
||||||
case EvConstants.EV_EFI_GPT_EVENT: evString = "EV_EFI_GPT_EVENT"; break;
|
return "EV_S_CRTM_VERSION";
|
||||||
case EvConstants.EV_EFI_ACTION: evString = "EV_EFI_ACTION"; break;
|
} else if (event == EvConstants.EV_CPU_MICROCODE) {
|
||||||
case EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB:
|
return "EV_CPU_MICROCODE";
|
||||||
evString = "EV_EFI_PLATFORM_FIRMWARE_BLOB"; break;
|
} else if (event == EvConstants.EV_PLATFORM_CONFIG_FLAGS) {
|
||||||
case EvConstants.EV_EFI_HANDOFF_TABLES: evString = "EV_EFI_HANDOFF_TABLES"; break;
|
return "EV_PLATFORM_CONFIG_FLAGS ";
|
||||||
case EvConstants.EV_EFI_HCRTM_EVENT: evString = "EV_EFI_HCRTM_EVENT"; break;
|
} else if (event == EvConstants.EV_TABLE_OF_DEVICES) {
|
||||||
case EvConstants.EV_EFI_VARIABLE_AUTHORITY:
|
return "EV_TABLE_OF_DEVICES";
|
||||||
evString = "EV_EFI_VARIABLE_AUTHORITY"; break;
|
} else if (event == EvConstants.EV_COMPACT_HASH) {
|
||||||
default: evString = "Unknown Event ID " + event + " encountered";
|
return "EV_COMPACT_HASH";
|
||||||
}
|
} else if (event == EvConstants.EV_IPL) {
|
||||||
} else {
|
return "EV_IPL";
|
||||||
switch (intEvent.intValue()) {
|
} else if (event == EvConstants.EV_IPL_PARTITION_DATA) {
|
||||||
case EvConstants.EV_PREBOOT_CERT: evString = "EV_PREBOOT_CERT"; break;
|
return "EV_IPL_PARTITION_DATA";
|
||||||
case EvConstants.EV_POST_CODE: evString = "EV_POST_CODE"; break;
|
} else if (event == EvConstants.EV_NONHOST_CODE) {
|
||||||
case EvConstants.EV_UNUSED: evString = "EV_Unused"; break;
|
return "EV_NONHOST_CODE";
|
||||||
case EvConstants.EV_NO_ACTION: evString = "EV_NO_ACTION"; break;
|
} else if (event == EvConstants.EV_NONHOST_CONFIG) {
|
||||||
case EvConstants.EV_SEPARATOR: evString = "EV_SEPARATOR"; break;
|
return "EV_NONHOST_CONFIG";
|
||||||
case EvConstants.EV_ACTION: evString = "EV_ACTION"; break;
|
} else if (event == EvConstants.EV_NONHOST_INFO) {
|
||||||
case EvConstants.EV_EVENT_TAG: evString = "EV_EVENT_TAG"; break;
|
return "EV_NONHOST_INFO";
|
||||||
case EvConstants.EV_S_CRTM_CONTENTS: evString = "EV_S_CRTM_CONTENTS"; break;
|
} else if (event == EvConstants.EV_EV_OMIT_BOOT_DEVICES_EVENTS) {
|
||||||
case EvConstants.EV_S_CRTM_VERSION: evString = "EV_S_CRTM_VERSION"; break;
|
return "EV_EV_OMIT_BOOT_DEVICES_EVENTS";
|
||||||
case EvConstants.EV_CPU_MICROCODE: evString = "EV_CPU_MICROCODE"; break;
|
} else if (event == EvConstants.EV_EFI_EVENT_BASE) {
|
||||||
case EvConstants.EV_PLATFORM_CONFIG_FLAGS: evString = "EV_PLATFORM_CONFIG_FLAGS ";
|
return "EV_EFI_EVENT_BASE";
|
||||||
break;
|
} else if (event == EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG) {
|
||||||
case EvConstants.EV_TABLE_OF_DEVICES: evString = "EV_TABLE_OF_DEVICES"; break;
|
return "EV_EFI_VARIABLE_DRIVER_CONFIG";
|
||||||
case EvConstants.EV_COMPACT_HASH: evString = "EV_COMPACT_HASH"; break;
|
} else if (event == EvConstants.EV_EFI_VARIABLE_BOOT) {
|
||||||
case EvConstants.EV_IPL: evString = "EV_IPL"; break;
|
return "EV_EFI_VARIABLE_BOOT";
|
||||||
case EvConstants.EV_IPL_PARTITION_DATA: evString = "EV_IPL_PARTITION_DATA"; break;
|
} else if (event == EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION) {
|
||||||
case EvConstants.EV_NONHOST_CODE: evString = "EV_NONHOST_CODE"; break;
|
return "EV_EFI_BOOT_SERVICES_APPLICATION";
|
||||||
case EvConstants.EV_NONHOST_CONFIG: evString = "EV_NONHOST_CONFIG"; break;
|
} else if (event == EvConstants.EV_EFI_BOOT_SERVICES_DRIVER) {
|
||||||
case EvConstants.EV_NONHOST_INFO: evString = "EV_NONHOST_INFO"; break;
|
return "EV_EFI_BOOT_SERVICES_DRIVER";
|
||||||
case EvConstants.EV_EV_OMIT_BOOT_DEVICES_EVENTS:
|
} else if (event == EvConstants.EV_EFI_RUNTIME_SERVICES_DRIVER) {
|
||||||
evString = "EV_EV_OMIT_BOOT_DEVICES_EVENTS"; break;
|
return "EV_EFI_RUNTIME_SERVICES_DRIVER";
|
||||||
default: evString = "Unknown Event ID " + event + " encountered";
|
} else if (event == EvConstants.EV_EFI_GPT_EVENT) {
|
||||||
}
|
return "EV_EFI_GPT_EVENT";
|
||||||
}
|
} else if (event == EvConstants.EV_EFI_ACTION) {
|
||||||
return evString;
|
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.
|
* Human readable output of a check of input against the current event hash.
|
||||||
@ -476,4 +489,43 @@ public class TpmPcrEvent {
|
|||||||
}
|
}
|
||||||
return true;
|
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";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,12 +32,13 @@ public class TpmPcrEvent1 extends TpmPcrEvent {
|
|||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param is ByteArrayInputStream holding the TCG Log event.
|
* @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 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.
|
* @throws CertificateException If a certificate within an event can't be processed.
|
||||||
*/
|
*/
|
||||||
public TpmPcrEvent1(final ByteArrayInputStream is) throws IOException, CertificateException,
|
public TpmPcrEvent1(final ByteArrayInputStream is, final int eventNumber)
|
||||||
NoSuchAlgorithmException {
|
throws IOException, CertificateException, NoSuchAlgorithmException {
|
||||||
super(is);
|
super(is);
|
||||||
setDigestLength(EvConstants.SHA1_LENGTH);
|
setDigestLength(EvConstants.SHA1_LENGTH);
|
||||||
setLogFormat(1);
|
setLogFormat(1);
|
||||||
@ -75,8 +76,9 @@ public class TpmPcrEvent1 extends TpmPcrEvent {
|
|||||||
offset += eventDigest.length;
|
offset += eventDigest.length;
|
||||||
System.arraycopy(rawEventSize, 0, event, offset, rawEventSize.length);
|
System.arraycopy(rawEventSize, 0, event, offset, rawEventSize.length);
|
||||||
offset += rawEventSize.length;
|
offset += rawEventSize.length;
|
||||||
|
setEventData(event);
|
||||||
//System.arraycopy(eventContent, 0, event, offset, eventContent.length);
|
//System.arraycopy(eventContent, 0, event, offset, eventContent.length);
|
||||||
this.processEvent(event, eventContent);
|
this.processEvent(event, eventContent, eventNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,12 +67,13 @@ public class TpmPcrEvent2 extends TpmPcrEvent {
|
|||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param is ByteArrayInputStream holding the TCG Log event
|
* @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 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.
|
* @throws CertificateException If a certificate within an event can't be processed.
|
||||||
*/
|
*/
|
||||||
public TpmPcrEvent2(final ByteArrayInputStream is) throws IOException, CertificateException,
|
public TpmPcrEvent2(final ByteArrayInputStream is, final int eventNumber)
|
||||||
NoSuchAlgorithmException {
|
throws IOException, CertificateException, NoSuchAlgorithmException {
|
||||||
super(is);
|
super(is);
|
||||||
setDigestLength(EvConstants.SHA256_LENGTH);
|
setDigestLength(EvConstants.SHA256_LENGTH);
|
||||||
setLogFormat(2);
|
setLogFormat(2);
|
||||||
@ -124,7 +125,8 @@ public class TpmPcrEvent2 extends TpmPcrEvent {
|
|||||||
System.arraycopy(rawEventSize, 0, event, offset, rawEventSize.length);
|
System.arraycopy(rawEventSize, 0, event, offset, rawEventSize.length);
|
||||||
offset += rawEventSize.length;
|
offset += rawEventSize.length;
|
||||||
//System.arraycopy(eventContent, 0, event, offset, eventContent.length);
|
//System.arraycopy(eventContent, 0, event, offset, eventContent.length);
|
||||||
this.processEvent(event, eventContent);
|
setEventData(event);
|
||||||
|
this.processEvent(event, eventContent, eventNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,11 +122,11 @@ public class EvEfiBootServicesApp {
|
|||||||
info += " Image physical address: " + HexUtils.byteArrayToHexString(physicalAddress);
|
info += " Image physical address: " + HexUtils.byteArrayToHexString(physicalAddress);
|
||||||
info += " Image length = " + imageLength;
|
info += " Image length = " + imageLength;
|
||||||
info += " Image link time address: " + HexUtils.byteArrayToHexString(physicalAddress);
|
info += " Image link time address: " + HexUtils.byteArrayToHexString(physicalAddress);
|
||||||
info += " Device path length = " + devicePathLength + "\n";
|
info += " Device path length = " + devicePathLength;
|
||||||
if (devicePathValid) {
|
if (devicePathValid) {
|
||||||
info += devPath.toString();
|
info += "\n" + devPath.toString();
|
||||||
} else {
|
} else {
|
||||||
info += " Error processing device path" + "\n";
|
info += "\n Error processing device path" + "\n";
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,10 @@ public class EvEfiGptPartition {
|
|||||||
partitionInfo.append("GPT Header Signature = " + headerStr + " : Number of Paritions = "
|
partitionInfo.append("GPT Header Signature = " + headerStr + " : Number of Paritions = "
|
||||||
+ numberOfPartitions + "\n");
|
+ numberOfPartitions + "\n");
|
||||||
for (int i = 0; i < numberOfPartitions; i++) {
|
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());
|
partitionInfo.append(partitionList.get(i).toString());
|
||||||
}
|
}
|
||||||
return partitionInfo.toString();
|
return partitionInfo.toString();
|
||||||
|
@ -101,7 +101,7 @@ public class EvEfiHandoffTable {
|
|||||||
tableInfo.append(" UEFI industry standard table type = "
|
tableInfo.append(" UEFI industry standard table type = "
|
||||||
+ currentGuid.getVendorTableReference() + "\n");
|
+ currentGuid.getVendorTableReference() + "\n");
|
||||||
tableInfo.append(" VendorTable " + i + " address: "
|
tableInfo.append(" VendorTable " + i + " address: "
|
||||||
+ HexUtils.byteArrayToHexString(vendorTables.get(i)) + "\n");
|
+ HexUtils.byteArrayToHexString(vendorTables.get(i)));
|
||||||
}
|
}
|
||||||
return tableInfo.toString();
|
return tableInfo.toString();
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ public class EvEfiSpecIdEvent {
|
|||||||
String specInfo = "";
|
String specInfo = "";
|
||||||
if (signature == "Spec ID Event#") {
|
if (signature == "Spec ID Event#") {
|
||||||
specInfo += "Platform Profile Specification version = " + vMaj + "." + vMin
|
specInfo += "Platform Profile Specification version = " + vMaj + "." + vMin
|
||||||
+ " using errata version" + errata + "\n";
|
+ " using errata version" + errata;
|
||||||
} else {
|
} else {
|
||||||
specInfo = "EV_NO_ACTION event named " + signature
|
specInfo = "EV_NO_ACTION event named " + signature
|
||||||
+ " ecncountered but support for processing it has not been added to this application";
|
+ " ecncountered but support for processing it has not been added to this application";
|
||||||
|
@ -66,13 +66,13 @@ public class EvNoAction {
|
|||||||
if (bSpecIDEvent) {
|
if (bSpecIDEvent) {
|
||||||
specInfo += " Signature = Spec ID Event03 : ";
|
specInfo += " Signature = Spec ID Event03 : ";
|
||||||
if (specIDEvent.isCryptoAgile()) {
|
if (specIDEvent.isCryptoAgile()) {
|
||||||
specInfo += "Log format is Crypto Agile \n";
|
specInfo += "Log format is Crypto Agile\n";
|
||||||
} else {
|
} 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 = "
|
specInfo += " Platform Profile Specification version = "
|
||||||
+ specIDEvent.getVersionMajor() + "." + specIDEvent.getVersionMinor()
|
+ specIDEvent.getVersionMajor() + "." + specIDEvent.getVersionMinor()
|
||||||
+ " using errata version " + specIDEvent.getErrata() + "\n";
|
+ " using errata version " + specIDEvent.getErrata();
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
specInfo = "EV_NO_ACTION event named " + signature
|
specInfo = "EV_NO_ACTION event named " + signature
|
||||||
+ " encountered but support for processing it has not been added to this application.\n";
|
+ " encountered but support for processing it has not been added to this application.\n";
|
||||||
|
@ -31,6 +31,7 @@ public String toString() {
|
|||||||
for (int i = 0; i < bootOrder.length; i++) {
|
for (int i = 0; i < bootOrder.length; i++) {
|
||||||
orderList.append(String.format("Boot %04d", (int) bootOrder[i]));
|
orderList.append(String.format("Boot %04d", (int) bootOrder[i]));
|
||||||
}
|
}
|
||||||
|
//orderList.append("\n");
|
||||||
return orderList.toString();
|
return orderList.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,8 @@ public final class UefiConstants {
|
|||||||
public static final int OFFSET_3 = 3;
|
public static final int OFFSET_3 = 3;
|
||||||
/** 4 byte offset. */
|
/** 4 byte offset. */
|
||||||
public static final int OFFSET_4 = 4;
|
public static final int OFFSET_4 = 4;
|
||||||
|
/** 5 byte offset. */
|
||||||
|
public static final int OFFSET_5 = 5;
|
||||||
/** 6 byte offset. */
|
/** 6 byte offset. */
|
||||||
public static final int OFFSET_6 = 4;
|
public static final int OFFSET_6 = 4;
|
||||||
/** 8 byte offset. */
|
/** 8 byte offset. */
|
||||||
@ -89,6 +91,8 @@ public final class UefiConstants {
|
|||||||
public static final int DEV_MEDIA = 0x04;
|
public static final int DEV_MEDIA = 0x04;
|
||||||
/** Device Type Hardware. */
|
/** Device Type Hardware. */
|
||||||
public static final int DEV_BIOS = 0x05;
|
public static final int DEV_BIOS = 0x05;
|
||||||
|
/** Device Sub-Type USV. */
|
||||||
|
public static final int DEV_SUB_USB = 0x05;
|
||||||
/** Device Sub-Type Sata. */
|
/** Device Sub-Type Sata. */
|
||||||
public static final int DEV_SUB_SATA = 0x12;
|
public static final int DEV_SUB_SATA = 0x12;
|
||||||
/** Device Sub-Type nvm. */
|
/** Device Sub-Type nvm. */
|
||||||
|
@ -84,26 +84,24 @@ public class UefiDevicePath {
|
|||||||
*/
|
*/
|
||||||
private String processDevPath(final byte[] path) throws UnsupportedEncodingException {
|
private String processDevPath(final byte[] path) throws UnsupportedEncodingException {
|
||||||
StringBuilder pInfo = new StringBuilder();
|
StringBuilder pInfo = new StringBuilder();
|
||||||
String devicePathInfo = "";
|
int devLength = 0, pathOffset = 0, devCount = 0;
|
||||||
int devLength = 0, pathOffset = 0;
|
|
||||||
while (true) {
|
while (true) {
|
||||||
Byte devPath = Byte.valueOf(path[pathOffset]);
|
Byte devPath = Byte.valueOf(path[pathOffset]);
|
||||||
if ((devPath.intValue() == UefiConstants.TERMINATOR)
|
if ((devPath.intValue() == UefiConstants.TERMINATOR)
|
||||||
|| (devPath.intValue() == UefiConstants.END_FLAG)) {
|
|| (devPath.intValue() == UefiConstants.END_FLAG)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
devicePathInfo = processDev(path, pathOffset);
|
if (devCount++ > 0) {
|
||||||
if (devicePathInfo.contains("Unknown Device Path")) {
|
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;
|
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();
|
return pInfo.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +118,7 @@ public class UefiDevicePath {
|
|||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
String devInfo = " ";
|
String devInfo = " ";
|
||||||
int devPath = path[offset];
|
int devPath = path[offset];
|
||||||
|
byte unknownSubType = path[offset + UefiConstants.OFFSET_1];
|
||||||
switch (path[0 + offset]) {
|
switch (path[0 + offset]) {
|
||||||
case UefiConstants.DEV_HW: type = "Hardware Device Path";
|
case UefiConstants.DEV_HW: type = "Hardware Device Path";
|
||||||
if (devPath == UefiConstants.DEVPATH_HARWARE) {
|
if (devPath == UefiConstants.DEVPATH_HARWARE) {
|
||||||
@ -132,9 +131,12 @@ public class UefiDevicePath {
|
|||||||
case UefiConstants.DEV_MSG: type = "Messaging Device Path";
|
case UefiConstants.DEV_MSG: type = "Messaging Device Path";
|
||||||
if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEV_SUB_SATA) {
|
if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEV_SUB_SATA) {
|
||||||
devInfo += type + ": " + sataSubType(path, offset);
|
devInfo += type + ": " + sataSubType(path, offset);
|
||||||
}
|
} else if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEV_SUB_NVM) {
|
||||||
if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEV_SUB_NVM) {
|
|
||||||
devInfo += type + ": " + nvmSubType(path, offset);
|
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;
|
break;
|
||||||
case UefiConstants.DEV_MEDIA: type = "Media Device Path";
|
case UefiConstants.DEV_MEDIA: type = "Media Device Path";
|
||||||
@ -148,6 +150,8 @@ public class UefiDevicePath {
|
|||||||
devInfo += type + ": " + piwgFirmVolFile(path, offset);
|
devInfo += type + ": " + piwgFirmVolFile(path, offset);
|
||||||
} else if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEVPATH_PWIG_VOL) {
|
} else if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEVPATH_PWIG_VOL) {
|
||||||
devInfo += type + ": " + piwgFirmVolPath(path, offset);
|
devInfo += type + ": " + piwgFirmVolPath(path, offset);
|
||||||
|
} else {
|
||||||
|
devInfo += "UEFI Media Device Path Type " + Integer.valueOf(unknownSubType);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UefiConstants.DEV_BIOS: type = "BIOS Device Path";
|
case UefiConstants.DEV_BIOS: type = "BIOS Device Path";
|
||||||
@ -155,11 +159,10 @@ public class UefiDevicePath {
|
|||||||
break;
|
break;
|
||||||
case UefiConstants.TERMINATOR: devInfo += "End of Hardware Device Path";
|
case UefiConstants.TERMINATOR: devInfo += "End of Hardware Device Path";
|
||||||
break;
|
break;
|
||||||
default: type = "Unknown Device Path";
|
default:
|
||||||
devInfo = type;
|
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);
|
subType += HexUtils.byteArrayToHexString(partnumber);
|
||||||
byte[] data = new byte[UefiConstants.SIZE_8];
|
byte[] data = new byte[UefiConstants.SIZE_8];
|
||||||
System.arraycopy(path, UefiConstants.OFFSET_8 + offset, data, 0, 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);
|
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];
|
byte[] signature = new byte[UefiConstants.SIZE_16];
|
||||||
System.arraycopy(path, UefiConstants.OFFSET_24 + offset, signature, 0, 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) {
|
if (path[UefiConstants.OFFSET_41 + offset] == UefiConstants.DRIVE_SIG_NONE) {
|
||||||
subType += "None";
|
subType += "None";
|
||||||
} else if (path[UefiConstants.OFFSET_41 + offset] == UefiConstants.DRIVE_SIG_32BIT) {
|
} 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 {
|
} else {
|
||||||
subType += "invalid partition signature type";
|
subType += "invalid partition signature type";
|
||||||
}
|
}
|
||||||
subType += "Partition Format = ";
|
subType += " Partition Format = ";
|
||||||
if (path[UefiConstants.OFFSET_40 + offset] == UefiConstants.DRIVE_TYPE_PC_AT) {
|
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) {
|
} else if (path[UefiConstants.OFFSET_40 + offset] == UefiConstants.DRIVE_TYPE_GPT) {
|
||||||
subType += "GUID Partition Table";
|
subType += " GUID Partition Table";
|
||||||
} else {
|
} else {
|
||||||
subType += "Invalid partition table type";
|
subType += " Invalid partition table type";
|
||||||
}
|
}
|
||||||
return subType;
|
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.
|
* UEFI Specification, Version 2.8.
|
||||||
* Name space Identifier (NSID) and IEEE Extended Unique Identifier (EUI-64):
|
* Name space Identifier (NSID) and IEEE Extended Unique Identifier (EUI-64):
|
||||||
* See Links to UEFI Related Documents
|
* See Links to UEFI Related Documents
|
||||||
|
@ -63,7 +63,7 @@ public int getBlobLength() {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
String blobInfo = "";
|
String blobInfo = "";
|
||||||
if (!berror) {
|
if (!berror) {
|
||||||
blobInfo += " Platform Firwmare Blob Address = " + blobAddress;
|
blobInfo += " Platform Firwmare Blob Address = " + Integer.toHexString(blobAddress);
|
||||||
blobInfo += " length = " + blobLength;
|
blobInfo += " length = " + blobLength;
|
||||||
} else {
|
} else {
|
||||||
blobInfo += " Invalid Firmware Blob event encountered";
|
blobInfo += " Invalid Firmware Blob event encountered";
|
||||||
|
@ -91,7 +91,7 @@ public String toString() {
|
|||||||
partitionInfo += " Partition Name : " + partitionName + "\n";
|
partitionInfo += " Partition Name : " + partitionName + "\n";
|
||||||
partitionInfo += " Partition Type GUID : " + partitionTypeGUID.toString() + "\n";
|
partitionInfo += " Partition Type GUID : " + partitionTypeGUID.toString() + "\n";
|
||||||
partitionInfo += " Unique Partition GUID : " + uniquePartitionGUID.toStringNoLookup() + "\n";
|
partitionInfo += " Unique Partition GUID : " + uniquePartitionGUID.toStringNoLookup() + "\n";
|
||||||
partitionInfo += " Attributes : " + attributes + "\n";
|
partitionInfo += " Attributes : " + attributes;
|
||||||
return partitionInfo;
|
return partitionInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,11 +43,11 @@ public int getSecurBootVariable() {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
if (!berror) {
|
if (!berror) {
|
||||||
if (secureBootVar == 1) {
|
if (secureBootVar == 1) {
|
||||||
info += " Secure Boot is enabled \n";
|
info += " Secure Boot is enabled ";
|
||||||
} else if (secureBootVar == 0) {
|
} else if (secureBootVar == 0) {
|
||||||
info += " Secure Boot is NOT enabled \n";
|
info += " Secure Boot is NOT enabled ";
|
||||||
} else {
|
} else {
|
||||||
info += " Unkown State: Secure Variable is undefined \n";
|
info += " Unkown State: Secure Variable is undefined ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
|
@ -175,7 +175,7 @@ public String toString() {
|
|||||||
} else {
|
} else {
|
||||||
if (signatureType.getVendorTableReference().equals("EFI_CERT_SHA256_GUID")) {
|
if (signatureType.getVendorTableReference().equals("EFI_CERT_SHA256_GUID")) {
|
||||||
sigInfo += "UEFI Signature Owner = " + efiGuid.toString() + "\n";
|
sigInfo += "UEFI Signature Owner = " + efiGuid.toString() + "\n";
|
||||||
sigInfo += "Binary Hash = " + HexUtils.byteArrayToHexString(binaryHash) + "\n";
|
sigInfo += " Binary Hash = " + HexUtils.byteArrayToHexString(binaryHash) + "\n";
|
||||||
} else {
|
} else {
|
||||||
sigInfo += "UEFI Signature Owner = " + efiGuid.toString() + "\n";
|
sigInfo += "UEFI Signature Owner = " + efiGuid.toString() + "\n";
|
||||||
sigInfo += cert.toString();
|
sigInfo += cert.toString();
|
||||||
|
@ -136,11 +136,15 @@ private void processSigList(final byte[] data)
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder efiVariable = new StringBuilder();
|
StringBuilder efiVariable = new StringBuilder();
|
||||||
efiVariable.append("UEFI Variable Name:" + varName + "\n");
|
efiVariable.append("UEFI Variable Name:" + varName + "\n");
|
||||||
efiVariable.append("UEFI_GUID = " + getEfiVarGuid().toString() + "\n");
|
efiVariable.append("UEFI_GUID = " + getEfiVarGuid().toString() + "\n ");
|
||||||
efiVariable.append("UEFI Variable Contents => " + "\n");
|
if (varName != "") {
|
||||||
|
efiVariable.append("UEFI Variable Contents => " + "\n ");
|
||||||
|
}
|
||||||
String tmpName = varName;
|
String tmpName = varName;
|
||||||
if (varName.contains("Boot00")) {
|
if (varName.contains("Boot00")) {
|
||||||
tmpName = "Boot00";
|
tmpName = "Boot00";
|
||||||
|
} else {
|
||||||
|
tmpName = varName;
|
||||||
}
|
}
|
||||||
switch (tmpName) {
|
switch (tmpName) {
|
||||||
case "Shim": efiVariable.append(printCert(uefiVaribelData, 0)); break;
|
case "Shim": efiVariable.append(printCert(uefiVaribelData, 0)); break;
|
||||||
@ -149,6 +153,11 @@ public String toString() {
|
|||||||
case "BootOrder": efiVariable.append(booto.toString()); break;
|
case "BootOrder": efiVariable.append(booto.toString()); break;
|
||||||
case "SecureBoot": efiVariable.append(sb.toString()); break;
|
case "SecureBoot": efiVariable.append(sb.toString()); break;
|
||||||
default:
|
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++) {
|
for (int i = 0; i < certSuperList.size(); i++) {
|
||||||
efiVariable.append(certSuperList.get(i).toString());
|
efiVariable.append(certSuperList.get(i).toString());
|
||||||
@ -173,7 +182,7 @@ public String printCert(final byte[] data, final int offset) {
|
|||||||
UefiX509Cert cert = new UefiX509Cert(certData);
|
UefiX509Cert cert = new UefiX509Cert(certData);
|
||||||
certInfo = cert.toString();
|
certInfo = cert.toString();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
certInfo = "Error Processing Certificate : " + e.getMessage() + "\n";
|
certInfo = "Error Processing Certificate : " + e.getMessage();
|
||||||
}
|
}
|
||||||
return (certInfo);
|
return (certInfo);
|
||||||
}
|
}
|
||||||
|
@ -74,14 +74,14 @@ public String getSHA1FingerPrint() {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
X509Certificate x509Cert = (X509Certificate) cert;
|
X509Certificate x509Cert = (X509Certificate) cert;
|
||||||
String certData = "";
|
String certData = "";
|
||||||
certData += "Certificate Serial Number = "
|
certData += " Certificate Serial Number = "
|
||||||
+ x509Cert.getSerialNumber().toString(UefiConstants.SIZE_16) + "\n";
|
+ x509Cert.getSerialNumber().toString(UefiConstants.SIZE_16) + "\n";
|
||||||
certData += "Subject DN = " + x509Cert.getSubjectDN() + "\n";
|
certData += " Subject DN = " + x509Cert.getSubjectDN() + "\n";
|
||||||
certData += "Issuer DN = " + x509Cert.getIssuerDN() + "\n";
|
certData += " Issuer DN = " + x509Cert.getIssuerDN() + "\n";
|
||||||
certData += "Not Before Date = " + x509Cert.getNotBefore() + "\n";
|
certData += " Not Before Date = " + x509Cert.getNotBefore() + "\n";
|
||||||
certData += "Not After Date = " + x509Cert.getNotAfter() + "\n";
|
certData += " Not After Date = " + x509Cert.getNotAfter() + "\n";
|
||||||
certData += "Signature Algorithm = " + x509Cert.getSigAlgName() + "\n";
|
certData += " Signature Algorithm = " + x509Cert.getSigAlgName() + "\n";
|
||||||
certData += "SHA1 Fingerprint = " + getSHA1FingerPrint() + "\n";
|
certData += " SHA1 Fingerprint = " + getSHA1FingerPrint() + "\n";
|
||||||
return certData;
|
return certData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,14 +28,14 @@ import org.testng.annotations.Test;
|
|||||||
/**
|
/**
|
||||||
* Class for testing TCG Event Log processing.
|
* Class for testing TCG Event Log processing.
|
||||||
*/
|
*/
|
||||||
//public class TCGEventLogProcessorTest extends SpringPersistenceTest {
|
//public class TCGEventLogTest extends SpringPersistenceTest {
|
||||||
public class TCGEventLogProcessorTest {
|
public class TCGEventLogTest {
|
||||||
private static final String DEFAULT_EVENT_LOG = "/tcgeventlog/TpmLog.bin";
|
private static final String DEFAULT_EVENT_LOG = "/tcgeventlog/TpmLog.bin";
|
||||||
private static final String DEFAULT_EXPECTED_PCRS = "/tcgeventlog/TpmLogExpectedPcrs.txt";
|
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_EVENT_LOG = "/tcgeventlog/TpmLogSHA1.bin";
|
||||||
private static final String SHA1_EXPECTED_PCRS = "/tcgeventlog/TpmLogSHA1ExpectedPcrs.txt";
|
private static final String SHA1_EXPECTED_PCRS = "/tcgeventlog/TpmLogSHA1ExpectedPcrs.txt";
|
||||||
private static final Logger LOGGER
|
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
|
* Initializes a <code>SessionFactory</code>. The factory is used for an in-memory database that
|
||||||
@ -89,8 +89,8 @@ public class TCGEventLogProcessorTest {
|
|||||||
boolean testPass = true;
|
boolean testPass = true;
|
||||||
log = this.getClass().getResourceAsStream(DEFAULT_EVENT_LOG);
|
log = this.getClass().getResourceAsStream(DEFAULT_EVENT_LOG);
|
||||||
byte[] rawLogBytes = IOUtils.toByteArray(log);
|
byte[] rawLogBytes = IOUtils.toByteArray(log);
|
||||||
TCGEventLogProcessor tlp = new TCGEventLogProcessor(rawLogBytes);
|
TCGEventLog evlog = new TCGEventLog(rawLogBytes, false, false, false);
|
||||||
String[] pcrFromLog = tlp.getExpectedPCRValues();
|
String[] pcrFromLog = evlog.getExpectedPCRValues();
|
||||||
pcrs = this.getClass().getResourceAsStream(DEFAULT_EXPECTED_PCRS);
|
pcrs = this.getClass().getResourceAsStream(DEFAULT_EXPECTED_PCRS);
|
||||||
Object[] pcrObj = IOUtils.readLines(pcrs).toArray();
|
Object[] pcrObj = IOUtils.readLines(pcrs).toArray();
|
||||||
String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class);
|
String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class);
|
||||||
@ -103,12 +103,12 @@ public class TCGEventLogProcessorTest {
|
|||||||
}
|
}
|
||||||
Assert.assertTrue(testPass);
|
Assert.assertTrue(testPass);
|
||||||
// Test 2 get an individual PCR
|
// Test 2 get an individual PCR
|
||||||
String pcr3 = tlp.getExpectedPCRValue(3);
|
String pcr3 = evlog.getExpectedPCRValue(3);
|
||||||
Assert.assertEquals(pcr3, pcrFromLog[3]);
|
Assert.assertEquals(pcr3, pcrFromLog[3]);
|
||||||
// Test 3 check the Algorithm Identifiers used in the log
|
// Test 3 check the Algorithm Identifiers used in the log
|
||||||
String algStr = tlp.getEventLogHashAlgorithm();
|
String algStr = evlog.getEventLogHashAlgorithm();
|
||||||
Assert.assertEquals(algStr, "TPM_ALG_SHA256");
|
Assert.assertEquals(algStr, "TPM_ALG_SHA256");
|
||||||
int id = tlp.getEventLogHashAlgorithmID();
|
int id = evlog.getEventLogHashAlgorithmID();
|
||||||
Assert.assertEquals(id, TcgTpmtHa.TPM_ALG_SHA256);
|
Assert.assertEquals(id, TcgTpmtHa.TPM_ALG_SHA256);
|
||||||
LOGGER.debug("OK. Parsing of a Crypto Agile Format Success");
|
LOGGER.debug("OK. Parsing of a Crypto Agile Format Success");
|
||||||
}
|
}
|
||||||
@ -127,8 +127,8 @@ public class TCGEventLogProcessorTest {
|
|||||||
boolean testPass = true;
|
boolean testPass = true;
|
||||||
log = this.getClass().getResourceAsStream(SHA1_EVENT_LOG);
|
log = this.getClass().getResourceAsStream(SHA1_EVENT_LOG);
|
||||||
byte[] rawLogBytes = IOUtils.toByteArray(log);
|
byte[] rawLogBytes = IOUtils.toByteArray(log);
|
||||||
TCGEventLogProcessor tlp = new TCGEventLogProcessor(rawLogBytes);
|
TCGEventLog evlog = new TCGEventLog(rawLogBytes, false, false, false);
|
||||||
String[] pcrFromLog = tlp.getExpectedPCRValues();
|
String[] pcrFromLog = evlog.getExpectedPCRValues();
|
||||||
pcrs = this.getClass().getResourceAsStream(SHA1_EXPECTED_PCRS);
|
pcrs = this.getClass().getResourceAsStream(SHA1_EXPECTED_PCRS);
|
||||||
Object[] pcrObj = IOUtils.readLines(pcrs).toArray();
|
Object[] pcrObj = IOUtils.readLines(pcrs).toArray();
|
||||||
String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class);
|
String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class);
|
||||||
@ -141,12 +141,12 @@ public class TCGEventLogProcessorTest {
|
|||||||
}
|
}
|
||||||
Assert.assertTrue(testPass);
|
Assert.assertTrue(testPass);
|
||||||
// Test 2 get an individual PCR
|
// Test 2 get an individual PCR
|
||||||
String pcr0 = tlp.getExpectedPCRValue(0);
|
String pcr0 = evlog.getExpectedPCRValue(0);
|
||||||
Assert.assertEquals(pcr0, pcrFromLog[0]);
|
Assert.assertEquals(pcr0, pcrFromLog[0]);
|
||||||
// Test 3 check the Algorithm Identifiers used in the log
|
// Test 3 check the Algorithm Identifiers used in the log
|
||||||
String algStr = tlp.getEventLogHashAlgorithm();
|
String algStr = evlog.getEventLogHashAlgorithm();
|
||||||
Assert.assertEquals(algStr, "TPM_ALG_SHA1");
|
Assert.assertEquals(algStr, "TPM_ALG_SHA1");
|
||||||
int id = tlp.getEventLogHashAlgorithmID();
|
int id = evlog.getEventLogHashAlgorithmID();
|
||||||
Assert.assertEquals(id, TcgTpmtHa.TPM_ALG_SHA1);
|
Assert.assertEquals(id, TcgTpmtHa.TPM_ALG_SHA1);
|
||||||
LOGGER.debug("OK. Parsing of a SHA1 formatted TCG Event Log Success");
|
LOGGER.debug("OK. Parsing of a SHA1 formatted TCG Event Log Success");
|
||||||
}
|
}
|
@ -13,7 +13,7 @@ import org.testng.annotations.AfterClass;
|
|||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import hirs.tpm.eventlog.TCGEventLogProcessorTest;
|
import hirs.tpm.eventlog.TCGEventLogTest;
|
||||||
import hirs.utils.HexUtils;
|
import hirs.utils.HexUtils;
|
||||||
import hirs.tpm.eventlog.uefi.UefiGuid;
|
import hirs.tpm.eventlog.uefi.UefiGuid;
|
||||||
import hirs.tpm.eventlog.uefi.UefiPartition;
|
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 EVENT_HANDOFF_TABLES = "/tcgeventlog/events/EvHandoffTables.txt";
|
||||||
private static final String UEFI_POST_CODE = "/tcgeventlog/events/EvPostCode.txt";
|
private static final String UEFI_POST_CODE = "/tcgeventlog/events/EvPostCode.txt";
|
||||||
private static final Logger LOGGER
|
private static final Logger LOGGER
|
||||||
= LogManager.getLogger(TCGEventLogProcessorTest.class);
|
= LogManager.getLogger(TCGEventLogTest.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a <code>SessionFactory</code>.
|
* Initializes a <code>SessionFactory</code>.
|
||||||
|
1
tools/tcglp/VERSION
Normal file
1
tools/tcglp/VERSION
Normal file
@ -0,0 +1 @@
|
|||||||
|
1.0
|
157
tools/tcglp/build.gradle
Normal file
157
tools/tcglp/build.gradle
Normal 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',
|
||||||
|
]
|
||||||
|
}
|
BIN
tools/tcglp/gradle/wrapper/gradle-4.5.1-all.zip
vendored
Normal file
BIN
tools/tcglp/gradle/wrapper/gradle-4.5.1-all.zip
vendored
Normal file
Binary file not shown.
BIN
tools/tcglp/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
tools/tcglp/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
tools/tcglp/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
tools/tcglp/gradle/wrapper/gradle-wrapper.properties
vendored
Normal 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
160
tools/tcglp/gradlew
vendored
Executable 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 "$@"
|
389
tools/tcglp/src/main/java/hirs/tcg_eventlog_tool/Commander.java
Normal file
389
tools/tcglp/src/main/java/hirs/tcg_eventlog_tool/Commander.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
277
tools/tcglp/src/main/java/hirs/tcg_eventlog_tool/Main.java
Normal file
277
tools/tcglp/src/main/java/hirs/tcg_eventlog_tool/Main.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user