From 7a24d2c79bc90262a13792caca364c2cebee2476 Mon Sep 17 00:00:00 2001 From: iadgovuser59 <133057011+iadgovuser59@users.noreply.github.com> Date: Mon, 17 Jul 2023 16:15:57 -0400 Subject: [PATCH] Adding UEFI unit tests --- HIRS_Utils/build.gradle | 22 ++- .../tpm/eventlog/uefi/UefiProcessingTest.java | 171 ++++++++++++++++++ 2 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 HIRS_Utils/src/test/java/hirs/tpm/eventlog/uefi/UefiProcessingTest.java diff --git a/HIRS_Utils/build.gradle b/HIRS_Utils/build.gradle index ea0abd57..da399e5f 100644 --- a/HIRS_Utils/build.gradle +++ b/HIRS_Utils/build.gradle @@ -35,16 +35,24 @@ dependencies { implementation libs.guava implementation libs.commons.codec implementation libs.commons.lang3 + implementation libs.commons.io implementation libs.minimal.json implementation 'org.apache.logging.log4j:log4j-core:2.19.0' implementation 'org.apache.logging.log4j:log4j-api:2.19.0' implementation 'org.glassfish.jaxb:jaxb-runtime:4.0.1' + + implementation 'org.junit.jupiter:junit-jupiter-api:5.9.3' + implementation 'org.junit.jupiter:junit-jupiter-engine:5.9.3' + testImplementation 'junit:junit:4.13.1' + compileOnly libs.lombok annotationProcessor libs.lombok - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' + //testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' + //testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' + testImplementation 'org.junit.platform:junit-platform-launcher:1.9.3' + testImplementation 'org.hamcrest:hamcrest:2.2' } test { @@ -55,11 +63,11 @@ jar { duplicatesStrategy = DuplicatesStrategy.EXCLUDE manifest { attributes( - 'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ') - ) + 'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ') + ) } - //jar name format: [archiveBaseName]-[archiveAppendix]-[archiveVersion]-[archiveClassifier].[archiveExtension] - archiveVersion = jarVersion + //jar name format: [archiveBaseName]-[archiveAppendix]-[archiveVersion]-[archiveClassifier].[archiveExtension] + archiveVersion = jarVersion } //task generateXjcLibrary(type:Exec) { @@ -67,4 +75,4 @@ jar { // // commandLine './genXjcLibrary.sh' //} -//compileJava.dependsOn generateXjcLibrary +//compileJava.dependsOn generateXjcLibrary \ No newline at end of file diff --git a/HIRS_Utils/src/test/java/hirs/tpm/eventlog/uefi/UefiProcessingTest.java b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/uefi/UefiProcessingTest.java new file mode 100644 index 00000000..183af293 --- /dev/null +++ b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/uefi/UefiProcessingTest.java @@ -0,0 +1,171 @@ +package hirs.tpm.eventlog.uefi; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; + +import com.eclipsesource.json.JsonObject; +import hirs.utils.JsonUtils; +import hirs.utils.tpm.eventlog.uefi.*; +import org.apache.commons.io.IOUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import hirs.utils.HexUtils; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +/** + * Class for testing TCG Event Log processing of UEFI defined Data. + */ +public class UefiProcessingTest { + // Variable files collected using an Event Parsing tool + private static final String JSON_FILE = "/tcgeventlog/uefi/vendor-table.json"; + private static final String UEFI_VARIABLE_BOOT = "/tcgeventlog/uefi/EV_EFI_VARIABLE_BOOT.txt"; + private static final String UEFI_VARIABLE_BOOT_SECURE_BOOT + = "/tcgeventlog/uefi/EV_EFI_VAR_SECURE_BOOT.txt"; + private static final String UEFI_VARIABLE_BOOT_DRIVER_CONFIG_KEK + = "/tcgeventlog/uefi/EV_EFI_VARIABLE_DRIVER_CONFIG_KEK.txt"; + private static final String UEFI_GPT_EVENT = "/tcgeventlog/uefi/EV_EFI_GPT_EVENT.txt"; + private static final String UEFI_FW_BLOB = "/tcgeventlog/uefi/EFI_PLATFORM_FIRMWARE_BLOB.txt"; + private static final String UEFI_DEVICE_PATH = "/tcgeventlog/uefi/EFI_DEVICE_PATH.txt"; + + private static final Logger LOGGER + = LogManager.getLogger(UefiProcessingTest.class); + + /** + * Initializes a SessionFactory. + * The factory is used for an in-memory database that is used for testing. + */ + @BeforeAll + public static final void setup() { + LOGGER.debug("retrieving session factory"); + } + + /** + * Closes the SessionFactory from setup. + */ + @AfterAll + public static final void tearDown() { + LOGGER.debug("closing session factory"); + } + + /** + * Tests the processing of UEFI Variables. + * + * @throws IOException when processing the test fails. + * @throws NoSuchAlgorithmException if non TCG Algorithm is encountered. + * @throws CertificateException if parsing issue for X509 cert is encountered. + * @throws URISyntaxException File location exception + */ + @Test + public final void testUefiVariables() throws IOException, + CertificateException, NoSuchAlgorithmException, URISyntaxException { + LOGGER.debug("Testing the parsing of UEFI Variables"); + Path jsonPath = Paths.get(this.getClass() + .getResource(JSON_FILE).toURI()); + String uefiTxt = IOUtils.toString(this.getClass().getResourceAsStream(UEFI_VARIABLE_BOOT), + "UTF-8"); + byte[] uefiVariableBytes = HexUtils.hexStringToByteArray(uefiTxt); + UefiVariable uefiVariable = new UefiVariable(uefiVariableBytes); + UefiGuid guid = uefiVariable.getUefiVarGuid(); + String varName = uefiVariable.getEfiVarName(); + JsonObject jsonObject = JsonUtils.getSpecificJsonObject(jsonPath, "VendorTable"); + String guidStr = jsonObject.getString( + guid.toStringNoLookup().toLowerCase(), "Unknown GUID reference"); + Assertions.assertEquals("EFI_Global_Variable", guidStr); + Assertions.assertEquals("BootOrder", varName); + + uefiTxt = IOUtils.toString(this.getClass() + .getResourceAsStream(UEFI_VARIABLE_BOOT_SECURE_BOOT), + "UTF-8"); + uefiVariableBytes = HexUtils.hexStringToByteArray(uefiTxt); + uefiVariable = new UefiVariable(uefiVariableBytes); + guid = uefiVariable.getUefiVarGuid(); + varName = uefiVariable.getEfiVarName(); + guidStr = jsonObject.getString( + guid.toStringNoLookup().toLowerCase(), "Unknown GUID reference"); + Assertions.assertEquals("EFI_Global_Variable", guidStr); + Assertions.assertEquals("SecureBoot", varName); + + uefiTxt = IOUtils.toString(this.getClass().getResourceAsStream( + UEFI_VARIABLE_BOOT_DRIVER_CONFIG_KEK), "UTF-8"); + uefiVariableBytes = HexUtils.hexStringToByteArray(uefiTxt); + uefiVariable = new UefiVariable(uefiVariableBytes); + varName = uefiVariable.getEfiVarName(); + Assertions.assertEquals("KEK", varName); + } + + /** + * Tests the processing of a UEFI defined GPT Partition event. + * + * @throws IOException when processing the test fails. + * @throws NoSuchAlgorithmException if non TCG Algorithm is encountered. + * @throws CertificateException if parsing issue for X509 cert is encountered. + * @throws URISyntaxException File location exception + */ + @Test + public final void testUefiPartiton() throws IOException, + CertificateException, NoSuchAlgorithmException, URISyntaxException { + LOGGER.debug("Testing the parsing of GPT Data"); + Path jsonPath = Paths.get(this.getClass() + .getResource(JSON_FILE).toURI()); + String uefiTxt = IOUtils.toString(this.getClass().getResourceAsStream(UEFI_GPT_EVENT), + "UTF-8"); + byte[] uefiPartitionBytes = HexUtils.hexStringToByteArray(uefiTxt); + UefiPartition gptPart = new UefiPartition(uefiPartitionBytes); + String gptPartName = gptPart.getPartitionName(); + UefiGuid gptTypeuid = gptPart.getPartitionTypeGUID(); + UefiGuid gptUniqueGuid = gptPart.getUniquePartitionGUID(); + JsonObject jsonObject = JsonUtils.getSpecificJsonObject(jsonPath, "VendorTable"); + String guidStr = jsonObject.getString( + gptTypeuid.toStringNoLookup().toLowerCase(), "Unknown GUID reference"); + Assertions.assertEquals("EFI System Partition", guidStr); + Assertions.assertEquals("8ca7623c-041e-4fab-8c12-f49a86b85d73 : Unknown GUID reference", + gptUniqueGuid.toString()); + Assertions.assertEquals("EFI system partition", gptPartName); + } + + /** + * Tests the processing of a UEFI defined GPT Partition event. + * + * @throws IOException when processing the test fails. + * @throws NoSuchAlgorithmException if non TCG Algorithm is encountered. + * @throws CertificateException if parsing issue for X509 cert is encountered. + */ + @Test + public final void testUefiFirmwareBlob() throws IOException, + CertificateException, NoSuchAlgorithmException { + LOGGER.debug("Testing the parsing of Uefi Firmware Blob"); + String uefiTxt = IOUtils.toString(this.getClass() + .getResourceAsStream(UEFI_FW_BLOB), "UTF-8"); + byte[] uefiFwBlobBytes = HexUtils.hexStringToByteArray(uefiTxt); + UefiFirmware uefiFWBlob = new UefiFirmware(uefiFwBlobBytes); + int fwAddress = uefiFWBlob.getPhysicalBlobAddress(); + int fwLength = uefiFWBlob.getBlobLength(); + Assertions.assertEquals(1797287936, fwAddress); + Assertions.assertEquals(851968, fwLength); + } + + /** + * Tests the processing of a UEFI defined Device Path. + * + * @throws IOException when processing the test fails. + * @throws URISyntaxException File location exception + */ + @Test + public final void testUefiDevicePath() throws IOException, URISyntaxException { + LOGGER.debug("Testing the parsing of Uefi Device Path"); + String uefiTxt = IOUtils.toString(this.getClass().getResourceAsStream(UEFI_DEVICE_PATH), + "UTF-8"); + byte[] uefiFwBlobBytes = HexUtils.hexStringToByteArray(uefiTxt); + UefiDevicePath uefiDevPath = new UefiDevicePath(uefiFwBlobBytes); + String devPathType = uefiDevPath.getType(); + Assertions.assertEquals("Media Device Path", devPathType); + } +} \ No newline at end of file