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