mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-18 20:47:58 +00:00
Merge pull request #869 from nsacyber/v3_issue-848
[#848] Rename properties and methods of firmware validation objects
This commit is contained in:
commit
d0faa39a15
@ -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
|
||||||
|
@ -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()));
|
||||||
|
Loading…
Reference in New Issue
Block a user