From 50098de266bd862485d31b79a7b0977436d9fca3 Mon Sep 17 00:00:00 2001 From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com> Date: Mon, 27 Jan 2025 18:21:41 -0500 Subject: [PATCH 01/14] issue_896: first cut at changing the logic on the validator --- .../certificate/PlatformCredential.java | 47 +++++++++++- .../attributes/ComponentClass.java | 6 ++ .../attributes/PlatformConfiguration.java | 8 ++- .../V2/PlatformConfigurationV2.java | 28 ++++++-- .../CertificateAttributeScvValidator.java | 72 +++++++++++-------- .../validation/CredentialValidator.java | 2 +- .../SupplyChainCredentialValidatorTest.java | 42 +++++------ 7 files changed, 140 insertions(+), 65 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java index e11ab1463..d8ce5315f 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java @@ -6,6 +6,7 @@ import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfigurationV1; import hirs.attestationca.persist.entity.userdefined.certificate.attributes.TBBSecurityAssertion; import hirs.attestationca.persist.entity.userdefined.certificate.attributes.URIReference; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2; import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.PlatformConfigurationV2; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -64,25 +65,30 @@ public class PlatformCredential extends DeviceAssociatedCertificate { * TCPA Trusted Platform Endorsement. */ public static final String CERTIFICATE_TYPE_1_2 = "TCPA Trusted Platform Endorsement"; + /** * TCG Trusted Platform Endorsement. */ public static final String CERTIFICATE_TYPE_2_0 = "TCG Trusted Platform Endorsement"; private static final int TCG_SPECIFICATION_LENGTH = 3; + // These are Object Identifiers (OIDs) for sections in the credentials private static final String POLICY_QUALIFIER_CPSURI = "1.3.6.1.5.5.7.2.1"; private static final String POLICY_QUALIFIER_USER_NOTICE = "1.3.6.1.5.5.7.2.2"; + // OID for TCG Attributes private static final String PLATFORM_MANUFACTURER = "2.23.133.2.4"; private static final String PLATFORM_MODEL = "2.23.133.2.5"; private static final String PLATFORM_VERSION = "2.23.133.2.6"; private static final String PLATFORM_SERIAL = "2.23.133.2.23"; private static final String PLATFORM_BASEBOARD_CHASSIS_COMBINED = "2.23.133.5.1.6"; + // OID for TCG Platform Class Common Attributes private static final String PLATFORM_MANUFACTURER_2_0 = "2.23.133.5.1.1"; private static final String PLATFORM_MODEL_2_0 = "2.23.133.5.1.4"; private static final String PLATFORM_VERSION_2_0 = "2.23.133.5.1.5"; private static final String PLATFORM_SERIAL_2_0 = "2.23.133.5.1.6"; + // OID for Certificate Attributes private static final String TCG_PLATFORM_SPECIFICATION = "2.23.133.2.17"; private static final String TPM_SECURITY_ASSERTION = "2.23.133.2.18"; @@ -582,8 +588,7 @@ public Map getAllAttributes() break; default: // No class defined for this attribute - log.warn("No class defined for attribute with OID: " - + attr.getAttrType().getId()); + log.warn("No class defined for attribute with OID: {}", attr.getAttrType().getId()); break; } } @@ -621,6 +626,24 @@ && getAttribute("platformConfiguration") instanceof PlatformConfiguration) { return null; } + /** + * Get the Version 2 Platform Configuration Attribute from the Platform Certificate. + * + * @return a map with the Version 2 Platform Configuration information. + * @throws IllegalArgumentException when there is a parsing error + * @throws IOException when reading the certificate. + */ + public PlatformConfigurationV2 getPlatformConfigurationV2() + throws IllegalArgumentException, IOException { + + if (getAttribute("platformConfiguration") != null + && getAttribute("platformConfiguration") instanceof PlatformConfigurationV2) { + return (PlatformConfigurationV2) getAttribute("platformConfiguration"); + } + + return null; + } + /** * Get the Platform Configuration URI Attribute from the Platform Certificate. * @@ -695,9 +718,27 @@ public List getComponentIdentifiers() { return platformConfig.getComponentIdentifier(); } } catch (IOException e) { - log.error("Unable to parse Platform Configuration from Credential or find" + log.error("Unable to parse Platform Configuration from Platform Credential or find" + "component identifiers"); } return Collections.emptyList(); } + + /** + * Get the list of version 2 component identifiers if there are any. + * + * @return the list of version 2 component identifiers if there are any + */ + public List getComponentIdentifiersV2() { + try { + PlatformConfigurationV2 platformConfigV2 = getPlatformConfigurationV2(); + if (platformConfigV2 != null) { + return platformConfigV2.getComponentIdentifierV2(); + } + } catch (IOException e) { + log.error("Unable to parse Platform Configuration Version 2 from Platform Credential or find" + + "version 2 component identifiers"); + } + return Collections.emptyList(); + } } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java index ab4683d1a..95684d3aa 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java @@ -33,6 +33,10 @@ private static final String SMBIOS_COMPONENT_REGISTRY = "2.23.133.18.3.3"; + private static final String PCIE_BASED_COMPONENT_REGISTRY = "2.23.133.18.3.4"; + + private static final String STORAGE_COMPONENT_REGISTRY = "2.23.133.18.3.5"; + private static final Path WINDOWS_JSON_PATH = FileSystems.getDefault().getPath( "C:/", "ProgramData", "hirs", "aca", "default-properties", "component-class.json"); @@ -122,6 +126,8 @@ public ComponentClass(final String registryOid, this.registryType = switch (registryOid) { case TCG_COMPONENT_REGISTRY -> "TCG"; case SMBIOS_COMPONENT_REGISTRY -> "SMBIOS"; + case PCIE_BASED_COMPONENT_REGISTRY -> "PCIE"; + case STORAGE_COMPONENT_REGISTRY -> "STORAGE"; default -> UNKNOWN_STRING; }; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfiguration.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfiguration.java index 9680dc926..6622aa1c0 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfiguration.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfiguration.java @@ -14,11 +14,15 @@ */ @AllArgsConstructor public abstract class PlatformConfiguration { - private ArrayList componentIdentifier = new ArrayList<>(); + + private List componentIdentifier; + @Getter @Setter private URIReference componentIdentifierUri; - private ArrayList platformProperties = new ArrayList<>(); + + private List platformProperties; + @Getter @Setter private URIReference platformPropertiesUri; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java index 58dd341d1..8e2a4c176 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java @@ -6,6 +6,8 @@ import org.bouncycastle.asn1.ASN1TaggedObject; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.stream.Collectors; /** @@ -26,9 +28,10 @@ public class PlatformConfigurationV2 extends PlatformConfiguration { private static final int COMPONENT_IDENTIFIER_URI = 1; private static final int PLATFORM_PROPERTIES = 2; private static final int PLATFORM_PROPERTIES_URI = 3; + private List componentIdentifierV2; /** - * Constructor given the SEQUENCE that contains Platform Configuration. + * Constructor given the SEQUENCE that contains version 2 Platform Configuration. * * @param sequence containing the the Platform Configuration. * @throws IllegalArgumentException if there was an error on the parsing @@ -87,6 +90,21 @@ public PlatformConfigurationV2(final ASN1Sequence sequence) throws IllegalArgume } } + /** + * @return a collection of version 2 component identifiers. + */ + public List getComponentIdentifierV2() { + return Collections.unmodifiableList(componentIdentifierV2); + } + + /** + * @param componentIdentifierV2 list of version 2 component identifiers + */ + public void setComponentIdentifierV2( + final List componentIdentifierV2) { + this.componentIdentifierV2 = new ArrayList<>(componentIdentifierV2); + } + /** * Creates a string representation of the Platform Configuration V2 object. * @@ -96,9 +114,9 @@ public PlatformConfigurationV2(final ASN1Sequence sequence) throws IllegalArgume public String toString() { StringBuilder sb = new StringBuilder(); sb.append("PlatformConfiguration{"); - sb.append("componentIdentifier="); - if (getComponentIdentifier().size() > 0) { - sb.append(getComponentIdentifier() + sb.append("componentIdentifierV2="); + if (!getComponentIdentifierV2().isEmpty()) { + sb.append(getComponentIdentifierV2() .stream() .map(Object::toString) .collect(Collectors.joining(","))); @@ -108,7 +126,7 @@ public String toString() { sb.append(getComponentIdentifierUri()); } sb.append(", platformProperties="); - if (getPlatformProperties().size() > 0) { + if (!getPlatformProperties().isEmpty()) { sb.append(getPlatformProperties() .stream() .map(Object::toString) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java index af9464ca2..4f5a34f81 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java @@ -80,8 +80,7 @@ public static AppraisalStatus validatePlatformCredentialAttributesV1p2( deviceBaseboardSerialNumber = null; } else { deviceInfoSerialNumbers.put("board serial number", deviceBaseboardSerialNumber); - log.info("Using device board serial number for validation: " - + deviceBaseboardSerialNumber); + log.info("Using device board serial number for validation: {}", deviceBaseboardSerialNumber); } if (StringUtils.isEmpty(deviceChassisSerialNumber) @@ -89,16 +88,15 @@ public static AppraisalStatus validatePlatformCredentialAttributesV1p2( log.error("Failed to retrieve device chassis serial number"); } else { deviceInfoSerialNumbers.put("chassis serial number", deviceChassisSerialNumber); - log.info("Using device chassis serial number for validation: " - + deviceChassisSerialNumber); + log.info("Using device chassis serial number for validation: {}", deviceChassisSerialNumber); } + if (StringUtils.isEmpty(deviceSystemSerialNumber) || DeviceInfoEnums.NOT_SPECIFIED.equalsIgnoreCase(deviceSystemSerialNumber)) { log.error("Failed to retrieve device system serial number"); } else { deviceInfoSerialNumbers.put("system serial number", deviceSystemSerialNumber); - log.info("Using device system serial number for validation: " - + deviceSystemSerialNumber); + log.info("Using device system serial number for validation: {}", deviceSystemSerialNumber); } AppraisalStatus status; @@ -233,12 +231,19 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0( passesValidation &= fieldValidation; - // Retrieve the list of all components from the Platform Credential - List allPcComponents - = new ArrayList<>(platformCredential.getComponentIdentifiers()); + // Retrieve the list of all version 2 component identifiers from the Platform Credential + List allPcComponents + = new ArrayList<>(platformCredential.getComponentIdentifiersV2()); // All components listed in the Platform Credential must have a manufacturer and model - for (ComponentIdentifier pcComponent : allPcComponents) { + for (ComponentIdentifierV2 pcComponent : allPcComponents) { + + fieldValidation = pcComponent.getComponentClass() != null; + + if (!fieldValidation) { + resultMessage.append("Component class is null\n"); + } + fieldValidation = !hasEmptyValueForRequiredField("componentManufacturer", pcComponent.getComponentManufacturer()); @@ -263,18 +268,24 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0( .findByCertificateSerialNumberAndBoardSerialNumber( platformCredential.getSerialNumber().toString(), platformCredential.getPlatformSerial()); + // first create hash map based on hashCode List remainingComponentResults = checkDeviceHashMap( componentInfos, componentResults); + //this is used to get a unique count List componentIdList = new ArrayList<>(); + int numOfAttributes = 0; + if (!remainingComponentResults.isEmpty()) { List attributeResults = checkComponentClassMap( componentInfos, remainingComponentResults); numOfAttributes = attributeResults.size(); + boolean saveAttributeResult; + for (ComponentAttributeResult componentAttributeResult : attributeResults) { saveAttributeResult = true; if (ignoreRevisionAttribute) { @@ -293,6 +304,7 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0( } StringBuilder additionalInfo = new StringBuilder(); + if (numOfAttributes > 0) { resultMessage.append(String.format("There are %d component(s) not matched%n " + "with %d total attributes mismatched.", @@ -455,7 +467,7 @@ && isMatch(cId, cInfo)) { if (ci.isVersion2() && PciIds.DB.isReady()) { ci = AcaPciIds.translate((ComponentIdentifierV2) ci); } - log.error("Unmatched component: " + ci); + log.error("Unmatched component: {}", ci); fullDeltaChainComponents.add(ci); invalidPcIds.append(String.format( "Manufacturer=%s, Model=%s, Serial=%s, Revision=%s;%n", @@ -532,6 +544,7 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc = allDeviceInfoComponents.stream().filter(componentInfo -> componentInfo.getComponentManufacturer().equals(pcManufacturer)) .collect(Collectors.toList()); + // For each component listed in the platform credential from this manufacturer // find the ones that specify a serial number so we can match the most specific ones // first. @@ -539,7 +552,8 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc = pcComponentsFromManufacturer.stream().filter(compIdentifier -> compIdentifier.getComponentSerial() != null && StringUtils.isNotEmpty(compIdentifier.getComponentSerial().getString())) - .collect(Collectors.toList()); + .toList(); + // Now match up the components from the device info that are from the same // manufacturer and have a serial number. As matches are found, remove them from // both lists. @@ -567,7 +581,7 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc = pcComponentsFromManufacturer.stream().filter(compIdentifier -> compIdentifier.getComponentRevision() != null && StringUtils.isNotEmpty(compIdentifier.getComponentRevision().getString())) - .collect(Collectors.toList()); + .toList(); // Now match up the components from the device info that are from the same // manufacturer and specify a value for the revision field. As matches are found, // remove them from both lists. @@ -608,8 +622,7 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc if (!pcUnmatchedComponents.isEmpty()) { untrimmedPcComponents.clear(); StringBuilder sb = new StringBuilder(); - log.error(String.format("Platform Credential contained %d unmatched components:", - pcUnmatchedComponents.size())); + log.error("Platform Credential contained {} unmatched components:", pcUnmatchedComponents.size()); int unmatchedComponentCounter = 1; for (ComponentIdentifier unmatchedComponent : pcUnmatchedComponents) { @@ -617,8 +630,7 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc unmatchedComponent = AcaPciIds.translate((ComponentIdentifierV2) unmatchedComponent); } - log.error("Unmatched component " + unmatchedComponentCounter++ + ": " - + unmatchedComponent); + log.error("Unmatched component {}: {}", unmatchedComponentCounter++, unmatchedComponent); sb.append(String.format("Manufacturer=%s, Model=%s, Serial=%s, Revision=%s;%n", unmatchedComponent.getComponentManufacturer(), unmatchedComponent.getComponentModel(), @@ -797,8 +809,7 @@ private static boolean optionalPlatformCredentialFieldNullOrMatches( private static boolean hasEmptyValueForRequiredField(final String description, final String fieldValue) { if (StringUtils.isEmpty(fieldValue)) { - log.error("Required field was empty or null in Platform Credential: " - + description); + log.error("Required field was empty or null in Platform Credential: {}", description); return true; } return false; @@ -829,15 +840,15 @@ private static boolean platformCredentialFieldMatches( String trimmedOtherValue = otherValue.trim(); if (!trimmedFieldValue.equals(trimmedOtherValue)) { - log.debug(String.format("%s field in Platform Credential (%s) does not match " - + "a related field in the DeviceInfoReport (%s)", - platformCredentialFieldName, trimmedFieldValue, trimmedOtherValue)); + log.debug("{} field in Platform Credential ({}) does not match " + + "a related field in the DeviceInfoReport ({})", + platformCredentialFieldName, trimmedFieldValue, trimmedOtherValue); return false; } - log.debug(String.format("%s field in Platform Credential matches " - + "a related field in the DeviceInfoReport (%s)", - platformCredentialFieldName, trimmedFieldValue) + log.debug("{} field in Platform Credential matches " + + "a related field in the DeviceInfoReport {}", + platformCredentialFieldName, trimmedFieldValue ); return true; @@ -853,8 +864,7 @@ private static boolean platformCredentialFieldMatches( private static boolean hasEmptyValueForRequiredField(final String description, final ASN1UTF8String fieldValue) { if (fieldValue == null || StringUtils.isEmpty(fieldValue.getString().trim())) { - log.error("Required field was empty or null in Platform Credential: " - + description); + log.error("Required field was empty or null in Platform Credential: {}", description); return true; } return false; @@ -871,7 +881,7 @@ private static List checkDeviceHashMap( final List componentInfos, final List compiledComponentList) { Map> deviceHashMap = new HashMap<>(); - componentInfos.stream().forEach((componentInfo) -> { + componentInfos.forEach((componentInfo) -> { List innerList; Integer compInfoHash = componentInfo.hashCommonElements(); if (deviceHashMap.containsKey(compInfoHash)) { @@ -910,7 +920,7 @@ private static List checkComponentClassMap( // continue down the options, move to a different method. // create component class mapping to component info Map> componentDeviceMap = new HashMap<>(); - componentInfos.stream().forEach((componentInfo) -> { + componentInfos.forEach((componentInfo) -> { List innerList; String componentClass = componentInfo.getComponentClass(); if (componentDeviceMap.containsKey(componentClass)) { @@ -1000,11 +1010,13 @@ private static List generateComponentAttributeResults( private static List findMismatchedValues( final List componentClassInfo, final ComponentResult componentResult) { + // this list only has those of the same class type Map componentSerialMap = new HashMap<>(); - componentClassInfo.stream().forEach((componentInfo) -> { + componentClassInfo.forEach((componentInfo) -> { componentSerialMap.put(componentInfo.getComponentSerial(), componentInfo); }); + // see if the serial exists ComponentInfo componentInfo = componentSerialMap.get(componentResult.getSerialNumber()); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java index 722f9b486..64f35ca4f 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java @@ -35,7 +35,7 @@ public class CredentialValidator extends SupplyChainCredentialValidator { * * @param ec the endorsement credential to verify. * @param trustStore trust store holding trusted certificates. - * @param acceptExpired whether or not to accept expired and not yet valid certificates + * @param acceptExpired whether to accept expired and not yet valid certificates * as valid. * @return the result of the validation. */ diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java index 7384e4b5f..278d2a8e2 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java @@ -415,14 +415,13 @@ private static InetAddress getTestIpAddress() { * Checks if the ST Micro Endorsement Credential can be validated against the * ST/GlobalSIgn Certificate Chain. * - * @throws IOException if error occurs while reading files - * @throws URISyntaxException if error occurs while reading files - * @throws CertificateException if error occurs while processing X509 Certs - * @throws KeyStoreException if error occurs while processing Keystore + * @throws IOException if error occurs while reading files + * @throws URISyntaxException if error occurs while reading files + * @throws KeyStoreException if error occurs while processing Keystore */ @Test public final void testValidateEndorsementCredential() - throws URISyntaxException, IOException, CertificateException, KeyStoreException { + throws URISyntaxException, IOException, KeyStoreException { EndorsementCredential ekcert = new EndorsementCredential(Files.readAllBytes( Paths.get(Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI())) @@ -455,14 +454,13 @@ public final void testValidateEndorsementCredential() * Validates a generated cert chain pretending to be from Intel. Credential was generated * with an intermediate CA. This tests the entire chain of validation back to the root CA. * - * @throws IOException if error occurs while reading files - * @throws KeyStoreException if there's an issue string certs to the keystore - * @throws CertificateException if error occurs while ingesting a certificate - * @throws URISyntaxException if a URI can't be processed + * @throws IOException if error occurs while reading files + * @throws KeyStoreException if there's an issue string certs to the keystore + * @throws URISyntaxException if a URI can't be processed */ @Test public final void validateIntelPlatformCredentials() - throws URISyntaxException, IOException, CertificateException, KeyStoreException { + throws URISyntaxException, IOException, KeyStoreException { Certificate intermediatecacert = new CertificateAuthorityCredential(Files.readAllBytes(Paths.get( @@ -855,7 +853,7 @@ public final void verifyX509AttributeCertificateAgainstIntermediate() KeyPair caKeyPair = createKeyPair(); KeyPair intermediateKeyPair = createKeyPair(); KeyPair targetKeyPair = createKeyPair(); - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); X509Certificate caCert = createSelfSignedCertificate(caKeyPair); X509Certificate intermediateCert = @@ -899,7 +897,7 @@ public final void verifyX509AttributeCertificateFailsIfSigningCertNotInList() KeyPair caKeyPair = createKeyPair(); KeyPair intermediateKeyPair = createKeyPair(); KeyPair targetKeyPair = createKeyPair(); - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); X509Certificate caCert = createSelfSignedCertificate(caKeyPair); X509Certificate intermediateCert = @@ -938,7 +936,7 @@ public final void verifyX509AttributeCertificateAgainstCA() throws SupplyChainValidatorException { KeyPair caKeyPair = createKeyPair(); KeyPair targetKeyPair = createKeyPair(); - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); X509Certificate caCert = createSelfSignedCertificate(caKeyPair); X509Certificate targetCert = @@ -977,7 +975,7 @@ public final void verifyX509CertificateAgainstIntermediate() KeyPair caKeyPair = createKeyPair(); KeyPair intermediateKeyPair = createKeyPair(); KeyPair targetKeyPair = createKeyPair(); - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); X509Certificate caCert = createSelfSignedCertificate(caKeyPair); X509Certificate intermediateCert = @@ -1017,7 +1015,7 @@ public final void verifyX509CertificateFailsIfSigningCertNotInList() KeyPair caKeyPair = createKeyPair(); KeyPair intermediateKeyPair = createKeyPair(); KeyPair targetKeyPair = createKeyPair(); - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); X509Certificate caCert = createSelfSignedCertificate(caKeyPair); X509Certificate intermediateCert = @@ -1051,7 +1049,7 @@ public final void verifyX509CertificateFailsIfSigningCertNotInList() public final void verifyX509CertificateAgainstCA() throws SupplyChainValidatorException { KeyPair caKeyPair = createKeyPair(); KeyPair targetKeyPair = createKeyPair(); - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); X509Certificate caCert = createSelfSignedCertificate(caKeyPair); X509Certificate targetCert = @@ -1175,13 +1173,12 @@ public final void verifyPlatformCredentialNullDeviceInfoReport() * * @throws URISyntaxException failed to read certificate * @throws IOException failed to read certificate - * @throws KeyStoreException failed to read key store * @throws SupplyChainValidatorException missing credential */ @Test public final void testPlatformDnEquals() throws URISyntaxException, IOException, - KeyStoreException, SupplyChainValidatorException { + SupplyChainValidatorException { Certificate signingCert; signingCert = new CertificateAuthorityCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(INTEL_SIGNING_KEY)).toURI())) @@ -1207,12 +1204,11 @@ public final void testPlatformDnEquals() throws URISyntaxException, IOException, * * @throws URISyntaxException failed to read certificate * @throws IOException failed to read certificate - * @throws KeyStoreException failed to read key store * @throws SupplyChainValidatorException missing credential */ @Test public final void testPlatformDnNotEquals() throws URISyntaxException, IOException, - KeyStoreException, SupplyChainValidatorException { + SupplyChainValidatorException { Certificate signingCert; signingCert = new CertificateAuthorityCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(INTEL_INT_CA)).toURI())) @@ -1237,12 +1233,11 @@ public final void testPlatformDnNotEquals() throws URISyntaxException, IOExcepti * * @throws URISyntaxException failed to read certificate * @throws IOException failed to read certificate - * @throws KeyStoreException failed to read key store * @throws SupplyChainValidatorException missing credential */ @Test public final void testEndorsementDnEquals() throws URISyntaxException, IOException, - KeyStoreException, SupplyChainValidatorException { + SupplyChainValidatorException { Certificate signingCert; signingCert = new CertificateAuthorityCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(INT_CA_CERT02)).toURI())) @@ -1268,12 +1263,11 @@ public final void testEndorsementDnEquals() throws URISyntaxException, IOExcepti * * @throws URISyntaxException failed to read certificate * @throws IOException failed to read certificate - * @throws KeyStoreException failed to read key store * @throws SupplyChainValidatorException missing credential */ @Test public final void testEndorsementDnNotEquals() throws URISyntaxException, IOException, - KeyStoreException, SupplyChainValidatorException { + SupplyChainValidatorException { Certificate signingCert; signingCert = new CertificateAuthorityCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(INTEL_INT_CA)).toURI())) From 9e94a527af250eaa3c3e27d31a7b5a48340614a5 Mon Sep 17 00:00:00 2001 From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com> Date: Thu, 30 Jan 2025 17:20:08 -0500 Subject: [PATCH 02/14] issue_896: Added more javadocs, still going through the process and figuring out places where this will work. Can successfully debug provisioner+aca. --- ...estfulAttestationCertificateAuthority.java | 2 +- .../persist/provision/AbstractProcessor.java | 4 +++- .../provision/IdentityClaimProcessor.java | 24 ++++++++++++++++--- .../CertificateAttributeScvValidator.java | 10 ++++---- .../SupplyChainCredentialValidator.java | 2 +- 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java index db00267de..1cc403028 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java @@ -108,7 +108,7 @@ public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim) * the client's desired attestation key, if the correct nonce is supplied. * * @param certificateRequest request containing nonce from earlier identity - * * claim handshake + * claim handshake * @return The response to the client provisioner. */ @Override diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java index 087f4be1b..64e567b53 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java @@ -159,6 +159,7 @@ protected EndorsementCredential parseEcFromIdentityClaim( final ProvisionerTpm2.IdentityClaim identityClaim, final PublicKey ekPub, final CertificateRepository certificateRepository) { EndorsementCredential endorsementCredential = null; + if (identityClaim.hasEndorsementCredential()) { endorsementCredential = CredentialManagementHelper.storeEndorsementCredential( certificateRepository, @@ -172,6 +173,7 @@ protected EndorsementCredential parseEcFromIdentityClaim( log.warn("No endorsement credential was received in identity claim and no EK Public" + " Key was provided to check for uploaded certificates."); } + return endorsementCredential; } @@ -254,7 +256,7 @@ private EndorsementCredential getEndorsementCredential( * @param endorsementCredential the endorsement credential used to generate the AC * @param platformCredentials the platform credentials used to generate the AC * @param device the device to which the attestation certificate is tied - * @param ldevID whether the certificate is a ldevid + * @param ldevID whether the certificate is a ldevid * @return whether the certificate was saved successfully * @throws {@link CertificateProcessingException} if error occurs in persisting the Attestation * Certificate diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java index cbe87597d..c63b4e36a 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java @@ -215,6 +215,7 @@ private AppraisalStatus.Status doSupplyChainValidation( // device.getDeviceInfo().setPaccorOutputString(claim.getPaccorOutput()); handleDeviceComponents(device.getDeviceInfo().getNetworkInfo().getHostname(), claim.getPaccorOutput()); + // There are situations in which the claim is sent with no PCs // or a PC from the tpm which will be deprecated // this is to check what is in the platform object and pull @@ -230,6 +231,7 @@ private AppraisalStatus.Status doSupplyChainValidation( platformCredentials.addAll(tempList); } + // store component results objects for (PlatformCredential platformCredential : platformCredentials) { List componentResults = componentResultRepository @@ -239,7 +241,7 @@ private AppraisalStatus.Status doSupplyChainValidation( if (componentResults.isEmpty()) { savePlatformComponents(platformCredential); } else { - componentResults.stream().forEach((componentResult) -> { + componentResults.forEach((componentResult) -> { componentResult.restore(); componentResult.resetCreateTime(); componentResultRepository.save(componentResult); @@ -256,9 +258,16 @@ private AppraisalStatus.Status doSupplyChainValidation( AppraisalStatus.Status validationResult = summary.getOverallValidationResult(); device.setSupplyChainValidationStatus(validationResult); this.deviceRepository.save(device); + return validationResult; } + /** + * Helper method that utilizes the identity claim to produce a device info report. + * + * @param claim identity claim + * @return device info + */ private Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) { DeviceInfoReport deviceInfoReport = null; @@ -620,7 +629,7 @@ private boolean generateDigestRecords(final String manufacturer, final String mo .findByManufacturerAndModel(manufacturer, model); Map digestValueMap = new HashMap<>(); - expectedValues.stream().forEach((rdv) -> { + expectedValues.forEach((rdv) -> { digestValueMap.put(rdv.getDigestValue(), rdv); }); @@ -728,6 +737,13 @@ private void savePlatformComponents(final Certificate certificate) { } } + /** + * Helper method that attempts to find all the provided device's components. + * + * @param hostName device's host name + * @param paccorString + * @return number of components + */ private int handleDeviceComponents(final String hostName, final String paccorString) { int deviceComponents = 0; Map componentInfoMap = new HashMap<>(); @@ -735,9 +751,11 @@ private int handleDeviceComponents(final String hostName, final String paccorStr List componentInfos = SupplyChainCredentialValidator .getComponentInfoFromPaccorOutput(hostName, paccorString); + deviceComponents = componentInfos.size(); + // check the DB for like component infos List dbComponentInfos = this.componentInfoRepository.findByDeviceName(hostName); - dbComponentInfos.stream().forEach((infos) -> { + dbComponentInfos.forEach((infos) -> { componentInfoMap.put(infos.hashCode(), infos); }); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java index 4f5a34f81..532f77189 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java @@ -238,11 +238,11 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0( // All components listed in the Platform Credential must have a manufacturer and model for (ComponentIdentifierV2 pcComponent : allPcComponents) { - fieldValidation = pcComponent.getComponentClass() != null; - - if (!fieldValidation) { - resultMessage.append("Component class is null\n"); - } +// fieldValidation = pcComponent.getComponentClass() != null; +// +// if (!fieldValidation) { +// resultMessage.append("Component class is null\n"); +// } fieldValidation = !hasEmptyValueForRequiredField("componentManufacturer", pcComponent.getComponentManufacturer()); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java index 914ac968c..bb9181d14 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java @@ -270,7 +270,7 @@ public static String validateCertChain(final X509Certificate cert, * Parses the output from PACCOR's allcomponents.sh script into ComponentInfo objects. * * @param hostName the host machine associated with the component - * @param paccorOutput the output from PACCOR's allcomoponents.sh + * @param paccorOutput the output from PACCOR's allcomponents.sh * @return a list of ComponentInfo objects built from paccorOutput * @throws java.io.IOException if something goes wrong parsing the JSON */ From 2f96fb0606bc9d3fd28311ec57481d72752394d1 Mon Sep 17 00:00:00 2001 From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com> Date: Fri, 31 Jan 2025 18:28:32 -0500 Subject: [PATCH 03/14] issue_896: slowly introducing component identifier v2 into multiple spots throughout out the app. Seems like we need to ensure that when we try to parse the pc from the identity claim, it needs to recognize the new kind of identifier. --- .../certificate/ComponentResult.java | 55 +++++-- .../certificate/PlatformCredential.java | 3 + .../attributes/V2/ComponentIdentifierV2.java | 2 +- .../V2/PlatformConfigurationV2.java | 2 +- .../persist/provision/AbstractProcessor.java | 14 +- .../provision/IdentityClaimProcessor.java | 78 +++++++--- .../CertificatePageController.java | 145 ++++++++++-------- 7 files changed, 194 insertions(+), 105 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ComponentResult.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ComponentResult.java index 01eef415a..85e44478f 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ComponentResult.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ComponentResult.java @@ -121,23 +121,46 @@ public ComponentResult(final String boardSerialNumber, final String certificateS element.getAddressValue().toString())); } componentAddress = sb.toString(); + } + + /** + * @param boardSerialNumber + * @param certificateSerialNumber + * @param certificateType + * @param componentIdentifierV2 + */ + public ComponentResult(final String boardSerialNumber, final String certificateSerialNumber, + final String certificateType, + final ComponentIdentifierV2 componentIdentifierV2) { + + this.boardSerialNumber = boardSerialNumber; + this.certificateSerialNumber = certificateSerialNumber; + this.certificateType = certificateType; + this.manufacturer = componentIdentifierV2.getComponentManufacturer().toString(); + this.model = componentIdentifierV2.getComponentModel().toString(); + this.serialNumber = componentIdentifierV2.getComponentSerial().toString(); + this.revisionNumber = componentIdentifierV2.getComponentRevision().toString(); + if (componentIdentifierV2.getFieldReplaceable() != null) { + this.fieldReplaceable = componentIdentifierV2.getFieldReplaceable().isTrue(); + } + + StringBuilder sb = new StringBuilder(); + for (ComponentAddress element : componentIdentifierV2.getComponentAddress()) { + sb.append(String.format("%s:%s;", element.getAddressTypeValue(), + element.getAddressValue().toString())); + } + componentAddress = sb.toString(); - // V2 fields - if (componentIdentifier.isVersion2() - && componentIdentifier instanceof ComponentIdentifierV2 ciV2) { - // this is a downside of findbugs, the code is set up to indicate if a CI is V2 or not - // but find bugs is throwing a flag because instanceof isn't being used. - this.componentClassValue = ciV2.getComponentClass().getComponentIdentifier(); - this.componentClassStr = ciV2.getComponentClass().toString(); - this.componentClassType = ciV2.getComponentClass().getRegistryType(); - this.attributeStatus = ciV2.getAttributeStatus(); - this.version2 = true; - if (ciV2.getCertificateIdentifier() != null) { - this.issuerDN = ciV2.getCertificateIdentifier().getIssuerDN().toString(); - if (ciV2.getComponentPlatformUri() != null) { - this.uniformResourceIdentifier = ciV2.getComponentPlatformUri() - .getUniformResourceIdentifier().toString(); - } + this.componentClassValue = componentIdentifierV2.getComponentClass().getComponentIdentifier(); + this.componentClassStr = componentIdentifierV2.getComponentClass().toString(); + this.componentClassType = componentIdentifierV2.getComponentClass().getRegistryType(); + this.attributeStatus = componentIdentifierV2.getAttributeStatus(); + this.version2 = true; + if (componentIdentifierV2.getCertificateIdentifier() != null) { + this.issuerDN = componentIdentifierV2.getCertificateIdentifier().getIssuerDN().toString(); + if (componentIdentifierV2.getComponentPlatformUri() != null) { + this.uniformResourceIdentifier = componentIdentifierV2.getComponentPlatformUri() + .getUniformResourceIdentifier().toString(); } } } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java index d8ce5315f..201f45e25 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java @@ -355,6 +355,9 @@ public boolean isSignatureValid(final ContentVerifierProvider verifierProvider) return verifier.verify(attCert.getSignatureValue().getOctets()); } + /** + * @throws IOException + */ private void parseFields() throws IOException { AttributeCertificateInfo certificate = getAttributeCertificate().getAcinfo(); Map policyQualifier = getPolicyQualifier(certificate); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java index e7b4aa5b9..633f40c80 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java @@ -239,7 +239,7 @@ public String toString() { sb.append(getFieldReplaceable()); } sb.append(", componentAddress="); - if (getComponentAddress().size() > 0) { + if (!getComponentAddress().isEmpty()) { sb.append(getComponentAddress() .stream() .map(Object::toString) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java index 8e2a4c176..71f6026d2 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java @@ -38,7 +38,7 @@ public class PlatformConfigurationV2 extends PlatformConfiguration { */ public PlatformConfigurationV2(final ASN1Sequence sequence) throws IllegalArgumentException { //Default values - setComponentIdentifier(new ArrayList<>()); + setComponentIdentifierV2(new ArrayList<>()); setComponentIdentifierUri(null); setPlatformProperties(new ArrayList<>()); setPlatformPropertiesUri(null); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java index 64e567b53..9b56ba374 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java @@ -193,6 +193,7 @@ protected List parsePcsFromIdentityClaim( final EndorsementCredential endorsementCredential, final CertificateRepository certificateRepository) { List platformCredentials = new LinkedList<>(); + if (identityClaim.getPlatformCredentialCount() > 0) { for (ByteString platformCredential : identityClaim.getPlatformCredentialList()) { if (!platformCredential.isEmpty()) { @@ -208,6 +209,7 @@ protected List parsePcsFromIdentityClaim( } else { log.warn("No platform credential received in identity claim."); } + return platformCredentials; } @@ -221,7 +223,7 @@ protected List parsePcsFromIdentityClaim( private EndorsementCredential getEndorsementCredential( final PublicKey ekPublicKey, final CertificateRepository certificateRepository) { - log.debug("Searching for endorsement credential based on public key: " + ekPublicKey); + log.debug("Searching for endorsement credential based on public key: {}", ekPublicKey); if (ekPublicKey == null) { throw new IllegalArgumentException("Cannot look up an EC given a null public key"); @@ -258,8 +260,6 @@ private EndorsementCredential getEndorsementCredential( * @param device the device to which the attestation certificate is tied * @param ldevID whether the certificate is a ldevid * @return whether the certificate was saved successfully - * @throws {@link CertificateProcessingException} if error occurs in persisting the Attestation - * Certificate */ public boolean saveAttestationCertificate(final CertificateRepository certificateRepository, final byte[] derEncodedAttestationCertificate, @@ -288,7 +288,7 @@ public boolean saveAttestationCertificate(final CertificateRepository certificat generateCertificate = ldevID ? policySettings.isIssueDevIdCertificate() : policySettings.isIssueAttestationCertificate(); - if (issuedAc != null && issuedAc.size() > 0 + if (issuedAc != null && !issuedAc.isEmpty() && (ldevID ? policySettings.isDevIdExpirationFlag() : policySettings.isGenerateOnExpiration())) { if (issuedAc.get(0).getEndValidity().after(currentDate)) { @@ -324,13 +324,13 @@ private List getPlatformCredentials(final CertificateReposit if (ec == null) { log.warn("Cannot look for platform credential(s). Endorsement credential was null."); } else { - log.debug("Searching for platform credential(s) based on holder serial number: " - + ec.getSerialNumber()); + log.debug("Searching for platform credential(s) based on holder serial number: {}", + ec.getSerialNumber()); credentials = certificateRepository.getByHolderSerialNumber(ec.getSerialNumber()); if (credentials == null || credentials.isEmpty()) { log.warn("No platform credential(s) found"); } else { - log.debug("Platform Credential(s) found: " + credentials.size()); + log.debug("Platform Credential(s) found: {}", credentials.size()); } } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java index c63b4e36a..065a6e305 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java @@ -20,6 +20,7 @@ import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; 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.V2.ComponentIdentifierV2; import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo; import hirs.attestationca.persist.entity.userdefined.info.FirmwareInfo; import hirs.attestationca.persist.entity.userdefined.info.HardwareInfo; @@ -156,6 +157,7 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) { } ByteString blobStr = ByteString.copyFrom(new byte[] {}); + if (validationResult == AppraisalStatus.Status.PASS) { RSAPublicKey akPub = ProvisionUtils.parsePublicKey(claim.getAkPublicArea().toByteArray()); byte[] nonce = ProvisionUtils.generateRandomBytes(NONCE_LENGTH); @@ -173,12 +175,14 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) { if (policySettings != null && policySettings.isIgnoreImaEnabled()) { pcrQuoteMask = PCR_QUOTE_MASK.replace("10,", ""); } + // Package response ProvisionerTpm2.IdentityClaimResponse response = ProvisionerTpm2.IdentityClaimResponse.newBuilder() .setCredentialBlob(blobStr).setPcrMask(pcrQuoteMask) .setStatus(ProvisionerTpm2.ResponseStatus.PASS) .build(); + return response.toByteArray(); } else { log.error("Supply chain validation did not succeed. Result is: {}", validationResult); @@ -201,6 +205,7 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) { */ private AppraisalStatus.Status doSupplyChainValidation( final ProvisionerTpm2.IdentityClaim claim, final PublicKey ekPub) { + // attempt to find an endorsement credential to validate EndorsementCredential endorsementCredential = parseEcFromIdentityClaim(claim, ekPub, certificateRepository); @@ -238,6 +243,7 @@ private AppraisalStatus.Status doSupplyChainValidation( .findByCertificateSerialNumberAndBoardSerialNumber( platformCredential.getSerialNumber().toString(), platformCredential.getPlatformSerial()); + if (componentResults.isEmpty()) { savePlatformComponents(platformCredential); } else { @@ -254,6 +260,7 @@ private AppraisalStatus.Status doSupplyChainValidation( endorsementCredential, platformCredentials, device, componentInfoRepository.findByDeviceName(device.getName())); device.setSummaryId(summary.getId().toString()); + // update the validation result in the device AppraisalStatus.Status validationResult = summary.getOverallValidationResult(); device.setSupplyChainValidationStatus(validationResult); @@ -284,13 +291,16 @@ private Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) { } log.info("Processing Device Info Report"); + // store device and device info report. Device device = null; + if (deviceInfoReport.getNetworkInfo() != null && deviceInfoReport.getNetworkInfo().getHostname() != null && !deviceInfoReport.getNetworkInfo().getHostname().isEmpty()) { device = this.deviceRepository.findByName(deviceInfoReport.getNetworkInfo().getHostname()); } + if (device == null) { device = new Device(deviceInfoReport); } @@ -329,6 +339,7 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim cla macAddressBytes[i] = hex.byteValue(); } } + NetworkInfo nw = new NetworkInfo(nwProto.getHostname(), ip, macAddressBytes); // Get firmware info @@ -343,16 +354,19 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim cla // Get hardware info ProvisionerTpm2.HardwareInfo hwProto = dv.getHw(); + // Make sure chassis info has at least one chassis String firstChassisSerialNumber = DeviceInfoEnums.NOT_SPECIFIED; if (hwProto.getChassisInfoCount() > 0) { firstChassisSerialNumber = hwProto.getChassisInfo(0).getSerialNumber(); } + // Make sure baseboard info has at least one baseboard String firstBaseboardSerialNumber = DeviceInfoEnums.NOT_SPECIFIED; if (hwProto.getBaseboardInfoCount() > 0) { firstBaseboardSerialNumber = hwProto.getBaseboardInfo(0).getSerialNumber(); } + HardwareInfo hw = new HardwareInfo(hwProto.getManufacturer(), hwProto.getProductName(), hwProto.getProductVersion(), hwProto.getSystemSerialNumber(), firstChassisSerialNumber, firstBaseboardSerialNumber); @@ -618,6 +632,14 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim cla return dvReport; } + /** + * Helper method that generates digest records using the provided device's manufacturer and model + * information. + * + * @param manufacturer device manufacturer + * @param model device model + * @return boolean that represents that status of the digest records generation + */ private boolean generateDigestRecords(final String manufacturer, final String model) { List rdValues = new LinkedList<>(); SupportReferenceManifest baseSupportRim = null; @@ -718,21 +740,46 @@ private boolean generateDigestRecords(final String manufacturer, final String mo return true; } + /** + * Helper method that saves the provided platform certificate's components in the database. + * + * @param certificate certificate + */ private void savePlatformComponents(final Certificate certificate) { PlatformCredential platformCredential; + if (certificate instanceof PlatformCredential) { platformCredential = (PlatformCredential) certificate; ComponentResult componentResult; - for (ComponentIdentifier componentIdentifier : platformCredential - .getComponentIdentifiers()) { - - componentResult = new ComponentResult(platformCredential.getPlatformSerial(), - platformCredential.getSerialNumber().toString(), - platformCredential.getPlatformChainType(), - componentIdentifier); - componentResult.setFailedValidation(false); - componentResult.setDelta(!platformCredential.isPlatformBase()); - componentResultRepository.save(componentResult); + + // if the provided platform certificate is version 1.2 + if (platformCredential.getCredentialType().equals(PlatformCredential.CERTIFICATE_TYPE_1_2)) { + + for (ComponentIdentifier componentIdentifier : platformCredential + .getComponentIdentifiers()) { + componentResult = new ComponentResult(platformCredential.getPlatformSerial(), + platformCredential.getSerialNumber().toString(), + platformCredential.getPlatformChainType(), + componentIdentifier); + componentResult.setFailedValidation(false); + componentResult.setDelta(!platformCredential.isPlatformBase()); + componentResultRepository.save(componentResult); + } + + } + // if the provided platform certificate is version 2.0 + else if (platformCredential.getCredentialType() + .equals(PlatformCredential.CERTIFICATE_TYPE_2_0)) { + for (ComponentIdentifierV2 componentIdentifierV2 : platformCredential + .getComponentIdentifiersV2()) { + componentResult = new ComponentResult(platformCredential.getPlatformSerial(), + platformCredential.getSerialNumber().toString(), + platformCredential.getPlatformChainType(), + componentIdentifierV2); + componentResult.setFailedValidation(false); + componentResult.setDelta(!platformCredential.isPlatformBase()); + componentResultRepository.save(componentResult); + } } } } @@ -741,18 +788,15 @@ private void savePlatformComponents(final Certificate certificate) { * Helper method that attempts to find all the provided device's components. * * @param hostName device's host name - * @param paccorString - * @return number of components + * @param paccorString string representation of the paccor tool output */ - private int handleDeviceComponents(final String hostName, final String paccorString) { - int deviceComponents = 0; + private void handleDeviceComponents(final String hostName, final String paccorString) { Map componentInfoMap = new HashMap<>(); + try { List componentInfos = SupplyChainCredentialValidator .getComponentInfoFromPaccorOutput(hostName, paccorString); - deviceComponents = componentInfos.size(); - // check the DB for like component infos List dbComponentInfos = this.componentInfoRepository.findByDeviceName(hostName); dbComponentInfos.forEach((infos) -> { @@ -771,7 +815,5 @@ private int handleDeviceComponents(final String hostName, final String paccorStr } catch (IOException ioEx) { log.warn("Error parsing paccor string"); } - - return deviceComponents; } } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java index 9db752596..a2c37fd12 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java @@ -19,6 +19,7 @@ import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate; 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.V2.ComponentIdentifierV2; import hirs.attestationca.persist.util.CredentialHelper; import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableResponse; @@ -165,21 +166,15 @@ private static Page getCertificatePage(final String certificateType) { * @return the certificate class type */ private static Class getCertificateClass(final String certificateType) { - switch (certificateType) { - case PLATFORMCREDENTIAL: - return PlatformCredential.class; - case ENDORSEMENTCREDENTIAL: - return EndorsementCredential.class; - case ISSUEDCERTIFICATES: - return IssuedAttestationCertificate.class; - case IDEVIDCERTIFICATE: - return IDevIDCertificate.class; - case TRUSTCHAIN: - return CertificateAuthorityCredential.class; - default: - throw new IllegalArgumentException( - String.format("Unknown certificate type: %s", certificateType)); - } + return switch (certificateType) { + case PLATFORMCREDENTIAL -> PlatformCredential.class; + case ENDORSEMENTCREDENTIAL -> EndorsementCredential.class; + case ISSUEDCERTIFICATES -> IssuedAttestationCertificate.class; + case IDEVIDCERTIFICATE -> IDevIDCertificate.class; + case TRUSTCHAIN -> CertificateAuthorityCredential.class; + default -> throw new IllegalArgumentException( + String.format("Unknown certificate type: %s", certificateType)); + }; } /** @@ -312,15 +307,15 @@ public void modify(final CriteriaQuery criteriaQuery) { .findBySerialNumber(pc.getHolderSerialNumber()); if (associatedEC != null) { - log.debug("EC ID for holder s/n " + pc - .getHolderSerialNumber() + " = " + associatedEC.getId()); + log.debug("EC ID for holder s/n {} = {}", pc + .getHolderSerialNumber(), associatedEC.getId()); } pc.setEndorsementCredential(associatedEC); } } - log.debug("Returning list of size: " + records.size()); + log.debug("Returning list of size: {}", records.size()); return new DataTableResponse<>(records, input); } else if (certificateType.equals(ENDORSEMENTCREDENTIAL)) { FilteredRecordsList records = new FilteredRecordsList<>(); @@ -336,7 +331,7 @@ public void modify(final CriteriaQuery criteriaQuery) { records.setRecordsFiltered(endorsementCredentialRepository.findByArchiveFlag(false).size()); - log.debug("Returning list of size: " + records.size()); + log.debug("Returning list of size: {}", records.size()); return new DataTableResponse<>(records, input); } else if (certificateType.equals(TRUSTCHAIN)) { FilteredRecordsList records = new FilteredRecordsList<>(); @@ -352,7 +347,7 @@ public void modify(final CriteriaQuery criteriaQuery) { records.setRecordsFiltered(caCredentialRepository.findByArchiveFlag(false).size()); - log.debug("Returning list of size: " + records.size()); + log.debug("Returning list of size: {}", records.size()); return new DataTableResponse<>(records, input); } else if (certificateType.equals(ISSUEDCERTIFICATES)) { FilteredRecordsList records = new FilteredRecordsList<>(); @@ -384,7 +379,7 @@ public void modify(final CriteriaQuery criteriaQuery) { records.setRecordsFiltered(iDevIDCertificateRepository.findByArchiveFlag(false).size()); - log.debug("Returning list of size: " + records.size()); + log.debug("Returning list of size: {}", records.size()); return new DataTableResponse<>(records, input); } @@ -443,7 +438,7 @@ public RedirectView delete( @PathVariable("certificateType") final String certificateType, @RequestParam final String id, final RedirectAttributes attr) throws URISyntaxException { - log.info("Handling request to delete " + id); + log.info("Handling request to delete {}", id); Map model = new HashMap<>(); PageMessages messages = new PageMessages(); @@ -506,7 +501,7 @@ public RedirectView delete( * @param id the UUID of the cert to download * @param response the response object (needed to update the header with the * file name) - * @throws java.io.IOException when writing to response output stream + * @throws IOException when writing to response output stream */ @RequestMapping(value = "/{certificateType}/download", method = RequestMethod.GET) public void download( @@ -552,7 +547,7 @@ public void download( * * @param response the response object (needed to update the header with the * file name) - * @throws java.io.IOException when writing to response output stream + * @throws IOException when writing to response output stream */ @ResponseBody @RequestMapping(value = "/trust-chain/download-aca-cert", method = RequestMethod.GET) @@ -573,7 +568,7 @@ public void downloadAcaCertificate(final HttpServletResponse response) * * @param response the response object (needed to update the header with the * file name) - * @throws java.io.IOException when writing to response output stream + * @throws IOException when writing to response output stream */ @RequestMapping(value = "/trust-chain/bulk", method = RequestMethod.GET) public void caBulkDownload(final HttpServletResponse response) @@ -605,7 +600,7 @@ public void caBulkDownload(final HttpServletResponse response) * * @param response the response object (needed to update the header with the * file name) - * @throws java.io.IOException when writing to response output stream + * @throws IOException when writing to response output stream */ @RequestMapping(value = "/platform-credentials/bulk", method = RequestMethod.GET) public void pcBulkDownload(final HttpServletResponse response) @@ -637,7 +632,7 @@ public void pcBulkDownload(final HttpServletResponse response) * * @param response the response object (needed to update the header with the * file name) - * @throws java.io.IOException when writing to response output stream + * @throws IOException when writing to response output stream */ @RequestMapping(value = "/issued-certificates/bulk", method = RequestMethod.GET) public void icBulkDownload(final HttpServletResponse response) @@ -670,7 +665,7 @@ public void icBulkDownload(final HttpServletResponse response) * * @param response the response object (needed to update the header with the * file name) - * @throws java.io.IOException when writing to response output stream + * @throws IOException when writing to response output stream */ @RequestMapping(value = "/endorsement-key-credentials/bulk", method = RequestMethod.GET) public void ekBulkDownload(final HttpServletResponse response) @@ -696,6 +691,13 @@ public void ekBulkDownload(final HttpServletResponse response) } } + /** + * @param zipOut + * @param certificates + * @param singleFileName + * @return + * @throws IOException + */ private ZipOutputStream bulkDownload(final ZipOutputStream zipOut, final List certificates, final String singleFileName) throws IOException { @@ -744,26 +746,21 @@ private Certificate getCertificateByHash( final String certificateType, final int certificateHash) { - switch (certificateType) { - case PLATFORMCREDENTIAL: - return this.certificateRepository - .findByCertificateHash(certificateHash, - "PlatformCredential"); - case ENDORSEMENTCREDENTIAL: - return this.certificateRepository - .findByCertificateHash(certificateHash, - "EndorsementCredential"); - case TRUSTCHAIN: - return this.certificateRepository - .findByCertificateHash(certificateHash, - "CertificateAuthorityCredential"); - case IDEVIDCERTIFICATE: - return this.certificateRepository - .findByCertificateHash(certificateHash, - "IDevIDCertificate"); - default: - return null; - } + return switch (certificateType) { + case PLATFORMCREDENTIAL -> this.certificateRepository + .findByCertificateHash(certificateHash, + "PlatformCredential"); + case ENDORSEMENTCREDENTIAL -> this.certificateRepository + .findByCertificateHash(certificateHash, + "EndorsementCredential"); + case TRUSTCHAIN -> this.certificateRepository + .findByCertificateHash(certificateHash, + "CertificateAuthorityCredential"); + case IDEVIDCERTIFICATE -> this.certificateRepository + .findByCertificateHash(certificateHash, + "IDevIDCertificate"); + default -> null; + }; } /** @@ -779,11 +776,9 @@ private List getCertificateByBoardSN( List associatedCertificates = new LinkedList<>(); if (serialNumber != null) { - switch (certificateType) { - case PLATFORMCREDENTIAL: - associatedCertificates.addAll(this.certificateRepository - .byBoardSerialNumber(serialNumber)); - default: + if (certificateType.equals(PLATFORMCREDENTIAL)) { + associatedCertificates.addAll(this.certificateRepository + .byBoardSerialNumber(serialNumber)); } } @@ -1010,6 +1005,11 @@ private void storeCertificate( log.error(failMessage); } + /** + * Helper method that attempts to manage the provided platform certificate's components. + * + * @param certificate certificate + */ private void handlePlatformComponents(final Certificate certificate) { PlatformCredential platformCredential; @@ -1019,17 +1019,38 @@ private void handlePlatformComponents(final Certificate certificate) { .findByCertificateSerialNumberAndBoardSerialNumber( platformCredential.getSerialNumber().toString(), platformCredential.getPlatformSerial()); + if (componentResults.isEmpty()) { ComponentResult componentResult; - for (ComponentIdentifier componentIdentifier : platformCredential - .getComponentIdentifiers()) { - componentResult = new ComponentResult(platformCredential.getPlatformSerial(), - platformCredential.getSerialNumber().toString(), - platformCredential.getPlatformChainType(), - componentIdentifier); - componentResult.setFailedValidation(false); - componentResult.setDelta(!platformCredential.isPlatformBase()); - componentResultRepository.save(componentResult); + + // if the provided platform certificate is version 1.2 + if (platformCredential.getCredentialType().equals(PlatformCredential.CERTIFICATE_TYPE_1_2)) { + + for (ComponentIdentifier componentIdentifier : platformCredential + .getComponentIdentifiers()) { + componentResult = new ComponentResult(platformCredential.getPlatformSerial(), + platformCredential.getSerialNumber().toString(), + platformCredential.getPlatformChainType(), + componentIdentifier); + componentResult.setFailedValidation(false); + componentResult.setDelta(!platformCredential.isPlatformBase()); + componentResultRepository.save(componentResult); + } + } + // if the provided platform certificate is version 2.0 + else if (platformCredential.getCredentialType() + .equals(PlatformCredential.CERTIFICATE_TYPE_2_0)) { + + for (ComponentIdentifierV2 componentIdentifierV2 : platformCredential + .getComponentIdentifiersV2()) { + componentResult = new ComponentResult(platformCredential.getPlatformSerial(), + platformCredential.getSerialNumber().toString(), + platformCredential.getPlatformChainType(), + componentIdentifierV2); + componentResult.setFailedValidation(false); + componentResult.setDelta(!platformCredential.isPlatformBase()); + componentResultRepository.save(componentResult); + } } } else { for (ComponentResult componentResult : componentResults) { From bbe22287ef8ca3f0eeac00ff508b51769c32b427 Mon Sep 17 00:00:00 2001 From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com> Date: Tue, 4 Feb 2025 15:12:05 -0500 Subject: [PATCH 04/14] issue_896: deleted abstract plat form config class, replaced it with plat config v1 (which already exists), moved attribuutes associated with v2 to the v2 class, when validating the aca will now verify if the platform config associated with the cert is v1 or v2. Made corrections to attributes names to better align with tcg docs. --- .../certificate/ComponentResult.java | 22 ++-- .../certificate/PlatformCredential.java | 34 +++--- .../attributes/ComponentAddress.java | 4 +- .../attributes/ComponentIdentifier.java | 22 ++-- .../attributes/PlatformConfiguration.java | 112 ----------------- .../attributes/PlatformConfigurationV1.java | 99 +++++++++++++-- .../attributes/V2/AttributeStatus.java | 2 +- .../attributes/V2/ComponentIdentifierV2.java | 98 ++++++--------- .../V2/PlatformConfigurationV2.java | 115 ++++++++++++++---- .../provision/IdentityClaimProcessor.java | 16 ++- .../service/SupplyChainValidationService.java | 9 +- .../persist/service/ValidationService.java | 2 +- .../attestationca/persist/util/AcaPciIds.java | 6 +- .../CertificateAttributeScvValidator.java | 49 ++++---- .../validation/CredentialValidator.java | 4 +- .../certificate/PlatformCredentialTest.java | 61 +++++----- .../SupplyChainCredentialValidatorTest.java | 8 +- .../CertificatePageController.java | 22 ++-- .../utils/CertificateStringMapBuilder.java | 27 ++-- package/linux/systemd/hirs-aca.service | 2 +- 20 files changed, 370 insertions(+), 344 deletions(-) delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfiguration.java diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ComponentResult.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ComponentResult.java index 85e44478f..5ce0127e5 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ComponentResult.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ComponentResult.java @@ -98,7 +98,7 @@ public class ComponentResult extends ArchivableEntity { * * @param boardSerialNumber associated platform certificate serial number. * @param certificateSerialNumber unique number associated with header info. - * @param certificateType parameter holds version 1.2 or 2.0. + * @param certificateType type of certificate. parameter holds version 1.2 or 2.0. * @param componentIdentifier object with information from the platform certificate components. */ public ComponentResult(final String boardSerialNumber, final String certificateSerialNumber, @@ -116,7 +116,7 @@ public ComponentResult(final String boardSerialNumber, final String certificateS } StringBuilder sb = new StringBuilder(); - for (ComponentAddress element : componentIdentifier.getComponentAddress()) { + for (ComponentAddress element : componentIdentifier.getComponentAddresses()) { sb.append(String.format("%s:%s;", element.getAddressTypeValue(), element.getAddressValue().toString())); } @@ -124,10 +124,10 @@ public ComponentResult(final String boardSerialNumber, final String certificateS } /** - * @param boardSerialNumber - * @param certificateSerialNumber - * @param certificateType - * @param componentIdentifierV2 + * @param boardSerialNumber associated platform certificate serial number + * @param certificateSerialNumber unique number associated with header info + * @param certificateType type of certificate. Parameter holds version 1.2 or 2.0. + * @param componentIdentifierV2 version 2 component identifier */ public ComponentResult(final String boardSerialNumber, final String certificateSerialNumber, final String certificateType, @@ -145,7 +145,7 @@ public ComponentResult(final String boardSerialNumber, final String certificateS } StringBuilder sb = new StringBuilder(); - for (ComponentAddress element : componentIdentifierV2.getComponentAddress()) { + for (ComponentAddress element : componentIdentifierV2.getComponentAddresses()) { sb.append(String.format("%s:%s;", element.getAddressTypeValue(), element.getAddressValue().toString())); } @@ -156,10 +156,10 @@ public ComponentResult(final String boardSerialNumber, final String certificateS this.componentClassType = componentIdentifierV2.getComponentClass().getRegistryType(); this.attributeStatus = componentIdentifierV2.getAttributeStatus(); this.version2 = true; - if (componentIdentifierV2.getCertificateIdentifier() != null) { - this.issuerDN = componentIdentifierV2.getCertificateIdentifier().getIssuerDN().toString(); - if (componentIdentifierV2.getComponentPlatformUri() != null) { - this.uniformResourceIdentifier = componentIdentifierV2.getComponentPlatformUri() + if (componentIdentifierV2.getComponentPlatformCert() != null) { + this.issuerDN = componentIdentifierV2.getComponentPlatformCert().getIssuerDN().toString(); + if (componentIdentifierV2.getComponentPlatformCertUri() != null) { + this.uniformResourceIdentifier = componentIdentifierV2.getComponentPlatformCertUri() .getUniformResourceIdentifier().toString(); } } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java index 201f45e25..03b640147 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java @@ -2,7 +2,6 @@ import com.google.common.base.Preconditions; import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier; -import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfiguration; import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfigurationV1; import hirs.attestationca.persist.entity.userdefined.certificate.attributes.TBBSecurityAssertion; import hirs.attestationca.persist.entity.userdefined.certificate.attributes.URIReference; @@ -261,8 +260,8 @@ public static PlatformCredential parseWithPossibleHeader(final byte[] certificat /** * Verify if the AlgorithmIdentifiers are equal. * - * @param id1 AlgorithIdentifier one - * @param id2 AlgorithIdentifier two + * @param id1 Algorithm Identifier one + * @param id2 Algorithm Identifier two * @return True if are the same, False if not */ public static boolean isAlgIdEqual(final AlgorithmIdentifier id1, @@ -356,7 +355,7 @@ public boolean isSignatureValid(final ContentVerifierProvider verifierProvider) } /** - * @throws IOException + * Parses the Platform Certificate fields. */ private void parseFields() throws IOException { AttributeCertificateInfo certificate = getAttributeCertificate().getAcinfo(); @@ -412,7 +411,7 @@ private void parseFields() throws IOException { } /** - * Parse a 1.2 Platform Certificate (Attribute Certificate). + * Parses a 1.2 Platform Certificate (Attribute Certificate). * * @param certificate Attribute Certificate */ @@ -465,7 +464,7 @@ private void parseAttributeCert(final AttributeCertificateInfo certificate) { } /** - * Parse a 2.0 Platform Certificate (Attribute Certificate). + * Parses a 2.0 Platform Certificate (Attribute Certificate). * * @param certificate Attribute Certificate */ @@ -514,7 +513,7 @@ private void parseAttributeCert2(final AttributeCertificateInfo certificate) } /** - * Get the x509 Platform Certificate version. + * Retrieves the x509 Platform Certificate version. * * @return a big integer representing the certificate version. */ @@ -533,7 +532,7 @@ public int getX509CredentialVersion() { } /** - * Get the cPSuri from the Certificate Policies. + * Retrieves the cPSuri from the Certificate Policies. * * @return cPSuri from the CertificatePolicies. * @throws IOException when reading the certificate. @@ -549,7 +548,7 @@ public String getCPSuri() throws IOException { } /** - * Get the Platform Configuration Attribute from the Platform Certificate. + * Retrieves the Platform Configuration Attribute from the Platform Certificate. * * @return a map with all the attributes * @throws IllegalArgumentException when there is a parsing error @@ -618,12 +617,12 @@ public Object getAttribute(final String attributeName) * @throws IllegalArgumentException when there is a parsing error * @throws IOException when reading the certificate. */ - public PlatformConfiguration getPlatformConfiguration() + public PlatformConfigurationV1 getPlatformConfigurationV1() throws IllegalArgumentException, IOException { if (getAttribute("platformConfiguration") != null - && getAttribute("platformConfiguration") instanceof PlatformConfiguration) { - return (PlatformConfiguration) getAttribute("platformConfiguration"); + && getAttribute("platformConfiguration") instanceof PlatformConfigurationV1) { + return (PlatformConfigurationV1) getAttribute("platformConfiguration"); } return null; @@ -710,15 +709,15 @@ private void getTCGCredentialSpecification(final ASN1Sequence attributeSequence) } /** - * Get the list of component identifiers if there are any. + * Retrieves the list of component identifiers if there are any. * * @return the list of component identifiers if there are any */ public List getComponentIdentifiers() { try { - PlatformConfiguration platformConfig = getPlatformConfiguration(); + PlatformConfigurationV1 platformConfig = getPlatformConfigurationV1(); if (platformConfig != null) { - return platformConfig.getComponentIdentifier(); + return platformConfig.getComponentIdentifiers(); } } catch (IOException e) { log.error("Unable to parse Platform Configuration from Platform Credential or find" @@ -728,15 +727,16 @@ public List getComponentIdentifiers() { } /** - * Get the list of version 2 component identifiers if there are any. + * Retrieves the list of version 2 component identifiers if there are any. * * @return the list of version 2 component identifiers if there are any */ public List getComponentIdentifiersV2() { try { PlatformConfigurationV2 platformConfigV2 = getPlatformConfigurationV2(); + if (platformConfigV2 != null) { - return platformConfigV2.getComponentIdentifierV2(); + return platformConfigV2.getComponentIdentifiers(); } } catch (IOException e) { log.error("Unable to parse Platform Configuration Version 2 from Platform Credential or find" diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentAddress.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentAddress.java index 2f9f82a93..a152e2245 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentAddress.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentAddress.java @@ -8,9 +8,9 @@ import org.bouncycastle.asn1.ASN1UTF8String; /** - * Basic class that handle component addresses from the component identifier. + * Basic class that represents the component addresses from the component identifier object. *
- * componentAddress ::= SEQUENCE {
+ * componentAddresses ::= SEQUENCE {
  *      addressType AddressType,
  *      addressValue UTF8String (SIZE (1..STRMAX)) }
  * where STRMAX is 256
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java
index 7b56a2838..41fbd2ebc 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java
@@ -16,8 +16,8 @@
 import java.util.stream.Collectors;
 
 /**
- * Basic class that handle component identifiers from the Platform Configuration
- * Attribute.
+ * Basic class that represents version 1 of the component identifiers from the Version 1
+ * Platform Configuration Attribute.
  * 
  * ComponentIdentifier ::= SEQUENCE {
  *      componentManufacturer UTF8String (SIZE (1..STRMAX)),
@@ -26,7 +26,7 @@
  *      componentRevision [1] IMPLICIT UTF8String (SIZE (1..STRMAX)) OPTIONAL,
  *      componentManufacturerId [2] IMPLICIT PrivateEnterpriseNumber OPTIONAL,
  *      fieldReplaceable [3] IMPLICIT BOOLEAN OPTIONAL,
- *      componentAddress [4] IMPLICIT
+ *      componentAddresses [4] IMPLICIT
  *          SEQUENCE(SIZE(1..CONFIGMAX)) OF ComponentAddress OPTIONAL}
  * where STRMAX is 256, CONFIGMAX is 32
  * 
@@ -80,7 +80,7 @@ public class ComponentIdentifier { private ASN1Boolean fieldReplaceable; - private List componentAddress; + private List componentAddresses; private boolean validationResult = true; @@ -94,7 +94,7 @@ public ComponentIdentifier() { componentRevision = new DERUTF8String(NOT_SPECIFIED_COMPONENT); componentManufacturerId = null; fieldReplaceable = null; - componentAddress = new ArrayList<>(); + componentAddresses = new ArrayList<>(); } /** @@ -121,7 +121,7 @@ public ComponentIdentifier(final DERUTF8String componentManufacturer, this.componentRevision = componentRevision; this.componentManufacturerId = componentManufacturerId; this.fieldReplaceable = fieldReplaceable; - this.componentAddress = componentAddress.stream().toList(); + this.componentAddresses = componentAddress.stream().toList(); } /** @@ -160,7 +160,7 @@ public ComponentIdentifier(final ASN1Sequence sequence) throws IllegalArgumentEx break; case COMPONENT_ADDRESS: ASN1Sequence addressesSequence = ASN1Sequence.getInstance(taggedObj, false); - componentAddress = retrieveComponentAddress(addressesSequence); + componentAddresses = retrieveComponentAddress(addressesSequence); break; default: throw new IllegalArgumentException("Component identifier contains " @@ -229,14 +229,14 @@ public String toString() { if (fieldReplaceable != null) { sb.append(fieldReplaceable); } - sb.append(", componentAddress="); - if (!componentAddress.isEmpty()) { - sb.append(componentAddress + sb.append(", componentAddresses="); + if (!componentAddresses.isEmpty()) { + sb.append(componentAddresses .stream() .map(Object::toString) .collect(Collectors.joining(","))); } - sb.append(", certificateIdentifier="); + sb.append(", componentPlatformCert="); sb.append("}"); return sb.toString(); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfiguration.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfiguration.java deleted file mode 100644 index 6622aa1c0..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfiguration.java +++ /dev/null @@ -1,112 +0,0 @@ -package hirs.attestationca.persist.entity.userdefined.certificate.attributes; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Abstract class that provides base info for Platform Configuration of - * the Platform Certificate Attribute. - */ -@AllArgsConstructor -public abstract class PlatformConfiguration { - - private List componentIdentifier; - - @Getter - @Setter - private URIReference componentIdentifierUri; - - private List platformProperties; - - @Getter - @Setter - private URIReference platformPropertiesUri; - - /** - * Default constructor. - */ - public PlatformConfiguration() { - this.componentIdentifier = new ArrayList<>(); - this.componentIdentifierUri = null; - this.platformProperties = new ArrayList<>(); - this.platformPropertiesUri = null; - } - - /** - * Constructor given the Platform Configuration values. - * - * @param componentIdentifier list containing all the components inside the - * Platform Configuration. - * @param platformProperties list containing all the properties inside the - * Platform Configuration. - * @param platformPropertiesUri object containing the URI Reference - */ - public PlatformConfiguration(final List componentIdentifier, - final List platformProperties, - final URIReference platformPropertiesUri) { - this.componentIdentifier = new ArrayList<>(componentIdentifier); - this.platformProperties = new ArrayList<>(platformProperties); - this.platformPropertiesUri = platformPropertiesUri; - } - - /** - * @return the componentIdentifier - */ - public List getComponentIdentifier() { - return Collections.unmodifiableList(componentIdentifier); - } - - /** - * @param componentIdentifier the componentIdentifier to set - */ - public void setComponentIdentifier(final List componentIdentifier) { - this.componentIdentifier = new ArrayList<>(componentIdentifier); - } - - /** - * Add function for the component identifier array. - * - * @param componentIdentifier object to add - * @return status of the add, if successful or not - */ - protected boolean add(final ComponentIdentifier componentIdentifier) { - if (this.componentIdentifier != null) { - return this.componentIdentifier.add(componentIdentifier); - } - - return false; - } - - /** - * @return the platformProperties - */ - public List getPlatformProperties() { - return Collections.unmodifiableList(platformProperties); - } - - /** - * @param platformProperties the platformProperties to set - */ - public void setPlatformProperties(final List platformProperties) { - this.platformProperties = new ArrayList<>(platformProperties); - } - - /** - * Add function for the platform property array. - * - * @param platformProperty property object to add - * @return status of the add, if successful or not - */ - protected boolean add(final PlatformProperty platformProperty) { - if (this.platformProperties != null) { - return this.platformProperties.add(platformProperty); - } - - return false; - } -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfigurationV1.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfigurationV1.java index c0dd0df62..757660b33 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfigurationV1.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfigurationV1.java @@ -1,28 +1,53 @@ package hirs.attestationca.persist.entity.userdefined.certificate.attributes; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.stream.Collectors; /** - * Basic class that handle Platform Configuration for the Platform Certificate + * Basic class that represents the Version 1 Platform Configuration used for the Platform Certificate * Attribute. *
  * PlatformConfiguration ::= SEQUENCE {
- *      componentIdentifier [0] IMPLICIT SEQUENCE(SIZE(1..CONFIGMAX)) OF
+ *      componentIdentifiers [0] IMPLICIT SEQUENCE(SIZE(1..CONFIGMAX)) OF
  *           ComponentIdentifier OPTIONAL,
  *      platformProperties [1] IMPLICIT SEQUENCE(SIZE(1..CONFIGMAX)) OF Properties OPTIONAL,
  *      platformPropertiesUri [2] IMPLICIT URIReference OPTIONAL }
  * 
*/ -public class PlatformConfigurationV1 extends PlatformConfiguration { +@AllArgsConstructor +public class PlatformConfigurationV1 { private static final int COMPONENT_IDENTIFIER = 0; + private static final int PLATFORM_PROPERTIES = 1; + private static final int PLATFORM_PROPERTIES_URI = 2; + private List componentIdentifiers; + + private List platformProperties; + + @Getter + @Setter + private URIReference platformPropertiesUri; + + /** + * Default constructor. + */ + public PlatformConfigurationV1() { + componentIdentifiers = new ArrayList<>(); + platformProperties = new ArrayList<>(); + platformPropertiesUri = null; + } + /** * Constructor given the SEQUENCE that contains Platform Configuration. * @@ -32,7 +57,7 @@ public class PlatformConfigurationV1 extends PlatformConfiguration { public PlatformConfigurationV1(final ASN1Sequence sequence) throws IllegalArgumentException { //Default values - setComponentIdentifier(new ArrayList<>()); + setComponentIdentifiers(new ArrayList<>()); setPlatformProperties(new ArrayList<>()); setPlatformPropertiesUri(null); @@ -42,7 +67,7 @@ public PlatformConfigurationV1(final ASN1Sequence sequence) throws IllegalArgume //Set information based on the set tagged switch (taggedSequence.getTagNo()) { case COMPONENT_IDENTIFIER: - //Get componentIdentifier + //Get componentIdentifiers ASN1Sequence componentConfiguration = ASN1Sequence.getInstance(taggedSequence, false); @@ -77,6 +102,62 @@ public PlatformConfigurationV1(final ASN1Sequence sequence) throws IllegalArgume } } + /** + * @return list of version 1 component identifiers + */ + public List getComponentIdentifiers() { + return Collections.unmodifiableList(componentIdentifiers); + } + + /** + * @param componentIdentifiers list of version 1 component identifiers + */ + public void setComponentIdentifiers(final List componentIdentifiers) { + this.componentIdentifiers = new ArrayList<>(componentIdentifiers); + } + + /** + * Add function for the version 1 component identifier array. + * + * @param componentIdentifier object to add + * @return status of the add, if successful or not + */ + protected boolean add(final ComponentIdentifier componentIdentifier) { + if (this.componentIdentifiers != null) { + return this.componentIdentifiers.add(componentIdentifier); + } + + return false; + } + + /** + * @return the platformProperties + */ + public List getPlatformProperties() { + return Collections.unmodifiableList(platformProperties); + } + + /** + * @param platformProperties the platformProperties to set + */ + public void setPlatformProperties(final List platformProperties) { + this.platformProperties = new ArrayList<>(platformProperties); + } + + /** + * Add function for the platform property array. + * + * @param platformProperty property object to add + * @return status of the add, if successful or not + */ + protected boolean add(final PlatformProperty platformProperty) { + if (this.platformProperties != null) { + return this.platformProperties.add(platformProperty); + } + + return false; + } + /** * Creates a string representation of the Platform Configuration V1 object. * @@ -86,15 +167,15 @@ public PlatformConfigurationV1(final ASN1Sequence sequence) throws IllegalArgume public String toString() { StringBuilder sb = new StringBuilder(); sb.append("PlatformConfiguration{"); - sb.append("componentIdentifier="); - if (getComponentIdentifier().size() > 0) { - sb.append(getComponentIdentifier() + sb.append("componentIdentifiers="); + if (!getComponentIdentifiers().isEmpty()) { + sb.append(getComponentIdentifiers() .stream() .map(Object::toString) .collect(Collectors.joining(","))); } sb.append(", platformProperties="); - if (getPlatformProperties().size() > 0) { + if (!getPlatformProperties().isEmpty()) { sb.append(getPlatformProperties() .stream() .map(Object::toString) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/AttributeStatus.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/AttributeStatus.java index 5a5b9b032..d9ea0999a 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/AttributeStatus.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/AttributeStatus.java @@ -16,6 +16,7 @@ * removed (2) } *
*/ +@Getter @AllArgsConstructor public enum AttributeStatus { /** @@ -35,6 +36,5 @@ public enum AttributeStatus { */ EMPTY_STATUS(StringUtils.EMPTY); - @Getter private final String value; } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java index 633f40c80..126d4b327 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java @@ -20,8 +20,8 @@ import java.util.stream.Collectors; /** - * Basic class that handle component identifiers from the Platform Configuration - * Attribute. + * Basic class that represents version 2 of the component identifiers from the Version 2 + * Platform Configuration Attribute. *
  * ComponentIdentifier ::= SEQUENCE {
  *      componentManufacturer UTF8String (SIZE (1..STRMAX)),
@@ -30,7 +30,7 @@
  *      componentRevision [1] IMPLICIT UTF8String (SIZE (1..STRMAX)) OPTIONAL,
  *      componentManufacturerId [2] IMPLICIT PrivateEnterpriseNumber OPTIONAL,
  *      fieldReplaceable [3] IMPLICIT BOOLEAN OPTIONAL,
- *      componentAddress [4] IMPLICIT
+ *      componentAddresses [4] IMPLICIT
  *          SEQUENCE(SIZE(1..CONFIGMAX)) OF ComponentAddress OPTIONAL
  *      componentPlatformCert [5] IMPLICIT CertificateIdentifier OPTIONAL,
  *      componentPlatformCertUri [6] IMPLICIT URIReference OPTIONAL,
@@ -48,15 +48,15 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
     // Additional optional identifiers for version 2
     private static final int COMPONENT_PLATFORM_CERT = 5;
 
-    private static final int COMPONENT_PLATFORM_URI = 6;
+    private static final int COMPONENT_PLATFORM_CERT_URI = 6;
 
     private static final int ATTRIBUTE_STATUS = 7;
 
     private ComponentClass componentClass;
 
-    private CertificateIdentifier certificateIdentifier;
+    private CertificateIdentifier componentPlatformCert;
 
-    private URIReference componentPlatformUri;
+    private URIReference componentPlatformCertUri;
 
     private AttributeStatus attributeStatus;
 
@@ -66,25 +66,25 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
     public ComponentIdentifierV2() {
         super();
         componentClass = new ComponentClass();
-        certificateIdentifier = null;
-        componentPlatformUri = null;
+        componentPlatformCert = null;
+        componentPlatformCertUri = null;
         attributeStatus = AttributeStatus.EMPTY_STATUS;
     }
 
     /**
      * Constructor given the components values.
      *
-     * @param componentClass          represent the component type
-     * @param componentManufacturer   represents the component manufacturer
-     * @param componentModel          represents the component model
-     * @param componentSerial         represents the component serial number
-     * @param componentRevision       represents the component revision
-     * @param componentManufacturerId represents the component manufacturer ID
-     * @param fieldReplaceable        represents if the component is replaceable
-     * @param componentAddress        represents a list of addresses
-     * @param certificateIdentifier   object representing certificate Id
-     * @param componentPlatformUri    object containing the URI Reference
-     * @param attributeStatus         object containing enumerated status
+     * @param componentClass           represent the component type
+     * @param componentManufacturer    represents the component manufacturer
+     * @param componentModel           represents the component model
+     * @param componentSerial          represents the component serial number
+     * @param componentRevision        represents the component revision
+     * @param componentManufacturerId  represents the component manufacturer ID
+     * @param fieldReplaceable         represents if the component is replaceable
+     * @param componentAddress         represents a list of addresses
+     * @param certificateIdentifier    object representing certificate Id
+     * @param componentPlatformCertUri object containing the URI Reference
+     * @param attributeStatus          object containing enumerated status
      */
     public ComponentIdentifierV2(final ComponentClass componentClass,
                                  final DERUTF8String componentManufacturer,
@@ -95,15 +95,15 @@ public ComponentIdentifierV2(final ComponentClass componentClass,
                                  final ASN1Boolean fieldReplaceable,
                                  final List componentAddress,
                                  final CertificateIdentifier certificateIdentifier,
-                                 final URIReference componentPlatformUri,
+                                 final URIReference componentPlatformCertUri,
                                  final AttributeStatus attributeStatus) {
         super(componentManufacturer, componentModel, componentSerial,
                 componentRevision, componentManufacturerId, fieldReplaceable,
                 componentAddress);
         this.componentClass = componentClass;
         // additional optional component identifiers
-        this.certificateIdentifier = certificateIdentifier;
-        this.componentPlatformUri = componentPlatformUri;
+        this.componentPlatformCert = certificateIdentifier;
+        this.componentPlatformCertUri = componentPlatformCertUri;
         this.attributeStatus = attributeStatus;
     }
 
@@ -150,15 +150,15 @@ public ComponentIdentifierV2(final ASN1Sequence sequence)
                     break;
                 case COMPONENT_ADDRESS:
                     ASN1Sequence addressesSequence = ASN1Sequence.getInstance(taggedObj, false);
-                    this.setComponentAddress(retrieveComponentAddress(addressesSequence));
+                    this.setComponentAddresses(retrieveComponentAddress(addressesSequence));
                     break;
                 case COMPONENT_PLATFORM_CERT:
                     ASN1Sequence ciSequence = ASN1Sequence.getInstance(taggedObj, false);
-                    certificateIdentifier = new CertificateIdentifier(ciSequence);
+                    componentPlatformCert = new CertificateIdentifier(ciSequence);
                     break;
-                case COMPONENT_PLATFORM_URI:
+                case COMPONENT_PLATFORM_CERT_URI:
                     ASN1Sequence uriSequence = ASN1Sequence.getInstance(taggedObj, false);
-                    this.componentPlatformUri = new URIReference(uriSequence);
+                    this.componentPlatformCertUri = new URIReference(uriSequence);
                     break;
                 case ATTRIBUTE_STATUS:
                     ASN1Enumerated enumerated = ASN1Enumerated.getInstance(taggedObj, false);
@@ -172,34 +172,6 @@ public ComponentIdentifierV2(final ASN1Sequence sequence)
         }
     }
 
-    /**
-     * @return true if the component has been modified.
-     */
-    public final boolean isAdded() {
-        return getAttributeStatus() == AttributeStatus.ADDED;
-    }
-
-    /**
-     * @return true if the component has been modified.
-     */
-    public final boolean isModified() {
-        return getAttributeStatus() == AttributeStatus.MODIFIED;
-    }
-
-    /**
-     * @return true if the component has been removed.
-     */
-    public final boolean isRemoved() {
-        return getAttributeStatus() == AttributeStatus.REMOVED;
-    }
-
-    /**
-     * @return true if the component status wasn't set.
-     */
-    public final boolean isEmpty() {
-        return (getAttributeStatus() == AttributeStatus.EMPTY_STATUS)
-                || (getAttributeStatus() == null);
-    }
 
     /**
      * @return indicates the type of platform certificate.
@@ -238,20 +210,20 @@ public String toString() {
         if (getFieldReplaceable() != null) {
             sb.append(getFieldReplaceable());
         }
-        sb.append(", componentAddress=");
-        if (!getComponentAddress().isEmpty()) {
-            sb.append(getComponentAddress()
+        sb.append(", componentAddresses=");
+        if (!getComponentAddresses().isEmpty()) {
+            sb.append(getComponentAddresses()
                     .stream()
                     .map(Object::toString)
                     .collect(Collectors.joining(",")));
         }
-        sb.append(", certificateIdentifier=");
-        if (certificateIdentifier != null) {
-            sb.append(certificateIdentifier);
+        sb.append(", componentPlatformCert=");
+        if (componentPlatformCert != null) {
+            sb.append(componentPlatformCert);
         }
-        sb.append(", componentPlatformUri=");
-        if (componentPlatformUri != null) {
-            sb.append(componentPlatformUri);
+        sb.append(", componentPlatformCertUri=");
+        if (componentPlatformCertUri != null) {
+            sb.append(componentPlatformCertUri);
         }
         sb.append(", status=");
         if (attributeStatus != null) {
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java
index 71f6026d2..58c2f4543 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java
@@ -1,7 +1,10 @@
 package hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2;
 
-import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfiguration;
+import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformProperty;
 import hirs.attestationca.persist.entity.userdefined.certificate.attributes.URIReference;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
 import org.bouncycastle.asn1.ASN1Sequence;
 import org.bouncycastle.asn1.ASN1TaggedObject;
 
@@ -11,7 +14,7 @@
 import java.util.stream.Collectors;
 
 /**
- * Basic class that handle Platform Configuration for the Platform Certificate
+ * Basic class that represents the Version 2 Platform Configuration used for the Platform Certificate
  * Attribute.
  * 
  * PlatformConfiguration ::= SEQUENCE {
@@ -22,24 +25,49 @@
  *      platformPropertiesUri [3] IMPLICIT URIReference OPTIONAL }
  * 
*/ -public class PlatformConfigurationV2 extends PlatformConfiguration { +@AllArgsConstructor +public class PlatformConfigurationV2 { private static final int COMPONENT_IDENTIFIER = 0; + private static final int COMPONENT_IDENTIFIER_URI = 1; + private static final int PLATFORM_PROPERTIES = 2; + private static final int PLATFORM_PROPERTIES_URI = 3; - private List componentIdentifierV2; + + private List componentIdentifiers; + + @Getter + @Setter + private URIReference componentIdentifiersUri; + + private List platformProperties; + + @Getter + @Setter + private URIReference platformPropertiesUri; + + /** + * Default constructor. + */ + public PlatformConfigurationV2() { + componentIdentifiers = new ArrayList<>(); + componentIdentifiersUri = null; + platformProperties = new ArrayList<>(); + platformPropertiesUri = null; + } /** * Constructor given the SEQUENCE that contains version 2 Platform Configuration. * - * @param sequence containing the the Platform Configuration. - * @throws IllegalArgumentException if there was an error on the parsing + * @param sequence containing the version 2 Platform Configuration. + * @throws IllegalArgumentException if there was an error while parsing */ public PlatformConfigurationV2(final ASN1Sequence sequence) throws IllegalArgumentException { //Default values - setComponentIdentifierV2(new ArrayList<>()); - setComponentIdentifierUri(null); + setComponentIdentifiers(new ArrayList<>()); + setComponentIdentifiersUri(null); setPlatformProperties(new ArrayList<>()); setPlatformPropertiesUri(null); @@ -65,7 +93,7 @@ public PlatformConfigurationV2(final ASN1Sequence sequence) throws IllegalArgume //Get componentIdentifierURI ASN1Sequence componentUri = ASN1Sequence.getInstance(taggedSequence, false); //Save Component Identifier URI - setComponentIdentifierUri(new URIReference(componentUri)); + setComponentIdentifiersUri(new URIReference(componentUri)); break; case PLATFORM_PROPERTIES: //Get platformProperties @@ -93,16 +121,59 @@ public PlatformConfigurationV2(final ASN1Sequence sequence) throws IllegalArgume /** * @return a collection of version 2 component identifiers. */ - public List getComponentIdentifierV2() { - return Collections.unmodifiableList(componentIdentifierV2); + public List getComponentIdentifiers() { + return Collections.unmodifiableList(componentIdentifiers); + } + + /** + * @param componentIdentifiers list of version 2 component identifiers + */ + public void setComponentIdentifiers( + final List componentIdentifiers) { + this.componentIdentifiers = new ArrayList<>(componentIdentifiers); + } + + + /** + * Add function for the component identifier array. + * + * @param componentIdentifierV2 object to add + * @return status of the add, if successful or not + */ + protected boolean add(final ComponentIdentifierV2 componentIdentifierV2) { + if (this.componentIdentifiers != null) { + return this.componentIdentifiers.add(componentIdentifierV2); + } + + return false; } /** - * @param componentIdentifierV2 list of version 2 component identifiers + * @return the platformProperties */ - public void setComponentIdentifierV2( - final List componentIdentifierV2) { - this.componentIdentifierV2 = new ArrayList<>(componentIdentifierV2); + public List getPlatformProperties() { + return Collections.unmodifiableList(platformProperties); + } + + /** + * @param platformProperties the platformProperties to set + */ + public void setPlatformProperties(final List platformProperties) { + this.platformProperties = new ArrayList<>(platformProperties); + } + + /** + * Add function for the platform property array. + * + * @param platformProperty property object to add + * @return status of the add, if successful or not + */ + protected boolean add(final PlatformProperty platformProperty) { + if (this.platformProperties != null) { + return this.platformProperties.add(platformProperty); + } + + return false; } /** @@ -113,17 +184,17 @@ public void setComponentIdentifierV2( @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("PlatformConfiguration{"); - sb.append("componentIdentifierV2="); - if (!getComponentIdentifierV2().isEmpty()) { - sb.append(getComponentIdentifierV2() + sb.append("PlatformConfigurationV2{"); + sb.append("componentIdentifiers="); + if (!getComponentIdentifiers().isEmpty()) { + sb.append(getComponentIdentifiers() .stream() .map(Object::toString) .collect(Collectors.joining(","))); } - sb.append(", componentIdentifierUri="); - if (getComponentIdentifierUri() != null) { - sb.append(getComponentIdentifierUri()); + sb.append(", componentIdentifiersUri="); + if (getComponentIdentifiersUri() != null) { + sb.append(getComponentIdentifiersUri()); } sb.append(", platformProperties="); if (!getPlatformProperties().isEmpty()) { diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java index 065a6e305..195b00135 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java @@ -204,7 +204,7 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) { * @return the {@link AppraisalStatus} of the supply chain validation */ private AppraisalStatus.Status doSupplyChainValidation( - final ProvisionerTpm2.IdentityClaim claim, final PublicKey ekPub) { + final ProvisionerTpm2.IdentityClaim claim, final PublicKey ekPub) throws IOException { // attempt to find an endorsement credential to validate EndorsementCredential endorsementCredential = @@ -745,16 +745,15 @@ private boolean generateDigestRecords(final String manufacturer, final String mo * * @param certificate certificate */ - private void savePlatformComponents(final Certificate certificate) { + private void savePlatformComponents(final Certificate certificate) throws IOException { PlatformCredential platformCredential; if (certificate instanceof PlatformCredential) { platformCredential = (PlatformCredential) certificate; ComponentResult componentResult; - // if the provided platform certificate is version 1.2 - if (platformCredential.getCredentialType().equals(PlatformCredential.CERTIFICATE_TYPE_1_2)) { - + // if the provided platform certificate is using version 1 Platform Configuration + if (platformCredential.getPlatformConfigurationV1() != null) { for (ComponentIdentifier componentIdentifier : platformCredential .getComponentIdentifiers()) { componentResult = new ComponentResult(platformCredential.getPlatformSerial(), @@ -765,11 +764,10 @@ private void savePlatformComponents(final Certificate certificate) { componentResult.setDelta(!platformCredential.isPlatformBase()); componentResultRepository.save(componentResult); } - } - // if the provided platform certificate is version 2.0 - else if (platformCredential.getCredentialType() - .equals(PlatformCredential.CERTIFICATE_TYPE_2_0)) { + + // if the provided platform certificate is using version 2 Platform Configuration + else if (platformCredential.getPlatformConfigurationV2() != null) { for (ComponentIdentifierV2 componentIdentifierV2 : platformCredential .getComponentIdentifiersV2()) { componentResult = new ComponentResult(platformCredential.getPlatformSerial(), diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java index 61120b1a0..3375f175e 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java @@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.io.IOException; import java.security.KeyStore; import java.util.ArrayList; import java.util.HashMap; @@ -108,7 +109,8 @@ public SupplyChainValidationService( public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredential ec, final List pcs, final Device device, - final List componentInfos) { + final List componentInfos) + throws IOException { boolean acceptExpiredCerts = getPolicySettings().isExpiredCertificateValidationEnabled(); provisionSessionId = UUID.randomUUID(); PlatformCredential baseCredential = null; @@ -153,6 +155,7 @@ public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent pcErrorMessage = String.format("%s%s%n", pcErrorMessage, platformScv.getMessage()); } + // set the base credential if (pc.isPlatformBase()) { baseCredential = pc; @@ -407,9 +410,9 @@ public SupplyChainValidationSummary validateQuote(final Device device) { } /** - * Helper function to get a fresh load of the default policy from the DB. + * Helper function that retrieves the default policy settings from the database. * - * @return The default Supply Chain Policy + * @return The default Supply Chain Policy Settings */ private PolicySettings getPolicySettings() { PolicySettings defaultSettings = this.policyRepository.findByName("Default"); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java index 76efb8df8..e77842852 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java @@ -139,7 +139,7 @@ public static SupplyChainValidation evaluatePCAttributesStatus( final ComponentResultRepository componentResultRepository, final ComponentAttributeRepository componentAttributeRepository, final List componentInfos, - final UUID provisionSessionId, final boolean ignoreRevisionAttribute) { + final UUID provisionSessionId, final boolean ignoreRevisionAttribute) throws IOException { final SupplyChainValidation.ValidationType validationType = SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/AcaPciIds.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/AcaPciIds.java index 73e90f12f..777cfe26e 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/AcaPciIds.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/AcaPciIds.java @@ -110,9 +110,9 @@ public static ComponentIdentifierV2 translate(final ComponentIdentifierV2 compon component.getComponentRevision(), component.getComponentManufacturerId(), component.getFieldReplaceable(), - component.getComponentAddress(), - component.getCertificateIdentifier(), - component.getComponentPlatformUri(), + component.getComponentAddresses(), + component.getComponentPlatformCert(), + component.getComponentPlatformCertUri(), component.getAttributeStatus()); } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java index 532f77189..0c25b1f57 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java @@ -23,6 +23,7 @@ import org.bouncycastle.asn1.ASN1UTF8String; import org.bouncycastle.asn1.DERUTF8String; +import java.io.IOException; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -167,7 +168,7 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0( final ComponentResultRepository componentResultRepository, final ComponentAttributeRepository componentAttributeRepository, final List componentInfos, - final UUID provisionSessionId, final boolean ignoreRevisionAttribute) { + final UUID provisionSessionId, final boolean ignoreRevisionAttribute) throws IOException { boolean passesValidation = true; StringBuilder resultMessage = new StringBuilder(); HardwareInfo hardwareInfo = deviceInfoReport.getHardwareInfo(); @@ -231,38 +232,42 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0( passesValidation &= fieldValidation; - // Retrieve the list of all version 2 component identifiers from the Platform Credential - List allPcComponents - = new ArrayList<>(platformCredential.getComponentIdentifiersV2()); + if (platformCredential.getPlatformConfigurationV1() != null) { - // All components listed in the Platform Credential must have a manufacturer and model - for (ComponentIdentifierV2 pcComponent : allPcComponents) { + // Retrieve the list of all version 2 component identifiers from the Platform Credential + List allPcComponents + = new ArrayList<>(platformCredential.getComponentIdentifiers()); -// fieldValidation = pcComponent.getComponentClass() != null; -// -// if (!fieldValidation) { -// resultMessage.append("Component class is null\n"); -// } + // All components listed in the Platform Credential must have a manufacturer and model + for (ComponentIdentifier pcComponent : allPcComponents) { - fieldValidation = !hasEmptyValueForRequiredField("componentManufacturer", - pcComponent.getComponentManufacturer()); + fieldValidation = !hasEmptyValueForRequiredField("componentManufacturer", + pcComponent.getComponentManufacturer()); - if (!fieldValidation) { - resultMessage.append("Component manufacturer is empty\n"); - } + if (!fieldValidation) { + resultMessage.append("Component manufacturer is empty\n"); + } - passesValidation &= fieldValidation; + passesValidation &= fieldValidation; - fieldValidation = !hasEmptyValueForRequiredField("componentModel", - pcComponent.getComponentModel()); + fieldValidation = !hasEmptyValueForRequiredField("componentModel", + pcComponent.getComponentModel()); - if (!fieldValidation) { - resultMessage.append("Component model is empty\n"); + if (!fieldValidation) { + resultMessage.append("Component model is empty\n"); + } + + passesValidation &= fieldValidation; } - passesValidation &= fieldValidation; + } else if (platformCredential.getPlatformConfigurationV2() != null) { + + // Retrieve the list of all version 2 component identifiers from the Platform Credential + List allPcComponents + = new ArrayList<>(platformCredential.getComponentIdentifiersV2()); } + // populate componentResults list List componentResults = componentResultRepository .findByCertificateSerialNumberAndBoardSerialNumber( diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java index 64f35ca4f..49cd6cf65 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java @@ -100,7 +100,7 @@ public static AppraisalStatus validateEndorsementCredential(final EndorsementCre * * @param pc The platform credential to verify. * @param trustStore trust store holding trusted certificates. - * @param acceptExpired whether or not to accept expired certificates as valid. + * @param acceptExpired whether to accept expired certificates as valid. * @return The result of the validation. */ public static AppraisalStatus validatePlatformCredential(final PlatformCredential pc, @@ -183,7 +183,7 @@ public static AppraisalStatus validatePlatformCredentialAttributes( final ComponentResultRepository componentResultRepository, final ComponentAttributeRepository componentAttributeRepository, final List componentInfos, - final UUID provisionSessionId, final boolean ignoreRevisionAttribute) { + final UUID provisionSessionId, final boolean ignoreRevisionAttribute) throws IOException { final String baseErrorMessage = "Can't validate platform credential attributes without "; String message; if (platformCredential == null) { diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredentialTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredentialTest.java index 355fa9037..6ab46e530 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredentialTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredentialTest.java @@ -3,10 +3,11 @@ import hirs.attestationca.persist.entity.userdefined.AbstractUserdefinedEntityTest; import hirs.attestationca.persist.entity.userdefined.Certificate; import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier; -import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfiguration; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfigurationV1; import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformProperty; import hirs.attestationca.persist.entity.userdefined.certificate.attributes.TBBSecurityAssertion; import hirs.attestationca.persist.entity.userdefined.certificate.attributes.URIReference; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2; import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.PlatformConfigurationV2; import org.apache.commons.codec.binary.Hex; import org.bouncycastle.util.encoders.Base64; @@ -439,10 +440,10 @@ public final void testPlatformConfiguration() throws IOException, URISyntaxExcep Path certPath = Paths.get(resource.toURI()); PlatformCredential platformCert = new PlatformCredential(certPath); - PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + PlatformConfigurationV1 platformConfigV1 = platformCert.getPlatformConfigurationV1(); //Check component identifier - List allComponents = platformConfig.getComponentIdentifier(); + List allComponents = platformConfigV1.getComponentIdentifiers(); if (allComponents.isEmpty()) { Assertions.fail("Component Identifier is empty."); } @@ -472,14 +473,14 @@ public final void testPlatformConfiguration() throws IOException, URISyntaxExcep component = allComponents.get(component5Position); Assertions.assertEquals("Ethernet Connection I219-LM", component.getComponentModel() .getString()); - Assertions.assertEquals("8c:0f:6f:72:c6:c5", component.getComponentAddress().get(0) + Assertions.assertEquals("8c:0f:6f:72:c6:c5", component.getComponentAddresses().get(0) .getAddressValue() .getString()); - Assertions.assertEquals("ethernet mac", component.getComponentAddress().get(0) + Assertions.assertEquals("ethernet mac", component.getComponentAddresses().get(0) .getAddressTypeValue()); //Check Platform Properties - List platformProperties = platformConfig.getPlatformProperties(); + List platformProperties = platformConfigV1.getPlatformProperties(); if (platformProperties.isEmpty()) { Assertions.fail("Platform Properties is empty."); } @@ -499,7 +500,7 @@ public final void testPlatformConfiguration() throws IOException, URISyntaxExcep Assertions.assertEquals("true", property.getPropertyValue().getString()); //Check Platform Properties URI - URIReference platformPropertyUri = platformConfig.getPlatformPropertiesUri(); + URIReference platformPropertyUri = platformConfigV1.getPlatformPropertiesUri(); Assertions.assertNotNull(platformPropertyUri); Assertions.assertEquals("https://www.intel.com/platformproperties.xml", @@ -522,13 +523,13 @@ public final void testPlatformConfiguration2() throws IOException, URISyntaxExce Path certPath = Paths.get(resource.toURI()); PlatformCredential platformCert = new PlatformCredential(certPath); - PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + PlatformConfigurationV1 platformConfigV1 = platformCert.getPlatformConfigurationV1(); //Check component identifier - List allComponents = platformConfig.getComponentIdentifier(); + List allComponents = platformConfigV1.getComponentIdentifiers(); Assertions.assertTrue(allComponents.isEmpty()); - List platformProperties = platformConfig.getPlatformProperties(); + List platformProperties = platformConfigV1.getPlatformProperties(); if (platformProperties.isEmpty()) { Assertions.fail("Platform Properties is empty."); } @@ -560,10 +561,10 @@ public final void testPlatformConfiguration3() throws IOException, URISyntaxExce Path certPath = Paths.get(resource.toURI()); PlatformCredential platformCert = new PlatformCredential(certPath); - PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + PlatformConfigurationV1 platformConfigV1 = platformCert.getPlatformConfigurationV1(); //Check component identifier - List allComponents = platformConfig.getComponentIdentifier(); + List allComponents = platformConfigV1.getComponentIdentifiers(); if (allComponents.isEmpty()) { Assertions.fail("Component Identifier is empty."); } @@ -589,7 +590,7 @@ public final void testPlatformConfiguration3() throws IOException, URISyntaxExce .getString()); //Check Platform Properties - List platformProperties = platformConfig.getPlatformProperties(); + List platformProperties = platformConfigV1.getPlatformProperties(); if (platformProperties.isEmpty()) { Assertions.fail("Platform Properties is empty."); } @@ -597,7 +598,7 @@ public final void testPlatformConfiguration3() throws IOException, URISyntaxExce Assertions.assertEquals(platformProperties.size(), 2); //Check Platform Properties URI - URIReference platformPropertyUri = platformConfig.getPlatformPropertiesUri(); + URIReference platformPropertyUri = platformConfigV1.getPlatformPropertiesUri(); Assertions.assertNotNull(platformPropertyUri); Assertions.assertEquals("https://www.intel.com/platformproperties.xml", @@ -629,10 +630,10 @@ public final void testPlatformConfiguration4() throws IOException, URISyntaxExce Path certPath = Paths.get(resource.toURI()); PlatformCredential platformCert = new PlatformCredential(certPath); - PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + PlatformConfigurationV1 platformConfigV1 = platformCert.getPlatformConfigurationV1(); //Check component identifier - List allComponents = platformConfig.getComponentIdentifier(); + List allComponents = platformConfigV1.getComponentIdentifiers(); if (allComponents.isEmpty()) { Assertions.fail("Component Identifier is empty."); } @@ -651,15 +652,15 @@ public final void testPlatformConfiguration4() throws IOException, URISyntaxExce //Check component #7 final int component7Position = 6; component = allComponents.get(component7Position); - Assertions.assertTrue(component.getComponentAddress().size() > 0); - Assertions.assertEquals("8c:0f:6f:72:c6:c5", component.getComponentAddress().get(0) + Assertions.assertFalse(component.getComponentAddresses().isEmpty()); + Assertions.assertEquals("8c:0f:6f:72:c6:c5", component.getComponentAddresses().get(0) .getAddressValue() .getString()); - Assertions.assertEquals("ethernet mac", component.getComponentAddress().get(0) + Assertions.assertEquals("ethernet mac", component.getComponentAddresses().get(0) .getAddressTypeValue()); //Check Platform Properties - List platformProperties = platformConfig.getPlatformProperties(); + List platformProperties = platformConfigV1.getPlatformProperties(); if (platformProperties.isEmpty()) { Assertions.fail("Platform Properties is empty."); } @@ -667,7 +668,7 @@ public final void testPlatformConfiguration4() throws IOException, URISyntaxExce Assertions.assertEquals(platformProperties.size(), 2); //Check Platform Properties URI - URIReference platformPropertyUri = platformConfig.getPlatformPropertiesUri(); + URIReference platformPropertyUri = platformConfigV1.getPlatformPropertiesUri(); Assertions.assertNotNull(platformPropertyUri); Assertions.assertEquals("https://www.intel.com/platformproperties.xml", @@ -700,17 +701,17 @@ public final void testPlatformConfiguration5() throws IOException, URISyntaxExce Path certPath = Paths.get(resource.toURI()); PlatformCredential platformCert = new PlatformCredential(certPath); - PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + PlatformConfigurationV2 platformConfigV2 = platformCert.getPlatformConfigurationV2(); //Check component identifier - List allComponents = platformConfig.getComponentIdentifier(); + List allComponents = platformConfigV2.getComponentIdentifiers(); Assertions.assertFalse(allComponents.isEmpty()); final int component6Position = 5; - ComponentIdentifier component = allComponents.get(component6Position); + ComponentIdentifierV2 component = allComponents.get(component6Position); Assertions.assertTrue(component.isVersion2()); - List platformProperties = platformConfig.getPlatformProperties(); + List platformProperties = platformConfigV2.getPlatformProperties(); if (platformProperties.isEmpty()) { Assertions.fail("Platform Properties is empty."); } @@ -749,15 +750,15 @@ public final void testPlatformConfiguration6() throws IOException, URISyntaxExce Path certPath = Paths.get(resource.toURI()); PlatformCredential platformCert = new PlatformCredential(certPath); - PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + PlatformConfigurationV2 platformConfigV2 = platformCert.getPlatformConfigurationV2(); - Assertions.assertInstanceOf(PlatformConfigurationV2.class, platformConfig); - Assertions.assertEquals(platformConfig.getPlatformPropertiesUri() + Assertions.assertInstanceOf(PlatformConfigurationV2.class, platformConfigV2); + Assertions.assertEquals(platformConfigV2.getPlatformPropertiesUri() .getUniformResourceIdentifier().toString(), "https://www.intel.com/platformproperties.xml"); -// Assertions.assertNotNull(platformConfig.getComponentIdentifierUri()); +// Assertions.assertNotNull(platformConfigV1.getComponentIdentifiersUri()); -// Assertions.assertEquals(platformConfig.getComponentIdentifierUri() +// Assertions.assertEquals(platformConfigV1.getComponentIdentifiersUri() // .getUniformResourceIdentifier().toString(), // "https://www.intel.com/platformidentifiers.xml"); diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java index 278d2a8e2..62d8e09b7 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java @@ -1990,7 +1990,7 @@ public final void testValidateDeltaPlatformCredentialAttributes() // ciV21Faulty.setComponentRevision(compId2.getComponentRevision()); // ciV21Faulty.setComponentManufacturerId(compId2.getComponentManufacturerId()); // ciV21Faulty.setFieldReplaceable(compId2.getFieldReplaceable()); -// ciV21Faulty.setComponentAddress(compId2.getComponentAddress()); +// ciV21Faulty.setComponentAddresses(compId2.getComponentAddresses()); // ciV21Faulty.setAttributeStatus(AttributeStatus.REMOVED); // ciV22Faulty.setComponentManufacturer(compId3.getComponentManufacturer()); // ciV22Faulty.setComponentClass(compId3.getComponentClass()); @@ -1999,7 +1999,7 @@ public final void testValidateDeltaPlatformCredentialAttributes() // ciV22Faulty.setComponentRevision(compId3.getComponentRevision()); // ciV22Faulty.setComponentManufacturerId(compId3.getComponentManufacturerId()); // ciV22Faulty.setFieldReplaceable(compId3.getFieldReplaceable()); -// ciV22Faulty.setComponentAddress(compId3.getComponentAddress()); +// ciV22Faulty.setComponentAddresses(compId3.getComponentAddresses()); // ciV22Faulty.setAttributeStatus(AttributeStatus.REMOVED); // // List compList = new ArrayList<>(3); @@ -2117,7 +2117,7 @@ public final void testValidateChainFailure() // ciV21Faulty.setComponentRevision(compId2.getComponentRevision()); // ciV21Faulty.setComponentManufacturerId(compId2.getComponentManufacturerId()); // ciV21Faulty.setFieldReplaceable(compId2.getFieldReplaceable()); -// ciV21Faulty.setComponentAddress(compId2.getComponentAddress()); +// ciV21Faulty.setComponentAddresses(compId2.getComponentAddresses()); // ciV21Faulty.setAttributeStatus(AttributeStatus.REMOVED); // ciV22Faulty.setComponentManufacturer(compId3.getComponentManufacturer()); // ciV22Faulty.setComponentModel(compId3.getComponentModel()); @@ -2125,7 +2125,7 @@ public final void testValidateChainFailure() // ciV22Faulty.setComponentRevision(compId3.getComponentRevision()); // ciV22Faulty.setComponentManufacturerId(compId3.getComponentManufacturerId()); // ciV22Faulty.setFieldReplaceable(compId3.getFieldReplaceable()); -// ciV22Faulty.setComponentAddress(compId3.getComponentAddress()); +// ciV22Faulty.setComponentAddresses(compId3.getComponentAddresses()); // ciV22Faulty.setAttributeStatus(AttributeStatus.REMOVED); // // List compList = new ArrayList<>(3); diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java index a2c37fd12..56e95125c 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java @@ -949,7 +949,7 @@ private void storeCertificate( } this.certificateRepository.save(certificate); - handlePlatformComponents(certificate); + parseAndSaveComponentResults(certificate); final String successMsg = String.format("New certificate successfully uploaded (%s): ", fileName); @@ -963,6 +963,11 @@ private void storeCertificate( messages.addError(failMessage + dbsEx.getMessage()); log.error(failMessage, dbsEx); return; + } catch (IOException ioException) { + final String ioExceptionMessage = "Failed to save component results in the database"; + messages.addError(ioExceptionMessage + ioException.getMessage()); + log.error(ioExceptionMessage, ioException); + return; } try { @@ -1006,11 +1011,12 @@ private void storeCertificate( } /** - * Helper method that attempts to manage the provided platform certificate's components. + * Helper method that utilizes the components of the provided platform certificate to generate + * a collection of component results and subsequently stores these results in the database. * * @param certificate certificate */ - private void handlePlatformComponents(final Certificate certificate) { + private void parseAndSaveComponentResults(final Certificate certificate) throws IOException { PlatformCredential platformCredential; if (certificate instanceof PlatformCredential) { @@ -1023,8 +1029,8 @@ private void handlePlatformComponents(final Certificate certificate) { if (componentResults.isEmpty()) { ComponentResult componentResult; - // if the provided platform certificate is version 1.2 - if (platformCredential.getCredentialType().equals(PlatformCredential.CERTIFICATE_TYPE_1_2)) { + // if the provided platform certificate is using version 1 Platform Configuration + if (platformCredential.getPlatformConfigurationV1() != null) { for (ComponentIdentifier componentIdentifier : platformCredential .getComponentIdentifiers()) { @@ -1037,9 +1043,9 @@ private void handlePlatformComponents(final Certificate certificate) { componentResultRepository.save(componentResult); } } - // if the provided platform certificate is version 2.0 - else if (platformCredential.getCredentialType() - .equals(PlatformCredential.CERTIFICATE_TYPE_2_0)) { + + // if the provided platform certificate is using version 2 Platform Configuration + else if (platformCredential.getPlatformConfigurationV2() != null) { for (ComponentIdentifierV2 componentIdentifierV2 : platformCredential .getComponentIdentifiersV2()) { diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java index 30d11444a..a22a52488 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java @@ -10,8 +10,8 @@ import hirs.attestationca.persist.entity.userdefined.certificate.IDevIDCertificate; import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate; 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.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.PlatformConfigurationV2; import hirs.attestationca.persist.util.AcaPciIds; import hirs.utils.BouncyCastleUtils; import hirs.utils.PciIds; @@ -401,21 +401,22 @@ public static HashMap getPlatformInformation(final UUID uuid, data.put("componentResults", compResults); //Get platform Configuration values and set map with it - PlatformConfiguration platformConfiguration = certificate.getPlatformConfiguration(); - if (platformConfiguration != null) { + PlatformConfigurationV2 platformConfigurationV2 = certificate.getPlatformConfigurationV2(); + if (platformConfigurationV2 != null) { //Component Identifier - attempt to translate hardware IDs - List comps = platformConfiguration.getComponentIdentifier(); - if (PciIds.DB.isReady()) { - comps = AcaPciIds.translate(comps); - } - data.put("componentsIdentifier", comps); + List componentIdentifiers = + platformConfigurationV2.getComponentIdentifiers(); + /* if (PciIds.DB.isReady()) { + componentIdentifiers = AcaPciIds.translate(componentIdentifiers); + }*/ + data.put("componentsIdentifier", componentIdentifiers); //Component Identifier URI - data.put("componentsIdentifierURI", platformConfiguration - .getComponentIdentifierUri()); + data.put("componentsIdentifierURI", platformConfigurationV2 + .getComponentIdentifiersUri()); //Platform Properties - data.put("platformProperties", platformConfiguration.getPlatformProperties()); + data.put("platformProperties", platformConfigurationV2.getPlatformProperties()); //Platform Properties URI - data.put("platformPropertiesURI", platformConfiguration.getPlatformPropertiesUri()); + data.put("platformPropertiesURI", platformConfigurationV2.getPlatformPropertiesUri()); } //TBB Security Assertion data.put("tbbSecurityAssertion", certificate.getTBBSecurityAssertion()); diff --git a/package/linux/systemd/hirs-aca.service b/package/linux/systemd/hirs-aca.service index 023e89f86..111fed3df 100644 --- a/package/linux/systemd/hirs-aca.service +++ b/package/linux/systemd/hirs-aca.service @@ -5,7 +5,7 @@ After=network.target [Service] User=root Group=root -ExecStart=/usr/bin/bash /opt/hirs/aca/scripts/aca/aca_bootRun.sh -w +ExecStart=/usr/bin/bash /opt/hirs/aca/scripts/aca/aca_bootRun.sh -d -w SuccessExitStatus=0 Restart=always RestartSec=60 From d2a9ca9aa8ba888f35d80636a3966db0ae61295d Mon Sep 17 00:00:00 2001 From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com> Date: Thu, 6 Feb 2025 18:05:11 -0500 Subject: [PATCH 05/14] issue_896:Added a new property to component info, made some more spelling corrections, deleted unused classes that were being referenced by componentinfo. pretty much done with the aca side of things. --- .../certificate/PlatformCredential.java | 5 +- .../attributes/ComponentAddress.java | 2 +- .../attributes/V2/CertificateIdentifier.java | 11 ++++ .../attributes/V2/ComponentIdentifierV2.java | 7 +-- .../userdefined/info/ComponentInfo.java | 51 ++++++++----------- .../info/component/BIOSComponentInfo.java | 30 ----------- .../component/BaseboardComponentInfo.java | 32 ------------ .../info/component/ChassisComponentInfo.java | 32 ------------ .../component/HardDriveComponentInfo.java | 32 ------------ .../info/component/MemoryComponentInfo.java | 32 ------------ .../info/component/NICComponentInfo.java | 32 ------------ .../component/ProcessorComponentInfo.java | 32 ------------ .../info/component/package-info.java | 1 - .../helper/CredentialManagementHelper.java | 27 ++++++---- .../persist/service/ValidationService.java | 8 +-- .../CertificateAttributeScvValidator.java | 32 ++++++++++-- .../SupplyChainCredentialValidator.java | 12 +++-- .../SupplyChainCredentialValidatorTest.java | 7 ++- .../utils/CertificateStringMapBuilder.java | 7 +-- 19 files changed, 104 insertions(+), 288 deletions(-) delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BIOSComponentInfo.java delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BaseboardComponentInfo.java delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ChassisComponentInfo.java delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/HardDriveComponentInfo.java delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/MemoryComponentInfo.java delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/NICComponentInfo.java delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ProcessorComponentInfo.java delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/package-info.java diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java index 03b640147..4a7d654f8 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java @@ -558,8 +558,11 @@ public Map getAllAttributes() throws IllegalArgumentException, IOException { Map attributes = new HashMap<>(); ASN1Sequence attributeSequence; + + ASN1Encodable[] asn1EncodableArray = getAttributeCertificate().getAcinfo().getAttributes().toArray(); + // Check all attributes for Platform Configuration - for (ASN1Encodable enc : getAttributeCertificate().getAcinfo().getAttributes().toArray()) { + for (ASN1Encodable enc : asn1EncodableArray) { Attribute attr = Attribute.getInstance(enc); attributeSequence = ASN1Sequence.getInstance(attr.getAttrValues().getObjectAt(0)); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentAddress.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentAddress.java index a152e2245..7284b08d1 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentAddress.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentAddress.java @@ -10,7 +10,7 @@ /** * Basic class that represents the component addresses from the component identifier object. *
- * componentAddresses ::= SEQUENCE {
+ * componentAddress ::= SEQUENCE {
  *      addressType AddressType,
  *      addressValue UTF8String (SIZE (1..STRMAX)) }
  * where STRMAX is 256
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/CertificateIdentifier.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/CertificateIdentifier.java
index 2512d4981..2a00f9ca1 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/CertificateIdentifier.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/CertificateIdentifier.java
@@ -76,6 +76,12 @@ public CertificateIdentifier(final ASN1Sequence sequence) {
         }
     }
 
+    /**
+     * Helper method that parses the attribute certificate id from the provided attribute
+     * certificate ASN1 Sequence.
+     *
+     * @param attrCertSeq ASN1 attribute certificate sequence
+     */
     private void parseAttributeCertId(final ASN1Sequence attrCertSeq) {
         //Check if it have a valid number of identifiers
         if (attrCertSeq.size() != SEQUENCE_NUMBER) {
@@ -87,6 +93,11 @@ private void parseAttributeCertId(final ASN1Sequence attrCertSeq) {
         hashSigValue = attrCertSeq.getObjectAt(1).toString();
     }
 
+    /**
+     * Helper method that parses the generic certificate id from the provided issuer serial ASN1 sequence.
+     *
+     * @param issuerSerialSeq ASN1 issuer serial sequence
+     */
     private void parseGenericCertId(final ASN1Sequence issuerSerialSeq) {
         //Check if it have a valid number of identifiers
         if (issuerSerialSeq.size() != SEQUENCE_NUMBER) {
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java
index 126d4b327..88dbceab7 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java
@@ -24,6 +24,7 @@
  * Platform Configuration Attribute.
  * 
  * ComponentIdentifier ::= SEQUENCE {
+ *      componentClass ComponentClass
  *      componentManufacturer UTF8String (SIZE (1..STRMAX)),
  *      componentModel UTF8String (SIZE (1..STRMAX)),
  *      componentSerial[0] IMPLICIT UTF8String (SIZE (1..STRMAX)) OPTIONAL,
@@ -82,7 +83,7 @@ public ComponentIdentifierV2() {
      * @param componentManufacturerId  represents the component manufacturer ID
      * @param fieldReplaceable         represents if the component is replaceable
      * @param componentAddress         represents a list of addresses
-     * @param certificateIdentifier    object representing certificate Id
+     * @param componentPlatformCert    object representing certificate Id
      * @param componentPlatformCertUri object containing the URI Reference
      * @param attributeStatus          object containing enumerated status
      */
@@ -94,7 +95,7 @@ public ComponentIdentifierV2(final ComponentClass componentClass,
                                  final ASN1ObjectIdentifier componentManufacturerId,
                                  final ASN1Boolean fieldReplaceable,
                                  final List componentAddress,
-                                 final CertificateIdentifier certificateIdentifier,
+                                 final CertificateIdentifier componentPlatformCert,
                                  final URIReference componentPlatformCertUri,
                                  final AttributeStatus attributeStatus) {
         super(componentManufacturer, componentModel, componentSerial,
@@ -102,7 +103,7 @@ public ComponentIdentifierV2(final ComponentClass componentClass,
                 componentAddress);
         this.componentClass = componentClass;
         // additional optional component identifiers
-        this.componentPlatformCert = certificateIdentifier;
+        this.componentPlatformCert = componentPlatformCert;
         this.componentPlatformCertUri = componentPlatformCertUri;
         this.attributeStatus = attributeStatus;
     }
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/ComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/ComponentInfo.java
index aa98f2828..cd279d41c 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/ComponentInfo.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/ComponentInfo.java
@@ -55,10 +55,14 @@ public class ComponentInfo extends ArchivableEntity {
 
     @XmlElement
     @Column
-    private String componentClass;
+    private String componentClassValue;
+
+    @XmlElement
+    @Column
+    private String componentClassRegistry;
 
     /**
-     * Base constructor for children.
+     * Constructor.
      *
      * @param componentManufacturer Component Manufacturer (must not be null)
      * @param componentModel        Component Model (must not be null)
@@ -87,24 +91,26 @@ public ComponentInfo(final String deviceName,
                          final String componentModel,
                          final String componentSerial,
                          final String componentRevision) {
-        if (isComplete(
-                componentManufacturer,
-                componentModel,
-                componentSerial,
-                componentRevision)) {
-            log.error("ComponentInfo: manufacturer and/or "
+
+        if ((StringUtils.isEmpty(componentManufacturer)
+                || StringUtils.isEmpty(componentModel))) {
+
+            log.error("Component Info's manufacturer and/or "
                     + "model can not be null");
             throw new NullPointerException("ComponentInfo: manufacturer and/or "
                     + "model can not be null");
         }
+
         this.deviceName = deviceName;
         this.componentManufacturer = componentManufacturer.trim();
         this.componentModel = componentModel.trim();
+
         if (componentSerial != null) {
             this.componentSerial = componentSerial.trim();
         } else {
             this.componentSerial = ComponentIdentifier.NOT_SPECIFIED_COMPONENT;
         }
+
         if (componentRevision != null) {
             this.componentRevision = componentRevision.trim();
         } else {
@@ -120,39 +126,22 @@ public ComponentInfo(final String deviceName,
      * @param componentModel        Component Model (must not be null)
      * @param componentSerial       Component Serial Number (can be null)
      * @param componentRevision     Component Revision or Version (can be null)
-     * @param componentClass        Component Class (can be null)
+     * @param componentClassValue   Component Class Value (can be null)
      */
     public ComponentInfo(final String deviceName,
                          final String componentManufacturer,
                          final String componentModel,
                          final String componentSerial,
                          final String componentRevision,
-                         final String componentClass) {
+                         final String componentClassValue,
+                         final String componentClassRegistry) {
         this(deviceName, componentManufacturer, componentModel,
                 componentSerial, componentRevision);
 
-        this.componentClass = Objects.requireNonNullElse(componentClass, StringUtils.EMPTY);
+        this.componentClassValue = Objects.requireNonNullElse(componentClassValue, StringUtils.EMPTY);
+        this.componentClassRegistry = Objects.requireNonNullElse(componentClassRegistry, StringUtils.EMPTY);
     }
 
-    /**
-     * Determines whether the given properties represent a
-     * ComponentInfo that will be useful in validation.
-     * Currently, only components which have a non-null
-     * manufacturer and model are considered valid.
-     *
-     * @param componentManufacturer a String containing a component's manufacturer
-     * @param componentModel        a String representing a component's model
-     * @param componentSerial       a String representing a component's serial number
-     * @param componentRevision     a String representing a component's revision
-     * @return true if the component is valid, false if not
-     */
-    public static boolean isComplete(final String componentManufacturer,
-                                     final String componentModel,
-                                     final String componentSerial,
-                                     final String componentRevision) {
-        return (StringUtils.isEmpty(componentManufacturer)
-                || StringUtils.isEmpty(componentModel));
-    }
 
     /**
      * Returns a hash code that is associated with common fields for components.
@@ -161,6 +150,6 @@ public static boolean isComplete(final String componentManufacturer,
      */
     public int hashCommonElements() {
         return Objects.hash(componentManufacturer, componentModel,
-                componentSerial, componentRevision, componentClass);
+                componentSerial, componentRevision, componentClassValue, componentClassRegistry);
     }
 }
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BIOSComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BIOSComponentInfo.java
deleted file mode 100644
index c74fe65be..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BIOSComponentInfo.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package hirs.attestationca.persist.entity.userdefined.info.component;
-
-import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
-import hirs.utils.enums.ComponentType;
-import jakarta.persistence.DiscriminatorValue;
-import jakarta.persistence.Entity;
-import lombok.NoArgsConstructor;
-
-/**
- * Class to hold BIOS/UEFI Component information.
- */
-@NoArgsConstructor
-@Entity
-@DiscriminatorValue(value = ComponentType.Values.BIOS_UEFI)
-public class BIOSComponentInfo extends ComponentInfo {
-
-    /**
-     * Constructor.
-     *
-     * @param componentManufacturer Component Manufacturer (must not be null)
-     * @param componentModel        Component Model (must not be null)
-     * @param componentRevision     Component Revision or Version (can be null)
-     */
-    public BIOSComponentInfo(final String componentManufacturer,
-                             final String componentModel,
-                             final String componentRevision) {
-        super(componentManufacturer, componentModel, null,
-                componentRevision);
-    }
-}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BaseboardComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BaseboardComponentInfo.java
deleted file mode 100644
index af9750610..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BaseboardComponentInfo.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package hirs.attestationca.persist.entity.userdefined.info.component;
-
-import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
-import hirs.utils.enums.ComponentType;
-import jakarta.persistence.DiscriminatorValue;
-import jakarta.persistence.Entity;
-import lombok.NoArgsConstructor;
-
-/**
- * Class to hold information about baseboard components.
- */
-@NoArgsConstructor
-@Entity
-@DiscriminatorValue(value = ComponentType.Values.BASEBOARD)
-public class BaseboardComponentInfo extends ComponentInfo {
-
-    /**
-     * Constructor.
-     *
-     * @param componentManufacturer Component Manufacturer (must not be null)
-     * @param componentModel        Component Model (must not be null)
-     * @param componentSerial       Component Serial Number (can be null)
-     * @param componentRevision     Component Revision or Version (can be null)
-     */
-    public BaseboardComponentInfo(final String componentManufacturer,
-                                  final String componentModel,
-                                  final String componentSerial,
-                                  final String componentRevision) {
-        super(componentManufacturer, componentModel, componentSerial,
-                componentRevision);
-    }
-}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ChassisComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ChassisComponentInfo.java
deleted file mode 100644
index b26a3f18c..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ChassisComponentInfo.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package hirs.attestationca.persist.entity.userdefined.info.component;
-
-import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
-import hirs.utils.enums.ComponentType;
-import jakarta.persistence.DiscriminatorValue;
-import jakarta.persistence.Entity;
-import lombok.NoArgsConstructor;
-
-/**
- * Class to hold chassis component information.
- */
-@NoArgsConstructor
-@Entity
-@DiscriminatorValue(value = ComponentType.Values.CHASSIS)
-public class ChassisComponentInfo extends ComponentInfo {
-
-    /**
-     * Constructor.
-     *
-     * @param componentManufacturer Component Manufacturer (must not be null)
-     * @param componentModel        Component Model (must not be null)
-     * @param componentSerial       Component Serial Number (can be null)
-     * @param componentRevision     Component Revision or Version (can be null)
-     */
-    public ChassisComponentInfo(final String componentManufacturer,
-                                final String componentModel,
-                                final String componentSerial,
-                                final String componentRevision) {
-        super(componentManufacturer, componentModel,
-                componentSerial, componentRevision);
-    }
-}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/HardDriveComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/HardDriveComponentInfo.java
deleted file mode 100644
index fe5f0846a..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/HardDriveComponentInfo.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package hirs.attestationca.persist.entity.userdefined.info.component;
-
-import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
-import hirs.utils.enums.ComponentType;
-import jakarta.persistence.DiscriminatorValue;
-import jakarta.persistence.Entity;
-import lombok.NoArgsConstructor;
-
-/**
- * Class to hold hard drive component information.
- */
-@NoArgsConstructor
-@Entity
-@DiscriminatorValue(value = ComponentType.Values.HARD_DRIVE)
-public class HardDriveComponentInfo extends ComponentInfo {
-
-    /**
-     * Constructor.
-     *
-     * @param componentManufacturer Component Manufacturer (must not be null)
-     * @param componentModel        Component Model (must not be null)
-     * @param componentSerial       Component Serial Number (can be null)
-     * @param componentRevision     Component Revision or Version (can be null)
-     */
-    public HardDriveComponentInfo(final String componentManufacturer,
-                                  final String componentModel,
-                                  final String componentSerial,
-                                  final String componentRevision) {
-        super(componentManufacturer, componentModel,
-                componentSerial, componentRevision);
-    }
-}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/MemoryComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/MemoryComponentInfo.java
deleted file mode 100644
index 5e794601d..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/MemoryComponentInfo.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package hirs.attestationca.persist.entity.userdefined.info.component;
-
-import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
-import hirs.utils.enums.ComponentType;
-import jakarta.persistence.DiscriminatorValue;
-import jakarta.persistence.Entity;
-import lombok.NoArgsConstructor;
-
-/**
- * Class to hold memory component information.
- */
-@NoArgsConstructor
-@Entity
-@DiscriminatorValue(value = ComponentType.Values.MEMORY)
-public class MemoryComponentInfo extends ComponentInfo {
-
-    /**
-     * Constructor.
-     *
-     * @param componentManufacturer Component Manufacturer (must not be null)
-     * @param componentModel        Component Model (must not be null)
-     * @param componentSerial       Component Serial Number (can be null)
-     * @param componentRevision     Component Revision or Version (can be null)
-     */
-    public MemoryComponentInfo(final String componentManufacturer,
-                               final String componentModel,
-                               final String componentSerial,
-                               final String componentRevision) {
-        super(componentManufacturer, componentModel,
-                componentSerial, componentRevision);
-    }
-}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/NICComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/NICComponentInfo.java
deleted file mode 100644
index 8f15c72cc..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/NICComponentInfo.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package hirs.attestationca.persist.entity.userdefined.info.component;
-
-import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
-import hirs.utils.enums.ComponentType;
-import jakarta.persistence.DiscriminatorValue;
-import jakarta.persistence.Entity;
-import lombok.NoArgsConstructor;
-
-/**
- * Class to hold Network Interface Card (NIC) component information.
- */
-@NoArgsConstructor
-@Entity
-@DiscriminatorValue(value = ComponentType.Values.NIC)
-public class NICComponentInfo extends ComponentInfo {
-
-    /**
-     * Constructor.
-     *
-     * @param componentManufacturer Component Manufacturer (must not be null)
-     * @param componentModel        Component Model (must not be null)
-     * @param componentSerial       Component Serial Number (can be null)
-     * @param componentRevision     Component Revision or Version (can be null)
-     */
-    public NICComponentInfo(final String componentManufacturer,
-                            final String componentModel,
-                            final String componentSerial,
-                            final String componentRevision) {
-        super(componentManufacturer, componentModel,
-                componentSerial, componentRevision);
-    }
-}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ProcessorComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ProcessorComponentInfo.java
deleted file mode 100644
index a2d53f254..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ProcessorComponentInfo.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package hirs.attestationca.persist.entity.userdefined.info.component;
-
-import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
-import hirs.utils.enums.ComponentType;
-import jakarta.persistence.DiscriminatorValue;
-import jakarta.persistence.Entity;
-import lombok.NoArgsConstructor;
-
-/**
- * Class to hold processor component information.
- */
-@NoArgsConstructor
-@Entity
-@DiscriminatorValue(value = ComponentType.Values.PROCESSOR)
-public class ProcessorComponentInfo extends ComponentInfo {
-
-    /**
-     * Constructor.
-     *
-     * @param componentManufacturer Component Manufacturer (must not be null)
-     * @param componentModel        Component Model (must not be null)
-     * @param componentSerial       Component Serial Number (can be null)
-     * @param componentRevision     Component Revision or Version (can be null)
-     */
-    public ProcessorComponentInfo(final String componentManufacturer,
-                                  final String componentModel,
-                                  final String componentSerial,
-                                  final String componentRevision) {
-        super(componentManufacturer, componentModel,
-                componentSerial, componentRevision);
-    }
-}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/package-info.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/package-info.java
deleted file mode 100644
index a7f241713..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package hirs.attestationca.persist.entity.userdefined.info.component;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java
index ae22d14ab..77f6a1f55 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java
@@ -16,7 +16,6 @@
 public final class CredentialManagementHelper {
 
     private CredentialManagementHelper() {
-
     }
 
     /**
@@ -48,7 +47,7 @@ public static EndorsementCredential storeEndorsementCredential(
             );
         }
 
-        log.info("Parsing Endorsement Credential of length " + endorsementBytes.length);
+        log.info("Parsing Endorsement Credential of length {}", endorsementBytes.length);
 
         EndorsementCredential endorsementCredential;
         try {
@@ -58,16 +57,18 @@ public static EndorsementCredential storeEndorsementCredential(
             log.error(iae.getMessage());
             throw iae;
         }
+
         int certificateHash = endorsementCredential.getCertificateHash();
         EndorsementCredential existingCredential = (EndorsementCredential) certificateRepository
                 .findByCertificateHash(certificateHash);
+
         if (existingCredential == null) {
-            log.info("No Endorsement Credential found with hash: " + certificateHash);
+            log.info("No Endorsement Credential found with hash: {}", certificateHash);
             endorsementCredential.setDeviceName(deviceName);
             return certificateRepository.save(endorsementCredential);
         } else if (existingCredential.isArchived()) {
-            // if the EK is stored in the DB and it's archived, unarchive.
-            log.info("Unarchiving credential");
+            // if the EK is stored in the DB and it's archived, un-archive it.
+            log.info("Un-archiving endorsement credential");
             existingCredential.restore();
             existingCredential.resetCreateTime();
             certificateRepository.save(existingCredential);
@@ -102,15 +103,19 @@ public static PlatformCredential storePlatformCredential(
             );
         }
 
-        log.info("Parsing Platform Credential of length " + platformBytes.length);
+        log.info("Parsing Platform Credential of length {}", platformBytes.length);
+
         try {
             PlatformCredential platformCredential =
                     PlatformCredential.parseWithPossibleHeader(platformBytes);
+
             if (platformCredential == null) {
                 return null;
             }
+
             PlatformCredential existingCredential = (PlatformCredential) certificateRepository
                     .findByCertificateHash(platformCredential.getCertificateHash());
+
             if (existingCredential == null) {
                 if (platformCredential.getPlatformSerial() != null) {
                     List certificates = certificateRepository
@@ -121,10 +126,10 @@ public static PlatformCredential storePlatformCredential(
                             if (pc.isPlatformBase() && platformCredential.isPlatformBase()) {
                                 // found a base in the database associated with
                                 // parsed certificate
-                                log.error(String.format("Base certificate stored"
+                                log.error("Base certificate stored"
                                                 + " in database with same platform"
-                                                + "serial number. (%s)",
-                                        platformCredential.getPlatformSerial()));
+                                                + "serial number. ({})",
+                                        platformCredential.getPlatformSerial());
                                 return null;
                             }
                         }
@@ -133,8 +138,8 @@ public static PlatformCredential storePlatformCredential(
                 platformCredential.setDeviceName(deviceName);
                 return certificateRepository.save(platformCredential);
             } else if (existingCredential.isArchived()) {
-                // if the PC is stored in the DB and it's archived, unarchive.
-                log.info("Unarchiving credential");
+                // if the PC is stored in the DB and it's archived, un-archive it.
+                log.info("Un-archiving platform credential");
                 existingCredential.restore();
                 certificateRepository.save(existingCredential);
                 return existingCredential;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java
index e77842852..7ee8e36a6 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java
@@ -98,9 +98,10 @@ public static SupplyChainValidation evaluatePlatformCredentialStatus(
                 = SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL;
 
         if (platformCredential == null) {
-            log.error("No platform credential to validate");
+            log.error("No platform credential to validate while evaluating platform credential status");
             return buildValidationRecord(validationType,
-                    AppraisalStatus.Status.FAIL, "Empty Platform credential", null, Level.ERROR);
+                    AppraisalStatus.Status.FAIL, "Empty Platform credential", null,
+                    Level.ERROR);
         }
 
         log.info("Validating Platform Credential");
@@ -144,7 +145,8 @@ public static SupplyChainValidation evaluatePCAttributesStatus(
                 = SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES;
 
         if (platformCredential == null) {
-            log.error("No platform credential to validate");
+            log.error("No platform credential to validate while evaluating platform credential attributes " +
+                    "status");
             return buildValidationRecord(validationType,
                     AppraisalStatus.Status.FAIL, "Platform credential is missing",
                     null, Level.ERROR);
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
index 0c25b1f57..3f01f18d0 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
@@ -234,11 +234,11 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0(
 
         if (platformCredential.getPlatformConfigurationV1() != null) {
 
-            // Retrieve the list of all version 2 component identifiers from the Platform Credential
+            // Retrieve the list of all version 1 component identifiers from the Platform Credential
             List allPcComponents
                     = new ArrayList<>(platformCredential.getComponentIdentifiers());
 
-            // All components listed in the Platform Credential must have a manufacturer and model
+            // All V1 components listed in the Platform Credential must have a manufacturer and model
             for (ComponentIdentifier pcComponent : allPcComponents) {
 
                 fieldValidation = !hasEmptyValueForRequiredField("componentManufacturer",
@@ -263,8 +263,30 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0(
         } else if (platformCredential.getPlatformConfigurationV2() != null) {
 
             // Retrieve the list of all version 2 component identifiers from the Platform Credential
-            List allPcComponents
+            List allV2PcComponents
                     = new ArrayList<>(platformCredential.getComponentIdentifiersV2());
+
+            // All V2 components listed in the Platform Credential must have a manufacturer and model
+            for (ComponentIdentifierV2 pcComponent : allV2PcComponents) {
+
+                fieldValidation = !hasEmptyValueForRequiredField("componentManufacturer",
+                        pcComponent.getComponentManufacturer());
+
+                if (!fieldValidation) {
+                    resultMessage.append("Component manufacturer is empty\n");
+                }
+
+                passesValidation &= fieldValidation;
+
+                fieldValidation = !hasEmptyValueForRequiredField("componentModel",
+                        pcComponent.getComponentModel());
+
+                if (!fieldValidation) {
+                    resultMessage.append("Component model is empty\n");
+                }
+
+                passesValidation &= fieldValidation;
+            }
         }
 
 
@@ -452,7 +474,7 @@ private static String validateV2PlatformCredentialAttributes(
         for (ComponentInfo cInfo : allDeviceInfoComponents) {
             for (ComponentIdentifier cId : fullDeltaChainComponents) {
                 ciV2 = (ComponentIdentifierV2) cId;
-                if (cInfo.getComponentClass().contains(
+                if (cInfo.getComponentClassValue().contains(
                         ciV2.getComponentClass().getComponentIdentifier())
                         && isMatch(cId, cInfo)) {
                     subCompIdList.remove(cId);
@@ -927,7 +949,7 @@ private static List checkComponentClassMap(
         Map> componentDeviceMap = new HashMap<>();
         componentInfos.forEach((componentInfo) -> {
             List innerList;
-            String componentClass = componentInfo.getComponentClass();
+            String componentClass = componentInfo.getComponentClassValue();
             if (componentDeviceMap.containsKey(componentClass)) {
                 innerList = componentDeviceMap.get(componentClass);
                 innerList.add(componentInfo);
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java
index bb9181d14..040c30d36 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java
@@ -296,17 +296,23 @@ public static List getComponentInfoFromPaccorOutput(final String
                             getJSONNodeValueAsText(next, "REVISION")));
                 } else {
                     // version 2
-                    String componentClass = StringUtils.EMPTY;
+                    String componentClassValue = StringUtils.EMPTY;
+                    String componentClassRegistry = StringUtils.EMPTY;
+
                     for (JsonNode subNode : compClassNodes) {
-                        componentClass = getJSONNodeValueAsText(subNode,
+                        componentClassValue = getJSONNodeValueAsText(subNode,
                                 "COMPONENTCLASSVALUE");
+                        componentClassRegistry = getJSONNodeValueAsText(subNode,
+                                "COMPONENTCLASSREGISTRY");
                     }
+
                     componentInfoList.add(new ComponentInfo(hostName,
                             getJSONNodeValueAsText(next, "MANUFACTURER"),
                             getJSONNodeValueAsText(next, "MODEL"),
                             getJSONNodeValueAsText(next, "SERIAL"),
                             getJSONNodeValueAsText(next, "REVISION"),
-                            componentClass));
+                            componentClassValue,
+                            componentClassRegistry));
                 }
             }
         }
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
index 62d8e09b7..4e9c61fc7 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
@@ -11,7 +11,6 @@
 import hirs.attestationca.persist.entity.userdefined.info.NetworkInfo;
 import hirs.attestationca.persist.entity.userdefined.info.OSInfo;
 import hirs.attestationca.persist.entity.userdefined.info.TPMInfo;
-import hirs.attestationca.persist.entity.userdefined.info.component.NICComponentInfo;
 import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
 import hirs.attestationca.persist.enums.AppraisalStatus;
 import hirs.utils.enums.DeviceInfoEnums;
@@ -1292,7 +1291,7 @@ public final void testEndorsementDnNotEquals() throws URISyntaxException, IOExce
      */
     @Test
     public void testMatcher() {
-        NICComponentInfo nicComponentInfo = new NICComponentInfo("Intel Corporation",
+        ComponentInfo nicComponentInfo = new ComponentInfo("Intel Corporation",
                 "Ethernet Connection I217-V",
                 "23:94:17:ba:86:5e",
                 "00");
@@ -1984,7 +1983,7 @@ public final void testValidateDeltaPlatformCredentialAttributes()
 //        ComponentIdentifierV2 ciV21Faulty = new ComponentIdentifierV2();
 //        ComponentIdentifierV2 ciV22Faulty = new ComponentIdentifierV2();
 //        ciV21Faulty.setComponentManufacturer(compId2.getComponentManufacturer());
-//        ciV21Faulty.setComponentClass(compId2.getComponentClass());
+//        ciV21Faulty.setComponentClass(compId2.getComponentClassValue());
 //        ciV21Faulty.setComponentModel(compId2.getComponentModel());
 //        ciV21Faulty.setComponentSerial(compId2.getComponentSerial());
 //        ciV21Faulty.setComponentRevision(compId2.getComponentRevision());
@@ -1993,7 +1992,7 @@ public final void testValidateDeltaPlatformCredentialAttributes()
 //        ciV21Faulty.setComponentAddresses(compId2.getComponentAddresses());
 //        ciV21Faulty.setAttributeStatus(AttributeStatus.REMOVED);
 //        ciV22Faulty.setComponentManufacturer(compId3.getComponentManufacturer());
-//        ciV22Faulty.setComponentClass(compId3.getComponentClass());
+//        ciV22Faulty.setComponentClass(compId3.getComponentClassValue());
 //        ciV22Faulty.setComponentModel(compId3.getComponentModel());
 //        ciV22Faulty.setComponentSerial(compId3.getComponentSerial());
 //        ciV22Faulty.setComponentRevision(compId3.getComponentRevision());
diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java
index a22a52488..9329a5755 100644
--- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java
+++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java
@@ -406,9 +406,10 @@ public static HashMap getPlatformInformation(final UUID uuid,
                 //Component Identifier - attempt to translate hardware IDs
                 List componentIdentifiers =
                         platformConfigurationV2.getComponentIdentifiers();
-         /*       if (PciIds.DB.isReady()) {
-                    componentIdentifiers = AcaPciIds.translate(componentIdentifiers);
-                }*/
+                if (PciIds.DB.isReady()) {
+                    // todo esacost
+                    //componentIdentifiers = AcaPciIds.translate(componentIdentifiers);
+                }
                 data.put("componentsIdentifier", componentIdentifiers);
                 //Component Identifier URI
                 data.put("componentsIdentifierURI", platformConfigurationV2

From 6215a6675bfed76d5007d32365bc9c49e9c2dc11 Mon Sep 17 00:00:00 2001
From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Fri, 7 Feb 2025 17:45:47 -0500
Subject: [PATCH 06/14] issue_896:I believe I have finished the issue. Further
 testing needs to be done. Will put in a WIP PR for now.

---
 .../userdefined/info/ComponentInfo.java       |  13 +-
 .../provision/IdentityClaimProcessor.java     |   6 +-
 .../persist/service/ValidationService.java    |   4 +-
 .../CertificateAttributeScvValidator.java     |  14 +-
 .../CertificatePageController.java            | 202 +++++++++---------
 .../utils/CertificateStringMapBuilder.java    |  34 ++-
 6 files changed, 154 insertions(+), 119 deletions(-)

diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/ComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/ComponentInfo.java
index cd279d41c..7ab181118 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/ComponentInfo.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/ComponentInfo.java
@@ -121,12 +121,13 @@ public ComponentInfo(final String deviceName,
     /**
      * Constructor.
      *
-     * @param deviceName            the host machine associated with this component.
-     * @param componentManufacturer Component Manufacturer (must not be null)
-     * @param componentModel        Component Model (must not be null)
-     * @param componentSerial       Component Serial Number (can be null)
-     * @param componentRevision     Component Revision or Version (can be null)
-     * @param componentClassValue   Component Class Value (can be null)
+     * @param deviceName             the host machine associated with this component.
+     * @param componentManufacturer  Component Manufacturer (must not be null)
+     * @param componentModel         Component Model (must not be null)
+     * @param componentSerial        Component Serial Number (can be null)
+     * @param componentRevision      Component Revision or Version (can be null)
+     * @param componentClassValue    Component Class Value (can be null)
+     * @param componentClassRegistry Component Class Registry (can be null)
      */
     public ComponentInfo(final String deviceName,
                          final String componentManufacturer,
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
index 195b00135..1850a1cda 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
@@ -752,7 +752,6 @@ private void savePlatformComponents(final Certificate certificate) throws IOExce
             platformCredential = (PlatformCredential) certificate;
             ComponentResult componentResult;
 
-            // if the provided platform certificate is using version 1 Platform Configuration
             if (platformCredential.getPlatformConfigurationV1() != null) {
                 for (ComponentIdentifier componentIdentifier : platformCredential
                         .getComponentIdentifiers()) {
@@ -764,10 +763,7 @@ private void savePlatformComponents(final Certificate certificate) throws IOExce
                     componentResult.setDelta(!platformCredential.isPlatformBase());
                     componentResultRepository.save(componentResult);
                 }
-            }
-            
-            // if the provided platform certificate is using version 2 Platform Configuration
-            else if (platformCredential.getPlatformConfigurationV2() != null) {
+            } else if (platformCredential.getPlatformConfigurationV2() != null) {
                 for (ComponentIdentifierV2 componentIdentifierV2 : platformCredential
                         .getComponentIdentifiersV2()) {
                     componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java
index 7ee8e36a6..26ceb8f83 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java
@@ -145,8 +145,8 @@ public static SupplyChainValidation evaluatePCAttributesStatus(
                 = SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES;
 
         if (platformCredential == null) {
-            log.error("No platform credential to validate while evaluating platform credential attributes " +
-                    "status");
+            log.error("No platform credential to validate while evaluating platform credential attributes "
+                    + "status");
             return buildValidationRecord(validationType,
                     AppraisalStatus.Status.FAIL, "Platform credential is missing",
                     null, Level.ERROR);
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
index 3f01f18d0..d769fbd81 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
@@ -286,10 +286,22 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0(
                 }
 
                 passesValidation &= fieldValidation;
+
+                if (pcComponent.getComponentClass() == null) {
+                    passesValidation = false;
+                } else {
+                    fieldValidation = !hasEmptyValueForRequiredField("componentClassRegistry",
+                            pcComponent.getComponentClass().getRegistryType());
+
+                    if (!fieldValidation) {
+                        resultMessage.append("Component class registry is empty\n");
+                    }
+
+                    passesValidation &= fieldValidation;
+                }
             }
         }
 
-
         // populate componentResults list
         List componentResults = componentResultRepository
                 .findByCertificateSerialNumberAndBoardSerialNumber(
diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java
index 56e95125c..6dad22a24 100644
--- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java
+++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java
@@ -283,107 +283,115 @@ public void modify(final CriteriaQuery criteriaQuery) {
         // special parsing for platform credential
         // Add the EndorsementCredential for each PlatformCredential based on the
         // serial number. (pc.HolderSerialNumber = ec.SerialNumber)
-        if (certificateType.equals(PLATFORMCREDENTIAL)) {
-            FilteredRecordsList records = new FilteredRecordsList<>();
-            org.springframework.data.domain.Page pagedResult =
-                    this.platformCertificateRepository.findByArchiveFlag(false, paging);
-
-            if (pagedResult.hasContent()) {
-                records.addAll(pagedResult.getContent());
-                records.setRecordsTotal(pagedResult.getContent().size());
-            } else {
-                records.setRecordsTotal(input.getLength());
-            }
+        switch (certificateType) {
+            case PLATFORMCREDENTIAL -> {
+                FilteredRecordsList records = new FilteredRecordsList<>();
+                org.springframework.data.domain.Page pagedResult =
+                        this.platformCertificateRepository.findByArchiveFlag(false, paging);
+
+                if (pagedResult.hasContent()) {
+                    records.addAll(pagedResult.getContent());
+                    records.setRecordsTotal(pagedResult.getContent().size());
+                } else {
+                    records.setRecordsTotal(input.getLength());
+                }
 
-            records.setRecordsFiltered(platformCertificateRepository.findByArchiveFlag(false).size());
-            EndorsementCredential associatedEC;
+                records.setRecordsFiltered(platformCertificateRepository.findByArchiveFlag(false).size());
+                EndorsementCredential associatedEC;
 
-            if (!records.isEmpty()) {
-                // loop all the platform certificates
-                for (int i = 0; i < records.size(); i++) {
-                    PlatformCredential pc = records.get(i);
-                    // find the EC using the PC's "holder serial number"
-                    associatedEC = this.endorsementCredentialRepository
-                            .findBySerialNumber(pc.getHolderSerialNumber());
+                if (!records.isEmpty()) {
+                    // loop all the platform certificates
+                    for (PlatformCredential pc : records) {
+                        // find the EC using the PC's "holder serial number"
+                        associatedEC = this.endorsementCredentialRepository
+                                .findBySerialNumber(pc.getHolderSerialNumber());
 
-                    if (associatedEC != null) {
-                        log.debug("EC ID for holder s/n {} = {}", pc
-                                .getHolderSerialNumber(), associatedEC.getId());
-                    }
+                        if (associatedEC != null) {
+                            log.debug("EC ID for holder s/n {} = {}", pc
+                                    .getHolderSerialNumber(), associatedEC.getId());
+                        }
 
-                    pc.setEndorsementCredential(associatedEC);
+                        pc.setEndorsementCredential(associatedEC);
+                    }
                 }
-            }
 
-            log.debug("Returning list of size: {}", records.size());
-            return new DataTableResponse<>(records, input);
-        } else if (certificateType.equals(ENDORSEMENTCREDENTIAL)) {
-            FilteredRecordsList records = new FilteredRecordsList<>();
-            org.springframework.data.domain.Page pagedResult =
-                    this.endorsementCredentialRepository.findByArchiveFlag(false, paging);
-
-            if (pagedResult.hasContent()) {
-                records.addAll(pagedResult.getContent());
-                records.setRecordsTotal(pagedResult.getContent().size());
-            } else {
-                records.setRecordsTotal(input.getLength());
+                log.debug("Returning the size of the list of platform credentials: {}", records.size());
+                return new DataTableResponse<>(records, input);
             }
+            case ENDORSEMENTCREDENTIAL -> {
+                FilteredRecordsList records = new FilteredRecordsList<>();
+                org.springframework.data.domain.Page pagedResult =
+                        this.endorsementCredentialRepository.findByArchiveFlag(false, paging);
+
+                if (pagedResult.hasContent()) {
+                    records.addAll(pagedResult.getContent());
+                    records.setRecordsTotal(pagedResult.getContent().size());
+                } else {
+                    records.setRecordsTotal(input.getLength());
+                }
 
-            records.setRecordsFiltered(endorsementCredentialRepository.findByArchiveFlag(false).size());
-
-            log.debug("Returning list of size: {}", records.size());
-            return new DataTableResponse<>(records, input);
-        } else if (certificateType.equals(TRUSTCHAIN)) {
-            FilteredRecordsList records = new FilteredRecordsList<>();
-            org.springframework.data.domain.Page pagedResult =
-                    this.caCredentialRepository.findByArchiveFlag(false, paging);
+                records.setRecordsFiltered(endorsementCredentialRepository.findByArchiveFlag(false).size());
 
-            if (pagedResult.hasContent()) {
-                records.addAll(pagedResult.getContent());
-                records.setRecordsTotal(pagedResult.getContent().size());
-            } else {
-                records.setRecordsTotal(input.getLength());
+                log.debug("Returning the size of the list of endorsement credentials: {}", records.size());
+                return new DataTableResponse<>(records, input);
             }
+            case TRUSTCHAIN -> {
+                FilteredRecordsList records = new FilteredRecordsList<>();
+                org.springframework.data.domain.Page pagedResult =
+                        this.caCredentialRepository.findByArchiveFlag(false, paging);
+
+                if (pagedResult.hasContent()) {
+                    records.addAll(pagedResult.getContent());
+                    records.setRecordsTotal(pagedResult.getContent().size());
+                } else {
+                    records.setRecordsTotal(input.getLength());
+                }
 
-            records.setRecordsFiltered(caCredentialRepository.findByArchiveFlag(false).size());
-
-            log.debug("Returning list of size: {}", records.size());
-            return new DataTableResponse<>(records, input);
-        } else if (certificateType.equals(ISSUEDCERTIFICATES)) {
-            FilteredRecordsList records = new FilteredRecordsList<>();
-            org.springframework.data.domain.Page pagedResult =
-                    this.issuedCertificateRepository.findByArchiveFlag(false, paging);
+                records.setRecordsFiltered(caCredentialRepository.findByArchiveFlag(false).size());
 
-            if (pagedResult.hasContent()) {
-                records.addAll(pagedResult.getContent());
-                records.setRecordsTotal(pagedResult.getContent().size());
-            } else {
-                records.setRecordsTotal(input.getLength());
+                log.debug("Returning the size of the list of certificate trust chains: {}", records.size());
+                return new DataTableResponse<>(records, input);
             }
+            case ISSUEDCERTIFICATES -> {
+                FilteredRecordsList records = new FilteredRecordsList<>();
+                org.springframework.data.domain.Page pagedResult =
+                        this.issuedCertificateRepository.findByArchiveFlag(false, paging);
+
+                if (pagedResult.hasContent()) {
+                    records.addAll(pagedResult.getContent());
+                    records.setRecordsTotal(pagedResult.getContent().size());
+                } else {
+                    records.setRecordsTotal(input.getLength());
+                }
 
-            records.setRecordsFiltered(issuedCertificateRepository.findByArchiveFlag(false).size());
-
-            log.debug("Returning list of size: " + records.size());
-            return new DataTableResponse<>(records, input);
-        } else if (certificateType.equals(IDEVIDCERTIFICATE)) {
-            FilteredRecordsList records = new FilteredRecordsList();
-            org.springframework.data.domain.Page pagedResult =
-                    this.iDevIDCertificateRepository.findByArchiveFlag(false, paging);
+                records.setRecordsFiltered(issuedCertificateRepository.findByArchiveFlag(false).size());
 
-            if (pagedResult.hasContent()) {
-                records.addAll(pagedResult.getContent());
-                records.setRecordsTotal(pagedResult.getContent().size());
-            } else {
-                records.setRecordsTotal(input.getLength());
+                log.debug("Returning the size of the list of issued certificates: {}", records.size());
+                return new DataTableResponse<>(records, input);
             }
+            case IDEVIDCERTIFICATE -> {
+                FilteredRecordsList records = new FilteredRecordsList();
+                org.springframework.data.domain.Page pagedResult =
+                        this.iDevIDCertificateRepository.findByArchiveFlag(false, paging);
+
+                if (pagedResult.hasContent()) {
+                    records.addAll(pagedResult.getContent());
+                    records.setRecordsTotal(pagedResult.getContent().size());
+                } else {
+                    records.setRecordsTotal(input.getLength());
+                }
 
-            records.setRecordsFiltered(iDevIDCertificateRepository.findByArchiveFlag(false).size());
+                records.setRecordsFiltered(iDevIDCertificateRepository.findByArchiveFlag(false).size());
 
-            log.debug("Returning list of size: {}", records.size());
-            return new DataTableResponse<>(records, input);
+                log.debug("Returning the size of the list of IDEVID certificates: {}", records.size());
+                return new DataTableResponse<>(records, input);
+            }
+            default -> {
+                log.error("Cannot provide the size of the records because the"
+                        + "provided certificate type does not exist.");
+                return new DataTableResponse<>(new FilteredRecordsList<>(), input);
+            }
         }
-
-        return new DataTableResponse<>(new FilteredRecordsList<>(), input);
     }
 
     /**
@@ -509,7 +517,7 @@ public void download(
             @RequestParam final String id,
             final HttpServletResponse response)
             throws IOException {
-        log.info("Handling request to download " + id);
+        log.info("Handling request to download {}", id);
 
         try {
             UUID uuid = UUID.fromString(id);
@@ -692,11 +700,13 @@ public void ekBulkDownload(final HttpServletResponse response)
     }
 
     /**
-     * @param zipOut
-     * @param certificates
-     * @param singleFileName
-     * @return
-     * @throws IOException
+     * Helper method that packages a collection of certificates into a zip file.
+     *
+     * @param zipOut         zip outputs stream
+     * @param certificates   collection of certificates
+     * @param singleFileName zip file name
+     * @return zip outputs stream
+     * @throws IOException if there are any issues packaging or downloading the zip file
      */
     private ZipOutputStream bulkDownload(final ZipOutputStream zipOut,
                                          final List certificates,
@@ -729,9 +739,8 @@ private ZipOutputStream bulkDownload(final ZipOutputStream zipOut,
      * table, false otherwise.
      */
     private boolean hasDeviceTableToJoin(final String certificateType) {
-        boolean hasDevice = !certificateType.equals(TRUSTCHAIN);
         // Trust_Chain Credential do not contain the device table to join.
-        return hasDevice;
+        return !certificateType.equals(TRUSTCHAIN);
     }
 
     /**
@@ -1029,9 +1038,7 @@ private void parseAndSaveComponentResults(final Certificate certificate) throws
             if (componentResults.isEmpty()) {
                 ComponentResult componentResult;
 
-                // if the provided platform certificate is using version 1 Platform Configuration
                 if (platformCredential.getPlatformConfigurationV1() != null) {
-
                     for (ComponentIdentifier componentIdentifier : platformCredential
                             .getComponentIdentifiers()) {
                         componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
@@ -1042,11 +1049,7 @@ private void parseAndSaveComponentResults(final Certificate certificate) throws
                         componentResult.setDelta(!platformCredential.isPlatformBase());
                         componentResultRepository.save(componentResult);
                     }
-                }
-                
-                // if the provided platform certificate is using version 2 Platform Configuration
-                else if (platformCredential.getPlatformConfigurationV2() != null) {
-
+                } else if (platformCredential.getPlatformConfigurationV2() != null) {
                     for (ComponentIdentifierV2 componentIdentifierV2 : platformCredential
                             .getComponentIdentifiersV2()) {
                         componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
@@ -1068,6 +1071,11 @@ else if (platformCredential.getPlatformConfigurationV2() != null) {
         }
     }
 
+    /**
+     * Helper method that deletes component results based on the provided platform serial number.
+     *
+     * @param platformSerial platform serial number
+     */
     private void deleteComponentResults(final String platformSerial) {
         List componentResults = componentResultRepository
                 .findByBoardSerialNumber(platformSerial);
diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java
index 9329a5755..b2cc472a2 100644
--- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java
+++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java
@@ -10,6 +10,8 @@
 import hirs.attestationca.persist.entity.userdefined.certificate.IDevIDCertificate;
 import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate;
 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.PlatformConfigurationV1;
 import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
 import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.PlatformConfigurationV2;
 import hirs.attestationca.persist.util.AcaPciIds;
@@ -401,16 +403,31 @@ public static HashMap getPlatformInformation(final UUID uuid,
             data.put("componentResults", compResults);
 
             //Get platform Configuration values and set map with it
-            PlatformConfigurationV2 platformConfigurationV2 = certificate.getPlatformConfigurationV2();
-            if (platformConfigurationV2 != null) {
-                //Component Identifier - attempt to translate hardware IDs
-                List componentIdentifiers =
-                        platformConfigurationV2.getComponentIdentifiers();
+            if (certificate.getPlatformConfigurationV1() != null) {
+                PlatformConfigurationV1 platformConfigurationV1 = certificate.getPlatformConfigurationV1();
+
+                List componentIdentifiersV1 =
+                        platformConfigurationV1.getComponentIdentifiers();
+
                 if (PciIds.DB.isReady()) {
-                    // todo esacost
-                    //componentIdentifiers = AcaPciIds.translate(componentIdentifiers);
+                    componentIdentifiersV1 = AcaPciIds.translate(componentIdentifiersV1);
                 }
-                data.put("componentsIdentifier", componentIdentifiers);
+                //Component Identifiers
+                data.put("componentsIdentifier", componentIdentifiersV1);
+
+                //Platform Properties
+                data.put("platformProperties", platformConfigurationV1.getPlatformProperties());
+                //Platform Properties URI
+                data.put("platformPropertiesURI", platformConfigurationV1.getPlatformPropertiesUri());
+
+            } else if (certificate.getPlatformConfigurationV2() != null) {
+                PlatformConfigurationV2 platformConfigurationV2 = certificate.getPlatformConfigurationV2();
+                
+                //Component Identifiers
+                List componentIdentifiersV2 =
+                        platformConfigurationV2.getComponentIdentifiers();
+
+                data.put("componentsIdentifier", componentIdentifiersV2);
                 //Component Identifier URI
                 data.put("componentsIdentifierURI", platformConfigurationV2
                         .getComponentIdentifiersUri());
@@ -419,6 +436,7 @@ public static HashMap getPlatformInformation(final UUID uuid,
                 //Platform Properties URI
                 data.put("platformPropertiesURI", platformConfigurationV2.getPlatformPropertiesUri());
             }
+
             //TBB Security Assertion
             data.put("tbbSecurityAssertion", certificate.getTBBSecurityAssertion());
 

From 1b502298e2ded2544da4ca41d39c71ef5aaaa474 Mon Sep 17 00:00:00 2001
From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Mon, 10 Feb 2025 15:57:31 -0500
Subject: [PATCH 07/14] issue_896: Made some more changes after viewing PR

---
 .../certificate/attributes/ComponentIdentifier.java           | 4 +++-
 package/linux/systemd/hirs-aca.service                        | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java
index 41fbd2ebc..0598f76f4 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java
@@ -236,7 +236,9 @@ public String toString() {
                     .map(Object::toString)
                     .collect(Collectors.joining(",")));
         }
-        sb.append(", componentPlatformCert=");
+        if (sb.charAt(sb.length() - 1) == ',') {
+            sb.deleteCharAt(sb.length() - 1);
+        }
         sb.append("}");
 
         return sb.toString();
diff --git a/package/linux/systemd/hirs-aca.service b/package/linux/systemd/hirs-aca.service
index 111fed3df..023e89f86 100644
--- a/package/linux/systemd/hirs-aca.service
+++ b/package/linux/systemd/hirs-aca.service
@@ -5,7 +5,7 @@ After=network.target
 [Service]
 User=root
 Group=root
-ExecStart=/usr/bin/bash /opt/hirs/aca/scripts/aca/aca_bootRun.sh -d -w
+ExecStart=/usr/bin/bash /opt/hirs/aca/scripts/aca/aca_bootRun.sh -w
 SuccessExitStatus=0
 Restart=always
 RestartSec=60

From 151c390202cef23a6676fab7108cef5fd86a2fa6 Mon Sep 17 00:00:00 2001
From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Tue, 11 Feb 2025 10:20:29 -0500
Subject: [PATCH 08/14] issue_896: Changed v3 to v4 in the github actions yaml
 files.

---
 .github/workflows/create_aca_images.yml       | 256 +++++++++---------
 .../dotnet_provisioner_unit_tests.yml         |   6 +-
 .github/workflows/hirs_package_linux.yml      | 104 +++----
 .github/workflows/hirs_unit_tests.yml         | 160 +++++------
 .github/workflows/rim_tests.yml               |   4 +-
 5 files changed, 265 insertions(+), 265 deletions(-)

diff --git a/.github/workflows/create_aca_images.yml b/.github/workflows/create_aca_images.yml
index 12677cb2f..9cda9434a 100644
--- a/.github/workflows/create_aca_images.yml
+++ b/.github/workflows/create_aca_images.yml
@@ -17,7 +17,7 @@ env:
   PUBLIC_IMAGE_NAME: ghcr.io/nsacyber/hirs/aca
   PUBLIC_IMAGE_TAG_LATEST: ghcr.io/nsacyber/hirs/aca:latest
   TAG_LATEST: ${{ github.event_name == 'release' || inputs.also_tag_latest }} # The public docker image will be tagged 'latest' for releases, or if this option is manually selected.
-jobs:   
+jobs:
   setup:
     runs-on: ubuntu-latest
     outputs:
@@ -27,44 +27,44 @@ jobs:
       WINDOWS_COMPAT_IMAGE_TAG: ${{ steps.setenv.outputs.WINDOWS_COMPAT_IMAGE_TAG }}
       PUBLIC_IMAGE_TAG: ${{ steps.setenv.outputs.PUBLIC_IMAGE_TAG }}
     steps:
-    - name: Set env
-      id: setenv
-      shell: bash
-      run: |
-        # Parse docker image tag from GitHub tag if available
-        if [ "${{ github.ref_type }}" = "tag" ]; then
-          # tags start with refs/tags/. Also remove v if it exists.
-          export IMAGE_TAG_VAR=${GITHUB_REF:10}
-          export IMAGE_TAG_VAR=${IMAGE_TAG_VAR//v/}
-        else
-          # Not a tag, use the commit hash. Do not tag as latest.
-          export IMAGE_TAG_VAR=${GITHUB_SHA:0:7}
-        fi
-        # To lowercase
-        export IMAGE_TAG_VAR=${IMAGE_TAG_VAR,,}
-        
-        # Save to output
-        echo "IMAGE_TAG=$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
-        echo "ROCKY_IMAGE_TAG=$IMAGE_NAME_ROCKY:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
-        echo "WINDOWS_IMAGE_TAG=$IMAGE_NAME_WINDOWS:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
-        echo "WINDOWS_COMPAT_IMAGE_TAG=$IMAGE_NAME_WINDOWS_COMPAT:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
-        echo "PUBLIC_IMAGE_TAG=$PUBLIC_IMAGE_NAME:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
-    - name: Print env
-      run: |
-        echo GITHUB_REF_NAME=${{ github.ref_name }}
-        echo DOCKERFILE_ROCKY=$DOCKERFILE_ROCKY
-        echo DOCKERFILE_WINDOWS=$DOCKERFILE_WINDOWS
-        echo IMAGE_NAME_ROCKY=$IMAGE_NAME_ROCKY
-        echo IMAGE_NAME_WINDOWS=$IMAGE_NAME_WINDOWS
-        echo IMAGE_NAME_WINDOWS_COMPAT=$IMAGE_NAME_WINDOWS_COMPAT
-        echo PUBLIC_IMAGE_NAME=$PUBLIC_IMAGE_NAME
-        echo PUBLIC_IMAGE_TAG_LATEST=$PUBLIC_IMAGE_TAG_LATEST
-        echo TAG_LATEST=$TAG_LATEST
-        echo IMAGE_TAG=${{ steps.setenv.outputs.IMAGE_TAG }}
-        echo ROCKY_IMAGE_TAG=${{ steps.setenv.outputs.ROCKY_IMAGE_TAG }}
-        echo WINDOWS_IMAGE_TAG=${{ steps.setenv.outputs.WINDOWS_IMAGE_TAG }}
-        echo WINDOWS_COMPAT_IMAGE_TAG=${{ steps.setenv.outputs.WINDOWS_COMPAT_IMAGE_TAG }}
-        echo PUBLIC_IMAGE_TAG=${{ steps.setenv.outputs.PUBLIC_IMAGE_TAG }}
+      - name: Set env
+        id: setenv
+        shell: bash
+        run: |
+          # Parse docker image tag from GitHub tag if available
+          if [ "${{ github.ref_type }}" = "tag" ]; then
+            # tags start with refs/tags/. Also remove v if it exists.
+            export IMAGE_TAG_VAR=${GITHUB_REF:10}
+            export IMAGE_TAG_VAR=${IMAGE_TAG_VAR//v/}
+          else
+            # Not a tag, use the commit hash. Do not tag as latest.
+            export IMAGE_TAG_VAR=${GITHUB_SHA:0:7}
+          fi
+          # To lowercase
+          export IMAGE_TAG_VAR=${IMAGE_TAG_VAR,,}
+          
+          # Save to output
+          echo "IMAGE_TAG=$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
+          echo "ROCKY_IMAGE_TAG=$IMAGE_NAME_ROCKY:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
+          echo "WINDOWS_IMAGE_TAG=$IMAGE_NAME_WINDOWS:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
+          echo "WINDOWS_COMPAT_IMAGE_TAG=$IMAGE_NAME_WINDOWS_COMPAT:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
+          echo "PUBLIC_IMAGE_TAG=$PUBLIC_IMAGE_NAME:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
+      - name: Print env
+        run: |
+          echo GITHUB_REF_NAME=${{ github.ref_name }}
+          echo DOCKERFILE_ROCKY=$DOCKERFILE_ROCKY
+          echo DOCKERFILE_WINDOWS=$DOCKERFILE_WINDOWS
+          echo IMAGE_NAME_ROCKY=$IMAGE_NAME_ROCKY
+          echo IMAGE_NAME_WINDOWS=$IMAGE_NAME_WINDOWS
+          echo IMAGE_NAME_WINDOWS_COMPAT=$IMAGE_NAME_WINDOWS_COMPAT
+          echo PUBLIC_IMAGE_NAME=$PUBLIC_IMAGE_NAME
+          echo PUBLIC_IMAGE_TAG_LATEST=$PUBLIC_IMAGE_TAG_LATEST
+          echo TAG_LATEST=$TAG_LATEST
+          echo IMAGE_TAG=${{ steps.setenv.outputs.IMAGE_TAG }}
+          echo ROCKY_IMAGE_TAG=${{ steps.setenv.outputs.ROCKY_IMAGE_TAG }}
+          echo WINDOWS_IMAGE_TAG=${{ steps.setenv.outputs.WINDOWS_IMAGE_TAG }}
+          echo WINDOWS_COMPAT_IMAGE_TAG=${{ steps.setenv.outputs.WINDOWS_COMPAT_IMAGE_TAG }}
+          echo PUBLIC_IMAGE_TAG=${{ steps.setenv.outputs.PUBLIC_IMAGE_TAG }}
   
   rocky-image:
     needs: setup
@@ -72,78 +72,78 @@ jobs:
     env:
       TAG: ${{ needs.setup.outputs.ROCKY_IMAGE_TAG }}
     steps:
-    - name: Checkout main
-      uses: actions/checkout@v4
-      
-    - name: Login to GitHub Container Registry
-      uses: docker/login-action@v3
-      with:
-        registry: ghcr.io
-        username: ${{ github.actor }}
-        password: ${{ secrets.GITHUB_TOKEN }}
-        
-    - name: Build and push a release Docker image for ${{ github.repository }}
-      uses: docker/build-push-action@v5
-      with:
-        context: "{{defaultContext}}:.ci/docker"
-        file: Dockerfile.${{env.DOCKERFILE_ROCKY}}
-        build-args: REF=${{ github.ref_name }}
-        tags: ${{env.TAG}}
-        push: true
-        
+      - name: Checkout main
+        uses: actions/checkout@v4
+
+      - name: Login to GitHub Container Registry
+        uses: docker/login-action@v4
+        with:
+          registry: ghcr.io
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Build and push a release Docker image for ${{ github.repository }}
+        uses: docker/build-push-action@v5
+        with:
+          context: "{{defaultContext}}:.ci/docker"
+          file: Dockerfile.${{env.DOCKERFILE_ROCKY}}
+          build-args: REF=${{ github.ref_name }}
+          tags: ${{env.TAG}}
+          push: true
+
   windows-11-image:
     needs: setup
     runs-on: windows-latest
     env:
       TAG: ${{ needs.setup.outputs.WINDOWS_IMAGE_TAG }}
     steps:
-    - name: Checkout main
-      uses: actions/checkout@v4
-      
-    - name: Login to GitHub Container Registry
-      uses: docker/login-action@v3
-      with:
-        registry: ghcr.io
-        username: ${{ github.actor }}
-        password: ${{ secrets.GITHUB_TOKEN }}
-
-    - name: Build the docker image for ${{ github.repository }}
-      run: |
-        cd ./.ci/docker
-        docker build --build-arg REF=${{ github.ref_name }} -f ./Dockerfile.${{env.DOCKERFILE_WINDOWS}} -t ${{env.TAG}} .
-    
-    - name: Push the docker image
-      run: |
-        docker push ${{env.TAG}}
-        
+      - name: Checkout main
+        uses: actions/checkout@v4
+
+      - name: Login to GitHub Container Registry
+        uses: docker/login-action@v4
+        with:
+          registry: ghcr.io
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Build the docker image for ${{ github.repository }}
+        run: |
+          cd ./.ci/docker
+          docker build --build-arg REF=${{ github.ref_name }} -f ./Dockerfile.${{env.DOCKERFILE_WINDOWS}} -t ${{env.TAG}} .
+
+      - name: Push the docker image
+        run: |
+          docker push ${{env.TAG}}
+
   windows-compat-image: # This job uses a different runner and build arg than the other windows job.
     needs: setup
     runs-on: windows-2019
     env:
       TAG: ${{ needs.setup.outputs.WINDOWS_COMPAT_IMAGE_TAG }}
     steps:
-    - name: Checkout main
-      uses: actions/checkout@v4
-
-    - name: Login to GitHub Container Registry
-      uses: docker/login-action@v3
-      with:
-        registry: ghcr.io
-        username: ${{ github.actor }}
-        password: ${{ secrets.GITHUB_TOKEN }}
-
-    - name: Build the docker image for ${{ github.repository }}
-      run: |
-        cd ./.ci/docker
-        docker build --build-arg REF=${{ github.ref_name }} -f ./Dockerfile.${{env.DOCKERFILE_WINDOWS}} -t ${{env.TAG}} --build-arg BASE_IMAGE_TAG=lts-windowsservercore-1809 .
-        
-    - name: Push the docker image
-      run: |
-        docker push ${{env.TAG}}
-        
-        
+      - name: Checkout main
+        uses: actions/checkout@v4
+
+      - name: Login to GitHub Container Registry
+        uses: docker/login-action@v4
+        with:
+          registry: ghcr.io
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Build the docker image for ${{ github.repository }}
+        run: |
+          cd ./.ci/docker
+          docker build --build-arg REF=${{ github.ref_name }} -f ./Dockerfile.${{env.DOCKERFILE_WINDOWS}} -t ${{env.TAG}} --build-arg BASE_IMAGE_TAG=lts-windowsservercore-1809 .
+
+      - name: Push the docker image
+        run: |
+          docker push ${{env.TAG}}
+  
+
   manifest:
-    needs: [setup, rocky-image, windows-11-image, windows-compat-image]
+    needs: [ setup, rocky-image, windows-11-image, windows-compat-image ]
     runs-on: ubuntu-latest
     env:
       IMAGE1: ${{ needs.setup.outputs.ROCKY_IMAGE_TAG }}
@@ -151,34 +151,34 @@ jobs:
       IMAGE3: ${{ needs.setup.outputs.WINDOWS_COMPAT_IMAGE_TAG }}
       PUB: ${{ needs.setup.outputs.PUBLIC_IMAGE_TAG }}
     steps:
-    - name: Print env
-      run: |
-        echo IMAGE1=${{env.IMAGE1}}
-        echo IMAGE2=${{env.IMAGE2}}
-        echo IMAGE3=${{env.IMAGE3}}
-        echo PUB=${{env.PUB}}
-        
-    - name: Checkout main
-      uses: actions/checkout@v4
-      
-    - name: Login to GitHub Container Registry
-      uses: docker/login-action@v3
-      with:
-        registry: ghcr.io
-        username: ${{ github.actor }}
-        password: ${{ secrets.GITHUB_TOKEN }}
-          
-    - name: Create a new manifest
-      run: |
-        docker manifest create ${{env.PUB}} --amend ${{env.IMAGE1}} --amend ${{env.IMAGE2}} --amend ${{env.IMAGE3}}
-        
-    - name: Push the new manifest
-      run: |
-        docker manifest push ${{env.PUB}}
-        
-    - name: Create and push manifest latest if selected
-      if: env.TAG_LATEST != 'false'
-      run: |
-        docker manifest create $PUBLIC_IMAGE_TAG_LATEST --amend $IMAGE1 --amend $IMAGE2 --amend $IMAGE3
-        docker manifest push $PUBLIC_IMAGE_TAG_LATEST
+      - name: Print env
+        run: |
+          echo IMAGE1=${{env.IMAGE1}}
+          echo IMAGE2=${{env.IMAGE2}}
+          echo IMAGE3=${{env.IMAGE3}}
+          echo PUB=${{env.PUB}}
+
+      - name: Checkout main
+        uses: actions/checkout@v4
+
+      - name: Login to GitHub Container Registry
+        uses: docker/login-action@v4
+        with:
+          registry: ghcr.io
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Create a new manifest
+        run: |
+          docker manifest create ${{env.PUB}} --amend ${{env.IMAGE1}} --amend ${{env.IMAGE2}} --amend ${{env.IMAGE3}}
+
+      - name: Push the new manifest
+        run: |
+          docker manifest push ${{env.PUB}}
+
+      - name: Create and push manifest latest if selected
+        if: env.TAG_LATEST != 'false'
+        run: |
+          docker manifest create $PUBLIC_IMAGE_TAG_LATEST --amend $IMAGE1 --amend $IMAGE2 --amend $IMAGE3
+          docker manifest push $PUBLIC_IMAGE_TAG_LATEST
  
diff --git a/.github/workflows/dotnet_provisioner_unit_tests.yml b/.github/workflows/dotnet_provisioner_unit_tests.yml
index 436bca1e1..59c6b6324 100644
--- a/.github/workflows/dotnet_provisioner_unit_tests.yml
+++ b/.github/workflows/dotnet_provisioner_unit_tests.yml
@@ -2,7 +2,7 @@ name: Dotnet Provisioner Unit Tests
 
 on: push
 env:
-  DOTNET_VERSION: '6.0'
+  DOTNET_VERSION: '8.0'
 jobs:
   dotnet_provisioner_unit_tests:
     name: Restore and Run Unit Tests
@@ -97,7 +97,7 @@ jobs:
 
   Evaluator:
     name: Evaluate Tests
-    needs: [dotnet_provisioner_unit_tests]
+    needs: [ dotnet_provisioner_unit_tests ]
     runs-on: ubuntu-latest
     continue-on-error: false
     steps:
@@ -110,7 +110,7 @@ jobs:
         run: |
           mkdir artifacts
 
-      - uses: actions/download-artifact@v3
+      - uses: actions/download-artifact@v4
         with:
           path: artifacts
 
diff --git a/.github/workflows/hirs_package_linux.yml b/.github/workflows/hirs_package_linux.yml
index b8f04b069..fe76880d4 100644
--- a/.github/workflows/hirs_package_linux.yml
+++ b/.github/workflows/hirs_package_linux.yml
@@ -8,34 +8,34 @@ on:
 
 jobs:
   # run the package script for HIRS ACA, Provisioners, tcg_rim_tool, and tcg_eventlog_tool
- Package_linux:
+  Package_linux:
     runs-on: ubuntu-latest
     permissions:
       contents: read
       packages: write
 
     steps:
-    - uses: actions/checkout@v4
-    - name: Set up JDK 17
-      uses: actions/setup-java@v4
-      with:
-        java-version: '17'
-        distribution: 'temurin'
-        server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
-        settings-path: ${{ github.workspace }} # location for the settings.xml file
-    - name: directory setup
-      run: |
-       mkdir -p artifacts/jars
-       mkdir -p artifacts/win
-       mkdir -p artifacts/win/hirstools
-    - name: install dependencies
-      run: |
-        sudo apt-get update
-        sudo apt-get install git curl nano cron mariadb-server
-    - name: Setup Gradle
-      uses: gradle/actions/setup-gradle@v3
-    - name: Execute Gradle build
-      run: |
+      - uses: actions/checkout@v4
+      - name: Set up JDK 17
+        uses: actions/setup-java@v4
+        with:
+          java-version: '17'
+          distribution: 'temurin'
+          server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
+          settings-path: ${{ github.workspace }} # location for the settings.xml file
+      - name: directory setup
+        run: |
+          mkdir -p artifacts/jars
+          mkdir -p artifacts/win
+          mkdir -p artifacts/win/hirstools
+      - name: install dependencies
+        run: |
+          sudo apt-get update
+          sudo apt-get install git curl nano cron mariadb-server
+      - name: Setup Gradle
+        uses: gradle/actions/setup-gradle@v4
+      - name: Execute Gradle build
+        run: |
           ./gradlew build;
           ./gradlew bootWar;
           ./gradlew buildDeb;
@@ -48,35 +48,35 @@ jobs:
           cp tools/tcg_rim_tool/build/distributions/*.zip artifacts/win
           cp tools/tcg_eventlog_tool/build/distributions/*.zip artifacts/win
           cp package/win/tcg-rim-tool/* artifacts/win/hirstools
-    - name: Archive RPM files
-      uses: actions/upload-artifact@v4
-      with:
-        name: RPM_Files
-        path: HIRS_AttestationCAPortal/build/distributions/*.rpm
-        if-no-files-found: error
-    - name: Archive DEB files
-      uses: actions/upload-artifact@v4
-      with:
-        name: DEB_Files
-        path: HIRS_AttestationCAPortal/build/distributions/*.deb
-        if-no-files-found: error
-    - name: War files
-      uses: actions/upload-artifact@v4
-      with:
-        name: WAR_Files
-        path: HIRS_AttestationCAPortal/build/libs/HIRS_AttestationCAPortal.war
-        if-no-files-found: error
-    - name: JAR_Files
-      uses: actions/upload-artifact@v4
-      with:
-        name: JAR_Files
-        path: artifacts/jars/
-        if-no-files-found: error
-    - name: ZIP_Files
-      uses: actions/upload-artifact@v4
-      with:
-        name: ZIP_Files
-        path: artifacts/win/
-        if-no-files-found: error
+      - name: Archive RPM files
+        uses: actions/upload-artifact@v4
+        with:
+          name: RPM_Files
+          path: HIRS_AttestationCAPortal/build/distributions/*.rpm
+          if-no-files-found: error
+      - name: Archive DEB files
+        uses: actions/upload-artifact@v4
+        with:
+          name: DEB_Files
+          path: HIRS_AttestationCAPortal/build/distributions/*.deb
+          if-no-files-found: error
+      - name: War files
+        uses: actions/upload-artifact@v4
+        with:
+          name: WAR_Files
+          path: HIRS_AttestationCAPortal/build/libs/HIRS_AttestationCAPortal.war
+          if-no-files-found: error
+      - name: JAR_Files
+        uses: actions/upload-artifact@v4
+        with:
+          name: JAR_Files
+          path: artifacts/jars/
+          if-no-files-found: error
+      - name: ZIP_Files
+        uses: actions/upload-artifact@v4
+        with:
+          name: ZIP_Files
+          path: artifacts/win/
+          if-no-files-found: error
 
         
diff --git a/.github/workflows/hirs_unit_tests.yml b/.github/workflows/hirs_unit_tests.yml
index fc12f3b41..6f5a2699c 100644
--- a/.github/workflows/hirs_unit_tests.yml
+++ b/.github/workflows/hirs_unit_tests.yml
@@ -4,7 +4,7 @@
 name: HIRS Build and Unit Test
 
 on:
-  # Runs this workflow whenever there is a push to main from a branch annotated with "v3"
+  # Runs this workflow whenever there is a push to main from a branch annotated with "v4"
   push:
     branches:
       - '*v3*'
@@ -17,82 +17,82 @@ jobs:
   ACA_Provisioner_Unit_Tests:
     runs-on: ubuntu-latest  # Configures the job to run on the latest version of an Ubuntu Linux runner
     steps:
-    - uses: actions/checkout@v3  # run v3 of actions/checkout action, which checks out your repository onto the runner
-    # Build will archive build reports and will create a failedFile if build is not successful
-    - name: Directory setup
-      run: |
-        mkdir -p artifacts/githubActionsResults
-        mkdir -p artifacts/upload_reports/HIRS_AttestationCA
-        mkdir -p artifacts/upload_reports/HIRS_AttestationCAPortal
-        mkdir -p artifacts/upload_reports/HIRS_Provisioner
-        mkdir -p artifacts/upload_reports/HIRS_ProvisionerTPM2
-        mkdir -p artifacts/upload_reports/HIRS_Structs
-        mkdir -p artifacts/upload_reports/HIRS_Utils
-        mkdir -p artifacts/upload_reports/tcg_rim_tool
-        mkdir -p artifacts/upload_reports/tcg_eventlog_tool
-    # Run the provisioner and ACA unit tests via gradle build in a Rocky Docker container
-    - name: Build HIRS and run unit tests
-      run: |
-        
-        # log into and run docker (note: must set up secrets in github for ghcr username and access_token)
-        echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u $ --password-stdin
-        
-        # docker run options:
-        #   create a mount between curr directory on the runner and the HIRS folder created by the cloning of HIRS repo
-        #     -v $(pwd):/HIRS
-        #   image used for the container, given by :
-        #     rocky8: ghcr.io/nsacyber/hirs/hirs-rocky8-ci:latest [repo: https://github.com/orgs/nsacyber/packages]
-        #   bash commands to clean/build/test each subproject
-        #     /bin/bash -c ''
-        docker run --rm \
-        -v $(pwd):/HIRS \
-        ghcr.io/nsacyber/hirs/hirs-rocky8-ci:latest /bin/bash -c \
-          'pushd /HIRS
-          gradle_status=0
-        
-          # git added a feature that gives error if user is not owner of the top-level directory; need to override this
-          git config --global --add safe.directory /HIRS
-        
-          # clean, build and run unit tests on all sub-projects; copy build reports to an artifacts directory
-          ./gradlew :HIRS_AttestationCA:clean :HIRS_AttestationCA:build :HIRS_AttestationCA:test
-          if (( $? != "0" )) ; then gradle_status=1; fi
-          cp -r /HIRS/HIRS_AttestationCA/build/reports/ /HIRS/artifacts/upload_reports/HIRS_AttestationCA/.
-          ./gradlew :HIRS_AttestationCAPortal:clean :HIRS_AttestationCAPortal:build :HIRS_AttestationCAPortal:test
-          if (( $? != "0" )) ; then gradle_status=1; fi
-          cp -r /HIRS/HIRS_AttestationCAPortal/build/reports/ /HIRS/artifacts/upload_reports/HIRS_AttestationCAPortal/.
-          #./gradlew :HIRS_Provisioner:clean :HIRS_Provisioner:build :HIRS_Provisioner:test
-          #if (( $? != "0" )) ; then gradle_status=1; fi
-          #cp -r /HIRS/HIRS_Provisioner/build/reports/ /HIRS/artifacts/upload_reports/HIRS_Provisioner/.
-          #./gradlew :HIRS_ProvisionerTPM2:clean :HIRS_ProvisionerTPM2:build :HIRS_ProvisionerTPM2:test
-          #if (( $? != "0" )) ; then gradle_status=1; fi
-          #cp -r /HIRS/HIRS_ProvisionerTPM2/docs/ /HIRS/artifacts/upload_reports/HIRS_ProvisionerTPM2/.
-          ./gradlew :HIRS_Structs:clean :HIRS_Structs:build :HIRS_Structs:test
-          if (( $? != "0" )) ; then gradle_status=1; fi
-          cp -r /HIRS/HIRS_Structs/build/reports/ /HIRS/artifacts/upload_reports/HIRS_Structs/.
-          ./gradlew :HIRS_Utils:clean :HIRS_Utils:build :HIRS_Utils:test
-          if (( $? != "0" )) ; then gradle_status=1; fi
-          cp -r /HIRS/HIRS_Utils/build/reports/ /HIRS/artifacts/upload_reports/HIRS_Utils/.
-          #./gradlew :TPM_Utils:clean :TPM_Utils:build :TPM_Utils:test
-          #if (( $? != "0" )) ; then gradle_status=1; fi
-        
-          # Create "fail file" to fail the Build ACA tests if gradle exited with anything other than 0      
-          if (( $gradle_status == "0" )) ; then
-            echo "In docker: Build Passed"
-          else
-            echo "In docker: Build Failed"
-            touch /HIRS/artifacts/githubActionsResults/buildFailed.txt
-          fi; popd;'
-    # Upload build report files
-    - name: Archive report files
-      uses: actions/upload-artifact@v3
-      with:
-        name: HIRS_Build_Reports
-        path: artifacts/upload_reports/*
-        if-no-files-found: ignore
-    # If buildFailed file exists, use that to fail the ACA unit tests
-    - name: Check if build/test passed or failed
-      if: ${{ hashFiles('artifacts/githubActionsResults/buildFailed.txt') != '' }}
-      uses: actions/github-script@v6
-      with:
-        script: |
-          core.setFailed('Build or Unit Test Failed')
\ No newline at end of file
+      - uses: actions/checkout@v4  # run v4 of actions/checkout action, which checks out your repository onto the runner
+      # Build will archive build reports and will create a failedFile if build is not successful
+      - name: Directory setup
+        run: |
+          mkdir -p artifacts/githubActionsResults
+          mkdir -p artifacts/upload_reports/HIRS_AttestationCA
+          mkdir -p artifacts/upload_reports/HIRS_AttestationCAPortal
+          mkdir -p artifacts/upload_reports/HIRS_Provisioner
+          mkdir -p artifacts/upload_reports/HIRS_ProvisionerTPM2
+          mkdir -p artifacts/upload_reports/HIRS_Structs
+          mkdir -p artifacts/upload_reports/HIRS_Utils
+          mkdir -p artifacts/upload_reports/tcg_rim_tool
+          mkdir -p artifacts/upload_reports/tcg_eventlog_tool
+      # Run the provisioner and ACA unit tests via gradle build in a Rocky Docker container
+      - name: Build HIRS and run unit tests
+        run: |
+          
+          # log into and run docker (note: must set up secrets in github for ghcr username and access_token)
+          echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u $ --password-stdin
+          
+          # docker run options:
+          #   create a mount between curr directory on the runner and the HIRS folder created by the cloning of HIRS repo
+          #     -v $(pwd):/HIRS
+          #   image used for the container, given by :
+          #     rocky8: ghcr.io/nsacyber/hirs/hirs-rocky8-ci:latest [repo: https://github.com/orgs/nsacyber/packages]
+          #   bash commands to clean/build/test each subproject
+          #     /bin/bash -c ''
+          docker run --rm \
+          -v $(pwd):/HIRS \
+          ghcr.io/nsacyber/hirs/hirs-rocky8-ci:latest /bin/bash -c \
+            'pushd /HIRS
+            gradle_status=0
+          
+            # git added a feature that gives error if user is not owner of the top-level directory; need to override this
+            git config --global --add safe.directory /HIRS
+          
+            # clean, build and run unit tests on all sub-projects; copy build reports to an artifacts directory
+            ./gradlew :HIRS_AttestationCA:clean :HIRS_AttestationCA:build :HIRS_AttestationCA:test
+            if (( $? != "0" )) ; then gradle_status=1; fi
+            cp -r /HIRS/HIRS_AttestationCA/build/reports/ /HIRS/artifacts/upload_reports/HIRS_AttestationCA/.
+            ./gradlew :HIRS_AttestationCAPortal:clean :HIRS_AttestationCAPortal:build :HIRS_AttestationCAPortal:test
+            if (( $? != "0" )) ; then gradle_status=1; fi
+            cp -r /HIRS/HIRS_AttestationCAPortal/build/reports/ /HIRS/artifacts/upload_reports/HIRS_AttestationCAPortal/.
+            #./gradlew :HIRS_Provisioner:clean :HIRS_Provisioner:build :HIRS_Provisioner:test
+            #if (( $? != "0" )) ; then gradle_status=1; fi
+            #cp -r /HIRS/HIRS_Provisioner/build/reports/ /HIRS/artifacts/upload_reports/HIRS_Provisioner/.
+            #./gradlew :HIRS_ProvisionerTPM2:clean :HIRS_ProvisionerTPM2:build :HIRS_ProvisionerTPM2:test
+            #if (( $? != "0" )) ; then gradle_status=1; fi
+            #cp -r /HIRS/HIRS_ProvisionerTPM2/docs/ /HIRS/artifacts/upload_reports/HIRS_ProvisionerTPM2/.
+            ./gradlew :HIRS_Structs:clean :HIRS_Structs:build :HIRS_Structs:test
+            if (( $? != "0" )) ; then gradle_status=1; fi
+            cp -r /HIRS/HIRS_Structs/build/reports/ /HIRS/artifacts/upload_reports/HIRS_Structs/.
+            ./gradlew :HIRS_Utils:clean :HIRS_Utils:build :HIRS_Utils:test
+            if (( $? != "0" )) ; then gradle_status=1; fi
+            cp -r /HIRS/HIRS_Utils/build/reports/ /HIRS/artifacts/upload_reports/HIRS_Utils/.
+            #./gradlew :TPM_Utils:clean :TPM_Utils:build :TPM_Utils:test
+            #if (( $? != "0" )) ; then gradle_status=1; fi
+          
+            # Create "fail file" to fail the Build ACA tests if gradle exited with anything other than 0      
+            if (( $gradle_status == "0" )) ; then
+              echo "In docker: Build Passed"
+            else
+              echo "In docker: Build Failed"
+              touch /HIRS/artifacts/githubActionsResults/buildFailed.txt
+            fi; popd;'
+      # Upload build report files
+      - name: Archive report files
+        uses: actions/upload-artifact@v4
+        with:
+          name: HIRS_Build_Reports
+          path: artifacts/upload_reports/*
+          if-no-files-found: ignore
+      # If buildFailed file exists, use that to fail the ACA unit tests
+      - name: Check if build/test passed or failed
+        if: ${{ hashFiles('artifacts/githubActionsResults/buildFailed.txt') != '' }}
+        uses: actions/github-script@v6
+        with:
+          script: |
+            core.setFailed('Build or Unit Test Failed')
\ No newline at end of file
diff --git a/.github/workflows/rim_tests.yml b/.github/workflows/rim_tests.yml
index 11799391b..b0fc9b7bb 100644
--- a/.github/workflows/rim_tests.yml
+++ b/.github/workflows/rim_tests.yml
@@ -28,7 +28,7 @@ jobs:
           sudo apt-get update
           sudo apt-get install git curl nano cron mariadb-server
       - name: Setup Gradle
-        uses: gradle/actions/setup-gradle@v3
+        uses: gradle/actions/setup-gradle@v4
       - name: Execute Gradle build
         run: |
           ./gradlew build;
@@ -37,7 +37,7 @@ jobs:
         run: |
           sudo dpkg -i tools/tcg_rim_tool/build/distributions/tcg-rim-tool*.deb
       - name: RIM tests
-        run: | 
+        run: |
           ./.ci/tcg-rim-tool/scripts/run_all_tests.sh --verbose
 
 

From 3913a224d5396729250d838f365b276ebf93e238 Mon Sep 17 00:00:00 2001
From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Tue, 11 Feb 2025 18:47:54 -0500
Subject: [PATCH 09/14] issue_896: Fixed issues in one of the test classes, can
 now test other aspects of the SupplyChainCredentialValidator class. Will add
 more tests as more issues get fixed.

---
 .github/workflows/create_aca_images.yml       |   2 +
 .../dotnet_provisioner_unit_tests.yml         |   2 +
 .github/workflows/hirs_package_linux.yml      |   2 +
 .github/workflows/hirs_unit_tests.yml         |   4 +-
 .github/workflows/rim_tests.yml               |   2 +
 .github/workflows/system_test.yml             |   4 +-
 .../attributes/ComponentIdentifier.java       |   6 +-
 .../entity/userdefined/info/HardwareInfo.java |  10 +-
 .../validation/CredentialValidator.java       |   3 +
 .../attributes/ComponentClassTest.java        | 252 +++++++------
 .../SupplyChainCredentialValidatorTest.java   | 343 +++++++++++-------
 11 files changed, 379 insertions(+), 251 deletions(-)

diff --git a/.github/workflows/create_aca_images.yml b/.github/workflows/create_aca_images.yml
index 9cda9434a..72bd40088 100644
--- a/.github/workflows/create_aca_images.yml
+++ b/.github/workflows/create_aca_images.yml
@@ -1,3 +1,5 @@
+# Updated: 02/11/2025
+
 name: Create ACA Docker Image
 on:
   release:
diff --git a/.github/workflows/dotnet_provisioner_unit_tests.yml b/.github/workflows/dotnet_provisioner_unit_tests.yml
index 59c6b6324..dda5b2e0c 100644
--- a/.github/workflows/dotnet_provisioner_unit_tests.yml
+++ b/.github/workflows/dotnet_provisioner_unit_tests.yml
@@ -1,3 +1,5 @@
+# Updated: 02/11/2025
+
 name: Dotnet Provisioner Unit Tests
 
 on: push
diff --git a/.github/workflows/hirs_package_linux.yml b/.github/workflows/hirs_package_linux.yml
index fe76880d4..04cea3fa2 100644
--- a/.github/workflows/hirs_package_linux.yml
+++ b/.github/workflows/hirs_package_linux.yml
@@ -1,3 +1,5 @@
+# Updated: 02/11/2025
+
 name: HIRS build and packages for Linux
 on:
   push:
diff --git a/.github/workflows/hirs_unit_tests.yml b/.github/workflows/hirs_unit_tests.yml
index 6f5a2699c..82991d652 100644
--- a/.github/workflows/hirs_unit_tests.yml
+++ b/.github/workflows/hirs_unit_tests.yml
@@ -1,10 +1,10 @@
 # This workflow will build HIRS, run unit tests, and create HIRS artifacts
-# Updated: 8/15/23
+# Updated: 02/11/2025
 
 name: HIRS Build and Unit Test
 
 on:
-  # Runs this workflow whenever there is a push to main from a branch annotated with "v4"
+  # Runs this workflow whenever there is a push to main from a branch annotated with "v3"
   push:
     branches:
       - '*v3*'
diff --git a/.github/workflows/rim_tests.yml b/.github/workflows/rim_tests.yml
index b0fc9b7bb..d1aea45f5 100644
--- a/.github/workflows/rim_tests.yml
+++ b/.github/workflows/rim_tests.yml
@@ -1,4 +1,6 @@
 # workflow is used to run RIM tests
+# Updated: 02/11/2025
+
 name: RIM Test
 on:
   push:
diff --git a/.github/workflows/system_test.yml b/.github/workflows/system_test.yml
index cb8b44e0f..8965545fc 100644
--- a/.github/workflows/system_test.yml
+++ b/.github/workflows/system_test.yml
@@ -1,6 +1,6 @@
 # This workflow will build HIRS, run system tests, and create artifacts consisting of ACA and Provisioner logs.
-# Updated: 06/05/2024
-#
+# Updated: 02/11/2025
+
 name: HIRS System Tests
 on:
   push:
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java
index 0598f76f4..d0549c9e6 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java
@@ -106,7 +106,7 @@ public ComponentIdentifier() {
      * @param componentRevision       represents the component revision
      * @param componentManufacturerId represents the component manufacturer ID
      * @param fieldReplaceable        represents if the component is replaceable
-     * @param componentAddress        represents a list of addresses
+     * @param componentAddresses      represents a list of addresses
      */
     public ComponentIdentifier(final DERUTF8String componentManufacturer,
                                final DERUTF8String componentModel,
@@ -114,14 +114,14 @@ public ComponentIdentifier(final DERUTF8String componentManufacturer,
                                final DERUTF8String componentRevision,
                                final ASN1ObjectIdentifier componentManufacturerId,
                                final ASN1Boolean fieldReplaceable,
-                               final List componentAddress) {
+                               final List componentAddresses) {
         this.componentManufacturer = componentManufacturer;
         this.componentModel = componentModel;
         this.componentSerial = componentSerial;
         this.componentRevision = componentRevision;
         this.componentManufacturerId = componentManufacturerId;
         this.fieldReplaceable = fieldReplaceable;
-        this.componentAddresses = componentAddress.stream().toList();
+        this.componentAddresses = componentAddresses.stream().toList();
     }
 
     /**
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/HardwareInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/HardwareInfo.java
index 35a9bd7fa..b9b379b17 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/HardwareInfo.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/HardwareInfo.java
@@ -22,11 +22,11 @@
 public class HardwareInfo implements Serializable {
 
     @XmlElement
-    @Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
+    @Column(nullable = false)
     private String manufacturer = DeviceInfoEnums.NOT_SPECIFIED;
 
     @XmlElement
-    @Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
+    @Column(nullable = false)
     private String productName = DeviceInfoEnums.NOT_SPECIFIED;
 
     @XmlElement
@@ -34,15 +34,15 @@ public class HardwareInfo implements Serializable {
     private String version = DeviceInfoEnums.NOT_SPECIFIED;
 
     @XmlElement
-    @Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
+    @Column(nullable = false)
     private String systemSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
 
     @XmlElement
-    @Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
+    @Column(nullable = false)
     private String chassisSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
 
     @XmlElement
-    @Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
+    @Column(nullable = false)
     private String baseboardSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
 
     /**
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java
index 49cd6cf65..1913ccd58 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java
@@ -190,14 +190,17 @@ public static AppraisalStatus validatePlatformCredentialAttributes(
             message = baseErrorMessage + "a platform credential";
             return new AppraisalStatus(FAIL, message);
         }
+
         if (deviceInfoReport == null) {
             message = baseErrorMessage + "a device info report";
             return new AppraisalStatus(FAIL, message);
         }
+
         if (endorsementCredential == null) {
             message = baseErrorMessage + "an endorsement credential";
             return new AppraisalStatus(FAIL, message);
         }
+
         if (componentInfos.isEmpty()) {
             message = baseErrorMessage + "a list of device components";
             return new AppraisalStatus(FAIL, message);
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClassTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClassTest.java
index 8dc543583..f32836b6c 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClassTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClassTest.java
@@ -4,6 +4,7 @@
 
 import java.net.URISyntaxException;
 import java.nio.file.Paths;
+import java.util.Objects;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
@@ -16,290 +17,315 @@ public class ComponentClassTest {
     private static final String JSON_FILE = "/config/component-class.json";
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentNoneUNK() throws URISyntaxException {
-        String componentIdentifier = "00000001";
+        final String componentIdentifier = "00000001";
         ComponentClass instance = new ComponentClass("TCG",
-                Paths.get(this.getClass().getResource(JSON_FILE).toURI()),
+                Paths.get(Objects.requireNonNull(this.getClass().getResource(JSON_FILE)).toURI()),
                 componentIdentifier);
-        String resultCategory = instance.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertEquals(resultComponent, "Unknown");
         assertEquals(resultCategory, "None");
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentNoneOther() throws URISyntaxException {
-        String componentIdentifier = "00000000";
-        ComponentClass instance = new ComponentClass("TCG", Paths.get(this.getClass()
-                .getResource(JSON_FILE).toURI()), componentIdentifier);
-        String resultCategory = instance.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "00000000";
+        ComponentClass instance = new ComponentClass("TCG", Paths.get(Objects.requireNonNull(this.getClass()
+                .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertEquals(resultComponent, "Unknown");
         assertEquals(resultCategory, "None");
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentBlank() throws URISyntaxException {
-        String componentIdentifier = "";
-        ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
-                .getResource(JSON_FILE).toURI()), componentIdentifier);
-        String resultCategory = instance.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "";
+        ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
+                .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertEquals(resultComponent, "Unknown");
         assertEquals(resultCategory, "None");
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentNFEx() throws URISyntaxException {
-        String componentIdentifier = "99999999";
-        ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
-                .getResource(JSON_FILE).toURI()), componentIdentifier);
-        String resultCategory = instance.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "99999999";
+        ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
+                .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertEquals(resultComponent, "Unknown");
         assertEquals(resultCategory, "None");
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentNull() throws URISyntaxException {
-        String componentIdentifier = null;
-        ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
-                .getResource(JSON_FILE).toURI()), componentIdentifier);
-        String resultCategory = instance.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = null;
+        ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
+                .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertEquals(resultComponent, "Unknown");
         assertEquals(resultCategory, "None");
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class where the
+     * registry type is of type TCG.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentStandardQueryTCG() throws URISyntaxException {
-        String componentIdentifier = "0x00040002";
-        ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
-                .getResource(JSON_FILE).toURI()), componentIdentifier);
-        String resultCategory = instance.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "0x00040002";
+        ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
+                .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertEquals(resultComponent, "SAS Bridgeboard");
         assertEquals(resultCategory, "Modules");
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class where the
+     * registry type is of type SMBIOS.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentStandardQuerySMBIOS() throws URISyntaxException {
-        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.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "0x00040003";
+        ComponentClass instance = new ComponentClass("2.23.133.18.3.3", Paths.get(
+                Objects.requireNonNull(this.getClass()
+                        .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
+        final String resultRegistry = instance.getRegistryType();
+
+        assertEquals("SMBIOS", resultRegistry);
         assertEquals("Central Processor", resultComponent);
         assertEquals("Processor", resultCategory);
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Test of getComponent method, of class ComponentClass where the
+     * registry type is of type PCIE.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
-    public void testGetComponentStandardQueryIntTCG() throws URISyntaxException {
-        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.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
-        assertEquals(resultComponent, "SAS Bridgeboard");
-        assertEquals(resultCategory, "Modules");
+    public void testGetComponentStandardQueryPCIE() throws URISyntaxException {
+        final String componentIdentifier = "0x00080004"; // TODO placeholder for now
+        ComponentClass instance = new ComponentClass("2.23.133.18.3.4", Paths.get(
+                Objects.requireNonNull(this.getClass()
+                        .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
+        final String resultRegistry = instance.getRegistryType();
+
+        assertEquals("PCIE", resultRegistry);
+
+        //TODO Once the component-class.json file is updated to reflect the two new component
+        // registries, we will then write tests that test the component class' category/component
+        // properties.
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class where the
+     * registry type is of type STORAGE.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
-    public void testGetComponentStandardQueryIntSMBIOS() throws URISyntaxException {
-        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.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
-        assertEquals("Central Processor", resultComponent);
-        assertEquals("Processor", resultCategory);
+    public void testGetComponentStandardQuerySTORAGE() throws URISyntaxException {
+        final String componentIdentifier = "0x00080004"; // TODO placeholder for now
+        ComponentClass instance = new ComponentClass("2.23.133.18.3.5", Paths.get(
+                Objects.requireNonNull(this.getClass()
+                        .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
+        final String resultRegistry = instance.getRegistryType();
+
+        assertEquals("STORAGE", resultRegistry);
+
+        //TODO Once the component-class.json file is updated to reflect the two new component
+        // registries, we will then write tests that test the component class' category/component
+        // properties.
+
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentStandardQueryIntOther() throws URISyntaxException {
-        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.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "0x00040000";
+        ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(
+                Objects.requireNonNull(this.getClass()
+                        .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertEquals("Other", resultComponent);
         assertEquals("Modules", resultCategory);
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentStandardQueryIntUnk() throws URISyntaxException {
-        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.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "0x00040001";
+        ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(
+                Objects.requireNonNull(this.getClass()
+                        .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertEquals("Unknown", resultComponent);
         assertEquals("Modules", resultCategory);
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentStandardQuery2() throws URISyntaxException {
-        String componentIdentifier = "0x00060015";
-        ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
-                .getResource(JSON_FILE).toURI()), componentIdentifier);
-        String resultCategory = instance.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "0x00060015";
+        ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
+                .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertEquals("DDR3 Memory", resultComponent);
         assertEquals("Memory", resultCategory);
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentStandardQueryUNK() throws URISyntaxException {
-        String componentIdentifier = "0x00060001";
-        ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
-                .getResource(JSON_FILE).toURI()), componentIdentifier);
-        String resultCategory = instance.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "0x00060001";
+        ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
+                .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertEquals("Unknown", resultComponent);
         assertEquals("Memory", resultCategory);
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentNonStandardQuery() throws URISyntaxException {
-        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.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "0x00040002";
+        ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(
+                Objects.requireNonNull(this.getClass()
+                        .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertEquals(resultComponent, "SAS Bridgeboard");
         assertEquals(resultCategory, "Modules");
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentNonStandardQuery2() throws URISyntaxException {
-        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.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "0x00040002";
+        ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(
+                Objects.requireNonNull(this.getClass()
+                        .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertEquals(resultComponent, "SAS Bridgeboard");
         assertEquals(resultCategory, "Modules");
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentNonExistentValue() throws URISyntaxException {
-        String componentIdentifier = "0x00040014";
-        ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
-                .getResource(JSON_FILE).toURI()), componentIdentifier);
-        String resultCategory = instance.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "0x00040014";
+        ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
+                .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertNull(resultComponent);
         assertEquals(resultCategory, "Modules");
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentNonExistentValue2() throws URISyntaxException {
-        String componentIdentifier = "0x0004FF14";
-        ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
-                .getResource(JSON_FILE).toURI()), componentIdentifier);
-        String resultCategory = instance.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "0x0004FF14";
+        ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
+                .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertNull(resultComponent);
         assertEquals(resultCategory, "Modules");
     }
 
     /**
-     * Test of getComponent method, of class ComponentClass.
+     * Tests the getComponent method from the ComponentClass class.
      *
      * @throws URISyntaxException if there is a problem constructing the URI
      */
     @Test
     public void testGetComponentNonExistentCategory() throws URISyntaxException {
-        String componentIdentifier = "0x0015FF14";
-        ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
-                .getResource(JSON_FILE).toURI()), componentIdentifier);
-        String resultCategory = instance.getCategoryStr();
-        String resultComponent = instance.getComponentStr();
+        final String componentIdentifier = "0x0015FF14";
+        ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
+                .getResource(JSON_FILE)).toURI()), componentIdentifier);
+        final String resultCategory = instance.getCategoryStr();
+        final String resultComponent = instance.getComponentStr();
         assertEquals(resultComponent, "Unknown");
         assertEquals(resultCategory, "None");
     }
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
index 4e9c61fc7..b605d7751 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
@@ -1,5 +1,7 @@
 package hirs.attestationca.persist.validation;
 
+import hirs.attestationca.persist.entity.manager.ComponentAttributeRepository;
+import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
 import hirs.attestationca.persist.entity.userdefined.Certificate;
 import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential;
 import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
@@ -34,7 +36,10 @@
 import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -206,6 +211,11 @@ public class SupplyChainCredentialValidatorTest {
 
     private static KeyStore emptyKeyStore;
 
+    @Mock
+    private ComponentResultRepository componentResultRepository;
+    @Mock
+    private ComponentAttributeRepository componentAttributeRepository;
+
     /**
      * Sets up a KeyStore for testing.
      *
@@ -245,57 +255,6 @@ public static void tearDown() {
         }
     }
 
-    private static DeviceInfoReport setupDeviceInfoReport() {
-        hardwareInfo = new HardwareInfo(
-                "ACME",
-                "anvil",
-                "3.0",
-                "1234",
-                "567",
-                "890");
-
-        DeviceInfoReport deviceInfoReport = mock(DeviceInfoReport.class);
-        when(deviceInfoReport.getHardwareInfo()).thenReturn(hardwareInfo);
-        return deviceInfoReport;
-    }
-
-    private static DeviceInfoReport setupDeviceInfoReportWithComponents() throws IOException {
-        return setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_TXT);
-    }
-
-    private static DeviceInfoReport setupDeviceInfoReportWithNotSpecifiedComponents()
-            throws IOException {
-        return setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_NOT_SPECIFIED_TXT);
-    }
-
-    private static DeviceInfoReport setupDeviceInfoReportWithComponents(
-            final String paccorOutputResource) throws IOException {
-        DeviceInfoReport deviceInfoReport = setupDeviceInfoReport();
-        URL url = SupplyChainCredentialValidator.class.getResource(paccorOutputResource);
-        String paccorOutputString = IOUtils.toString(url, StandardCharsets.UTF_8);
-        when(deviceInfoReport.getPaccorOutputString()).thenReturn(paccorOutputString);
-        return deviceInfoReport;
-    }
-
-    /**
-     * Creates a new RSA 1024-bit KeyPair using a Bouncy Castle Provider.
-     *
-     * @return new KeyPair
-     */
-    private static KeyPair createKeyPair() {
-        final int keySize = 1024;
-        KeyPairGenerator gen;
-        KeyPair keyPair = null;
-        try {
-            gen = KeyPairGenerator.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME);
-            gen.initialize(keySize, SECURE_RANDOM);
-            keyPair = gen.generateKeyPair();
-        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
-            fail("Error occurred while generating key pair", e);
-        }
-        return keyPair;
-    }
-
     /**
      * Create a new X.509 attribute certificate given the holder cert, the signing cert, and the
      * signing key.
@@ -401,7 +360,113 @@ private static X509Certificate createSelfSignedCertificate(final KeyPair pair) {
         return cert;
     }
 
-    private static InetAddress getTestIpAddress() {
+    @BeforeEach
+    public void setUpEachTest() {
+        MockitoAnnotations.openMocks(this);
+    }
+
+    /**
+     * Creates a new RSA 1024-bit KeyPair using a Bouncy Castle Provider.
+     *
+     * @return new KeyPair
+     */
+    private KeyPair createKeyPair() {
+        final int keySize = 1024;
+        KeyPairGenerator gen;
+        KeyPair keyPair = null;
+        try {
+            gen = KeyPairGenerator.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME);
+            gen.initialize(keySize, SECURE_RANDOM);
+            keyPair = gen.generateKeyPair();
+        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
+            fail("Error occurred while generating key pair", e);
+        }
+        return keyPair;
+    }
+
+    /**
+     * Helper method that creates a device info report.
+     *
+     * @return device info report
+     */
+    private DeviceInfoReport setupDeviceInfoReport() {
+        hardwareInfo = new HardwareInfo(
+                "ACME",
+                "anvil",
+                "3.0",
+                "1234",
+                "567",
+                "890");
+
+        DeviceInfoReport deviceInfoReport = mock(DeviceInfoReport.class);
+        when(deviceInfoReport.getHardwareInfo()).thenReturn(hardwareInfo);
+        return deviceInfoReport;
+    }
+
+    /**
+     * Helper method that creates a device info report that contains the provided components.
+     *
+     * @return device info report that contains provided components
+     * @throws IOException is thrown if issues arise from parsing out the paccor output
+     */
+    private DeviceInfoReport setupDeviceInfoReportWithComponents() throws IOException {
+        return setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_TXT);
+    }
+
+    /**
+     * Helper method that creates a device info report that contains the provided non-specified components.
+     *
+     * @return device info report that contains not specified components
+     * @throws IOException is thrown if issues arise from parsing out the paccor output
+     */
+    private DeviceInfoReport setupDeviceInfoReportWithNotSpecifiedComponents()
+            throws IOException {
+        return setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_NOT_SPECIFIED_TXT);
+    }
+
+    /**
+     * Helper method that generates a device info report using the provided sample paccor output.
+     *
+     * @param paccorOutputResource sample paccor output text
+     * @return device info report
+     * @throws IOException is thrown if issues arise from parsing out the paccor output
+     */
+    private DeviceInfoReport setupDeviceInfoReportWithComponents(
+            final String paccorOutputResource) throws IOException {
+        DeviceInfoReport deviceInfoReport = setupDeviceInfoReport();
+        URL url = SupplyChainCredentialValidator.class.getResource(paccorOutputResource);
+        String paccorOutputString = IOUtils.toString(url, StandardCharsets.UTF_8);
+        when(deviceInfoReport.getPaccorOutputString()).thenReturn(paccorOutputString);
+        return deviceInfoReport;
+    }
+
+    /**
+     * Helper method that generates a collection of component info that can be used
+     * for this class' test methods.
+     *
+     * @return a generic list of component info
+     */
+    private List retrieveListOfComponentInfos() {
+
+        return List.of(
+                new ComponentInfo("the-device", "Dell Inc", "11",
+                        "9ZLUO9", "Not Specified", "020000123",
+                        "2.23.133.18.3.1"),
+                new ComponentInfo("the-device", "9090", "AE12",
+                        "Not Specified", "Not Specified", "00070700",
+                        "2.23.133.18.3.4"),
+                new ComponentInfo("the-device", "Not Specified", "109 NVM",
+                        "1110_1100_2230_0000_8CE3_8E10_0164_9CC7.", "Not Specified",
+                        "00060001", "2.23.133.18.3.5"));
+    }
+
+
+    /**
+     * Helper method that returns an IP Address.
+     *
+     * @return IP address
+     */
+    private InetAddress getTestIpAddress() {
         try {
             final byte[] byteAddress = new byte[] {127, 0, 0, 1};
             return InetAddress.getByAddress(byteAddress);
@@ -499,7 +564,7 @@ public final void validateIntelPlatformCredentials()
      *
      * @throws Exception If there are errors.
      */
-//    @Test
+    @Test
     public final void validateIntelPlatformCredentialAttributes()
             throws Exception {
 
@@ -517,22 +582,25 @@ public final void validateIntelPlatformCredentialAttributes()
         EndorsementCredential ec = new EndorsementCredential(Files.readAllBytes(Paths.get(
                 Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI())));
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus result =
                 CredentialValidator.validatePlatformCredentialAttributes(pc,
-                        deviceInfoReport, ec, null, null,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        deviceInfoReport, ec, componentResultRepository, componentAttributeRepository,
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
     }
 
+
     /**
      * Checks if the Platform Credential contains the serial number from
      * the device in the platform serial number field.
      *
      * @throws Exception If there are errors.
      */
-//    @Test
+    @Test
     public final void validatePlatformCredentialWithDeviceBaseboard()
             throws Exception {
         DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo(
@@ -549,10 +617,12 @@ public final void validatePlatformCredentialWithDeviceBaseboard()
         EndorsementCredential ec = new EndorsementCredential(Files.readAllBytes(Paths.get(
                 Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI())));
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus result =
                 CredentialValidator.validatePlatformCredentialAttributes(pc,
-                        deviceInfoReport, ec, null, null,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        deviceInfoReport, ec, componentResultRepository, componentAttributeRepository,
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -562,7 +632,7 @@ public final void validatePlatformCredentialWithDeviceBaseboard()
      * Checks if the Platform Credential contains the serial number from
      * the device in the chassis serial number field.
      */
-//    @Test
+    @Test
     public final void validatePlatformCredentialWithDeviceChassis()
             throws Exception {
 
@@ -580,10 +650,12 @@ public final void validatePlatformCredentialWithDeviceChassis()
         EndorsementCredential ec = new EndorsementCredential(Files.readAllBytes(Paths.get(
                 Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI())));
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus result =
                 CredentialValidator.validatePlatformCredentialAttributes(pc,
-                        deviceInfoReport, ec, null, null,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        deviceInfoReport, ec, componentResultRepository, componentAttributeRepository,
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -595,7 +667,7 @@ public final void validatePlatformCredentialWithDeviceChassis()
      *
      * @throws Exception If there are errors.
      */
-//    @Test
+    @Test
     public final void validatePlatformCredentialWithDeviceSystemSerialNumber()
             throws Exception {
 
@@ -613,10 +685,12 @@ public final void validatePlatformCredentialWithDeviceSystemSerialNumber()
         EndorsementCredential ec = new EndorsementCredential(Files.readAllBytes(Paths.get(
                 Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI())));
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus result =
                 CredentialValidator.validatePlatformCredentialAttributes(pc,
-                        deviceInfoReport, ec, null, null,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        deviceInfoReport, ec, componentResultRepository, componentAttributeRepository,
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -626,7 +700,7 @@ public final void validatePlatformCredentialWithDeviceSystemSerialNumber()
      * Checks if validation occurs when the Platform Credential baseboard
      * serial number is in the device chassis serial number field.
      */
-//    @Test
+    @Test
     public final void validatePlatformCredentialCombinedWithChassisSerialNumbersMatchedBaseboard()
             throws Exception {
 
@@ -645,10 +719,12 @@ public final void validatePlatformCredentialCombinedWithChassisSerialNumbersMatc
                 Files.readAllBytes(Paths.get(
                         Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI())));
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus result =
                 CredentialValidator.validatePlatformCredentialAttributes(pc,
-                        deviceInfoReport, ec, null, null,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        deviceInfoReport, ec, componentResultRepository, componentAttributeRepository,
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -658,7 +734,7 @@ public final void validatePlatformCredentialCombinedWithChassisSerialNumbersMatc
      * Checks if validation occurs when the Platform Credential chassis
      * serial number is in the device baseboard serial number field.
      */
-//    @Test
+    @Test
     public final void validatePlatformCredentialCombinedWithBaseboardSerialNumbersMatchedChassis()
             throws Exception {
 
@@ -676,10 +752,12 @@ public final void validatePlatformCredentialCombinedWithBaseboardSerialNumbersMa
         EndorsementCredential ec = new EndorsementCredential(Files.readAllBytes(Paths.get(
                 Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI())));
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus result =
                 CredentialValidator.validatePlatformCredentialAttributes(pc,
-                        deviceInfoReport, ec, null, null,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        deviceInfoReport, ec, componentResultRepository, componentAttributeRepository,
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -689,7 +767,7 @@ public final void validatePlatformCredentialCombinedWithBaseboardSerialNumbersMa
      * Checks if validation occurs when the Platform Credential chassis
      * serial number is in the device system serial number field.
      */
-//    @Test
+    @Test
     public final void validatePlatformCredentialCombinedWithSystemSerialNumbersMatchedChassis()
             throws Exception {
 
@@ -707,10 +785,12 @@ public final void validatePlatformCredentialCombinedWithSystemSerialNumbersMatch
         EndorsementCredential ec = new EndorsementCredential(Files.readAllBytes(Paths.get(
                 Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI())));
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus result =
                 CredentialValidator.validatePlatformCredentialAttributes(pc,
-                        deviceInfoReport, ec, null, null,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        deviceInfoReport, ec, componentResultRepository, componentAttributeRepository,
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -722,7 +802,7 @@ public final void validatePlatformCredentialCombinedWithSystemSerialNumbersMatch
      *
      * @throws Exception If there are errors.
      */
-//    @Test
+    @Test
     public final void validatePlatformCredentialWithNoDeviceSerialNumbers()
             throws Exception {
 
@@ -743,10 +823,12 @@ public final void validatePlatformCredentialWithNoDeviceSerialNumbers()
 
         String expectedMessage = "Platform serial did not match device info";
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus result =
                 CredentialValidator.validatePlatformCredentialAttributes(
-                        pc, deviceInfoReport, ec, null, null,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        pc, deviceInfoReport, ec, componentResultRepository, componentAttributeRepository,
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals(expectedMessage, result.getMessage());
     }
@@ -757,7 +839,7 @@ public final void validatePlatformCredentialWithNoDeviceSerialNumbers()
      *
      * @throws Exception If there are errors.
      */
-//    @Test
+    @Test
     public final void validatePlatformCredentialCombinedWithNoMatchedDeviceSerialNumbers()
             throws Exception {
 
@@ -777,10 +859,12 @@ public final void validatePlatformCredentialCombinedWithNoMatchedDeviceSerialNum
 
         String expectedMessage = "Platform serial did not match device info";
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus result =
                 CredentialValidator.validatePlatformCredentialAttributes(
-                        pc, deviceInfoReport, ec, null, null,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        pc, deviceInfoReport, ec, componentResultRepository, componentAttributeRepository,
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals(expectedMessage, result.getMessage());
     }
@@ -1144,7 +1228,7 @@ public final void verifyPlatformCredentialNullKeyStore()
      * @throws IOException        an error occurs when parsing the certificate
      * @throws URISyntaxException an error occurs parsing the certificate file path
      */
-//    @Test
+    @Test
     public final void verifyPlatformCredentialNullDeviceInfoReport()
             throws URISyntaxException, IOException {
         byte[] certBytes = Files.readAllBytes(Paths.get(
@@ -1159,9 +1243,12 @@ public final void verifyPlatformCredentialNullDeviceInfoReport()
         String expectedMessage = "Can't validate platform credential attributes without a "
                 + "device info report";
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus result =
-                CredentialValidator.validatePlatformCredentialAttributes(pc, null, ec, null, null,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                CredentialValidator.validatePlatformCredentialAttributes(pc, null, ec,
+                        componentResultRepository, componentAttributeRepository,
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals(expectedMessage, result.getMessage());
     }
@@ -1379,14 +1466,15 @@ private PlatformCredential setupMatchingPlatformCredential(
      *
      * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-//    @Test
+    //@Test TODO esacost
     public final void testValidatePlatformCredentialAttributesV2p0NoComponentsPass()
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReport();
         PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
 
         AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
-                .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, null, null,
+                .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport,
+                        componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS,
                 appraisalStatus.getAppStatus());
@@ -1407,7 +1495,8 @@ public final void testValidatePlatformCredentialAttributesV2p0WithComponentsPass
         PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
 
         AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
-                .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, null, null,
+                .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport,
+                        componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, appraisalStatus.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1430,7 +1519,8 @@ public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSys
                 .thenReturn(hardwareInfo.getSystemSerialNumber());
 
         AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
-                .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, null, null,
+                .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport,
+                        componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, appraisalStatus.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1455,7 +1545,8 @@ public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSys
                                 SAMPLE_TEST_PACCOR_CERT)).toURI())));
 
         AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
-                .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, null, null,
+                .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport,
+                        componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, appraisalStatus.getAppStatus());
     }
@@ -1473,7 +1564,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1481,7 +1572,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         when(platformCredential.getManufacturer()).thenReturn(null);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Platform manufacturer did not match\n", result.getMessage());
@@ -1489,7 +1580,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1497,7 +1588,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         when(platformCredential.getModel()).thenReturn(null);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(result.getAppStatus(), AppraisalStatus.Status.FAIL);
         assertEquals(result.getMessage(), "Platform model did not match\n");
@@ -1505,7 +1596,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1513,13 +1604,13 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         when(platformCredential.getPlatformSerial()).thenReturn(null);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1527,7 +1618,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         when(platformCredential.getVersion()).thenReturn(null);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1536,7 +1627,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1547,7 +1638,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         when(platformCredential.getComponentIdentifiers()).thenReturn(modifiedComponentIdentifiers);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Component manufacturer is empty\n", result.getMessage());
@@ -1555,7 +1646,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1565,7 +1656,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         when(platformCredential.getComponentIdentifiers()).thenReturn(modifiedComponentIdentifiers);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Component model is empty\n", result.getMessage());
@@ -1586,7 +1677,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt
         PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1594,7 +1685,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt
         when(platformCredential.getManufacturer()).thenReturn("");
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Platform manufacturer did not match\n", result.getMessage());
@@ -1602,7 +1693,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt
         platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1610,7 +1701,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt
         when(platformCredential.getModel()).thenReturn("");
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Platform model did not match\n", result.getMessage());
@@ -1618,7 +1709,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt
         platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1626,7 +1717,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt
         when(platformCredential.getPlatformSerial()).thenReturn("");
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Platform serial did not match\n", result.getMessage());
@@ -1634,7 +1725,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt
         platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1642,7 +1733,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt
         when(platformCredential.getVersion()).thenReturn("");
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Platform version did not match\n", result.getMessage());
@@ -1650,7 +1741,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt
         platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1661,7 +1752,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt
         when(platformCredential.getComponentIdentifiers()).thenReturn(modifiedComponentIdentifiers);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Component manufacturer is empty\n"
@@ -1673,7 +1764,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt
         platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1683,7 +1774,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt
         when(platformCredential.getComponentIdentifiers()).thenReturn(modifiedComponentIdentifiers);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Component model is empty\n", result.getMessage());
@@ -1703,7 +1794,7 @@ public final void testValidatePlatformCredentialAttributesV2p0MissingComponentIn
         PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1725,7 +1816,7 @@ public final void testValidatePlatformCredentialAttributesV2p0MissingComponentIn
         );
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("There are unmatched components:\n"
@@ -1752,7 +1843,7 @@ public final void testValidatePlatformCredentialAttributesV2p0ExtraComponentInDe
 
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1760,7 +1851,7 @@ public final void testValidatePlatformCredentialAttributesV2p0ExtraComponentInDe
 
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1781,7 +1872,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentF
         PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1794,7 +1885,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentF
 
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Component manufacturer is empty\n"
@@ -1806,7 +1897,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentF
         platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1818,7 +1909,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentF
 
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Component model is empty\n", result.getMessage());
@@ -1849,7 +1940,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentN
 
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1881,7 +1972,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentN
 
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1915,7 +2006,7 @@ public final void testValPlatCredentialAttributesV2p0RequiredComponentNoSerialOr
 
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
-                        deviceInfoReport, null, null,
+                        deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1926,8 +2017,8 @@ public final void testValPlatCredentialAttributesV2p0RequiredComponentNoSerialOr
      * Tests that SupplyChainCredentialValidator passes with a base and delta certificate where
      * the base serial number and delta holder serial number match.
      *
-     * @throws java.io.IOException         Reading file for the certificates
-     * @throws java.net.URISyntaxException when loading certificates bytes
+     * @throws IOException        Reading file for the certificates
+     * @throws URISyntaxException when loading certificates bytes
      */
 //    @Test
     public final void testValidateDeltaPlatformCredentialAttributes()
@@ -2063,8 +2154,8 @@ public final void testValidateDeltaPlatformCredentialAttributes()
      * Tests that SupplyChainCredentialValidator fails when a component needs to
      * be replaced but hasn't been by a delta certificate.
      *
-     * @throws java.io.IOException         Reading file for the certificates
-     * @throws java.net.URISyntaxException when loading certificates bytes
+     * @throws IOException        Reading file for the certificates
+     * @throws URISyntaxException when loading certificates bytes
      */
 //    @Test
     public final void testValidateChainFailure()

From 1892075d64eaaba523c5297286d7cae0e357ba37 Mon Sep 17 00:00:00 2001
From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Tue, 11 Feb 2025 19:03:20 -0500
Subject: [PATCH 10/14] issue_896: Hopefully GITHUB actions will be more
 forgiving.

---
 .github/workflows/create_aca_images.yml                    | 1 -
 .github/workflows/dotnet_provisioner_unit_tests.yml        | 1 -
 .github/workflows/hirs_package_linux.yml                   | 1 -
 .github/workflows/hirs_unit_tests.yml                      | 1 -
 .github/workflows/rim_tests.yml                            | 1 -
 .github/workflows/system_test.yml                          | 1 -
 .../certificate/attributes/ComponentClassTest.java         | 4 ----
 .../validation/SupplyChainCredentialValidatorTest.java     | 7 -------
 .../portal/page/utils/CertificateStringMapBuilder.java     | 1 -
 9 files changed, 18 deletions(-)

diff --git a/.github/workflows/create_aca_images.yml b/.github/workflows/create_aca_images.yml
index 72bd40088..35322ddb4 100644
--- a/.github/workflows/create_aca_images.yml
+++ b/.github/workflows/create_aca_images.yml
@@ -1,5 +1,4 @@
 # Updated: 02/11/2025
-
 name: Create ACA Docker Image
 on:
   release:
diff --git a/.github/workflows/dotnet_provisioner_unit_tests.yml b/.github/workflows/dotnet_provisioner_unit_tests.yml
index dda5b2e0c..f0b6d52aa 100644
--- a/.github/workflows/dotnet_provisioner_unit_tests.yml
+++ b/.github/workflows/dotnet_provisioner_unit_tests.yml
@@ -1,5 +1,4 @@
 # Updated: 02/11/2025
-
 name: Dotnet Provisioner Unit Tests
 
 on: push
diff --git a/.github/workflows/hirs_package_linux.yml b/.github/workflows/hirs_package_linux.yml
index 04cea3fa2..5b7b5ca07 100644
--- a/.github/workflows/hirs_package_linux.yml
+++ b/.github/workflows/hirs_package_linux.yml
@@ -1,5 +1,4 @@
 # Updated: 02/11/2025
-
 name: HIRS build and packages for Linux
 on:
   push:
diff --git a/.github/workflows/hirs_unit_tests.yml b/.github/workflows/hirs_unit_tests.yml
index 82991d652..09b979014 100644
--- a/.github/workflows/hirs_unit_tests.yml
+++ b/.github/workflows/hirs_unit_tests.yml
@@ -1,6 +1,5 @@
 # This workflow will build HIRS, run unit tests, and create HIRS artifacts
 # Updated: 02/11/2025
-
 name: HIRS Build and Unit Test
 
 on:
diff --git a/.github/workflows/rim_tests.yml b/.github/workflows/rim_tests.yml
index d1aea45f5..c45e6d348 100644
--- a/.github/workflows/rim_tests.yml
+++ b/.github/workflows/rim_tests.yml
@@ -1,6 +1,5 @@
 # workflow is used to run RIM tests
 # Updated: 02/11/2025
-
 name: RIM Test
 on:
   push:
diff --git a/.github/workflows/system_test.yml b/.github/workflows/system_test.yml
index 8965545fc..ab5167bbf 100644
--- a/.github/workflows/system_test.yml
+++ b/.github/workflows/system_test.yml
@@ -1,6 +1,5 @@
 # This workflow will build HIRS, run system tests, and create artifacts consisting of ACA and Provisioner logs.
 # Updated: 02/11/2025
-
 name: HIRS System Tests
 on:
   push:
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClassTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClassTest.java
index f32836b6c..0bd1c0f25 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClassTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClassTest.java
@@ -147,8 +147,6 @@ public void testGetComponentStandardQueryPCIE() throws URISyntaxException {
         ComponentClass instance = new ComponentClass("2.23.133.18.3.4", Paths.get(
                 Objects.requireNonNull(this.getClass()
                         .getResource(JSON_FILE)).toURI()), componentIdentifier);
-        final String resultCategory = instance.getCategoryStr();
-        final String resultComponent = instance.getComponentStr();
         final String resultRegistry = instance.getRegistryType();
 
         assertEquals("PCIE", resultRegistry);
@@ -170,8 +168,6 @@ public void testGetComponentStandardQuerySTORAGE() throws URISyntaxException {
         ComponentClass instance = new ComponentClass("2.23.133.18.3.5", Paths.get(
                 Objects.requireNonNull(this.getClass()
                         .getResource(JSON_FILE)).toURI()), componentIdentifier);
-        final String resultCategory = instance.getCategoryStr();
-        final String resultComponent = instance.getComponentStr();
         final String resultRegistry = instance.getRegistryType();
 
         assertEquals("STORAGE", resultRegistry);
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
index b605d7751..fc1b92940 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
@@ -36,10 +36,8 @@
 import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -360,11 +358,6 @@ private static X509Certificate createSelfSignedCertificate(final KeyPair pair) {
         return cert;
     }
 
-    @BeforeEach
-    public void setUpEachTest() {
-        MockitoAnnotations.openMocks(this);
-    }
-
     /**
      * Creates a new RSA 1024-bit KeyPair using a Bouncy Castle Provider.
      *
diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java
index b2cc472a2..51d340bd3 100644
--- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java
+++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java
@@ -422,7 +422,6 @@ public static HashMap getPlatformInformation(final UUID uuid,
 
             } else if (certificate.getPlatformConfigurationV2() != null) {
                 PlatformConfigurationV2 platformConfigurationV2 = certificate.getPlatformConfigurationV2();
-                
                 //Component Identifiers
                 List componentIdentifiersV2 =
                         platformConfigurationV2.getComponentIdentifiers();

From a5a0fc7391c041a0e13d29c28b41ed926e94c186 Mon Sep 17 00:00:00 2001
From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Thu, 13 Feb 2025 17:20:26 -0500
Subject: [PATCH 11/14] issue_896: Placed test task in the root build.gradle.
 Made more fixes to the test classes.

---
 HIRS_AttestationCA/build.gradle               |   6 +-
 .../entity/userdefined/info/FirmwareInfo.java |   4 +-
 .../entity/userdefined/info/OSInfo.java       |   8 +-
 .../entity/userdefined/info/TPMInfo.java      |  16 +--
 .../SupplyChainCredentialValidatorTest.java   | 132 ++++++++++++++----
 HIRS_AttestationCAPortal/build.gradle         |   4 -
 HIRS_Structs/build.gradle                     |   4 -
 HIRS_Utils/build.gradle                       |   4 -
 build.gradle                                  |  17 ++-
 .../java/hirs/swid/TestSwidTagGateway.java    |  85 ++++++-----
 10 files changed, 182 insertions(+), 98 deletions(-)

diff --git a/HIRS_AttestationCA/build.gradle b/HIRS_AttestationCA/build.gradle
index e47c417bb..18664f7d0 100644
--- a/HIRS_AttestationCA/build.gradle
+++ b/HIRS_AttestationCA/build.gradle
@@ -70,8 +70,4 @@ sourceSets {
             srcDir '../HIRS_Provisioner.NET/hirs/Resources'
         }
     }
-}
-
-test {
-    useJUnitPlatform()
-}
+}
\ No newline at end of file
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/FirmwareInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/FirmwareInfo.java
index 8921c1088..784199226 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/FirmwareInfo.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/FirmwareInfo.java
@@ -19,11 +19,11 @@
 public class FirmwareInfo implements Serializable {
 
     @XmlElement
-    @Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
+    @Column(nullable = false)
     private final String biosVendor;
 
     @XmlElement
-    @Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
+    @Column(nullable = false)
     private final String biosVersion;
 
     @XmlElement
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/OSInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/OSInfo.java
index 285682df4..218ce6978 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/OSInfo.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/OSInfo.java
@@ -21,11 +21,11 @@
 public class OSInfo implements Serializable {
 
     @XmlElement
-    @Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
+    @Column(nullable = false)
     private final String osName;
 
     @XmlElement
-    @Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
+    @Column(nullable = false)
     private final String osVersion;
 
     @XmlElement
@@ -33,11 +33,11 @@ public class OSInfo implements Serializable {
     private final String osArch;
 
     @XmlElement
-    @Column(length = DeviceInfoEnums.SHORT_STRING_LENGTH, nullable = true)
+    @Column(length = DeviceInfoEnums.SHORT_STRING_LENGTH)
     private final String distribution;
 
     @XmlElement
-    @Column(length = DeviceInfoEnums.SHORT_STRING_LENGTH, nullable = true)
+    @Column(length = DeviceInfoEnums.SHORT_STRING_LENGTH)
     private final String distributionRelease;
 
     /**
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/TPMInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/TPMInfo.java
index 5ca240ff4..55ec2b9e8 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/TPMInfo.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/TPMInfo.java
@@ -30,23 +30,23 @@ public class TPMInfo implements Serializable {
     private static final int MAX_BLOB_SIZE = 65535;
 
     @XmlElement
-    @Column(length = DeviceInfoEnums.MED_STRING_LENGTH, nullable = true)
+    @Column(length = DeviceInfoEnums.MED_STRING_LENGTH)
     private String tpmMake;
 
     @XmlElement
-    @Column(nullable = true)
+    @Column
     private short tpmVersionMajor;
 
     @XmlElement
-    @Column(nullable = true)
+    @Column
     private short tpmVersionMinor;
 
     @XmlElement
-    @Column(nullable = true)
+    @Column
     private short tpmVersionRevMajor;
 
     @XmlElement
-    @Column(nullable = true)
+    @Column
     private short tpmVersionRevMinor;
 
     /**
@@ -60,13 +60,13 @@ public class TPMInfo implements Serializable {
     @JsonIgnore
     private X509Certificate identityCertificate;
 
-    @Column(nullable = true, columnDefinition = "blob")
+    @Column(columnDefinition = "blob")
     private byte[] pcrValues;
 
-    @Column(nullable = true, columnDefinition = "blob")
+    @Column(columnDefinition = "blob")
     private byte[] tpmQuoteHash;
 
-    @Column(nullable = true, columnDefinition = "blob")
+    @Column(columnDefinition = "blob")
     private byte[] tpmQuoteSignature;
 
     /**
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
index fc1b92940..5605aba67 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
@@ -35,9 +35,12 @@
 import org.bouncycastle.operator.OperatorCreationException;
 import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -203,17 +206,21 @@ public class SupplyChainCredentialValidatorTest {
     private static final String NEW_NUC1 =
             "/validation/platform_credentials/Intel_pc3.cer";
 
-    private static HardwareInfo hardwareInfo;
-
     private static KeyStore keyStore;
 
     private static KeyStore emptyKeyStore;
 
     @Mock
     private ComponentResultRepository componentResultRepository;
+
     @Mock
     private ComponentAttributeRepository componentAttributeRepository;
 
+    /**
+     * Holds the AutoCloseable instance returned by openMocks.
+     */
+    private AutoCloseable mocks;
+
     /**
      * Sets up a KeyStore for testing.
      *
@@ -358,6 +365,26 @@ private static X509Certificate createSelfSignedCertificate(final KeyPair pair) {
         return cert;
     }
 
+    /**
+     * Setup mocks.
+     */
+    @BeforeEach
+    public void setUpBeforeEach() {
+        mocks = MockitoAnnotations.openMocks(this);
+    }
+
+    /**
+     * Tears down the mock instances.
+     *
+     * @throws Exception if there are any issues closing down mock instances
+     */
+    @AfterEach
+    public void tearDownAfterEach() throws Exception {
+        if (mocks != null) {
+            mocks.close();
+        }
+    }
+
     /**
      * Creates a new RSA 1024-bit KeyPair using a Bouncy Castle Provider.
      *
@@ -382,8 +409,23 @@ private KeyPair createKeyPair() {
      *
      * @return device info report
      */
-    private DeviceInfoReport setupDeviceInfoReport() {
-        hardwareInfo = new HardwareInfo(
+    private DeviceInfoReport setupDeviceInfoReport() throws UnknownHostException {
+
+        // setup network info
+        final byte[] byteAddress = new byte[] {127, 0, 0, 1};
+        InetAddress inetAddress = InetAddress.getByAddress(byteAddress);
+        NetworkInfo networkInfo = new NetworkInfo("the-device", inetAddress, new byte[] {1, 0, 1, 0, 1, 0});
+
+        // setup os info
+        OSInfo osInfo = new OSInfo("Windows", "11.0", "Not Specified",
+                "Not Specified", "Not Specified");
+
+        // setup firmware info
+        FirmwareInfo firmwareInfo = new FirmwareInfo("Dell Inc", "A11",
+                "03/12/2013");
+
+        // setup hardware info
+        HardwareInfo hardwareInfo = new HardwareInfo(
                 "ACME",
                 "anvil",
                 "3.0",
@@ -391,9 +433,9 @@ private DeviceInfoReport setupDeviceInfoReport() {
                 "567",
                 "890");
 
-        DeviceInfoReport deviceInfoReport = mock(DeviceInfoReport.class);
-        when(deviceInfoReport.getHardwareInfo()).thenReturn(hardwareInfo);
-        return deviceInfoReport;
+        TPMInfo tpmInfo = new TPMInfo();
+
+        return new DeviceInfoReport(networkInfo, osInfo, firmwareInfo, hardwareInfo, tpmInfo);
     }
 
     /**
@@ -429,7 +471,7 @@ private DeviceInfoReport setupDeviceInfoReportWithComponents(
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReport();
         URL url = SupplyChainCredentialValidator.class.getResource(paccorOutputResource);
         String paccorOutputString = IOUtils.toString(url, StandardCharsets.UTF_8);
-        when(deviceInfoReport.getPaccorOutputString()).thenReturn(paccorOutputString);
+        deviceInfoReport.setPaccorOutputString(paccorOutputString);
         return deviceInfoReport;
     }
 
@@ -453,7 +495,6 @@ private List retrieveListOfComponentInfos() {
                         "00060001", "2.23.133.18.3.5"));
     }
 
-
     /**
      * Helper method that returns an IP Address.
      *
@@ -1407,25 +1448,41 @@ public void testMatcher() {
         );
     }
 
+    /**
+     * Helper method that mocks out the Platform Credential object used for this class' test methods.
+     *
+     * @param deviceInfoReport device info report
+     * @return mocked out Platform Credential
+     * @throws IOException is thrown if there are any issues using the provided device info report's
+     *                     information
+     */
     private PlatformCredential setupMatchingPlatformCredential(
             final DeviceInfoReport deviceInfoReport) throws IOException {
         PlatformCredential platformCredential = mock(PlatformCredential.class);
 
         when(platformCredential.getCredentialType()).thenReturn(
                 PlatformCredential.CERTIFICATE_TYPE_2_0);
+
         when(platformCredential.getManufacturer())
-                .thenReturn(hardwareInfo.getManufacturer());
+                .thenReturn(deviceInfoReport.getHardwareInfo().getManufacturer());
+
         when(platformCredential.getModel())
-                .thenReturn(hardwareInfo.getProductName());
+                .thenReturn(deviceInfoReport.getHardwareInfo().getProductName());
+
         when(platformCredential.getPlatformSerial())
-                .thenReturn(hardwareInfo.getBaseboardSerialNumber());
+                .thenReturn(deviceInfoReport.getHardwareInfo().getBaseboardSerialNumber());
+
         when(platformCredential.getVersion())
-                .thenReturn(hardwareInfo.getVersion());
+                .thenReturn(deviceInfoReport.getHardwareInfo().getVersion());
+
+        when(platformCredential.getSerialNumber()).thenReturn(
+                new BigInteger(deviceInfoReport.getHardwareInfo().getSystemSerialNumber()));
 
         List deviceInfoComponents
                 = SupplyChainCredentialValidator.getComponentInfoFromPaccorOutput(
                 deviceInfoReport.getNetworkInfo().getHostname(),
                 deviceInfoReport.getPaccorOutputString());
+
         List componentIdentifierList = new ArrayList<>();
         for (ComponentInfo deviceInfoComponent : deviceInfoComponents) {
             DERUTF8String serial = null;
@@ -1459,16 +1516,19 @@ private PlatformCredential setupMatchingPlatformCredential(
      *
      * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-    //@Test TODO esacost
+    @Test
     public final void testValidatePlatformCredentialAttributesV2p0NoComponentsPass()
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReport();
+
         PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport,
                         componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS,
                 appraisalStatus.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@@ -1481,16 +1541,19 @@ public final void testValidatePlatformCredentialAttributesV2p0NoComponentsPass()
      *
      * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-//    @Test
+    @Test
     public final void testValidatePlatformCredentialAttributesV2p0WithComponentsPass()
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
+
         PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport,
                         componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, appraisalStatus.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 appraisalStatus.getMessage());
@@ -1503,44 +1566,51 @@ public final void testValidatePlatformCredentialAttributesV2p0WithComponentsPass
      *
      * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-//    @Test
+    @Test
     public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSystemSerial()
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
+
         PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+
+        List componentInfoList = retrieveListOfComponentInfos();
+
         when(platformCredential.getPlatformSerial())
-                .thenReturn(hardwareInfo.getSystemSerialNumber());
+                .thenReturn(deviceInfoReport.getHardwareInfo().getSystemSerialNumber());
 
         AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport,
                         componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, appraisalStatus.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 appraisalStatus.getMessage());
     }
 
     /**
-     * Tests that TPM 2.0 Platform Credentials validate correctly against the device info report
+     * Second test that tests that TPM 2.0 Platform Credentials validate correctly against the device info report
      * when there are components present, and when the PlatformSerial field holds the system's
      * serial number instead of the baseboard serial number.
      *
      * @throws IOException        if unable to set up DeviceInfoReport from resource file
      * @throws URISyntaxException failed to read certificate
      */
-//    @Test
+    @Test
     public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSystemSerial2()
             throws IOException, URISyntaxException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithNotSpecifiedComponents();
+
         PlatformCredential platformCredential = new PlatformCredential(
                 Files.readAllBytes(Paths.get(
                         Objects.requireNonNull(SupplyChainCredentialValidator.class.getResource(
                                 SAMPLE_TEST_PACCOR_CERT)).toURI())));
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport,
                         componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, appraisalStatus.getAppStatus());
     }
 
@@ -1549,19 +1619,23 @@ public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSys
      *
      * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-//    @Test
+    //@Test todo ea
     public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull()
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
 
         PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
+
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
+
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
+
         when(platformCredential.getManufacturer()).thenReturn(null);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
@@ -1824,7 +1898,7 @@ public final void testValidatePlatformCredentialAttributesV2p0MissingComponentIn
      *
      * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-//    @Test
+    @Test
     public final void testValidatePlatformCredentialAttributesV2p0ExtraComponentInDeviceInfo()
             throws IOException {
         PlatformCredential platformCredential = setupMatchingPlatformCredential(
@@ -1914,7 +1988,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentF
      *
      * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-//    @Test
+    @Test
     public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentNoSerial()
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
@@ -1946,10 +2020,11 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentN
      *
      * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-//    @Test
+    @Test
     public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentNoRevision()
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
+
         PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
 
         ArrayList modifiedIdentifiers = new ArrayList<>();
@@ -1979,10 +2054,11 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentN
      *
      * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-//    @Test
+    @Test
     public final void testValPlatCredentialAttributesV2p0RequiredComponentNoSerialOrRevision()
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
+
         PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
 
         ArrayList modifiedIdentifiers = new ArrayList<>();
diff --git a/HIRS_AttestationCAPortal/build.gradle b/HIRS_AttestationCAPortal/build.gradle
index e404801c8..7235a4f94 100644
--- a/HIRS_AttestationCAPortal/build.gradle
+++ b/HIRS_AttestationCAPortal/build.gradle
@@ -81,10 +81,6 @@ dependencies {
     testImplementation libs.xmlunit.core
 }
 
-test {
-    useJUnitPlatform()
-}
-
 task buildVersion() {
     doLast {
         def verFile = new File(projectDir, "build/VERSION")
diff --git a/HIRS_Structs/build.gradle b/HIRS_Structs/build.gradle
index 4c69c7ace..bc50238c8 100644
--- a/HIRS_Structs/build.gradle
+++ b/HIRS_Structs/build.gradle
@@ -13,10 +13,6 @@ dependencies {
     testAnnotationProcessor libs.lombok
 }
 
-test {
-    useJUnitPlatform()
-}
-
 //publishing {
 //    publications {
 //        maven(MavenPublication) {
diff --git a/HIRS_Utils/build.gradle b/HIRS_Utils/build.gradle
index 0f79d21a7..3b223be60 100644
--- a/HIRS_Utils/build.gradle
+++ b/HIRS_Utils/build.gradle
@@ -42,10 +42,6 @@ dependencies {
     testAnnotationProcessor libs.lombok
 }
 
-test {
-    useJUnitPlatform()
-}
-
 jar {
     duplicatesStrategy = DuplicatesStrategy.EXCLUDE
     manifest {
diff --git a/build.gradle b/build.gradle
index 73f8a56c1..40406567b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,7 @@ plugins {
     id 'com.github.spotbugs' version '6.0.13' apply false
     id 'org.owasp.dependencycheck' version '11.1.1'
     id 'java'
+    id 'jacoco'
 }
 
 // Global checkstyle file
@@ -19,6 +20,7 @@ subprojects {
     apply plugin: "java"
     apply plugin: "checkstyle"
     apply plugin: "org.owasp.dependencycheck"
+    apply plugin: "jacoco"
 
     repositories {
         flatDir { dirs "lib" }
@@ -31,6 +33,20 @@ subprojects {
         }
     }
 
+    jacoco {
+        toolVersion = '0.8.12'
+    }
+
+    if (project.name != 'tcg_rim_tool') // run tests on every subproject except for rim_tools
+        test {
+            useJUnitPlatform() // Use JUnit platform
+            finalizedBy jacocoTestReport // Generate the JaCoCo report after running tests
+        }
+
+    jacocoTestReport {
+        dependsOn test // tests are required to run before generating the report
+    }
+
     checkstyle {
         toolVersion = '10.20.0'
         configFile file("${rootDir}/config/checkstyle/checkstyle.xml")
@@ -61,7 +77,6 @@ subprojects {
     }
 }
 
-
 dependencies {
     repositories {
         // Use Maven Central for resolving dependencies.
diff --git a/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java b/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java
index 06254b4ce..f34fa75c7 100644
--- a/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java
+++ b/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java
@@ -1,45 +1,56 @@
 package hirs.swid;
 
 import hirs.utils.rim.ReferenceManifestValidator;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
-import org.springframework.test.context.event.annotation.AfterTestClass;
-import org.springframework.test.context.event.annotation.BeforeTestClass;
 
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Objects;
 
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-
+//TODO tests are broken
 public class TestSwidTagGateway {
+    private static final String ATTRIBUTES_FILE = Objects.requireNonNull(
+            TestSwidTagGateway.class.getClassLoader()
+                    .getResource("rim_fields.json")).getPath();
+
+    private static final String CA_CHAIN_FILE = Objects.requireNonNull(
+            TestSwidTagGateway.class.getClassLoader()
+                    .getResource("RimCertChain.pem")).getPath();
+
+    private static final String SUPPORT_RIM_FILE = Objects.requireNonNull(
+            TestSwidTagGateway.class.getClassLoader()
+                    .getResource("TpmLog.bin")).getPath();
+
+    private static SwidTagGateway gateway;
+
+    private static ReferenceManifestValidator validator;
+
     private final String DEFAULT_OUTPUT = "generated_swidTag.swidtag";
+
     private final String BASE_USER_CERT = "generated_user_cert.swidtag";
-    private final String BASE_USER_CERT_EMBED = "generated_user_cert_embed.swidtag";
-    private final String BASE_DEFAULT_CERT = "generated_default_cert.swidtag";
-    private final String BASE_RFC3339_TIMESTAMP = "generated_timestamp_rfc3339.swidtag";
-    private final String BASE_RFC3852_TIMESTAMP = "generated_timestamp_rfc3852.swidtag";
-    private final String ATTRIBUTES_FILE = TestSwidTagGateway.class.getClassLoader()
-            .getResource("rim_fields.json").getPath();
-    private final String JKS_KEYSTORE_FILE = TestSwidTagGateway.class.getClassLoader()
-            .getResource("keystore.jks").getPath();
-    private final String SIGNING_CERT_FILE = TestSwidTagGateway.class.getClassLoader()
-            .getResource("RimSignCert.pem").getPath();
-    private final String PRIVATE_KEY_FILE = TestSwidTagGateway.class.getClassLoader()
-            .getResource("privateRimKey.pem").getPath();
-    private final String CA_CHAIN_FILE = TestSwidTagGateway.class.getClassLoader()
-            .getResource("RimCertChain.pem").getPath();
-    private final String SUPPORT_RIM_FILE = TestSwidTagGateway.class.getClassLoader()
-            .getResource("TpmLog.bin").getPath();
-    private final String RFC3852_COUNTERSIGNATURE_FILE = TestSwidTagGateway.class.getClassLoader()
-            .getResource("counterSignature.file").getPath();
-    private SwidTagGateway gateway;
-    private ReferenceManifestValidator validator;
+
+    private final String JKS_KEYSTORE_FILE = Objects.requireNonNull(TestSwidTagGateway.class.getClassLoader()
+            .getResource("keystore.jks")).getPath();
+
+    private final String SIGNING_CERT_FILE = Objects.requireNonNull(TestSwidTagGateway.class.getClassLoader()
+            .getResource("RimSignCert.pem")).getPath();
+
+    private final String PRIVATE_KEY_FILE = Objects.requireNonNull(TestSwidTagGateway.class.getClassLoader()
+            .getResource("privateRimKey.pem")).getPath();
+
+    private final String RFC3852_COUNTERSIGNATURE_FILE = Objects.requireNonNull(
+            TestSwidTagGateway.class.getClassLoader()
+                    .getResource("counterSignature.file")).getPath();
+
     private InputStream expectedFile;
 
-    @BeforeTestClass
-    public void setUp() throws Exception {
+    @BeforeAll
+    public static void setUp() {
         gateway = new SwidTagGateway();
         gateway.setRimEventLog(SUPPORT_RIM_FILE);
         gateway.setAttributesFile(ATTRIBUTES_FILE);
@@ -48,7 +59,7 @@ public void setUp() throws Exception {
         validator.setTrustStoreFile(CA_CHAIN_FILE);
     }
 
-    @AfterTestClass
+    @AfterEach
     public void tearDown() throws Exception {
         if (expectedFile != null) {
             expectedFile.close();
@@ -87,6 +98,7 @@ public void testCreateBaseUserCertEmbedded() {
         gateway.setPemPrivateKeyFile(PRIVATE_KEY_FILE);
         gateway.setEmbeddedCert(true);
         gateway.generateSwidTag(DEFAULT_OUTPUT);
+        final String BASE_USER_CERT_EMBED = "generated_user_cert_embed.swidtag";
         expectedFile = TestSwidTagGateway.class.getClassLoader()
                 .getResourceAsStream(BASE_USER_CERT_EMBED);
         assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
@@ -103,6 +115,7 @@ public void testCreateBaseDefaultCert() {
         gateway.setDefaultCredentials(true);
         gateway.setJksTruststoreFile(JKS_KEYSTORE_FILE);
         gateway.generateSwidTag(DEFAULT_OUTPUT);
+        final String BASE_DEFAULT_CERT = "generated_default_cert.swidtag";
         expectedFile = TestSwidTagGateway.class.getClassLoader()
                 .getResourceAsStream(BASE_DEFAULT_CERT);
         assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
@@ -121,6 +134,7 @@ public void testCreateTimestampRfc3339() {
         gateway.setTimestampFormat("RFC3339");
         gateway.setTimestampArgument("2023-01-01T00:00:00Z");
         gateway.generateSwidTag(DEFAULT_OUTPUT);
+        final String BASE_RFC3339_TIMESTAMP = "generated_timestamp_rfc3339.swidtag";
         expectedFile = TestSwidTagGateway.class.getClassLoader()
                 .getResourceAsStream(BASE_RFC3339_TIMESTAMP);
         assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
@@ -139,6 +153,7 @@ public void testCreateTimestampRfc3852() {
         gateway.setTimestampFormat("RFC3852");
         gateway.setTimestampArgument(RFC3852_COUNTERSIGNATURE_FILE);
         gateway.generateSwidTag(DEFAULT_OUTPUT);
+        final String BASE_RFC3852_TIMESTAMP = "generated_timestamp_rfc3852.swidtag";
         expectedFile = TestSwidTagGateway.class.getClassLoader()
                 .getResourceAsStream(BASE_RFC3852_TIMESTAMP);
         assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
@@ -150,10 +165,10 @@ public void testCreateTimestampRfc3852() {
      * This test corresponds to the arguments:
      * -v 
      */
-
-    public void testvalidateSwidtagFile() {
-        String filepath = TestSwidTagGateway.class.getClassLoader()
-                .getResource(BASE_USER_CERT).getPath();
+    @Test
+    public void testValidateSwidtagFile() {
+        final String filepath = Objects.requireNonNull(TestSwidTagGateway.class.getClassLoader()
+                .getResource(BASE_USER_CERT)).getPath();
         System.out.println("Validating file at " + filepath);
         validator.setRim(DEFAULT_OUTPUT);
         assertTrue(validator.validateRim(SIGNING_CERT_FILE));
@@ -178,13 +193,7 @@ private boolean compareFileBytesToExpectedFile(String file) {
                     return false;
                 }
             }
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-            return false;
-        } catch (IOException e) {
-            e.printStackTrace();
-            return false;
-        } catch (NullPointerException e) {
+        } catch (IOException | NullPointerException e) {
             e.printStackTrace();
             return false;
         } finally {

From 828afe2e2d469ef4c27bc924b833878b519f3913 Mon Sep 17 00:00:00 2001
From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Fri, 14 Feb 2025 14:34:24 -0500
Subject: [PATCH 12/14] issue_896: Realized there might be more work needed for
 the validation part. Started adding more logic to validation.

---
 .../entity/userdefined/info/NetworkInfo.java  |   2 +-
 .../CertificateAttributeScvValidator.java     |  96 +-
 .../SupplyChainCredentialValidatorTest.java   | 908 ++++++++++--------
 3 files changed, 575 insertions(+), 431 deletions(-)

diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/NetworkInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/NetworkInfo.java
index 73ec8d801..8993d3be8 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/NetworkInfo.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/NetworkInfo.java
@@ -23,7 +23,7 @@ public class NetworkInfo implements Serializable {
 
     @XmlElement
     @Getter
-    @Column(length = DeviceInfoEnums.LONG_STRING_LENGTH)
+    @Column
     private String hostname;
 
     @XmlElement
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
index d769fbd81..ee4c84030 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
@@ -241,7 +241,7 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0(
             // All V1 components listed in the Platform Credential must have a manufacturer and model
             for (ComponentIdentifier pcComponent : allPcComponents) {
 
-                fieldValidation = !hasEmptyValueForRequiredField("componentManufacturer",
+                fieldValidation = !isRequiredASN1StringFieldBlank("componentManufacturer",
                         pcComponent.getComponentManufacturer());
 
                 if (!fieldValidation) {
@@ -250,7 +250,7 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0(
 
                 passesValidation &= fieldValidation;
 
-                fieldValidation = !hasEmptyValueForRequiredField("componentModel",
+                fieldValidation = !isRequiredASN1StringFieldBlank("componentModel",
                         pcComponent.getComponentModel());
 
                 if (!fieldValidation) {
@@ -261,43 +261,53 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0(
             }
 
         } else if (platformCredential.getPlatformConfigurationV2() != null) {
-
             // Retrieve the list of all version 2 component identifiers from the Platform Credential
             List allV2PcComponents
                     = new ArrayList<>(platformCredential.getComponentIdentifiersV2());
 
-            // All V2 components listed in the Platform Credential must have a manufacturer and model
-            for (ComponentIdentifierV2 pcComponent : allV2PcComponents) {
-
-                fieldValidation = !hasEmptyValueForRequiredField("componentManufacturer",
-                        pcComponent.getComponentManufacturer());
-
-                if (!fieldValidation) {
-                    resultMessage.append("Component manufacturer is empty\n");
-                }
+            if (componentInfos == null) {
+                log.error("The device's reported list of components is null.");
+                passesValidation = false;
+            } else if (componentInfos.size() != allV2PcComponents.size()) {
+                log.error(
+                        "The device's reported list of components' sizes (size of {}) do not match the size (size of {}) "
+                                + "of the platform credential's version 2 component identifiers.",
+                        componentInfos.size(), allV2PcComponents.size());
 
-                passesValidation &= fieldValidation;
-
-                fieldValidation = !hasEmptyValueForRequiredField("componentModel",
-                        pcComponent.getComponentModel());
+                passesValidation = false;
+            } else {
+                // All V2 components listed in the Platform Credential must have a manufacturer and model
+                for (ComponentIdentifierV2 pcComponent : allV2PcComponents) {
+                    fieldValidation = !isRequiredASN1StringFieldBlank("componentManufacturer",
+                            pcComponent.getComponentManufacturer());
 
-                if (!fieldValidation) {
-                    resultMessage.append("Component model is empty\n");
-                }
+                    if (!fieldValidation) {
+                        resultMessage.append("Component manufacturer is empty\n");
+                    }
 
-                passesValidation &= fieldValidation;
+                    passesValidation &= fieldValidation;
 
-                if (pcComponent.getComponentClass() == null) {
-                    passesValidation = false;
-                } else {
-                    fieldValidation = !hasEmptyValueForRequiredField("componentClassRegistry",
-                            pcComponent.getComponentClass().getRegistryType());
+                    fieldValidation = !isRequiredASN1StringFieldBlank("componentModel",
+                            pcComponent.getComponentModel());
 
                     if (!fieldValidation) {
-                        resultMessage.append("Component class registry is empty\n");
+                        resultMessage.append("Component model is empty\n");
                     }
 
                     passesValidation &= fieldValidation;
+
+                    if (pcComponent.getComponentClass() == null) {
+                        passesValidation = false;
+                    } else {
+                        fieldValidation = !isRequiredStringFieldBlank("componentClassRegistry",
+                                pcComponent.getComponentClass().getRegistryType());
+
+                        if (!fieldValidation) {
+                            resultMessage.append("Component class registry is empty\n");
+                        }
+
+                        passesValidation &= fieldValidation;
+                    }
                 }
             }
         }
@@ -564,24 +574,32 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc
 
         log.info("Validating the following Platform Cert components...");
         pcComponents.forEach(component -> log.info(component.toString()));
+
         log.info("...against the the following DeviceInfoReport components:");
         allDeviceInfoComponents.forEach(component -> log.info(component.toString()));
+
         Set manufacturerSet = new HashSet<>();
+        // create a set of component manufacturers
         pcComponents.forEach(pcComp -> manufacturerSet.add(pcComp.getComponentManufacturer()));
 
         // Create a list for unmatched components across all manufacturers to display at the end.
         List pcUnmatchedComponents = new ArrayList<>();
 
         for (ASN1UTF8String derUtf8Manufacturer : manufacturerSet) {
+
+            // look for all the component identifiers whose manufacturer matches that of the current
+            // manufacturer
             List pcComponentsFromManufacturer
                     = pcComponents.stream().filter(compIdentifier
                             -> compIdentifier.getComponentManufacturer().equals(derUtf8Manufacturer))
                     .collect(Collectors.toList());
 
-            String pcManufacturer = derUtf8Manufacturer.getString();
+            // look for all the component infos whose manufacturer matches that of the current
+            // manufacturer
+            String currentPCManufacturer = derUtf8Manufacturer.getString();
             List deviceInfoComponentsFromManufacturer
                     = allDeviceInfoComponents.stream().filter(componentInfo
-                            -> componentInfo.getComponentManufacturer().equals(pcManufacturer))
+                            -> componentInfo.getComponentManufacturer().equals(currentPCManufacturer))
                     .collect(Collectors.toList());
 
             // For each component listed in the platform credential from this manufacturer
@@ -613,6 +631,7 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc
                     }
                 }
             }
+
             // For each component listed in the platform credential from this manufacturer
             // find the ones that specify value for the revision field so we can match the most
             // specific ones first.
@@ -621,6 +640,7 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc
                             -> compIdentifier.getComponentRevision() != null
                             && StringUtils.isNotEmpty(compIdentifier.getComponentRevision().getString()))
                     .toList();
+
             // Now match up the components from the device info that are from the same
             // manufacturer and specify a value for the revision field. As matches are found,
             // remove them from both lists.
@@ -721,7 +741,7 @@ public static boolean isMatch(final ComponentIdentifier pcComponent,
     private static boolean isMatchOrEmptyInPlatformCert(
             final String evidenceFromDevice,
             final ASN1UTF8String valueInPlatformCert) {
-        if (valueInPlatformCert == null || StringUtils.isEmpty(valueInPlatformCert.getString())) {
+        if (StringUtils.isBlank(valueInPlatformCert.getString())) {
             return true;
         }
         return valueInPlatformCert.getString().equals(evidenceFromDevice);
@@ -807,7 +827,7 @@ private static boolean requiredPlatformCredentialFieldIsNonEmptyAndMatches(
             final String platformCredentialFieldName,
             final String platformCredentialFieldValue,
             final String otherValue) {
-        if (hasEmptyValueForRequiredField(platformCredentialFieldName,
+        if (isRequiredStringFieldBlank(platformCredentialFieldName,
                 platformCredentialFieldValue)) {
             return false;
         }
@@ -845,10 +865,10 @@ private static boolean optionalPlatformCredentialFieldNullOrMatches(
      * @param fieldValue  value of the field
      * @return true if fieldValue is null or empty; false otherwise
      */
-    private static boolean hasEmptyValueForRequiredField(final String description,
-                                                         final String fieldValue) {
-        if (StringUtils.isEmpty(fieldValue)) {
-            log.error("Required field was empty or null in Platform Credential: {}", description);
+    private static boolean isRequiredStringFieldBlank(final String description,
+                                                      final String fieldValue) {
+        if (StringUtils.isBlank(fieldValue)) {
+            log.error("Required string field was empty or null in Platform Credential: {}", description);
             return true;
         }
         return false;
@@ -900,10 +920,10 @@ private static boolean platformCredentialFieldMatches(
      * @param fieldValue  value of the field
      * @return true if fieldValue is null or empty; false otherwise
      */
-    private static boolean hasEmptyValueForRequiredField(final String description,
-                                                         final ASN1UTF8String fieldValue) {
-        if (fieldValue == null || StringUtils.isEmpty(fieldValue.getString().trim())) {
-            log.error("Required field was empty or null in Platform Credential: {}", description);
+    private static boolean isRequiredASN1StringFieldBlank(final String description,
+                                                          final ASN1UTF8String fieldValue) {
+        if (fieldValue == null || StringUtils.isBlank(fieldValue.getString().trim())) {
+            log.error("Required ASN1 string field was empty or null in Platform Credential: {}", description);
             return true;
         }
         return false;
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
index 5605aba67..d749ea2a7 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
@@ -6,7 +6,14 @@
 import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential;
 import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
 import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
+import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentClass;
 import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
+import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfigurationV1;
+import hirs.attestationca.persist.entity.userdefined.certificate.attributes.URIReference;
+import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.AttributeStatus;
+import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.CertificateIdentifier;
+import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
+import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.PlatformConfigurationV2;
 import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
 import hirs.attestationca.persist.entity.userdefined.info.FirmwareInfo;
 import hirs.attestationca.persist.entity.userdefined.info.HardwareInfo;
@@ -260,111 +267,6 @@ public static void tearDown() {
         }
     }
 
-    /**
-     * Create a new X.509 attribute certificate given the holder cert, the signing cert, and the
-     * signing key.
-     *
-     * @param targetCert   X509Certificate that will be the holder of the attribute cert
-     * @param signingCert  X509Certificate used to sign the new attribute cert
-     * @param caPrivateKey PrivateKey used to sign the new attribute cert
-     * @return new X509AttributeCertificate
-     */
-    private static X509AttributeCertificateHolder createAttributeCert(
-            final X509Certificate targetCert, final X509Certificate signingCert,
-            final PrivateKey caPrivateKey) {
-        X509AttributeCertificateHolder cert = null;
-        try {
-            final int timeRange = 50000;
-            AttributeCertificateHolder holder =
-                    new AttributeCertificateHolder(new X509CertificateHolder(
-                            targetCert.getEncoded()));
-            AttributeCertificateIssuer issuer =
-                    new AttributeCertificateIssuer(new X500Name(signingCert
-                            .getSubjectX500Principal().getName()));
-            BigInteger serialNumber = BigInteger.ONE;
-            Date notBefore = new Date(System.currentTimeMillis() - timeRange);
-            Date notAfter = new Date(System.currentTimeMillis() + timeRange);
-            X509v2AttributeCertificateBuilder builder =
-                    new X509v2AttributeCertificateBuilder(holder, issuer, serialNumber, notBefore,
-                            notAfter);
-
-            ContentSigner signer =
-                    new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC")
-                            .build(caPrivateKey);
-
-            cert = builder.build(signer);
-        } catch (CertificateEncodingException | IOException | OperatorCreationException e) {
-            fail("Exception occurred while creating a cert", e);
-        }
-
-        return cert;
-
-    }
-
-    /**
-     * Create a new X.509 public-key certificate signed by the given certificate.
-     *
-     * @param keyPair     KeyPair to create the cert for
-     * @param signingKey  PrivateKey of the signing cert
-     * @param signingCert signing cert
-     * @return new X509Certificate
-     */
-    private static X509Certificate createCertSignedByAnotherCert(final KeyPair keyPair,
-                                                                 final PrivateKey signingKey,
-                                                                 final X509Certificate signingCert) {
-        final int timeRange = 10000;
-        X509Certificate cert = null;
-        try {
-
-            X500Name issuerName = new X500Name(signingCert.getSubjectX500Principal().getName());
-            X500Name subjectName = new X500Name("CN=Test V3 Certificate");
-            BigInteger serialNumber = BigInteger.ONE;
-            Date notBefore = new Date(System.currentTimeMillis() - timeRange);
-            Date notAfter = new Date(System.currentTimeMillis() + timeRange);
-            X509v3CertificateBuilder builder =
-                    new JcaX509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter,
-                            subjectName, keyPair.getPublic());
-            ContentSigner signer =
-                    new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC").build(signingKey);
-            return new JcaX509CertificateConverter().setProvider("BC").getCertificate(
-                    builder.build(signer));
-        } catch (Exception e) {
-            fail("Exception occurred while creating a cert", e);
-        }
-        return cert;
-    }
-
-    /**
-     * Creates a self-signed X.509 public-key certificate.
-     *
-     * @param pair KeyPair to create the cert for
-     * @return self-signed X509Certificate
-     */
-    private static X509Certificate createSelfSignedCertificate(final KeyPair pair) {
-        Security.addProvider(new BouncyCastleProvider());
-        final int timeRange = 10000;
-        X509Certificate cert = null;
-        try {
-
-            X500Name issuerName = new X500Name("CN=Test Self-Signed V3 Certificate");
-            X500Name subjectName = new X500Name("CN=Test Self-Signed V3 Certificate");
-            BigInteger serialNumber = BigInteger.ONE;
-            Date notBefore = new Date(System.currentTimeMillis() - timeRange);
-            Date notAfter = new Date(System.currentTimeMillis() + timeRange);
-            X509v3CertificateBuilder builder =
-                    new JcaX509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter,
-                            subjectName, pair.getPublic());
-            ContentSigner signer =
-                    new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC").build(
-                            pair.getPrivate());
-            return new JcaX509CertificateConverter().setProvider("BC").getCertificate(
-                    builder.build(signer));
-        } catch (Exception e) {
-            fail("Exception occurred while creating a cert", e);
-        }
-        return cert;
-    }
-
     /**
      * Setup mocks.
      */
@@ -385,129 +287,6 @@ public void tearDownAfterEach() throws Exception {
         }
     }
 
-    /**
-     * Creates a new RSA 1024-bit KeyPair using a Bouncy Castle Provider.
-     *
-     * @return new KeyPair
-     */
-    private KeyPair createKeyPair() {
-        final int keySize = 1024;
-        KeyPairGenerator gen;
-        KeyPair keyPair = null;
-        try {
-            gen = KeyPairGenerator.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME);
-            gen.initialize(keySize, SECURE_RANDOM);
-            keyPair = gen.generateKeyPair();
-        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
-            fail("Error occurred while generating key pair", e);
-        }
-        return keyPair;
-    }
-
-    /**
-     * Helper method that creates a device info report.
-     *
-     * @return device info report
-     */
-    private DeviceInfoReport setupDeviceInfoReport() throws UnknownHostException {
-
-        // setup network info
-        final byte[] byteAddress = new byte[] {127, 0, 0, 1};
-        InetAddress inetAddress = InetAddress.getByAddress(byteAddress);
-        NetworkInfo networkInfo = new NetworkInfo("the-device", inetAddress, new byte[] {1, 0, 1, 0, 1, 0});
-
-        // setup os info
-        OSInfo osInfo = new OSInfo("Windows", "11.0", "Not Specified",
-                "Not Specified", "Not Specified");
-
-        // setup firmware info
-        FirmwareInfo firmwareInfo = new FirmwareInfo("Dell Inc", "A11",
-                "03/12/2013");
-
-        // setup hardware info
-        HardwareInfo hardwareInfo = new HardwareInfo(
-                "ACME",
-                "anvil",
-                "3.0",
-                "1234",
-                "567",
-                "890");
-
-        TPMInfo tpmInfo = new TPMInfo();
-
-        return new DeviceInfoReport(networkInfo, osInfo, firmwareInfo, hardwareInfo, tpmInfo);
-    }
-
-    /**
-     * Helper method that creates a device info report that contains the provided components.
-     *
-     * @return device info report that contains provided components
-     * @throws IOException is thrown if issues arise from parsing out the paccor output
-     */
-    private DeviceInfoReport setupDeviceInfoReportWithComponents() throws IOException {
-        return setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_TXT);
-    }
-
-    /**
-     * Helper method that creates a device info report that contains the provided non-specified components.
-     *
-     * @return device info report that contains not specified components
-     * @throws IOException is thrown if issues arise from parsing out the paccor output
-     */
-    private DeviceInfoReport setupDeviceInfoReportWithNotSpecifiedComponents()
-            throws IOException {
-        return setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_NOT_SPECIFIED_TXT);
-    }
-
-    /**
-     * Helper method that generates a device info report using the provided sample paccor output.
-     *
-     * @param paccorOutputResource sample paccor output text
-     * @return device info report
-     * @throws IOException is thrown if issues arise from parsing out the paccor output
-     */
-    private DeviceInfoReport setupDeviceInfoReportWithComponents(
-            final String paccorOutputResource) throws IOException {
-        DeviceInfoReport deviceInfoReport = setupDeviceInfoReport();
-        URL url = SupplyChainCredentialValidator.class.getResource(paccorOutputResource);
-        String paccorOutputString = IOUtils.toString(url, StandardCharsets.UTF_8);
-        deviceInfoReport.setPaccorOutputString(paccorOutputString);
-        return deviceInfoReport;
-    }
-
-    /**
-     * Helper method that generates a collection of component info that can be used
-     * for this class' test methods.
-     *
-     * @return a generic list of component info
-     */
-    private List retrieveListOfComponentInfos() {
-
-        return List.of(
-                new ComponentInfo("the-device", "Dell Inc", "11",
-                        "9ZLUO9", "Not Specified", "020000123",
-                        "2.23.133.18.3.1"),
-                new ComponentInfo("the-device", "9090", "AE12",
-                        "Not Specified", "Not Specified", "00070700",
-                        "2.23.133.18.3.4"),
-                new ComponentInfo("the-device", "Not Specified", "109 NVM",
-                        "1110_1100_2230_0000_8CE3_8E10_0164_9CC7.", "Not Specified",
-                        "00060001", "2.23.133.18.3.5"));
-    }
-
-    /**
-     * Helper method that returns an IP Address.
-     *
-     * @return IP address
-     */
-    private InetAddress getTestIpAddress() {
-        try {
-            final byte[] byteAddress = new byte[] {127, 0, 0, 1};
-            return InetAddress.getByAddress(byteAddress);
-        } catch (UnknownHostException e) {
-            return null;
-        }
-    }
 
     /**
      * Checks if the ST Micro Endorsement Credential can be validated against the
@@ -608,7 +387,7 @@ public final void validateIntelPlatformCredentialAttributes()
 
         PlatformCredential pc = new PlatformCredential(certBytes);
 
-        DeviceInfoReport deviceInfoReport = buildReport(
+        DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(
                 new HardwareInfo(PLATFORM_MANUFACTURER, PLATFORM_MODEL,
                         PLATFORM_VERSION, TEST_BOARD_SERIAL_NUMBER,
                         TEST_CHASSIS_SERIAL_NUMBER, TEST_BOARD_SERIAL_NUMBER));
@@ -637,7 +416,7 @@ public final void validateIntelPlatformCredentialAttributes()
     @Test
     public final void validatePlatformCredentialWithDeviceBaseboard()
             throws Exception {
-        DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo(
+        DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(new HardwareInfo(
                 DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED,
                 DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED,
                 DeviceInfoEnums.NOT_SPECIFIED, TEST_BOARD_SERIAL_NUMBER));
@@ -670,7 +449,7 @@ public final void validatePlatformCredentialWithDeviceBaseboard()
     public final void validatePlatformCredentialWithDeviceChassis()
             throws Exception {
 
-        DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo(
+        DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(new HardwareInfo(
                 DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED,
                 DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED,
                 TEST_CHASSIS_SERIAL_NUMBER, DeviceInfoEnums.NOT_SPECIFIED));
@@ -705,7 +484,7 @@ public final void validatePlatformCredentialWithDeviceChassis()
     public final void validatePlatformCredentialWithDeviceSystemSerialNumber()
             throws Exception {
 
-        DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo(
+        DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(new HardwareInfo(
                 DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED,
                 DeviceInfoEnums.NOT_SPECIFIED, TEST_BOARD_SERIAL_NUMBER,
                 DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED));
@@ -738,7 +517,7 @@ public final void validatePlatformCredentialWithDeviceSystemSerialNumber()
     public final void validatePlatformCredentialCombinedWithChassisSerialNumbersMatchedBaseboard()
             throws Exception {
 
-        DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo(
+        DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(new HardwareInfo(
                 DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED,
                 DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED,
                 TEST_BOARD_SERIAL_NUMBER, DeviceInfoEnums.NOT_SPECIFIED));
@@ -772,7 +551,7 @@ public final void validatePlatformCredentialCombinedWithChassisSerialNumbersMatc
     public final void validatePlatformCredentialCombinedWithBaseboardSerialNumbersMatchedChassis()
             throws Exception {
 
-        DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo(
+        DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(new HardwareInfo(
                 DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED,
                 DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED,
                 DeviceInfoEnums.NOT_SPECIFIED, TEST_CHASSIS_SERIAL_NUMBER));
@@ -805,7 +584,7 @@ public final void validatePlatformCredentialCombinedWithBaseboardSerialNumbersMa
     public final void validatePlatformCredentialCombinedWithSystemSerialNumbersMatchedChassis()
             throws Exception {
 
-        DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo(
+        DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(new HardwareInfo(
                 DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED,
                 DeviceInfoEnums.NOT_SPECIFIED, TEST_CHASSIS_SERIAL_NUMBER,
                 DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED));
@@ -840,7 +619,7 @@ public final void validatePlatformCredentialCombinedWithSystemSerialNumbersMatch
     public final void validatePlatformCredentialWithNoDeviceSerialNumbers()
             throws Exception {
 
-        DeviceInfoReport deviceInfoReport = buildReport(
+        DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(
                 new HardwareInfo(PLATFORM_MANUFACTURER, PLATFORM_MODEL,
                         PLATFORM_VERSION, DeviceInfoEnums.NOT_SPECIFIED,
                         DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED));
@@ -877,7 +656,7 @@ public final void validatePlatformCredentialWithNoDeviceSerialNumbers()
     public final void validatePlatformCredentialCombinedWithNoMatchedDeviceSerialNumbers()
             throws Exception {
 
-        DeviceInfoReport deviceInfoReport = buildReport(
+        DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(
                 new HardwareInfo(DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED,
                         DeviceInfoEnums.NOT_SPECIFIED, "zzz", "aaa", "bbb"));
 
@@ -1449,91 +1228,28 @@ public void testMatcher() {
     }
 
     /**
-     * Helper method that mocks out the Platform Credential object used for this class' test methods.
+     * Tests that TPM 2.0 Platform Credentials validate correctly against the device info report
+     * when there are no components.
      *
-     * @param deviceInfoReport device info report
-     * @return mocked out Platform Credential
-     * @throws IOException is thrown if there are any issues using the provided device info report's
-     *                     information
+     * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-    private PlatformCredential setupMatchingPlatformCredential(
-            final DeviceInfoReport deviceInfoReport) throws IOException {
-        PlatformCredential platformCredential = mock(PlatformCredential.class);
-
-        when(platformCredential.getCredentialType()).thenReturn(
-                PlatformCredential.CERTIFICATE_TYPE_2_0);
-
-        when(platformCredential.getManufacturer())
-                .thenReturn(deviceInfoReport.getHardwareInfo().getManufacturer());
+    @Test
+    public final void testValidatePlatformCredentialAttributesV2p0NoComponentsPass()
+            throws IOException {
+        DeviceInfoReport deviceInfoReport = setupDeviceInfoReport();
 
-        when(platformCredential.getModel())
-                .thenReturn(deviceInfoReport.getHardwareInfo().getProductName());
+        PlatformCredential platformCredential =
+                setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
 
-        when(platformCredential.getPlatformSerial())
-                .thenReturn(deviceInfoReport.getHardwareInfo().getBaseboardSerialNumber());
-
-        when(platformCredential.getVersion())
-                .thenReturn(deviceInfoReport.getHardwareInfo().getVersion());
-
-        when(platformCredential.getSerialNumber()).thenReturn(
-                new BigInteger(deviceInfoReport.getHardwareInfo().getSystemSerialNumber()));
-
-        List deviceInfoComponents
-                = SupplyChainCredentialValidator.getComponentInfoFromPaccorOutput(
-                deviceInfoReport.getNetworkInfo().getHostname(),
-                deviceInfoReport.getPaccorOutputString());
-
-        List componentIdentifierList = new ArrayList<>();
-        for (ComponentInfo deviceInfoComponent : deviceInfoComponents) {
-            DERUTF8String serial = null;
-            DERUTF8String revision = null;
-            if (deviceInfoComponent.getComponentSerial() != null) {
-                serial = new DERUTF8String(deviceInfoComponent.getComponentSerial());
-            }
-            if (deviceInfoComponent.getComponentRevision() != null) {
-                revision = new DERUTF8String(deviceInfoComponent.getComponentRevision());
-            }
-            componentIdentifierList.add(new ComponentIdentifier(
-                    new DERUTF8String(deviceInfoComponent.getComponentManufacturer()),
-                    new DERUTF8String(deviceInfoComponent.getComponentModel()),
-                    serial,
-                    revision,
-                    null,
-                    ASN1Boolean.TRUE,
-                    Collections.emptyList()
-            ));
-
-        }
-
-        when(platformCredential.getComponentIdentifiers()).thenReturn(componentIdentifierList);
-
-        return platformCredential;
-    }
-
-    /**
-     * Tests that TPM 2.0 Platform Credentials validate correctly against the device info report
-     * when there are no components.
-     *
-     * @throws IOException if unable to set up DeviceInfoReport from resource file
-     */
-    @Test
-    public final void testValidatePlatformCredentialAttributesV2p0NoComponentsPass()
-            throws IOException {
-        DeviceInfoReport deviceInfoReport = setupDeviceInfoReport();
-
-        PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
-
-        List componentInfoList = retrieveListOfComponentInfos();
-
-        AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
-                .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport,
-                        componentResultRepository, componentAttributeRepository,
-                        componentInfoList, UUID.randomUUID(), false);
-        assertEquals(AppraisalStatus.Status.PASS,
-                appraisalStatus.getAppStatus());
-        assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
-                appraisalStatus.getMessage());
-    }
+        AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
+                .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport,
+                        componentResultRepository, componentAttributeRepository,
+                        Collections.emptyList(), UUID.randomUUID(), false);
+        assertEquals(AppraisalStatus.Status.PASS,
+                appraisalStatus.getAppStatus());
+        assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
+                appraisalStatus.getMessage());
+    }
 
     /**
      * Tests that TPM 2.0 Platform Credentials validate correctly against the device info report
@@ -1546,7 +1262,8 @@ public final void testValidatePlatformCredentialAttributesV2p0WithComponentsPass
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
 
-        PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        PlatformCredential platformCredential =
+                setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
 
         List componentInfoList = retrieveListOfComponentInfos();
 
@@ -1571,7 +1288,8 @@ public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSys
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
 
-        PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        PlatformCredential platformCredential =
+                setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
 
         List componentInfoList = retrieveListOfComponentInfos();
 
@@ -1619,17 +1337,20 @@ public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSys
      *
      * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-    //@Test todo ea
+    @Test
     public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull()
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
 
-        PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        PlatformCredential platformCredential =
+                setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
+
+        List componentInfoList = retrieveListOfComponentInfos();
 
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
 
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
 
@@ -1640,15 +1361,15 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Platform manufacturer did not match\n", result.getMessage());
 
-        platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -1656,15 +1377,15 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(result.getAppStatus(), AppraisalStatus.Status.FAIL);
         assertEquals(result.getMessage(), "Platform model did not match\n");
 
-        platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -1672,13 +1393,13 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
-        platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -1686,16 +1407,16 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
 
-        platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -1706,15 +1427,15 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Component manufacturer is empty\n", result.getMessage());
 
-        platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -1724,7 +1445,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Component model is empty\n", result.getMessage());
 
@@ -1736,83 +1457,98 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull
      *
      * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-//    @Test
+    @Test
     public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpty()
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
 
-        PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        PlatformCredential platformCredential =
+                setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
+
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
+
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
+
+        // Part II: Testing using an empty platform manufacturer string
         when(platformCredential.getManufacturer()).thenReturn("");
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Platform manufacturer did not match\n", result.getMessage());
 
-        platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
+
+        // Part III: Testing using an empty platform model string
         when(platformCredential.getModel()).thenReturn("");
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Platform model did not match\n", result.getMessage());
 
-        platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
+
+        // Part IV: Testing using an empty platform serial number
         when(platformCredential.getPlatformSerial()).thenReturn("");
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Platform serial did not match\n", result.getMessage());
 
-        platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
+
+        // Part V: Testing using an empty platform version string
         when(platformCredential.getVersion()).thenReturn("");
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Platform version did not match\n", result.getMessage());
 
-        platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
+
+        // Part VI: Testing using an empty computer manufacturer string
         List modifiedComponentIdentifiers
                 = platformCredential.getComponentIdentifiers();
         modifiedComponentIdentifiers.get(0).setComponentManufacturer(new DERUTF8String(""));
@@ -1820,49 +1556,52 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
-        assertEquals("Component manufacturer is empty\n"
-                        + "There are unmatched components:\n"
-                        + "Manufacturer=, Model=Core i7, Serial=Not Specified,"
-                        + " Revision=Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz;\n",
+        assertEquals("Component manufacturer is empty\n",
                 result.getMessage());
 
-        platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
+
+        // Part VII: Testing using an empty computer model string
         modifiedComponentIdentifiers = platformCredential.getComponentIdentifiers();
         modifiedComponentIdentifiers.get(0).setComponentModel(new DERUTF8String(""));
         when(platformCredential.getComponentIdentifiers()).thenReturn(modifiedComponentIdentifiers);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
         assertEquals("Component model is empty\n", result.getMessage());
     }
 
     /**
-     * Tests that {@link SupplyChainCredentialValidator} failes when a component exists in the
+     * Tests that {@link SupplyChainCredentialValidator} fails when a component exists in the
      * platform credential, but not in the device info report.
      *
      * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-//    @Test
+    //@Test
     public final void testValidatePlatformCredentialAttributesV2p0MissingComponentInDeviceInfo()
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
 
-        PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        PlatformCredential platformCredential =
+                setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
+
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -1878,9 +1617,11 @@ public final void testValidatePlatformCredentialAttributesV2p0MissingComponentIn
                 ASN1Boolean.FALSE,
                 Collections.emptyList()
         ));
+
         when(platformCredential.getComponentIdentifiers()).thenReturn(
                 modifiedComponentIdentifiers
         );
+
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
@@ -1901,17 +1642,19 @@ public final void testValidatePlatformCredentialAttributesV2p0MissingComponentIn
     @Test
     public final void testValidatePlatformCredentialAttributesV2p0ExtraComponentInDeviceInfo()
             throws IOException {
-        PlatformCredential platformCredential = setupMatchingPlatformCredential(
+        PlatformCredential platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(
                 setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_TXT));
 
         // The device info report will contain one extra component.
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(
                 SAMPLE_PACCOR_OUTPUT_WITH_EXTRA_COMPONENT_TXT);
 
+        List componentInfoList = retrieveListOfComponentInfos();
+
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -1919,7 +1662,7 @@ public final void testValidatePlatformCredentialAttributesV2p0ExtraComponentInDe
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -1931,12 +1674,14 @@ public final void testValidatePlatformCredentialAttributesV2p0ExtraComponentInDe
      *
      * @throws IOException if unable to set up DeviceInfoReport from resource file
      */
-//    @Test
+    @Test
     public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentFieldEmpty()
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
 
-        PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        PlatformCredential platformCredential =
+                setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
+
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
@@ -1955,13 +1700,10 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentF
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
                         Collections.emptyList(), UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
-        assertEquals("Component manufacturer is empty\n"
-                        + "There are unmatched components:\n"
-                        + "Manufacturer=, Model=Core i7, Serial=Not Specified,"
-                        + " Revision=Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz;\n",
+        assertEquals("Component manufacturer is empty\n",
                 result.getMessage());
 
-        platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
         result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
@@ -1992,7 +1734,8 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentF
     public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentNoSerial()
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
-        PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        PlatformCredential platformCredential =
+                setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
 
         ArrayList modifiedIdentifiers = new ArrayList<>();
         for (ComponentIdentifier identifier : platformCredential.getComponentIdentifiers()) {
@@ -2025,7 +1768,10 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentN
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
 
-        PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        PlatformCredential platformCredential =
+                setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
+
+        List componentInfoList = retrieveListOfComponentInfos();
 
         ArrayList modifiedIdentifiers = new ArrayList<>();
         for (ComponentIdentifier identifier : platformCredential.getComponentIdentifiers()) {
@@ -2041,7 +1787,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentN
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
@@ -2059,7 +1805,10 @@ public final void testValPlatCredentialAttributesV2p0RequiredComponentNoSerialOr
             throws IOException {
         DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
 
-        PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
+        PlatformCredential platformCredential =
+                setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport);
+
+        List componentInfoList = retrieveListOfComponentInfos();
 
         ArrayList modifiedIdentifiers = new ArrayList<>();
         for (ComponentIdentifier identifier : platformCredential.getComponentIdentifiers()) {
@@ -2076,12 +1825,398 @@ public final void testValPlatCredentialAttributesV2p0RequiredComponentNoSerialOr
         AppraisalStatus result = CertificateAttributeScvValidator
                 .validatePlatformCredentialAttributesV2p0(platformCredential,
                         deviceInfoReport, componentResultRepository, componentAttributeRepository,
-                        Collections.emptyList(), UUID.randomUUID(), false);
+                        componentInfoList, UUID.randomUUID(), false);
         assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
         assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
                 result.getMessage());
     }
 
+    /**
+     * Create a new X.509 attribute certificate given the holder cert, the signing cert, and the
+     * signing key.
+     *
+     * @param targetCert   X509Certificate that will be the holder of the attribute cert
+     * @param signingCert  X509Certificate used to sign the new attribute cert
+     * @param caPrivateKey PrivateKey used to sign the new attribute cert
+     * @return new X509AttributeCertificate
+     */
+    private X509AttributeCertificateHolder createAttributeCert(
+            final X509Certificate targetCert, final X509Certificate signingCert,
+            final PrivateKey caPrivateKey) {
+        X509AttributeCertificateHolder cert = null;
+        try {
+            final int timeRange = 50000;
+            AttributeCertificateHolder holder =
+                    new AttributeCertificateHolder(new X509CertificateHolder(
+                            targetCert.getEncoded()));
+            AttributeCertificateIssuer issuer =
+                    new AttributeCertificateIssuer(new X500Name(signingCert
+                            .getSubjectX500Principal().getName()));
+            BigInteger serialNumber = BigInteger.ONE;
+            Date notBefore = new Date(System.currentTimeMillis() - timeRange);
+            Date notAfter = new Date(System.currentTimeMillis() + timeRange);
+            X509v2AttributeCertificateBuilder builder =
+                    new X509v2AttributeCertificateBuilder(holder, issuer, serialNumber, notBefore,
+                            notAfter);
+
+            ContentSigner signer =
+                    new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC")
+                            .build(caPrivateKey);
+
+            cert = builder.build(signer);
+        } catch (CertificateEncodingException | IOException | OperatorCreationException e) {
+            fail("Exception occurred while creating a cert", e);
+        }
+
+        return cert;
+
+    }
+
+    /**
+     * Create a new X.509 public-key certificate signed by the given certificate.
+     *
+     * @param keyPair     KeyPair to create the cert for
+     * @param signingKey  PrivateKey of the signing cert
+     * @param signingCert signing cert
+     * @return new X509Certificate
+     */
+    private X509Certificate createCertSignedByAnotherCert(final KeyPair keyPair,
+                                                          final PrivateKey signingKey,
+                                                          final X509Certificate signingCert) {
+        final int timeRange = 10000;
+        X509Certificate cert = null;
+        try {
+
+            X500Name issuerName = new X500Name(signingCert.getSubjectX500Principal().getName());
+            X500Name subjectName = new X500Name("CN=Test V3 Certificate");
+            BigInteger serialNumber = BigInteger.ONE;
+            Date notBefore = new Date(System.currentTimeMillis() - timeRange);
+            Date notAfter = new Date(System.currentTimeMillis() + timeRange);
+            X509v3CertificateBuilder builder =
+                    new JcaX509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter,
+                            subjectName, keyPair.getPublic());
+            ContentSigner signer =
+                    new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC").build(signingKey);
+            return new JcaX509CertificateConverter().setProvider("BC").getCertificate(
+                    builder.build(signer));
+        } catch (Exception e) {
+            fail("Exception occurred while creating a cert", e);
+        }
+        return cert;
+    }
+
+    /**
+     * Creates a self-signed X.509 public-key certificate.
+     *
+     * @param pair KeyPair to create the cert for
+     * @return self-signed X509Certificate
+     */
+    private X509Certificate createSelfSignedCertificate(final KeyPair pair) {
+        Security.addProvider(new BouncyCastleProvider());
+        final int timeRange = 10000;
+        X509Certificate cert = null;
+        try {
+
+            X500Name issuerName = new X500Name("CN=Test Self-Signed V3 Certificate");
+            X500Name subjectName = new X500Name("CN=Test Self-Signed V3 Certificate");
+            BigInteger serialNumber = BigInteger.ONE;
+            Date notBefore = new Date(System.currentTimeMillis() - timeRange);
+            Date notAfter = new Date(System.currentTimeMillis() + timeRange);
+            X509v3CertificateBuilder builder =
+                    new JcaX509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter,
+                            subjectName, pair.getPublic());
+            ContentSigner signer =
+                    new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC").build(
+                            pair.getPrivate());
+            return new JcaX509CertificateConverter().setProvider("BC").getCertificate(
+                    builder.build(signer));
+        } catch (Exception e) {
+            fail("Exception occurred while creating a cert", e);
+        }
+        return cert;
+    }
+
+
+    /**
+     * Creates a new RSA 1024-bit KeyPair using a Bouncy Castle Provider.
+     *
+     * @return new KeyPair
+     */
+    private KeyPair createKeyPair() {
+        final int keySize = 1024;
+        KeyPairGenerator gen;
+        KeyPair keyPair = null;
+        try {
+            gen = KeyPairGenerator.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME);
+            gen.initialize(keySize, SECURE_RANDOM);
+            keyPair = gen.generateKeyPair();
+        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
+            fail("Error occurred while generating key pair", e);
+        }
+        return keyPair;
+    }
+
+    /**
+     * Helper method that creates a device info report.
+     *
+     * @return device info report
+     */
+    private DeviceInfoReport setupDeviceInfoReport() throws UnknownHostException {
+
+        // setup network info
+        final byte[] byteAddress = new byte[] {127, 0, 0, 1};
+        InetAddress inetAddress = InetAddress.getByAddress(byteAddress);
+        NetworkInfo networkInfo = new NetworkInfo("the-device", inetAddress, new byte[] {1, 0, 1, 0, 1, 0});
+
+        // setup os info
+        OSInfo osInfo = new OSInfo("Windows", "11.0", "Not Specified",
+                "Not Specified", "Not Specified");
+
+        // setup firmware info
+        FirmwareInfo firmwareInfo = new FirmwareInfo("Dell Inc", "A11",
+                "03/12/2013");
+
+        // setup hardware info
+        HardwareInfo hardwareInfo = new HardwareInfo(
+                "ACME",
+                "anvil",
+                "3.0",
+                "1234",
+                "567",
+                "890");
+
+        TPMInfo tpmInfo = new TPMInfo();
+
+        return new DeviceInfoReport(networkInfo, osInfo, firmwareInfo, hardwareInfo, tpmInfo);
+    }
+
+    /**
+     * Helper method that creates a device info report that contains the provided components.
+     *
+     * @return device info report that contains provided components
+     * @throws IOException is thrown if issues arise from parsing out the paccor output
+     */
+    private DeviceInfoReport setupDeviceInfoReportWithComponents() throws IOException {
+        return setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_TXT);
+    }
+
+    /**
+     * Helper method that creates a device info report that contains the provided non-specified components.
+     *
+     * @return device info report that contains not specified components
+     * @throws IOException is thrown if issues arise from parsing out the paccor output
+     */
+    private DeviceInfoReport setupDeviceInfoReportWithNotSpecifiedComponents()
+            throws IOException {
+        return setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_NOT_SPECIFIED_TXT);
+    }
+
+    /**
+     * Helper method that generates a device info report using the provided sample paccor output.
+     *
+     * @param paccorOutputResource sample paccor output text
+     * @return device info report
+     * @throws IOException is thrown if issues arise from parsing out the paccor output
+     */
+    private DeviceInfoReport setupDeviceInfoReportWithComponents(
+            final String paccorOutputResource) throws IOException {
+        DeviceInfoReport deviceInfoReport = setupDeviceInfoReport();
+        URL url = SupplyChainCredentialValidator.class.getResource(paccorOutputResource);
+        String paccorOutputString = IOUtils.toString(url, StandardCharsets.UTF_8);
+        deviceInfoReport.setPaccorOutputString(paccorOutputString);
+        return deviceInfoReport;
+    }
+
+    /**
+     * Helper method that generates a collection of component info that can be used
+     * for this class' test methods.
+     *
+     * @return a generic list of component info
+     */
+    private List retrieveListOfComponentInfos() {
+
+        return List.of(
+                new ComponentInfo("the-device", "Dell Inc", "11",
+                        "9ZLUO9", "Not Specified", "020000123",
+                        "2.23.133.18.3.1"),
+                new ComponentInfo("the-device", "9090", "AE12",
+                        "Not Specified", "Not Specified", "00070700",
+                        "2.23.133.18.3.4"),
+                new ComponentInfo("the-device", "Not Specified", "109 NVM",
+                        "1110_1100_2230_0000_8CE3_8E10_0164_9CC7.", "Not Specified",
+                        "00060001", "2.23.133.18.3.5"));
+    }
+
+    /**
+     * Helper method that returns an IP Address.
+     *
+     * @return IP address
+     */
+    private InetAddress getTestIpAddress() {
+        try {
+            final byte[] byteAddress = new byte[] {127, 0, 0, 1};
+            return InetAddress.getByAddress(byteAddress);
+        } catch (UnknownHostException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Helper method that mocks out the Platform Credential object (that uses information derived from
+     * platform configuration V!) used for this class' test methods.
+     *
+     * @param deviceInfoReport device info report
+     * @return mocked out Platform Credential (associated with Platform Configuration V1)
+     * @throws IOException is thrown if there are any issues using the provided device info report's
+     *                     information
+     */
+    private PlatformCredential setupMockPlatformCredentialWithPlatformConfigV1(
+            final DeviceInfoReport deviceInfoReport) throws IOException {
+        PlatformCredential platformCredential = mock(PlatformCredential.class);
+
+        when(platformCredential.getCredentialType()).thenReturn(
+                PlatformCredential.CERTIFICATE_TYPE_2_0);
+
+        when(platformCredential.getManufacturer())
+                .thenReturn(deviceInfoReport.getHardwareInfo().getManufacturer());
+
+        when(platformCredential.getModel())
+                .thenReturn(deviceInfoReport.getHardwareInfo().getProductName());
+
+        when(platformCredential.getPlatformSerial())
+                .thenReturn(deviceInfoReport.getHardwareInfo().getBaseboardSerialNumber());
+
+        when(platformCredential.getVersion())
+                .thenReturn(deviceInfoReport.getHardwareInfo().getVersion());
+
+        when(platformCredential.getSerialNumber()).thenReturn(
+                new BigInteger(deviceInfoReport.getHardwareInfo().getSystemSerialNumber()));
+
+        when(platformCredential.getPlatformConfigurationV1()).thenReturn(new PlatformConfigurationV1());
+
+        List deviceInfoComponents = retrieveListOfComponentInfos();
+
+        List componentIdentifierList = new ArrayList<>();
+        for (ComponentInfo deviceInfoComponent : deviceInfoComponents) {
+            DERUTF8String serial = null;
+            DERUTF8String revision = null;
+            if (deviceInfoComponent.getComponentSerial() != null) {
+                serial = new DERUTF8String(deviceInfoComponent.getComponentSerial());
+            }
+            if (deviceInfoComponent.getComponentRevision() != null) {
+                revision = new DERUTF8String(deviceInfoComponent.getComponentRevision());
+            }
+            componentIdentifierList.add(new ComponentIdentifier(
+                    new DERUTF8String(deviceInfoComponent.getComponentManufacturer()),
+                    new DERUTF8String(deviceInfoComponent.getComponentModel()),
+                    serial,
+                    revision,
+                    null,
+                    ASN1Boolean.TRUE,
+                    Collections.emptyList()
+            ));
+
+        }
+
+        when(platformCredential.getComponentIdentifiers()).thenReturn(componentIdentifierList);
+
+        return platformCredential;
+    }
+
+    /**
+     * Helper method that mocks out the Platform Credential object (that uses information derived from
+     * platform configuration V2) used for this class' test methods.
+     *
+     * @param deviceInfoReport device info report
+     * @return mocked out Platform Credential (associated with Platform Configuration V2)
+     * @throws IOException is thrown if there are any issues using the provided device info report's
+     *                     information
+     */
+    private PlatformCredential setupMockPlatformCredentialWithPlatformConfigV2(
+            final DeviceInfoReport deviceInfoReport) throws IOException {
+
+        PlatformCredential platformCredential = mock(PlatformCredential.class);
+
+        when(platformCredential.getCredentialType()).thenReturn(
+                PlatformCredential.CERTIFICATE_TYPE_2_0);
+
+        when(platformCredential.getManufacturer())
+                .thenReturn(deviceInfoReport.getHardwareInfo().getManufacturer());
+
+        when(platformCredential.getModel())
+                .thenReturn(deviceInfoReport.getHardwareInfo().getProductName());
+
+        when(platformCredential.getPlatformSerial())
+                .thenReturn(deviceInfoReport.getHardwareInfo().getBaseboardSerialNumber());
+
+        when(platformCredential.getVersion())
+                .thenReturn(deviceInfoReport.getHardwareInfo().getVersion());
+
+        when(platformCredential.getSerialNumber()).thenReturn(
+                new BigInteger(deviceInfoReport.getHardwareInfo().getSystemSerialNumber()));
+
+        when(platformCredential.getPlatformConfigurationV2()).thenReturn(new PlatformConfigurationV2());
+
+        List deviceInfoComponents
+                = retrieveListOfComponentInfos();
+
+        List componentIdentifierV2List = new ArrayList<>();
+
+        for (ComponentInfo deviceInfoComponent : deviceInfoComponents) {
+            DERUTF8String componentSerial = null;
+            DERUTF8String componentRevision = null;
+
+            ComponentClass componentClass =
+                    new ComponentClass(deviceInfoComponent.getComponentClassValue(), "");
+
+            if (deviceInfoComponent.getComponentSerial() != null) {
+                componentSerial = new DERUTF8String(deviceInfoComponent.getComponentSerial());
+            }
+
+            if (deviceInfoComponent.getComponentRevision() != null) {
+                componentRevision = new DERUTF8String(deviceInfoComponent.getComponentRevision());
+            }
+
+            componentIdentifierV2List.add(new ComponentIdentifierV2(
+                    componentClass,
+                    new DERUTF8String(deviceInfoComponent.getComponentManufacturer()),
+                    new DERUTF8String(deviceInfoComponent.getComponentModel()),
+                    componentSerial,
+                    componentRevision,
+                    null,
+                    ASN1Boolean.TRUE,
+                    Collections.emptyList(),
+                    new CertificateIdentifier(),
+                    new URIReference(),
+                    AttributeStatus.ADDED
+            ));
+
+        }
+
+        when(platformCredential.getComponentIdentifiersV2()).thenReturn(componentIdentifierV2List);
+
+        return platformCredential;
+    }
+
+    /**
+     * Helper method that uses the provided hardware info to create a device info report.
+     *
+     * @param givenHardwareInfo hardware info
+     * @return device info report
+     */
+    private DeviceInfoReport buildDeviceInfoReportUsingHardwareInfo(final HardwareInfo givenHardwareInfo) {
+        final InetAddress ipAddress = getTestIpAddress();
+        final byte[] macAddress = new byte[] {11, 22, 33, 44, 55, 66};
+
+        OSInfo osInfo = new OSInfo();
+        NetworkInfo networkInfo = new NetworkInfo("test", ipAddress, macAddress);
+        FirmwareInfo firmwareInfo = new FirmwareInfo();
+        TPMInfo tpmInfo = new TPMInfo();
+
+        return new DeviceInfoReport(networkInfo, osInfo,
+                firmwareInfo, givenHardwareInfo, tpmInfo);
+    }
+
     /**
      * Tests that SupplyChainCredentialValidator passes with a base and delta certificate where
      * the base serial number and delta holder serial number match.
@@ -2333,16 +2468,5 @@ public final void testValidateChainFailure()
 //                result.getMessage());
     }
 
-    private DeviceInfoReport buildReport(final HardwareInfo givenHardwareInfo) {
-        final InetAddress ipAddress = getTestIpAddress();
-        final byte[] macAddress = new byte[] {11, 22, 33, 44, 55, 66};
 
-        OSInfo osInfo = new OSInfo();
-        NetworkInfo networkInfo = new NetworkInfo("test", ipAddress, macAddress);
-        FirmwareInfo firmwareInfo = new FirmwareInfo();
-        TPMInfo tpmInfo = new TPMInfo();
-
-        return new DeviceInfoReport(networkInfo, osInfo,
-                firmwareInfo, givenHardwareInfo, tpmInfo);
-    }
 }

From 6b38fa8ee556d9b2fc327f76911e778de7569cbf Mon Sep 17 00:00:00 2001
From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Fri, 14 Feb 2025 14:48:23 -0500
Subject: [PATCH 13/14] issue_896: Last change before the long weekend. Hoping
 these changes will make github actions happy.

---
 .../validation/CertificateAttributeScvValidator.java      | 8 +++-----
 .../validation/SupplyChainCredentialValidatorTest.java    | 4 ++--
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
index ee4c84030..ccd5adf9d 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
@@ -265,12 +265,10 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0(
             List allV2PcComponents
                     = new ArrayList<>(platformCredential.getComponentIdentifiersV2());
 
-            if (componentInfos == null) {
-                log.error("The device's reported list of components is null.");
-                passesValidation = false;
-            } else if (componentInfos.size() != allV2PcComponents.size()) {
+            if (componentInfos.size() != allV2PcComponents.size()) {
                 log.error(
-                        "The device's reported list of components' sizes (size of {}) do not match the size (size of {}) "
+                        "The device's reported list of components' sizes (size of {}) " +
+                                "do not match the size (size of {}) "
                                 + "of the platform credential's version 2 component identifiers.",
                         componentInfos.size(), allV2PcComponents.size());
 
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
index d749ea2a7..83feb0306 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java
@@ -1306,8 +1306,8 @@ public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSys
     }
 
     /**
-     * Second test that tests that TPM 2.0 Platform Credentials validate correctly against the device info report
-     * when there are components present, and when the PlatformSerial field holds the system's
+     * Second test that tests that TPM 2.0 Platform Credentials validate correctly against the device info
+     * report when there are components present, and when the PlatformSerial field holds the system's
      * serial number instead of the baseboard serial number.
      *
      * @throws IOException        if unable to set up DeviceInfoReport from resource file

From 5904c8be5b8ed6bbd960d48ed70d3397b4993742 Mon Sep 17 00:00:00 2001
From: TheSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Thu, 20 Feb 2025 13:11:46 -0500
Subject: [PATCH 14/14] issue_896: Verifying that this part works. We will need
 to figure out a smart/efficient way of comparing the components from platform
 cert and device info report.

---
 .../CertificateAttributeScvValidator.java     | 101 +++++++++++++-----
 1 file changed, 76 insertions(+), 25 deletions(-)

diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
index ccd5adf9d..88d179220 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
@@ -6,6 +6,7 @@
 import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult;
 import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
 import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentAttributeResult;
+import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentClass;
 import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
 import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.AttributeStatus;
 import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
@@ -265,47 +266,97 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0(
             List allV2PcComponents
                     = new ArrayList<>(platformCredential.getComponentIdentifiersV2());
 
-            if (componentInfos.size() != allV2PcComponents.size()) {
-                log.error(
-                        "The device's reported list of components' sizes (size of {}) " +
-                                "do not match the size (size of {}) "
-                                + "of the platform credential's version 2 component identifiers.",
-                        componentInfos.size(), allV2PcComponents.size());
 
-                passesValidation = false;
-            } else {
-                // All V2 components listed in the Platform Credential must have a manufacturer and model
-                for (ComponentIdentifierV2 pcComponent : allV2PcComponents) {
-                    fieldValidation = !isRequiredASN1StringFieldBlank("componentManufacturer",
-                            pcComponent.getComponentManufacturer());
+            // All V2 components listed in the Platform Credential must have a manufacturer and model
+            for (ComponentIdentifierV2 pcComponent : allV2PcComponents) {
+                fieldValidation = !isRequiredASN1StringFieldBlank("componentManufacturer",
+                        pcComponent.getComponentManufacturer());
+
+                if (!fieldValidation) {
+                    resultMessage.append("Component manufacturer is empty\n");
+                }
+
+                passesValidation &= fieldValidation;
+
+                fieldValidation = !isRequiredASN1StringFieldBlank("componentModel",
+                        pcComponent.getComponentModel());
+
+                if (!fieldValidation) {
+                    resultMessage.append("Component model is empty\n");
+                }
+
+                passesValidation &= fieldValidation;
+
+                if (pcComponent.getComponentClass() == null) {
+                    passesValidation = false;
+                } else {
+                    ComponentClass pcComponentClass = pcComponent.getComponentClass();
+
+                    // Component Class Registry Type field
+
+                    fieldValidation = !isRequiredStringFieldBlank("registryType",
+                            pcComponentClass.getRegistryType());
 
                     if (!fieldValidation) {
-                        resultMessage.append("Component manufacturer is empty\n");
+                        resultMessage.append("Component class registry type is empty or null\n");
                     }
 
                     passesValidation &= fieldValidation;
 
-                    fieldValidation = !isRequiredASN1StringFieldBlank("componentModel",
-                            pcComponent.getComponentModel());
+                    // Component Class Component Identifier field
+
+                    fieldValidation = !isRequiredStringFieldBlank("componentIdentifier",
+                            pcComponentClass.getComponentIdentifier());
 
                     if (!fieldValidation) {
-                        resultMessage.append("Component model is empty\n");
+                        resultMessage.append("Component class component identifier is empty or null\n");
                     }
 
                     passesValidation &= fieldValidation;
 
-                    if (pcComponent.getComponentClass() == null) {
-                        passesValidation = false;
-                    } else {
-                        fieldValidation = !isRequiredStringFieldBlank("componentClassRegistry",
-                                pcComponent.getComponentClass().getRegistryType());
+                    // Component Class category field
 
-                        if (!fieldValidation) {
-                            resultMessage.append("Component class registry is empty\n");
-                        }
+                    fieldValidation = !isRequiredStringFieldBlank("category",
+                            pcComponentClass.getCategory());
 
-                        passesValidation &= fieldValidation;
+                    if (!fieldValidation) {
+                        resultMessage.append("Component class category is empty or null\n");
+                    }
+
+                    passesValidation &= fieldValidation;
+
+                    // Component Class Category String field
+
+                    fieldValidation = !isRequiredStringFieldBlank("categoryStr",
+                            pcComponentClass.getCategoryStr());
+
+                    if (!fieldValidation) {
+                        resultMessage.append("Component class category string is empty or null\n");
+                    }
+
+                    passesValidation &= fieldValidation;
+
+                    // Component Class Component String field
+
+                    fieldValidation = !isRequiredStringFieldBlank("componentStr",
+                            pcComponentClass.getComponentStr());
+
+                    if (!fieldValidation) {
+                        resultMessage.append("Component class string is empty or null\n");
+                    }
+
+                    passesValidation &= fieldValidation;
+
+                    // Component Class Component field
+
+                    fieldValidation = !isRequiredStringFieldBlank("component",
+                            pcComponentClass.getComponent());
+
+                    if (!fieldValidation) {
+                        resultMessage.append("Component class component is empty or null\n");
                     }
+
+                    passesValidation &= fieldValidation;
                 }
             }
         }