mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-19 04:58:00 +00:00
This latest push should have the code that'll highlight the components based on a string rather than the serial number. This also adds additional checks for the validity begin date of the delta not matching or being before the base. It also checks that they don't have the same certificate serial number.
This commit is contained in:
parent
f38fa87013
commit
7028810707
@ -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<PlatformCredential> platformCredentials = parsePcsFromIdentityClaim(claim,
|
||||
endorsementCredential);
|
||||
Map<BigInteger, PlatformCredential> 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);
|
||||
|
@ -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<SupplyChainValidation> validations = new LinkedList<>();
|
||||
Map<PlatformCredential, SupplyChainValidation> 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<PlatformCredential> 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);
|
||||
if (platformScv.getResult() == FAIL) {
|
||||
pcErrorMessage = String.format("%s%s%n", pcErrorMessage,
|
||||
platformScv.getMessage());
|
||||
}
|
||||
} else {
|
||||
validationTypeMap.put(platformType, platformScv);
|
||||
}
|
||||
|
||||
// set the base credential
|
||||
if (pc.isBase()) {
|
||||
baseCredential = pc;
|
||||
LOGGER.error("Found the base Certificate");
|
||||
} 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,
|
||||
pcErrorMessage = String.format("%s%s%n", pcErrorMessage,
|
||||
"Delta Certificate's validity "
|
||||
+ "date is not after Base",
|
||||
null, Level.ERROR));
|
||||
+ "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;
|
||||
|
||||
List<ArchivableEntity> 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<PlatformCredential> 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())));
|
||||
}
|
||||
} 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);
|
||||
if (attributeScv.getResult() == FAIL) {
|
||||
attrErrorMessage = String.format("%s%s%n", attrErrorMessage,
|
||||
attributeScv.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!attrErrorMessage.isEmpty()) {
|
||||
//combine platform and platform attributes
|
||||
validations.remove(platformScv);
|
||||
attributeScv = validationTypeMap.get(
|
||||
platformAttrType);
|
||||
if (platformScv.getResult() == PASS && attributeScv.getResult() == FAIL) {
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<String, Object> entry : data.entrySet()) {
|
||||
LOGGER.error(String.format("%s -> %s", entry.getKey(),
|
||||
String.valueOf(entry.getValue())));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -316,35 +316,29 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
final DeviceInfoReport deviceInfoReport,
|
||||
final PlatformCredential basePlatformCredential,
|
||||
final Map<PlatformCredential, SupplyChainValidation> 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);
|
||||
}
|
||||
|
||||
// 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(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(),
|
||||
.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.
|
||||
List<ComponentIdentifier> origPcComponents
|
||||
@ -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<ComponentInfo> componentInfoList
|
||||
// = getComponentInfoFromPaccorOutput(paccorOutputString);
|
||||
// compare based on component class
|
||||
List<ComponentInfo> 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
|
||||
|
Loading…
Reference in New Issue
Block a user