mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-01-18 10:46:39 +00:00
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.
This commit is contained in:
parent
69cd06df3b
commit
9917fadef7
@ -133,6 +133,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
boolean acceptExpiredCerts = policy.isExpiredCertificateValidationEnabled();
|
||||
PlatformCredential baseCredential = null;
|
||||
SupplyChainValidation platformScv = null;
|
||||
boolean chkDeltas = false;
|
||||
String pcErrorMessage = "";
|
||||
List<SupplyChainValidation> validations = new LinkedList<>();
|
||||
Map<PlatformCredential, SupplyChainValidation> deltaMapping = new HashMap<>();
|
||||
@ -174,6 +175,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
if (pc.isBase()) {
|
||||
baseCredential = pc;
|
||||
} else {
|
||||
chkDeltas = true;
|
||||
deltaMapping.put(pc, null);
|
||||
}
|
||||
pc.setDevice(device);
|
||||
@ -214,13 +216,23 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
&& pcErrorMessage.isEmpty()) {
|
||||
// Ensure there are platform credentials to validate
|
||||
SupplyChainValidation attributeScv = null;
|
||||
|
||||
String attrErrorMessage = "";
|
||||
List<ArchivableEntity> 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<PlatformCredential> it = pcs.iterator();
|
||||
String attrErrorMessage = "";
|
||||
while (it.hasNext()) {
|
||||
PlatformCredential pc = it.next();
|
||||
if (pc != null) {
|
||||
@ -235,12 +247,23 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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()) {
|
||||
//combine platform and platform attributes
|
||||
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 class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
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 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
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:
|
||||
|
@ -74,6 +74,7 @@ public class ComponentIdentifier {
|
||||
private ASN1ObjectIdentifier componentManufacturerId;
|
||||
private ASN1Boolean fieldReplaceable;
|
||||
private List<ComponentAddress> componentAddress;
|
||||
private boolean validationResult = true;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
@ -264,6 +265,24 @@ public class ComponentIdentifier {
|
||||
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.
|
||||
*
|
||||
|
@ -95,8 +95,6 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
*/
|
||||
public static final String FIRMWARE_VALID = "Firmware validated";
|
||||
|
||||
private static final Map<PlatformCredential, StringBuilder> 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 final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
final Map<PlatformCredential, SupplyChainValidation> 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 final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.error("This is before validateDeltaAttributesChainV2p0");
|
||||
// parse out the provided delta and its specific chain.
|
||||
List<ComponentIdentifier> origPcComponents
|
||||
= new LinkedList<>(basePlatformCredential.getComponentIdentifiers());
|
||||
@ -560,9 +555,15 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
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 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
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 final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
// finished up
|
||||
List<ArchivableEntity> certificateList = null;
|
||||
SupplyChainValidation scv = null;
|
||||
StringBuilder deltaSb = new StringBuilder();
|
||||
|
||||
// non-empty serial values
|
||||
for (ComponentIdentifier deltaCi : leftOverDeltas) {
|
||||
@ -653,6 +655,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
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 final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
// 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 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
|
||||
if (!subCompInfoList.isEmpty()) {
|
||||
for (ComponentInfo ci : subCompInfoList) {
|
||||
LOGGER.error("For subComInfoList -> {}", ci.getComponentSerial());
|
||||
invalidDeviceInfo.append(String.format("%d;",
|
||||
ci.hashCode()));
|
||||
}
|
||||
@ -783,6 +787,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
* 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 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
componentSerial, componentRevision,
|
||||
component.getComponentManufacturerId(),
|
||||
component.getFieldReplaceable(),
|
||||
component.getComponentAddress()
|
||||
));
|
||||
component.getComponentAddress()));
|
||||
}
|
||||
|
||||
LOGGER.info("Validating the following Platform Cert components...");
|
||||
@ -822,8 +827,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
LOGGER.info("...against the the following DeviceInfoReport components:");
|
||||
allDeviceInfoComponents.forEach(component -> LOGGER.info(component.toString()));
|
||||
Set<DERUTF8String> 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<ComponentIdentifier> pcUnmatchedComponents = new ArrayList<>();
|
||||
@ -859,8 +863,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
.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 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
// just match them.
|
||||
List<ComponentIdentifier> templist = new ArrayList<>(pcComponentsFromManufacturer);
|
||||
for (ComponentIdentifier ci : templist) {
|
||||
ComponentIdentifier pcComponent = ci;
|
||||
Iterator<ComponentInfo> 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 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
}
|
||||
|
||||
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 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
unmatchedComponent.getComponentModel(),
|
||||
unmatchedComponent.getComponentSerial(),
|
||||
unmatchedComponent.getComponentRevision()));
|
||||
unmatchedComponent.setValidationResult(false);
|
||||
untrimmedPcComponents.add(unmatchedComponent);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
@ -1664,13 +1669,4 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the collection of delta certificates that have failed and the
|
||||
* associated message.
|
||||
* @return unmodifiable list of failed certificates
|
||||
*/
|
||||
public Map<PlatformCredential, StringBuilder> getDeltaFailures() {
|
||||
return Collections.unmodifiableMap(DELTA_FAILURES);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user