Skip to content

Commit

Permalink
Move part of PciIds from AttestationCA back to Utils (#796)
Browse files Browse the repository at this point in the history
* update pciids to acapciids throughout code

* add pciids to utils and update classes that use it

* moved the 4 vendor/device translate functions to the utils pciids

* added pciids translations to SPDM Device Context file

* cleaning up imports

* cleaning up comments

* cleaned up a few checkstyle warnings

* working to get class code

* update output message in main

* working on class code

* fixes/minor changes

* fixed check of class code list
  • Loading branch information
iadgovuser58 authored Jul 22, 2024
1 parent 86646a2 commit 315d3a2
Show file tree
Hide file tree
Showing 9 changed files with 228 additions and 145 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package hirs.attestationca.persist.util;

import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;

import lombok.extern.log4j.Log4j2;
import org.bouncycastle.asn1.DERUTF8String;

import java.util.ArrayList;
import java.util.List;

import static hirs.utils.PciIds.translateDevice;
import static hirs.utils.PciIds.translateVendor;

/**
* Provide Java access to PCI IDs.
*/
@Log4j2
public final class AcaPciIds {

/**
* The Component Class TCG Registry OID.
*/
public static final String COMPCLASS_TCG_OID = "2.23.133.18.3.1";
/**
* The Component Class Value mask for NICs.
*/
public static final String COMPCLASS_TCG_CAT_NIC = "00090000";
/**
* The Component Class Value mask for GFX cards.
*/
public static final String COMPCLASS_TCG_CAT_GFX = "00050000";

/**
* Iterate through all components and translate PCI hardware IDs as necessary. It will only
* translate ComponentIdentifierV2+ objects as it relies on Component Class information.
* @param components List of ComponentIdentifiers.
* @return the translated list of ComponentIdentifiers.
*/
public static List<ComponentIdentifier> translate(
final List<ComponentIdentifier> components) {
List<ComponentIdentifier> newList = new ArrayList<>();
if (components != null && !components.isEmpty()) {
for (final ComponentIdentifier component : components) {
// V2 components should not be found alongside V1 components
// they pass through just in case
if (component.isVersion2()) {
newList.add(translate((ComponentIdentifierV2) component));
} else {
newList.add(component);
}
}
}
return newList;
}

/**
* Iterate through all components and translate PCI hardware IDs as necessary. It will only
* translate ComponentResults objects as it relies on Component Class information.
* @param componentResults List of ComponentResults.
* @return the translated list of ComponentResults.
*/
public static List<ComponentResult> translateResults(final List<ComponentResult> componentResults) {
List<ComponentResult> newList = new ArrayList<>();
if (componentResults != null && !componentResults.isEmpty()) {
for (final ComponentResult componentResult : componentResults) {
newList.add(translateResult(componentResult));
}
}

return newList;
}

/**
* Translate Vendor and Device IDs, if found, in ComponentIdentifierV2 objects.
* It will only translate ID values, any other value will pass through.
* @param component ComponentIdentifierV2 object.
* @return the translated ComponentIdentifierV2 object.
*/
public static ComponentIdentifierV2 translate(final ComponentIdentifierV2 component) {
ComponentIdentifierV2 newComponent = null;
if (component != null) {
newComponent = component;
// This can be updated as we get more accurate component class registries and values
// Component Class Registry not accessible: TCG assumed
final String compClassValue = component.getComponentClass().getCategory();
if (compClassValue.equals(COMPCLASS_TCG_CAT_NIC)
|| compClassValue.equals(COMPCLASS_TCG_CAT_GFX)) {
DERUTF8String manufacturer = (DERUTF8String) translateVendor(
component.getComponentManufacturer());
DERUTF8String model = (DERUTF8String) translateDevice(
component.getComponentManufacturer(),
component.getComponentModel());

newComponent = new ComponentIdentifierV2(component.getComponentClass(),
manufacturer,
model,
component.getComponentSerial(),
component.getComponentRevision(),
component.getComponentManufacturerId(),
component.getFieldReplaceable(),
component.getComponentAddress(),
component.getCertificateIdentifier(),
component.getComponentPlatformUri(),
component.getAttributeStatus());
}

}
return newComponent;
}

/**
* Translate Vendor and Device IDs, if found, in ComponentResult objects.
* It will only translate ID values, any other value will pass through.
* @param componentResult ComponentResult object.
* @return the translated ComponentResult object.
*/
public static ComponentResult translateResult(final ComponentResult componentResult) {
ComponentResult newComponent = null;
if (componentResult != null) {
newComponent = componentResult;
newComponent.setManufacturer(translateVendor(componentResult.getManufacturer()));
newComponent.setModel(translateDevice(componentResult.getManufacturer(),
componentResult.getModel()));
}
return newComponent;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
import hirs.attestationca.persist.entity.userdefined.info.HardwareInfo;
import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
import hirs.attestationca.persist.enums.AppraisalStatus;
import hirs.attestationca.persist.util.PciIds;
import hirs.attestationca.persist.util.AcaPciIds;
import hirs.utils.PciIds;
import hirs.utils.enums.DeviceInfoEnums;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.digest.DigestUtils;
Expand Down Expand Up @@ -446,7 +447,7 @@ && isMatch(cId, cInfo)) {
fullDeltaChainComponents.clear();
for (ComponentIdentifier ci : subCompIdList) {
if (ci.isVersion2() && PciIds.DB.isReady()) {
ci = PciIds.translate((ComponentIdentifierV2) ci);
ci = AcaPciIds.translate((ComponentIdentifierV2) ci);
}
log.error("Unmatched component: " + ci);
fullDeltaChainComponents.add(ci);
Expand Down Expand Up @@ -608,7 +609,7 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc
for (ComponentIdentifier unmatchedComponent : pcUnmatchedComponents) {
if (unmatchedComponent.isVersion2() && PciIds.DB.isReady()) {
unmatchedComponent =
PciIds.translate((ComponentIdentifierV2) unmatchedComponent);
AcaPciIds.translate((ComponentIdentifierV2) unmatchedComponent);
}
log.error("Unmatched component " + unmatchedComponentCounter++ + ": "
+ unmatchedComponent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfiguration;
import hirs.attestationca.persist.util.PciIds;
import hirs.attestationca.persist.util.AcaPciIds;
import hirs.utils.BouncyCastleUtils;
import hirs.utils.PciIds;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
Expand Down Expand Up @@ -372,7 +373,7 @@ public static HashMap<String, Object> getPlatformInformation(final UUID uuid,
certificate.getSerialNumber().toString(),
certificate.getPlatformSerial());
if (PciIds.DB.isReady()) {
compResults = PciIds.translateResults(compResults);
compResults = AcaPciIds.translateResults(compResults);
}
data.put("componentResults", compResults);

Expand All @@ -382,7 +383,7 @@ public static HashMap<String, Object> getPlatformInformation(final UUID uuid,
//Component Identifier - attempt to translate hardware IDs
List<ComponentIdentifier> comps = platformConfiguration.getComponentIdentifier();
if (PciIds.DB.isReady()) {
comps = PciIds.translate(comps);
comps = AcaPciIds.translate(comps);
}
data.put("componentsIdentifier", comps);
//Component Identifier URI
Expand Down
1 change: 1 addition & 0 deletions HIRS_Utils/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ dependencies {
implementation libs.commons.lang3
implementation libs.commons.io
implementation libs.minimal.json
implementation libs.pci

implementation 'org.apache.logging.log4j:log4j-core:2.19.0'
implementation 'org.apache.logging.log4j:log4j-api:2.19.0'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package hirs.attestationca.persist.util;
package hirs.utils;

import com.github.marandus.pciid.model.Device;
import com.github.marandus.pciid.model.DeviceClass;
import com.github.marandus.pciid.model.DeviceSubclass;
import com.github.marandus.pciid.model.ProgramInterface;
import com.github.marandus.pciid.model.Vendor;
import com.github.marandus.pciid.service.PciIdsDatabase;
import com.google.common.base.Strings;
import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;

import lombok.extern.log4j.Log4j2;
import org.bouncycastle.asn1.ASN1UTF8String;
import org.bouncycastle.asn1.DERUTF8String;
Expand All @@ -25,6 +24,7 @@
*/
@Log4j2
public final class PciIds {

/**
* This pci ids file can be in different places on different distributions.
*/
Expand Down Expand Up @@ -78,114 +78,6 @@ public final class PciIds {
}
}

/**
* The Component Class TCG Registry OID.
*/
public static final String COMPCLASS_TCG_OID = "2.23.133.18.3.1";
/**
* The Component Class Value mask for NICs.
*/
public static final String COMPCLASS_TCG_CAT_NIC = "00090000";
/**
* The Component Class Value mask for GFX cards.
*/
public static final String COMPCLASS_TCG_CAT_GFX = "00050000";

/**
* Iterate through all components and translate PCI hardware IDs as necessary. It will only
* translate ComponentIdentifierV2+ objects as it relies on Component Class information.
* @param components List of ComponentIdentifiers.
* @return the translated list of ComponentIdentifiers.
*/
public static List<ComponentIdentifier> translate(
final List<ComponentIdentifier> components) {
List<ComponentIdentifier> newList = new ArrayList<>();
if (components != null && !components.isEmpty()) {
for (final ComponentIdentifier component : components) {
// V2 components should not be found alongside V1 components
// they pass through just in case
if (component.isVersion2()) {
newList.add(translate((ComponentIdentifierV2) component));
} else {
newList.add(component);
}
}
}
return newList;
}

/**
* Iterate through all components and translate PCI hardware IDs as necessary. It will only
* translate ComponentResults objects as it relies on Component Class information.
* @param componentResults List of ComponentResults.
* @return the translated list of ComponentResults.
*/
public static List<ComponentResult> translateResults(final List<ComponentResult> componentResults) {
List<ComponentResult> newList = new ArrayList<>();
if (componentResults != null && !componentResults.isEmpty()) {
for (final ComponentResult componentResult : componentResults) {
newList.add(translateResult(componentResult));
}
}

return newList;
}

/**
* Translate Vendor and Device IDs, if found, in ComponentIdentifierV2 objects.
* It will only translate ID values, any other value will pass through.
* @param component ComponentIdentifierV2 object.
* @return the translated ComponentIdentifierV2 object.
*/
public static ComponentIdentifierV2 translate(final ComponentIdentifierV2 component) {
ComponentIdentifierV2 newComponent = null;
if (component != null) {
newComponent = component;
// This can be updated as we get more accurate component class registries and values
// Component Class Registry not accessible: TCG assumed
final String compClassValue = component.getComponentClass().getCategory();
if (compClassValue.equals(COMPCLASS_TCG_CAT_NIC)
|| compClassValue.equals(COMPCLASS_TCG_CAT_GFX)) {
DERUTF8String manufacturer = (DERUTF8String) translateVendor(
component.getComponentManufacturer());
DERUTF8String model = (DERUTF8String) translateDevice(
component.getComponentManufacturer(),
component.getComponentModel());

newComponent = new ComponentIdentifierV2(component.getComponentClass(),
manufacturer,
model,
component.getComponentSerial(),
component.getComponentRevision(),
component.getComponentManufacturerId(),
component.getFieldReplaceable(),
component.getComponentAddress(),
component.getCertificateIdentifier(),
component.getComponentPlatformUri(),
component.getAttributeStatus());
}

}
return newComponent;
}

/**
* Translate Vendor and Device IDs, if found, in ComponentResult objects.
* It will only translate ID values, any other value will pass through.
* @param componentResult ComponentResult object.
* @return the translated ComponentResult object.
*/
public static ComponentResult translateResult(final ComponentResult componentResult) {
ComponentResult newComponent = null;
if (componentResult != null) {
newComponent = componentResult;
newComponent.setManufacturer(translateVendor(componentResult.getManufacturer()));
newComponent.setModel(translateDevice(componentResult.getManufacturer(),
componentResult.getModel()));
}
return newComponent;
}

/**
* Look up the vendor name from the PCI IDs list, if the input string contains an ID.
* If any part of this fails, return the original manufacturer value.
Expand Down Expand Up @@ -229,7 +121,7 @@ public static String translateVendor(final String refManufacturer) {
* @return ASN1UTF8String with the discovered device name, or the original model value.
*/
public static ASN1UTF8String translateDevice(final ASN1UTF8String refManufacturer,
final ASN1UTF8String refModel) {
final ASN1UTF8String refModel) {
ASN1UTF8String manufacturer = refManufacturer;
ASN1UTF8String model = refModel;
if (manufacturer != null
Expand Down Expand Up @@ -268,4 +160,44 @@ public static String translateDevice(final String refManufacturer,
}
return model;
}

/**
* Look up the device class name from the PCI IDs list, if the input string contains an ID.
* If any part of this fails, return the original manufacturer value.
* @param refClassCode String, formatted as 2 characters (1 byte) for each of the 3 categories
* Example "010802":
* Class: "01"
* Subclass: "08"
* Programming Interface: "02"
* @return List<String> 3-element list with the class code
* 1st element: human-readable description of Class
* 2nd element: human-readable description of Subclass
* 3rd element: human-readable description of Programming Interface
*/
public static List<String> translateDeviceClass(final String refClassCode) {
List<String> translatedClassCode = new ArrayList<>();

String classCode = refClassCode;
if (classCode != null && classCode.trim().matches("^[0-9A-Fa-f]{6}$")) {
String deviceClass = classCode.substring(0,2).toLowerCase();
String deviceSubclass = classCode.substring(2,4).toLowerCase();
String programInterface = classCode.substring(4,6).toLowerCase();
translatedClassCode.add(deviceClass);
translatedClassCode.add(deviceSubclass);
translatedClassCode.add(programInterface);
DeviceClass devC = DB.findDeviceClass(deviceClass);
DeviceSubclass devSc = DB.findDeviceSubclass(deviceClass, deviceSubclass);
ProgramInterface progI = DB.findProgramInterface(deviceClass, deviceSubclass, programInterface);
if (devC != null && !Strings.isNullOrEmpty(devC.getName())) {
translatedClassCode.set(0, devC.getName());
}
if (devSc != null && !Strings.isNullOrEmpty(devSc.getName())) {
translatedClassCode.set(1, devSc.getName());
}
if (progI != null && !Strings.isNullOrEmpty(progI.getName())) {
translatedClassCode.set(2, progI.getName());
}
}
return translatedClassCode;
}
}
Loading

0 comments on commit 315d3a2

Please sign in to comment.