Merge pull request #869 from nsacyber/v3_issue-848

[#848] Rename properties and methods of firmware validation objects
This commit is contained in:
iadgovuser26 2024-11-15 09:28:30 -05:00 committed by GitHub
commit d0faa39a15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 149 additions and 136 deletions

View File

@ -1,6 +1,5 @@
package hirs.attestationca.persist.provision; package hirs.attestationca.persist.provision;
import com.fasterxml.jackson.databind.ser.Serializers;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2; import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
import hirs.attestationca.persist.entity.manager.CertificateRepository; import hirs.attestationca.persist.entity.manager.CertificateRepository;
@ -69,24 +68,23 @@ import java.util.regex.Pattern;
@Log4j2 @Log4j2
public class IdentityClaimProcessor extends AbstractProcessor { public class IdentityClaimProcessor extends AbstractProcessor {
private static final String PCR_QUOTE_MASK = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,"
+ "14,15,16,17,18,19,20,21,22,23";
private static final int NUM_OF_VARIABLES = 5;
/** /**
* Number of bytes to include in the TPM2.0 nonce. * Number of bytes to include in the TPM2.0 nonce.
*/ */
public static final int NONCE_LENGTH = 20; public static final int NONCE_LENGTH = 20;
private static final String PCR_QUOTE_MASK = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,"
+ "14,15,16,17,18,19,20,21,22,23";
private static final int NUM_OF_VARIABLES = 5;
private static final int MAC_BYTES = 6; private static final int MAC_BYTES = 6;
private SupplyChainValidationService supplyChainValidationService; private final SupplyChainValidationService supplyChainValidationService;
private CertificateRepository certificateRepository; private final CertificateRepository certificateRepository;
private ComponentResultRepository componentResultRepository; private final ComponentResultRepository componentResultRepository;
private ComponentInfoRepository componentInfoRepository; private final ComponentInfoRepository componentInfoRepository;
private ReferenceManifestRepository referenceManifestRepository; private final ReferenceManifestRepository referenceManifestRepository;
private ReferenceDigestValueRepository referenceDigestValueRepository; private final ReferenceDigestValueRepository referenceDigestValueRepository;
private DeviceRepository deviceRepository; private final DeviceRepository deviceRepository;
private TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository; private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
/** /**
* Constructor. * Constructor.
@ -116,8 +114,8 @@ public class IdentityClaimProcessor extends AbstractProcessor {
* Basic implementation of the ACA processIdentityClaimTpm2 method. Parses the claim, * Basic implementation of the ACA processIdentityClaimTpm2 method. Parses the claim,
* stores the device info, performs supply chain validation, generates a nonce, * stores the device info, performs supply chain validation, generates a nonce,
* and wraps that nonce with the make credential process before returning it to the client. * and wraps that nonce with the make credential process before returning it to the client.
* attCert.setPcrValues(pcrValues); * attCert.setPcrValues(pcrValues);
*
* @param identityClaim the request to process, cannot be null * @param identityClaim the request to process, cannot be null
* @return an identity claim response for the specified request containing a wrapped blob * @return an identity claim response for the specified request containing a wrapped blob
*/ */
@ -147,7 +145,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
} }
} }
ByteString blobStr = ByteString.copyFrom(new byte[]{}); ByteString blobStr = ByteString.copyFrom(new byte[] {});
if (validationResult == AppraisalStatus.Status.PASS) { if (validationResult == AppraisalStatus.Status.PASS) {
RSAPublicKey akPub = ProvisionUtils.parsePublicKey(claim.getAkPublicArea().toByteArray()); RSAPublicKey akPub = ProvisionUtils.parsePublicKey(claim.getAkPublicArea().toByteArray());
byte[] nonce = ProvisionUtils.generateRandomBytes(NONCE_LENGTH); byte[] nonce = ProvisionUtils.generateRandomBytes(NONCE_LENGTH);
@ -195,7 +193,8 @@ public class IdentityClaimProcessor extends AbstractProcessor {
private AppraisalStatus.Status doSupplyChainValidation( private AppraisalStatus.Status doSupplyChainValidation(
final ProvisionerTpm2.IdentityClaim claim, final PublicKey ekPub) { final ProvisionerTpm2.IdentityClaim claim, final PublicKey ekPub) {
// attempt to find an endorsement credential to validate // attempt to find an endorsement credential to validate
EndorsementCredential endorsementCredential = parseEcFromIdentityClaim(claim, ekPub, certificateRepository); EndorsementCredential endorsementCredential =
parseEcFromIdentityClaim(claim, ekPub, certificateRepository);
// attempt to find platform credentials to validate // attempt to find platform credentials to validate
List<PlatformCredential> platformCredentials = parsePcsFromIdentityClaim(claim, List<PlatformCredential> platformCredentials = parsePcsFromIdentityClaim(claim,
@ -283,6 +282,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
/** /**
* Converts a protobuf DeviceInfo object to a HIRS Utils DeviceInfoReport object. * Converts a protobuf DeviceInfo object to a HIRS Utils DeviceInfoReport object.
*
* @param claim the protobuf serialized identity claim containing the device info * @param claim the protobuf serialized identity claim containing the device info
* @return a HIRS Utils DeviceInfoReport representation of device info * @return a HIRS Utils DeviceInfoReport representation of device info
*/ */
@ -348,69 +348,69 @@ public class IdentityClaimProcessor extends AbstractProcessor {
String defaultClientName = String.format("%s_%s", String defaultClientName = String.format("%s_%s",
dv.getHw().getManufacturer(), dv.getHw().getManufacturer(),
dv.getHw().getProductName()); dv.getHw().getProductName());
BaseReferenceManifest dbBaseRim = null; BaseReferenceManifest baseRim = null;
SupportReferenceManifest support = null; SupportReferenceManifest supportRim = null;
EventLogMeasurements measurements; EventLogMeasurements integrityMeasurements;
boolean isReplacement = false; boolean isReplacement = false;
String replacementRimId = ""; String replacementRimId = "";
String tagId = ""; String tagId = "";
String fileName = ""; String fileName = "";
Pattern pattern = Pattern.compile("([^\\s]+(\\.(?i)(rimpcr|rimel|bin|log))$)"); Pattern pattern = Pattern.compile("([^\\s]+(\\.(?i)(rimpcr|rimel|bin|log))$)");
Matcher matcher; Matcher matcher;
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
if (dv.getSwidfileCount() > 0) { if (dv.getSwidfileCount() > 0) {
for (ByteString swidFile : dv.getSwidfileList()) { for (ByteString swidFile : dv.getSwidfileList()) {
try { try {
dbBaseRim = (BaseReferenceManifest) referenceManifestRepository baseRim = (BaseReferenceManifest) referenceManifestRepository
.findByBase64Hash(Base64.getEncoder() .findByBase64Hash(Base64.getEncoder()
.encodeToString(messageDigest .encodeToString(messageDigest
.digest(swidFile.toByteArray()))); .digest(swidFile.toByteArray())));
if (dbBaseRim == null) { if (baseRim == null) {
/* /*
Either the swidFile does not have a corresponding base RIM in the backend Either the swidFile does not have a corresponding base RIM in the backend
or it was deleted. Check if there is a replacement by comparing tagId against or it was deleted. Check if there is a replacement by comparing tagId against
all other base RIMs, and then set the corresponding support rim's deviceName. all other base RIMs, and then set the corresponding support rim's deviceName.
*/ */
dbBaseRim = new BaseReferenceManifest( baseRim = new BaseReferenceManifest(
String.format("%s.swidtag", String.format("%s.swidtag",
defaultClientName), defaultClientName),
swidFile.toByteArray()); swidFile.toByteArray());
List<BaseReferenceManifest> baseRims = referenceManifestRepository.findAllBaseRims(); List<BaseReferenceManifest> baseRims = referenceManifestRepository.findAllBaseRims();
for (BaseReferenceManifest bRim : baseRims) { for (BaseReferenceManifest bRim : baseRims) {
if (bRim.getTagId().equals(dbBaseRim.getTagId())) { if (bRim.getTagId().equals(baseRim.getTagId())) {
dbBaseRim = bRim; baseRim = bRim;
replacementRimId = dbBaseRim.getAssociatedRim().toString(); replacementRimId = baseRim.getAssociatedRim().toString();
isReplacement = true; isReplacement = true;
break; break;
} }
} }
dbBaseRim.setDeviceName(dv.getNw().getHostname()); baseRim.setDeviceName(dv.getNw().getHostname());
this.referenceManifestRepository.save(dbBaseRim); this.referenceManifestRepository.save(baseRim);
} else if (dbBaseRim.isArchived()) { } else if (baseRim.isArchived()) {
/* /*
This block accounts for RIMs that may have been soft-deleted (archived) This block accounts for RIMs that may have been soft-deleted (archived)
in an older version of the ACA. in an older version of the ACA.
*/ */
List<ReferenceManifest> rims = referenceManifestRepository.findByArchiveFlag(false); List<ReferenceManifest> rims = referenceManifestRepository.findByArchiveFlag(false);
for (ReferenceManifest rim : rims) { for (ReferenceManifest rim : rims) {
if (rim.isBase() && rim.getTagId().equals(dbBaseRim.getTagId()) && if (rim.isBase() && rim.getTagId().equals(baseRim.getTagId()) &&
rim.getCreateTime().after(dbBaseRim.getCreateTime())) { rim.getCreateTime().after(baseRim.getCreateTime())) {
dbBaseRim.setDeviceName(null); baseRim.setDeviceName(null);
dbBaseRim = (BaseReferenceManifest) rim; baseRim = (BaseReferenceManifest) rim;
dbBaseRim.setDeviceName(dv.getNw().getHostname()); baseRim.setDeviceName(dv.getNw().getHostname());
} }
} }
if (dbBaseRim.isArchived()) { if (baseRim.isArchived()) {
throw new Exception("Unable to locate an unarchived base RIM."); throw new Exception("Unable to locate an unarchived base RIM.");
} else { } else {
this.referenceManifestRepository.save(dbBaseRim); this.referenceManifestRepository.save(baseRim);
} }
} else { } else {
dbBaseRim.setDeviceName(dv.getNw().getHostname()); baseRim.setDeviceName(dv.getNw().getHostname());
this.referenceManifestRepository.save(dbBaseRim); this.referenceManifestRepository.save(baseRim);
} }
tagId = dbBaseRim.getTagId(); tagId = baseRim.getTagId();
} catch (UnmarshalException e) { } catch (UnmarshalException e) {
log.error(e); log.error(e);
} catch (Exception ex) { } catch (Exception ex) {
@ -425,10 +425,11 @@ public class IdentityClaimProcessor extends AbstractProcessor {
if (dv.getLogfileCount() > 0) { if (dv.getLogfileCount() > 0) {
for (ByteString logFile : dv.getLogfileList()) { for (ByteString logFile : dv.getLogfileList()) {
try { try {
support = (SupportReferenceManifest) referenceManifestRepository.findByHexDecHashAndRimType( supportRim =
(SupportReferenceManifest) referenceManifestRepository.findByHexDecHashAndRimType(
Hex.encodeHexString(messageDigest.digest(logFile.toByteArray())), Hex.encodeHexString(messageDigest.digest(logFile.toByteArray())),
ReferenceManifest.SUPPORT_RIM); ReferenceManifest.SUPPORT_RIM);
if (support == null) { if (supportRim == null) {
/* /*
Either the logFile does not have a corresponding support RIM in the backend Either the logFile does not have a corresponding support RIM in the backend
or it was deleted. The support RIM for a replacement base RIM is handled or it was deleted. The support RIM for a replacement base RIM is handled
@ -438,28 +439,28 @@ public class IdentityClaimProcessor extends AbstractProcessor {
Optional<ReferenceManifest> replacementRim = Optional<ReferenceManifest> replacementRim =
referenceManifestRepository.findById(UUID.fromString(replacementRimId)); referenceManifestRepository.findById(UUID.fromString(replacementRimId));
if (replacementRim.isPresent()) { if (replacementRim.isPresent()) {
support = (SupportReferenceManifest) replacementRim.get(); supportRim = (SupportReferenceManifest) replacementRim.get();
support.setDeviceName(dv.getNw().getHostname()); supportRim.setDeviceName(dv.getNw().getHostname());
} else { } else {
throw new Exception("Unable to locate support RIM " + replacementRimId); throw new Exception("Unable to locate support RIM " + replacementRimId);
} }
} else { } else {
support = new SupportReferenceManifest( supportRim = new SupportReferenceManifest(
String.format("%s.rimel", String.format("%s.rimel",
defaultClientName), defaultClientName),
logFile.toByteArray()); logFile.toByteArray());
// this is a validity check // this is a validity check
new TCGEventLog(support.getRimBytes()); new TCGEventLog(supportRim.getRimBytes());
// no issues, continue // no issues, continue
support.setPlatformManufacturer(dv.getHw().getManufacturer()); supportRim.setPlatformManufacturer(dv.getHw().getManufacturer());
support.setPlatformModel(dv.getHw().getProductName()); supportRim.setPlatformModel(dv.getHw().getProductName());
support.setFileName(String.format("%s_[%s].rimel", defaultClientName, supportRim.setFileName(String.format("%s_[%s].rimel", defaultClientName,
support.getHexDecHash().substring( supportRim.getHexDecHash().substring(
support.getHexDecHash().length() - NUM_OF_VARIABLES))); supportRim.getHexDecHash().length() - NUM_OF_VARIABLES)));
} }
support.setDeviceName(dv.getNw().getHostname()); supportRim.setDeviceName(dv.getNw().getHostname());
this.referenceManifestRepository.save(support); this.referenceManifestRepository.save(supportRim);
} else if (support.isArchived()) { } else if (supportRim.isArchived()) {
/* /*
This block accounts for RIMs that may have been soft-deleted (archived) This block accounts for RIMs that may have been soft-deleted (archived)
in an older version of the ACA. in an older version of the ACA.
@ -467,21 +468,21 @@ public class IdentityClaimProcessor extends AbstractProcessor {
List<ReferenceManifest> rims = referenceManifestRepository.findByArchiveFlag(false); List<ReferenceManifest> rims = referenceManifestRepository.findByArchiveFlag(false);
for (ReferenceManifest rim : rims) { for (ReferenceManifest rim : rims) {
if (rim.isSupport() && if (rim.isSupport() &&
rim.getTagId().equals(support.getTagId()) && rim.getTagId().equals(supportRim.getTagId()) &&
rim.getCreateTime().after(support.getCreateTime())) { rim.getCreateTime().after(supportRim.getCreateTime())) {
support.setDeviceName(null); supportRim.setDeviceName(null);
support = (SupportReferenceManifest) rim; supportRim = (SupportReferenceManifest) rim;
support.setDeviceName(dv.getNw().getHostname()); supportRim.setDeviceName(dv.getNw().getHostname());
} }
} }
if (support.isArchived()) { if (supportRim.isArchived()) {
throw new Exception("Unable to locate an unarchived support RIM."); throw new Exception("Unable to locate an unarchived support RIM.");
} else { } else {
this.referenceManifestRepository.save(support); this.referenceManifestRepository.save(supportRim);
} }
} else { } else {
support.setDeviceName(dv.getNw().getHostname()); supportRim.setDeviceName(dv.getNw().getHostname());
this.referenceManifestRepository.save(support); this.referenceManifestRepository.save(supportRim);
} }
} catch (IOException ioEx) { } catch (IOException ioEx) {
log.error(ioEx); log.error(ioEx);
@ -496,39 +497,41 @@ public class IdentityClaimProcessor extends AbstractProcessor {
//update Support RIMs and Base RIMs. //update Support RIMs and Base RIMs.
for (ByteString swidFile : dv.getSwidfileList()) { for (ByteString swidFile : dv.getSwidfileList()) {
dbBaseRim = (BaseReferenceManifest) referenceManifestRepository baseRim = (BaseReferenceManifest) referenceManifestRepository
.findByBase64Hash(Base64.getEncoder().encodeToString(messageDigest.digest( .findByBase64Hash(Base64.getEncoder().encodeToString(messageDigest.digest(
swidFile.toByteArray()))); swidFile.toByteArray())));
if (dbBaseRim != null) { if (baseRim != null) {
// get file name to use // get file name to use
for (SwidResource swid : dbBaseRim.getFileResources()) { for (SwidResource swid : baseRim.getFileResources()) {
matcher = pattern.matcher(swid.getName()); matcher = pattern.matcher(swid.getName());
if (matcher.matches()) { if (matcher.matches()) {
//found the file name //found the file name
int dotIndex = swid.getName().lastIndexOf("."); int dotIndex = swid.getName().lastIndexOf(".");
fileName = swid.getName().substring(0, dotIndex); fileName = swid.getName().substring(0, dotIndex);
dbBaseRim.setFileName(String.format("%s.swidtag", baseRim.setFileName(String.format("%s.swidtag",
fileName)); fileName));
} }
// now update support rim // now update support rim
SupportReferenceManifest dbSupport = (SupportReferenceManifest) referenceManifestRepository SupportReferenceManifest dbSupport =
.findByHexDecHashAndRimType(swid.getHashValue(), ReferenceManifest.SUPPORT_RIM); (SupportReferenceManifest) referenceManifestRepository
.findByHexDecHashAndRimType(swid.getHashValue(),
ReferenceManifest.SUPPORT_RIM);
if (dbSupport != null) { if (dbSupport != null) {
dbSupport.setFileName(swid.getName()); dbSupport.setFileName(swid.getName());
dbSupport.setSwidTagVersion(dbBaseRim.getSwidTagVersion()); dbSupport.setSwidTagVersion(baseRim.getSwidTagVersion());
dbSupport.setTagId(dbBaseRim.getTagId()); dbSupport.setTagId(baseRim.getTagId());
dbSupport.setSwidTagVersion(dbBaseRim.getSwidTagVersion()); dbSupport.setSwidTagVersion(baseRim.getSwidTagVersion());
dbSupport.setSwidVersion(dbBaseRim.getSwidVersion()); dbSupport.setSwidVersion(baseRim.getSwidVersion());
dbSupport.setSwidPatch(dbBaseRim.isSwidPatch()); dbSupport.setSwidPatch(baseRim.isSwidPatch());
dbSupport.setSwidSupplemental(dbBaseRim.isSwidSupplemental()); dbSupport.setSwidSupplemental(baseRim.isSwidSupplemental());
dbBaseRim.setAssociatedRim(dbSupport.getId()); baseRim.setAssociatedRim(dbSupport.getId());
dbSupport.setUpdated(true); dbSupport.setUpdated(true);
dbSupport.setAssociatedRim(dbBaseRim.getId()); dbSupport.setAssociatedRim(baseRim.getId());
this.referenceManifestRepository.save(dbSupport); this.referenceManifestRepository.save(dbSupport);
} }
} }
this.referenceManifestRepository.save(dbBaseRim); this.referenceManifestRepository.save(baseRim);
} }
} }
@ -539,40 +542,40 @@ public class IdentityClaimProcessor extends AbstractProcessor {
fileName = String.format("%s.measurement", fileName = String.format("%s.measurement",
dv.getNw().getHostname()); dv.getNw().getHostname());
try { try {
EventLogMeasurements temp = new EventLogMeasurements(fileName, EventLogMeasurements deviceLiveLog = new EventLogMeasurements(fileName,
dv.getLivelog().toByteArray()); dv.getLivelog().toByteArray());
// find previous version. // find previous version.
measurements = referenceManifestRepository integrityMeasurements = referenceManifestRepository
.byMeasurementDeviceName(dv.getNw().getHostname()); .byMeasurementDeviceName(dv.getNw().getHostname());
if (measurements != null) { if (integrityMeasurements != null) {
// Find previous log and delete it // Find previous log and delete it
referenceManifestRepository.delete(measurements); referenceManifestRepository.delete(integrityMeasurements);
} }
List<BaseReferenceManifest> baseRims = referenceManifestRepository List<BaseReferenceManifest> baseRims = referenceManifestRepository
.getBaseByManufacturerModel(dv.getHw().getManufacturer(), .getBaseByManufacturerModel(dv.getHw().getManufacturer(),
dv.getHw().getProductName()); dv.getHw().getProductName());
measurements = temp; integrityMeasurements = deviceLiveLog;
measurements.setPlatformManufacturer(dv.getHw().getManufacturer()); integrityMeasurements.setPlatformManufacturer(dv.getHw().getManufacturer());
measurements.setPlatformModel(dv.getHw().getProductName()); integrityMeasurements.setPlatformModel(dv.getHw().getProductName());
if (tagId != null && !tagId.trim().isEmpty()) { if (tagId != null && !tagId.trim().isEmpty()) {
measurements.setTagId(tagId); integrityMeasurements.setTagId(tagId);
} }
measurements.setDeviceName(dv.getNw().getHostname()); integrityMeasurements.setDeviceName(dv.getNw().getHostname());
measurements.archive(); integrityMeasurements.archive();
this.referenceManifestRepository.save(measurements); this.referenceManifestRepository.save(integrityMeasurements);
for (BaseReferenceManifest baseRim : baseRims) { for (BaseReferenceManifest bRim : baseRims) {
if (baseRim != null) { if (bRim != null) {
// pull the base versions of the swidtag and rimel and set the // pull the base versions of the swidtag and rimel and set the
// event log hash for use during provision // event log hash for use during provision
SupportReferenceManifest sBaseRim = referenceManifestRepository SupportReferenceManifest sBaseRim = referenceManifestRepository
.getSupportRimEntityById(baseRim.getAssociatedRim()); .getSupportRimEntityById(bRim.getAssociatedRim());
baseRim.setEventLogHash(temp.getHexDecHash()); bRim.setEventLogHash(deviceLiveLog.getHexDecHash());
sBaseRim.setEventLogHash(temp.getHexDecHash()); sBaseRim.setEventLogHash(deviceLiveLog.getHexDecHash());
referenceManifestRepository.save(baseRim); referenceManifestRepository.save(bRim);
referenceManifestRepository.save(sBaseRim); referenceManifestRepository.save(sBaseRim);
} }
} }
@ -584,7 +587,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
dv.getNw().getHostname())); dv.getNw().getHostname()));
} }
// Get TPM info, currently unimplemented // Get TPM info, currently unimplemented
TPMInfo tpmInfo = new TPMInfo(DeviceInfoEnums.NOT_SPECIFIED, TPMInfo tpmInfo = new TPMInfo(DeviceInfoEnums.NOT_SPECIFIED,
(short) 0, (short) 0,
(short) 0, (short) 0,
@ -608,11 +611,11 @@ public class IdentityClaimProcessor extends AbstractProcessor {
List<SupportReferenceManifest> patchRims = new ArrayList<>(); List<SupportReferenceManifest> patchRims = new ArrayList<>();
List<SupportReferenceManifest> dbSupportRims = this.referenceManifestRepository List<SupportReferenceManifest> dbSupportRims = this.referenceManifestRepository
.getSupportByManufacturerModel(manufacturer, model); .getSupportByManufacturerModel(manufacturer, model);
List<ReferenceDigestValue> sourcedValues = referenceDigestValueRepository List<ReferenceDigestValue> expectedValues = referenceDigestValueRepository
.findByManufacturerAndModel(manufacturer, model); .findByManufacturerAndModel(manufacturer, model);
Map<String, ReferenceDigestValue> digestValueMap = new HashMap<>(); Map<String, ReferenceDigestValue> digestValueMap = new HashMap<>();
sourcedValues.stream().forEach((rdv) -> { expectedValues.stream().forEach((rdv) -> {
digestValueMap.put(rdv.getDigestValue(), rdv); digestValueMap.put(rdv.getDigestValue(), rdv);
}); });
@ -628,11 +631,12 @@ public class IdentityClaimProcessor extends AbstractProcessor {
} }
if (baseSupportRim != null if (baseSupportRim != null
&& referenceDigestValueRepository.findBySupportRimHash(baseSupportRim.getHexDecHash()).isEmpty()) { && referenceDigestValueRepository.findBySupportRimHash(baseSupportRim.getHexDecHash())
.isEmpty()) {
try { try {
TCGEventLog logProcessor = new TCGEventLog(baseSupportRim.getRimBytes()); TCGEventLog eventLog = new TCGEventLog(baseSupportRim.getRimBytes());
ReferenceDigestValue rdv; ReferenceDigestValue rdv;
for (TpmPcrEvent tpe : logProcessor.getEventList()) { for (TpmPcrEvent tpe : eventLog.getEventList()) {
rdv = new ReferenceDigestValue(baseSupportRim.getAssociatedRim(), rdv = new ReferenceDigestValue(baseSupportRim.getAssociatedRim(),
baseSupportRim.getId(), manufacturer, model, tpe.getPcrIndex(), baseSupportRim.getId(), manufacturer, model, tpe.getPcrIndex(),
tpe.getEventDigestStr(), baseSupportRim.getHexDecHash(), tpe.getEventDigestStr(), baseSupportRim.getHexDecHash(),
@ -644,8 +648,8 @@ public class IdentityClaimProcessor extends AbstractProcessor {
// since I have the base already I don't have to care about the backward // since I have the base already I don't have to care about the backward
// linkage // linkage
for (SupportReferenceManifest supplemental : supplementalRims) { for (SupportReferenceManifest supplemental : supplementalRims) {
logProcessor = new TCGEventLog(supplemental.getRimBytes()); eventLog = new TCGEventLog(supplemental.getRimBytes());
for (TpmPcrEvent tpe : logProcessor.getEventList()) { for (TpmPcrEvent tpe : eventLog.getEventList()) {
// all RDVs will have the same base rim // all RDVs will have the same base rim
rdv = new ReferenceDigestValue(baseSupportRim.getAssociatedRim(), rdv = new ReferenceDigestValue(baseSupportRim.getAssociatedRim(),
supplemental.getId(), manufacturer, model, tpe.getPcrIndex(), supplemental.getId(), manufacturer, model, tpe.getPcrIndex(),
@ -679,8 +683,8 @@ public class IdentityClaimProcessor extends AbstractProcessor {
ReferenceDigestValue dbRdv; ReferenceDigestValue dbRdv;
String patchedValue; String patchedValue;
for (SupportReferenceManifest patch : patchRims) { for (SupportReferenceManifest patch : patchRims) {
logProcessor = new TCGEventLog(patch.getRimBytes()); eventLog = new TCGEventLog(patch.getRimBytes());
for (TpmPcrEvent tpe : logProcessor.getEventList()) { for (TpmPcrEvent tpe : eventLog.getEventList()) {
patchedValue = tpe.getEventDigestStr(); patchedValue = tpe.getEventDigestStr();
dbRdv = digestValueMap.get(patchedValue); dbRdv = digestValueMap.get(patchedValue);
@ -688,7 +692,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
log.error(String.format("Patching value does not exist (%s)", log.error(String.format("Patching value does not exist (%s)",
patchedValue)); patchedValue));
} else { } else {
// WIP - Until we get patch examples // WIP - Until we get patch examples
dbRdv.setPatched(true); dbRdv.setPatched(true);
} }
} }
@ -721,7 +725,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
} }
private int handleDeviceComponents(final String hostName, final String paccorString) { private int handleDeviceComponents(final String hostName, final String paccorString) {
int deviceComponents = 0 ; int deviceComponents = 0;
Map<Integer, ComponentInfo> componentInfoMap = new HashMap<>(); Map<Integer, ComponentInfo> componentInfoMap = new HashMap<>();
try { try {
List<ComponentInfo> componentInfos = SupplyChainCredentialValidator List<ComponentInfo> componentInfos = SupplyChainCredentialValidator

View File

@ -12,8 +12,8 @@ import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements;
import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue; import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue;
import hirs.attestationca.persist.enums.AppraisalStatus; import hirs.attestationca.persist.enums.AppraisalStatus;
import hirs.attestationca.persist.service.ValidationService; import hirs.attestationca.persist.service.ValidationService;
import hirs.utils.rim.ReferenceManifestValidator;
import hirs.utils.SwidResource; import hirs.utils.SwidResource;
import hirs.utils.rim.ReferenceManifestValidator;
import hirs.utils.tpm.eventlog.TCGEventLog; import hirs.utils.tpm.eventlog.TCGEventLog;
import hirs.utils.tpm.eventlog.TpmPcrEvent; import hirs.utils.tpm.eventlog.TpmPcrEvent;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
@ -24,7 +24,12 @@ import java.security.KeyStore;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.*; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import static hirs.attestationca.persist.enums.AppraisalStatus.Status.FAIL; import static hirs.attestationca.persist.enums.AppraisalStatus.Status.FAIL;
import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS; import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS;
@ -35,7 +40,6 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator {
private static PcrValidator pcrValidator; private static PcrValidator pcrValidator;
/** /**
*
* @param device * @param device
* @param policySettings * @param policySettings
* @param referenceManifestRepository * @param referenceManifestRepository
@ -66,7 +70,8 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator {
// In this case, try to look up the event log associated with the device, then get the base rim associated by event log hash // In this case, try to look up the event log associated with the device, then get the base rim associated by event log hash
List<ReferenceManifest> deviceRims = referenceManifestRepository.findByDeviceName(hostName); List<ReferenceManifest> deviceRims = referenceManifestRepository.findByDeviceName(hostName);
for (ReferenceManifest deviceRim : deviceRims) { for (ReferenceManifest deviceRim : deviceRims) {
if (deviceRim instanceof BaseReferenceManifest && !deviceRim.isSwidSupplemental() && !deviceRim.isSwidPatch()) { if (deviceRim instanceof BaseReferenceManifest && !deviceRim.isSwidSupplemental() &&
!deviceRim.isSwidPatch()) {
baseReferenceManifest = (BaseReferenceManifest) deviceRim; baseReferenceManifest = (BaseReferenceManifest) deviceRim;
} }
@ -77,7 +82,9 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator {
// Attempt to get an event log from the database matching the expected hash // Attempt to get an event log from the database matching the expected hash
if (baseReferenceManifest == null && measurement != null) { if (baseReferenceManifest == null && measurement != null) {
baseReferenceManifest = (BaseReferenceManifest)referenceManifestRepository.findByEventLogHashAndRimType(measurement.getHexDecHash(), ReferenceManifest.BASE_RIM); baseReferenceManifest =
(BaseReferenceManifest) referenceManifestRepository.findByEventLogHashAndRimType(
measurement.getHexDecHash(), ReferenceManifest.BASE_RIM);
} }
String failedString = ""; String failedString = "";
@ -101,7 +108,7 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator {
if (passed) { if (passed) {
List<SwidResource> resources = List<SwidResource> resources =
((BaseReferenceManifest) baseReferenceManifest).getFileResources(); baseReferenceManifest.getFileResources();
fwStatus = new AppraisalStatus(PASS, fwStatus = new AppraisalStatus(PASS,
SupplyChainCredentialValidator.FIRMWARE_VALID); SupplyChainCredentialValidator.FIRMWARE_VALID);
@ -131,20 +138,22 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator {
try { try {
certs.add(cac.getX509Certificate()); certs.add(cac.getX509Certificate());
} catch (IOException e) { } catch (IOException e) {
log.error("Error building CA chain for " + signingCert.getSubjectKeyIdentifier() + ": " log.error(
+ e.getMessage()); "Error building CA chain for " + signingCert.getSubjectKeyIdentifier() + ": "
+ e.getMessage());
} }
} }
referenceManifestValidator.setTrustStore(certs); referenceManifestValidator.setTrustStore(certs);
try { try {
if (referenceManifestValidator.validateXmlSignature(signingCert.getX509Certificate().getPublicKey(), if (referenceManifestValidator.validateXmlSignature(
signingCert.getSubjectKeyIdString(), signingCert.getEncodedPublicKey())) { signingCert.getX509Certificate().getPublicKey(),
signingCert.getSubjectKeyIdString(), signingCert.getEncodedPublicKey())) {
try { try {
if (!SupplyChainCredentialValidator.verifyCertificate( if (!SupplyChainCredentialValidator.verifyCertificate(
signingCert.getX509Certificate(), keyStore)) { signingCert.getX509Certificate(), keyStore)) {
passed = false; passed = false;
fwStatus = new AppraisalStatus(FAIL, fwStatus = new AppraisalStatus(FAIL,
"Firmware validation failed: invalid certificate path."); "Firmware validation failed: invalid certificate path.");
} }
} catch (IOException ioEx) { } catch (IOException ioEx) {
log.error("Error getting X509 cert from manager: " + ioEx.getMessage()); log.error("Error getting X509 cert from manager: " + ioEx.getMessage());
@ -197,10 +206,10 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator {
} }
if (passed) { if (passed) {
TCGEventLog logProcessor; TCGEventLog expectedEventLog;
try { try {
logProcessor = new TCGEventLog(supportReferenceManifest.getRimBytes()); expectedEventLog = new TCGEventLog(supportReferenceManifest.getRimBytes());
baseline = logProcessor.getExpectedPCRValues(); baseline = expectedEventLog.getExpectedPCRValues();
} catch (CertificateException cEx) { } catch (CertificateException cEx) {
log.error(cEx); log.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) { } catch (NoSuchAlgorithmException noSaEx) {
@ -233,21 +242,21 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator {
// part 2 of firmware validation check: bios measurements // part 2 of firmware validation check: bios measurements
// vs baseline tcg event log // vs baseline tcg event log
// find the measurement // find the measurement
TCGEventLog tcgMeasurementLog; TCGEventLog actualEventLog;
LinkedList<TpmPcrEvent> tpmPcrEvents = new LinkedList<>(); LinkedList<TpmPcrEvent> failedPcrValues = new LinkedList<>();
List<ReferenceDigestValue> eventValue; List<ReferenceDigestValue> rimIntegrityMeasurements;
HashMap<String, ReferenceDigestValue> eventValueMap = new HashMap<>(); HashMap<String, ReferenceDigestValue> expectedEventLogRecords = new HashMap<>();
try { try {
if (measurement.getDeviceName().equals(hostName)) { if (measurement.getDeviceName().equals(hostName)) {
tcgMeasurementLog = new TCGEventLog(measurement.getRimBytes()); actualEventLog = new TCGEventLog(measurement.getRimBytes());
eventValue = referenceDigestValueRepository rimIntegrityMeasurements = referenceDigestValueRepository
.findValuesByBaseRimId(baseReferenceManifest.getId()); .findValuesByBaseRimId(baseReferenceManifest.getId());
for (ReferenceDigestValue rdv : eventValue) { for (ReferenceDigestValue rdv : rimIntegrityMeasurements) {
eventValueMap.put(rdv.getDigestValue(), rdv); expectedEventLogRecords.put(rdv.getDigestValue(), rdv);
} }
tpmPcrEvents.addAll(pcrValidator.validateTpmEvents( failedPcrValues.addAll(pcrValidator.validateTpmEvents(
tcgMeasurementLog, eventValueMap, policySettings)); actualEventLog, expectedEventLogRecords, policySettings));
} }
} catch (CertificateException cEx) { } catch (CertificateException cEx) {
log.error(cEx); log.error(cEx);
@ -257,11 +266,11 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator {
log.error(ioEx); log.error(ioEx);
} }
if (!tpmPcrEvents.isEmpty()) { if (!failedPcrValues.isEmpty()) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(String.format("%d digest(s) were not found:%n", sb.append(String.format("%d digest(s) were not found:%n",
tpmPcrEvents.size())); failedPcrValues.size()));
for (TpmPcrEvent tpe : tpmPcrEvents) { for (TpmPcrEvent tpe : failedPcrValues) {
sb.append(String.format("PCR Index %d - %s%n", sb.append(String.format("PCR Index %d - %s%n",
tpe.getPcrIndex(), tpe.getPcrIndex(),
tpe.getEventTypeStr())); tpe.getEventTypeStr()));