mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-06-06 01:11:53 +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();
|
boolean acceptExpiredCerts = policy.isExpiredCertificateValidationEnabled();
|
||||||
PlatformCredential baseCredential = null;
|
PlatformCredential baseCredential = null;
|
||||||
SupplyChainValidation platformScv = null;
|
SupplyChainValidation platformScv = null;
|
||||||
|
boolean chkDeltas = false;
|
||||||
String pcErrorMessage = "";
|
String pcErrorMessage = "";
|
||||||
List<SupplyChainValidation> validations = new LinkedList<>();
|
List<SupplyChainValidation> validations = new LinkedList<>();
|
||||||
Map<PlatformCredential, SupplyChainValidation> deltaMapping = new HashMap<>();
|
Map<PlatformCredential, SupplyChainValidation> deltaMapping = new HashMap<>();
|
||||||
@ -174,6 +175,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
if (pc.isBase()) {
|
if (pc.isBase()) {
|
||||||
baseCredential = pc;
|
baseCredential = pc;
|
||||||
} else {
|
} else {
|
||||||
|
chkDeltas = true;
|
||||||
deltaMapping.put(pc, null);
|
deltaMapping.put(pc, null);
|
||||||
}
|
}
|
||||||
pc.setDevice(device);
|
pc.setDevice(device);
|
||||||
@ -214,13 +216,23 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
&& pcErrorMessage.isEmpty()) {
|
&& pcErrorMessage.isEmpty()) {
|
||||||
// Ensure there are platform credentials to validate
|
// Ensure there are platform credentials to validate
|
||||||
SupplyChainValidation attributeScv = null;
|
SupplyChainValidation attributeScv = null;
|
||||||
|
String attrErrorMessage = "";
|
||||||
List<ArchivableEntity> aes = new ArrayList<>();
|
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) {
|
if (platformScv != null) {
|
||||||
aes.addAll(platformScv.getCertificatesUsed());
|
aes.addAll(platformScv.getCertificatesUsed());
|
||||||
}
|
}
|
||||||
Iterator<PlatformCredential> it = pcs.iterator();
|
Iterator<PlatformCredential> it = pcs.iterator();
|
||||||
String attrErrorMessage = "";
|
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
PlatformCredential pc = it.next();
|
PlatformCredential pc = it.next();
|
||||||
if (pc != null) {
|
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()) {
|
if (!attrErrorMessage.isEmpty()) {
|
||||||
//combine platform and platform attributes
|
//combine platform and platform attributes
|
||||||
validations.remove(platformScv);
|
validations.remove(platformScv);
|
||||||
if (platformScv != null) {
|
if (platformScv != null) {
|
||||||
validations.add(new SupplyChainValidation(
|
validations.add(new SupplyChainValidation(
|
||||||
platformScv.getValidationType(),
|
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL,
|
||||||
attributeScv.getResult(), aes, attributeScv.getMessage()));
|
attributeScv.getResult(), aes, attributeScv.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,7 +275,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
validations.add(validateFirmware(device, policy.getPcrPolicy()));
|
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.
|
// Generate validation summary, save it, and return it.
|
||||||
SupplyChainValidationSummary summary
|
SupplyChainValidationSummary summary
|
||||||
= new SupplyChainValidationSummary(device, validations);
|
= new SupplyChainValidationSummary(device, validations);
|
||||||
@ -662,6 +685,10 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
return buildValidationRecord(validationType, PASS,
|
return buildValidationRecord(validationType, PASS,
|
||||||
result.getMessage(), pc, Level.INFO);
|
result.getMessage(), pc, Level.INFO);
|
||||||
case FAIL:
|
case FAIL:
|
||||||
|
if (!result.getAdditionalInfo().isEmpty()) {
|
||||||
|
pc.setComponentFailures(result.getAdditionalInfo());
|
||||||
|
this.certificateManager.update(pc);
|
||||||
|
}
|
||||||
return buildValidationRecord(validationType, AppraisalStatus.Status.FAIL,
|
return buildValidationRecord(validationType, AppraisalStatus.Status.FAIL,
|
||||||
result.getMessage(), pc, Level.WARN);
|
result.getMessage(), pc, Level.WARN);
|
||||||
case ERROR:
|
case ERROR:
|
||||||
|
@ -74,6 +74,7 @@ public class ComponentIdentifier {
|
|||||||
private ASN1ObjectIdentifier componentManufacturerId;
|
private ASN1ObjectIdentifier componentManufacturerId;
|
||||||
private ASN1Boolean fieldReplaceable;
|
private ASN1Boolean fieldReplaceable;
|
||||||
private List<ComponentAddress> componentAddress;
|
private List<ComponentAddress> componentAddress;
|
||||||
|
private boolean validationResult = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
@ -264,6 +265,24 @@ public class ComponentIdentifier {
|
|||||||
return false;
|
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.
|
* 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";
|
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
|
* Ensure that BouncyCastle is configured as a javax.security.Security provider, as this
|
||||||
* class expects it to be available.
|
* class expects it to be available.
|
||||||
@ -318,8 +316,6 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
final Map<PlatformCredential, SupplyChainValidation> deltaMapping) {
|
final Map<PlatformCredential, SupplyChainValidation> deltaMapping) {
|
||||||
String message;
|
String message;
|
||||||
|
|
||||||
LOGGER.error("Starting the method validateDeltaPlatformCredentialAttributes");
|
|
||||||
|
|
||||||
// this needs to be a loop for all deltas, link to issue #110
|
// this needs to be a loop for all deltas, link to issue #110
|
||||||
// check that they don't have the same serial number
|
// check that they don't have the same serial number
|
||||||
for (PlatformCredential delta : deltaMapping.keySet()) {
|
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.
|
// parse out the provided delta and its specific chain.
|
||||||
List<ComponentIdentifier> origPcComponents
|
List<ComponentIdentifier> origPcComponents
|
||||||
= new LinkedList<>(basePlatformCredential.getComponentIdentifiers());
|
= new LinkedList<>(basePlatformCredential.getComponentIdentifiers());
|
||||||
@ -560,9 +555,15 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
return new AppraisalStatus(ERROR, baseErrorMessage + e.getMessage());
|
return new AppraisalStatus(ERROR, baseErrorMessage + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringBuilder additionalInfo = new StringBuilder();
|
||||||
if (!fieldValidation) {
|
if (!fieldValidation) {
|
||||||
resultMessage.append("There are unmatched components:\n");
|
resultMessage.append("There are unmatched components:\n");
|
||||||
resultMessage.append(unmatchedComponents);
|
resultMessage.append(unmatchedComponents);
|
||||||
|
|
||||||
|
// pass information of which ones failed in additionInfo
|
||||||
|
for (ComponentIdentifier ci : validPcComponents) {
|
||||||
|
additionalInfo.append(String.format("%d;", ci.hashCode()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
passesValidation &= fieldValidation;
|
passesValidation &= fieldValidation;
|
||||||
@ -570,7 +571,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
if (passesValidation) {
|
if (passesValidation) {
|
||||||
return new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID);
|
return new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID);
|
||||||
} else {
|
} 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
|
// finished up
|
||||||
List<ArchivableEntity> certificateList = null;
|
List<ArchivableEntity> certificateList = null;
|
||||||
SupplyChainValidation scv = null;
|
SupplyChainValidation scv = null;
|
||||||
|
StringBuilder deltaSb = new StringBuilder();
|
||||||
|
|
||||||
// non-empty serial values
|
// non-empty serial values
|
||||||
for (ComponentIdentifier deltaCi : leftOverDeltas) {
|
for (ComponentIdentifier deltaCi : leftOverDeltas) {
|
||||||
@ -653,6 +655,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
if (ciV2.isAdded()) {
|
if (ciV2.isAdded()) {
|
||||||
// error
|
// error
|
||||||
resultMessage.append("ADDED attempted with prior instance\n");
|
resultMessage.append("ADDED attempted with prior instance\n");
|
||||||
|
deltaSb.append(String.format("%s;", ci.hashCode()));
|
||||||
}
|
}
|
||||||
if (ciV2.isModified()) {
|
if (ciV2.isModified()) {
|
||||||
// since the base list doesn't have this ci
|
// 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
|
// error because you can't modify something
|
||||||
// that isn't here
|
// that isn't here
|
||||||
resultMessage.append("MODIFIED attempted without prior instance\n");
|
resultMessage.append("MODIFIED attempted without prior instance\n");
|
||||||
|
deltaSb.append(String.format("%s;", ci.hashCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ciV2.isRemoved()) {
|
if (ciV2.isRemoved()) {
|
||||||
// error because you can't remove something
|
// error because you can't remove something
|
||||||
// that isn't here
|
// that isn't here
|
||||||
resultMessage.append("REMOVED attempted without prior instance\n");
|
resultMessage.append("REMOVED attempted without prior instance\n");
|
||||||
|
deltaSb.append(String.format("%s;", ci.hashCode()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fieldValidation) {
|
if (!fieldValidation) {
|
||||||
return new AppraisalStatus(FAIL, resultMessage.toString());
|
return new AppraisalStatus(FAIL, resultMessage.toString(), deltaSb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
String paccorOutputString = deviceInfoReport.getPaccorOutputString();
|
String paccorOutputString = deviceInfoReport.getPaccorOutputString();
|
||||||
@ -766,7 +771,6 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
|
|
||||||
if (!subCompInfoList.isEmpty()) {
|
if (!subCompInfoList.isEmpty()) {
|
||||||
for (ComponentInfo ci : subCompInfoList) {
|
for (ComponentInfo ci : subCompInfoList) {
|
||||||
LOGGER.error("For subComInfoList -> {}", ci.getComponentSerial());
|
|
||||||
invalidDeviceInfo.append(String.format("%d;",
|
invalidDeviceInfo.append(String.format("%d;",
|
||||||
ci.hashCode()));
|
ci.hashCode()));
|
||||||
}
|
}
|
||||||
@ -783,6 +787,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
* components not represented in the platform credential.
|
* components not represented in the platform credential.
|
||||||
*
|
*
|
||||||
* @param untrimmedPcComponents the platform credential components (may contain end whitespace)
|
* @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
|
* @param allDeviceInfoComponents the device info report components
|
||||||
* @return true if validation passes
|
* @return true if validation passes
|
||||||
*/
|
*/
|
||||||
@ -813,8 +819,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
componentSerial, componentRevision,
|
componentSerial, componentRevision,
|
||||||
component.getComponentManufacturerId(),
|
component.getComponentManufacturerId(),
|
||||||
component.getFieldReplaceable(),
|
component.getFieldReplaceable(),
|
||||||
component.getComponentAddress()
|
component.getComponentAddress()));
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.info("Validating the following Platform Cert components...");
|
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:");
|
LOGGER.info("...against the the following DeviceInfoReport components:");
|
||||||
allDeviceInfoComponents.forEach(component -> LOGGER.info(component.toString()));
|
allDeviceInfoComponents.forEach(component -> LOGGER.info(component.toString()));
|
||||||
Set<DERUTF8String> manufacturerSet = new HashSet<>();
|
Set<DERUTF8String> manufacturerSet = new HashSet<>();
|
||||||
pcComponents.forEach(component -> manufacturerSet.add(
|
pcComponents.forEach(pcComp -> manufacturerSet.add(pcComp.getComponentManufacturer()));
|
||||||
component.getComponentManufacturer()));
|
|
||||||
|
|
||||||
// Create a list for unmatched components across all manufacturers to display at the end.
|
// Create a list for unmatched components across all manufacturers to display at the end.
|
||||||
List<ComponentIdentifier> pcUnmatchedComponents = new ArrayList<>();
|
List<ComponentIdentifier> pcUnmatchedComponents = new ArrayList<>();
|
||||||
@ -859,8 +863,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
.filter(componentInfo
|
.filter(componentInfo
|
||||||
-> StringUtils.isNotEmpty(componentInfo.getComponentSerial()))
|
-> StringUtils.isNotEmpty(componentInfo.getComponentSerial()))
|
||||||
.filter(componentInfo -> componentInfo.getComponentSerial()
|
.filter(componentInfo -> componentInfo.getComponentSerial()
|
||||||
.equals(pcComponent.getComponentSerial().getString()))
|
.equals(pcComponent.getComponentSerial().getString())).findFirst();
|
||||||
.findFirst();
|
|
||||||
|
|
||||||
if (first.isPresent()) {
|
if (first.isPresent()) {
|
||||||
ComponentInfo potentialMatch = first.get();
|
ComponentInfo potentialMatch = first.get();
|
||||||
@ -905,12 +908,11 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
// just match them.
|
// just match them.
|
||||||
List<ComponentIdentifier> templist = new ArrayList<>(pcComponentsFromManufacturer);
|
List<ComponentIdentifier> templist = new ArrayList<>(pcComponentsFromManufacturer);
|
||||||
for (ComponentIdentifier ci : templist) {
|
for (ComponentIdentifier ci : templist) {
|
||||||
ComponentIdentifier pcComponent = ci;
|
|
||||||
Iterator<ComponentInfo> diComponentIter
|
Iterator<ComponentInfo> diComponentIter
|
||||||
= deviceInfoComponentsFromManufacturer.iterator();
|
= deviceInfoComponentsFromManufacturer.iterator();
|
||||||
while (diComponentIter.hasNext()) {
|
while (diComponentIter.hasNext()) {
|
||||||
ComponentInfo potentialMatch = diComponentIter.next();
|
ComponentInfo potentialMatch = diComponentIter.next();
|
||||||
if (isMatch(pcComponent, potentialMatch)) {
|
if (isMatch(ci, potentialMatch)) {
|
||||||
pcComponentsFromManufacturer.remove(ci);
|
pcComponentsFromManufacturer.remove(ci);
|
||||||
diComponentIter.remove();
|
diComponentIter.remove();
|
||||||
}
|
}
|
||||||
@ -920,6 +922,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!pcUnmatchedComponents.isEmpty()) {
|
if (!pcUnmatchedComponents.isEmpty()) {
|
||||||
|
untrimmedPcComponents.clear();
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
LOGGER.error(String.format("Platform Credential contained %d unmatched components:",
|
LOGGER.error(String.format("Platform Credential contained %d unmatched components:",
|
||||||
pcUnmatchedComponents.size()));
|
pcUnmatchedComponents.size()));
|
||||||
@ -933,6 +936,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
unmatchedComponent.getComponentModel(),
|
unmatchedComponent.getComponentModel(),
|
||||||
unmatchedComponent.getComponentSerial(),
|
unmatchedComponent.getComponentSerial(),
|
||||||
unmatchedComponent.getComponentRevision()));
|
unmatchedComponent.getComponentRevision()));
|
||||||
|
unmatchedComponent.setValidationResult(false);
|
||||||
|
untrimmedPcComponents.add(unmatchedComponent);
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
@ -1664,13 +1669,4 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
return false;
|
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…
x
Reference in New Issue
Block a user