propogating error dealing with file access through the sequence of code

This commit is contained in:
iadgovuser58 2024-06-03 15:42:44 -04:00
parent 56db55cf25
commit 2423b157bb
8 changed files with 114 additions and 178 deletions

View File

@ -121,6 +121,7 @@ public final class JsonUtils {
return new JsonObject();
}
public static JsonObject getJsonObject(final String jsonFilename) {
return getJsonObject(jsonFilename, StandardCharsets.UTF_8);
}
@ -131,7 +132,7 @@ public final class JsonUtils {
try {
InputStream jsonIs = UefiGuid.class
.getClassLoader().getResourceAsStream("vendor-table2.json");
.getClassLoader().getResourceAsStream(jsonFilename);
jsonObject = Json.parse(new InputStreamReader(jsonIs,
charset)).asObject();
} catch (IOException e) {

View File

@ -20,8 +20,8 @@ import java.security.cert.CertificateException;
import java.util.Collection;
import java.util.LinkedHashMap;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILE_NORMAL;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILE_NOT_ACCESSIBLE;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_FROM_FILESYSTEM;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
/**
* Class for handling different formats of TCG Event logs.
@ -80,14 +80,15 @@ public final class TCGEventLog {
/** Event Output Flag use. */
@Getter
private boolean bCryptoAgile = false;
/** Track if vendor-table file is inaccessible.
* If vendor-table file is not used, this remains false.
/**
* Track status of vendor-table.json
* This is only used if there is an event that uses a UefiVariable data structure.
* Default is normal status (normal status is from-filesystem).
* Status will only change IF there is a UefiVariable event in this log,
* and if that event causes a different status.
* */
@Getter
private boolean bVendorTableFileInaccessbile = false;
/** Track status of vendor-table.json */
@Getter
private String bVendorTableFileStatus = FILE_NORMAL;
private String vendorTableFileStatus = FILESTATUS_FROM_FILESYSTEM;
/**
* Default blank object constructor.
@ -158,11 +159,19 @@ public final class TCGEventLog {
} else {
eventList.put(eventNumber, new TpmPcrEvent1(is, eventNumber++));
}
if(eventList.get(eventNumber-1).isBVendorTableFileInaccessbile()) {
bVendorTableFileInaccessbile = true;
}
if(eventList.get(eventNumber-1).getBVendorTableFileStatus() == FILE_NOT_ACCESSIBLE) {
bVendorTableFileStatus = FILE_NOT_ACCESSIBLE;
// first check if any previous event has not been able to access vendor-table.json,
// and if that is the case, the first comparison in the if returns false and
// the if statement is not executed
// [previous event file status = vendorTableFileStatus]
// (ie. keep the file status to reflect that file was not accessible at some point)
// next, check if the new event has any status other than the default 'filesystem',
// and if that is the case, the 2nd comparison in the if returns true and
// the if statement is executed
// [new event file status = eventList.get(eventNumber-1).getVendorTableFileStatus()]
// (ie. if the new file status is not-accessible or from-code, then want to update)
if((vendorTableFileStatus != FILESTATUS_NOT_ACCESSIBLE) &&
(eventList.get(eventNumber-1).getVendorTableFileStatus() != FILESTATUS_FROM_FILESYSTEM)) {
vendorTableFileStatus = eventList.get(eventNumber-1).getVendorTableFileStatus();
}
}
calculatePcrValues();

View File

@ -33,8 +33,8 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILE_NORMAL;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILE_NOT_ACCESSIBLE;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_FROM_FILESYSTEM;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
/**
* Class to process a TCG_PCR_EVENT.
@ -120,14 +120,15 @@ public class TpmPcrEvent {
@Setter @Getter
private boolean error = false;
/** Track if vendor-table file is inaccessible.
* If vendor-table file is not used, this remains false.
/**
* Track status of vendor-table.json
* This is only used for events that use a UefiVariable data structure.
* Default is normal status (normal status is from-filesystem).
* Status will only change IF this is an event that has a UefiVariable,
* and if that event causes a different status.
* */
@Getter
private boolean bVendorTableFileInaccessbile = false;
/** Track status of vendor-table.json */
@Getter
private String bVendorTableFileStatus = FILE_NORMAL;
private String vendorTableFileStatus = FILESTATUS_FROM_FILESYSTEM;
/**
* Constructor.
@ -520,22 +521,12 @@ public class TpmPcrEvent {
String efiVarDescription = efiVar.toString().replace("\n", "\n ");
description += "Event Content:\n " + efiVarDescription.substring(0,
efiVarDescription.length() - INDENT_3);
if(efiVar.isBVendorTableFileInaccessbile()) {
bVendorTableFileInaccessbile = true;
}
if(efiVar.getBVendorTableFileStatus() == FILE_NOT_ACCESSIBLE) {
bVendorTableFileStatus = FILE_NOT_ACCESSIBLE;
}
vendorTableFileStatus = efiVar.getVendorTableFileStatus();
break;
case EvConstants.EV_EFI_VARIABLE_BOOT:
UefiVariable efiVarBoot = new UefiVariable(content);
description += "Event Content:\n" + efiVarBoot.toString();
if(efiVarBoot.isBVendorTableFileInaccessbile()) {
bVendorTableFileInaccessbile = true;
}
if(efiVarBoot.getBVendorTableFileStatus() == FILE_NOT_ACCESSIBLE) {
bVendorTableFileStatus = FILE_NOT_ACCESSIBLE;
}
vendorTableFileStatus = efiVarBoot.getVendorTableFileStatus();
break;
case EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION:
EvEfiBootServicesApp bootServices = new EvEfiBootServicesApp(content);
@ -566,12 +557,7 @@ public class TpmPcrEvent {
case EvConstants.EV_EFI_VARIABLE_AUTHORITY:
UefiVariable efiVarAuth = new UefiVariable(content);
description += "Event Content:\n" + efiVarAuth.toString();
if(efiVarAuth.isBVendorTableFileInaccessbile()) {
bVendorTableFileInaccessbile = true;
}
if(efiVarAuth.getBVendorTableFileStatus() == FILE_NOT_ACCESSIBLE) {
bVendorTableFileStatus = FILE_NOT_ACCESSIBLE;
}
vendorTableFileStatus = efiVarAuth.getVendorTableFileStatus();
break;
case EvConstants.EV_EFI_SPDM_FIRMWARE_BLOB:
description += "Event Content:\n" + new EvEfiSpdmFirmwareBlob(content).toString();

View File

@ -272,18 +272,18 @@ public final class UefiConstants {
*/
public static final int UEFI_PT_LENGTH = 72;
/**
* file status, where file was successfully found on local machine
* file status, where file was successfully found on local machine.
*/
public static final String FILE_NORMAL = "fileNormal";
public static final String FILESTATUS_FROM_FILESYSTEM = "fileFromFilesystem";
/**
* file status, where file is not accessible
* file status, where file was not found on local machine, so file from code was used.
* For instance, if vendor-table.json is not found in filesystem at location
* /etc/hirs/aca/default-properties/, it will be grabbed from code at
* HIRS_AttestationCA/src/main/resources/.
*/
public static final String FILE_NOT_ACCESSIBLE = "fileNotAccessible";
public static final String FILESTATUS_FROM_CODE = "fileFromCode";
/**
* file status, where file was not found on the local machine,
* and so file from the code was used.
* For instance, if vendor-table.json is not found in /etc/hirs/aca/default-properties/,
* it will be grabbed from code at HIRS_AttestationCA/src/main/resources/.
* file status, where file is not accessible (either not found, or no access permission).
*/
public static final String FILE_FROM_CODE_USED = "fileFromCodeUsed";
public static final String FILESTATUS_NOT_ACCESSIBLE = "fileNotAccessible";
}

View File

@ -1,9 +1,11 @@
package hirs.utils.tpm.eventlog.uefi;
import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonObject;
import hirs.utils.HexUtils;
import hirs.utils.JsonUtils;
import hirs.utils.rim.ReferenceManifestValidator;
import lombok.Getter;
import org.apache.commons.io.IOUtils;
import javax.xml.transform.Source;
@ -22,6 +24,10 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_FROM_CODE;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_FROM_FILESYSTEM;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
/**
* Class to process GUID per the UEFI specification
* GUIDs are essentially UUID as defined by RFC-1422, however Microsoft refers to GUIDS.
@ -39,9 +45,13 @@ public class UefiGuid {
private static final Path JSON_PATH = FileSystems.getDefault().getPath("/etc",
"hirs", "aca", "default-properties", "vendor-table.json");
private static final String vendorTableFilename = "vendor-table.json";
private static final String JSON_FILENAME = "vendor-table3.json";
private JsonObject uefiVendorRef;
/** Track status of vendor-table.json */
@Getter
private String vendorTableFileStatus = FILESTATUS_NOT_ACCESSIBLE;
/**
* guid byte array.
*/
@ -57,103 +67,7 @@ public class UefiGuid {
* @param guidBytes byte array holding a valid guid.
*/
public UefiGuid(final byte[] guidBytes) {
guid = new byte[UefiConstants.SIZE_16];
System.arraycopy(guidBytes, 0, guid, 0, UefiConstants.SIZE_16);
uuid = processGuid(guidBytes);
// uefiVendorRef = JsonUtils.getSpecificJsonObject(JSON_PATH, "VendorTable");
Path bad = FileSystems.getDefault().getPath("/etc",
"hirs", "aca", "default-properties", "vendor-tableBAD.json");
uefiVendorRef = JsonUtils.getSpecificJsonObject(bad,
"VendorTable");
if(isVendorTableReferenceHandleEmpty()) {
System.out.println("XXXX EMPTYYYYYYY, before trying to grab file from code");
// uefiVendorRef = JsonUtils.getJsonObject("vendor-table2.json",
// StandardCharsets.UTF_8);
uefiVendorRef = JsonUtils.getSpecificJsonObject("vendor-table2.json", "VendorTable",
StandardCharsets.UTF_8);
// System.out.println("XXXX getClass: " + getClass());
// System.out.println("XXXX getClassResource: " + getClass().getResource("/vendor-table2.json"));
//
//
// InputStream inpStr = UefiGuid.class
// .getClassLoader().getResourceAsStream("vendor-table2.json");
// System.out.println("XXXX InputStream: " + inpStr);
//
// Source inpSource = new StreamSource(
// ReferenceManifestValidator.class.getClassLoader()
// .getResourceAsStream("vendor-table2.json"));
// System.out.println("XXXX Source: " + inpSource);
//
// String path = this.getClass().getClassLoader().getResource("vendor-table2.json").toExternalForm();
// System.out.println("XXXX External Form: " + path);
// JsonReader reader = new JsonReader(new InputStreamReader(inpStr, "UTF-8"));
// try {
// BufferedReader streamReader = new BufferedReader(new InputStreamReader(inpStr, "UTF-8"));
// StringBuilder responseStrBuilder = new StringBuilder();
//
// String inputStr;
// while ((inputStr = streamReader.readLine()) != null)
// responseStrBuilder.append(inputStr);
//
// String test = responseStrBuilder.toString();
//// Gson gson = new Gson();
//
// JsonObject testjj = parser.
//
// String temp = "hello";
//
//// JsonObject jsonObject = new JsonObject(responseStrBuilder.toString());
//
// } catch (UnsupportedEncodingException e) {
// throw new RuntimeException(e);
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// byte[] rawLogBytes = IOUtils.toByteArray(inpStr);
// Path fPath2 = Paths.get(inpStr.toURI());
// try {
//// private static final String EK_PUBLIC_PATH = "/tpm2/ek.pub";
//
//// Source source = new StreamSource(
//// getClass().getClassLoader().getResourceAsStream("identity_transform.xslt"));
//
//
// Path fPath = Paths.get(getClass().getResource("/vendor-table2.json").toURI());
//// URL url = ClassLoader.getSystemResources("vendor-table.json").nextElement();
//// URL url = ClassLoader.getSystemResources("vendor-table.json");
//// Path fPath = Paths.get(url.toURI());
// uefiVendorRef = JsonUtils.getSpecificJsonObject(fPath,
// "VendorTable");
//
// }
//// catch (IOException e) {
//// System.out.print("XXXX IOException");
//// throw new RuntimeException(e);
//// }
// catch (URISyntaxException e) {
// System.out.print("XXXX URISyntaxException");
// throw new RuntimeException(e);
// }
}
if(isVendorTableReferenceHandleEmpty()) {
System.out.println("YYYY EMPTY STILL, after trying to grab file from code");
}
this(guidBytes, JSON_PATH);
}
/**
@ -168,6 +82,18 @@ public class UefiGuid {
uuid = processGuid(guidBytes);
uefiVendorRef = JsonUtils.getSpecificJsonObject(vendorPathString,
"VendorTable");
if(!isVendorTableReferenceHandleEmpty()) {
vendorTableFileStatus = FILESTATUS_FROM_FILESYSTEM;
}
else {
// could not access vendor-table.json from filesystem, so attempt to access from code
uefiVendorRef = JsonUtils.getSpecificJsonObject(JSON_FILENAME, "VendorTable",
StandardCharsets.UTF_8);
if(!isVendorTableReferenceHandleEmpty()) {
vendorTableFileStatus = FILESTATUS_FROM_CODE;
}
}
}
/**

View File

@ -9,8 +9,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILE_NORMAL;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILE_NOT_ACCESSIBLE;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
/**
* Class for processing the contents of a Secure Boot DB or DBX contents.
@ -72,14 +71,9 @@ public class UefiSignatureList {
* Type of signature.
*/
private UefiGuid signatureType = null;
/** Track if vendor-table file is inaccessible.
* If vendor-table file is not used, this remains false.
* */
@Getter
private boolean bVendorTableFileInaccessbile = false;
/** Track status of vendor-table.json */
@Getter
private String bVendorTableFileStatus = FILE_NORMAL;
private String vendorTableFileStatus = FILESTATUS_NOT_ACCESSIBLE;
/**
* UefiSignatureList constructor.
@ -95,6 +89,7 @@ public class UefiSignatureList {
byte[] guid = new byte[UefiConstants.SIZE_16];
System.arraycopy(list, 0, guid, 0, UefiConstants.SIZE_16);
signatureType = new UefiGuid(guid);
vendorTableFileStatus = signatureType.getVendorTableFileStatus();
byte[] lSize = new byte[UefiConstants.SIZE_4];
System.arraycopy(list, UefiConstants.OFFSET_16, lSize, 0, UefiConstants.SIZE_4);
@ -125,10 +120,11 @@ public class UefiSignatureList {
byte[] guid = new byte[UefiConstants.SIZE_16];
lists.read(guid);
signatureType = new UefiGuid(guid);
if(signatureType.isVendorTableReferenceHandleEmpty()) {
bVendorTableFileInaccessbile = true;
bVendorTableFileStatus = FILE_NOT_ACCESSIBLE;
}
vendorTableFileStatus = signatureType.getVendorTableFileStatus();
// if(signatureType.isVendorTableReferenceHandleEmpty()) {
// bVendorTableFileInaccessbile = true;
// vendorTableFileStatus = FILE_NOT_ACCESSIBLE;
// }
// if signatureType is invalid, don't even process any of the data
// however, if signatureTYpe is valid, but some of the data later on is invalid, that will

View File

@ -12,8 +12,9 @@ import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILE_NORMAL;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILE_NOT_ACCESSIBLE;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_FROM_CODE;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_FROM_FILESYSTEM;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
/**
* Class to process a UEFI variable within a TPM Event.
@ -66,14 +67,14 @@ public class UefiVariable {
*/
private byte[] uefiVariableData = null;
/** Track if vendor-table file is inaccessible.
* If vendor-table file is not used, this remains false.
/**
* Track status of vendor-table.json.
* The default here is that each list correctly grabbed the file from file system.
* If any one list has issues, this overall status will change to reflect the
* problematic list's status.
* */
@Getter
private boolean bVendorTableFileInaccessbile = false;
/** Track status of vendor-table.json */
@Getter
private String bVendorTableFileStatus = FILE_NORMAL;
private String vendorTableFileStatus = FILESTATUS_FROM_FILESYSTEM;
/**
* EFIVariable constructor.
@ -158,13 +159,23 @@ public class UefiVariable {
while (certData.available() > 0) {
UefiSignatureList list;
list = new UefiSignatureList(certData);
// first check if any previous list has not been able to access vendor-table.json,
// and if that is the case, the first comparison in the if returns false and
// the if statement is not executed
// [previous event file status = vendorTableFileStatus]
// (ie. keep the file status to reflect that file was not accessible at some point)
// next, check if the new list has any status other than the default 'filesystem',
// and if that is the case, the 2nd comparison in the if returns true and
// the if statement is executed
// [new event file status = list.getVendorTableFileStatus()]
// (ie. if the new file status is not-accessible or from-code, then want to update)
if((vendorTableFileStatus != FILESTATUS_NOT_ACCESSIBLE) &&
(list.getVendorTableFileStatus() != FILESTATUS_FROM_FILESYSTEM)) {
vendorTableFileStatus = list.getVendorTableFileStatus();
}
// efiVariableSigListContents += list.toString();
if(list.isBVendorTableFileInaccessbile()) {
bVendorTableFileInaccessbile = true;
}
if(list.getBVendorTableFileStatus() == FILE_NOT_ACCESSIBLE) {
bVendorTableFileStatus = FILE_NOT_ACCESSIBLE;
}
if(!list.isSignatureTypeValid()) {
invalidSignatureListEncountered = true;
invalidSignatureListStatus = list.toString();

View File

@ -16,7 +16,8 @@ import hirs.utils.tpm.eventlog.TCGEventLog;
import hirs.utils.tpm.eventlog.TpmPcrEvent;
import hirs.utils.HexUtils;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILE_NOT_ACCESSIBLE;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_FROM_CODE;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
/**
* Command-line application for processing TCG Event Logs.
@ -129,13 +130,19 @@ final class Main {
writeOut("\nEvent Log follows the \"SHA1\" format and has "
+ evLog.getEventList().size() + " events:\n\n");
}
if (evLog.isBVendorTableFileInaccessbile()) {
writeOut("*** remove this.\n\n");
}
if (evLog.getBVendorTableFileStatus() == FILE_NOT_ACCESSIBLE) {
if (evLog.getVendorTableFileStatus() == FILESTATUS_NOT_ACCESSIBLE) {
writeOut("*** WARNING: The file vendor-table.json file was not accessible so data " +
"in some Secure Boot PCR 7 events cannot be processed.\n\n");
}
else if (evLog.getVendorTableFileStatus() == FILESTATUS_FROM_CODE) {
writeOut("*** NOTE: " +
"The file vendor-table.json file was not accessible from the filesystem,\n" +
" so the vendor-table.json from code was " +
"used. If updates were made in the\n" +
" filesystem file, they will not be reflected. " +
"This affects parsing in some\n" +
" Secure Boot PCR 7 events.\n\n");
}
}
int eventCount = 0;
for (TpmPcrEvent event : evLog.getEventList()) {