Merge pull request #377 from nsacyber/component-class-revision

Component Class Bug Fix
This commit is contained in:
Cyrus 2021-07-01 14:29:21 -04:00 committed by GitHub
commit e7cdba07c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 131 additions and 134 deletions

View File

@ -6,6 +6,8 @@ import com.github.marandus.pciid.service.PciIdsDatabase;
import com.google.common.base.Strings;
import hirs.data.persist.certificate.attributes.ComponentIdentifier;
import hirs.data.persist.certificate.attributes.V2.ComponentIdentifierV2;
import org.bouncycastle.asn1.DERUTF8String;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@ -13,7 +15,6 @@ import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import org.bouncycastle.asn1.DERUTF8String;
/**
* Provide Java access to PCI IDs.
@ -84,11 +85,11 @@ public final class PciIds {
/**
* The Component Class Value mask for NICs.
*/
public static final int COMPCLASS_TCG_CAT_NIC = 0x00090000;
public static final String COMPCLASS_TCG_CAT_NIC = "00090000";
/**
* The Component Class Value mask for GFX cards.
*/
public static final int COMPCLASS_TCG_CAT_GFX = 0x00050000;
public static final String COMPCLASS_TCG_CAT_GFX = "00050000";
/**
* Iterate through all components and translate PCI hardware IDs as necessary. It will only
@ -125,9 +126,9 @@ public final class PciIds {
newComponent = component;
// This can be updated as we get more accurate component class registries and values
// Component Class Registry not accessible: TCG assumed
final int compClassValue = component.getComponentClass().getValue();
if (((compClassValue & COMPCLASS_TCG_CAT_NIC)
| (compClassValue & COMPCLASS_TCG_CAT_GFX)) > 0) {
final String compClassValue = component.getComponentClass().getCategoryValue();
if (compClassValue.equals(COMPCLASS_TCG_CAT_NIC)
|| compClassValue.equals(COMPCLASS_TCG_CAT_GFX)) {
DERUTF8String manufacturer = translateVendor(component.getComponentManufacturer());
DERUTF8String model = translateDevice(component.getComponentManufacturer(),
component.getComponentModel());

View File

@ -22,6 +22,8 @@ import java.nio.file.Path;
* componentClassRegistry ComponentClassRegistry,
* componentClassValue OCTET STRING SIZE(4) ) }
* </pre>
*
* A note for the future.
*/
public class ComponentClass {
private static final String TCG_COMPONENT_REGISTRY = "2.23.133.18.3.1";
@ -33,24 +35,21 @@ public class ComponentClass {
private static final String UNKNOWN_STRING = "Unknown";
private static final String NONE_STRING = "None";
// Used to test bytes associated with just the component
private static final int COMPONENT_MASK = 0x0000FFFF;
// Used to test bytes associated with just the category
private static final int CATEGORY_MASK = 0xFFFF0000;
// Used to indicate that the component string value provided is erroneous
private static final int ERROR = -1;
private static final String ERROR = "-1";
private static final int MID_INDEX = 4;
/**
* All categories have Other and Unknown as the first 2 values.
* All TCG categories have Other and Unknown as the first 2 values.
*/
private static final int OTHER = 0;
private static final int UNKNOWN = 1;
private static final String OTHER = "0000";
private static final String UNKNOWN = "0001";
private String category;
private String component;
private String categoryStr;
private String componentStr;
private String registryType;
private int componentIdentifier;
private String classValueString;
private String componentIdentifier;
/**
* Default class constructor.
@ -59,15 +58,6 @@ public class ComponentClass {
this("TCG", JSON_PATH, UNKNOWN);
}
/**
* Class Constructor that takes a int representation of the component value.
*
* @param componentIdentifier component value
*/
public ComponentClass(final int componentIdentifier) {
this(TCG_COMPONENT_REGISTRY, JSON_PATH, componentIdentifier);
}
/**
* Class Constructor that takes a String representation of the component
* value.
@ -76,21 +66,7 @@ public class ComponentClass {
* @param componentIdentifier component value
*/
public ComponentClass(final String registryOid, final String componentIdentifier) {
this(registryOid, JSON_PATH, getComponentIntValue(componentIdentifier));
}
/**
* Class Constructor that takes a String representation of the component
* value.
*
* @param registryOid the decimal notation for the type of registry
* @param componentClassPath file path for the json
* @param componentIdentifier component value
*/
public ComponentClass(final String registryOid,
final Path componentClassPath,
final String componentIdentifier) {
this(registryOid, componentClassPath, getComponentIntValue(componentIdentifier));
this(registryOid, JSON_PATH, componentIdentifier);
}
/**
@ -101,12 +77,7 @@ public class ComponentClass {
* @param componentIdentifier component value
*/
public ComponentClass(final Path componentClassPath, final String componentIdentifier) {
this(TCG_COMPONENT_REGISTRY, componentClassPath, getComponentIntValue(componentIdentifier));
if (componentIdentifier != null && componentIdentifier.contains("#")) {
this.classValueString = componentIdentifier.replaceAll("#", "");
} else {
this.classValueString = componentIdentifier;
}
this(TCG_COMPONENT_REGISTRY, componentClassPath, componentIdentifier);
}
/**
@ -120,10 +91,14 @@ public class ComponentClass {
*/
public ComponentClass(final String registryOid,
final Path componentClassPath,
final int componentIdentifier) {
this.category = UNKNOWN_STRING;
final String componentIdentifier) {
this.category = OTHER;
this.component = NONE_STRING;
this.componentIdentifier = componentIdentifier;
if (componentIdentifier == null || componentIdentifier.isEmpty()) {
this.componentIdentifier = "";
} else {
this.componentIdentifier = verifyComponentValue(componentIdentifier);
}
switch (registryOid) {
case TCG_COMPONENT_REGISTRY:
@ -136,31 +111,45 @@ public class ComponentClass {
registryType = UNKNOWN_STRING;
}
switch (componentIdentifier) {
switch (this.componentIdentifier) {
case OTHER:
this.category = NONE_STRING;
this.component = OTHER_STRING;
this.categoryStr = NONE_STRING;
this.component = OTHER;
this.componentStr = OTHER_STRING;
break;
case UNKNOWN:
this.category = NONE_STRING;
this.component = UNKNOWN_STRING;
case "":
this.categoryStr = NONE_STRING;
this.component = UNKNOWN;
this.componentStr = UNKNOWN_STRING;
break;
case ERROR:
// Number Format Exception
break;
default:
getCategory(JsonUtils.getSpecificJsonObject(componentClassPath, registryType));
this.category = this.componentIdentifier.substring(0, MID_INDEX) + this.category;
this.component = OTHER + this.componentIdentifier.substring(MID_INDEX);
findStringValues(JsonUtils.getSpecificJsonObject(componentClassPath, registryType));
break;
}
}
/**
* Getter for the Category complete value.
*
* @return string value of the category
*/
public final String getCategoryValue() {
return category;
}
/**
* Getter for the Category type.
*
* @return string value of the category
*/
public final String getCategory() {
return category;
return categoryStr;
}
/**
@ -169,25 +158,17 @@ public class ComponentClass {
* @return string value of the component
*/
public final String getComponent() {
return component;
return componentStr;
}
/**
* Getter for the Component Class Value.
* @return int value of the component class.
*/
public final int getValue() {
public final String getValue() {
return componentIdentifier;
}
/**
* Getter for the Component Class Value as a string.
* @return String representation of the class.
*/
public final String getClassValueString() {
return classValueString;
}
/**
* This is the main way this class will be referenced and how it
* will be displayed on the portal.
@ -196,10 +177,10 @@ public class ComponentClass {
@Override
public String toString() {
String resultString;
if (component.equals(UNKNOWN_STRING) || component.equals(OTHER_STRING)) {
resultString = String.format("%s%n%s", registryType, category);
if (componentStr.equals(UNKNOWN_STRING) || component.equals(OTHER_STRING)) {
resultString = String.format("%s%n%s", registryType, categoryStr);
} else {
resultString = String.format("%s%n%s - %s", registryType, category, component);
resultString = String.format("%s%n%s - %s", registryType, categoryStr, componentStr);
}
return resultString;
}
@ -210,54 +191,72 @@ public class ComponentClass {
* @param categories a JSON object associated with mapped categories in file
* {}@link componentIdentifier}.
*/
private void getCategory(final JsonObject categories) {
int componentID;
private void findStringValues(final JsonObject categories) {
String categoryID;
String componentMask;
boolean found = false;
if (categories != null) {
for (String name : categories.names()) {
componentID = Integer.decode(categories.get(name).asObject().get("ID").asString());
categoryID = verifyComponentValue(categories.get(name)
.asObject().get("ID").asString());
componentMask = componentIdentifier.substring(MID_INDEX);
// check for the correct flag
if ((componentIdentifier & CATEGORY_MASK) == componentID) {
if (categoryMatch(componentIdentifier.substring(0, MID_INDEX),
categoryID.substring(0, MID_INDEX))) {
found = true;
JsonObject componentTypes = categories.get(name)
.asObject().get("Types").asObject();
category = name;
categoryStr = name;
switch (componentIdentifier & COMPONENT_MASK) {
switch (componentMask) {
case OTHER:
component = OTHER_STRING;
componentStr = OTHER_STRING;
break;
case UNKNOWN:
component = UNKNOWN_STRING;
componentStr = UNKNOWN_STRING;
break;
default:
getComponent(componentID, componentTypes);
getComponent(componentTypes);
}
}
}
}
if (!found) {
this.categoryStr = NONE_STRING;
this.componentStr = UNKNOWN_STRING;
}
}
/**
* Returns the value of the comparison between a category and the what's in the id.
* @param category the category to compare
* @param componentId the id value to compare
* @return true if they match
*/
public boolean categoryMatch(final String category, final String componentId) {
return category.equals(componentId);
}
/**
* Getter for the component associated with the component JSON Object mapped
* in the JSON file.
*
* @param componentID the ID associated with the category
* @param components JSON Object for the categories components
*/
private void getComponent(final int componentID, final JsonObject components) {
int typeID, testID;
private void getComponent(final JsonObject components) {
String typeID;
if (components != null) {
for (Member member : components) {
typeID = Integer.decode(member.getName());
testID = componentID + typeID;
typeID = verifyComponentValue(member.getName());
if (componentIdentifier == testID) {
component = member.getValue().asString();
if (component.equals(typeID)) {
componentStr = member.getValue().asString();
}
}
}
}
/**
@ -267,21 +266,18 @@ public class ComponentClass {
* @param component string representation of the component ID
* @return the int representation of the component
*/
private static int getComponentIntValue(final String component) {
int componentValue = ERROR;
private static String verifyComponentValue(final String component) {
String componentValue = ERROR;
if (component != null) {
try {
if (component.contains("x")) {
componentValue = Integer.decode(component);
componentValue = component.substring(component.indexOf("x") + 1);
} else {
if (component.contains("#")) {
componentValue = Integer.valueOf(
component.replace("#", ""),
Short.SIZE);
componentValue = component.replace("#", "");
} else {
componentValue = Integer.valueOf(
component, Short.SIZE);
return component;
}
}
} catch (NumberFormatException nfEx) {

View File

@ -649,10 +649,10 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
boolean classFound;
for (ComponentIdentifier ci : absentSerialNum) {
classValue = ciV2.getComponentClass().getClassValueString();
classValue = ciV2.getComponentClass().getValue();
baseCiV2 = (ComponentIdentifierV2) ci;
classFound = classValue.equals(baseCiV2.getComponentClass()
.getClassValueString());
.getValue());
if (classFound) {
if (isMatch(ciV2, baseCiV2)) {
if (ciV2.isAdded()) {
@ -750,8 +750,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
for (ComponentInfo cInfo : allDeviceInfoComponents) {
for (ComponentIdentifier cId : fullDeltaChainComponents) {
ciV2 = (ComponentIdentifierV2) cId;
if (ciV2.getComponentClass().getClassValueString()
.contains(cInfo.getComponentClass())
if (cInfo.getComponentClass().contains(
ciV2.getComponentClass().getValue())
&& isMatch(cId, cInfo)) {
subCompIdList.remove(cId);
subCompInfoList.remove(cInfo);

View File

@ -19,13 +19,13 @@ public class ComponentClassTest {
*/
@Test
public void testGetComponentNoneUNK() throws URISyntaxException {
int componentIdentifier = 1;
String componentIdentifier = "00000001";
ComponentClass instance = new ComponentClass("TCG", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
String resultComponent = instance.getComponent();
Assert.assertEquals("Unknown", resultComponent);
Assert.assertEquals("None", resultCategory);
Assert.assertEquals(resultComponent, "Unknown");
Assert.assertEquals(resultCategory, "None");
}
/**
@ -34,13 +34,13 @@ public class ComponentClassTest {
*/
@Test
public void testGetComponentNoneOther() throws URISyntaxException {
int componentIdentifier = 0;
String componentIdentifier = "00000000";
ComponentClass instance = new ComponentClass("TCG", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
String resultComponent = instance.getComponent();
Assert.assertEquals("Other", resultComponent);
Assert.assertEquals("None", resultCategory);
Assert.assertEquals(resultComponent, "Unknown");
Assert.assertEquals(resultCategory, "None");
}
/**
@ -54,8 +54,8 @@ public class ComponentClassTest {
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
String resultComponent = instance.getComponent();
Assert.assertEquals("None", resultComponent);
Assert.assertEquals("Unknown", resultCategory);
Assert.assertEquals(resultComponent, "Unknown");
Assert.assertEquals(resultCategory, "None");
}
/**
* Test of getComponent method, of class ComponentClass.
@ -63,13 +63,13 @@ public class ComponentClassTest {
*/
@Test
public void testGetComponentNFEx() throws URISyntaxException {
String componentIdentifier = "HIRS";
String componentIdentifier = "99999999";
ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
String resultComponent = instance.getComponent();
Assert.assertEquals("None", resultComponent);
Assert.assertEquals("Unknown", resultCategory);
Assert.assertEquals(resultComponent, "Unknown");
Assert.assertEquals(resultCategory, "None");
}
/**
@ -83,8 +83,8 @@ public class ComponentClassTest {
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
String resultComponent = instance.getComponent();
Assert.assertEquals("None", resultComponent);
Assert.assertEquals("Unknown", resultCategory);
Assert.assertEquals(resultComponent, "Unknown");
Assert.assertEquals(resultCategory, "None");
}
/**
@ -98,8 +98,8 @@ public class ComponentClassTest {
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
String resultComponent = instance.getComponent();
Assert.assertEquals("SAS Bridgeboard", resultComponent);
Assert.assertEquals("Modules", resultCategory);
Assert.assertEquals(resultComponent, "SAS Bridgeboard");
Assert.assertEquals(resultCategory, "Modules");
}
/**
@ -123,13 +123,13 @@ public class ComponentClassTest {
*/
@Test
public void testGetComponentStandardQueryIntTCG() throws URISyntaxException {
int componentIdentifier = 0x00040002;
String componentIdentifier = "0x00040002";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
String resultComponent = instance.getComponent();
Assert.assertEquals("SAS Bridgeboard", resultComponent);
Assert.assertEquals("Modules", resultCategory);
Assert.assertEquals(resultComponent, "SAS Bridgeboard");
Assert.assertEquals(resultCategory, "Modules");
}
/**
@ -138,7 +138,7 @@ public class ComponentClassTest {
*/
@Test
public void testGetComponentStandardQueryIntSMBIOS() throws URISyntaxException {
int componentIdentifier = 0x00040003;
String componentIdentifier = "0x00040003";
ComponentClass instance = new ComponentClass("2.23.133.18.3.3", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
@ -153,7 +153,7 @@ public class ComponentClassTest {
*/
@Test
public void testGetComponentStandardQueryIntOther() throws URISyntaxException {
int componentIdentifier = 0x00040000;
String componentIdentifier = "0x00040000";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
@ -168,7 +168,7 @@ public class ComponentClassTest {
*/
@Test
public void testGetComponentStandardQueryIntUnk() throws URISyntaxException {
int componentIdentifier = 0x00040001;
String componentIdentifier = "0x00040001";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
@ -213,13 +213,13 @@ public class ComponentClassTest {
*/
@Test
public void testGetComponentNonStandardQuery() throws URISyntaxException {
String componentIdentifier = "00040002";
ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
String componentIdentifier = "0x00040002";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
String resultComponent = instance.getComponent();
Assert.assertEquals("SAS Bridgeboard", resultComponent);
Assert.assertEquals("Modules", resultCategory);
Assert.assertEquals(resultComponent, "SAS Bridgeboard");
Assert.assertEquals(resultCategory, "Modules");
}
/**
@ -228,13 +228,13 @@ public class ComponentClassTest {
*/
@Test
public void testGetComponentNonStandardQuery2() throws URISyntaxException {
String componentIdentifier = "#00040002";
ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
String componentIdentifier = "0x00040002";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
String resultComponent = instance.getComponent();
Assert.assertEquals("SAS Bridgeboard", resultComponent);
Assert.assertEquals("Modules", resultCategory);
Assert.assertEquals(resultComponent, "SAS Bridgeboard");
Assert.assertEquals(resultCategory, "Modules");
}
/**
@ -248,8 +248,8 @@ public class ComponentClassTest {
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
String resultComponent = instance.getComponent();
Assert.assertEquals("None", resultComponent);
Assert.assertEquals("Modules", resultCategory);
Assert.assertNull(resultComponent);
Assert.assertEquals(resultCategory, "Modules");
}
/**
@ -263,8 +263,8 @@ public class ComponentClassTest {
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
String resultComponent = instance.getComponent();
Assert.assertEquals("None", resultComponent);
Assert.assertEquals("Modules", resultCategory);
Assert.assertNull(resultComponent);
Assert.assertEquals(resultCategory, "Modules");
}
/**
@ -278,7 +278,7 @@ public class ComponentClassTest {
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategory();
String resultComponent = instance.getComponent();
Assert.assertEquals("None", resultComponent);
Assert.assertEquals("Unknown", resultCategory);
Assert.assertEquals(resultComponent, "Unknown");
Assert.assertEquals(resultCategory, "None");
}
}