diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java index e2ed2b60..ebd3e015 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java @@ -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 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())); diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/CryptoAgileEventLog.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/CryptoAgileEventLog.java deleted file mode 100644 index 360603f6..00000000 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/CryptoAgileEventLog.java +++ /dev/null @@ -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 { - -} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/SHA1EventLog.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/SHA1EventLog.java deleted file mode 100644 index 84d246d5..00000000 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/SHA1EventLog.java +++ /dev/null @@ -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 { - - -} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java index 051d0952..35a8c291 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java @@ -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"); + } } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLogProcessor.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLogProcessor.java deleted file mode 100644 index efc84477..00000000 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLogProcessor.java +++ /dev/null @@ -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 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(); - } -} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent.java index 26c4303e..a49e07f7 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent.java @@ -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; } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent1.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent1.java index 6a97e348..9db82b05 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent1.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent1.java @@ -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); } } } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent2.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent2.java index 6e692b15..deafad26 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent2.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent2.java @@ -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); } } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiBootOrder.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiBootOrder.java index 0d6e033c..056bfe0a 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiBootOrder.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiBootOrder.java @@ -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(); } } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiSignatureData.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiSignatureData.java index 4db7a1f5..894e65f5 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiSignatureData.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiSignatureData.java @@ -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(); diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiX509Cert.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiX509Cert.java index 61e556fe..5e71a206 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiX509Cert.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiX509Cert.java @@ -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; } } diff --git a/HIRS_Utils/src/test/java/hirs/tpm/eventlog/TCGEventLogProcessorTest.java b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/TCGEventLogTest.java similarity index 89% rename from HIRS_Utils/src/test/java/hirs/tpm/eventlog/TCGEventLogProcessorTest.java rename to HIRS_Utils/src/test/java/hirs/tpm/eventlog/TCGEventLogTest.java index cbbdbb56..558ac2e8 100644 --- a/HIRS_Utils/src/test/java/hirs/tpm/eventlog/TCGEventLogProcessorTest.java +++ b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/TCGEventLogTest.java @@ -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 SessionFactory. 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"); } diff --git a/HIRS_Utils/src/test/java/hirs/tpm/eventlog/events/TCGEventLogEventsTest.java b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/events/TCGEventLogEventsTest.java index 7e57d1dd..7410f5e2 100644 --- a/HIRS_Utils/src/test/java/hirs/tpm/eventlog/events/TCGEventLogEventsTest.java +++ b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/events/TCGEventLogEventsTest.java @@ -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 SessionFactory. diff --git a/tools/tcglp/src/main/java/hirs/tcglp/utils/Commander.java b/tools/tcglp/src/main/java/hirs/tcglp/utils/Commander.java index 07c34dbb..cd680f8a 100644 --- a/tools/tcglp/src/main/java/hirs/tcglp/utils/Commander.java +++ b/tools/tcglp/src/main/java/hirs/tcglp/utils/Commander.java @@ -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" diff --git a/tools/tcglp/src/main/java/hirs/tcglp/utils/Main.java b/tools/tcglp/src/main/java/hirs/tcglp/utils/Main.java index b3c7151c..d931e332 100644 --- a/tools/tcglp/src/main/java/hirs/tcglp/utils/Main.java +++ b/tools/tcglp/src/main/java/hirs/tcglp/utils/Main.java @@ -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