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 9a2a1d24..d9ba2dbd 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java @@ -58,6 +58,8 @@ public final class TCGEventLog { private boolean bHexEvent = false; /** Event Output Flag use. */ private boolean bEvent = false; + /** Event Output Flag use. */ + private boolean bCryptoAgile = false; /** * Default blank object constructor. */ @@ -96,7 +98,7 @@ public final class TCGEventLog { final boolean bContentFlag, final boolean bHexEventFlag) throws CertificateException, NoSuchAlgorithmException, IOException { - boolean bCryptoAgile = isLogCrytoAgile(rawlog); + bCryptoAgile = isLogCrytoAgile(rawlog); if (bCryptoAgile) { initValue = INIT_SHA256_LIST; algorithm = "TPM_ALG_SHA256"; @@ -219,7 +221,14 @@ public final class TCGEventLog { } return pcrs; } - + /** + * Returns a flag which is set if the event log follows the "Crypto Agile" Format Type. + * A false implies the type is SHA1 format. + * @return true if log follows the Crypto Agile format. + */ + public boolean isCryptoAgile() { + return bCryptoAgile; + } /** * Returns a list of event found in the Event Log. * @return an arraylist of event. diff --git a/settings.gradle b/settings.gradle index a996fc2d..4f9b7300 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,4 +7,5 @@ include 'TPM_Utils', 'HIRS_AttestationCA', 'HIRS_AttestationCAPortal', 'tpm_module', - 'tools/tcg_rim_tool' + 'tools/tcg_rim_tool', + 'tools/tcg_eventlog_tool' \ No newline at end of file diff --git a/tools/scripts/eventcheck.sh b/tools/scripts/eventcheck.sh new file mode 100644 index 00000000..ec301827 --- /dev/null +++ b/tools/scripts/eventcheck.sh @@ -0,0 +1,79 @@ +#!bin/bash + +# outline: +# 1. Run the tcg_rim_tool to check the validity of the rim using cmd line +# 2. Run the event_log_tool diff cmdline +# 3. Output results + +function eventcheck_help() { + echo "Event Check: Checks a TCG defined Event Log agianst a Integrity Reference Manifest for a Linux Device with a TPM 2.0" + echo "usage: eventcheck -r [file] - p [file] -s [file] -l [file]"; + echo "Options" + echo "-r --rim <path> : Reference Integrity Manifest (RIM) <path> Reference Integrity Manifest (RIM) Base RIM file holding OEM product information."; + echo "-p --publicCertificate <path> : Public key certificate path used to validate the rim file."; + echo "-s --supportRim <path> : PC Client defined support RIM file holding the reference data provided by the OEM of the product."; + echo "-l --log <path> : Event Log of the device being tested. Will default to latest event log if parameter is not supplied."; + echo "-h --help : help listing"; +} + + while [[ "$#" -gt 0 ]]; do + case $1 in + -p|--publicCertificate) oem_cert="$2"; shift ;; + -r|--rim) oem_rim=$2; shift ;; + -s|--supportRim) support_rim=$2; shift ;; + -l|--log) event_log=$2; shift ;; + -h|--help) eventcheck_help; exit 0 ;; + *) echo "Unknown parameter passed: $1"; eventcheck_help; exit 1 ;; + esac + shift +done +# Check for required parameters +if ${oem_rim+"false"}; then + echo "Error: Base RIM file needs to be specified using the -r parameter"; + echo "Exiting without processing."; + exit 1; +fi + +if ${support_rim+"false"}; then + echo "Error: Support RIM file needs to be specified using the -s parameter"; + echo "Exiting without processing."; + exit 1; +fi + +if ${oem_cert+"false"}; then + echo "Error: OEM Public Key Certificate Chain file needs to be specified using the -p parameter"; + echo "Exiting without processing."; + exit 1; +fi +# If event log not specified, then use the local devices log (if present) +if ${event_log+"false"}; then + ech0 "Event log not specified attempting to use local devices event log..."; + event_log="/sys/kernel/security/tpm0/binary_bios_measurements"; + if [ ! -f $event_log ]; then + kver=$(uname -r); + echo "Error opening default event log file, sudo may be required."; + echo " Note kernel version must be greater than 4.18 to produce an Event log. Current verion is $kver."; + echo "Exiting without processing."; + exit 1; + fi +fi + +echo "OEM Certificate Chain = $oem_cert"; +echo "Base RIM = $oem_rim"; +echo "Support RIM = $support_rim"; +echo "eventlog = $event_log"; + +echo "Checking the RIM signature and OEM Certificate Chain"; + +java -jar ../tcg_rim_tool/build/libs/tools/tcg_rim_tool-1.0.jar -v $oem_rim -p $oem_cert + +if [ $? -ne 0 ]; then + exit 1; +fi + +echo "Comparing RIM against the specified Event Log"; + +java -jar ../tcg_eventlog_tool/build/libs/tools/tcg_eventlog_tool-1.0.jar -d $support_rim $event_log + +echo " "; +echo "Event Check against RIM complete" diff --git a/tools/scripts/identity_transform.xslt b/tools/scripts/identity_transform.xslt new file mode 100644 index 00000000..c69ba714 --- /dev/null +++ b/tools/scripts/identity_transform.xslt @@ -0,0 +1,7 @@ +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + <xsl:template match="@*|node()"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> + </xsl:template> +</xsl:stylesheet> diff --git a/tools/tcglp/VERSION b/tools/tcg_eventlog_tool/VERSION similarity index 100% rename from tools/tcglp/VERSION rename to tools/tcg_eventlog_tool/VERSION diff --git a/tools/tcg_eventlog_tool/build.gradle b/tools/tcg_eventlog_tool/build.gradle new file mode 100644 index 00000000..e2812f0a --- /dev/null +++ b/tools/tcg_eventlog_tool/build.gradle @@ -0,0 +1,55 @@ +apply plugin: 'java' +apply plugin: 'findbugs' +apply plugin: 'checkstyle' + +version = '1.0' + +repositories { + mavenCentral() +} + +dependencies { + compile project(':HIRS_Utils') + compile libs.jcommander + + compileOnly libs.checkstyle + compileOnly libs.findbugs + + testCompile libs.testng +} + +ext.configDir = new File(projectDir, 'config') +ext.checkstyleConfigDir = "$configDir/checkstyle" +checkstyle { + toolVersion = '5.7' + configFile = checkstyleConfigFile + configProperties.put('basedir', checkstyleConfigDir) + ignoreFailures = false + showViolations = true +} + +ext.findbugsConfigDir = "$configDir/findbugs" + +findbugs { + toolVersion = '3.0.0' + ignoreFailures = false + effort = 'max' +} + +jar { + manifest { + attributes("Main-Class": "hirs.tcg_eventlog.Main", + "Class-Path": configurations.runtime.files.collect { "lib/$it.name" }.join(' ') + ) + } + from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {} + exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA' +} + +uploadArchives { + repositories { + flatDir { + dirs "${buildDir}" + } + } +} diff --git a/tools/tcg_eventlog_tool/config/checkstyle/suppressions.xml b/tools/tcg_eventlog_tool/config/checkstyle/suppressions.xml new file mode 100644 index 00000000..1e844d8c --- /dev/null +++ b/tools/tcg_eventlog_tool/config/checkstyle/suppressions.xml @@ -0,0 +1,12 @@ +<?xml version="1.0"?> + +<!DOCTYPE suppressions PUBLIC + "-//Puppy Crawl//DTD Suppressions 1.1//EN" + "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd"> + +<suppressions> + <suppress files="Main.java" checks="HideUtilityClassConstructor" /> + <suppress checks="MagicNumber" files=".*[/\\]src[/\\]test[/\\]+" /> + <suppress checks="FinalParameters" files=".*[/\\]src[/\\]test[/\\]+" /> + <suppress checks="JavadocPackage" files=".*[/\\]src[/\\]test[/\\]+" /> +</suppressions> diff --git a/tools/tcglp/gradle/wrapper/gradle-4.5.1-all.zip b/tools/tcg_eventlog_tool/gradle/wrapper/gradle-4.5.1-all.zip similarity index 100% rename from tools/tcglp/gradle/wrapper/gradle-4.5.1-all.zip rename to tools/tcg_eventlog_tool/gradle/wrapper/gradle-4.5.1-all.zip diff --git a/tools/tcglp/gradle/wrapper/gradle-wrapper.jar b/tools/tcg_eventlog_tool/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from tools/tcglp/gradle/wrapper/gradle-wrapper.jar rename to tools/tcg_eventlog_tool/gradle/wrapper/gradle-wrapper.jar diff --git a/tools/tcglp/gradle/wrapper/gradle-wrapper.properties b/tools/tcg_eventlog_tool/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from tools/tcglp/gradle/wrapper/gradle-wrapper.properties rename to tools/tcg_eventlog_tool/gradle/wrapper/gradle-wrapper.properties diff --git a/tools/tcglp/gradlew b/tools/tcg_eventlog_tool/gradlew similarity index 100% rename from tools/tcglp/gradlew rename to tools/tcg_eventlog_tool/gradlew diff --git a/tools/tcg_eventlog_tool/libs/HIRS_Utils-1.1.1.jar b/tools/tcg_eventlog_tool/libs/HIRS_Utils-1.1.1.jar new file mode 100644 index 00000000..930698d3 Binary files /dev/null and b/tools/tcg_eventlog_tool/libs/HIRS_Utils-1.1.1.jar differ diff --git a/tools/tcglp/src/main/java/hirs/tcg_eventlog_tool/Commander.java b/tools/tcg_eventlog_tool/src/main/java/hirs/tcg_eventlog/Commander.java similarity index 70% rename from tools/tcglp/src/main/java/hirs/tcg_eventlog_tool/Commander.java rename to tools/tcg_eventlog_tool/src/main/java/hirs/tcg_eventlog/Commander.java index 911784ef..e958416c 100644 --- a/tools/tcglp/src/main/java/hirs/tcg_eventlog_tool/Commander.java +++ b/tools/tcg_eventlog_tool/src/main/java/hirs/tcg_eventlog/Commander.java @@ -1,4 +1,4 @@ -package hirs.tcg_eventlog_tool; +package hirs.tcg_eventlog; import java.io.File; import java.io.IOException; @@ -12,7 +12,6 @@ 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"; @@ -27,7 +26,7 @@ public class Commander { private static final String VERSION_NUMBER = "1.0"; private boolean hasArguments = false; - private boolean bAll = false; + private boolean bValidArgs = true; private boolean bContentHex = false; private boolean bDiff = false; private boolean bEventIds = false; @@ -37,19 +36,20 @@ public class Commander { private boolean bOutput = false; private boolean bPCRs = false; private boolean bVerify = false; + private boolean bHelp = false; private String inFile = ""; private String inFile2 = ""; - private String outFile = ""; + private String outFile = ""; private String eventFilter = ""; private String pcrFilter = ""; private int pcrNumber = -1; private int eventNumber = -1; - + /** - * The main constructor for the Commander class + * The main constructor for the Commander class. * - * @param args + * @param args inout parameters */ public Commander(final String[] args) { hasArguments = args.length > 0; @@ -62,10 +62,10 @@ public class Commander { } /** - * This method is called if an empty Commander was created, and later gets - * args. Will be used by the main constructor. + * This method is called if an empty Commander was created, and later gets args. + * Will be used by the main constructor. * - * @param args + * @param args input parameters */ public final void parseArguments(final String[] args) { String tempValue; @@ -74,17 +74,13 @@ public class Commander { 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(); + if (i < args.length - 1) { // Check for a filter following the -e + if (!args[i + 1].startsWith("-")) { + eventFilter = args[i++ + 1]; + eventNumber = Integer.parseInt(eventFilter); } } bEventIds = true; @@ -95,20 +91,22 @@ public class Commander { case FULL_COMMAND_PREFIX + EVENTHEX_STRING: case COMMAND_PREFIX + "ex": bEventHex = true; - break; + 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"); + if ((args.length < i + 2 + 1) || (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); + bValidArgs = false; } 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(); + 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 = Integer.parseInt(eventFilter); } } bDiff = true; @@ -121,22 +119,22 @@ public class Commander { 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]; + if (i < args.length - 1) { // Check for a filter following the -o + if (!args[i + 1].startsWith("-")) { + outFile = args[i++ + 1]; } else { System.out.print("no output file specified with -o option"); - System.exit (1); + bValidArgs = false; } } 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(); + if (i < args.length - 1) { // Check for a filter following the -p + if (!args[i + 1].startsWith("-")) { + pcrFilter = args[i++ + 1 ]; + pcrNumber = Integer.parseInt(pcrFilter); } } bPCRs = true; @@ -144,8 +142,8 @@ public class Commander { case FULL_COMMAND_PREFIX + VERSION_STRING: case COMMAND_PREFIX + "v": System.out.print("TCG Event Log Parser version " + VERSION_NUMBER); - System.exit (0); - break; + bValidArgs = false; + break; case FULL_COMMAND_PREFIX + VERIFY_STRING: case COMMAND_PREFIX + "V": bVerify = true; @@ -153,18 +151,21 @@ public class Commander { case FULL_COMMAND_PREFIX + HEX_STRING: case COMMAND_PREFIX + "x": bHex = true; - break; + break; case FULL_COMMAND_PREFIX + HELP_STRING: + bHelp = true; + break; case COMMAND_PREFIX + "h": default: printHelp(""); + bValidArgs = false; } } } /** - * Getter for the property that indicates if something was given at the commandline. - * + * Getter for the property that indicates if something was given at the command line. + * * @return true if any arguments were passed in. */ public final boolean hasArguments() { @@ -175,10 +176,16 @@ public class Commander { * Getter for the input All flag. * @return true if the All flag was set. */ - public final boolean getAllFlag() { - return bAll; + public final boolean getValidityFlag() { + return bValidArgs; + } + /** + * Getter for the help flag. + * @return true if the Help flag was set. + */ + public final boolean getHelpFlag() { + return bHelp; } - /** * Getter for the input associated with the PCR flag. * @return true if the PCR Flag was set. @@ -212,7 +219,7 @@ public class Commander { /** * Getter for the input associated with the EventIds flag. - * @return true of EventIds Falg was set. + * @return true of EventIds Flag was set. */ public final boolean getEventIdsFlag() { return bEventIds; @@ -220,14 +227,14 @@ public class Commander { /** * Getter for the input associated with the File flag. - * @return true if File Flage was set. + * @return true if File Flag was set. */ public final boolean getFileFlag() { return bFile; } /** * Getter for the input associated with the diff flag. - * @return + * @return true if the diff flag was set */ public final boolean getDiffFlag() { return bDiff; @@ -235,7 +242,7 @@ public class Commander { /** * Getter for the input associated with the Verify flag. - * @return + * @return true if the verify flag was set */ public final boolean getVerifyFile() { return bVerify; @@ -297,17 +304,17 @@ public class Commander { return pcrNumber; } /** - * This method is used to inform the user of the allowed functionality of - * the program. + * This method is used to inform the user of the allowed functionality of the program. + * @param message message caller specific message to print before listing the help. */ - private void printHelp(String message) { + public final void printHelp(final 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)); + if ((message != null) && (!message.isEmpty())) { + sb.append("\n\n" + message); } sb.append("\nTCG Log Parser "); - if (os.compareToIgnoreCase("linux")==0) { + 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"); @@ -317,14 +324,16 @@ public class Commander { + "\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. " + + " -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" + + "\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" + + " 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. " @@ -334,53 +343,57 @@ public class Commander { + "\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." +// + " -V\t--Verify\t Attempts to verify the log file against values." + " -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) { + + "\n\t\t\t All output will be human readble form if 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" + + "\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 " + + "\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 " + + "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 " + + "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 + * Checks that the file path is a valid. + * @param filepath file path of file to check + * @return true if path is valid */ - public static boolean isValidPath(String filepath) { + public static boolean isValidPath(final String filepath) { try { System.out.println("Checking for a valid creation path..."); File file = new File(filepath); - file.createNewFile(); + boolean test = file.createNewFile(); + if (!test) { + return false; + } } catch (IOException | InvalidPathException | NullPointerException ex) { return false; } diff --git a/tools/tcg_eventlog_tool/src/main/java/hirs/tcg_eventlog/Main.java b/tools/tcg_eventlog_tool/src/main/java/hirs/tcg_eventlog/Main.java new file mode 100644 index 00000000..fd5bb6e1 --- /dev/null +++ b/tools/tcg_eventlog_tool/src/main/java/hirs/tcg_eventlog/Main.java @@ -0,0 +1,313 @@ +package hirs.tcg_eventlog; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.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 + */ +final class Main { + private static Commander commander = null; + private static FileOutputStream outputStream = null; + private static byte[] eventLog = null; + private static boolean bContentFlag, bEventFlag, bHexEvent, bHexFlag, bPcrFlag = false; + + /** + * Main Constructor. + * @param args command line parameters. + */ + public static void main(final String[] args) { + commander = new Commander(args); + if (!commander.getValidityFlag()) { + System.out.print("Program exiting wihtout processs due to issues with" + + " parameters provided."); + System.exit(1); + } + if (commander.hasArguments()) { + if (commander.getHelpFlag()) { + commander.printHelp(""); + System.exit(1); + } + if (commander.getOutputFlag()) { + try { + outputStream = new FileOutputStream(commander.getOutputFileName()); + } catch (FileNotFoundException e) { + System.out.print("Error opening output file" + commander.getOutputFileName() + + "\nError was " + e.getMessage()); + System.exit(1); + } + } + if (commander.getFileFlag()) { + eventLog = openLog(commander.getInFileName()); + } + if (commander.getContentFlag()) { + bContentFlag = true; + } + if (commander.getDiffFlag()) { + bEventFlag = true; + String results = compareLogs(commander.getInFileName(), + commander.getInFile2Name()); + writeOut(results); + System.exit(0); + } + if (commander.getEventIdsFlag()) { + bEventFlag = true; + } + if (commander.getEventHexFlag()) { + bHexEvent = true; + } + if (commander.getPCRFlag()) { + bPcrFlag = true; + } + if (commander.getVerifyFile()) { + System.out.print("Verify option is not yet implemented"); + System.exit(1); + } + if (commander.getHexFlag()) { + bHexFlag = true; + } + } else { + System.out.print("Nothing to do: No Parameters provided."); + System.exit(1); + } // End commander processing + + try { + if (eventLog == null) { + eventLog = openLog(""); + } + // Main Event processing + TCGEventLog evLog = new TCGEventLog(eventLog, bEventFlag, bContentFlag, bHexEvent); + if (bPcrFlag) { + String[] pcrs = evLog.getExpectedPCRValues(); + int count = 0; + if (!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) { + if (!bHexFlag) { + if (evLog.isCryptoAgile()) { + writeOut("\nEvent Log follows the \"Crypto Agile\" format and has " + + evLog.getEventList().size() + " events:\n\n"); + } else { + writeOut("\nEvent Log follows the \"SHA1\" format and has " + + evLog.getEventList().size() + " events:\n\n"); + } + } + 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 (IOException i) { + System.out.print("IO error processing Event Log " + commander.getInFileName() + + "\nError was " + i.toString()); + System.exit(1); + } catch (CertificateException c) { + System.out.print("Certificate error processing Event Log " + commander.getInFileName() + + "\nError was " + c.toString()); + System.exit(1); + } catch (NoSuchAlgorithmException a) { + System.out.print("Algorithm error processing Event Log " + commander.getInFileName() + + "\nError was " + a.toString()); + System.exit(1); + } +} + + /** + * Opens a TCG Event log file. + * @param fileName Name of the log file. Will use a OS specific default. + * @return a byte array holding the entire log + */ + public static byte[] openLog(final String fileName) { + String os = System.getProperty("os.name").toLowerCase(), fName = fileName; + byte[] rawLog = null; + boolean bDefault = false; + try { + + if (fileName.isEmpty()) { + if (os.compareToIgnoreCase("linux") == 0) { // need to find Windows path + fName = "/sys/kernel/security/tpm0/binary_bios_measurements"; + bDefault = true; + writeOut("Local Event Log being used: " + fileName + "\n"); + } + } + Path path = Paths.get(fName); + rawLog = Files.readAllBytes(path); + if (!commander.getHexFlag()) { + writeOut("tcg_eventlog_tool is opening file:" + path + "\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(final String data) { + try { + String dataNoNull = data.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters + if (commander.getOutputFlag()) { + outputStream.write(dataNoNull.getBytes(Charset.forName("UTF-8"))); + } else { + System.out.print(dataNoNull); // 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 reference. + * @return A sting containing human readable results. + */ + public static String compareLogs(final String logFileName1, final String logFileName2) { + TCGEventLog eventLog1 = null, eventLog2 = null; + byte[] evLog = openLog(logFileName1); + byte[] evLog2 = openLog(logFileName2); + StringBuilder sb = new StringBuilder(); + try { + eventLog1 = new TCGEventLog(evLog); + } catch (Exception e) { + sb.append("\nError processing event log " + logFileName1 + " : " + e.getMessage()); + return sb.toString(); + } + try { + eventLog2 = new TCGEventLog(evLog2); + ArrayList<TpmPcrEvent> errors = diffEventLogs(eventLog1.getEventList(), + eventLog2.getEventList(), commander.getPcrNumber()); + if (errors.isEmpty() && !bHexFlag) { + sb.append("\nEvent Log " + logFileName1 + " MATCHED EventLog " + logFileName2); + } else { + if (!errors.isEmpty() && !bHexFlag) { + sb.append("\nEvent Log " + logFileName1 + + " did NOT match EventLog " + logFileName2 + "\n"); + sb.append("There were " + errors.size() + " event mismatches: \n\n"); + } + for (TpmPcrEvent error : errors) { + if (bHexFlag) { + if (bEventFlag || bHexEvent) { + sb.append(HexUtils.byteArrayToHexString(error.getEvent()) + "\n"); + } + if (bContentFlag) { + sb.append(HexUtils.byteArrayToHexString(error.getEventContent()) + + "\n"); + } + } else { + sb.append(error.toString(bEventFlag, bContentFlag, bHexEvent) + "\n"); + } + } + } + } catch (IOException i) { + System.out.print("IO error processing Event Log " + commander.getInFileName() + + "\nError was " + i.toString()); + System.exit(1); + } catch (CertificateException c) { + System.out.print("Certificate error processing Event Log " + commander.getInFileName() + + "\nError was " + c.toString()); + System.exit(1); + } catch (NoSuchAlgorithmException a) { + System.out.print("Algorithm error processing Event Log " + commander.getInFileName() + + "\nError was " + a.toString()); + System.exit(1); + } + 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(final ArrayList<TpmPcrEvent> eventList, + final ArrayList<TpmPcrEvent> eventList2, final int pcr) { + ArrayList<TpmPcrEvent> results = new ArrayList<TpmPcrEvent>(); + for (TpmPcrEvent event2 : eventList2) { + if (pcr >= 0) { + if (event2.getPcrIndex() == pcr) { + if (!digestMatch(eventList, event2)) { + results.add(event2); + } + } + } else { + if (!digestMatch(eventList, event2)) { + results.add(event2); + } + } + } + return results; + } + + /** + * 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; + } +} diff --git a/tools/tcg_eventlog_tool/src/main/java/hirs/tcg_eventlog/package-info.java b/tools/tcg_eventlog_tool/src/main/java/hirs/tcg_eventlog/package-info.java new file mode 100644 index 00000000..d77fcdad --- /dev/null +++ b/tools/tcg_eventlog_tool/src/main/java/hirs/tcg_eventlog/package-info.java @@ -0,0 +1,5 @@ +/** + * Base package that includes common exceptions, interfaces and base implementations for and related + * to the ACA. + */ +package hirs.tcg_eventlog; diff --git a/tools/tcg_rim_tool/generated_swidTag.swidtag b/tools/tcg_rim_tool/generated_swidTag.swidtag index e50475ab..6c37f9d4 100644 --- a/tools/tcg_rim_tool/generated_swidTag.swidtag +++ b/tools/tcg_rim_tool/generated_swidTag.swidtag @@ -18,25 +18,17 @@ F9MDKy55mXkxb/Z5RUC3IKqsoz+EuKjs6d+yhtb1EQtpJD2dZj23+VjMH4gXxEerDNR1PiPhma/i QMFa1hwSO7AuasYPy0WCRIgrJ5ZL5x2ZoaSIdE2TsCqnStVL+KLZeMWNCqw4k89hsuELW7Azrl57 Vm2qzPok0svrB1K4QyZdyK2bnG1QY3Fip5Jdmg==</SignatureValue> <KeyInfo> - <X509Data> - <X509SubjectName>CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US</X509SubjectName> - <X509Certificate>MIIDYTCCAkmgAwIBAgIJAPB+r6VBhBn4MA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAlVTMQsw -CQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxEjAQBgNVBAMM -CUV4YW1wbGVDQTAeFw0yMDAyMTAxODE1MzRaFw0yOTEyMTkxODE1MzRaMFwxCzAJBgNVBAYTAlVT -MQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNV -BAMMEmV4YW1wbGUuUklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1 -lWGkSRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44/nBaccZD -OjdfIxIUCMfwhGXjxCaqZbgTucNsExDnu4arTGraoAwzHg0cVLiKT/Cxj9NL4dcMgxRXsPdHfXb0 -923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY -2hq+z82x/rqwr2hmyizD6FpFSyIABPEMPfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0 -Hh4mNFSKD4pP41VSKY1nus83mdkuukPy5o0CAwEAAaMvMC0wCQYDVR0TBAIwADALBgNVHQ8EBAMC -BsAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAGuJ+dasb3/Mb7TBJ1Oe -al5ISq8d2LQD5ke5qnjgSQWKXfQ9fcUy3dWnt3Oked/i8B/Tyk3jCdTZJU3J3iRNgTqFfMLP8rU1 -w2tPYBjjuPKiiK4YRBHPxtFxPdOL1BPmL4ZzNs33Lv6H0m4aff9p6QpMclX5b/CRjl+80JWRLiLj -U3B0CejZB9dJrPr9SBaC31cDoeTpja9Cl86ip7KkqrZZIYeMuNF6ucWyWtjrW2kr3UhmEy8x/6y4 -KigsK8sBwmNv4N2Pu3RppeIcpjYj5NVA1hwRA4eeMgJp2u+urm3l1oo1UNX1HsSSBHp1Owc9zZLm -07Pl8T46kpIA4sroCAU=</X509Certificate> - </X509Data> + <KeyName>2fdeb8e7d030a2209daa01861a964fedecf2bcc1</KeyName> + <KeyValue> + <RSAKeyValue> + <Modulus>p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx +xkM6N18jEhQIx/CEZePEJqpluBO5w2wTEOe7hqtMatqgDDMeDRxUuIpP8LGP00vh1wyDFFew90d9 +dvT3bcLvFh3a3ap9bTm6aBqPup5CXpzrwIU2wZfgkDytYVBm+8bHkMaUrgpNyM+5BAg2zl/Fqw0q +otjaGr7PzbH+urCvaGbKLMPoWkVLIgAE8Qw98HTfoYSFHC7VYQySrzIinaOBFSgViR72kHemH2lW +jDQeHiY0VIoPik/jVVIpjWe6zzeZ2S66Q/LmjQ==</Modulus> + <Exponent>AQAB</Exponent> + </RSAKeyValue> + </KeyValue> </KeyInfo> </Signature> </SoftwareIdentity> diff --git a/tools/tcg_rim_tool/identity_transform.xslt b/tools/tcg_rim_tool/identity_transform.xslt new file mode 100644 index 00000000..c69ba714 --- /dev/null +++ b/tools/tcg_rim_tool/identity_transform.xslt @@ -0,0 +1,7 @@ +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + <xsl:template match="@*|node()"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> + </xsl:template> +</xsl:stylesheet> diff --git a/tools/tcglp/build.gradle b/tools/tcglp/build.gradle deleted file mode 100644 index 26d24f74..00000000 --- a/tools/tcglp/build.gradle +++ /dev/null @@ -1,157 +0,0 @@ -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', - ] -} diff --git a/tools/tcglp/src/main/java/hirs/tcg_eventlog_tool/Main.java b/tools/tcglp/src/main/java/hirs/tcg_eventlog_tool/Main.java deleted file mode 100644 index ea95358f..00000000 --- a/tools/tcglp/src/main/java/hirs/tcg_eventlog_tool/Main.java +++ /dev/null @@ -1,277 +0,0 @@ -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; - } - -}