From fbdcf83840d89f45c1857a2e05c67b27c18b65a4 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Mon, 23 Nov 2020 14:46:29 -0500 Subject: [PATCH 01/41] Continued refactoring to update the failed components part of the attribute validation. The delta mapping needs to be reworked to not use serials. --- .../SupplyChainValidationServiceImpl.java | 52 +++---- .../CertificateRequestPageController.java | 11 -- .../util/CertificateStringMapBuilder.java | 6 +- .../hirs/data/persist/AppraisalStatus.java | 31 ++++ .../attributes/ComponentClass.java | 10 ++ .../hirs/data/persist/info/ComponentInfo.java | 76 ++++++++-- .../SupplyChainCredentialValidator.java | 135 ++++++++++++++++-- 7 files changed, 253 insertions(+), 68 deletions(-) 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 02ca8693..b4060661 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -132,7 +132,6 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe supplyChainAppraiser); boolean acceptExpiredCerts = policy.isExpiredCertificateValidationEnabled(); PlatformCredential baseCredential = null; - String componentFailures = ""; List validations = new LinkedList<>(); Map deltaMapping = new HashMap<>(); SupplyChainValidation platformScv = null; @@ -199,15 +198,22 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe Iterator it = pcs.iterator(); while (it.hasNext()) { PlatformCredential pc = it.next(); - SupplyChainValidation attributeScv; + SupplyChainValidation attributeScv = null; if (pc != null) { if (pc.isDeltaChain()) { - // this check validates the delta changes and recompares + // this check validates the delta changes and re-compares // the modified list to the original. - attributeScv = validateDeltaPlatformCredentialAttributes( - pc, device.getDeviceInfo(), - baseCredential, deltaMapping); + try { + attributeScv = validateDeltaPlatformCredentialAttributes( + pc, device.getDeviceInfo(), + baseCredential, deltaMapping); + } catch (Exception ex) { + for (StackTraceElement element : ex.getStackTrace()) { + LOGGER.error(element.toString()); + } + LOGGER.error(ex.getMessage()); + } } else { attributeScv = validatePlatformCredentialAttributes( pc, device.getDeviceInfo(), ec); @@ -239,8 +245,6 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe String.format("%s%n%s", platformScv.getMessage(), attributeScv.getMessage()))); } - componentFailures = updateUnmatchedComponents( - attributeScv.getMessage()); } pc.setDevice(device); @@ -259,10 +263,6 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe // Generate validation summary, save it, and return it. SupplyChainValidationSummary summary = new SupplyChainValidationSummary(device, validations); - if (baseCredential != null) { - baseCredential.setComponentFailures(componentFailures); - this.certificateManager.update(baseCredential); - } try { supplyChainValidatorSummaryManager.save(summary); } catch (DBManagerException ex) { @@ -272,29 +272,6 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe return summary; } - private String updateUnmatchedComponents(final String unmatchedString) { - StringBuilder updatedFailures = new StringBuilder(); - String manufacturer = ""; - String model = ""; - for (String rows : unmatchedString.split(";")) { - for (String str : rows.split(",")) { - String[] manufacturerSplit; - String[] modelSplit; - if (str.contains("Manufacturer")) { - manufacturerSplit = str.split("="); - manufacturer = manufacturerSplit[VALUE_INDEX]; - } - if (str.contains("Model")) { - modelSplit = str.split("="); - model = modelSplit[VALUE_INDEX]; - } - } - updatedFailures.append(String.format("%s%s;", manufacturer, model)); - } - - return updatedFailures.toString(); - } - /** * This method is a sub set of the validate supply chain method and focuses * on the specific multibase validation check for a delta chain. This method @@ -724,6 +701,11 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe return buildValidationRecord(validationType, PASS, result.getMessage(), delta, Level.INFO); case FAIL: + if (!result.getAdditionalInfo().isEmpty()) { + LOGGER.error(result.getAdditionalInfo()); + base.setComponentFailures(result.getAdditionalInfo()); + this.certificateManager.update(base); + } return buildValidationRecord(validationType, AppraisalStatus.Status.FAIL, result.getMessage(), delta, Level.WARN); case ERROR: diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificateRequestPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificateRequestPageController.java index 9f3b4f08..80f428e8 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificateRequestPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificateRequestPageController.java @@ -153,17 +153,6 @@ public class CertificateRequestPageController extends PageController getV2PaccorOutput( + final String paccorOutput) throws IOException { + List ciList = new LinkedList<>(); + String manufacturer, model, serial, revision; + String componentClass = Strings.EMPTY; + + if (StringUtils.isNotEmpty(paccorOutput)) { + ObjectMapper objectMapper = new ObjectMapper(new JsonFactory()); + JsonNode rootNode = objectMapper.readTree(paccorOutput); + Iterator jsonComponentNodes + = rootNode.findValue("COMPONENTS").elements(); + while (jsonComponentNodes.hasNext()) { + JsonNode next = jsonComponentNodes.next(); + manufacturer = getJSONNodeValueAsText(next, "MANUFACTURER"); + model = getJSONNodeValueAsText(next, "MODEL"); + serial = getJSONNodeValueAsText(next, "SERIAL"); + revision = getJSONNodeValueAsText(next, "REVISION"); + List compClassNodes = next.findValues("COMPONENTCLASS"); + + for (JsonNode subNode : compClassNodes) { + componentClass = getJSONNodeValueAsText(subNode, + "COMPONENTCLASSVALUE"); + } + ciList.add(new ComponentInfo(manufacturer, model, + serial, revision, componentClass)); + } + } + + return ciList; + } + private static String getJSONNodeValueAsText(final JsonNode node, final String fieldName) { if (node.hasNonNull(fieldName)) { return node.findValue(fieldName).asText(); @@ -555,6 +592,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator * base cert for this specific chain * @return Appraisal Status of delta being validated. */ + @SuppressWarnings("methodlength") static AppraisalStatus validateDeltaAttributesChainV2p0( final DeviceInfoReport deviceInfoReport, final Map deltaMapping, @@ -602,7 +640,10 @@ public final class SupplyChainCredentialValidator implements CredentialValidator StringBuilder failureMsg = new StringBuilder(); certificateList = new ArrayList<>(); certificateList.add(delta); - + /** + * This chainnn maipping may have to change because + * the serial number isn't required + */ for (ComponentIdentifier ci : delta.getComponentIdentifiers()) { if (ci.isVersion2()) { ciSerial = ci.getComponentSerial().toString(); @@ -681,10 +722,18 @@ public final class SupplyChainCredentialValidator implements CredentialValidator String paccorOutputString = deviceInfoReport.getPaccorOutputString(); String unmatchedComponents; try { - List componentInfoList - = getComponentInfoFromPaccorOutput(paccorOutputString); - unmatchedComponents = validateV2p0PlatformCredentialComponentsExpectingExactMatch( - new LinkedList<>(chainCiMapping.values()), componentInfoList); +// List componentInfoList +// = getComponentInfoFromPaccorOutput(paccorOutputString); + // compare based on component class + List componentInfoList = getV2PaccorOutput(paccorOutputString); +// testComponentMatching(compMapping, chainCiMapping.values()); + // this is what I want to rewrite +// unmatchedComponents = validateV2p0PlatformCredentialComponentsExpectingExactMatch( +// new LinkedList<>(chainCiMapping.values()), +// compMapping.keySet().stream().collect(Collectors.toList())); + unmatchedComponents = validateV2PlatformCredentialAttributes( + new LinkedList<>(chainCiMapping.values()), + componentInfoList); fieldValidation &= unmatchedComponents.isEmpty(); } catch (IOException e) { final String baseErrorMessage = "Error parsing JSON output from PACCOR: "; @@ -692,16 +741,82 @@ public final class SupplyChainCredentialValidator implements CredentialValidator LOGGER.error("PACCOR output string:\n" + paccorOutputString); return new AppraisalStatus(ERROR, baseErrorMessage + e.getMessage()); } - if (!fieldValidation) { + // instead of listing all unmatched, just print the #. The failure + // will link to the platform certificate that'll display them. + LOGGER.error(unmatchedComponents); + String failureResults = unmatchedComponents.substring(0, + unmatchedComponents.length() - 1); + String size = unmatchedComponents.substring(unmatchedComponents.length() - 1); resultMessage = new StringBuilder(); - resultMessage.append("There are unmatched components:\n"); - resultMessage.append(unmatchedComponents); + resultMessage.append(String.format("There are %s unmatched components", + size)); + return new AppraisalStatus(FAIL, resultMessage.toString(), failureResults); + } + return new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID); + } - return new AppraisalStatus(FAIL, resultMessage.toString()); + private static String validateV2PlatformCredentialAttributes( + final List fullDeltaChainComponents, + final List allDeviceInfoComponents) { + ComponentIdentifierV2 ciV2; + StringBuilder invalidDeviceInfo = new StringBuilder(); + StringBuilder invalidPcIds = new StringBuilder(); + List subCompIdList = fullDeltaChainComponents + .stream().collect(Collectors.toList()); + List subCompInfoList = allDeviceInfoComponents + .stream().collect(Collectors.toList()); + LOGGER.error(String.format("fullDeltaChainComponents - %d", fullDeltaChainComponents.size())); + LOGGER.error(String.format("subCompIdList - %d", subCompIdList.size())); + LOGGER.error(String.format("allDeviceInfoComponents - %d", allDeviceInfoComponents.size())); + LOGGER.error(String.format("subCompInfoList - %d", subCompInfoList.size())); + // Delta is the baseline + for (ComponentInfo cInfo : allDeviceInfoComponents) { + for (ComponentIdentifier cId : fullDeltaChainComponents) { + ciV2 = (ComponentIdentifierV2) cId; + if (cInfo.getComponentClass().equals( + ciV2.getComponentClass().getClassValueString())) { + LOGGER.error(String.format("Testing %s -> %s%n%n", cInfo, ciV2)); + if (!isMatch(cId, cInfo)) { + invalidDeviceInfo.append(String.format("%s:%s;", + cInfo.getComponentClass(), cInfo.toString())); + invalidPcIds.append(String.format("%s:%s;", + ciV2.getComponentClass().getClassValueString(), + ciV2.toString())); + } else { + LOGGER.error("TDM - Removed items"); + subCompIdList.remove(cId); + subCompInfoList.remove(cInfo); + } + } + } } - return new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID); + if (subCompIdList.isEmpty() && subCompInfoList.isEmpty()) { + return Strings.EMPTY; + } + + // now we return everything that was unmatched + // what is in the component info/device reported components + // is to be displayed as the failure + if (!subCompIdList.isEmpty()) { + for (ComponentIdentifier ci : subCompIdList) { + ciV2 = (ComponentIdentifierV2) ci; + invalidPcIds.append(String.format("%s:%s;", + ciV2.getComponentClass().getClassValueString(), + ciV2.getComponentModel())); + } + } + + if (!subCompInfoList.isEmpty()) { + for (ComponentInfo ci : subCompInfoList) { + invalidDeviceInfo.append(String.format("%s:%s;", + ci.getComponentClass(), ci.getComponentModel())); + } + } + + return String.format("DEVICEINFO=%s?COMPID=%s%d", + invalidDeviceInfo.toString(), invalidPcIds.toString(), subCompInfoList.size()); } /** From ffbcebbf117c8c2da2beb8f86a952dfa9d505a4e Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Tue, 24 Nov 2020 09:12:00 -0500 Subject: [PATCH 02/41] Found the issue with the isMatch class not working. The component class string for the class value has a pound sign. --- .../SupplyChainCredentialValidator.java | 136 ++++++++++++++---- 1 file changed, 106 insertions(+), 30 deletions(-) diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 423e0eb1..305b2666 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -606,12 +606,12 @@ public final class SupplyChainCredentialValidator implements CredentialValidator List chainCertificates = new LinkedList<>(deltaMapping.keySet()); // map the components throughout the chain - Map chainCiMapping = new HashMap<>(); List deltaBuildList = new LinkedList<>(validOrigPcComponents); - deltaBuildList.stream().forEach((ci) -> { - chainCiMapping.put(ci.getComponentSerial().toString(), ci); - }); + List builtMatchList = new LinkedList<>(validOrigPcComponents); + /** + * Make sure the certificates are in the correct order. + */ Collections.sort(chainCertificates, new Comparator() { @Override public int compare(final PlatformCredential obj1, @@ -629,7 +629,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator } }); - String ciSerial; + List modifiedClassValues = new LinkedList<>(); List certificateList = null; SupplyChainValidation scv = null; resultMessage.append("There are errors with Delta " @@ -640,22 +640,39 @@ public final class SupplyChainCredentialValidator implements CredentialValidator StringBuilder failureMsg = new StringBuilder(); certificateList = new ArrayList<>(); certificateList.add(delta); - /** - * This chainnn maipping may have to change because - * the serial number isn't required - */ + String classValue; + ComponentIdentifierV2 ciV2; + boolean classFound = false; + for (ComponentIdentifier ci : delta.getComponentIdentifiers()) { if (ci.isVersion2()) { - ciSerial = ci.getComponentSerial().toString(); - ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) ci; + ciV2 = (ComponentIdentifierV2) ci; + classValue = ciV2.getComponentClass().getClassValueString(); if (ciV2.isModified()) { - // this won't match - // check it is there - if (!chainCiMapping.containsKey(ciSerial)) { + // A component was modified + // if it exists, update + // if doesn't exist, error + for (ComponentIdentifier subCi : deltaBuildList) { + ComponentIdentifierV2 subCiV2 = (ComponentIdentifierV2) subCi; + classFound = classValue.equals(subCiV2.getComponentClass() + .getClassValueString()); + if (classFound && isMatch(ciV2, subCiV2)) { + if (modifiedClassValues.contains(classValue)) { + modifiedClassValues.remove(classValue); + } else { + // we found the class and it is a match + break; + } + } + } + if (classFound) { + modifiedClassValues.add(classValue); + builtMatchList.add(ci); + } else { fieldValidation = false; failureMsg.append(String.format( "%s attempted MODIFIED with no prior instance.%n", - ciSerial)); + classValue)); scv = deltaMapping.get(delta); if (scv.getResult() != AppraisalStatus.Status.PASS) { failureMsg.append(scv.getMessage()); @@ -665,16 +682,27 @@ public final class SupplyChainCredentialValidator implements CredentialValidator AppraisalStatus.Status.FAIL, certificateList, failureMsg.toString())); - } else { - chainCiMapping.put(ciSerial, ci); } } else if (ciV2.isRemoved()) { - if (!chainCiMapping.containsKey(ciSerial)) { + for (ComponentIdentifier subCi : deltaBuildList) { + ComponentIdentifierV2 subCiV2 = (ComponentIdentifierV2) subCi; + classFound = classValue.equals(subCiV2.getComponentClass() + .getClassValueString()); + if (classFound && isMatch(ciV2, subCiV2)) { + break; + } else { + classFound = false; + } + } + + if (classFound) { + builtMatchList.remove(ci); + } else { // error thrown, can't remove if it doesn't exist fieldValidation = false; failureMsg.append(String.format( "%s attempted REMOVED with no prior instance.%n", - ciSerial)); + classValue)); scv = deltaMapping.get(delta); if (scv.getResult() != AppraisalStatus.Status.PASS) { failureMsg.append(scv.getMessage()); @@ -684,17 +712,26 @@ public final class SupplyChainCredentialValidator implements CredentialValidator AppraisalStatus.Status.FAIL, certificateList, failureMsg.toString())); - } else { - chainCiMapping.remove(ciSerial); } } else if (ciV2.isAdded()) { // ADDED - if (chainCiMapping.containsKey(ciSerial)) { + for (ComponentIdentifier subCi : deltaBuildList) { + ComponentIdentifierV2 subCiV2 = (ComponentIdentifierV2) subCi; + classFound = classValue.equals(subCiV2.getComponentClass() + .getClassValueString()); + if (classFound && isMatch(ciV2, subCiV2)) { + break; + } else { + classFound = false; + } + } + + if (classFound) { // error, shouldn't exist fieldValidation = false; failureMsg.append(String.format( "%s was ADDED, the serial already exists.%n", - ciSerial)); + classValue)); scv = deltaMapping.get(delta); if (scv.getResult() != AppraisalStatus.Status.PASS) { failureMsg.append(scv.getMessage()); @@ -705,12 +742,13 @@ public final class SupplyChainCredentialValidator implements CredentialValidator certificateList, failureMsg.toString())); } else { - // have to add in case later it is removed - chainCiMapping.put(ciSerial, ci); + builtMatchList.add(ci); } } } } + // each delta has a change to change or modify what was just modified + modifiedClassValues.clear(); resultMessage.append(failureMsg.toString()); } @@ -732,7 +770,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator // new LinkedList<>(chainCiMapping.values()), // compMapping.keySet().stream().collect(Collectors.toList())); unmatchedComponents = validateV2PlatformCredentialAttributes( - new LinkedList<>(chainCiMapping.values()), + builtMatchList, componentInfoList); fieldValidation &= unmatchedComponents.isEmpty(); } catch (IOException e) { @@ -766,16 +804,24 @@ public final class SupplyChainCredentialValidator implements CredentialValidator .stream().collect(Collectors.toList()); List subCompInfoList = allDeviceInfoComponents .stream().collect(Collectors.toList()); - LOGGER.error(String.format("fullDeltaChainComponents - %d", fullDeltaChainComponents.size())); + LOGGER.error(String.format("fullDeltaChainComponents - %d", + fullDeltaChainComponents.size())); LOGGER.error(String.format("subCompIdList - %d", subCompIdList.size())); - LOGGER.error(String.format("allDeviceInfoComponents - %d", allDeviceInfoComponents.size())); + LOGGER.error(String.format("allDeviceInfoComponents - %d", + allDeviceInfoComponents.size())); LOGGER.error(String.format("subCompInfoList - %d", subCompInfoList.size())); // Delta is the baseline for (ComponentInfo cInfo : allDeviceInfoComponents) { for (ComponentIdentifier cId : fullDeltaChainComponents) { ciV2 = (ComponentIdentifierV2) cId; - if (cInfo.getComponentClass().equals( - ciV2.getComponentClass().getClassValueString())) { + LOGGER.error(String.format("%s -> %s", cInfo.getComponentClass(), + ciV2.getComponentClass().getClassValueString())); + if (ciV2.getComponentClass().getClassValueString() + .contains(cInfo.getComponentClass())) { + // TDM RIGHT HERE, you are getting a # from componentclass + /** + * YOU CAN DO IT. Don't fall asleep -_- + */ LOGGER.error(String.format("Testing %s -> %s%n%n", cInfo, ciV2)); if (!isMatch(cId, cInfo)) { invalidDeviceInfo.append(String.format("%s:%s;", @@ -788,6 +834,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator subCompIdList.remove(cId); subCompInfoList.remove(cInfo); } + } else { + LOGGER.error("Didn't match."); } } } @@ -1113,6 +1161,28 @@ public final class SupplyChainCredentialValidator implements CredentialValidator return matchesSoFar; } + /** + * Checks if the fields in the potentialMatch match the fields in the pcComponent, + * or if the relevant field in the pcComponent is empty. + * @param pcComponent the platform credential component + * @param potentialMatch the component info from a device info report + * @return true if the fields match exactly (null is considered the same as an empty string) + */ + static boolean isMatch(final ComponentIdentifierV2 pcComponent, + final ComponentIdentifierV2 potentialMatch) { + boolean matchesSoFar = true; + + matchesSoFar &= isMatchOrEmptyInPlatformCert( + potentialMatch.getComponentManufacturer(), + pcComponent.getComponentManufacturer()); + + matchesSoFar &= isMatchOrEmptyInPlatformCert( + potentialMatch.getComponentModel(), + pcComponent.getComponentModel()); + + return matchesSoFar; + } + private static boolean isMatchOrEmptyInPlatformCert( final String evidenceFromDevice, final DERUTF8String valueInPlatformCert) { @@ -1122,6 +1192,12 @@ public final class SupplyChainCredentialValidator implements CredentialValidator return valueInPlatformCert.getString().equals(evidenceFromDevice); } + private static boolean isMatchOrEmptyInPlatformCert( + final DERUTF8String evidenceFromDevice, + final DERUTF8String valueInPlatformCert) { + return evidenceFromDevice.equals(valueInPlatformCert); + } + /** * Validates the platform credential's serial numbers with the device info's set of * serial numbers. From 9433c97dc906186bef0ea0b788778d1422fe7d02 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Wed, 25 Nov 2020 08:02:45 -0500 Subject: [PATCH 03/41] The code now uses a combination of the class value and the platform manufacturer and model to identify mismatches. This now highlights the failured components --- ...stractAttestationCertificateAuthority.java | 2 +- .../SupplyChainValidationServiceImpl.java | 1 - .../util/CertificateStringMapBuilder.java | 5 ++- .../WEB-INF/jsp/certificate-details.jsp | 2 +- .../attributes/ComponentClass.java | 6 +++- .../SupplyChainCredentialValidator.java | 33 +++++-------------- 6 files changed, 18 insertions(+), 31 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java index e3051ee0..94602aa2 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java @@ -798,7 +798,7 @@ public abstract class AbstractAttestationCertificateAuthority support.setTagId(tagId); this.referenceManifestManager.save(support); } else { - LOG.error("Client provided Support RIM already loaded in database."); + LOG.info("Client provided Support RIM already loaded in database."); if (dbBaseRim != null) { support.setPlatformManufacturer(dbBaseRim.getPlatformManufacturer()); support.setPlatformModel(dbBaseRim.getPlatformModel()); 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 b4060661..95c26c8b 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -702,7 +702,6 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe result.getMessage(), delta, Level.INFO); case FAIL: if (!result.getAdditionalInfo().isEmpty()) { - LOGGER.error(result.getAdditionalInfo()); base.setComponentFailures(result.getAdditionalInfo()); this.certificateManager.update(base); } 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 60041aca..abba78cd 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 @@ -340,10 +340,9 @@ public final class CertificateStringMapBuilder { //CPSuri data.put("CPSuri", certificate.getCPSuri()); //component failure - if (certificate.getComponentFailures().isEmpty()) { + LOGGER.error(certificate.getComponentFailures()); + if (!certificate.getComponentFailures().isEmpty()) { data.put("failures", certificate.getComponentFailures()); - } else { - LOGGER.error(certificate.getComponentFailures()); } //Get platform Configuration values and set map with it diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/certificate-details.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/certificate-details.jsp index e6158a3b..8240ad33 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/certificate-details.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/certificate-details.jsp @@ -614,7 +614,7 @@
- +
diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentClass.java b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentClass.java index a8997f48..834b82cf 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentClass.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentClass.java @@ -84,7 +84,11 @@ public class ComponentClass { */ public ComponentClass(final Path componentClassPath, final String componentIdentifier) { this(componentClassPath, getComponentIntValue(componentIdentifier)); - this.classValueString = componentIdentifier; + if (componentIdentifier.contains("#")) { + this.classValueString = componentIdentifier.replaceAll("#", ""); + } else { + this.classValueString = componentIdentifier; + } } /** diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 305b2666..0bc16c29 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -782,7 +782,6 @@ public final class SupplyChainCredentialValidator implements CredentialValidator if (!fieldValidation) { // instead of listing all unmatched, just print the #. The failure // will link to the platform certificate that'll display them. - LOGGER.error(unmatchedComponents); String failureResults = unmatchedComponents.substring(0, unmatchedComponents.length() - 1); String size = unmatchedComponents.substring(unmatchedComponents.length() - 1); @@ -804,38 +803,25 @@ public final class SupplyChainCredentialValidator implements CredentialValidator .stream().collect(Collectors.toList()); List subCompInfoList = allDeviceInfoComponents .stream().collect(Collectors.toList()); - LOGGER.error(String.format("fullDeltaChainComponents - %d", - fullDeltaChainComponents.size())); - LOGGER.error(String.format("subCompIdList - %d", subCompIdList.size())); - LOGGER.error(String.format("allDeviceInfoComponents - %d", - allDeviceInfoComponents.size())); - LOGGER.error(String.format("subCompInfoList - %d", subCompInfoList.size())); + // Delta is the baseline for (ComponentInfo cInfo : allDeviceInfoComponents) { for (ComponentIdentifier cId : fullDeltaChainComponents) { ciV2 = (ComponentIdentifierV2) cId; - LOGGER.error(String.format("%s -> %s", cInfo.getComponentClass(), - ciV2.getComponentClass().getClassValueString())); if (ciV2.getComponentClass().getClassValueString() .contains(cInfo.getComponentClass())) { // TDM RIGHT HERE, you are getting a # from componentclass /** * YOU CAN DO IT. Don't fall asleep -_- */ - LOGGER.error(String.format("Testing %s -> %s%n%n", cInfo, ciV2)); - if (!isMatch(cId, cInfo)) { - invalidDeviceInfo.append(String.format("%s:%s;", - cInfo.getComponentClass(), cInfo.toString())); - invalidPcIds.append(String.format("%s:%s;", - ciV2.getComponentClass().getClassValueString(), - ciV2.toString())); - } else { + if (isMatch(cId, cInfo)) { LOGGER.error("TDM - Removed items"); subCompIdList.remove(cId); subCompInfoList.remove(cInfo); + } else { + // FUCK PMD + LOGGER.error("No match"); } - } else { - LOGGER.error("Didn't match."); } } } @@ -850,16 +836,15 @@ public final class SupplyChainCredentialValidator implements CredentialValidator if (!subCompIdList.isEmpty()) { for (ComponentIdentifier ci : subCompIdList) { ciV2 = (ComponentIdentifierV2) ci; - invalidPcIds.append(String.format("%s:%s;", - ciV2.getComponentClass().getClassValueString(), - ciV2.getComponentModel())); + invalidPcIds.append(String.format("%s;", + ciV2.getComponentClass().getClassValueString())); } } if (!subCompInfoList.isEmpty()) { for (ComponentInfo ci : subCompInfoList) { - invalidDeviceInfo.append(String.format("%s:%s;", - ci.getComponentClass(), ci.getComponentModel())); + invalidDeviceInfo.append(String.format("%s;", + ci.getComponentClass())); } } From a32d3a5f02dc7b1cb6d061c257e4f51f16419285 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Tue, 1 Dec 2020 09:46:05 -0500 Subject: [PATCH 04/41] Remove comments --- .../service/SupplyChainValidationServiceImpl.java | 14 +++----------- .../validation/SupplyChainCredentialValidator.java | 8 -------- 2 files changed, 3 insertions(+), 19 deletions(-) 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 95c26c8b..48662096 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -204,21 +204,13 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe if (pc.isDeltaChain()) { // this check validates the delta changes and re-compares // the modified list to the original. - try { - attributeScv = validateDeltaPlatformCredentialAttributes( - pc, device.getDeviceInfo(), - baseCredential, deltaMapping); - } catch (Exception ex) { - for (StackTraceElement element : ex.getStackTrace()) { - LOGGER.error(element.toString()); - } - LOGGER.error(ex.getMessage()); - } + attributeScv = validateDeltaPlatformCredentialAttributes( + pc, device.getDeviceInfo(), + baseCredential, deltaMapping); } else { attributeScv = validatePlatformCredentialAttributes( pc, device.getDeviceInfo(), ec); } - if (platformScv != null) { // have to make sure the attribute validation isn't ignored and // doesn't override general validation status diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 0bc16c29..4ecdbb8f 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -810,17 +810,9 @@ public final class SupplyChainCredentialValidator implements CredentialValidator ciV2 = (ComponentIdentifierV2) cId; if (ciV2.getComponentClass().getClassValueString() .contains(cInfo.getComponentClass())) { - // TDM RIGHT HERE, you are getting a # from componentclass - /** - * YOU CAN DO IT. Don't fall asleep -_- - */ if (isMatch(cId, cInfo)) { - LOGGER.error("TDM - Removed items"); subCompIdList.remove(cId); subCompInfoList.remove(cInfo); - } else { - // FUCK PMD - LOGGER.error("No match"); } } } From 640966ae8cacc13ede754a28bf1adfcf9662b7f2 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Mon, 14 Dec 2020 11:40:04 -0500 Subject: [PATCH 05/41] Removed debug statement --- .../attestationca/portal/util/CertificateStringMapBuilder.java | 2 -- 1 file changed, 2 deletions(-) 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 abba78cd..08b95f7d 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 @@ -339,8 +339,6 @@ public final class CertificateStringMapBuilder { data.put("x509Version", certificate.getX509CredentialVersion()); //CPSuri data.put("CPSuri", certificate.getCPSuri()); - //component failure - LOGGER.error(certificate.getComponentFailures()); if (!certificate.getComponentFailures().isEmpty()) { data.put("failures", certificate.getComponentFailures()); } From 1db52cebf9a9800b8a7665d86ea15e0968641105 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Thu, 17 Dec 2020 07:24:51 -0500 Subject: [PATCH 06/41] This is a stopping point because the code can't be fully worked out because the data (certificates) aren't correct. --- ...stractAttestationCertificateAuthority.java | 13 +- .../SupplyChainValidationServiceImpl.java | 154 ++++++++++++++---- .../hirs/data/persist/AppraisalStatus.java | 3 +- .../attributes/V2/ComponentIdentifierV2.java | 8 + .../SupplyChainCredentialValidator.java | 21 ++- 5 files changed, 155 insertions(+), 44 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java index eb178210..9566ff9b 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java @@ -90,7 +90,9 @@ import java.security.spec.RSAPublicKeySpec; import java.util.Arrays; import java.util.Calendar; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -101,7 +103,6 @@ import java.util.regex.Pattern; */ public abstract class AbstractAttestationCertificateAuthority implements AttestationCertificateAuthority { - /** * Logger instance for for subclass instances. */ @@ -122,7 +123,6 @@ public abstract class AbstractAttestationCertificateAuthority * Number of bytes to include in the TPM2.0 nonce. */ public static final int NONCE_LENGTH = 20; - private static final int SEED_LENGTH = 32; private static final int MAX_SECRET_LENGTH = 32; private static final int RSA_MODULUS_LENGTH = 256; @@ -130,13 +130,11 @@ public abstract class AbstractAttestationCertificateAuthority private static final int HMAC_KEY_LENGTH_BYTES = 32; private static final int HMAC_SIZE_LENGTH_BYTES = 2; private static final int TPM2_CREDENTIAL_BLOB_SIZE = 392; - // Constants used to parse out the ak name from the ak public data. Used in generateAkName private static final String AK_NAME_PREFIX = "000b"; private static final String AK_NAME_HASH_PREFIX = "0001000b00050072000000100014000b0800000000000100"; private static final String TPM_SIGNATURE_ALG = "sha"; - private static final int MAC_BYTES = 6; /** @@ -165,7 +163,6 @@ public abstract class AbstractAttestationCertificateAuthority * certificates issued by this ACA are valid for. */ private final Integer validDays; - private final CertificateManager certificateManager; private final ReferenceManifestManager referenceManifestManager; private final DeviceRegister deviceRegister; @@ -456,6 +453,12 @@ public abstract class AbstractAttestationCertificateAuthority // attempt to find platform credentials to validate Set platformCredentials = parsePcsFromIdentityClaim(claim, endorsementCredential); + Map correctedMap = new HashMap<>(); + for (PlatformCredential pc : platformCredentials) { + correctedMap.put(pc.getSerialNumber(), pc); + } + platformCredentials.clear(); + platformCredentials.addAll(correctedMap.values()); // Parse and save device info Device device = processDeviceInfo(claim); 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 8aa5cf2b..0883a239 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -135,6 +135,12 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe List validations = new LinkedList<>(); Map deltaMapping = new HashMap<>(); SupplyChainValidation platformScv = null; + SupplyChainValidation.ValidationType platformType = SupplyChainValidation + .ValidationType.PLATFORM_CREDENTIAL; + SupplyChainValidation.ValidationType platformAttrType = SupplyChainValidation + .ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES; + Map validationTypeMap + = new HashMap<>(); LOGGER.info("Validating supply chain."); // Validate the Endorsement Credential @@ -153,7 +159,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe if (pcs == null || pcs.isEmpty()) { LOGGER.error("There were no Platform Credentials to validate."); validations.add(buildValidationRecord( - SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + platformType, AppraisalStatus.Status.FAIL, "Platform credential(s) missing", null, Level.ERROR)); } else { @@ -170,16 +176,63 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe platformScv = validatePcPolicy(pc, platformScv, deltaMapping, acceptExpiredCerts); - validations.add(platformScv); - validations.addAll(deltaMapping.values()); + /** + * Alright, this should work but because the test material is bad + * I can't finish it. Currently the delta certificate has the same + * serial number as the base, the same validity and so on. I will + * attempt to generate my own but for right now, I'm going to move + * on to something else. + */ + if (validationTypeMap.containsKey( + platformType)) { + SupplyChainValidation tmpScv = validationTypeMap.get(platformType); + if (tmpScv.getResult() == PASS && platformScv.getResult() == FAIL) { + validationTypeMap.put(platformType, platformScv); + } + } else { + validationTypeMap.put(platformType, platformScv); + } if (pc.isBase()) { baseCredential = pc; + LOGGER.error("Found the base Certificate"); } pc.setDevice(device); this.certificateManager.update(pc); } } + + // check that the delta certificates validity date is after + // the base + if (baseCredential != null) { + for (PlatformCredential pc : pcs) { + int result = pc.getBeginValidity() + .compareTo(baseCredential.getBeginValidity()); + if (!pc.isBase() && (result <= 0)) { + LOGGER.error("You are not crazy"); + validationTypeMap.put(platformType, + buildValidationRecord( + platformType, + AppraisalStatus.Status.FAIL, + "Delta Certificate's validity " + + "date is not after Base", + null, Level.ERROR)); + break; + } + } + } else { + // we don't have a base cert, fail + validationTypeMap.put(platformType, + buildValidationRecord( + platformType, + AppraisalStatus.Status.FAIL, + "Base Platform credential missing", + null, + Level.ERROR)); + } + + validations.add(validationTypeMap.get( + platformType)); } } @@ -189,17 +242,23 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe if (pcs == null || pcs.isEmpty()) { LOGGER.error("There were no Platform Credentials to validate attributes."); validations.add(buildValidationRecord( - SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + platformAttrType, AppraisalStatus.Status.FAIL, "Platform credential(s) missing." + " Cannot validate attributes", null, Level.ERROR)); } else { + platformScv = validationTypeMap.get( + platformType); + SupplyChainValidation attributeScv = null; + + List aes = new ArrayList<>(); + if (platformScv != null) { + aes.addAll(platformScv.getCertificatesUsed()); + } Iterator it = pcs.iterator(); while (it.hasNext()) { PlatformCredential pc = it.next(); - SupplyChainValidation attributeScv = null; - if (pc != null) { if (pc.isDeltaChain()) { // this check validates the delta changes and re-compares @@ -211,38 +270,69 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe attributeScv = validatePlatformCredentialAttributes( pc, device.getDeviceInfo(), ec); } - if (platformScv != null) { - // have to make sure the attribute validation isn't ignored and - // doesn't override general validation status - if (platformScv.getResult() == PASS - && attributeScv.getResult() != PASS) { - // if the platform trust store validated but the attribute didn't - // replace - validations.remove(platformScv); - validations.add(attributeScv); - } else if ((platformScv.getResult() == PASS - && attributeScv.getResult() == PASS) - || (platformScv.getResult() != PASS - && attributeScv.getResult() != PASS)) { - // if both trust store and attributes validated or failed - // combine messages - validations.remove(platformScv); - List aes = new ArrayList<>(); - for (Certificate cert : platformScv.getCertificatesUsed()) { - aes.add(cert); - } - validations.add(new SupplyChainValidation( - platformScv.getValidationType(), - platformScv.getResult(), aes, - String.format("%s%n%s", platformScv.getMessage(), + + // update the attribute SCV + if (validationTypeMap.containsKey(platformAttrType)) { + SupplyChainValidation tmpScv = validationTypeMap.get( + platformAttrType); + if (tmpScv.getResult() == PASS && attributeScv.getResult() == FAIL) { + validationTypeMap.put(platformAttrType, attributeScv); + } else if (tmpScv.getResult() == FAIL + && attributeScv.getResult() == FAIL) { + validationTypeMap.put(platformAttrType, new SupplyChainValidation( + attributeScv.getValidationType(), + attributeScv.getResult(), aes, + String.format("%s%n%s", tmpScv.getMessage(), attributeScv.getMessage()))); } + } else { + validationTypeMap.put(platformAttrType, attributeScv); } +// if (platformScv != null) { +// // have to make sure the attribute validation isn't ignored and +// // doesn't override general validation status +// if (platformScv.getResult() == PASS +// && attributeScv.getResult() != PASS) { +// // if the platform trust store validated but the attribute didn't +// // replace +// validationTypeMap.put( +// SupplyChainValidation.ValidationType +// .PLATFORM_CREDENTIAL_ATTRIBUTES, +// attributeScv); +// } else if ((platformScv.getResult() == PASS +// && attributeScv.getResult() == PASS) +// || (platformScv.getResult() != PASS +// && attributeScv.getResult() != PASS)) { +// // if both trust store and attributes validated or failed +// // combine messages +// validations.add(new SupplyChainValidation( +// platformScv.getValidationType(), +// platformScv.getResult(), aes, +// String.format("%s%n%s", platformScv.getMessage(), +// attributeScv.getMessage()))); +// } +// } + pc.setDevice(device); this.certificateManager.update(pc); } } + //combine platform and platform attributes + validations.remove(platformScv); + attributeScv = validationTypeMap.get( + platformAttrType); + if (platformScv.getResult() == PASS && attributeScv.getResult() == FAIL) { + validations.add(new SupplyChainValidation( + platformScv.getValidationType(), + attributeScv.getResult(), aes, attributeScv.getMessage())); + } else if (platformScv.getResult() == FAIL && attributeScv.getResult() == FAIL) { + validations.add(new SupplyChainValidation( + platformScv.getValidationType(), + platformScv.getResult(), aes, + String.format("%s%n%s", platformScv.getMessage(), + attributeScv.getMessage()))); + } } } @@ -645,7 +735,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe final PlatformCredential pc, final DeviceInfoReport deviceInfoReport, final EndorsementCredential ec) { final SupplyChainValidation.ValidationType validationType - = SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL; + = SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES; if (pc == null) { LOGGER.error("No platform credential to validate"); @@ -676,7 +766,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe final PlatformCredential base, final Map deltaMapping) { final SupplyChainValidation.ValidationType validationType - = SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL; + = SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES; if (delta == null) { LOGGER.error("No delta certificate to validate"); diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/AppraisalStatus.java b/HIRS_Utils/src/main/java/hirs/data/persist/AppraisalStatus.java index dd5ddfc5..87491887 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/AppraisalStatus.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/AppraisalStatus.java @@ -40,8 +40,7 @@ public class AppraisalStatus { * @param message description of result */ public AppraisalStatus(final Status appStatus, final String message) { - this.appStatus = appStatus; - this.message = message; + this(appStatus, message, ""); } /** diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/V2/ComponentIdentifierV2.java b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/V2/ComponentIdentifierV2.java index a9e5fdb0..00ebf805 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/V2/ComponentIdentifierV2.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/V2/ComponentIdentifierV2.java @@ -235,6 +235,14 @@ public class ComponentIdentifierV2 extends ComponentIdentifier { 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. */ diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 6ce019d4..5e65b1f1 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -633,7 +633,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator List certificateList = null; SupplyChainValidation scv = null; resultMessage.append("There are errors with Delta " - + "Component Statuses components:\n"); + + "Component Statuses:\n"); // go through the leaf and check the changes against the valid components // forget modifying validOrigPcComponents for (PlatformCredential delta : chainCertificates) { @@ -744,12 +744,24 @@ public final class SupplyChainCredentialValidator implements CredentialValidator } else { builtMatchList.add(ci); } + } else if (ciV2.isEmpty()) { + fieldValidation = false; + LOGGER.warn(String.format("%s for delta %s has empty status", + ciV2.getComponentClass().toString(), + delta.getSerialNumber().toString())); + failureMsg.append(String.format("Empty component status " + + "in delta certificate. (%s)%n", + delta.getSerialNumber().toString())); + deltaMapping.put(delta, new SupplyChainValidation( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + FAIL, certificateList, + failureMsg.toString() + )); } } } // each delta has a change to change or modify what was just modified modifiedClassValues.clear(); - resultMessage.append(failureMsg.toString()); } @@ -809,11 +821,10 @@ public final class SupplyChainCredentialValidator implements CredentialValidator for (ComponentIdentifier cId : fullDeltaChainComponents) { ciV2 = (ComponentIdentifierV2) cId; if (ciV2.getComponentClass().getClassValueString() - .contains(cInfo.getComponentClass())) { - if (isMatch(cId, cInfo)) { + .contains(cInfo.getComponentClass()) + && isMatch(cId, cInfo)) { subCompIdList.remove(cId); subCompInfoList.remove(cInfo); - } } } } From f38fa87013dafd1ddf67db8b31521817fe30a192 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Thu, 17 Dec 2020 09:31:39 -0500 Subject: [PATCH 07/41] Undid some code I took out --- .../service/SupplyChainValidationServiceImpl.java | 7 ------- 1 file changed, 7 deletions(-) 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 0883a239..9cfbdf93 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -176,13 +176,6 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe platformScv = validatePcPolicy(pc, platformScv, deltaMapping, acceptExpiredCerts); - /** - * Alright, this should work but because the test material is bad - * I can't finish it. Currently the delta certificate has the same - * serial number as the base, the same validity and so on. I will - * attempt to generate my own but for right now, I'm going to move - * on to something else. - */ if (validationTypeMap.containsKey( platformType)) { SupplyChainValidation tmpScv = validationTypeMap.get(platformType); From 7028810707c4ae71a91e905fc13cebf427880f3e Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Wed, 30 Dec 2020 08:41:47 -0500 Subject: [PATCH 08/41] This latest push should have the code that'll highlight the components based on a string rather than the serial number. This also adds additional checks for the validity begin date of the delta not matching or being before the base. It also checks that they don't have the same certificate serial number. --- ...stractAttestationCertificateAuthority.java | 7 - .../SupplyChainValidationServiceImpl.java | 179 +++++------------- ...eferenceManifestDetailsPageController.java | 5 - .../certificate/PlatformCredential.java | 13 +- .../SupplyChainCredentialValidator.java | 74 +++----- 5 files changed, 83 insertions(+), 195 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java index 9566ff9b..3d72d42e 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java @@ -392,7 +392,6 @@ public abstract class AbstractAttestationCertificateAuthority */ @Override public byte[] processIdentityClaimTpm2(final byte[] identityClaim) { - LOG.debug("Got identity claim"); if (ArrayUtils.isEmpty(identityClaim)) { @@ -414,7 +413,6 @@ public abstract class AbstractAttestationCertificateAuthority LOG.error(ex); } if (validationResult == AppraisalStatus.Status.PASS) { - RSAPublicKey akPub = parsePublicKey(claim.getAkPublicArea().toByteArray()); byte[] nonce = generateRandomBytes(NONCE_LENGTH); ByteString blobStr = tpm20MakeCredential(ekPub, akPub, nonce); @@ -454,11 +452,6 @@ public abstract class AbstractAttestationCertificateAuthority Set platformCredentials = parsePcsFromIdentityClaim(claim, endorsementCredential); Map correctedMap = new HashMap<>(); - for (PlatformCredential pc : platformCredentials) { - correctedMap.put(pc.getSerialNumber(), pc); - } - platformCredentials.clear(); - platformCredentials.addAll(correctedMap.values()); // Parse and save device info Device device = processDeviceInfo(claim); 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 9cfbdf93..e41720da 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -84,7 +84,6 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe private static final Logger LOGGER = LogManager.getLogger(SupplyChainValidationServiceImpl.class); - private static final int VALUE_INDEX = 1; /** * Constructor. @@ -132,9 +131,10 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe supplyChainAppraiser); boolean acceptExpiredCerts = policy.isExpiredCertificateValidationEnabled(); PlatformCredential baseCredential = null; + SupplyChainValidation platformScv = null; + String pcErrorMessage = ""; List validations = new LinkedList<>(); Map deltaMapping = new HashMap<>(); - SupplyChainValidation platformScv = null; SupplyChainValidation.ValidationType platformType = SupplyChainValidation .ValidationType.PLATFORM_CREDENTIAL; SupplyChainValidation.ValidationType platformAttrType = SupplyChainValidation @@ -158,41 +158,26 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe // Ensure there are platform credentials to validate if (pcs == null || pcs.isEmpty()) { LOGGER.error("There were no Platform Credentials to validate."); - validations.add(buildValidationRecord( - platformType, - AppraisalStatus.Status.FAIL, - "Platform credential(s) missing", null, Level.ERROR)); + pcErrorMessage = "Platform credential(s) missing\n"; } else { - Iterator it = pcs.iterator(); - while (it.hasNext()) { - PlatformCredential pc = it.next(); + for (PlatformCredential pc : pcs) { KeyStore trustedCa = getCaChain(pc); platformScv = validatePlatformCredential( pc, trustedCa, acceptExpiredCerts); - // check if this cert has been verified for multiple base - // associated with the serial number - if (pc != null) { - platformScv = validatePcPolicy(pc, platformScv, - deltaMapping, acceptExpiredCerts); - - if (validationTypeMap.containsKey( - platformType)) { - SupplyChainValidation tmpScv = validationTypeMap.get(platformType); - if (tmpScv.getResult() == PASS && platformScv.getResult() == FAIL) { - validationTypeMap.put(platformType, platformScv); - } - } else { - validationTypeMap.put(platformType, platformScv); - } - - if (pc.isBase()) { - baseCredential = pc; - LOGGER.error("Found the base Certificate"); - } - pc.setDevice(device); - this.certificateManager.update(pc); + if (platformScv.getResult() == FAIL) { + pcErrorMessage = String.format("%s%s%n", pcErrorMessage, + platformScv.getMessage()); } + // set the base credential + if (pc.isBase()) { + baseCredential = pc; + } else { + deltaMapping.put(pc, null); + } + pc.setDevice(device); + this.certificateManager.update(pc); + } // check that the delta certificates validity date is after @@ -202,130 +187,70 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe int result = pc.getBeginValidity() .compareTo(baseCredential.getBeginValidity()); if (!pc.isBase() && (result <= 0)) { - LOGGER.error("You are not crazy"); - validationTypeMap.put(platformType, - buildValidationRecord( - platformType, - AppraisalStatus.Status.FAIL, - "Delta Certificate's validity " - + "date is not after Base", - null, Level.ERROR)); + pcErrorMessage = String.format("%s%s%n", pcErrorMessage, + "Delta Certificate's validity " + + "date is not after Base"); break; } } } else { // we don't have a base cert, fail - validationTypeMap.put(platformType, - buildValidationRecord( - platformType, - AppraisalStatus.Status.FAIL, - "Base Platform credential missing", - null, - Level.ERROR)); + pcErrorMessage = String.format("%s%s%n", pcErrorMessage, + "Base Platform credential missing"); } + } - validations.add(validationTypeMap.get( - platformType)); + if (pcErrorMessage.isEmpty()) { + validations.add(platformScv); + } else { + validations.add(new SupplyChainValidation(platformType, + AppraisalStatus.Status.FAIL, new ArrayList<>(pcs), pcErrorMessage)); } } // Validate Platform Credential attributes - if (policy.isPcAttributeValidationEnabled()) { + if (policy.isPcAttributeValidationEnabled() + && pcErrorMessage.isEmpty()) { // Ensure there are platform credentials to validate - if (pcs == null || pcs.isEmpty()) { - LOGGER.error("There were no Platform Credentials to validate attributes."); - validations.add(buildValidationRecord( - platformAttrType, - AppraisalStatus.Status.FAIL, - "Platform credential(s) missing." - + " Cannot validate attributes", - null, Level.ERROR)); - } else { - platformScv = validationTypeMap.get( - platformType); - SupplyChainValidation attributeScv = null; + SupplyChainValidation attributeScv = null; - List aes = new ArrayList<>(); - if (platformScv != null) { - aes.addAll(platformScv.getCertificatesUsed()); - } + List aes = new ArrayList<>(); + if (platformScv != null) { + aes.addAll(platformScv.getCertificatesUsed()); + } + // ok, still want to validate the base credential attributes + attributeScv = validatePlatformCredentialAttributes( + baseCredential, device.getDeviceInfo(), ec); + + if (attributeScv.getResult() != FAIL) { Iterator it = pcs.iterator(); + String attrErrorMessage = ""; while (it.hasNext()) { PlatformCredential pc = it.next(); if (pc != null) { - if (pc.isDeltaChain()) { - // this check validates the delta changes and re-compares - // the modified list to the original. + if (!pc.isBase() && attributeScv.getResult() != FAIL) { attributeScv = validateDeltaPlatformCredentialAttributes( pc, device.getDeviceInfo(), baseCredential, deltaMapping); - } else { - attributeScv = validatePlatformCredentialAttributes( - pc, device.getDeviceInfo(), ec); - } - - // update the attribute SCV - if (validationTypeMap.containsKey(platformAttrType)) { - SupplyChainValidation tmpScv = validationTypeMap.get( - platformAttrType); - if (tmpScv.getResult() == PASS && attributeScv.getResult() == FAIL) { - validationTypeMap.put(platformAttrType, attributeScv); - } else if (tmpScv.getResult() == FAIL - && attributeScv.getResult() == FAIL) { - validationTypeMap.put(platformAttrType, new SupplyChainValidation( - attributeScv.getValidationType(), - attributeScv.getResult(), aes, - String.format("%s%n%s", tmpScv.getMessage(), - attributeScv.getMessage()))); + if (attributeScv.getResult() == FAIL) { + attrErrorMessage = String.format("%s%s%n", attrErrorMessage, + attributeScv.getMessage()); } - } else { - validationTypeMap.put(platformAttrType, attributeScv); } - -// if (platformScv != null) { -// // have to make sure the attribute validation isn't ignored and -// // doesn't override general validation status -// if (platformScv.getResult() == PASS -// && attributeScv.getResult() != PASS) { -// // if the platform trust store validated but the attribute didn't -// // replace -// validationTypeMap.put( -// SupplyChainValidation.ValidationType -// .PLATFORM_CREDENTIAL_ATTRIBUTES, -// attributeScv); -// } else if ((platformScv.getResult() == PASS -// && attributeScv.getResult() == PASS) -// || (platformScv.getResult() != PASS -// && attributeScv.getResult() != PASS)) { -// // if both trust store and attributes validated or failed -// // combine messages -// validations.add(new SupplyChainValidation( -// platformScv.getValidationType(), -// platformScv.getResult(), aes, -// String.format("%s%n%s", platformScv.getMessage(), -// attributeScv.getMessage()))); -// } -// } - - pc.setDevice(device); - this.certificateManager.update(pc); } } - //combine platform and platform attributes - validations.remove(platformScv); - attributeScv = validationTypeMap.get( - platformAttrType); - if (platformScv.getResult() == PASS && attributeScv.getResult() == FAIL) { + if (!attrErrorMessage.isEmpty()) { + //combine platform and platform attributes + validations.remove(platformScv); validations.add(new SupplyChainValidation( platformScv.getValidationType(), attributeScv.getResult(), aes, attributeScv.getMessage())); - } else if (platformScv.getResult() == FAIL && attributeScv.getResult() == FAIL) { - validations.add(new SupplyChainValidation( - platformScv.getValidationType(), - platformScv.getResult(), aes, - String.format("%s%n%s", platformScv.getMessage(), - attributeScv.getMessage()))); } + } else { + validations.remove(platformScv); + // base platform has errors + validations.add(new SupplyChainValidation(platformScv.getValidationType(), + attributeScv.getResult(), aes, attributeScv.getMessage())); } } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java index 65298a58..93ede6b3 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java @@ -275,7 +275,6 @@ public class ReferenceManifestDetailsPageController for (CertificateAuthorityCredential cert : certificates) { if (Arrays.equals(cert.getEncodedPublicKey(), RIM_VALIDATOR.getPublicKey().getEncoded())) { - LOGGER.info("Found matching cert!"); data.put("issuerID", cert.getId().toString()); } } @@ -407,10 +406,6 @@ public class ReferenceManifestDetailsPageController data.put("supportEvents", supportEvents); data.put("livelogEvents", livelogEvents); - for (Map.Entry entry : data.entrySet()) { - LOGGER.error(String.format("%s -> %s", entry.getKey(), - String.valueOf(entry.getValue()))); - } return data; } } diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java index 45a43965..ce35d6e1 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java @@ -380,25 +380,16 @@ public class PlatformCredential extends DeviceAssociatedCertificate { /** * Get the type of platform certificate. * - * @return the TCG platform type { base | delta } + * @return flag for base certificate */ public boolean isBase() { return platformBase; } - /** - * Flag that indicates this PC has or can have a chain of delta - * certificates. - * @return status of the chain - */ - public boolean isDeltaChain() { - return isDeltaChain; - } - /** * Getter for the string representation of the platform type. * - * @return Delta or Base + * @return the TCG platform type { base | delta } */ public String getPlatformType() { return platformChainType; diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 5e65b1f1..32cf8784 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -316,34 +316,28 @@ public final class SupplyChainCredentialValidator implements CredentialValidator final DeviceInfoReport deviceInfoReport, final PlatformCredential basePlatformCredential, final Map deltaMapping) { - final String baseErrorMessage = "Can't validate delta platform" - + "certificate attributes without "; String message; - if (deltaPlatformCredential == null) { - message = baseErrorMessage + "a delta platform certificate"; - LOGGER.error(message); - return new AppraisalStatus(FAIL, message); - } - if (deviceInfoReport == null) { - message = baseErrorMessage + "a device info report"; - LOGGER.error(message); - return new AppraisalStatus(FAIL, message); - } - if (basePlatformCredential == null) { - message = baseErrorMessage + "a base platform credential"; - LOGGER.error(message); - return new AppraisalStatus(FAIL, message); - } - if (!basePlatformCredential.getPlatformSerial() - .equals(deltaPlatformCredential.getPlatformSerial())) { - message = String.format("Delta platform certificate " - + "platform serial number (%s) does not match " - + "the base certificate's platform serial number (%s)", - deltaPlatformCredential.getPlatformSerial(), - basePlatformCredential.getPlatformSerial()); - LOGGER.error(message); - return new AppraisalStatus(FAIL, message); + // this needs to be a loop for all deltas, link to issue #110 + // check that they don't have the same serial number + for (PlatformCredential delta : deltaMapping.keySet()) { + if (!basePlatformCredential.getPlatformSerial() + .equals(delta.getPlatformSerial())) { + message = String.format("Base and Delta platform serial " + + "numbers do not match (%s != %s)", + delta.getPlatformSerial(), + basePlatformCredential.getPlatformSerial()); + LOGGER.error(message); + return new AppraisalStatus(FAIL, message); + } + // none of the deltas should have the serial number of the base + if (basePlatformCredential.getSerialNumber() + .equals(delta.getSerialNumber())) { + message = String.format("Delta Certificate with same serial number as base. (%s)", + delta.getSerialNumber()); + LOGGER.error(message); + return new AppraisalStatus(FAIL, message); + } } // parse out the provided delta and its specific chain. @@ -501,18 +495,14 @@ public final class SupplyChainCredentialValidator implements CredentialValidator // check PlatformSerial against both system-serial-number and baseboard-serial-number fieldValidation = ( - ( - optionalPlatformCredentialFieldNullOrMatches( + (optionalPlatformCredentialFieldNullOrMatches( "PlatformSerial", platformCredential.getPlatformSerial(), - hardwareInfo.getSystemSerialNumber()) - ) || ( - optionalPlatformCredentialFieldNullOrMatches( + hardwareInfo.getSystemSerialNumber())) + || (optionalPlatformCredentialFieldNullOrMatches( "PlatformSerial", platformCredential.getPlatformSerial(), - hardwareInfo.getBaseboardSerialNumber()) - ) - ); + hardwareInfo.getBaseboardSerialNumber()))); if (!fieldValidation) { resultMessage.append("Platform serial did not match\n"); @@ -755,8 +745,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator deltaMapping.put(delta, new SupplyChainValidation( SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, FAIL, certificateList, - failureMsg.toString() - )); + failureMsg.toString())); + builtMatchList.add(ci); } } } @@ -772,24 +762,18 @@ public final class SupplyChainCredentialValidator implements CredentialValidator String paccorOutputString = deviceInfoReport.getPaccorOutputString(); String unmatchedComponents; try { -// List componentInfoList -// = getComponentInfoFromPaccorOutput(paccorOutputString); // compare based on component class List componentInfoList = getV2PaccorOutput(paccorOutputString); -// testComponentMatching(compMapping, chainCiMapping.values()); // this is what I want to rewrite -// unmatchedComponents = validateV2p0PlatformCredentialComponentsExpectingExactMatch( -// new LinkedList<>(chainCiMapping.values()), -// compMapping.keySet().stream().collect(Collectors.toList())); unmatchedComponents = validateV2PlatformCredentialAttributes( builtMatchList, componentInfoList); fieldValidation &= unmatchedComponents.isEmpty(); - } catch (IOException e) { + } catch (IOException ioEx) { final String baseErrorMessage = "Error parsing JSON output from PACCOR: "; - LOGGER.error(baseErrorMessage + e.toString()); + LOGGER.error(baseErrorMessage + ioEx.toString()); LOGGER.error("PACCOR output string:\n" + paccorOutputString); - return new AppraisalStatus(ERROR, baseErrorMessage + e.getMessage()); + return new AppraisalStatus(ERROR, baseErrorMessage + ioEx.getMessage()); } if (!fieldValidation) { // instead of listing all unmatched, just print the #. The failure From 90a6e75f595ad8e388885b0ecb4add9f44e15e17 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Mon, 4 Jan 2021 08:56:41 -0500 Subject: [PATCH 09/41] Removed unused import --- .../page/controllers/ReferenceManifestDetailsPageController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java index 93ede6b3..48c22c46 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java @@ -24,7 +24,6 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.ArrayList; -import java.util.Map; import java.util.Set; import java.util.UUID; From 058c58d208cbbead27a09beb6a5be8aa8c78d11e Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Thu, 7 Jan 2021 12:51:01 -0500 Subject: [PATCH 10/41] Updated the begin validity date check for the base and delta so that it is only an error if the delta begin date is older than the platform. Equal is allowed. --- .../attestationca/service/SupplyChainValidationServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e41720da..65b268e9 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -186,7 +186,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe for (PlatformCredential pc : pcs) { int result = pc.getBeginValidity() .compareTo(baseCredential.getBeginValidity()); - if (!pc.isBase() && (result <= 0)) { + if (!pc.isBase() && (result > 0)) { pcErrorMessage = String.format("%s%s%n", pcErrorMessage, "Delta Certificate's validity " + "date is not after Base"); From fcb496686c7cb5c087241541a168c6308a292fff Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Mon, 11 Jan 2021 13:24:49 -0500 Subject: [PATCH 11/41] This includes some refactoring of the component identifier. --- .../attributes/ComponentIdentifier.java | 35 +++++++++++++++++++ .../attributes/V2/ComponentIdentifierV2.java | 10 ++++++ .../SupplyChainCredentialValidator.java | 8 +++++ 3 files changed, 53 insertions(+) diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentIdentifier.java b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentIdentifier.java index c3f78f39..b98d325a 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentIdentifier.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentIdentifier.java @@ -3,6 +3,7 @@ package hirs.data.persist.certificate.attributes; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -287,6 +288,40 @@ public class ComponentIdentifier { return Collections.unmodifiableList(addresses); } +// +// @Override +// public boolean equals(Object o) { +// if (this == o) return true; +// if (o == null || getClass() != o.getClass()) return false; +// ComponentIdentifier that = (ComponentIdentifier) o; +// return componentManufacturer.equals(that.componentManufacturer) +// && componentModel.equals(that.componentModel) && Objects.equals +// (componentSerial, that.componentSerial) && Objects.equals(componentRevision, +// that.componentRevision); +// } +// + @Override + public int hashCode() { + return Objects.hash(componentManufacturer, componentModel, + componentSerial, componentRevision); + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + + if (obj instanceof ComponentIdentifier) { + ComponentIdentifier testCi = (ComponentIdentifier) obj; + return testCi.getComponentManufacturer().equals(this.getComponentManufacturer()) + && testCi.getComponentModel().equals(this.getComponentModel()) + && testCi.getComponentSerial().equals(this.getComponentSerial()) + && testCi.getComponentRevision().equals(this.getComponentRevision()); + } else { + return false; + } + } @Override public String toString() { diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/V2/ComponentIdentifierV2.java b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/V2/ComponentIdentifierV2.java index 00ebf805..6232c89f 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/V2/ComponentIdentifierV2.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/V2/ComponentIdentifierV2.java @@ -251,6 +251,16 @@ public class ComponentIdentifierV2 extends ComponentIdentifier { return true; } + @Override + public boolean equals(final Object obj) { + return super.equals(obj); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 32cf8784..ec8b00a1 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -792,9 +792,17 @@ public final class SupplyChainCredentialValidator implements CredentialValidator private static String validateV2PlatformCredentialAttributes( final List fullDeltaChainComponents, final List allDeviceInfoComponents) { + LOGGER.error(String.format("fullDeltaChainComponents %d", + fullDeltaChainComponents.size())); + LOGGER.error(String.format("allDeviceInfoComponents %d", + allDeviceInfoComponents.size())); ComponentIdentifierV2 ciV2; StringBuilder invalidDeviceInfo = new StringBuilder(); StringBuilder invalidPcIds = new StringBuilder(); + LOGGER.error("DELTA CHAIN PRINT"); + fullDeltaChainComponents.stream().forEach(ci -> LOGGER.error(ci)); + LOGGER.error("DEVICE INFOs"); + allDeviceInfoComponents.stream().forEach(dic -> LOGGER.error(dic)); List subCompIdList = fullDeltaChainComponents .stream().collect(Collectors.toList()); List subCompInfoList = allDeviceInfoComponents From beb1ccbee3ab47faf63a0e45d57c404f6463fb89 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Tue, 12 Jan 2021 12:26:54 -0500 Subject: [PATCH 12/41] Updated a supply chain validation check for delta certificates. Updated the check for duplicate base platform certificates when storing them for the same device and updated the begin validity date for the delta vs the base check. --- .../java/hirs/attestationca/CredentialManagementHelper.java | 2 +- .../service/SupplyChainValidationServiceImpl.java | 4 ++-- .../hirs/validation/SupplyChainCredentialValidator.java | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/CredentialManagementHelper.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/CredentialManagementHelper.java index e1dbd778..fcb47793 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/CredentialManagementHelper.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/CredentialManagementHelper.java @@ -122,7 +122,7 @@ public final class CredentialManagementHelper { if (!certificates.isEmpty()) { // found associated certificates for (PlatformCredential pc : certificates) { - if (pc.isBase()) { + if (pc.isBase() && platformCredential.isBase()) { // found a base in the database associated with // parsed certificate LOG.error(String.format("Base certificate stored" 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 65b268e9..2dca7923 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -184,8 +184,8 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe // the base if (baseCredential != null) { for (PlatformCredential pc : pcs) { - int result = pc.getBeginValidity() - .compareTo(baseCredential.getBeginValidity()); + int result = baseCredential.getBeginValidity() + .compareTo(pc.getBeginValidity()); if (!pc.isBase() && (result > 0)) { pcErrorMessage = String.format("%s%s%n", pcErrorMessage, "Delta Certificate's validity " diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index ec8b00a1..8aa55638 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -664,7 +664,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator "%s attempted MODIFIED with no prior instance.%n", classValue)); scv = deltaMapping.get(delta); - if (scv.getResult() != AppraisalStatus.Status.PASS) { + if (scv != null && scv.getResult() != AppraisalStatus.Status.PASS) { failureMsg.append(scv.getMessage()); } deltaMapping.put(delta, new SupplyChainValidation( @@ -694,7 +694,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator "%s attempted REMOVED with no prior instance.%n", classValue)); scv = deltaMapping.get(delta); - if (scv.getResult() != AppraisalStatus.Status.PASS) { + if (scv != null && scv.getResult() != AppraisalStatus.Status.PASS) { failureMsg.append(scv.getMessage()); } deltaMapping.put(delta, new SupplyChainValidation( @@ -723,7 +723,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator "%s was ADDED, the serial already exists.%n", classValue)); scv = deltaMapping.get(delta); - if (scv.getResult() != AppraisalStatus.Status.PASS) { + if (scv != null && scv.getResult() != AppraisalStatus.Status.PASS) { failureMsg.append(scv.getMessage()); } deltaMapping.put(delta, new SupplyChainValidation( From fa126142210a6357e0daf29c5fc16089c3cc50cc Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Thu, 14 Jan 2021 10:34:27 -0500 Subject: [PATCH 13/41] Testing out new code --- .../SupplyChainCredentialValidator.java | 170 +++++++++++++++--- 1 file changed, 145 insertions(+), 25 deletions(-) diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 8aa55638..a0f701ba 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -596,12 +596,10 @@ public final class SupplyChainCredentialValidator implements CredentialValidator List chainCertificates = new LinkedList<>(deltaMapping.keySet()); // map the components throughout the chain - List deltaBuildList = new LinkedList<>(validOrigPcComponents); - List builtMatchList = new LinkedList<>(validOrigPcComponents); + List deltaCompList = new LinkedList<>(validOrigPcComponents); + List baseCompList = new LinkedList<>(validOrigPcComponents); + List leftOvers = new LinkedList<>(); - /** - * Make sure the certificates are in the correct order. - */ Collections.sort(chainCertificates, new Comparator() { @Override public int compare(final PlatformCredential obj1, @@ -617,13 +615,25 @@ public final class SupplyChainCredentialValidator implements CredentialValidator } return obj1.getBeginValidity().compareTo(obj2.getBeginValidity()); } - }); + });// start of some changes + resultMessage.append("There are errors with Delta " + + "Component Statuses:\n"); + resultMessage.append(validateDeltaChain(deltaMapping, baseCompList, + leftOvers, chainCertificates)); - List modifiedClassValues = new LinkedList<>(); + // I have leftovers that don't have serial numbers + LOGGER.error(leftOvers.size()); + + /** + * + * Ok, I need to change the serial run to not care if it doesn't find something...right? + * + * Then come to this block with left over delta comps and if it still doesn't find something + * then write up the error. + */ + List modifiedClassValues = new LinkedList<>();// finished up List certificateList = null; SupplyChainValidation scv = null; - resultMessage.append("There are errors with Delta " - + "Component Statuses:\n"); // go through the leaf and check the changes against the valid components // forget modifying validOrigPcComponents for (PlatformCredential delta : chainCertificates) { @@ -642,7 +652,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator // A component was modified // if it exists, update // if doesn't exist, error - for (ComponentIdentifier subCi : deltaBuildList) { + for (ComponentIdentifier subCi : deltaCompList) { ComponentIdentifierV2 subCiV2 = (ComponentIdentifierV2) subCi; classFound = classValue.equals(subCiV2.getComponentClass() .getClassValueString()); @@ -657,7 +667,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator } if (classFound) { modifiedClassValues.add(classValue); - builtMatchList.add(ci); + baseCompList.add(ci); } else { fieldValidation = false; failureMsg.append(String.format( @@ -674,7 +684,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator failureMsg.toString())); } } else if (ciV2.isRemoved()) { - for (ComponentIdentifier subCi : deltaBuildList) { + for (ComponentIdentifier subCi : deltaCompList) { ComponentIdentifierV2 subCiV2 = (ComponentIdentifierV2) subCi; classFound = classValue.equals(subCiV2.getComponentClass() .getClassValueString()); @@ -686,7 +696,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator } if (classFound) { - builtMatchList.remove(ci); + baseCompList.remove(ci); } else { // error thrown, can't remove if it doesn't exist fieldValidation = false; @@ -705,7 +715,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator } } else if (ciV2.isAdded()) { // ADDED - for (ComponentIdentifier subCi : deltaBuildList) { + for (ComponentIdentifier subCi : deltaCompList) { ComponentIdentifierV2 subCiV2 = (ComponentIdentifierV2) subCi; classFound = classValue.equals(subCiV2.getComponentClass() .getClassValueString()); @@ -732,7 +742,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator certificateList, failureMsg.toString())); } else { - builtMatchList.add(ci); + baseCompList.add(ci); } } else if (ciV2.isEmpty()) { fieldValidation = false; @@ -746,7 +756,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, FAIL, certificateList, failureMsg.toString())); - builtMatchList.add(ci); + baseCompList.add(ci); } } } @@ -766,7 +776,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator List componentInfoList = getV2PaccorOutput(paccorOutputString); // this is what I want to rewrite unmatchedComponents = validateV2PlatformCredentialAttributes( - builtMatchList, + baseCompList, componentInfoList); fieldValidation &= unmatchedComponents.isEmpty(); } catch (IOException ioEx) { @@ -792,17 +802,9 @@ public final class SupplyChainCredentialValidator implements CredentialValidator private static String validateV2PlatformCredentialAttributes( final List fullDeltaChainComponents, final List allDeviceInfoComponents) { - LOGGER.error(String.format("fullDeltaChainComponents %d", - fullDeltaChainComponents.size())); - LOGGER.error(String.format("allDeviceInfoComponents %d", - allDeviceInfoComponents.size())); ComponentIdentifierV2 ciV2; StringBuilder invalidDeviceInfo = new StringBuilder(); StringBuilder invalidPcIds = new StringBuilder(); - LOGGER.error("DELTA CHAIN PRINT"); - fullDeltaChainComponents.stream().forEach(ci -> LOGGER.error(ci)); - LOGGER.error("DEVICE INFOs"); - allDeviceInfoComponents.stream().forEach(dic -> LOGGER.error(dic)); List subCompIdList = fullDeltaChainComponents .stream().collect(Collectors.toList()); List subCompInfoList = allDeviceInfoComponents @@ -1470,7 +1472,125 @@ public final class SupplyChainCredentialValidator implements CredentialValidator return foundRootOfCertChain; } +// start of some changes + private static String validateDeltaChain( + final Map deltaMapping, + final List baseCompList, + final List leftOvers, + final List chainCertificates) { + boolean fieldValidation = true; + StringBuilder resultMessage = new StringBuilder(); + // map the components throughout the chain + Map chainCiMapping = new HashMap<>(); + baseCompList.stream().forEach((ci) -> { + chainCiMapping.put(ci.getComponentSerial().toString().replaceAll("\\.", ""), ci); + LOGGER.error(String.format("Comp Serial (%s)", ci.getComponentSerial().toString())); + }); + + for (String s : chainCiMapping.keySet()) { + LOGGER.error(s); + } + if (chainCiMapping.containsKey("Not Specified")) { + leftOvers.add(chainCiMapping.remove("Not Specified")); + } else if (chainCiMapping.containsKey(null)) { + leftOvers.add(chainCiMapping.remove(null)); + } else if (chainCiMapping.containsKey("")) { + LOGGER.error("Africa"); + leftOvers.add(chainCiMapping.remove("")); + } else if (chainCiMapping.containsKey("To Be Filled By OEM")) { + LOGGER.error("USA"); + leftOvers.add(chainCiMapping.remove("To Be Filled By OEM")); + } + + String ciSerial; + List certificateList = null; + SupplyChainValidation scv = null; + resultMessage.append("There are errors with Delta " + + "Component Statuses components:\n"); + // go through the leaf and check the changes against the valid components + // forget modifying validOrigPcComponents + for (PlatformCredential delta : chainCertificates) { + StringBuilder failureMsg = new StringBuilder(); + certificateList = new ArrayList<>(); + certificateList.add(delta); + + for (ComponentIdentifier ci : delta.getComponentIdentifiers()) { + if (ci.isVersion2()) { + ciSerial = ci.getComponentSerial().toString(); + ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) ci; + if (ciV2.isModified()) { + // this won't match + // check it is there + if (!chainCiMapping.containsKey(ciSerial)) { + fieldValidation = false; + failureMsg.append(String.format( + "%s attempted MODIFIED with no prior instance.%n", + ciSerial)); + scv = deltaMapping.get(delta); + if (scv.getResult() != AppraisalStatus.Status.PASS) { + failureMsg.append(scv.getMessage()); + } + deltaMapping.put(delta, new SupplyChainValidation( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + AppraisalStatus.Status.FAIL, + certificateList, + failureMsg.toString())); + } else { + chainCiMapping.put(ciSerial, ci); + } + } else if (ciV2.isRemoved()) { + if (!chainCiMapping.containsKey(ciSerial)) { + // error thrown, can't remove if it doesn't exist + fieldValidation = false; + failureMsg.append(String.format( + "%s attempted REMOVED with no prior instance.%n", + ciSerial)); + scv = deltaMapping.get(delta); + if (scv.getResult() != AppraisalStatus.Status.PASS) { + failureMsg.append(scv.getMessage()); + } + deltaMapping.put(delta, new SupplyChainValidation( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + AppraisalStatus.Status.FAIL, + certificateList, + failureMsg.toString())); + } else { + chainCiMapping.remove(ciSerial); + } + } else if (ciV2.isAdded()) { + // ADDED + if (chainCiMapping.containsKey(ciSerial)) { + // error, shouldn't exist + fieldValidation = false; + failureMsg.append(String.format( + "%s was ADDED, the serial already exists.%n", + ciSerial)); + scv = deltaMapping.get(delta); + if (scv.getResult() != AppraisalStatus.Status.PASS) { + failureMsg.append(scv.getMessage()); + } + deltaMapping.put(delta, new SupplyChainValidation( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + AppraisalStatus.Status.FAIL, + certificateList, + failureMsg.toString())); + } else { + // have to add in case later it is removed + chainCiMapping.put(ciSerial, ci); + } + } + } + } + + resultMessage.append(failureMsg.toString()); + } + baseCompList.clear(); + baseCompList.addAll(chainCiMapping.values()); + + return resultMessage.toString(); + } +// finish of some changes /** * Checks if the issuer info of an attribute cert matches the supposed signing cert's * distinguished name. From e9eef0e5b3f9622fedd8c0f7201a6cce7c3a5a27 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Wed, 20 Jan 2021 08:00:24 -0500 Subject: [PATCH 14/41] Updated the code to go through the serial numbers that are valid numbers verus generic filler. Tested against the provisioner. --- .../SupplyChainCredentialValidator.java | 327 ++++++------------ 1 file changed, 109 insertions(+), 218 deletions(-) diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index a0f701ba..96cdb323 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -596,9 +596,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator List chainCertificates = new LinkedList<>(deltaMapping.keySet()); // map the components throughout the chain - List deltaCompList = new LinkedList<>(validOrigPcComponents); List baseCompList = new LinkedList<>(validOrigPcComponents); - List leftOvers = new LinkedList<>(); Collections.sort(chainCertificates, new Comparator() { @Override @@ -615,154 +613,51 @@ public final class SupplyChainCredentialValidator implements CredentialValidator } return obj1.getBeginValidity().compareTo(obj2.getBeginValidity()); } - });// start of some changes + }); + // start of some changes resultMessage.append("There are errors with Delta " + "Component Statuses:\n"); + List leftOverDeltas = new ArrayList<>(); resultMessage.append(validateDeltaChain(deltaMapping, baseCompList, - leftOvers, chainCertificates)); + leftOverDeltas, chainCertificates)); - // I have leftovers that don't have serial numbers - LOGGER.error(leftOvers.size()); - - /** - * - * Ok, I need to change the serial run to not care if it doesn't find something...right? - * - * Then come to this block with left over delta comps and if it still doesn't find something - * then write up the error. - */ - List modifiedClassValues = new LinkedList<>();// finished up + // finished up List certificateList = null; SupplyChainValidation scv = null; // go through the leaf and check the changes against the valid components // forget modifying validOrigPcComponents - for (PlatformCredential delta : chainCertificates) { - StringBuilder failureMsg = new StringBuilder(); - certificateList = new ArrayList<>(); - certificateList.add(delta); + + // what wasn't handled by the serial number, + // not match by the serial number and the class type + // then the matching manufacturer and model + + for (ComponentIdentifier deltaCi : leftOverDeltas) { String classValue; - ComponentIdentifierV2 ciV2; - boolean classFound = false; + ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) deltaCi; + ComponentIdentifierV2 baseCiV2; + boolean classFound; - for (ComponentIdentifier ci : delta.getComponentIdentifiers()) { - if (ci.isVersion2()) { - ciV2 = (ComponentIdentifierV2) ci; - classValue = ciV2.getComponentClass().getClassValueString(); - if (ciV2.isModified()) { - // A component was modified - // if it exists, update - // if doesn't exist, error - for (ComponentIdentifier subCi : deltaCompList) { - ComponentIdentifierV2 subCiV2 = (ComponentIdentifierV2) subCi; - classFound = classValue.equals(subCiV2.getComponentClass() - .getClassValueString()); - if (classFound && isMatch(ciV2, subCiV2)) { - if (modifiedClassValues.contains(classValue)) { - modifiedClassValues.remove(classValue); - } else { - // we found the class and it is a match - break; - } - } - } - if (classFound) { - modifiedClassValues.add(classValue); - baseCompList.add(ci); - } else { - fieldValidation = false; - failureMsg.append(String.format( - "%s attempted MODIFIED with no prior instance.%n", - classValue)); - scv = deltaMapping.get(delta); - if (scv != null && scv.getResult() != AppraisalStatus.Status.PASS) { - failureMsg.append(scv.getMessage()); - } - deltaMapping.put(delta, new SupplyChainValidation( - SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, - AppraisalStatus.Status.FAIL, - certificateList, - failureMsg.toString())); - } - } else if (ciV2.isRemoved()) { - for (ComponentIdentifier subCi : deltaCompList) { - ComponentIdentifierV2 subCiV2 = (ComponentIdentifierV2) subCi; - classFound = classValue.equals(subCiV2.getComponentClass() - .getClassValueString()); - if (classFound && isMatch(ciV2, subCiV2)) { - break; - } else { - classFound = false; - } - } - - if (classFound) { - baseCompList.remove(ci); - } else { - // error thrown, can't remove if it doesn't exist - fieldValidation = false; - failureMsg.append(String.format( - "%s attempted REMOVED with no prior instance.%n", - classValue)); - scv = deltaMapping.get(delta); - if (scv != null && scv.getResult() != AppraisalStatus.Status.PASS) { - failureMsg.append(scv.getMessage()); - } - deltaMapping.put(delta, new SupplyChainValidation( - SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, - AppraisalStatus.Status.FAIL, - certificateList, - failureMsg.toString())); - } - } else if (ciV2.isAdded()) { - // ADDED - for (ComponentIdentifier subCi : deltaCompList) { - ComponentIdentifierV2 subCiV2 = (ComponentIdentifierV2) subCi; - classFound = classValue.equals(subCiV2.getComponentClass() - .getClassValueString()); - if (classFound && isMatch(ciV2, subCiV2)) { - break; - } else { - classFound = false; - } - } - - if (classFound) { - // error, shouldn't exist - fieldValidation = false; - failureMsg.append(String.format( - "%s was ADDED, the serial already exists.%n", - classValue)); - scv = deltaMapping.get(delta); - if (scv != null && scv.getResult() != AppraisalStatus.Status.PASS) { - failureMsg.append(scv.getMessage()); - } - deltaMapping.put(delta, new SupplyChainValidation( - SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, - AppraisalStatus.Status.FAIL, - certificateList, - failureMsg.toString())); - } else { - baseCompList.add(ci); - } - } else if (ciV2.isEmpty()) { - fieldValidation = false; - LOGGER.warn(String.format("%s for delta %s has empty status", - ciV2.getComponentClass().toString(), - delta.getSerialNumber().toString())); - failureMsg.append(String.format("Empty component status " - + "in delta certificate. (%s)%n", - delta.getSerialNumber().toString())); - deltaMapping.put(delta, new SupplyChainValidation( - SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, - FAIL, certificateList, - failureMsg.toString())); - baseCompList.add(ci); + for (ComponentIdentifier ci : baseCompList) { + classValue = ciV2.getComponentClass().getClassValueString(); + baseCiV2 = (ComponentIdentifierV2) ci; + classFound = classValue.equals(baseCiV2.getComponentClass() + .getClassValueString()); + if (classFound) { + if (isMatch(ciV2, baseCiV2)) { + LOGGER.error("Not Found and added"); + } else { + LOGGER.error("Not Found and added"); + } + } else { + // delta change to a class not there + // is it an add? + if (ciV2.isAdded()) { + LOGGER.error("Not Found and added"); } } } - // each delta has a change to change or modify what was just modified - modifiedClassValues.clear(); - resultMessage.append(failureMsg.toString()); + // this needs to be removed. + baseCompList.add(deltaCi); } if (!fieldValidation) { @@ -810,6 +705,13 @@ public final class SupplyChainCredentialValidator implements CredentialValidator List subCompInfoList = allDeviceInfoComponents .stream().collect(Collectors.toList()); + subCompIdList.stream().forEach((ci) -> { + LOGGER.error(ci.toString()); + }); + + subCompInfoList.stream().forEach((ci) -> { + LOGGER.error(ci.toString()); + }); // Delta is the baseline for (ComponentInfo cInfo : allDeviceInfoComponents) { for (ComponentIdentifier cId : fullDeltaChainComponents) { @@ -1472,42 +1374,28 @@ public final class SupplyChainCredentialValidator implements CredentialValidator return foundRootOfCertChain; } -// start of some changes + private static String validateDeltaChain( final Map deltaMapping, final List baseCompList, final List leftOvers, final List chainCertificates) { - boolean fieldValidation = true; StringBuilder resultMessage = new StringBuilder(); + List noneSerialValues = new ArrayList<>(); + noneSerialValues.add(""); + noneSerialValues.add(null); + noneSerialValues.add("Not Specified"); + noneSerialValues.add("To Be Filled By O.E.M."); // map the components throughout the chain Map chainCiMapping = new HashMap<>(); baseCompList.stream().forEach((ci) -> { - chainCiMapping.put(ci.getComponentSerial().toString().replaceAll("\\.", ""), ci); - LOGGER.error(String.format("Comp Serial (%s)", ci.getComponentSerial().toString())); + chainCiMapping.put(ci.getComponentSerial().toString(), ci); }); - for (String s : chainCiMapping.keySet()) { - LOGGER.error(s); - } - if (chainCiMapping.containsKey("Not Specified")) { - leftOvers.add(chainCiMapping.remove("Not Specified")); - } else if (chainCiMapping.containsKey(null)) { - leftOvers.add(chainCiMapping.remove(null)); - } else if (chainCiMapping.containsKey("")) { - LOGGER.error("Africa"); - leftOvers.add(chainCiMapping.remove("")); - } else if (chainCiMapping.containsKey("To Be Filled By OEM")) { - LOGGER.error("USA"); - leftOvers.add(chainCiMapping.remove("To Be Filled By OEM")); - } - String ciSerial; List certificateList = null; SupplyChainValidation scv = null; - resultMessage.append("There are errors with Delta " - + "Component Statuses components:\n"); // go through the leaf and check the changes against the valid components // forget modifying validOrigPcComponents for (PlatformCredential delta : chainCertificates) { @@ -1516,70 +1404,73 @@ public final class SupplyChainCredentialValidator implements CredentialValidator certificateList.add(delta); for (ComponentIdentifier ci : delta.getComponentIdentifiers()) { - if (ci.isVersion2()) { - ciSerial = ci.getComponentSerial().toString(); - ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) ci; - if (ciV2.isModified()) { - // this won't match - // check it is there - if (!chainCiMapping.containsKey(ciSerial)) { - fieldValidation = false; - failureMsg.append(String.format( - "%s attempted MODIFIED with no prior instance.%n", - ciSerial)); - scv = deltaMapping.get(delta); - if (scv.getResult() != AppraisalStatus.Status.PASS) { - failureMsg.append(scv.getMessage()); + if (!noneSerialValues.contains(ci.getComponentSerial().toString())) { + if (ci.isVersion2()) { + ciSerial = ci.getComponentSerial().toString(); + ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) ci; + if (ciV2.isModified()) { + // this won't match + // check it is there + if (chainCiMapping.containsKey(ciSerial)) { + chainCiMapping.put(ciSerial, ci); + } else { + failureMsg.append(String.format( + "%s attempted MODIFIED with no prior instance.%n", + ciSerial)); + scv = deltaMapping.get(delta); + if (scv.getResult() != AppraisalStatus.Status.PASS) { + failureMsg.append(scv.getMessage()); + } + deltaMapping.put(delta, new SupplyChainValidation( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + AppraisalStatus.Status.FAIL, + certificateList, + failureMsg.toString())); } - deltaMapping.put(delta, new SupplyChainValidation( - SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, - AppraisalStatus.Status.FAIL, - certificateList, - failureMsg.toString())); - } else { - chainCiMapping.put(ciSerial, ci); - } - } else if (ciV2.isRemoved()) { - if (!chainCiMapping.containsKey(ciSerial)) { - // error thrown, can't remove if it doesn't exist - fieldValidation = false; - failureMsg.append(String.format( - "%s attempted REMOVED with no prior instance.%n", - ciSerial)); - scv = deltaMapping.get(delta); - if (scv.getResult() != AppraisalStatus.Status.PASS) { - failureMsg.append(scv.getMessage()); + } else if (ciV2.isRemoved()) { + if (!chainCiMapping.containsKey(ciSerial)) { + // error thrown, can't remove if it doesn't exist + failureMsg.append(String.format( + "%s attempted REMOVED with no prior instance.%n", + ciSerial)); + scv = deltaMapping.get(delta); + if (scv.getResult() != AppraisalStatus.Status.PASS) { + failureMsg.append(scv.getMessage()); + } + deltaMapping.put(delta, new SupplyChainValidation( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + AppraisalStatus.Status.FAIL, + certificateList, + failureMsg.toString())); + } else { + chainCiMapping.remove(ciSerial); } - deltaMapping.put(delta, new SupplyChainValidation( - SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, - AppraisalStatus.Status.FAIL, - certificateList, - failureMsg.toString())); - } else { - chainCiMapping.remove(ciSerial); - } - } else if (ciV2.isAdded()) { - // ADDED - if (chainCiMapping.containsKey(ciSerial)) { - // error, shouldn't exist - fieldValidation = false; - failureMsg.append(String.format( - "%s was ADDED, the serial already exists.%n", - ciSerial)); - scv = deltaMapping.get(delta); - if (scv.getResult() != AppraisalStatus.Status.PASS) { - failureMsg.append(scv.getMessage()); + } else if (ciV2.isAdded()) { + // ADDED + if (chainCiMapping.containsKey(ciSerial)) { + // error, shouldn't exist + failureMsg.append(String.format( + "%s was ADDED, the serial already exists.%n", + ciSerial)); + scv = deltaMapping.get(delta); + if (scv.getResult() != AppraisalStatus.Status.PASS) { + failureMsg.append(scv.getMessage()); + } + deltaMapping.put(delta, new SupplyChainValidation( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + AppraisalStatus.Status.FAIL, + certificateList, + failureMsg.toString())); + } else { + // have to add in case later it is removed + chainCiMapping.put(ciSerial, ci); } - deltaMapping.put(delta, new SupplyChainValidation( - SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, - AppraisalStatus.Status.FAIL, - certificateList, - failureMsg.toString())); - } else { - // have to add in case later it is removed - chainCiMapping.put(ciSerial, ci); } } + } else { + // found a delta ci with no serial + // add to list + leftOvers.add(ci); } } @@ -1590,7 +1481,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator return resultMessage.toString(); } -// finish of some changes + /** * Checks if the issuer info of an attribute cert matches the supposed signing cert's * distinguished name. From acc022d7845c119840976af7d8f71d3680ccb421 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Wed, 20 Jan 2021 13:05:43 -0500 Subject: [PATCH 15/41] Finalized clean up. --- .../SupplyChainCredentialValidator.java | 71 +++++++++++++------ 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 96cdb323..ad2b2f4c 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -589,6 +589,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator final List origPcComponents) { boolean fieldValidation = true; StringBuilder resultMessage = new StringBuilder(); + String tempStringMessage = ""; List validOrigPcComponents = origPcComponents.stream() .filter(identifier -> identifier.getComponentManufacturer() != null && identifier.getComponentModel() != null) @@ -618,46 +619,72 @@ public final class SupplyChainCredentialValidator implements CredentialValidator resultMessage.append("There are errors with Delta " + "Component Statuses:\n"); List leftOverDeltas = new ArrayList<>(); - resultMessage.append(validateDeltaChain(deltaMapping, baseCompList, - leftOverDeltas, chainCertificates)); + List absentSerialNum = new ArrayList<>(); + tempStringMessage = validateDeltaChain(deltaMapping, baseCompList, + leftOverDeltas, absentSerialNum, chainCertificates); + + // check if there were any issues + if (!tempStringMessage.isEmpty()) { + resultMessage.append(tempStringMessage); + fieldValidation = false; + } // finished up List certificateList = null; SupplyChainValidation scv = null; - // go through the leaf and check the changes against the valid components - // forget modifying validOrigPcComponents - - // what wasn't handled by the serial number, - // not match by the serial number and the class type - // then the matching manufacturer and model - + // Ok, we went through valid non-empty serial values + // now do the rest, if there are more deltas and if there are any + // non-empty serial values for (ComponentIdentifier deltaCi : leftOverDeltas) { String classValue; ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) deltaCi; ComponentIdentifierV2 baseCiV2; boolean classFound; - for (ComponentIdentifier ci : baseCompList) { + for (ComponentIdentifier ci : absentSerialNum) { classValue = ciV2.getComponentClass().getClassValueString(); baseCiV2 = (ComponentIdentifierV2) ci; classFound = classValue.equals(baseCiV2.getComponentClass() .getClassValueString()); if (classFound) { if (isMatch(ciV2, baseCiV2)) { - LOGGER.error("Not Found and added"); + if (ciV2.isAdded()) { + // error + resultMessage.append("ADDED attempted with prior instance\n"); + } + if (ciV2.isModified()) { + // since the base list doesn't have this ci + // just add the delta + baseCompList.add(deltaCi); + } + // if it is a remove + // we do nothing because baseCompList doesn't have it } else { - LOGGER.error("Not Found and added"); + // it is an add + if (ciV2.isAdded()) { + baseCompList.add(deltaCi); + } } } else { // delta change to a class not there // is it an add? if (ciV2.isAdded()) { - LOGGER.error("Not Found and added"); + baseCompList.add(deltaCi); + } + + if (ciV2.isModified()) { + // error because you can't modify something + // that isn't here + resultMessage.append("MODIFIED attempted without prior instance\n"); + } + + if (ciV2.isRemoved()) { + // error because you can't remove something + // that isn't here + resultMessage.append("REMOVED attempted without prior instance\n"); } } } - // this needs to be removed. - baseCompList.add(deltaCi); } if (!fieldValidation) { @@ -705,13 +732,6 @@ public final class SupplyChainCredentialValidator implements CredentialValidator List subCompInfoList = allDeviceInfoComponents .stream().collect(Collectors.toList()); - subCompIdList.stream().forEach((ci) -> { - LOGGER.error(ci.toString()); - }); - - subCompInfoList.stream().forEach((ci) -> { - LOGGER.error(ci.toString()); - }); // Delta is the baseline for (ComponentInfo cInfo : allDeviceInfoComponents) { for (ComponentIdentifier cId : fullDeltaChainComponents) { @@ -1379,6 +1399,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator final Map deltaMapping, final List baseCompList, final List leftOvers, + final List absentSerials, final List chainCertificates) { StringBuilder resultMessage = new StringBuilder(); List noneSerialValues = new ArrayList<>(); @@ -1390,7 +1411,11 @@ public final class SupplyChainCredentialValidator implements CredentialValidator // map the components throughout the chain Map chainCiMapping = new HashMap<>(); baseCompList.stream().forEach((ci) -> { - chainCiMapping.put(ci.getComponentSerial().toString(), ci); + if (!noneSerialValues.contains(ci.getComponentSerial().toString())) { + chainCiMapping.put(ci.getComponentSerial().toString(), ci); + } else { + absentSerials.add(ci); + } }); String ciSerial; From 55890964433cc916d77164ead2e539f901ae0d17 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Wed, 20 Jan 2021 13:23:51 -0500 Subject: [PATCH 16/41] Cleaned up some stuff I found during code compare in github. --- .../AbstractAttestationCertificateAuthority.java | 2 +- .../certificate/attributes/ComponentIdentifier.java | 13 +------------ .../java/hirs/data/persist/info/ComponentInfo.java | 3 +-- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java index 3d72d42e..6d62d414 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java @@ -806,7 +806,7 @@ public abstract class AbstractAttestationCertificateAuthority support.setTagId(tagId); this.referenceManifestManager.save(support); } else { - LOG.info("Client provided Support RIM already loaded in database."); + LOG.info("Client provided Support RIM already loaded in database."); if (dbBaseRim != null) { support.setPlatformManufacturer(dbBaseRim.getPlatformManufacturer()); support.setPlatformModel(dbBaseRim.getPlatformModel()); diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentIdentifier.java b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentIdentifier.java index b98d325a..2e9607b8 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentIdentifier.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentIdentifier.java @@ -288,18 +288,7 @@ public class ComponentIdentifier { return Collections.unmodifiableList(addresses); } -// -// @Override -// public boolean equals(Object o) { -// if (this == o) return true; -// if (o == null || getClass() != o.getClass()) return false; -// ComponentIdentifier that = (ComponentIdentifier) o; -// return componentManufacturer.equals(that.componentManufacturer) -// && componentModel.equals(that.componentModel) && Objects.equals -// (componentSerial, that.componentSerial) && Objects.equals(componentRevision, -// that.componentRevision); -// } -// + @Override public int hashCode() { return Objects.hash(componentManufacturer, componentModel, diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/info/ComponentInfo.java b/HIRS_Utils/src/main/java/hirs/data/persist/info/ComponentInfo.java index 97377871..1805a13c 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/info/ComponentInfo.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/info/ComponentInfo.java @@ -111,8 +111,7 @@ public class ComponentInfo implements Serializable { componentManufacturer, componentModel, componentSerial, - componentRevision - )); + componentRevision)); this.componentManufacturer = componentManufacturer.trim(); this.componentModel = componentModel.trim(); if (componentSerial != null) { From 653bfddc6dd7be11c4fc694adbe3fa6d93af8ac3 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Thu, 21 Jan 2021 07:40:55 -0500 Subject: [PATCH 17/41] Updated some code and took out things that didin't need to be in the official build for unit tests --- .../persist/certificate/attributes/ComponentClass.java | 2 +- .../validation/SupplyChainCredentialValidatorTest.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentClass.java b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentClass.java index 834b82cf..91669b25 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentClass.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/attributes/ComponentClass.java @@ -84,7 +84,7 @@ public class ComponentClass { */ public ComponentClass(final Path componentClassPath, final String componentIdentifier) { this(componentClassPath, getComponentIntValue(componentIdentifier)); - if (componentIdentifier.contains("#")) { + if (componentIdentifier != null && componentIdentifier.contains("#")) { this.classValueString = componentIdentifier.replaceAll("#", ""); } else { this.classValueString = componentIdentifier; diff --git a/HIRS_Utils/src/test/java/hirs/validation/SupplyChainCredentialValidatorTest.java b/HIRS_Utils/src/test/java/hirs/validation/SupplyChainCredentialValidatorTest.java index 75309c2b..77a07fb6 100644 --- a/HIRS_Utils/src/test/java/hirs/validation/SupplyChainCredentialValidatorTest.java +++ b/HIRS_Utils/src/test/java/hirs/validation/SupplyChainCredentialValidatorTest.java @@ -1121,7 +1121,7 @@ public class SupplyChainCredentialValidatorTest { + "Platform serial did not match\n" + "There are unmatched components:\n" + "Manufacturer=Intel, Model=platform2018," - + " Serial=BQKP52840678, Revision=1.0\n"; + + " Serial=BQKP52840678, Revision=1.0;\n"; AppraisalStatus result = supplyChainCredentialValidator.validatePlatformCredentialAttributes( @@ -1767,7 +1767,7 @@ public class SupplyChainCredentialValidatorTest { Assert.assertEquals(result.getMessage(), "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"); + + " Revision=Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz;\n"); platformCredential = setupMatchingPlatformCredential(deviceInfoReport); result = SupplyChainCredentialValidator @@ -1823,7 +1823,7 @@ public class SupplyChainCredentialValidatorTest { deviceInfoReport); Assert.assertEquals(result.getAppStatus(), AppraisalStatus.Status.FAIL); Assert.assertEquals(result.getMessage(), "There are unmatched components:\n" - + "Manufacturer=ACME, Model=TNT, Serial=2, Revision=1.1\n"); + + "Manufacturer=ACME, Model=TNT, Serial=2, Revision=1.1;\n"); } /** @@ -1887,7 +1887,7 @@ public class SupplyChainCredentialValidatorTest { Assert.assertEquals(result.getMessage(), "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"); + + " Revision=Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz;\n"); platformCredential = setupMatchingPlatformCredential(deviceInfoReport); result = SupplyChainCredentialValidator @@ -2222,7 +2222,7 @@ public class SupplyChainCredentialValidatorTest { "There are unmatched components:\n" + "Manufacturer=Intel Corporation, Model=82580 " + "Gigabit Network Connection-faulty, " - + "Serial=90:e2:ba:31:83:10, Revision=\n"); + + "Serial=90:e2:ba:31:83:10, Revision=;\n"); } /** From 8d6a697a236040929d724f726d4a233516161099 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Thu, 28 Jan 2021 08:08:12 -0500 Subject: [PATCH 18/41] Removed some unnecessary comments --- .../java/hirs/validation/SupplyChainCredentialValidator.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index ad2b2f4c..0cac1b38 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -632,8 +632,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator // finished up List certificateList = null; SupplyChainValidation scv = null; - // Ok, we went through valid non-empty serial values - // now do the rest, if there are more deltas and if there are any + // non-empty serial values for (ComponentIdentifier deltaCi : leftOverDeltas) { String classValue; @@ -667,7 +666,6 @@ public final class SupplyChainCredentialValidator implements CredentialValidator } } else { // delta change to a class not there - // is it an add? if (ciV2.isAdded()) { baseCompList.add(deltaCi); } From 447c817839ad31f6cfc7ebfc90ceb59abb21a87b Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Tue, 2 Feb 2021 12:57:55 -0500 Subject: [PATCH 19/41] Updated the lists for the left over components. --- .../java/hirs/validation/SupplyChainCredentialValidator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 0cac1b38..d7302e46 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -1427,6 +1427,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator certificateList.add(delta); for (ComponentIdentifier ci : delta.getComponentIdentifiers()) { + LOGGER.error("This is the serial {}", ci.getComponentSerial().toString()); if (!noneSerialValues.contains(ci.getComponentSerial().toString())) { if (ci.isVersion2()) { ciSerial = ci.getComponentSerial().toString(); @@ -1501,6 +1502,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator } baseCompList.clear(); baseCompList.addAll(chainCiMapping.values()); + baseCompList.addAll(absentSerials); return resultMessage.toString(); } From 4999c9668514997e1c3fa0cb6ae2bea7cc159157 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Fri, 5 Feb 2021 16:10:15 -0500 Subject: [PATCH 20/41] Updated code to correct situations that were not linking up with properly for delta and platform certificate component validation. --- ...stractAttestationCertificateAuthority.java | 9 ++++++- .../util/CertificateStringMapBuilder.java | 13 +++++++++ .../WEB-INF/jsp/certificate-details.jsp | 2 +- .../SupplyChainCredentialValidator.java | 27 ++++++++++++------- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java index 1ead2286..aba6761a 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java @@ -408,7 +408,14 @@ public abstract class AbstractAttestationCertificateAuthority RSAPublicKey ekPub = parsePublicKey(claim.getEkPublicArea().toByteArray()); AppraisalStatus.Status validationResult = AppraisalStatus.Status.FAIL; - validationResult = doSupplyChainValidation(claim, ekPub); + try { + validationResult = doSupplyChainValidation(claim, ekPub); + } catch (Exception ex) { + for (StackTraceElement ste : ex.getStackTrace()) { + LOG.error(ste.toString()); + } + } + if (validationResult == AppraisalStatus.Status.PASS) { RSAPublicKey akPub = parsePublicKey(claim.getAkPublicArea().toByteArray()); byte[] nonce = generateRandomBytes(NONCE_LENGTH); 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 34f75bca..17908de8 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 @@ -303,6 +303,7 @@ public final class CertificateStringMapBuilder { .select(certificateManager) .byEntityId(uuid) .getCertificate(); + if (certificate != null) { data.putAll(getGeneralCertificateInfo(certificate, certificateManager)); data.put("credentialType", certificate.getCredentialType()); @@ -357,6 +358,7 @@ public final class CertificateStringMapBuilder { data.put("x509Version", certificate.getX509CredentialVersion()); //CPSuri data.put("CPSuri", certificate.getCPSuri()); + if (!certificate.getComponentFailures().isEmpty()) { data.put("failures", certificate.getComponentFailures()); } @@ -398,6 +400,17 @@ public final class CertificateStringMapBuilder { }); data.put("chainCertificates", chainCertificates); + + if (!certificate.isBase()) { + for (PlatformCredential pc : chainCertificates) { + if (pc.isBase()) { + if (!pc.getComponentFailures().isEmpty()) { + data.put("failures", pc.getComponentFailures()); + } + break; + } + } + } } } else { String notFoundMessage = "Unable to find Platform Certificate " diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/certificate-details.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/certificate-details.jsp index 8240ad33..c9711c0b 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/certificate-details.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/certificate-details.jsp @@ -614,7 +614,7 @@
- +
diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index d7302e46..907bfa09 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -656,6 +656,9 @@ public final class SupplyChainCredentialValidator implements CredentialValidator // just add the delta baseCompList.add(deltaCi); } + if (ciV2.isRemoved()) { + LOGGER.error("Made it to this!"); + } // if it is a remove // we do nothing because baseCompList doesn't have it } else { @@ -753,20 +756,21 @@ public final class SupplyChainCredentialValidator implements CredentialValidator if (!subCompIdList.isEmpty()) { for (ComponentIdentifier ci : subCompIdList) { ciV2 = (ComponentIdentifierV2) ci; - invalidPcIds.append(String.format("%s;", - ciV2.getComponentClass().getClassValueString())); + invalidPcIds.append(String.format("%d;", + ciV2.hashCode())); } } if (!subCompInfoList.isEmpty()) { for (ComponentInfo ci : subCompInfoList) { - invalidDeviceInfo.append(String.format("%s;", - ci.getComponentClass())); + LOGGER.error("For subComInfoList -> {}", ci.getComponentSerial()); + invalidDeviceInfo.append(String.format("%d;", + ci.hashCode())); } } return String.format("DEVICEINFO=%s?COMPID=%s%d", - invalidDeviceInfo.toString(), invalidPcIds.toString(), subCompInfoList.size()); + invalidDeviceInfo.toString(), invalidPcIds.toString(), subCompIdList.size()); } /** @@ -1422,12 +1426,13 @@ public final class SupplyChainCredentialValidator implements CredentialValidator // go through the leaf and check the changes against the valid components // forget modifying validOrigPcComponents for (PlatformCredential delta : chainCertificates) { + LOGGER.error(delta.getSerialNumber()); StringBuilder failureMsg = new StringBuilder(); certificateList = new ArrayList<>(); certificateList.add(delta); for (ComponentIdentifier ci : delta.getComponentIdentifiers()) { - LOGGER.error("This is the serial {}", ci.getComponentSerial().toString()); + LOGGER.error(ci.getComponentSerial()); if (!noneSerialValues.contains(ci.getComponentSerial().toString())) { if (ci.isVersion2()) { ciSerial = ci.getComponentSerial().toString(); @@ -1442,7 +1447,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator "%s attempted MODIFIED with no prior instance.%n", ciSerial)); scv = deltaMapping.get(delta); - if (scv.getResult() != AppraisalStatus.Status.PASS) { + if (scv != null + && scv.getResult() != AppraisalStatus.Status.PASS) { failureMsg.append(scv.getMessage()); } deltaMapping.put(delta, new SupplyChainValidation( @@ -1458,7 +1464,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator "%s attempted REMOVED with no prior instance.%n", ciSerial)); scv = deltaMapping.get(delta); - if (scv.getResult() != AppraisalStatus.Status.PASS) { + if (scv != null + && scv.getResult() != AppraisalStatus.Status.PASS) { failureMsg.append(scv.getMessage()); } deltaMapping.put(delta, new SupplyChainValidation( @@ -1477,7 +1484,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator "%s was ADDED, the serial already exists.%n", ciSerial)); scv = deltaMapping.get(delta); - if (scv.getResult() != AppraisalStatus.Status.PASS) { + if (scv != null + && scv.getResult() != AppraisalStatus.Status.PASS) { failureMsg.append(scv.getMessage()); } deltaMapping.put(delta, new SupplyChainValidation( @@ -1488,6 +1496,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator } else { // have to add in case later it is removed chainCiMapping.put(ciSerial, ci); + LOGGER.error("This should be what happens"); } } } From 7b79ceb07a37ed400d7bc511336da9587deab9e0 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Mon, 8 Feb 2021 14:25:10 -0500 Subject: [PATCH 21/41] Found the issue with the component being removed that doesn't have a proper serial number and adding one with it. The code was revalidating the base in the attributes enabled flag. This was unncessary. --- ...stractAttestationCertificateAuthority.java | 7 +-- .../SupplyChainValidationServiceImpl.java | 54 ++++++++----------- .../SupplyChainCredentialValidator.java | 8 +-- 3 files changed, 28 insertions(+), 41 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java index aba6761a..3652ee32 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java @@ -90,9 +90,7 @@ import java.security.spec.RSAPublicKeySpec; import java.util.Arrays; import java.util.Calendar; import java.util.Date; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -411,9 +409,7 @@ public abstract class AbstractAttestationCertificateAuthority try { validationResult = doSupplyChainValidation(claim, ekPub); } catch (Exception ex) { - for (StackTraceElement ste : ex.getStackTrace()) { - LOG.error(ste.toString()); - } + LOG.error(ex.getMessage()); } if (validationResult == AppraisalStatus.Status.PASS) { @@ -455,7 +451,6 @@ public abstract class AbstractAttestationCertificateAuthority // attempt to find platform credentials to validate Set platformCredentials = parsePcsFromIdentityClaim(claim, endorsementCredential); - Map correctedMap = new HashMap<>(); // Parse and save device info Device device = processDeviceInfo(claim); 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 7ec2718a..3351a9c1 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -188,9 +188,9 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe int result = baseCredential.getBeginValidity() .compareTo(pc.getBeginValidity()); if (!pc.isBase() && (result > 0)) { - pcErrorMessage = String.format("%s%s%n", pcErrorMessage, - "Delta Certificate's validity " - + "date is not after Base"); + pcErrorMessage = String.format("%s%s%n", pcErrorMessage, + "Delta Certificate's validity " + + "date is not after Base"); break; } } @@ -219,39 +219,30 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe if (platformScv != null) { aes.addAll(platformScv.getCertificatesUsed()); } - // ok, still want to validate the base credential attributes - attributeScv = validatePlatformCredentialAttributes( - baseCredential, device.getDeviceInfo(), ec); - - if (attributeScv.getResult() != FAIL) { - Iterator it = pcs.iterator(); - String attrErrorMessage = ""; - while (it.hasNext()) { - PlatformCredential pc = it.next(); - if (pc != null) { - if (!pc.isBase() && attributeScv.getResult() != FAIL) { - attributeScv = validateDeltaPlatformCredentialAttributes( - pc, device.getDeviceInfo(), - baseCredential, deltaMapping); - if (attributeScv.getResult() == FAIL) { - attrErrorMessage = String.format("%s%s%n", attrErrorMessage, - attributeScv.getMessage()); - } + Iterator it = pcs.iterator(); + String attrErrorMessage = ""; + 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 (!attrErrorMessage.isEmpty()) { - //combine platform and platform attributes - validations.remove(platformScv); + } + if (!attrErrorMessage.isEmpty()) { + //combine platform and platform attributes + validations.remove(platformScv); + if (platformScv != null) { validations.add(new SupplyChainValidation( platformScv.getValidationType(), attributeScv.getResult(), aes, attributeScv.getMessage())); } - } else { - validations.remove(platformScv); - // base platform has errors - validations.add(new SupplyChainValidation(platformScv.getValidationType(), - attributeScv.getResult(), aes, attributeScv.getMessage())); } } @@ -261,6 +252,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe validations.add(validateFirmware(device, policy.getPcrPolicy())); } + LOGGER.error("The service finished and now summarizing"); // Generate validation summary, save it, and return it. SupplyChainValidationSummary summary = new SupplyChainValidationSummary(device, validations); @@ -784,9 +776,9 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe * already queried for that organization (which prevents infinite loops on * certs with an identical subject and issuer org) * - * @param credential the credential whose CA chain should be retrieved + * @param credential the credential whose CA chain should be retrieved * @param previouslyQueriedSubjects a list of organizations to refrain - * from querying + * from querying * @return a Set containing all relevant CA credentials to the given * certificate's organization */ diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 907bfa09..6d06e573 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -318,6 +318,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator final Map deltaMapping) { String message; + LOGGER.error("Starting the method validateDeltaPlatformCredentialAttributes"); + // this needs to be a loop for all deltas, link to issue #110 // check that they don't have the same serial number for (PlatformCredential delta : deltaMapping.keySet()) { @@ -340,6 +342,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator } } + LOGGER.error("This is before validateDeltaAttributesChainV2p0"); // parse out the provided delta and its specific chain. List origPcComponents = new LinkedList<>(basePlatformCredential.getComponentIdentifiers()); @@ -657,7 +660,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator baseCompList.add(deltaCi); } if (ciV2.isRemoved()) { - LOGGER.error("Made it to this!"); + baseCompList.remove(ciV2); } // if it is a remove // we do nothing because baseCompList doesn't have it @@ -1426,13 +1429,11 @@ public final class SupplyChainCredentialValidator implements CredentialValidator // go through the leaf and check the changes against the valid components // forget modifying validOrigPcComponents for (PlatformCredential delta : chainCertificates) { - LOGGER.error(delta.getSerialNumber()); StringBuilder failureMsg = new StringBuilder(); certificateList = new ArrayList<>(); certificateList.add(delta); for (ComponentIdentifier ci : delta.getComponentIdentifiers()) { - LOGGER.error(ci.getComponentSerial()); if (!noneSerialValues.contains(ci.getComponentSerial().toString())) { if (ci.isVersion2()) { ciSerial = ci.getComponentSerial().toString(); @@ -1496,7 +1497,6 @@ public final class SupplyChainCredentialValidator implements CredentialValidator } else { // have to add in case later it is removed chainCiMapping.put(ciSerial, ci); - LOGGER.error("This should be what happens"); } } } From 69cd06df3b501fab10e48d450d57ef35a84d9e35 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Tue, 9 Feb 2021 06:54:31 -0500 Subject: [PATCH 22/41] Merging error didn't include the update to Assert.State --- .../main/java/hirs/data/persist/info/ComponentInfo.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/info/ComponentInfo.java b/HIRS_Utils/src/main/java/hirs/data/persist/info/ComponentInfo.java index 1805a13c..4febbd67 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/info/ComponentInfo.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/info/ComponentInfo.java @@ -111,7 +111,9 @@ public class ComponentInfo implements Serializable { componentManufacturer, componentModel, componentSerial, - componentRevision)); + componentRevision), + "ComponentInfo: manufacturer and/or " + + "model can not be null"); this.componentManufacturer = componentManufacturer.trim(); this.componentModel = componentModel.trim(); if (componentSerial != null) { @@ -143,8 +145,9 @@ public class ComponentInfo implements Serializable { componentManufacturer, componentModel, componentSerial, - componentRevision - )); + componentRevision), + "ComponentInfo: manufacturer and/or " + + "model can not be null"); this.componentManufacturer = componentManufacturer.trim(); this.componentModel = componentModel.trim(); if (componentSerial != null) { From a4d639925e2cce3653d53efad100e25ff7832a08 Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Fri, 20 Nov 2020 20:56:26 -0500 Subject: [PATCH 23/41] Frontend changes: download link to validation report --- .../webapp/WEB-INF/jsp/validation-reports.jsp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp index 530d4f3c..d3663ac8 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp @@ -93,7 +93,10 @@ { // TODO render a link to a device details page, // passing the device.id - data: 'device.name' + data: 'device.name', + render: function (data, type, full, meta) { + return createDownloadLink(full); + } }, { data: 'id', @@ -126,6 +129,16 @@ dataTable.order([1, 'desc']).draw(); //order by createTime }); + /** + * This method builds a url to download the device validation report. + */ + function createDownloadLink(full) { + return full.device.name + ' ' + + '' + + ''; + } + /** * Gets HTML to display (icon tag) for the specified validation type. * If a validation for the requested type is not found, an empty From 18ec7d4a5b4a35af853075e4b56db33c4fae1792 Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Wed, 25 Nov 2020 13:11:17 -0500 Subject: [PATCH 24/41] Controller changes: Pull platform credential for device and parse info --- .../ValidationReportsPageController.java | 33 ++++++++++++++++++- .../webapp/WEB-INF/jsp/validation-reports.jsp | 2 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java index e95d4ca3..bdafe79d 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java @@ -6,6 +6,9 @@ import hirs.attestationca.portal.datatables.OrderedListQueryDataTableAdapter; import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.params.NoPageParams; import hirs.data.persist.certificate.Certificate; +import hirs.data.persist.certificate.PlatformCredential; +import hirs.data.persist.certificate.attributes.ComponentIdentifier; +import hirs.persist.CertificateManager; import org.apache.logging.log4j.Logger; import static org.apache.logging.log4j.LogManager.getLogger; import org.hibernate.Criteria; @@ -16,6 +19,7 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; @@ -25,6 +29,10 @@ import hirs.data.persist.SupplyChainValidationSummary; import hirs.persist.CriteriaModifier; import hirs.persist.CrudManager; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.UUID; + /** * Controller for the Validation Reports page. */ @@ -33,6 +41,7 @@ import hirs.persist.CrudManager; public class ValidationReportsPageController extends PageController { private final CrudManager supplyChainValidatorSummaryManager; + private final CertificateManager certificateManager; private static final Logger LOGGER = getLogger(ValidationReportsPageController.class); @@ -42,9 +51,11 @@ public class ValidationReportsPageController extends PageController supplyChainValidatorSummaryManager) { + final CrudManager supplyChainValidatorSummaryManager, + final CertificateManager certificateManager) { super(VALIDATION_REPORTS); this.supplyChainValidatorSummaryManager = supplyChainValidatorSummaryManager; + this.certificateManager = certificateManager; } /** @@ -97,4 +108,24 @@ public class ValidationReportsPageController extends PageController(records, input); } + + @RequestMapping(value = "download", method = RequestMethod.GET) + public void download(@RequestParam final String id, + final HttpServletResponse response) { + LOGGER.info("Downloading validation report for " + id); + UUID uuid = UUID.fromString(id); + PlatformCredential pc = PlatformCredential.select(certificateManager).byDeviceId(uuid).getCertificate(); + LOGGER.info("Verified manufacturer: " + pc.getManufacturer()); + LOGGER.info("Model: " + pc.getModel()); + LOGGER.info("SN: " + pc.getChassisSerialNumber()); + LOGGER.info("Verification date: " + pc.getBeginValidity()); + if (pc.getComponentIdentifiers() != null && + pc.getComponentIdentifiers().size() > 0) { + for (ComponentIdentifier ci : pc.getComponentIdentifiers()) { + LOGGER.info("Manufacturer ID: " + ci.getComponentManufacturerId().toString() + + "\nModel: " + ci.getComponentModel().getString() + + "\nRevision: " + ci.getComponentRevision().getString()); + } + } + } } diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp index d3663ac8..ce09ed94 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp @@ -134,7 +134,7 @@ */ function createDownloadLink(full) { return full.device.name + ' ' + - '' + ''; } From bb6cbfe87174038198ee0e84feecc04b30b011d8 Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Mon, 7 Dec 2020 16:31:26 -0500 Subject: [PATCH 25/41] Front end change: display modal dialog for user input on download link click. --- .../ValidationReportsPageController.java | 18 +++++++--- .../webapp/WEB-INF/jsp/validation-reports.jsp | 33 ++++++++++++++++--- .../webapp/WEB-INF/tags/download-info.tag | 14 ++++++++ 3 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/tags/download-info.tag diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java index bdafe79d..c1548f77 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java @@ -29,8 +29,9 @@ import hirs.data.persist.SupplyChainValidationSummary; import hirs.persist.CriteriaModifier; import hirs.persist.CrudManager; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.util.ArrayList; +import java.util.Enumeration; import java.util.UUID; /** @@ -109,10 +110,17 @@ public class ValidationReportsPageController extends PageController(records, input); } - @RequestMapping(value = "download", method = RequestMethod.GET) + @RequestMapping(value = "download", method = RequestMethod.POST) public void download(@RequestParam final String id, + final HttpServletRequest request, final HttpServletResponse response) { + LOGGER.info("Downloading validation report for " + id); + Enumeration parameters = request.getParameterNames(); + while (parameters.hasMoreElements()) { + String parameter = (String) parameters.nextElement(); + LOGGER.info(parameter + ": " + request.getParameter(parameter)); + } UUID uuid = UUID.fromString(id); PlatformCredential pc = PlatformCredential.select(certificateManager).byDeviceId(uuid).getCertificate(); LOGGER.info("Verified manufacturer: " + pc.getManufacturer()); @@ -122,8 +130,10 @@ public class ValidationReportsPageController extends PageController 0) { for (ComponentIdentifier ci : pc.getComponentIdentifiers()) { - LOGGER.info("Manufacturer ID: " + ci.getComponentManufacturerId().toString() + - "\nModel: " + ci.getComponentModel().getString() + + if (ci.getComponentManufacturerId() != null) { + LOGGER.info("Manufacturer ID: " + ci.getComponentManufacturerId().toString()); + } + LOGGER.info("\nModel: " + ci.getComponentModel().getString() + "\nRevision: " + ci.getComponentRevision().getString()); } } diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp index ce09ed94..85ffeda2 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp @@ -133,10 +133,35 @@ * This method builds a url to download the device validation report. */ function createDownloadLink(full) { - return full.device.name + ' ' + - '' + - ''; + var device = full.device; + var html = '
' + + device.name + + '' + + '' + + '' + + '' + + '
'; + return html; } /** diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/tags/download-info.tag b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/tags/download-info.tag new file mode 100644 index 00000000..f14e33e0 --- /dev/null +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/tags/download-info.tag @@ -0,0 +1,14 @@ +<%@tag description="download icon that opens modal dialog with form" pageEncoding="UTF-8"%> + +<%@attribute name="id"%> +<%@attribute name="label"%> +<%@attribute name="customButtons" fragment="true" required="false"%> + +<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %> + + + + + + + \ No newline at end of file From 3cd9e06f97b2dbb74b6a482df18c2bc49247f7bc Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Wed, 23 Dec 2020 10:08:25 -0500 Subject: [PATCH 26/41] Add user input fields to modal dialog. Handle user input, collect device report data, and write to local file. --- .../ValidationReportsPageController.java | 72 ++++++++++++++++--- .../webapp/WEB-INF/jsp/validation-reports.jsp | 6 +- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java index c1548f77..039f50bb 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java @@ -8,6 +8,7 @@ import hirs.attestationca.portal.page.params.NoPageParams; import hirs.data.persist.certificate.Certificate; import hirs.data.persist.certificate.PlatformCredential; import hirs.data.persist.certificate.attributes.ComponentIdentifier; +import hirs.data.persist.certificate.attributes.V2.ComponentIdentifierV2; import hirs.persist.CertificateManager; import org.apache.logging.log4j.Logger; import static org.apache.logging.log4j.LogManager.getLogger; @@ -31,6 +32,9 @@ import hirs.persist.CrudManager; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; import java.util.Enumeration; import java.util.UUID; @@ -49,6 +53,7 @@ public class ValidationReportsPageController extends PageController(records, input); } + /** + * This method handles downloading a validation report. The report will contain the + * following data: + * - Company devices where shipped from + * - Contract# + * - Report for Date range (default to current date) + * -Verified Manufacturer is the Platform Vendor + * - Model is the Platform Model + * - SN is the Chassis SN + * - Verification Data is the not before time on the Attestation Certificate + * - Component Status column is 8 component classes names listed above + * (Component Status data is taken from the pass/fail status of the report summary) + * - Device Status is the overall pass/fail of the report summary + * @param id of the validated device + * @param deviceName name of the validated device + * @param request object + * @param response object + * @throws IOException thrown by BufferedWriter object + */ @RequestMapping(value = "download", method = RequestMethod.POST) public void download(@RequestParam final String id, + @RequestParam final String deviceName, final HttpServletRequest request, - final HttpServletResponse response) { + final HttpServletResponse response) throws IOException { LOGGER.info("Downloading validation report for " + id); + response.setHeader("Content-Type", "text/plain"); + response.setHeader("Content-Disposition", + "attachment;filename=\"" + deviceName + "_validation_report.txt\""); + BufferedWriter bufferedWriter = new BufferedWriter( + new OutputStreamWriter(response.getOutputStream(), "UTF-8")); Enumeration parameters = request.getParameterNames(); while (parameters.hasMoreElements()) { String parameter = (String) parameters.nextElement(); + bufferedWriter.append(parameter + ": " + request.getParameter(parameter) + "\n"); LOGGER.info(parameter + ": " + request.getParameter(parameter)); } +// String columnHeaders = "Company, Contract Number, Date Range, Verified Manufacturer, " +// + "Model, SN, Verification Date, Component Statuses, Device Status"; +// bufferedWriter.append(columnHeaders + "\n"); +// LOGGER.info(columnHeaders); UUID uuid = UUID.fromString(id); - PlatformCredential pc = PlatformCredential.select(certificateManager).byDeviceId(uuid).getCertificate(); + PlatformCredential pc = PlatformCredential.select(certificateManager) + .byDeviceId(uuid).getCertificate(); + bufferedWriter.append("Verified manufacturer: " + pc.getManufacturer() + "\n"); + bufferedWriter.append("Model: " + pc.getModel() + "\n"); + bufferedWriter.append("SN: " + pc.getChassisSerialNumber() + "\n"); + bufferedWriter.append("Verification date: " + pc.getBeginValidity() + "\n"); LOGGER.info("Verified manufacturer: " + pc.getManufacturer()); LOGGER.info("Model: " + pc.getModel()); LOGGER.info("SN: " + pc.getChassisSerialNumber()); LOGGER.info("Verification date: " + pc.getBeginValidity()); - if (pc.getComponentIdentifiers() != null && - pc.getComponentIdentifiers().size() > 0) { + if (pc.getComponentIdentifiers() != null + && pc.getComponentIdentifiers().size() > 0) { for (ComponentIdentifier ci : pc.getComponentIdentifiers()) { - if (ci.getComponentManufacturerId() != null) { - LOGGER.info("Manufacturer ID: " + ci.getComponentManufacturerId().toString()); + if (ci instanceof ComponentIdentifierV2) { + bufferedWriter.append(((ComponentIdentifierV2) ci).getComponentClass() + + "\nComponent status: " + + ((ComponentIdentifierV2) ci).getAttributeStatus() + "\n"); + LOGGER.info(((ComponentIdentifierV2) ci).getComponentClass() + + "\nComponent status: " + + ((ComponentIdentifierV2) ci).getAttributeStatus()); + } else { + bufferedWriter.append("Platform Components" + "\n"); + LOGGER.info("Platform Components"); } - LOGGER.info("\nModel: " + ci.getComponentModel().getString() + - "\nRevision: " + ci.getComponentRevision().getString()); + bufferedWriter.append("Component manufacturer : " + + ci.getComponentManufacturer().getString() + + "\nComponent model: " + ci.getComponentModel().getString() + + "\nComponent revision: " + ci.getComponentRevision().getString() + "\n"); + LOGGER.info("Component manufacturer : " + + ci.getComponentManufacturer().getString() + + "\nComponent model: " + ci.getComponentModel().getString() + + "\nComponent revision: " + ci.getComponentRevision().getString()); } } + + bufferedWriter.flush(); } } diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp index 85ffeda2..f811c998 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp @@ -134,7 +134,9 @@ */ function createDownloadLink(full) { var device = full.device; - var html = '
' + + var deviceStatus = full.overallValidationResult; + var html = '' + device.name + '' + '' + @@ -149,6 +151,8 @@ '' + '' + '' + + '' + '
' + '