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] This latest push should have the code that'll highlight the components based on a string rather than the serial number. This also adds additional checks for the validity begin date of the delta not matching or being before the base. It also checks that they don't have the same certificate serial number. --- ...stractAttestationCertificateAuthority.java | 7 - .../SupplyChainValidationServiceImpl.java | 179 +++++------------- ...eferenceManifestDetailsPageController.java | 5 - .../certificate/PlatformCredential.java | 13 +- .../SupplyChainCredentialValidator.java | 74 +++----- 5 files changed, 83 insertions(+), 195 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java index 9566ff9b..3d72d42e 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java @@ -392,7 +392,6 @@ public abstract class AbstractAttestationCertificateAuthority */ @Override public byte[] processIdentityClaimTpm2(final byte[] identityClaim) { - LOG.debug("Got identity claim"); if (ArrayUtils.isEmpty(identityClaim)) { @@ -414,7 +413,6 @@ public abstract class AbstractAttestationCertificateAuthority LOG.error(ex); } if (validationResult == AppraisalStatus.Status.PASS) { - RSAPublicKey akPub = parsePublicKey(claim.getAkPublicArea().toByteArray()); byte[] nonce = generateRandomBytes(NONCE_LENGTH); ByteString blobStr = tpm20MakeCredential(ekPub, akPub, nonce); @@ -454,11 +452,6 @@ public abstract class AbstractAttestationCertificateAuthority Set platformCredentials = parsePcsFromIdentityClaim(claim, endorsementCredential); Map correctedMap = new HashMap<>(); - for (PlatformCredential pc : platformCredentials) { - correctedMap.put(pc.getSerialNumber(), pc); - } - platformCredentials.clear(); - platformCredentials.addAll(correctedMap.values()); // Parse and save device info Device device = processDeviceInfo(claim); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java index 9cfbdf93..e41720da 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -84,7 +84,6 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe private static final Logger LOGGER = LogManager.getLogger(SupplyChainValidationServiceImpl.class); - private static final int VALUE_INDEX = 1; /** * Constructor. @@ -132,9 +131,10 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe supplyChainAppraiser); boolean acceptExpiredCerts = policy.isExpiredCertificateValidationEnabled(); PlatformCredential baseCredential = null; + SupplyChainValidation platformScv = null; + String pcErrorMessage = ""; List validations = new LinkedList<>(); Map deltaMapping = new HashMap<>(); - SupplyChainValidation platformScv = null; SupplyChainValidation.ValidationType platformType = SupplyChainValidation .ValidationType.PLATFORM_CREDENTIAL; SupplyChainValidation.ValidationType platformAttrType = SupplyChainValidation @@ -158,41 +158,26 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe // Ensure there are platform credentials to validate if (pcs == null || pcs.isEmpty()) { LOGGER.error("There were no Platform Credentials to validate."); - validations.add(buildValidationRecord( - platformType, - AppraisalStatus.Status.FAIL, - "Platform credential(s) missing", null, Level.ERROR)); + pcErrorMessage = "Platform credential(s) missing\n"; } else { - Iterator it = pcs.iterator(); - while (it.hasNext()) { - PlatformCredential pc = it.next(); + for (PlatformCredential pc : pcs) { KeyStore trustedCa = getCaChain(pc); platformScv = validatePlatformCredential( pc, trustedCa, acceptExpiredCerts); - // check if this cert has been verified for multiple base - // associated with the serial number - if (pc != null) { - platformScv = validatePcPolicy(pc, platformScv, - deltaMapping, acceptExpiredCerts); - - if (validationTypeMap.containsKey( - platformType)) { - SupplyChainValidation tmpScv = validationTypeMap.get(platformType); - if (tmpScv.getResult() == PASS && platformScv.getResult() == FAIL) { - validationTypeMap.put(platformType, platformScv); - } - } else { - validationTypeMap.put(platformType, platformScv); - } - - if (pc.isBase()) { - baseCredential = pc; - LOGGER.error("Found the base Certificate"); - } - pc.setDevice(device); - this.certificateManager.update(pc); + if (platformScv.getResult() == FAIL) { + pcErrorMessage = String.format("%s%s%n", pcErrorMessage, + platformScv.getMessage()); } + // set the base credential + if (pc.isBase()) { + baseCredential = pc; + } else { + deltaMapping.put(pc, null); + } + pc.setDevice(device); + this.certificateManager.update(pc); + } // check that the delta certificates validity date is after @@ -202,130 +187,70 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe int result = pc.getBeginValidity() .compareTo(baseCredential.getBeginValidity()); if (!pc.isBase() && (result <= 0)) { - LOGGER.error("You are not crazy"); - validationTypeMap.put(platformType, - buildValidationRecord( - platformType, - AppraisalStatus.Status.FAIL, - "Delta Certificate's validity " - + "date is not after Base", - null, Level.ERROR)); + pcErrorMessage = String.format("%s%s%n", pcErrorMessage, + "Delta Certificate's validity " + + "date is not after Base"); break; } } } else { // we don't have a base cert, fail - validationTypeMap.put(platformType, - buildValidationRecord( - platformType, - AppraisalStatus.Status.FAIL, - "Base Platform credential missing", - null, - Level.ERROR)); + pcErrorMessage = String.format("%s%s%n", pcErrorMessage, + "Base Platform credential missing"); } + } - validations.add(validationTypeMap.get( - platformType)); + if (pcErrorMessage.isEmpty()) { + validations.add(platformScv); + } else { + validations.add(new SupplyChainValidation(platformType, + AppraisalStatus.Status.FAIL, new ArrayList<>(pcs), pcErrorMessage)); } } // Validate Platform Credential attributes - if (policy.isPcAttributeValidationEnabled()) { + if (policy.isPcAttributeValidationEnabled() + && pcErrorMessage.isEmpty()) { // Ensure there are platform credentials to validate - if (pcs == null || pcs.isEmpty()) { - LOGGER.error("There were no Platform Credentials to validate attributes."); - validations.add(buildValidationRecord( - platformAttrType, - AppraisalStatus.Status.FAIL, - "Platform credential(s) missing." - + " Cannot validate attributes", - null, Level.ERROR)); - } else { - platformScv = validationTypeMap.get( - platformType); - SupplyChainValidation attributeScv = null; + SupplyChainValidation attributeScv = null; - List aes = new ArrayList<>(); - if (platformScv != null) { - aes.addAll(platformScv.getCertificatesUsed()); - } + List aes = new ArrayList<>(); + if (platformScv != null) { + aes.addAll(platformScv.getCertificatesUsed()); + } + // ok, still want to validate the base credential attributes + attributeScv = validatePlatformCredentialAttributes( + baseCredential, device.getDeviceInfo(), ec); + + if (attributeScv.getResult() != FAIL) { Iterator it = pcs.iterator(); + String attrErrorMessage = ""; while (it.hasNext()) { PlatformCredential pc = it.next(); if (pc != null) { - if (pc.isDeltaChain()) { - // this check validates the delta changes and re-compares - // the modified list to the original. + if (!pc.isBase() && attributeScv.getResult() != FAIL) { attributeScv = validateDeltaPlatformCredentialAttributes( pc, device.getDeviceInfo(), baseCredential, deltaMapping); - } else { - attributeScv = validatePlatformCredentialAttributes( - pc, device.getDeviceInfo(), ec); - } - - // update the attribute SCV - if (validationTypeMap.containsKey(platformAttrType)) { - SupplyChainValidation tmpScv = validationTypeMap.get( - platformAttrType); - if (tmpScv.getResult() == PASS && attributeScv.getResult() == FAIL) { - validationTypeMap.put(platformAttrType, attributeScv); - } else if (tmpScv.getResult() == FAIL - && attributeScv.getResult() == FAIL) { - validationTypeMap.put(platformAttrType, new SupplyChainValidation( - attributeScv.getValidationType(), - attributeScv.getResult(), aes, - String.format("%s%n%s", tmpScv.getMessage(), - attributeScv.getMessage()))); + if (attributeScv.getResult() == FAIL) { + attrErrorMessage = String.format("%s%s%n", attrErrorMessage, + attributeScv.getMessage()); } - } else { - validationTypeMap.put(platformAttrType, attributeScv); } - -// if (platformScv != null) { -// // have to make sure the attribute validation isn't ignored and -// // doesn't override general validation status -// if (platformScv.getResult() == PASS -// && attributeScv.getResult() != PASS) { -// // if the platform trust store validated but the attribute didn't -// // replace -// validationTypeMap.put( -// SupplyChainValidation.ValidationType -// .PLATFORM_CREDENTIAL_ATTRIBUTES, -// attributeScv); -// } else if ((platformScv.getResult() == PASS -// && attributeScv.getResult() == PASS) -// || (platformScv.getResult() != PASS -// && attributeScv.getResult() != PASS)) { -// // if both trust store and attributes validated or failed -// // combine messages -// validations.add(new SupplyChainValidation( -// platformScv.getValidationType(), -// platformScv.getResult(), aes, -// String.format("%s%n%s", platformScv.getMessage(), -// attributeScv.getMessage()))); -// } -// } - - pc.setDevice(device); - this.certificateManager.update(pc); } } - //combine platform and platform attributes - validations.remove(platformScv); - attributeScv = validationTypeMap.get( - platformAttrType); - if (platformScv.getResult() == PASS && attributeScv.getResult() == FAIL) { + if (!attrErrorMessage.isEmpty()) { + //combine platform and platform attributes + validations.remove(platformScv); validations.add(new SupplyChainValidation( platformScv.getValidationType(), attributeScv.getResult(), aes, attributeScv.getMessage())); - } else if (platformScv.getResult() == FAIL && attributeScv.getResult() == FAIL) { - validations.add(new SupplyChainValidation( - platformScv.getValidationType(), - platformScv.getResult(), aes, - String.format("%s%n%s", platformScv.getMessage(), - attributeScv.getMessage()))); } + } else { + validations.remove(platformScv); + // base platform has errors + validations.add(new SupplyChainValidation(platformScv.getValidationType(), + attributeScv.getResult(), aes, attributeScv.getMessage())); } } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java index 65298a58..93ede6b3 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java @@ -275,7 +275,6 @@ public class ReferenceManifestDetailsPageController for (CertificateAuthorityCredential cert : certificates) { if (Arrays.equals(cert.getEncodedPublicKey(), RIM_VALIDATOR.getPublicKey().getEncoded())) { - LOGGER.info("Found matching cert!"); data.put("issuerID", cert.getId().toString()); } } @@ -407,10 +406,6 @@ public class ReferenceManifestDetailsPageController data.put("supportEvents", supportEvents); data.put("livelogEvents", livelogEvents); - for (Map.Entry entry : data.entrySet()) { - LOGGER.error(String.format("%s -> %s", entry.getKey(), - String.valueOf(entry.getValue()))); - } return data; } } diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java index 45a43965..ce35d6e1 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java @@ -380,25 +380,16 @@ public class PlatformCredential extends DeviceAssociatedCertificate { /** * Get the type of platform certificate. * - * @return the TCG platform type { base | delta } + * @return flag for base certificate */ public boolean isBase() { return platformBase; } - /** - * Flag that indicates this PC has or can have a chain of delta - * certificates. - * @return status of the chain - */ - public boolean isDeltaChain() { - return isDeltaChain; - } - /** * Getter for the string representation of the platform type. * - * @return Delta or Base + * @return the TCG platform type { base | delta } */ public String getPlatformType() { return platformChainType; diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index 5e65b1f1..32cf8784 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -316,34 +316,28 @@ public final class SupplyChainCredentialValidator implements CredentialValidator final DeviceInfoReport deviceInfoReport, final PlatformCredential basePlatformCredential, final Map deltaMapping) { - final String baseErrorMessage = "Can't validate delta platform" - + "certificate attributes without "; String message; - if (deltaPlatformCredential == null) { - message = baseErrorMessage + "a delta platform certificate"; - LOGGER.error(message); - return new AppraisalStatus(FAIL, message); - } - if (deviceInfoReport == null) { - message = baseErrorMessage + "a device info report"; - LOGGER.error(message); - return new AppraisalStatus(FAIL, message); - } - if (basePlatformCredential == null) { - message = baseErrorMessage + "a base platform credential"; - LOGGER.error(message); - return new AppraisalStatus(FAIL, message); - } - if (!basePlatformCredential.getPlatformSerial() - .equals(deltaPlatformCredential.getPlatformSerial())) { - message = String.format("Delta platform certificate " - + "platform serial number (%s) does not match " - + "the base certificate's platform serial number (%s)", - deltaPlatformCredential.getPlatformSerial(), - basePlatformCredential.getPlatformSerial()); - LOGGER.error(message); - return new AppraisalStatus(FAIL, message); + // this needs to be a loop for all deltas, link to issue #110 + // check that they don't have the same serial number + for (PlatformCredential delta : deltaMapping.keySet()) { + if (!basePlatformCredential.getPlatformSerial() + .equals(delta.getPlatformSerial())) { + message = String.format("Base and Delta platform serial " + + "numbers do not match (%s != %s)", + delta.getPlatformSerial(), + basePlatformCredential.getPlatformSerial()); + LOGGER.error(message); + return new AppraisalStatus(FAIL, message); + } + // none of the deltas should have the serial number of the base + if (basePlatformCredential.getSerialNumber() + .equals(delta.getSerialNumber())) { + message = String.format("Delta Certificate with same serial number as base. (%s)", + delta.getSerialNumber()); + LOGGER.error(message); + return new AppraisalStatus(FAIL, message); + } } // parse out the provided delta and its specific chain. @@ -501,18 +495,14 @@ public final class SupplyChainCredentialValidator implements CredentialValidator // check PlatformSerial against both system-serial-number and baseboard-serial-number fieldValidation = ( - ( - optionalPlatformCredentialFieldNullOrMatches( + (optionalPlatformCredentialFieldNullOrMatches( "PlatformSerial", platformCredential.getPlatformSerial(), - hardwareInfo.getSystemSerialNumber()) - ) || ( - optionalPlatformCredentialFieldNullOrMatches( + hardwareInfo.getSystemSerialNumber())) + || (optionalPlatformCredentialFieldNullOrMatches( "PlatformSerial", platformCredential.getPlatformSerial(), - hardwareInfo.getBaseboardSerialNumber()) - ) - ); + hardwareInfo.getBaseboardSerialNumber()))); if (!fieldValidation) { resultMessage.append("Platform serial did not match\n"); @@ -755,8 +745,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator deltaMapping.put(delta, new SupplyChainValidation( SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, FAIL, certificateList, - failureMsg.toString() - )); + failureMsg.toString())); + builtMatchList.add(ci); } } } @@ -772,24 +762,18 @@ public final class SupplyChainCredentialValidator implements CredentialValidator String paccorOutputString = deviceInfoReport.getPaccorOutputString(); String unmatchedComponents; try { -// List componentInfoList -// = getComponentInfoFromPaccorOutput(paccorOutputString); // compare based on component class List componentInfoList = getV2PaccorOutput(paccorOutputString); -// testComponentMatching(compMapping, chainCiMapping.values()); // this is what I want to rewrite -// unmatchedComponents = validateV2p0PlatformCredentialComponentsExpectingExactMatch( -// new LinkedList<>(chainCiMapping.values()), -// compMapping.keySet().stream().collect(Collectors.toList())); unmatchedComponents = validateV2PlatformCredentialAttributes( builtMatchList, componentInfoList); fieldValidation &= unmatchedComponents.isEmpty(); - } catch (IOException e) { + } catch (IOException ioEx) { final String baseErrorMessage = "Error parsing JSON output from PACCOR: "; - LOGGER.error(baseErrorMessage + e.toString()); + LOGGER.error(baseErrorMessage + ioEx.toString()); LOGGER.error("PACCOR output string:\n" + paccorOutputString); - return new AppraisalStatus(ERROR, baseErrorMessage + e.getMessage()); + return new AppraisalStatus(ERROR, baseErrorMessage + ioEx.getMessage()); } if (!fieldValidation) { // instead of listing all unmatched, just print the #. The failure