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/23] 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 02ca86935..b4060661c 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent String.format("%s%n%s", platformScv.getMessage(), attributeScv.getMessage()))); } - componentFailures = updateUnmatchedComponents( - attributeScv.getMessage()); } pc.setDevice(device); @@ -259,10 +263,6 @@ public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent // 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 @@ private SupplyChainValidation validateDeltaPlatformCredentialAttributes( 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 9f3b4f08d..80f428e81 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 ModelAndView initPage(@PathVariable("certificateType") final String certi return mav; } - /** - * TODO - * 1. add flag for rim validation dependent on pc attribute flag DONE - * 2. create tpmbaseline on upload of rimel file (DONE?) - * a. add device id? though one won't exist yet - * 3. validation - * a. looks for baseline - * b. if it doesn't find one, looks for rim - * a. creates baseline if it exists - * c. validates after reading rimel, if it finds one. - */ /** * Queries for the list of Certificates and returns a data table response 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 60c7a734a..60041acaf 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,7 +340,11 @@ public static HashMap getPlatformInformation(final UUID uuid, //CPSuri data.put("CPSuri", certificate.getCPSuri()); //component failure - data.put("failures", 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 PlatformConfiguration platformConfiguration = certificate.getPlatformConfiguration(); 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 ade46dc5a..dd5ddfc57 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/AppraisalStatus.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/AppraisalStatus.java @@ -32,6 +32,7 @@ public enum Status { private Status appStatus; private String message; + private String additionalInfo; /** * Default constructor. Set appraisal status and description. @@ -43,6 +44,20 @@ public AppraisalStatus(final Status appStatus, final String message) { this.message = message; } + /** + * Default constructor. Set appraisal status and description. + * @param appStatus status of appraisal + * @param message description of result + * @param additionalInfo any additional information needed to + * be passed on + */ + public AppraisalStatus(final Status appStatus, final String message, + final String additionalInfo) { + this.appStatus = appStatus; + this.message = message; + this.additionalInfo = additionalInfo; + } + /** * Get appraisal status. * @return appraisal status @@ -74,4 +89,20 @@ public String getMessage() { public void setMessage(final String message) { this.message = message; } + + /** + * Getter for additional information during validation. + * @return string of additional information + */ + public String getAdditionalInfo() { + return additionalInfo; + } + + /** + * Setter for any additional information. + * @param additionalInfo the string of additional information + */ + public void setAdditionalInfo(final String additionalInfo) { + this.additionalInfo = additionalInfo; + } } 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 491daf97f..a8997f481 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 @@ -47,6 +47,7 @@ public class ComponentClass { private String category; private String component; private int componentIdentifier; + private String classValueString; /** * Default class constructor. @@ -83,6 +84,7 @@ public ComponentClass(final String componentIdentifier) { */ public ComponentClass(final Path componentClassPath, final String componentIdentifier) { this(componentClassPath, getComponentIntValue(componentIdentifier)); + this.classValueString = componentIdentifier; } /** @@ -142,6 +144,14 @@ public final int getValue() { return componentIdentifier; } + /** + * Getter for the Component Class Value as a string. + * @return String representation of the class. + */ + public final String getClassValueString() { + return classValueString; + } + /** * This is the main way this class will be referenced and how it * will be displayed on the portal. 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 8a493e16d..97377871b 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 @@ -46,6 +46,10 @@ public class ComponentInfo implements Serializable { @Column private String componentRevision; + @XmlElement + @Column + private String componentClass; + /** * Get the Component's Manufacturer. * @return the Component's Manufacturer @@ -78,6 +82,14 @@ public String getComponentRevision() { return componentRevision; } + /** + * Get the Component's Class Registry. + * @return the Component's Class + */ + public String getComponentClass() { + return componentClass; + } + /** * Default constructor required by Hibernate. */ @@ -115,6 +127,45 @@ public ComponentInfo(final String componentManufacturer, } } + /** + * Constructor. + * @param componentManufacturer Component Manufacturer (must not be null) + * @param componentModel Component Model (must not be null) + * @param componentSerial Component Serial Number (can be null) + * @param componentRevision Component Revision or Version (can be null) + * @param componentClass Component Class (can be null) + */ + public ComponentInfo(final String componentManufacturer, + final String componentModel, + final String componentSerial, + final String componentRevision, + final String componentClass) { + Assert.state(isComplete( + componentManufacturer, + componentModel, + componentSerial, + componentRevision + )); + this.componentManufacturer = componentManufacturer.trim(); + this.componentModel = componentModel.trim(); + if (componentSerial != null) { + this.componentSerial = componentSerial.trim(); + } else { + this.componentSerial = StringUtils.EMPTY; + } + if (componentRevision != null) { + this.componentRevision = componentRevision.trim(); + } else { + this.componentRevision = StringUtils.EMPTY; + } + + if (componentClass != null) { + this.componentClass = componentClass; + } else { + this.componentClass = StringUtils.EMPTY; + } + } + /** * Determines whether the given properties represent a * ComponentInfo that will be useful in validation. @@ -131,9 +182,8 @@ public static boolean isComplete(final String componentManufacturer, final String componentModel, final String componentSerial, final String componentRevision) { - return !( - StringUtils.isEmpty(componentManufacturer) || StringUtils.isEmpty(componentModel) - ); + return !(StringUtils.isEmpty(componentManufacturer) + || StringUtils.isEmpty(componentModel)); } @Override @@ -149,22 +199,26 @@ public boolean equals(final Object o) { && Objects.equals(componentManufacturer, that.componentManufacturer) && Objects.equals(componentModel, that.componentModel) && Objects.equals(componentSerial, that.componentSerial) - && Objects.equals(componentRevision, that.componentRevision); + && Objects.equals(componentRevision, that.componentRevision) + && Objects.equals(componentClass, that.componentClass); } @Override public int hashCode() { return Objects.hash(id, componentManufacturer, componentModel, - componentSerial, componentRevision); + componentSerial, componentRevision, componentClass); } @Override public String toString() { - return "ComponentInfo{" - + "componentManufacturer='" + componentManufacturer + '\'' - + ", componentModel='" + componentModel + '\'' - + ", componentSerial='" + componentSerial + '\'' - + ", componentRevision='" + componentRevision + '\'' - + '}'; + return String.format("ComponentInfo{" + + "componentManufacturer='%s'" + + ", componentModel='%s'" + + ", componentSerial='%s'" + + ", componentRevision='%s'" + + ", componentClass='%s'}", + componentManufacturer, + componentModel, componentSerial, + componentRevision, componentClass); } } diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index b449e2de6..423e0eb1a 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -140,6 +140,43 @@ public static List getComponentInfoFromPaccorOutput(final String return componentInfoList; } + /** + * Parses the output from PACCOR's allcomponents.sh script into ComponentInfo objects. + * @param paccorOutput the output from PACCOR's allcomoponents.sh + * @return a list of ComponentInfo objects built from paccorOutput + * @throws IOException if something goes wrong parsing the JSON + */ + public static List 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 @@ static AppraisalStatus validatePlatformCredentialAttributesV2p0( * 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 int compare(final PlatformCredential obj1, 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 int compare(final PlatformCredential obj1, 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 int compare(final PlatformCredential obj1, 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/23] 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 423e0eb1a..305b2666b 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 @@ static AppraisalStatus validateDeltaAttributesChainV2p0( 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 int compare(final PlatformCredential obj1, } }); - String ciSerial; + List modifiedClassValues = new LinkedList<>(); List certificateList = null; SupplyChainValidation scv = null; resultMessage.append("There are errors with Delta " @@ -640,22 +640,39 @@ public int compare(final PlatformCredential obj1, 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 int compare(final PlatformCredential obj1, 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 int compare(final PlatformCredential obj1, 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 int compare(final PlatformCredential obj1, 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 int compare(final PlatformCredential obj1, // 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 @@ private static String validateV2PlatformCredentialAttributes( .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 @@ private static String validateV2PlatformCredentialAttributes( subCompIdList.remove(cId); subCompInfoList.remove(cInfo); } + } else { + LOGGER.error("Didn't match."); } } } @@ -1113,6 +1161,28 @@ static boolean isMatch(final ComponentIdentifier pcComponent, 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 @@ private static boolean isMatchOrEmptyInPlatformCert( 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/23] 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 e3051ee0d..94602aa2f 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 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim cla 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 b4060661c..95c26c8bc 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 @@ private SupplyChainValidation validateDeltaPlatformCredentialAttributes( 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 60041acaf..abba78cdd 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 static HashMap getPlatformInformation(final UUID uuid, //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 e6158a3b8..8240ad33d 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 a8997f481..834b82cf7 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 ComponentClass(final String componentIdentifier) { */ 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 305b2666b..0bc16c295 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 int compare(final PlatformCredential obj1, 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 @@ private static String validateV2PlatformCredentialAttributes( .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 @@ private static String validateV2PlatformCredentialAttributes( 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/23] 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 95c26c8bc..486620964 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 0bc16c295..4ecdbb8f4 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 @@ private static String validateV2PlatformCredentialAttributes( 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/23] 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 abba78cdd..08b95f7db 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 static HashMap getPlatformInformation(final UUID uuid, 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/23] 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 eb1782102..9566ff9bc 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.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 @@ */ 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 @@ private AppraisalStatus.Status doSupplyChainValidation( // 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 8aa5cf2b3..0883a2397 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 @@ private SupplyChainValidation validatePlatformCredentialAttributes( 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 @@ private SupplyChainValidation validateDeltaPlatformCredentialAttributes( 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 dd5ddfc57..874918876 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 enum Status { * @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 a9e5fdb0c..00ebf8055 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 final boolean isRemoved() { return getAttributeStatus() == AttributeStatus.REMOVED; } + /** + * @return true if the component status wasn't set. + */ + public final boolean isEmpty() { + return (getAttributeStatus() == AttributeStatus.EMPTY_STATUS) + || (getAttributeStatus() == null); + } + /** * @return indicates the type of platform certificate. */ diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 6ce019d42..5e65b1f1d 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 int compare(final PlatformCredential obj1, 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 int compare(final PlatformCredential obj1, } 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 @@ private static String validateV2PlatformCredentialAttributes( 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/23] 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 0883a2397..9cfbdf930 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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/23] 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 9566ff9bc..3d72d42ea 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 @@ private IdentityResponseEnvelope generateIdentityResponseEnvelopeAndStoreIssuedC */ @Override public byte[] processIdentityClaimTpm2(final byte[] identityClaim) { - LOG.debug("Got identity claim"); if (ArrayUtils.isEmpty(identityClaim)) { @@ -414,7 +413,6 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) { 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 @@ private AppraisalStatus.Status doSupplyChainValidation( 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 9cfbdf930..e41720da2 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent // 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 65298a58e..93ede6b3b 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 @@ private static HashMap getBaseRimInfo( 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 @@ private static HashMap getMeasurementsRimInfo( 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 45a439651..ce35d6e16 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 String getCredentialType() { /** * 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 5e65b1f1d..32cf87843 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 AppraisalStatus validateDeltaPlatformCredentialAttributes( 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 @@ static AppraisalStatus validatePlatformCredentialAttributesV2p0( // 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 int compare(final PlatformCredential obj1, deltaMapping.put(delta, new SupplyChainValidation( SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, FAIL, certificateList, - failureMsg.toString() - )); + failureMsg.toString())); + builtMatchList.add(ci); } } } @@ -772,24 +762,18 @@ public int compare(final PlatformCredential obj1, 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/23] 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 93ede6b3b..48c22c46f 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.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/23] 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 e41720da2..65b268e96 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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/23] 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 c3f78f397..b98d325a0 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 @@ 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 static List retrieveComponentAddress(final ASN1Sequence 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 00ebf8055..6232c89f1 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 boolean isVersion2() { 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 32cf87843..ec8b00a14 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 int compare(final PlatformCredential obj1, 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/23] 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 e1dbd7788..fcb477934 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 static PlatformCredential storePlatformCredential( 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 65b268e96..2dca79237 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent // 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 ec8b00a14..8aa556388 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 int compare(final PlatformCredential obj1, "%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 int compare(final PlatformCredential obj1, "%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 int compare(final PlatformCredential obj1, "%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/23] 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 8aa556388..a0f701ba1 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 @@ static AppraisalStatus validateDeltaAttributesChainV2p0( 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 int compare(final PlatformCredential obj1, } 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)); + + // I have leftovers that don't have serial numbers + LOGGER.error(leftOvers.size()); - List modifiedClassValues = new LinkedList<>(); + /** + * + * 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 int compare(final PlatformCredential obj1, // 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 int compare(final PlatformCredential obj1, } if (classFound) { modifiedClassValues.add(classValue); - builtMatchList.add(ci); + baseCompList.add(ci); } else { fieldValidation = false; failureMsg.append(String.format( @@ -674,7 +684,7 @@ public int compare(final PlatformCredential obj1, 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 int compare(final PlatformCredential obj1, } 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 int compare(final PlatformCredential obj1, } } 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 int compare(final PlatformCredential obj1, certificateList, failureMsg.toString())); } else { - builtMatchList.add(ci); + baseCompList.add(ci); } } else if (ciV2.isEmpty()) { fieldValidation = false; @@ -746,7 +756,7 @@ public int compare(final PlatformCredential obj1, SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, FAIL, certificateList, failureMsg.toString())); - builtMatchList.add(ci); + baseCompList.add(ci); } } } @@ -766,7 +776,7 @@ public int compare(final PlatformCredential obj1, 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 int compare(final PlatformCredential obj1, 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 @@ && signatureMatchesPublicKey(cert, trustedCert)) { 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/23] Updated the code to go through the serial numbers that are valid numbers verus generic filler. Tested against the provisioner. --- .../SupplyChainCredentialValidator.java | 329 ++++++------------ 1 file changed, 110 insertions(+), 219 deletions(-) diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index a0f701ba1..96cdb323a 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 @@ static AppraisalStatus validateDeltaAttributesChainV2p0( 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 int compare(final PlatformCredential obj1, } 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)); - - // 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 + leftOverDeltas, chainCertificates)); + + // 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); - String classValue; - ComponentIdentifierV2 ciV2; - boolean classFound = false; - - 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; - } - } + // what wasn't handled by the serial number, + // not match by the serial number and the class type + // then the matching manufacturer and model - 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 deltaCi : leftOverDeltas) { + String classValue; + ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) deltaCi; + ComponentIdentifierV2 baseCiV2; + boolean classFound; + + 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 @@ private static String validateV2PlatformCredentialAttributes( 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 @@ && signatureMatchesPublicKey(cert, trustedCert)) { 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 @@ private static String validateDeltaChain( 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 @@ private static String validateDeltaChain( 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/23] 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 96cdb323a..ad2b2f4c0 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 @@ static AppraisalStatus validateDeltaAttributesChainV2p0( 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 int compare(final PlatformCredential obj1, 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 @@ private static String validateV2PlatformCredentialAttributes( 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 @@ private static String validateDeltaChain( 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 @@ private static String validateDeltaChain( // 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/23] 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 3d72d42ea..6d62d414f 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 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim cla 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 b98d325a0..2e9607b89 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 static List retrieveComponentAddress(final ASN1Sequence 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 97377871b..1805a13ca 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 ComponentInfo(final String componentManufacturer, 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/23] 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 834b82cf7..91669b254 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 ComponentClass(final String componentIdentifier) { */ 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 75309c2b3..77a07fb6d 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 final void verifyPlatformCredentialSerialNumberUnexpectedDeviceSerial() + "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 final void testvalidatePlatformCredentialAttributesV2p0RequiredFieldsEmpt 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 final void testvalidatePlatformCredentialAttributesV2p0MissingComponentIn 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 final void testvalidatePlatformCredentialAttributesV2p0RequiredComponentF 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 final void testValidateChainFailure() "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/23] 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 ad2b2f4c0..0cac1b385 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 int compare(final PlatformCredential obj1, // 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 int compare(final PlatformCredential obj1, } } 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/23] 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 0cac1b385..d7302e46f 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 @@ private static String validateDeltaChain( 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 @@ private static String validateDeltaChain( } 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/23] 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 1ead22863..aba6761a5 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 byte[] processIdentityClaimTpm2(final byte[] identityClaim) { 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 34f75bcab..17908de8c 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 static HashMap getPlatformInformation(final UUID uuid, .select(certificateManager) .byEntityId(uuid) .getCertificate(); + if (certificate != null) { data.putAll(getGeneralCertificateInfo(certificate, certificateManager)); data.put("credentialType", certificate.getCredentialType()); @@ -357,6 +358,7 @@ public static HashMap getPlatformInformation(final UUID uuid, 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 int compare(final PlatformCredential obj1, }); 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 8240ad33d..c9711c0be 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 d7302e46f..907bfa09b 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 int compare(final PlatformCredential obj1, // 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 @@ && isMatch(cId, cInfo)) { 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 @@ private static String validateDeltaChain( // 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 @@ private static String validateDeltaChain( "%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 @@ private static String validateDeltaChain( "%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 @@ private static String validateDeltaChain( "%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 @@ private static String validateDeltaChain( } 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/23] 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 aba6761a5..3652ee323 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.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 byte[] processIdentityClaimTpm2(final byte[] identityClaim) { 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 @@ private AppraisalStatus.Status doSupplyChainValidation( // 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 7ec2718af..3351a9c15 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent 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 KeyStore getCaChain(final Certificate credential) { * 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 907bfa09b..6d06e573f 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 AppraisalStatus validateDeltaPlatformCredentialAttributes( 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 AppraisalStatus validateDeltaPlatformCredentialAttributes( } } + 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 int compare(final PlatformCredential obj1, 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 @@ private static String validateDeltaChain( // 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 @@ private static String validateDeltaChain( } 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/23] 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 1805a13ca..4febbd67a 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 ComponentInfo(final String componentManufacturer, 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 ComponentInfo(final String componentManufacturer, 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 9917fadef7fcad8de6bcfe9315d75c980608783b Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Tue, 9 Feb 2021 13:30:37 -0500 Subject: [PATCH 23/23] On a previous commit, I removed a piece of code that checked the base credential first. Because the delta fixed a problem in the base, the base failed before the delta was checked. This was completely removed. On a test that we had previously done, the test passes when it should fail because there is only a base, so that check isn't being done. This change reintroduces the check but in a different location with flags for when there is a delta present. --- .../SupplyChainValidationServiceImpl.java | 63 +++++++++++++------ .../attributes/ComponentIdentifier.java | 19 ++++++ .../SupplyChainCredentialValidator.java | 46 +++++++------- 3 files changed, 85 insertions(+), 43 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 3351a9c15..e22fcddc5 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -133,6 +133,7 @@ public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent boolean acceptExpiredCerts = policy.isExpiredCertificateValidationEnabled(); PlatformCredential baseCredential = null; SupplyChainValidation platformScv = null; + boolean chkDeltas = false; String pcErrorMessage = ""; List validations = new LinkedList<>(); Map deltaMapping = new HashMap<>(); @@ -174,6 +175,7 @@ public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent if (pc.isBase()) { baseCredential = pc; } else { + chkDeltas = true; deltaMapping.put(pc, null); } pc.setDevice(device); @@ -214,25 +216,46 @@ public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent && pcErrorMessage.isEmpty()) { // Ensure there are platform credentials to validate SupplyChainValidation attributeScv = null; - - List aes = new ArrayList<>(); - if (platformScv != null) { - aes.addAll(platformScv.getCertificatesUsed()); - } - 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()); + List aes = new ArrayList<>(); + // need to check if there are deltas, if not then just verify + // components of the base + if (baseCredential == null) { + validations.add(buildValidationRecord( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + AppraisalStatus.Status.FAIL, + "Base Platform credential missing." + + " Cannot validate attributes", + null, Level.ERROR)); + } else { + if (chkDeltas) { + if (platformScv != null) { + aes.addAll(platformScv.getCertificatesUsed()); + } + Iterator it = pcs.iterator(); + while (it.hasNext()) { + PlatformCredential pc = it.next(); + if (pc != null) { + if (!pc.isBase()) { + attributeScv = validateDeltaPlatformCredentialAttributes( + pc, device.getDeviceInfo(), + baseCredential, deltaMapping); + if (attributeScv.getResult() == FAIL) { + attrErrorMessage = String.format("%s%s%n", attrErrorMessage, + attributeScv.getMessage()); + } + } } } + } else { + aes.add(baseCredential); + validations.remove(platformScv); + // if there are no deltas, just check base credential + platformScv = validatePlatformCredentialAttributes( + baseCredential, device.getDeviceInfo(), ec); + validations.add(new SupplyChainValidation( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + platformScv.getResult(), aes, platformScv.getMessage())); } } if (!attrErrorMessage.isEmpty()) { @@ -240,7 +263,7 @@ public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent validations.remove(platformScv); if (platformScv != null) { validations.add(new SupplyChainValidation( - platformScv.getValidationType(), + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, attributeScv.getResult(), aes, attributeScv.getMessage())); } } @@ -252,7 +275,7 @@ public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent validations.add(validateFirmware(device, policy.getPcrPolicy())); } - LOGGER.error("The service finished and now summarizing"); + LOGGER.info("The service finished and now summarizing"); // Generate validation summary, save it, and return it. SupplyChainValidationSummary summary = new SupplyChainValidationSummary(device, validations); @@ -662,6 +685,10 @@ private SupplyChainValidation validatePlatformCredentialAttributes( return buildValidationRecord(validationType, PASS, result.getMessage(), pc, Level.INFO); case FAIL: + if (!result.getAdditionalInfo().isEmpty()) { + pc.setComponentFailures(result.getAdditionalInfo()); + this.certificateManager.update(pc); + } return buildValidationRecord(validationType, AppraisalStatus.Status.FAIL, result.getMessage(), pc, Level.WARN); case ERROR: 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 2e9607b89..f02075026 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 @@ -74,6 +74,7 @@ public class ComponentIdentifier { private ASN1ObjectIdentifier componentManufacturerId; private ASN1Boolean fieldReplaceable; private List componentAddress; + private boolean validationResult = true; /** * Default constructor. @@ -264,6 +265,24 @@ public boolean isVersion2() { return false; } + /** + * Holds the status of the validation process for attributes + * specific to this instance. + * @return true is passed, false if failed. + */ + public boolean isValidationResult() { + return validationResult; + } + + /** + * Sets the flag for the validation status for this instance + * of the attribute. + * @param validationResult validation flag. + */ + public void setValidationResult(final boolean validationResult) { + this.validationResult = validationResult; + } + /** * Get all the component addresses inside the sequence. * diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 6d06e573f..2322bf06e 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -95,8 +95,6 @@ public final class SupplyChainCredentialValidator implements CredentialValidator */ public static final String FIRMWARE_VALID = "Firmware validated"; - private static final Map DELTA_FAILURES = new HashMap<>(); - /* * Ensure that BouncyCastle is configured as a javax.security.Security provider, as this * class expects it to be available. @@ -318,8 +316,6 @@ public AppraisalStatus validateDeltaPlatformCredentialAttributes( 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()) { @@ -342,7 +338,6 @@ public AppraisalStatus validateDeltaPlatformCredentialAttributes( } } - LOGGER.error("This is before validateDeltaAttributesChainV2p0"); // parse out the provided delta and its specific chain. List origPcComponents = new LinkedList<>(basePlatformCredential.getComponentIdentifiers()); @@ -560,9 +555,15 @@ static AppraisalStatus validatePlatformCredentialAttributesV2p0( return new AppraisalStatus(ERROR, baseErrorMessage + e.getMessage()); } + StringBuilder additionalInfo = new StringBuilder(); if (!fieldValidation) { resultMessage.append("There are unmatched components:\n"); resultMessage.append(unmatchedComponents); + + // pass information of which ones failed in additionInfo + for (ComponentIdentifier ci : validPcComponents) { + additionalInfo.append(String.format("%d;", ci.hashCode())); + } } passesValidation &= fieldValidation; @@ -570,7 +571,7 @@ static AppraisalStatus validatePlatformCredentialAttributesV2p0( if (passesValidation) { return new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID); } else { - return new AppraisalStatus(FAIL, resultMessage.toString()); + return new AppraisalStatus(FAIL, resultMessage.toString(), additionalInfo.toString()); } } @@ -635,6 +636,7 @@ public int compare(final PlatformCredential obj1, // finished up List certificateList = null; SupplyChainValidation scv = null; + StringBuilder deltaSb = new StringBuilder(); // non-empty serial values for (ComponentIdentifier deltaCi : leftOverDeltas) { @@ -653,6 +655,7 @@ public int compare(final PlatformCredential obj1, if (ciV2.isAdded()) { // error resultMessage.append("ADDED attempted with prior instance\n"); + deltaSb.append(String.format("%s;", ci.hashCode())); } if (ciV2.isModified()) { // since the base list doesn't have this ci @@ -680,19 +683,21 @@ public int compare(final PlatformCredential obj1, // error because you can't modify something // that isn't here resultMessage.append("MODIFIED attempted without prior instance\n"); + deltaSb.append(String.format("%s;", ci.hashCode())); } if (ciV2.isRemoved()) { // error because you can't remove something // that isn't here resultMessage.append("REMOVED attempted without prior instance\n"); + deltaSb.append(String.format("%s;", ci.hashCode())); } } } } if (!fieldValidation) { - return new AppraisalStatus(FAIL, resultMessage.toString()); + return new AppraisalStatus(FAIL, resultMessage.toString(), deltaSb.toString()); } String paccorOutputString = deviceInfoReport.getPaccorOutputString(); @@ -766,7 +771,6 @@ && isMatch(cId, cInfo)) { if (!subCompInfoList.isEmpty()) { for (ComponentInfo ci : subCompInfoList) { - LOGGER.error("For subComInfoList -> {}", ci.getComponentSerial()); invalidDeviceInfo.append(String.format("%d;", ci.hashCode())); } @@ -783,6 +787,8 @@ && isMatch(cId, cInfo)) { * components not represented in the platform credential. * * @param untrimmedPcComponents the platform credential components (may contain end whitespace) + * **NEW** this is updated with just the unmatched components + * if there are any failures, otherwise it remains unchanged. * @param allDeviceInfoComponents the device info report components * @return true if validation passes */ @@ -813,8 +819,7 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc componentSerial, componentRevision, component.getComponentManufacturerId(), component.getFieldReplaceable(), - component.getComponentAddress() - )); + component.getComponentAddress())); } LOGGER.info("Validating the following Platform Cert components..."); @@ -822,8 +827,7 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc LOGGER.info("...against the the following DeviceInfoReport components:"); allDeviceInfoComponents.forEach(component -> LOGGER.info(component.toString())); Set manufacturerSet = new HashSet<>(); - pcComponents.forEach(component -> manufacturerSet.add( - component.getComponentManufacturer())); + pcComponents.forEach(pcComp -> manufacturerSet.add(pcComp.getComponentManufacturer())); // Create a list for unmatched components across all manufacturers to display at the end. List pcUnmatchedComponents = new ArrayList<>(); @@ -859,8 +863,7 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc .filter(componentInfo -> StringUtils.isNotEmpty(componentInfo.getComponentSerial())) .filter(componentInfo -> componentInfo.getComponentSerial() - .equals(pcComponent.getComponentSerial().getString())) - .findFirst(); + .equals(pcComponent.getComponentSerial().getString())).findFirst(); if (first.isPresent()) { ComponentInfo potentialMatch = first.get(); @@ -905,12 +908,11 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc // just match them. List templist = new ArrayList<>(pcComponentsFromManufacturer); for (ComponentIdentifier ci : templist) { - ComponentIdentifier pcComponent = ci; Iterator diComponentIter = deviceInfoComponentsFromManufacturer.iterator(); while (diComponentIter.hasNext()) { ComponentInfo potentialMatch = diComponentIter.next(); - if (isMatch(pcComponent, potentialMatch)) { + if (isMatch(ci, potentialMatch)) { pcComponentsFromManufacturer.remove(ci); diComponentIter.remove(); } @@ -920,6 +922,7 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc } if (!pcUnmatchedComponents.isEmpty()) { + untrimmedPcComponents.clear(); StringBuilder sb = new StringBuilder(); LOGGER.error(String.format("Platform Credential contained %d unmatched components:", pcUnmatchedComponents.size())); @@ -933,6 +936,8 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc unmatchedComponent.getComponentModel(), unmatchedComponent.getComponentSerial(), unmatchedComponent.getComponentRevision())); + unmatchedComponent.setValidationResult(false); + untrimmedPcComponents.add(unmatchedComponent); } return sb.toString(); } @@ -1664,13 +1669,4 @@ private static boolean isSelfSigned(final X509Certificate cert) return false; } } - - /** - * Getter for the collection of delta certificates that have failed and the - * associated message. - * @return unmodifiable list of failed certificates - */ - public Map getDeltaFailures() { - return Collections.unmodifiableMap(DELTA_FAILURES); - } }