From 763dcbd975c96669bdbbe7d4cef77af830a80e99 Mon Sep 17 00:00:00 2001
From: Cyrus <24922493+cyrus-dev@users.noreply.github.com>
Date: Thu, 4 Mar 2021 08:01:18 -0500
Subject: [PATCH] These are changes that were made in the system-tests-test
 that resolved the issues in the first TPM 2.0 system tests on travis.

---
 ...stractAttestationCertificateAuthority.java | 14 ++++--
 .../SupplyChainValidationServiceImpl.java     | 16 +++----
 .../util/CertificateStringMapBuilder.java     |  2 +-
 .../SupplyChainCredentialValidator.java       | 46 ++++++++++++++++---
 4 files changed, 58 insertions(+), 20 deletions(-)

diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java
index 3652ee32..2411a604 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java
@@ -455,6 +455,15 @@ public abstract class AbstractAttestationCertificateAuthority
         // Parse and save device info
         Device device = processDeviceInfo(claim);
 
+        // 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
+        // additional information from the DB if information exists
+        if (platformCredentials.size() == 1) {
+            String serial = platformCredentials.iterator().next().getPlatformSerial();
+            platformCredentials.addAll(PlatformCredential.select(this.certificateManager)
+                    .byBoardSerialNumber(serial).getCertificates());
+        }
         // perform supply chain validation
         SupplyChainValidationSummary summary = supplyChainValidationService.validateSupplyChain(
                 endorsementCredential, platformCredentials, device);
@@ -1278,9 +1287,8 @@ public abstract class AbstractAttestationCertificateAuthority
             ContentSigner signer = new JcaContentSignerBuilder("SHA1WithRSA")
                 .setProvider("BC").build(privateKey);
             X509CertificateHolder holder = builder.build(signer);
-            X509Certificate certificate = new JcaX509CertificateConverter()
-                .setProvider("BC").getCertificate(holder);
-            return certificate;
+            return new JcaX509CertificateConverter()
+                    .setProvider("BC").getCertificate(holder);
         } catch (IOException | OperatorCreationException | CertificateException e) {
             throw new CertificateProcessingException("Encountered error while generating "
                     + "identity credential: " + e.getMessage(), e);
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java
index 29c6233c..ed5d3698 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java
@@ -231,15 +231,13 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
                     Iterator<PlatformCredential> it = pcs.iterator();
                     while (it.hasNext()) {
                         PlatformCredential pc = it.next();
-                        if (pc != null) {
-                            if (!pc.isBase()) {
-                                attributeScv = validateDeltaPlatformCredentialAttributes(
-                                        pc, device.getDeviceInfo(),
-                                        baseCredential, deltaMapping);
-                                if (attributeScv.getResult() == FAIL) {
-                                    attrErrorMessage = String.format("%s%s%n", attrErrorMessage,
-                                            attributeScv.getMessage());
-                                }
+                        if (pc != null && pc.isBase()) {
+                            attributeScv = validateDeltaPlatformCredentialAttributes(
+                                    pc, device.getDeviceInfo(),
+                                    baseCredential, deltaMapping);
+                            if (attributeScv.getResult() == FAIL) {
+                                attrErrorMessage = String.format("%s%s%n", attrErrorMessage,
+                                        attributeScv.getMessage());
                             }
                         }
                     }
diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/util/CertificateStringMapBuilder.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/util/CertificateStringMapBuilder.java
index 17908de8..ebdee349 100644
--- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/util/CertificateStringMapBuilder.java
+++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/util/CertificateStringMapBuilder.java
@@ -436,7 +436,7 @@ public final class CertificateStringMapBuilder {
         String data = str.trim().substring(str.trim().indexOf('{') + 1,
                 str.trim().length() - 1);
         // Separate key and value and parse the key
-        for (String pair: data.split(",")) {
+        for (String pair : data.split(",")) {
             String[] keyValue = pair.split("=");
             // Remove white space and change first character in the key to uppercase
             keyValue[0] = Character.toUpperCase(
diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java
index 9c988056..f045002d 100644
--- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java
+++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonFactory;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import hirs.data.persist.AppraisalStatus;
+import hirs.data.persist.certificate.attributes.ComponentClass;
 import hirs.data.persist.info.ComponentInfo;
 import hirs.data.persist.DeviceInfoReport;
 import hirs.data.persist.info.HardwareInfo;
@@ -721,10 +722,39 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
             // will link to the platform certificate that'll display them.
             String failureResults = unmatchedComponents.substring(0,
                     unmatchedComponents.length() - 1);
-            String size = unmatchedComponents.substring(unmatchedComponents.length() - 1);
+            int size = 0;
             resultMessage = new StringBuilder();
-            resultMessage.append(String.format("There are %s unmatched components",
-                    size));
+            // UPDATED: need to account for device info still having components
+            String[] componentSplit = unmatchedComponents.split("\\?");
+
+            if (componentSplit[1].indexOf('=') < (componentSplit[1].length() - 1)) {
+                String subCertComps = componentSplit[1].split("=")[1];
+                if (subCertComps.isEmpty()) {
+                    size = subCertComps.split(";").length;
+                }
+            }
+
+            if (size == 0) {
+                // the platform certificate components have been accounted for
+                // therefore there are additional components in the device info report
+                // not accounted for
+                String subDeviceComps = componentSplit[0].split("=")[1];
+                if (subDeviceComps != null && !subDeviceComps.isEmpty()) {
+                    size = subDeviceComps.split(";").length;
+                    resultMessage.append(String.format("The device is reporting %d"
+                            + " unmatched components:", size));
+                    for (String comp : subDeviceComps.split(";")) {
+                        resultMessage.append(String.format("%n%s", comp));
+                    }
+                } else {
+                    // we can assume this is ever true
+                    LOGGER.warn("Validation failed comparing components.  However there was"
+                            + "no print out of the failed components.");
+                }
+            } else {
+                resultMessage.append(String.format("There are %d unmatched components "
+                                + "on the Platform Certificate.", size));
+            }
             return new AppraisalStatus(FAIL, resultMessage.toString(), failureResults);
         }
         return new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID);
@@ -770,14 +800,16 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
         }
 
         if (!subCompInfoList.isEmpty()) {
+            ComponentClass cc;
             for (ComponentInfo ci : subCompInfoList) {
-                invalidDeviceInfo.append(String.format("%d;",
-                        ci.hashCode()));
+                cc = new ComponentClass(ci.getComponentClass());
+                invalidDeviceInfo.append(String.format("%s;",
+                        cc.toString()));
             }
         }
 
-        return String.format("DEVICEINFO=%s?COMPID=%s%d",
-                invalidDeviceInfo.toString(), invalidPcIds.toString(), subCompIdList.size());
+        return String.format("DEVICEINFO=%s?COMPID=%s",
+                invalidDeviceInfo.toString(), invalidPcIds.toString());
     }
 
     /**