mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-01-30 16:13:55 +00:00
* This pull request contains 2 main changes, the first is transferring the status text from the attributes failure to the icon specifically for platform trust chain validation. Then this removes the third column on the validation page that singles out the icons for the attribute status. In addition, this status is also rolled up to the summary status icon and displays the text there as well for all that have failed. This last change meant a change to the sizes of the columns in the database. The validation of a single base certificate with an error was not handled in the code base. Due to the changes with the introduction of delta certifications, the validation was modified and only handled changes presented by the deltas and ignored errors in the base certificate. This commit modifies the code that if there is just a single base certificate that is bad and error is thrown.
This commit is contained in:
parent
aa707b8665
commit
7cfabe756d
@ -12,14 +12,13 @@ import org.springframework.context.annotation.Import;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.HashMap;
|
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
import hirs.appraiser.Appraiser;
|
import hirs.appraiser.Appraiser;
|
||||||
import hirs.appraiser.SupplyChainAppraiser;
|
import hirs.appraiser.SupplyChainAppraiser;
|
||||||
@ -41,6 +40,8 @@ import hirs.persist.DBManagerException;
|
|||||||
import hirs.persist.PersistenceConfiguration;
|
import hirs.persist.PersistenceConfiguration;
|
||||||
import hirs.persist.PolicyManager;
|
import hirs.persist.PolicyManager;
|
||||||
import hirs.validation.CredentialValidator;
|
import hirs.validation.CredentialValidator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main executor of supply chain verification tasks. The AbstractAttestationCertificateAuthority
|
* The main executor of supply chain verification tasks. The AbstractAttestationCertificateAuthority
|
||||||
@ -102,17 +103,16 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
SupplyChainPolicy policy = (SupplyChainPolicy) policyManager.getDefaultPolicy(
|
SupplyChainPolicy policy = (SupplyChainPolicy) policyManager.getDefaultPolicy(
|
||||||
supplyChainAppraiser);
|
supplyChainAppraiser);
|
||||||
boolean acceptExpiredCerts = policy.isExpiredCertificateValidationEnabled();
|
boolean acceptExpiredCerts = policy.isExpiredCertificateValidationEnabled();
|
||||||
HashMap<PlatformCredential, SupplyChainValidation> credentialMap = new HashMap<>();
|
|
||||||
PlatformCredential baseCredential = null;
|
PlatformCredential baseCredential = null;
|
||||||
List<SupplyChainValidation> validations = new LinkedList<>();
|
List<SupplyChainValidation> validations = new LinkedList<>();
|
||||||
List<SupplyChainValidation> deltaValidations = new LinkedList<>();
|
Map<SupplyChainValidation.ValidationType,
|
||||||
|
SupplyChainValidation> validationTypeMap = new HashMap<>();
|
||||||
// validate all supply chain pieces. Potentially, a policy setting could be made
|
Map<PlatformCredential, SupplyChainValidation> deltaMapping = new HashMap<>();
|
||||||
// to dictate stopping after the first validation failure.
|
|
||||||
|
|
||||||
// Validate the Endorsement Credential
|
// Validate the Endorsement Credential
|
||||||
if (policy.isEcValidationEnabled()) {
|
if (policy.isEcValidationEnabled()) {
|
||||||
validations.add(validateEndorsementCredential(ec, acceptExpiredCerts));
|
validationTypeMap.put(SupplyChainValidation.ValidationType.ENDORSEMENT_CREDENTIAL,
|
||||||
|
validateEndorsementCredential(ec, acceptExpiredCerts));
|
||||||
// store the device with the credential
|
// store the device with the credential
|
||||||
if (null != ec) {
|
if (null != ec) {
|
||||||
ec.setDevice(device);
|
ec.setDevice(device);
|
||||||
@ -125,7 +125,9 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
// Ensure there are platform credentials to validate
|
// Ensure there are platform credentials to validate
|
||||||
if (pcs == null || pcs.isEmpty()) {
|
if (pcs == null || pcs.isEmpty()) {
|
||||||
LOGGER.error("There were no Platform Credentials to validate.");
|
LOGGER.error("There were no Platform Credentials to validate.");
|
||||||
validations.add(buildValidationRecord(
|
validationTypeMap.put(SupplyChainValidation
|
||||||
|
.ValidationType.PLATFORM_CREDENTIAL,
|
||||||
|
buildValidationRecord(
|
||||||
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL,
|
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL,
|
||||||
AppraisalStatus.Status.FAIL,
|
AppraisalStatus.Status.FAIL,
|
||||||
"Platform credential(s) missing", null, Level.ERROR));
|
"Platform credential(s) missing", null, Level.ERROR));
|
||||||
@ -137,20 +139,17 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
SupplyChainValidation platformScv = validatePlatformCredential(
|
SupplyChainValidation platformScv = validatePlatformCredential(
|
||||||
pc, trustedCa, acceptExpiredCerts);
|
pc, trustedCa, acceptExpiredCerts);
|
||||||
|
|
||||||
// check if this cert has been verified for multiple base associated
|
// check if this cert has been verified for multiple base
|
||||||
// with the serial number
|
// associated with the serial number
|
||||||
if (pc != null) {
|
if (pc != null) {
|
||||||
platformScv = validatePcPolicy(pc, platformScv,
|
platformScv = validatePcPolicy(pc, platformScv,
|
||||||
deltaValidations, acceptExpiredCerts);
|
deltaMapping, acceptExpiredCerts);
|
||||||
}
|
|
||||||
validations.add(platformScv);
|
validationTypeMap.put(SupplyChainValidation
|
||||||
if (!deltaValidations.isEmpty()) {
|
.ValidationType.PLATFORM_CREDENTIAL,
|
||||||
validations.addAll(deltaValidations);
|
platformScv);
|
||||||
}
|
|
||||||
if (pc != null) {
|
|
||||||
pc.setDevice(device);
|
pc.setDevice(device);
|
||||||
this.certificateManager.update(pc);
|
this.certificateManager.update(pc);
|
||||||
credentialMap.put(pc, platformScv);
|
|
||||||
if (pc.isBase()) {
|
if (pc.isBase()) {
|
||||||
baseCredential = pc;
|
baseCredential = pc;
|
||||||
}
|
}
|
||||||
@ -164,53 +163,30 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
// Ensure there are platform credentials to validate
|
// Ensure there are platform credentials to validate
|
||||||
if (pcs == null || pcs.isEmpty()) {
|
if (pcs == null || pcs.isEmpty()) {
|
||||||
LOGGER.error("There were no Platform Credentials to validate attributes.");
|
LOGGER.error("There were no Platform Credentials to validate attributes.");
|
||||||
validations.add(buildValidationRecord(
|
validationTypeMap.put(SupplyChainValidation
|
||||||
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES,
|
.ValidationType.PLATFORM_CREDENTIAL,
|
||||||
|
buildValidationRecord(
|
||||||
|
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL,
|
||||||
AppraisalStatus.Status.FAIL,
|
AppraisalStatus.Status.FAIL,
|
||||||
"Platform credential(s) missing. Cannot validate attributes",
|
"Platform credential(s) missing.\nPlatform credential(s) missing."
|
||||||
|
+ " Cannot validate attributes",
|
||||||
null, Level.ERROR));
|
null, Level.ERROR));
|
||||||
} else {
|
} else {
|
||||||
Iterator<PlatformCredential> it = pcs.iterator();
|
Iterator<PlatformCredential> it = pcs.iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
PlatformCredential pc = it.next();
|
PlatformCredential pc = it.next();
|
||||||
SupplyChainValidation attributeScv;
|
SupplyChainValidation attributeScv;
|
||||||
if (baseCredential == null || pc == baseCredential && !pc.isDeltaChain()) {
|
if (baseCredential == null || pc == baseCredential) {
|
||||||
attributeScv = validatePlatformCredentialAttributes(
|
attributeScv = validatePlatformCredentialAttributes(
|
||||||
pc, device.getDeviceInfo(), ec);
|
pc, device.getDeviceInfo(), ec);
|
||||||
} else {
|
validationTypeMap.put(SupplyChainValidation
|
||||||
List<PlatformCredential> chainCertificates = PlatformCredential
|
.ValidationType.PLATFORM_CREDENTIAL,
|
||||||
.select(certificateManager)
|
attributeScv);
|
||||||
.byBoardSerialNumber(pc.getPlatformSerial())
|
|
||||||
.getCertificates().stream().collect(Collectors.toList());
|
|
||||||
Collections.sort(chainCertificates,
|
|
||||||
new Comparator<PlatformCredential>() {
|
|
||||||
@Override
|
|
||||||
public int compare(final PlatformCredential obj1,
|
|
||||||
final PlatformCredential obj2) {
|
|
||||||
return obj1.getBeginValidity()
|
|
||||||
.compareTo(obj2.getBeginValidity());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
attributeScv = validateDeltaPlatformCredentialAttributes(
|
|
||||||
pc, device.getDeviceInfo(), baseCredential, chainCertificates);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SupplyChainValidation platformScv = credentialMap.get(pc);
|
if (pc != null && pc.isDeltaChain()) {
|
||||||
if (platformScv != null) {
|
validateDeltaPlatformCredentialAttributes(
|
||||||
if (platformScv.getResult() == AppraisalStatus.Status.FAIL
|
pc, device.getDeviceInfo(), baseCredential, deltaMapping);
|
||||||
|| platformScv.getResult() == AppraisalStatus.Status.ERROR) {
|
|
||||||
if (attributeScv != null
|
|
||||||
&& attributeScv.getResult() == AppraisalStatus.Status.PASS) {
|
|
||||||
validations.add(buildValidationRecord(
|
|
||||||
SupplyChainValidation.ValidationType
|
|
||||||
.PLATFORM_CREDENTIAL_ATTRIBUTES,
|
|
||||||
AppraisalStatus.Status.FAIL,
|
|
||||||
platformScv.getMessage(), pc, Level.WARN));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
validations.add(attributeScv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pc != null) {
|
if (pc != null) {
|
||||||
@ -221,6 +197,14 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!validationTypeMap.isEmpty()) {
|
||||||
|
validations.addAll(validationTypeMap.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!deltaMapping.isEmpty()) {
|
||||||
|
validations.addAll(deltaMapping.values());
|
||||||
|
}
|
||||||
|
|
||||||
// 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);
|
||||||
@ -244,7 +228,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
private SupplyChainValidation validatePcPolicy(
|
private SupplyChainValidation validatePcPolicy(
|
||||||
final PlatformCredential pc,
|
final PlatformCredential pc,
|
||||||
final SupplyChainValidation platformScv,
|
final SupplyChainValidation platformScv,
|
||||||
final List<SupplyChainValidation> deltaValidations,
|
final Map<PlatformCredential, SupplyChainValidation> deltaMapping,
|
||||||
final boolean acceptExpiredCerts) {
|
final boolean acceptExpiredCerts) {
|
||||||
SupplyChainValidation subPlatformScv = platformScv;
|
SupplyChainValidation subPlatformScv = platformScv;
|
||||||
|
|
||||||
@ -263,26 +247,34 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
AppraisalStatus.Status.FAIL,
|
AppraisalStatus.Status.FAIL,
|
||||||
message, pc, Level.ERROR);
|
message, pc, Level.ERROR);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Grab all certs associated with this platform chain
|
// Grab all certs associated with this platform chain
|
||||||
List<PlatformCredential> chainCertificates = PlatformCredential
|
List<PlatformCredential> chainCertificates = PlatformCredential
|
||||||
.select(certificateManager)
|
.select(certificateManager)
|
||||||
.byBoardSerialNumber(pc.getPlatformSerial())
|
.byBoardSerialNumber(pc.getPlatformSerial())
|
||||||
.getCertificates().stream().collect(Collectors.toList());
|
.getCertificates().stream().collect(Collectors.toList());
|
||||||
|
Collections.sort(chainCertificates,
|
||||||
|
new Comparator<PlatformCredential>() {
|
||||||
|
@Override
|
||||||
|
public int compare(final PlatformCredential obj1,
|
||||||
|
final PlatformCredential obj2) {
|
||||||
|
return obj1.getBeginValidity()
|
||||||
|
.compareTo(obj2.getBeginValidity());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
SupplyChainValidation deltaScv;
|
SupplyChainValidation deltaScv;
|
||||||
KeyStore trustedCa;
|
KeyStore trustedCa;
|
||||||
// verify that the deltas trust chain is valid.
|
// verify that the deltas trust chain is valid.
|
||||||
for (PlatformCredential delta : chainCertificates) {
|
for (PlatformCredential delta : chainCertificates) {
|
||||||
if (delta != null && !delta.isBase()) {
|
if (delta != null && !delta.isBase()) {
|
||||||
trustedCa = getCaChain(delta);
|
trustedCa = getCaChain(delta);
|
||||||
deltaScv = validatePlatformCredential(
|
deltaScv = validatePlatformCredential(
|
||||||
delta, trustedCa, acceptExpiredCerts);
|
delta, trustedCa, acceptExpiredCerts);
|
||||||
deltaValidations.add(deltaScv);
|
deltaMapping.put(delta, deltaScv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return subPlatformScv;
|
return subPlatformScv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,7 +344,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
final DeviceInfoReport deviceInfoReport,
|
final DeviceInfoReport deviceInfoReport,
|
||||||
final EndorsementCredential ec) {
|
final EndorsementCredential ec) {
|
||||||
final SupplyChainValidation.ValidationType validationType
|
final SupplyChainValidation.ValidationType validationType
|
||||||
= SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES;
|
= SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL;
|
||||||
|
|
||||||
if (pc == null) {
|
if (pc == null) {
|
||||||
LOGGER.error("No platform credential to validate");
|
LOGGER.error("No platform credential to validate");
|
||||||
@ -383,7 +375,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
final PlatformCredential delta,
|
final PlatformCredential delta,
|
||||||
final DeviceInfoReport deviceInfoReport,
|
final DeviceInfoReport deviceInfoReport,
|
||||||
final PlatformCredential base,
|
final PlatformCredential base,
|
||||||
final List<PlatformCredential> chainCertificates) {
|
final Map<PlatformCredential, SupplyChainValidation> deltaMapping) {
|
||||||
final SupplyChainValidation.ValidationType validationType =
|
final SupplyChainValidation.ValidationType validationType =
|
||||||
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES;
|
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES;
|
||||||
|
|
||||||
@ -396,7 +388,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
LOGGER.info("Validating delta platform certificate attributes");
|
LOGGER.info("Validating delta platform certificate attributes");
|
||||||
AppraisalStatus result = supplyChainCredentialValidator.
|
AppraisalStatus result = supplyChainCredentialValidator.
|
||||||
validateDeltaPlatformCredentialAttributes(delta, deviceInfoReport,
|
validateDeltaPlatformCredentialAttributes(delta, deviceInfoReport,
|
||||||
base, chainCertificates);
|
base, deltaMapping);
|
||||||
switch (result.getAppStatus()) {
|
switch (result.getAppStatus()) {
|
||||||
case PASS:
|
case PASS:
|
||||||
return buildValidationRecord(validationType, AppraisalStatus.Status.PASS,
|
return buildValidationRecord(validationType, AppraisalStatus.Status.PASS,
|
||||||
|
@ -144,7 +144,6 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest
|
|||||||
//when(delta.getSerialNumber()).thenReturn(BigInteger.ONE);
|
//when(delta.getSerialNumber()).thenReturn(BigInteger.ONE);
|
||||||
when(delta.getIssuerOrganization()).thenReturn("STMicroelectronics NV");
|
when(delta.getIssuerOrganization()).thenReturn("STMicroelectronics NV");
|
||||||
when(delta.getSubjectOrganization()).thenReturn("STMicroelectronics NV");
|
when(delta.getSubjectOrganization()).thenReturn("STMicroelectronics NV");
|
||||||
//pcs.add(delta);
|
|
||||||
|
|
||||||
Set<Certificate> resultPcs = new HashSet<>();
|
Set<Certificate> resultPcs = new HashSet<>();
|
||||||
resultPcs.add(pc);
|
resultPcs.add(pc);
|
||||||
@ -242,7 +241,7 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest
|
|||||||
validateEndorsementCredential(eq(ec), any(KeyStore.class), eq(true));
|
validateEndorsementCredential(eq(ec), any(KeyStore.class), eq(true));
|
||||||
doReturn(new AppraisalStatus(FAIL, "")).when(supplyChainCredentialValidator).
|
doReturn(new AppraisalStatus(FAIL, "")).when(supplyChainCredentialValidator).
|
||||||
validatePlatformCredential(eq(pc), any(KeyStore.class), eq(true));
|
validatePlatformCredential(eq(pc), any(KeyStore.class), eq(true));
|
||||||
doReturn(new AppraisalStatus(PASS, "")).when(supplyChainCredentialValidator)
|
doReturn(new AppraisalStatus(FAIL, "")).when(supplyChainCredentialValidator)
|
||||||
.validatePlatformCredentialAttributes(eq(pc), any(DeviceInfoReport.class),
|
.validatePlatformCredentialAttributes(eq(pc), any(DeviceInfoReport.class),
|
||||||
any(EndorsementCredential.class));
|
any(EndorsementCredential.class));
|
||||||
Assert.assertEquals(service.validateSupplyChain(ec, pcs,
|
Assert.assertEquals(service.validateSupplyChain(ec, pcs,
|
||||||
|
@ -616,12 +616,12 @@
|
|||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<c:choose>
|
<c:choose>
|
||||||
<c:when test="${component.isVersion2()=='TRUE'}">
|
<c:when test="${component.isVersion2()=='TRUE'}">
|
||||||
<span data-toggle="tooltip" data-placement="top" title="Component Class">${component.getComponentClass()}</span>
|
<span data-toggle="tooltip" data-placement="top" title="Component Class">${component.getComponentClass()}</span>
|
||||||
</c:when>
|
</c:when>
|
||||||
<c:otherwise>
|
<c:otherwise>
|
||||||
<span data-toggle="tooltip" data-placement="top" title="Component Class">Platform Components</span>
|
<span data-toggle="tooltip" data-placement="top" title="Component Class">Platform Components</span>
|
||||||
</c:otherwise>
|
</c:otherwise>
|
||||||
</c:choose>
|
</c:choose>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
@ -649,22 +649,22 @@
|
|||||||
<span class="label label-danger">Irreplaceable</span><br/>
|
<span class="label label-danger">Irreplaceable</span><br/>
|
||||||
</c:otherwise>
|
</c:otherwise>
|
||||||
</c:choose>
|
</c:choose>
|
||||||
<c:if test="${component.isVersion2()}">
|
<c:if test="${component.isVersion2()}">
|
||||||
<c:if test="${not empty component.getCertificateIdentifier()}">
|
<c:if test="${not empty component.getCertificateIdentifier()}">
|
||||||
<span class="fieldHeader">Platform Certificate Issuer:</span>
|
<span class="fieldHeader">Platform Certificate Issuer:</span>
|
||||||
<span class="fieldValue">${component.getCertificateIdentifier().getIssuerDN()}</span><br />
|
<span class="fieldValue">${component.getCertificateIdentifier().getIssuerDN()}</span><br />
|
||||||
<span class="fieldHeader">Platform Certificate Serial Number:</span>
|
<span class="fieldHeader">Platform Certificate Serial Number:</span>
|
||||||
<span class="fieldValue">${component.getCertificateIdentifier().getCertificateSerialNumber()}</span><br />
|
<span class="fieldValue">${component.getCertificateIdentifier().getCertificateSerialNumber()}</span><br />
|
||||||
<span class="fieldHeader">Platform Certificate URI:</span>
|
<span class="fieldHeader">Platform Certificate URI:</span>
|
||||||
</c:if>
|
|
||||||
<span class="fieldValue">
|
|
||||||
<a href="${component.getComponentPlatformUri().getUniformResourceIdentifier()}">
|
|
||||||
${component.getComponentPlatformUri().getUniformResourceIdentifier()}
|
|
||||||
</a>
|
|
||||||
</span><br />
|
|
||||||
<span class="fieldHeader">Status:</span>
|
|
||||||
<span class="fieldValue">${component.getAttributeStatus()}</span><br/>
|
|
||||||
</c:if>
|
</c:if>
|
||||||
|
<span class="fieldValue">
|
||||||
|
<a href="${component.getComponentPlatformUri().getUniformResourceIdentifier()}">
|
||||||
|
${component.getComponentPlatformUri().getUniformResourceIdentifier()}
|
||||||
|
</a>
|
||||||
|
</span><br />
|
||||||
|
<span class="fieldHeader">Status:</span>
|
||||||
|
<span class="fieldValue">${component.getAttributeStatus()}</span><br/>
|
||||||
|
</c:if>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -826,10 +826,10 @@
|
|||||||
</c:otherwise>
|
</c:otherwise>
|
||||||
</c:choose>
|
</c:choose>
|
||||||
|
|
||||||
<c:if test="${not empty initialData.authSerialNumber}">
|
<c:if test="${not empty initialData.authSerialNumber}">
|
||||||
//Convert string to serial String
|
//Convert string to serial String
|
||||||
$("#authSerialNumber").html(parseSerialNumber(authoritySerialNumber));
|
$("#authSerialNumber").html(parseSerialNumber(authoritySerialNumber));
|
||||||
</c:if>
|
</c:if>
|
||||||
<c:choose>
|
<c:choose>
|
||||||
<c:when test="${not empty initialData.publicKeyValue}">
|
<c:when test="${not empty initialData.publicKeyValue}">
|
||||||
var publicKey = '${initialData.publicKeyValue}';
|
var publicKey = '${initialData.publicKeyValue}';
|
||||||
|
@ -32,12 +32,12 @@
|
|||||||
<th rowspan="2">Result</th>
|
<th rowspan="2">Result</th>
|
||||||
<th rowspan="2">Timestamp</th>
|
<th rowspan="2">Timestamp</th>
|
||||||
<th rowspan="2">Device</th>
|
<th rowspan="2">Device</th>
|
||||||
<th colspan="3">Credential Validations</th>
|
<th colspan="2">Credential Validations</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Endorsement</th>
|
<th style="text-align:center">Endorsement</th>
|
||||||
<th>Platform</th>
|
<th style="text-align:center">Platform</th>
|
||||||
<th>Platform Attributes</th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
@ -55,16 +55,17 @@
|
|||||||
|
|
||||||
// create status icon
|
// create status icon
|
||||||
var result = full.overallValidationResult;
|
var result = full.overallValidationResult;
|
||||||
|
var ovallMessage = full.message;
|
||||||
if (result) {
|
if (result) {
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case "PASS":
|
case "PASS":
|
||||||
html += '<img src="${passIcon}" title="${passText}"/>';
|
html += '<img src="${passIcon}" title="${passText}"/>';
|
||||||
break;
|
break;
|
||||||
case "FAIL":
|
case "FAIL":
|
||||||
html += '<img src="${failIcon}" title="${failText}"/>';
|
html += '<img src="${failIcon}" title="' + ovallMessage + '"/>';
|
||||||
break;
|
break;
|
||||||
case "ERROR":
|
case "ERROR":
|
||||||
html += '<img src="${errorIcon}" title="${errorText}"/>';
|
html += '<img src="${errorIcon}" title="' + ovallMessage + '"/>';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
html += unknownStatus;
|
html += unknownStatus;
|
||||||
@ -161,7 +162,7 @@
|
|||||||
|
|
||||||
html += '<a href="${portal}/certificate-details?id='
|
html += '<a href="${portal}/certificate-details?id='
|
||||||
+ curValidation.certificatesUsed[0].id
|
+ curValidation.certificatesUsed[0].id
|
||||||
+ '&type=' + certType + '">'
|
+ '&type=' + certType + '">';
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (curResult) {
|
switch (curResult) {
|
||||||
|
@ -15,6 +15,13 @@ import org.hibernate.annotations.Type;
|
|||||||
*/
|
*/
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
public abstract class AbstractEntity {
|
public abstract class AbstractEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* static value for the length of a status message for objects that
|
||||||
|
* can have extremely long values, potentially.
|
||||||
|
*/
|
||||||
|
protected static final int RESULT_MESSAGE_LENGTH = 1000000;
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@Column(name = "id")
|
@Column(name = "id")
|
||||||
@GeneratedValue(generator = "uuid2")
|
@GeneratedValue(generator = "uuid2")
|
||||||
|
@ -29,8 +29,6 @@ import javax.xml.bind.annotation.XmlTransient;
|
|||||||
@JsonSerialize(using = AppraisalResultSerializer.class)
|
@JsonSerialize(using = AppraisalResultSerializer.class)
|
||||||
public class AppraisalResult extends AbstractEntity {
|
public class AppraisalResult extends AbstractEntity {
|
||||||
|
|
||||||
private static final int RESULT_MESSAGE_LENGTH = 1000000;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Corresponding <code>Appraiser</code>. Can be NULL.
|
* Corresponding <code>Appraiser</code>. Can be NULL.
|
||||||
*/
|
*/
|
||||||
|
@ -22,22 +22,24 @@ public class NetworkInfo implements Serializable {
|
|||||||
private static final Logger LOGGER = LogManager
|
private static final Logger LOGGER = LogManager
|
||||||
.getLogger(NetworkInfo.class);
|
.getLogger(NetworkInfo.class);
|
||||||
|
|
||||||
|
private static final int LONG_STRING_LENGTH = 255;
|
||||||
|
private static final int SHORT_STRING_LENGTH = 32;
|
||||||
private static final int NUM_MAC_ADDRESS_BYTES = 6;
|
private static final int NUM_MAC_ADDRESS_BYTES = 6;
|
||||||
|
|
||||||
@XmlElement
|
@XmlElement
|
||||||
@Column(length = 255, nullable = true)
|
@Column(length = LONG_STRING_LENGTH, nullable = true)
|
||||||
@SuppressWarnings("checkstyle:magicnumber")
|
@SuppressWarnings("checkstyle:magicnumber")
|
||||||
private String hostname;
|
private String hostname;
|
||||||
|
|
||||||
@XmlElement
|
@XmlElement
|
||||||
@XmlJavaTypeAdapter(value = InetAddressXmlAdapter.class)
|
@XmlJavaTypeAdapter(value = InetAddressXmlAdapter.class)
|
||||||
@SuppressWarnings("checkstyle:magicnumber")
|
@SuppressWarnings("checkstyle:magicnumber")
|
||||||
@Column(length = 32, nullable = true)
|
@Column(length = SHORT_STRING_LENGTH, nullable = true)
|
||||||
@Type(type = "hirs.data.persist.type.InetAddressType")
|
@Type(type = "hirs.data.persist.type.InetAddressType")
|
||||||
private InetAddress ipAddress;
|
private InetAddress ipAddress;
|
||||||
|
|
||||||
@XmlElement
|
@XmlElement
|
||||||
@Column(length = 6, nullable = true)
|
@Column(length = NUM_MAC_ADDRESS_BYTES, nullable = true)
|
||||||
@SuppressWarnings("checkstyle:magicnumber")
|
@SuppressWarnings("checkstyle:magicnumber")
|
||||||
private byte[] macAddress;
|
private byte[] macAddress;
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import java.util.HashSet;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import org.apache.logging.log4j.util.Strings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A container class to group multiple related {@link SupplyChainValidation} instances
|
* A container class to group multiple related {@link SupplyChainValidation} instances
|
||||||
@ -42,6 +43,9 @@ public class SupplyChainValidationSummary extends ArchivableEntity {
|
|||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private final AppraisalStatus.Status overallValidationResult;
|
private final AppraisalStatus.Status overallValidationResult;
|
||||||
|
|
||||||
|
@Column(length = RESULT_MESSAGE_LENGTH)
|
||||||
|
private final String message;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER,
|
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER,
|
||||||
targetEntity = SupplyChainValidation.class, orphanRemoval = true)
|
targetEntity = SupplyChainValidation.class, orphanRemoval = true)
|
||||||
private final Set<SupplyChainValidation> validations;
|
private final Set<SupplyChainValidation> validations;
|
||||||
@ -53,6 +57,7 @@ public class SupplyChainValidationSummary extends ArchivableEntity {
|
|||||||
this.device = null;
|
this.device = null;
|
||||||
overallValidationResult = AppraisalStatus.Status.FAIL;
|
overallValidationResult = AppraisalStatus.Status.FAIL;
|
||||||
validations = Collections.emptySet();
|
validations = Collections.emptySet();
|
||||||
|
this.message = Strings.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -183,9 +188,10 @@ public class SupplyChainValidationSummary extends ArchivableEntity {
|
|||||||
|
|
||||||
|
|
||||||
this.device = device;
|
this.device = device;
|
||||||
this.overallValidationResult = calculateValidationResult(validations);
|
AppraisalStatus status = calculateValidationResult(validations);
|
||||||
|
this.overallValidationResult = status.getAppStatus();
|
||||||
this.validations = new HashSet<>(validations);
|
this.validations = new HashSet<>(validations);
|
||||||
|
this.message = status.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,6 +210,13 @@ public class SupplyChainValidationSummary extends ArchivableEntity {
|
|||||||
return overallValidationResult;
|
return overallValidationResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fail message if there is a failure.
|
||||||
|
*/
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the validations that this summary contains
|
* @return the validations that this summary contains
|
||||||
*/
|
*/
|
||||||
@ -217,17 +230,20 @@ public class SupplyChainValidationSummary extends ArchivableEntity {
|
|||||||
* @param validations the validations to evaluate
|
* @param validations the validations to evaluate
|
||||||
* @return the overall appraisal result
|
* @return the overall appraisal result
|
||||||
*/
|
*/
|
||||||
private AppraisalStatus.Status calculateValidationResult(
|
private AppraisalStatus calculateValidationResult(
|
||||||
final Collection<SupplyChainValidation> validations) {
|
final Collection<SupplyChainValidation> validations) {
|
||||||
boolean hasAnyFailures = false;
|
boolean hasAnyFailures = false;
|
||||||
|
StringBuilder failureMsg = new StringBuilder();
|
||||||
|
|
||||||
for (SupplyChainValidation validation : validations) {
|
for (SupplyChainValidation validation : validations) {
|
||||||
switch (validation.getResult()) {
|
switch (validation.getResult()) {
|
||||||
// if any error, then process overall as error immediately.
|
// if any error, then process overall as error immediately.
|
||||||
case ERROR:
|
case ERROR:
|
||||||
return AppraisalStatus.Status.ERROR;
|
return new AppraisalStatus(AppraisalStatus.Status.ERROR,
|
||||||
|
validation.getMessage());
|
||||||
case FAIL:
|
case FAIL:
|
||||||
hasAnyFailures = true;
|
hasAnyFailures = true;
|
||||||
|
failureMsg.append(validation.getMessage());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -236,8 +252,10 @@ public class SupplyChainValidationSummary extends ArchivableEntity {
|
|||||||
}
|
}
|
||||||
// if failures, but no error, indicate failure result.
|
// if failures, but no error, indicate failure result.
|
||||||
if (hasAnyFailures) {
|
if (hasAnyFailures) {
|
||||||
return AppraisalStatus.Status.FAIL;
|
return new AppraisalStatus(AppraisalStatus.Status.FAIL,
|
||||||
|
failureMsg.toString());
|
||||||
}
|
}
|
||||||
return AppraisalStatus.Status.PASS;
|
return new AppraisalStatus(AppraisalStatus.Status.PASS,
|
||||||
|
Strings.EMPTY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,12 @@ package hirs.validation;
|
|||||||
|
|
||||||
import hirs.data.persist.AppraisalStatus;
|
import hirs.data.persist.AppraisalStatus;
|
||||||
import hirs.data.persist.DeviceInfoReport;
|
import hirs.data.persist.DeviceInfoReport;
|
||||||
|
import hirs.data.persist.SupplyChainValidation;
|
||||||
import hirs.data.persist.certificate.EndorsementCredential;
|
import hirs.data.persist.certificate.EndorsementCredential;
|
||||||
import hirs.data.persist.certificate.PlatformCredential;
|
import hirs.data.persist.certificate.PlatformCredential;
|
||||||
|
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class used to support supply chain validation by performing the actual
|
* A class used to support supply chain validation by performing the actual
|
||||||
@ -44,14 +45,15 @@ public interface CredentialValidator {
|
|||||||
* serial number of the platform to be validated.
|
* serial number of the platform to be validated.
|
||||||
* @param base the base credential from the same identity request
|
* @param base the base credential from the same identity request
|
||||||
* as the delta credential.
|
* as the delta credential.
|
||||||
* @param chainCertificates base and delta certificates associated with the
|
* @param deltaMapping delta certificates associated with the
|
||||||
* delta being validated.
|
* delta supply validation.
|
||||||
* @return the result of the validation.
|
* @return the result of the validation.
|
||||||
*/
|
*/
|
||||||
AppraisalStatus validateDeltaPlatformCredentialAttributes(PlatformCredential delta,
|
AppraisalStatus validateDeltaPlatformCredentialAttributes(PlatformCredential delta,
|
||||||
DeviceInfoReport deviceInfoReport,
|
DeviceInfoReport deviceInfoReport,
|
||||||
PlatformCredential base,
|
PlatformCredential base,
|
||||||
List<PlatformCredential> chainCertificates);
|
Map<PlatformCredential,
|
||||||
|
SupplyChainValidation> deltaMapping);
|
||||||
/**
|
/**
|
||||||
* Checks if the endorsement credential is valid.
|
* Checks if the endorsement credential is valid.
|
||||||
*
|
*
|
||||||
|
@ -55,6 +55,8 @@ import java.util.stream.Collectors;
|
|||||||
import static hirs.data.persist.AppraisalStatus.Status.ERROR;
|
import static hirs.data.persist.AppraisalStatus.Status.ERROR;
|
||||||
import static hirs.data.persist.AppraisalStatus.Status.FAIL;
|
import static hirs.data.persist.AppraisalStatus.Status.FAIL;
|
||||||
import static hirs.data.persist.AppraisalStatus.Status.PASS;
|
import static hirs.data.persist.AppraisalStatus.Status.PASS;
|
||||||
|
import hirs.data.persist.SupplyChainValidation;
|
||||||
|
import hirs.data.persist.certificate.Certificate;
|
||||||
import hirs.data.persist.certificate.attributes.V2.ComponentIdentifierV2;
|
import hirs.data.persist.certificate.attributes.V2.ComponentIdentifierV2;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -87,6 +89,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
public static final String PLATFORM_ATTRIBUTES_VALID =
|
public static final String PLATFORM_ATTRIBUTES_VALID =
|
||||||
"Platform credential attributes validated";
|
"Platform credential attributes 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.
|
||||||
@ -135,7 +139,6 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
return node.findValue(fieldName).asText();
|
return node.findValue(fieldName).asText();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -153,16 +156,15 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
final String baseErrorMessage = "Can't validate platform credential without ";
|
final String baseErrorMessage = "Can't validate platform credential without ";
|
||||||
String message;
|
String message;
|
||||||
if (pc == null) {
|
if (pc == null) {
|
||||||
message = baseErrorMessage + "a platform credential";
|
message = baseErrorMessage + "a platform credential\n";
|
||||||
LOGGER.error(message);
|
LOGGER.error(message);
|
||||||
return new AppraisalStatus(FAIL, message);
|
return new AppraisalStatus(FAIL, message);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (trustStore == null || trustStore.size() == 0) {
|
if (trustStore == null || trustStore.size() == 0) {
|
||||||
message = baseErrorMessage + "a trust store";
|
message = baseErrorMessage + "a trust store\n";
|
||||||
LOGGER.error(message);
|
LOGGER.error(message);
|
||||||
return new AppraisalStatus(FAIL, message);
|
return new AppraisalStatus(FAIL, message);
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (KeyStoreException e) {
|
} catch (KeyStoreException e) {
|
||||||
message = baseErrorMessage + "an intitialized trust store";
|
message = baseErrorMessage + "an intitialized trust store";
|
||||||
@ -261,8 +263,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
* serial number of the platform to be validated.
|
* serial number of the platform to be validated.
|
||||||
* @param basePlatformCredential the base credential from the same identity request
|
* @param basePlatformCredential the base credential from the same identity request
|
||||||
* as the delta credential.
|
* as the delta credential.
|
||||||
* @param chainCertificates base and delta certificates associated with the
|
* @param deltaMapping delta certificates associated with the
|
||||||
* delta being validated.
|
* delta supply validation.
|
||||||
* @return the result of the validation.
|
* @return the result of the validation.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@ -270,7 +272,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
final PlatformCredential deltaPlatformCredential,
|
final PlatformCredential deltaPlatformCredential,
|
||||||
final DeviceInfoReport deviceInfoReport,
|
final DeviceInfoReport deviceInfoReport,
|
||||||
final PlatformCredential basePlatformCredential,
|
final PlatformCredential basePlatformCredential,
|
||||||
final List<PlatformCredential> chainCertificates) {
|
final Map<PlatformCredential, SupplyChainValidation> deltaMapping) {
|
||||||
final String baseErrorMessage = "Can't validate delta platform"
|
final String baseErrorMessage = "Can't validate delta platform"
|
||||||
+ "certificate attributes without ";
|
+ "certificate attributes without ";
|
||||||
String message;
|
String message;
|
||||||
@ -302,30 +304,11 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parse out the provided delta and its specific chain.
|
// parse out the provided delta and its specific chain.
|
||||||
Collections.reverse(chainCertificates);
|
List<ComponentIdentifier> origPcComponents
|
||||||
List<PlatformCredential> leafChain = new LinkedList<>();
|
= new LinkedList<>(basePlatformCredential.getComponentIdentifiers());
|
||||||
List<ComponentIdentifier> origPcComponents = new LinkedList<>();
|
|
||||||
|
|
||||||
for (PlatformCredential pc : chainCertificates) {
|
|
||||||
if (pc.isBase()) {
|
|
||||||
if (basePlatformCredential.getSerialNumber()
|
|
||||||
.equals(pc.getSerialNumber())) {
|
|
||||||
// get original component list
|
|
||||||
origPcComponents.addAll(pc.getComponentIdentifiers());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
leafChain.add(pc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// map the deltas to their holder serial numbers
|
|
||||||
Map<String, PlatformCredential> leafMap = new HashMap<>();
|
|
||||||
leafChain.stream().forEach((delta) -> {
|
|
||||||
leafMap.put(delta.getHolderSerialNumber().toString(), delta);
|
|
||||||
});
|
|
||||||
|
|
||||||
return validateDeltaAttributesChainV2p0(deviceInfoReport,
|
return validateDeltaAttributesChainV2p0(deviceInfoReport,
|
||||||
leafChain, origPcComponents);
|
deltaMapping, origPcComponents);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AppraisalStatus validatePlatformCredentialAttributesV1p2(
|
private static AppraisalStatus validatePlatformCredentialAttributesV1p2(
|
||||||
@ -561,19 +544,17 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
* are valid.
|
* are valid.
|
||||||
*
|
*
|
||||||
* @param deviceInfoReport The paccor profile of device being validated against.
|
* @param deviceInfoReport The paccor profile of device being validated against.
|
||||||
* @param leafChain The specific chain associated with delta cert being
|
* @param deltaMapping map of delta certificates to their validated status
|
||||||
* validated.
|
|
||||||
* @param origPcComponents The component identifier list associated with the
|
* @param origPcComponents The component identifier list associated with the
|
||||||
* base cert for this specific chain
|
* base cert for this specific chain
|
||||||
* @return Appraisal Status of delta being validated.
|
* @return Appraisal Status of delta being validated.
|
||||||
*/
|
*/
|
||||||
static AppraisalStatus validateDeltaAttributesChainV2p0(
|
static AppraisalStatus validateDeltaAttributesChainV2p0(
|
||||||
final DeviceInfoReport deviceInfoReport,
|
final DeviceInfoReport deviceInfoReport,
|
||||||
final List<PlatformCredential> leafChain,
|
final Map<PlatformCredential, SupplyChainValidation> deltaMapping,
|
||||||
final List<ComponentIdentifier> origPcComponents) {
|
final List<ComponentIdentifier> origPcComponents) {
|
||||||
boolean fieldValidation = true;
|
boolean fieldValidation = true;
|
||||||
StringBuilder resultMessage = new StringBuilder();
|
StringBuilder resultMessage = new StringBuilder();
|
||||||
StringBuilder deltaMessage = new StringBuilder();
|
|
||||||
List<ComponentIdentifier> validOrigPcComponents = origPcComponents.stream()
|
List<ComponentIdentifier> validOrigPcComponents = origPcComponents.stream()
|
||||||
.filter(identifier -> identifier.getComponentManufacturer() != null
|
.filter(identifier -> identifier.getComponentManufacturer() != null
|
||||||
&& identifier.getComponentModel() != null)
|
&& identifier.getComponentModel() != null)
|
||||||
@ -587,9 +568,20 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
});
|
});
|
||||||
|
|
||||||
String ciSerial;
|
String ciSerial;
|
||||||
|
List<Certificate> certificateList = null;
|
||||||
|
PlatformCredential delta = 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
|
// go through the leaf and check the changes against the valid components
|
||||||
// forget modifying validOrigPcComponents
|
// forget modifying validOrigPcComponents
|
||||||
for (PlatformCredential delta : leafChain) {
|
for (Map.Entry<PlatformCredential, SupplyChainValidation> deltaEntry
|
||||||
|
: deltaMapping.entrySet()) {
|
||||||
|
StringBuilder failureMsg = new StringBuilder();
|
||||||
|
delta = deltaEntry.getKey();
|
||||||
|
certificateList = new ArrayList<>();
|
||||||
|
certificateList.add(delta);
|
||||||
|
|
||||||
for (ComponentIdentifier ci : delta.getComponentIdentifiers()) {
|
for (ComponentIdentifier ci : delta.getComponentIdentifiers()) {
|
||||||
if (ci.isVersion2()) {
|
if (ci.isVersion2()) {
|
||||||
ciSerial = ci.getComponentSerial().toString();
|
ciSerial = ci.getComponentSerial().toString();
|
||||||
@ -599,9 +591,18 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
// check it is there
|
// check it is there
|
||||||
if (!chainCiMapping.containsKey(ciSerial)) {
|
if (!chainCiMapping.containsKey(ciSerial)) {
|
||||||
fieldValidation = false;
|
fieldValidation = false;
|
||||||
deltaMessage.append(String.format(
|
failureMsg.append(String.format(
|
||||||
"%s attempted MODIFIED with no prior instance.%n",
|
"%s attempted MODIFIED with no prior instance.%n",
|
||||||
ciSerial));
|
ciSerial));
|
||||||
|
scv = deltaEntry.getValue();
|
||||||
|
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 {
|
} else {
|
||||||
chainCiMapping.put(ci.getComponentSerial().toString(), ci);
|
chainCiMapping.put(ci.getComponentSerial().toString(), ci);
|
||||||
}
|
}
|
||||||
@ -609,9 +610,18 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
if (!chainCiMapping.containsKey(ciSerial)) {
|
if (!chainCiMapping.containsKey(ciSerial)) {
|
||||||
// error thrown, can't remove if it doesn't exist
|
// error thrown, can't remove if it doesn't exist
|
||||||
fieldValidation = false;
|
fieldValidation = false;
|
||||||
deltaMessage.append(String.format(
|
failureMsg.append(String.format(
|
||||||
"%s attempted REMOVED with no prior instance.%n",
|
"%s attempted REMOVED with no prior instance.%n",
|
||||||
ciSerial));
|
ciSerial));
|
||||||
|
scv = deltaEntry.getValue();
|
||||||
|
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 {
|
} else {
|
||||||
chainCiMapping.remove(ci.getComponentSerial().toString());
|
chainCiMapping.remove(ci.getComponentSerial().toString());
|
||||||
}
|
}
|
||||||
@ -620,9 +630,18 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
if (chainCiMapping.containsKey(ciSerial)) {
|
if (chainCiMapping.containsKey(ciSerial)) {
|
||||||
// error, shouldn't exist
|
// error, shouldn't exist
|
||||||
fieldValidation = false;
|
fieldValidation = false;
|
||||||
deltaMessage.append(String.format(
|
failureMsg.append(String.format(
|
||||||
"%s was ADDED, the serial already exists.%n",
|
"%s was ADDED, the serial already exists.%n",
|
||||||
ciSerial));
|
ciSerial));
|
||||||
|
scv = deltaEntry.getValue();
|
||||||
|
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 {
|
} else {
|
||||||
// have to add in case later it is removed
|
// have to add in case later it is removed
|
||||||
chainCiMapping.put(ciSerial, ci);
|
chainCiMapping.put(ciSerial, ci);
|
||||||
@ -630,11 +649,11 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resultMessage.append(failureMsg.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fieldValidation) {
|
if (!fieldValidation) {
|
||||||
resultMessage.append("There are errors with Delta Component Statuses components:\n");
|
|
||||||
resultMessage.append(deltaMessage.toString());
|
|
||||||
return new AppraisalStatus(FAIL, resultMessage.toString());
|
return new AppraisalStatus(FAIL, resultMessage.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -654,6 +673,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!fieldValidation) {
|
if (!fieldValidation) {
|
||||||
|
resultMessage = new StringBuilder();
|
||||||
resultMessage.append("There are unmatched components:\n");
|
resultMessage.append("There are unmatched components:\n");
|
||||||
resultMessage.append(unmatchedComponents);
|
resultMessage.append(unmatchedComponents);
|
||||||
|
|
||||||
@ -1407,4 +1427,13 @@ 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import hirs.data.persist.HardwareInfo;
|
|||||||
import hirs.data.persist.NICComponentInfo;
|
import hirs.data.persist.NICComponentInfo;
|
||||||
import hirs.data.persist.NetworkInfo;
|
import hirs.data.persist.NetworkInfo;
|
||||||
import hirs.data.persist.OSInfo;
|
import hirs.data.persist.OSInfo;
|
||||||
|
import hirs.data.persist.SupplyChainValidation;
|
||||||
import hirs.data.persist.TPMInfo;
|
import hirs.data.persist.TPMInfo;
|
||||||
import hirs.data.persist.certificate.Certificate;
|
import hirs.data.persist.certificate.Certificate;
|
||||||
import hirs.data.persist.certificate.CertificateAuthorityCredential;
|
import hirs.data.persist.certificate.CertificateAuthorityCredential;
|
||||||
@ -79,8 +80,10 @@ import java.security.spec.X509EncodedKeySpec;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.powermock.api.mockito.PowerMockito.mock;
|
import static org.powermock.api.mockito.PowerMockito.mock;
|
||||||
@ -1158,7 +1161,8 @@ public class SupplyChainCredentialValidatorTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public final void verifyPlatformCredentialNullCredentialPath() {
|
public final void verifyPlatformCredentialNullCredentialPath() {
|
||||||
String expectedMessage = "Can't validate platform credential without a platform credential";
|
String expectedMessage = "Can't validate platform credential without "
|
||||||
|
+ "a platform credential\n";
|
||||||
|
|
||||||
AppraisalStatus result = supplyChainCredentialValidator.validatePlatformCredential(
|
AppraisalStatus result = supplyChainCredentialValidator.validatePlatformCredential(
|
||||||
null, keyStore, true);
|
null, keyStore, true);
|
||||||
@ -1182,7 +1186,7 @@ public class SupplyChainCredentialValidatorTest {
|
|||||||
PlatformCredential pc = new PlatformCredential(certBytes);
|
PlatformCredential pc = new PlatformCredential(certBytes);
|
||||||
|
|
||||||
String expectedMessage = "Can't validate platform credential without a "
|
String expectedMessage = "Can't validate platform credential without a "
|
||||||
+ "trust store";
|
+ "trust store\n";
|
||||||
|
|
||||||
AppraisalStatus result = supplyChainCredentialValidator.validatePlatformCredential(pc, null,
|
AppraisalStatus result = supplyChainCredentialValidator.validatePlatformCredential(pc, null,
|
||||||
true);
|
true);
|
||||||
@ -2092,10 +2096,22 @@ public class SupplyChainCredentialValidatorTest {
|
|||||||
when(delta1.getComponentIdentifiers()).thenReturn(delta1List);
|
when(delta1.getComponentIdentifiers()).thenReturn(delta1List);
|
||||||
when(delta2.getComponentIdentifiers()).thenReturn(delta2List);
|
when(delta2.getComponentIdentifiers()).thenReturn(delta2List);
|
||||||
|
|
||||||
List<PlatformCredential> chainCredentials = new ArrayList<>(0);
|
Map<PlatformCredential, SupplyChainValidation> chainCredentials = new HashMap<>(0);
|
||||||
chainCredentials.add(base);
|
List<Certificate> certsUsed = new ArrayList<>();
|
||||||
chainCredentials.add(delta1);
|
certsUsed.add(base);
|
||||||
chainCredentials.add(delta2);
|
chainCredentials.put(base, new SupplyChainValidation(
|
||||||
|
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL,
|
||||||
|
AppraisalStatus.Status.PASS, certsUsed, ""));
|
||||||
|
certsUsed.clear();
|
||||||
|
certsUsed.add(delta1);
|
||||||
|
chainCredentials.put(delta1, new SupplyChainValidation(
|
||||||
|
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL,
|
||||||
|
AppraisalStatus.Status.PASS, certsUsed, ""));
|
||||||
|
certsUsed.clear();
|
||||||
|
certsUsed.add(delta2);
|
||||||
|
chainCredentials.put(delta2, new SupplyChainValidation(
|
||||||
|
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL,
|
||||||
|
AppraisalStatus.Status.PASS, certsUsed, ""));
|
||||||
|
|
||||||
AppraisalStatus result = supplyChainCredentialValidator
|
AppraisalStatus result = supplyChainCredentialValidator
|
||||||
.validateDeltaPlatformCredentialAttributes(delta2,
|
.validateDeltaPlatformCredentialAttributes(delta2,
|
||||||
@ -2185,9 +2201,17 @@ public class SupplyChainCredentialValidatorTest {
|
|||||||
when(base.getComponentIdentifiers()).thenReturn(compList);
|
when(base.getComponentIdentifiers()).thenReturn(compList);
|
||||||
when(delta1.getComponentIdentifiers()).thenReturn(delta1List);
|
when(delta1.getComponentIdentifiers()).thenReturn(delta1List);
|
||||||
|
|
||||||
List<PlatformCredential> chainCredentials = new ArrayList<>(0);
|
Map<PlatformCredential, SupplyChainValidation> chainCredentials = new HashMap<>(0);
|
||||||
chainCredentials.add(base);
|
List<Certificate> certsUsed = new ArrayList<>();
|
||||||
chainCredentials.add(delta1);
|
certsUsed.add(base);
|
||||||
|
chainCredentials.put(base, new SupplyChainValidation(
|
||||||
|
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL,
|
||||||
|
AppraisalStatus.Status.PASS, certsUsed, ""));
|
||||||
|
certsUsed.clear();
|
||||||
|
certsUsed.add(delta1);
|
||||||
|
chainCredentials.put(delta1, new SupplyChainValidation(
|
||||||
|
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL,
|
||||||
|
AppraisalStatus.Status.PASS, certsUsed, ""));
|
||||||
|
|
||||||
AppraisalStatus result = supplyChainCredentialValidator
|
AppraisalStatus result = supplyChainCredentialValidator
|
||||||
.validateDeltaPlatformCredentialAttributes(delta1,
|
.validateDeltaPlatformCredentialAttributes(delta1,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user