mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-18 20:47:58 +00:00
Added support for obtaining event and content data. Removed TCGLogProcessor.
This commit is contained in:
parent
a7d57f92d9
commit
f24c53f6c6
@ -3,7 +3,7 @@ package hirs.attestationca.portal.page.controllers;
|
||||
import hirs.data.persist.ReferenceManifest;
|
||||
import hirs.data.persist.SwidResource;
|
||||
import hirs.persist.ReferenceManifestManager;
|
||||
import hirs.tpm.eventlog.TCGEventLogProcessor;
|
||||
import hirs.tpm.eventlog.TCGEventLog;
|
||||
import hirs.attestationca.portal.page.Page;
|
||||
import hirs.attestationca.portal.page.PageController;
|
||||
import hirs.attestationca.portal.page.PageMessages;
|
||||
@ -157,7 +157,7 @@ public class ReferenceManifestDetailsPageController
|
||||
data.put("rimType", rim.getRimType());
|
||||
List<SwidResource> resources = rim.parseResource();
|
||||
String resourceFilename = null;
|
||||
TCGEventLogProcessor logProcessor = new TCGEventLogProcessor();
|
||||
TCGEventLog logProcessor = new TCGEventLog();
|
||||
|
||||
try {
|
||||
for (SwidResource swidRes : resources) {
|
||||
@ -166,7 +166,7 @@ public class ReferenceManifestDetailsPageController
|
||||
SwidResource.RESOURCE_UPLOAD_FOLDER,
|
||||
resourceFilename));
|
||||
if (Files.exists(logPath)) {
|
||||
logProcessor = new TCGEventLogProcessor(
|
||||
logProcessor = new TCGEventLog(
|
||||
Files.readAllBytes(logPath));
|
||||
swidRes.setPcrValues(Arrays.asList(
|
||||
logProcessor.getExpectedPCRValues()));
|
||||
|
@ -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.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import 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.uefi.UefiConstants;
|
||||
import hirs.utils.HexUtils;
|
||||
|
||||
/**
|
||||
@ -15,7 +23,12 @@ import hirs.utils.HexUtils;
|
||||
public final class TCGEventLog {
|
||||
|
||||
// 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.*/
|
||||
public static final String INIT_SHA256_LIST = "00000000000000000000000000"
|
||||
+ "00000000000000000000000000000000000000";
|
||||
@ -39,7 +52,12 @@ public final class TCGEventLog {
|
||||
private String hashType;
|
||||
/** Initial Value to use. */
|
||||
private String initValue;
|
||||
|
||||
/** Content Output Flag use. */
|
||||
private boolean bContent = false;
|
||||
/** Event Output Flag use. */
|
||||
private boolean bHexEvent = false;
|
||||
/** Event Output Flag use. */
|
||||
private boolean bEvent = false;
|
||||
/**
|
||||
* Default blank object constructor.
|
||||
*/
|
||||
@ -47,47 +65,64 @@ public final class TCGEventLog {
|
||||
this.pcrList = new byte[PCR_COUNT][EvConstants.SHA1_LENGTH];
|
||||
initValue = INIT_SHA1_LIST;
|
||||
pcrLength = EvConstants.SHA1_LENGTH;
|
||||
hashType = HASH_STRING;
|
||||
algorithm = "TPM_ALG_SHA1";
|
||||
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.
|
||||
* @throws NoSuchAlgorithmException if an unknown algorithm is encountered.
|
||||
* @throws CertificateException if a certificate in the log cannot be parsed.
|
||||
* @throws IOException IO Stream if event cannot be parsed.
|
||||
*/
|
||||
public TCGEventLog(final byte[] rawlog) throws CertificateException, NoSuchAlgorithmException,
|
||||
IOException {
|
||||
this(rawlog, EvConstants.SHA1_LENGTH, HASH_STRING, INIT_SHA1_LIST);
|
||||
public TCGEventLog(final byte[] rawlog)
|
||||
throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||
this(rawlog, false, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor for specific log.
|
||||
* @param rawlog data for the event log file
|
||||
* @param pLength determined by SHA1 or 256
|
||||
* @param hType the type of algorithm
|
||||
* @param iValue the default blank value.
|
||||
* @throws IOException IO Stream for the event log
|
||||
* Default constructor for just the rawlog that'll set up SHA1 Log.
|
||||
* @param rawlog data for the event log file.
|
||||
* @param bEventFlag if true provides human readable event descriptions.
|
||||
* @param bContentFlag if true provides hex output for Content in the description.
|
||||
* @param bHexEventFlag if true provides hex event structure in the description.
|
||||
* @throws NoSuchAlgorithmException if an unknown algorithm is encountered.
|
||||
* @throws CertificateException 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,
|
||||
final String iValue) throws IOException, CertificateException,
|
||||
NoSuchAlgorithmException {
|
||||
pcrLength = pLength;
|
||||
public TCGEventLog(final byte[] rawlog, final boolean bEventFlag,
|
||||
final boolean bContentFlag, final boolean bHexEventFlag)
|
||||
throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||
|
||||
boolean bCryptoAgile = isLogCrytoAgile(rawlog);
|
||||
if (bCryptoAgile) {
|
||||
initValue = INIT_SHA256_LIST;
|
||||
algorithm = "TPM_ALG_SHA256";
|
||||
hashType = HASH256_STRING;
|
||||
pcrLength = EvConstants.SHA256_LENGTH;
|
||||
} else {
|
||||
initValue = INIT_SHA1_LIST;
|
||||
hashType = HASH_STRING;
|
||||
algorithm = "TPM_ALG_SHA1";
|
||||
pcrLength = EvConstants.SHA1_LENGTH;
|
||||
}
|
||||
this.pcrList = new byte[PCR_COUNT][pcrLength];
|
||||
hashType = hType;
|
||||
initValue = iValue;
|
||||
int eventNumber = 0;
|
||||
bContent = bContentFlag;
|
||||
bEvent = bEventFlag;
|
||||
bHexEvent = bHexEventFlag;
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(rawlog);
|
||||
// Process the 1st entry as a SHA1 format (per the spec)
|
||||
eventList.add(new TpmPcrEvent1(is));
|
||||
eventList.add(new TpmPcrEvent1(is, eventNumber++));
|
||||
// put all events into an event list for further processing
|
||||
|
||||
while (is.available() > 0) {
|
||||
if (hashType.compareToIgnoreCase(HASH_STRING) == 0) {
|
||||
eventList.add(new TpmPcrEvent1(is));
|
||||
if (bCryptoAgile) {
|
||||
eventList.add(new TpmPcrEvent2(is, eventNumber++));
|
||||
} else {
|
||||
eventList.add(new TpmPcrEvent2(is));
|
||||
eventList.add(new TpmPcrEvent1(is, eventNumber++));
|
||||
}
|
||||
}
|
||||
calculatePcrValues();
|
||||
@ -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.
|
||||
* Uses the algorithm and eventList passed into the constructor,
|
||||
@ -181,8 +244,63 @@ public final class TCGEventLog {
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (TpmPcrEvent event:eventList) {
|
||||
sb.append(event.toString() + "\n");
|
||||
}
|
||||
if (bEvent) {
|
||||
sb.append(event.toString());
|
||||
}
|
||||
if (bHexEvent) {
|
||||
byte[] eventData = event.getEvent();
|
||||
sb.append("Event (Hex no Content) (" + eventData.length + " bytes): "
|
||||
+ HexUtils.byteArrayToHexString(eventData) + "\n");
|
||||
}
|
||||
if (bContent) {
|
||||
byte[] eventContent = event.getEventContent();
|
||||
sb.append("Event content (Hex) (" + eventContent.length + " bytes): "
|
||||
+ HexUtils.byteArrayToHexString(eventContent) + "\n");
|
||||
}
|
||||
if (bEvent || bHexEvent || bContent) {
|
||||
sb.append("\n");
|
||||
}
|
||||
}
|
||||
sb.append("Event Log proessing 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,164 +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 java.util.ArrayList;
|
||||
|
||||
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 a list of event found in the Event Log.
|
||||
* @return an arraylist of event.
|
||||
*/
|
||||
public ArrayList<TpmPcrEvent> getEventList() {
|
||||
return tcgLog.getEventList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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");
|
||||
}
|
||||
|
||||
/**
|
||||
* Human readable string representing the contents of the Event Log.
|
||||
* @return Description of the log.
|
||||
*/
|
||||
public String toString() {
|
||||
return tcgLog.toString();
|
||||
}
|
||||
}
|
@ -51,6 +51,8 @@ public class TpmPcrEvent {
|
||||
private long eventType = 0;
|
||||
/** Event digest. */
|
||||
private byte[] digest = null;
|
||||
/** Even data (no content). */
|
||||
private byte[] event;
|
||||
/** Even content data. */
|
||||
private byte[] eventContent;
|
||||
/** TCG Event Log spec version. */
|
||||
@ -61,18 +63,12 @@ public class TpmPcrEvent {
|
||||
private String description = "";
|
||||
/** Length (in bytes) of a pcr. */
|
||||
private int digestLength = 0;
|
||||
/** Event Number. */
|
||||
private int eventNumber = 1;
|
||||
/** Event Contents flag. */
|
||||
private boolean bEvContent = false;
|
||||
/** Event hash for SHA1 event logs. */
|
||||
private byte[] eventDataSha1hash;
|
||||
/** Event hash for Crypto Agile events. */
|
||||
private byte[] eventDataSha256hash;
|
||||
/** Signature extension mask.*/
|
||||
private static final long SIGN_MASK = 0x00000000FFFFFFFFL;
|
||||
/** Mask used to remove upper values from a long. */
|
||||
private static final long INT_MASK = 0x000000007FFFFFFFL;
|
||||
/** Indent Offset. */
|
||||
private static final int INDENT_3 = 3;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -179,7 +175,24 @@ public class TpmPcrEvent {
|
||||
public String getSpecErrataVersion() {
|
||||
return errata;
|
||||
}
|
||||
/**
|
||||
* Sets the event data after processing.
|
||||
*
|
||||
* @param eventData The PFP defined event content
|
||||
*/
|
||||
protected void setEventData(final byte[] eventData) {
|
||||
event = new byte[eventData.length];
|
||||
System.arraycopy(eventData, 0, event, 0, eventData.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Event Data (no event content) for the event.
|
||||
* event log format.
|
||||
* @return byte array holding the event structure.
|
||||
*/
|
||||
public byte[] getEvent() {
|
||||
return java.util.Arrays.copyOf(event, event.length);
|
||||
}
|
||||
/**
|
||||
* Sets the event content after processing.
|
||||
*
|
||||
@ -191,9 +204,7 @@ public class TpmPcrEvent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of number of bytes in a PCR for the event.
|
||||
* event log format.
|
||||
*
|
||||
* Gets the event Content Data (not the entire event structure).
|
||||
* @return byte array holding the events content field
|
||||
*/
|
||||
public byte[] getEventContent() {
|
||||
@ -223,15 +234,16 @@ public class TpmPcrEvent {
|
||||
* Parses the event content and creates a human readable description of each event.
|
||||
* @param event the byte array holding the event data.
|
||||
* @param eventContent the byte array holding the event content.
|
||||
* @param eventNumber event position within the event log.
|
||||
* @return String description of the event.
|
||||
* @throws CertificateException if the event contains an event that cannot be processed.
|
||||
* @throws NoSuchAlgorithmException if an event contains an unsupported algorithm.
|
||||
* @throws IOException if the event cannot be parsed.
|
||||
*/
|
||||
public String processEvent(final byte[] event, final byte[] eventContent)
|
||||
public String processEvent(final byte[] event, final byte[] eventContent, final int eventNumber)
|
||||
throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||
int eventID = (int) eventType;
|
||||
description += "Event# " + eventNumber++ + ": ";
|
||||
description += "Event# " + eventNumber + ": ";
|
||||
description += "Index PCR[" + getPcrIndex() + "]\n";
|
||||
description += "Event Type: 0x" + Long.toHexString(eventType) + " " + eventString(eventID);
|
||||
description += "\n";
|
||||
@ -320,7 +332,9 @@ public class TpmPcrEvent {
|
||||
break;
|
||||
case EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG:
|
||||
UefiVariable efiVar = new UefiVariable(eventContent);
|
||||
description += "Event Content:\n" + efiVar.toString();
|
||||
String efiVarDescription = efiVar.toString().replace("\n", "\n ");
|
||||
description += "Event Content:\n " + efiVarDescription.substring(0,
|
||||
efiVarDescription.length() - INDENT_3);
|
||||
break;
|
||||
case EvConstants.EV_EFI_VARIABLE_BOOT:
|
||||
description += "Event Content:\n" + new UefiVariable(eventContent).toString();
|
||||
@ -356,11 +370,6 @@ public class TpmPcrEvent {
|
||||
break;
|
||||
default: description += " Unknown Event found" + "\n";
|
||||
}
|
||||
|
||||
if (bEvContent) {
|
||||
description += "Event content (Hex) (" + event.length + "): "
|
||||
+ HexUtils.byteArrayToHexString(eventContent) + "\n\n";
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
|
@ -32,12 +32,13 @@ public class TpmPcrEvent1 extends TpmPcrEvent {
|
||||
* Constructor.
|
||||
*
|
||||
* @param is ByteArrayInputStream holding the TCG Log event.
|
||||
* @param eventNumber event position within the event log.
|
||||
* @throws IOException if an error occurs in parsing the event.
|
||||
* @throws NoSuchAlgorithmException if an undefined algorithm is encountered.
|
||||
* @throws CertificateException If a certificate within an event can't be processed.
|
||||
*/
|
||||
public TpmPcrEvent1(final ByteArrayInputStream is) throws IOException, CertificateException,
|
||||
NoSuchAlgorithmException {
|
||||
public TpmPcrEvent1(final ByteArrayInputStream is, final int eventNumber)
|
||||
throws IOException, CertificateException, NoSuchAlgorithmException {
|
||||
super(is);
|
||||
setDigestLength(EvConstants.SHA1_LENGTH);
|
||||
setLogFormat(1);
|
||||
@ -75,8 +76,9 @@ public class TpmPcrEvent1 extends TpmPcrEvent {
|
||||
offset += eventDigest.length;
|
||||
System.arraycopy(rawEventSize, 0, event, offset, rawEventSize.length);
|
||||
offset += rawEventSize.length;
|
||||
setEventData(event);
|
||||
//System.arraycopy(eventContent, 0, event, offset, eventContent.length);
|
||||
this.processEvent(event, eventContent);
|
||||
this.processEvent(event, eventContent, eventNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,12 +67,13 @@ public class TpmPcrEvent2 extends TpmPcrEvent {
|
||||
* Constructor.
|
||||
*
|
||||
* @param is ByteArrayInputStream holding the TCG Log event
|
||||
* @param eventNumber event position within the event log.
|
||||
* @throws IOException if an error occurs in parsing the event
|
||||
* @throws NoSuchAlgorithmException if an undefined algorithm is encountered.
|
||||
* @throws NoSuchAlgorithmException if an undefined algorithm is encountered.
|
||||
* @throws CertificateException If a certificate within an event can't be processed.
|
||||
*/
|
||||
public TpmPcrEvent2(final ByteArrayInputStream is) throws IOException, CertificateException,
|
||||
NoSuchAlgorithmException {
|
||||
public TpmPcrEvent2(final ByteArrayInputStream is, final int eventNumber)
|
||||
throws IOException, CertificateException, NoSuchAlgorithmException {
|
||||
super(is);
|
||||
setDigestLength(EvConstants.SHA256_LENGTH);
|
||||
setLogFormat(2);
|
||||
@ -124,7 +125,8 @@ public class TpmPcrEvent2 extends TpmPcrEvent {
|
||||
System.arraycopy(rawEventSize, 0, event, offset, rawEventSize.length);
|
||||
offset += rawEventSize.length;
|
||||
//System.arraycopy(eventContent, 0, event, offset, eventContent.length);
|
||||
this.processEvent(event, eventContent);
|
||||
setEventData(event);
|
||||
this.processEvent(event, eventContent, eventNumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ public String toString() {
|
||||
for (int i = 0; i < bootOrder.length; i++) {
|
||||
orderList.append(String.format("Boot %04d", (int) bootOrder[i]));
|
||||
}
|
||||
orderList.append("\n");
|
||||
return orderList.toString();
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ public String toString() {
|
||||
} else {
|
||||
if (signatureType.getVendorTableReference().equals("EFI_CERT_SHA256_GUID")) {
|
||||
sigInfo += "UEFI Signature Owner = " + efiGuid.toString() + "\n";
|
||||
sigInfo += "Binary Hash = " + HexUtils.byteArrayToHexString(binaryHash) + "\n";
|
||||
sigInfo += " Binary Hash = " + HexUtils.byteArrayToHexString(binaryHash) + "\n";
|
||||
} else {
|
||||
sigInfo += "UEFI Signature Owner = " + efiGuid.toString() + "\n";
|
||||
sigInfo += cert.toString();
|
||||
|
@ -74,14 +74,14 @@ public String getSHA1FingerPrint() {
|
||||
public String toString() {
|
||||
X509Certificate x509Cert = (X509Certificate) cert;
|
||||
String certData = "";
|
||||
certData += "Certificate Serial Number = "
|
||||
certData += " Certificate Serial Number = "
|
||||
+ x509Cert.getSerialNumber().toString(UefiConstants.SIZE_16) + "\n";
|
||||
certData += "Subject DN = " + x509Cert.getSubjectDN() + "\n";
|
||||
certData += "Issuer DN = " + x509Cert.getIssuerDN() + "\n";
|
||||
certData += "Not Before Date = " + x509Cert.getNotBefore() + "\n";
|
||||
certData += "Not After Date = " + x509Cert.getNotAfter() + "\n";
|
||||
certData += "Signature Algorithm = " + x509Cert.getSigAlgName() + "\n";
|
||||
certData += "SHA1 Fingerprint = " + getSHA1FingerPrint() + "\n";
|
||||
certData += " Subject DN = " + x509Cert.getSubjectDN() + "\n";
|
||||
certData += " Issuer DN = " + x509Cert.getIssuerDN() + "\n";
|
||||
certData += " Not Before Date = " + x509Cert.getNotBefore() + "\n";
|
||||
certData += " Not After Date = " + x509Cert.getNotAfter() + "\n";
|
||||
certData += " Signature Algorithm = " + x509Cert.getSigAlgName() + "\n";
|
||||
certData += " SHA1 Fingerprint = " + getSHA1FingerPrint() + "\n";
|
||||
return certData;
|
||||
}
|
||||
}
|
||||
|
@ -28,14 +28,14 @@ import org.testng.annotations.Test;
|
||||
/**
|
||||
* Class for testing TCG Event Log processing.
|
||||
*/
|
||||
//public class TCGEventLogProcessorTest extends SpringPersistenceTest {
|
||||
public class TCGEventLogProcessorTest {
|
||||
private static final String DEFAULT_EVENT_LOG = "/tcgeventlog/TpmLog.bin";
|
||||
//public class TCGEventLogTest extends SpringPersistenceTest {
|
||||
public class TCGEventLogTest {
|
||||
private static final String DEFAULT_EVENT_LOG = "/tcgeventlog/TpmLog.bin";
|
||||
private static final String DEFAULT_EXPECTED_PCRS = "/tcgeventlog/TpmLogExpectedPcrs.txt";
|
||||
private static final String SHA1_EVENT_LOG = "/tcgeventlog/TpmLogSHA1.bin";
|
||||
private static final String SHA1_EXPECTED_PCRS = "/tcgeventlog/TpmLogSHA1ExpectedPcrs.txt";
|
||||
private static final Logger LOGGER
|
||||
= LogManager.getLogger(TCGEventLogProcessorTest.class);
|
||||
= LogManager.getLogger(TCGEventLogTest.class);
|
||||
|
||||
/**
|
||||
* Initializes a <code>SessionFactory</code>. The factory is used for an in-memory database that
|
||||
@ -89,8 +89,8 @@ public class TCGEventLogProcessorTest {
|
||||
boolean testPass = true;
|
||||
log = this.getClass().getResourceAsStream(DEFAULT_EVENT_LOG);
|
||||
byte[] rawLogBytes = IOUtils.toByteArray(log);
|
||||
TCGEventLogProcessor tlp = new TCGEventLogProcessor(rawLogBytes);
|
||||
String[] pcrFromLog = tlp.getExpectedPCRValues();
|
||||
TCGEventLog evlog = new TCGEventLog(rawLogBytes, false, false, false);
|
||||
String[] pcrFromLog = evlog.getExpectedPCRValues();
|
||||
pcrs = this.getClass().getResourceAsStream(DEFAULT_EXPECTED_PCRS);
|
||||
Object[] pcrObj = IOUtils.readLines(pcrs).toArray();
|
||||
String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class);
|
||||
@ -103,12 +103,12 @@ public class TCGEventLogProcessorTest {
|
||||
}
|
||||
Assert.assertTrue(testPass);
|
||||
// Test 2 get an individual PCR
|
||||
String pcr3 = tlp.getExpectedPCRValue(3);
|
||||
String pcr3 = evlog.getExpectedPCRValue(3);
|
||||
Assert.assertEquals(pcr3, pcrFromLog[3]);
|
||||
// Test 3 check the Algorithm Identifiers used in the log
|
||||
String algStr = tlp.getEventLogHashAlgorithm();
|
||||
String algStr = evlog.getEventLogHashAlgorithm();
|
||||
Assert.assertEquals(algStr, "TPM_ALG_SHA256");
|
||||
int id = tlp.getEventLogHashAlgorithmID();
|
||||
int id = evlog.getEventLogHashAlgorithmID();
|
||||
Assert.assertEquals(id, TcgTpmtHa.TPM_ALG_SHA256);
|
||||
LOGGER.debug("OK. Parsing of a Crypto Agile Format Success");
|
||||
}
|
||||
@ -127,8 +127,8 @@ public class TCGEventLogProcessorTest {
|
||||
boolean testPass = true;
|
||||
log = this.getClass().getResourceAsStream(SHA1_EVENT_LOG);
|
||||
byte[] rawLogBytes = IOUtils.toByteArray(log);
|
||||
TCGEventLogProcessor tlp = new TCGEventLogProcessor(rawLogBytes);
|
||||
String[] pcrFromLog = tlp.getExpectedPCRValues();
|
||||
TCGEventLog evlog = new TCGEventLog(rawLogBytes, false, false, false);
|
||||
String[] pcrFromLog = evlog.getExpectedPCRValues();
|
||||
pcrs = this.getClass().getResourceAsStream(SHA1_EXPECTED_PCRS);
|
||||
Object[] pcrObj = IOUtils.readLines(pcrs).toArray();
|
||||
String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class);
|
||||
@ -141,12 +141,12 @@ public class TCGEventLogProcessorTest {
|
||||
}
|
||||
Assert.assertTrue(testPass);
|
||||
// Test 2 get an individual PCR
|
||||
String pcr0 = tlp.getExpectedPCRValue(0);
|
||||
String pcr0 = evlog.getExpectedPCRValue(0);
|
||||
Assert.assertEquals(pcr0, pcrFromLog[0]);
|
||||
// Test 3 check the Algorithm Identifiers used in the log
|
||||
String algStr = tlp.getEventLogHashAlgorithm();
|
||||
String algStr = evlog.getEventLogHashAlgorithm();
|
||||
Assert.assertEquals(algStr, "TPM_ALG_SHA1");
|
||||
int id = tlp.getEventLogHashAlgorithmID();
|
||||
int id = evlog.getEventLogHashAlgorithmID();
|
||||
Assert.assertEquals(id, TcgTpmtHa.TPM_ALG_SHA1);
|
||||
LOGGER.debug("OK. Parsing of a SHA1 formatted TCG Event Log Success");
|
||||
}
|
@ -13,7 +13,7 @@ import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import hirs.tpm.eventlog.TCGEventLogProcessorTest;
|
||||
import hirs.tpm.eventlog.TCGEventLogTest;
|
||||
import hirs.utils.HexUtils;
|
||||
import hirs.tpm.eventlog.uefi.UefiGuid;
|
||||
import hirs.tpm.eventlog.uefi.UefiPartition;
|
||||
@ -31,7 +31,7 @@ public class TCGEventLogEventsTest {
|
||||
private static final String EVENT_HANDOFF_TABLES = "/tcgeventlog/events/EvHandoffTables.txt";
|
||||
private static final String UEFI_POST_CODE = "/tcgeventlog/events/EvPostCode.txt";
|
||||
private static final Logger LOGGER
|
||||
= LogManager.getLogger(TCGEventLogProcessorTest.class);
|
||||
= LogManager.getLogger(TCGEventLogTest.class);
|
||||
|
||||
/**
|
||||
* Initializes a <code>SessionFactory</code>.
|
||||
|
@ -229,10 +229,10 @@ public class Commander {
|
||||
+ " -e\t--eventids\t Filters the output to only display events using ID's provided.\n\t\t\t ID is single work mask of the event ID's. \n\t\t\t No EventID will output all events.\n"
|
||||
+ " -f\t--file\t\t Use specific input file. \n\t\t\t Following parameter MUST be a relative path and file name.\n"
|
||||
+ " -o\t--output\t Output to a file. \n\t\t\t Following parameter MUST be a relative path and file name.\n"
|
||||
+ " -t\t--tpmpcrs\t Output PCR contents calculated from the TCG Log. \n\t\t\t Following parameter MAY be a PCR number or Text PCR[] string.\n\t\t\t No following parameters will display ALl PCRs.\n"
|
||||
+ " -p\t--tpmpcrs\t Output PCR contents calculated from the TCG Log. \n\t\t\t Following parameter MAY be a PCR number or Text PCR[] string.\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.\n"
|
||||
+ " -x\t--hex\t\t Displays entire event log in hexdecimal.\n");
|
||||
+ " -x\t--hex\t\t Displays event structure of each log event in hexdecimal.\n");
|
||||
if (os.compareToIgnoreCase("linux")==0) {
|
||||
sb.append("\nIf no FILE parameter is provided then the standard Linux TCGEventLog path (/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"
|
||||
|
@ -6,15 +6,13 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
import hirs.tpm.eventlog.TCGEventLogProcessor;
|
||||
import hirs.tpm.eventlog.TCGEventLog;
|
||||
|
||||
/**
|
||||
* Command-line application for processing TCG Event Logs.
|
||||
* Input arg: path to *.tcglp file
|
||||
*
|
||||
*
|
||||
* If an argument is given it will be validated against the schema at http://standards.iso.org/iso/19770/-2/2015/schema.xsd
|
||||
* If an argument is not given a SWID tag file will be generated.
|
||||
*/
|
||||
@ -22,10 +20,11 @@ public class Main {
|
||||
private static Commander commander = null;
|
||||
static FileOutputStream outputStream = null;
|
||||
static byte[] eventLlog = null;
|
||||
static boolean bContentFlag, bEventFlag, bHexEvent, bOutFile = false;
|
||||
public static void main(String[] args) {
|
||||
commander = new Commander(args);
|
||||
String os = System.getProperty("os.name").toLowerCase();
|
||||
|
||||
|
||||
if (commander.hasArguments()) {
|
||||
// we have arguments to work with
|
||||
if (commander.getFileFlag()) {
|
||||
@ -39,35 +38,28 @@ public class Main {
|
||||
}
|
||||
if (commander.getPCRFlag()) {
|
||||
try {
|
||||
TCGEventLogProcessor tlp = new TCGEventLogProcessor(eventLlog);
|
||||
TCGEventLog tlp = new TCGEventLog(eventLlog, bEventFlag, bContentFlag, bHexEvent);
|
||||
String[] pcrs = tlp.getExpectedPCRValues();
|
||||
int i=0;
|
||||
System.out.print("Platform Configuration Register (PCR) values: \n");
|
||||
System.out.print("Platform Configuration Register (PCR) values: \n\n");
|
||||
for (String pcr: pcrs) {
|
||||
System.out.print("pcr "+ i++ + " = " + pcr.toString() + "\n");
|
||||
System.out.print(" pcr "+ i++ + " = " + pcr.toString() + "\n");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.print("Error processing Event Log " + commander.getInFileName()
|
||||
+ "\nError was "+ e.toString());
|
||||
System.exit(1);
|
||||
}
|
||||
System.out.print("\n----------------- End PCR Values ----------------- \n\n");
|
||||
}
|
||||
if (commander.getContentFlag()) {
|
||||
|
||||
bContentFlag = true;
|
||||
}
|
||||
if (commander.getHexFlag()) {
|
||||
|
||||
bHexEvent = true;
|
||||
}
|
||||
if (commander.getEventIdsFlag()) {
|
||||
try {
|
||||
TCGEventLogProcessor tlp = new TCGEventLogProcessor(eventLlog);
|
||||
writeOut(tlp.toString());
|
||||
} catch (Exception e) {
|
||||
System.out.print("Error processing Event Log " + commander.getInFileName()
|
||||
+ "\nError was "+ e.toString());
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
bEventFlag = true;
|
||||
}
|
||||
if (commander.getOutputFile()) {
|
||||
try {
|
||||
@ -87,8 +79,18 @@ public class Main {
|
||||
System.out.print("Nothing to do: No Parameters provided.");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
TCGEventLog tlp = new TCGEventLog(eventLlog, bEventFlag, bContentFlag, bHexEvent);
|
||||
writeOut(tlp.toString());
|
||||
} 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
|
||||
|
Loading…
Reference in New Issue
Block a user