mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-04-11 05:10:26 +00:00
Missed files
This commit is contained in:
parent
4b67747e3e
commit
310102bc8a
HIRS_AttestationCA/src/main/java/hirs/attestationca/persist
338
HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationManager.java
Normal file
338
HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationManager.java
Normal file
@ -0,0 +1,338 @@
|
||||
package hirs.attestationca.persist.service;
|
||||
|
||||
import hirs.attestationca.persist.entity.ArchivableEntity;
|
||||
import hirs.attestationca.persist.entity.manager.CACredentialRepository;
|
||||
import hirs.attestationca.persist.entity.manager.CertificateRepository;
|
||||
import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
|
||||
import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository;
|
||||
import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository;
|
||||
import hirs.attestationca.persist.entity.userdefined.Certificate;
|
||||
import hirs.attestationca.persist.entity.userdefined.Device;
|
||||
import hirs.attestationca.persist.entity.userdefined.PolicySettings;
|
||||
import hirs.attestationca.persist.entity.userdefined.SupplyChainValidation;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
|
||||
import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
|
||||
import hirs.attestationca.persist.enums.AppraisalStatus;
|
||||
import hirs.attestationca.persist.validation.CertificateAttributeScvValidator;
|
||||
import hirs.attestationca.persist.validation.CredentialValidator;
|
||||
import hirs.attestationca.persist.validation.FirmwareScvValidator;
|
||||
import hirs.utils.BouncyCastleUtils;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Log4j2
|
||||
public class ValidationManager {
|
||||
|
||||
public static SupplyChainValidation evaluateEndorsementCredentialStatus(
|
||||
final EndorsementCredential ec,
|
||||
final CACredentialRepository caCredentialRepository,
|
||||
final boolean acceptExpiredCerts) {
|
||||
final SupplyChainValidation.ValidationType validationType
|
||||
= SupplyChainValidation.ValidationType.ENDORSEMENT_CREDENTIAL;
|
||||
log.info("Validating endorsement credential");
|
||||
if (ec == null) {
|
||||
log.error("No endorsement credential to validate");
|
||||
return buildValidationRecord(validationType,
|
||||
AppraisalStatus.Status.FAIL, "Endorsement credential is missing",
|
||||
null, Level.ERROR);
|
||||
}
|
||||
|
||||
KeyStore ecStore = getCaChain(ec, caCredentialRepository);
|
||||
AppraisalStatus result = CredentialValidator.
|
||||
validateEndorsementCredential(ec, ecStore, acceptExpiredCerts);
|
||||
switch (result.getAppStatus()) {
|
||||
case PASS:
|
||||
return buildValidationRecord(validationType, AppraisalStatus.Status.PASS,
|
||||
result.getMessage(), ec, Level.INFO);
|
||||
case FAIL:
|
||||
return buildValidationRecord(validationType, AppraisalStatus.Status.FAIL,
|
||||
result.getMessage(), ec, Level.WARN);
|
||||
case ERROR:
|
||||
default:
|
||||
return buildValidationRecord(validationType, AppraisalStatus.Status.ERROR,
|
||||
result.getMessage(), ec, Level.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public static SupplyChainValidation evaluatePlatformCredentialStatus(
|
||||
final PlatformCredential pc,
|
||||
final KeyStore trustedCertificateAuthority, final boolean acceptExpiredCerts) {
|
||||
final SupplyChainValidation.ValidationType validationType
|
||||
= SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL;
|
||||
|
||||
if (pc == null) {
|
||||
log.error("No platform credential to validate");
|
||||
return buildValidationRecord(validationType,
|
||||
AppraisalStatus.Status.FAIL, "Empty Platform credential", null, Level.ERROR);
|
||||
}
|
||||
log.info("Validating Platform Credential");
|
||||
AppraisalStatus result = CredentialValidator.validatePlatformCredential(pc,
|
||||
trustedCertificateAuthority, acceptExpiredCerts);
|
||||
switch (result.getAppStatus()) {
|
||||
case PASS:
|
||||
return buildValidationRecord(validationType, AppraisalStatus.Status.PASS,
|
||||
result.getMessage(), pc, Level.INFO);
|
||||
case FAIL:
|
||||
return buildValidationRecord(validationType, AppraisalStatus.Status.FAIL,
|
||||
result.getMessage(), pc, Level.WARN);
|
||||
case ERROR:
|
||||
default:
|
||||
return buildValidationRecord(validationType, AppraisalStatus.Status.ERROR,
|
||||
result.getMessage(), pc, Level.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public static SupplyChainValidation evaluatePCAttributesStatus(
|
||||
final PlatformCredential pc, final DeviceInfoReport deviceInfoReport,
|
||||
final EndorsementCredential ec,
|
||||
final CertificateRepository certificateRepository,
|
||||
final ComponentResultRepository componentResultRepository) {
|
||||
final SupplyChainValidation.ValidationType validationType
|
||||
= SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES;
|
||||
|
||||
if (pc == null) {
|
||||
log.error("No platform credential to validate");
|
||||
return buildValidationRecord(validationType,
|
||||
AppraisalStatus.Status.FAIL, "Platform credential is missing",
|
||||
null, Level.ERROR);
|
||||
}
|
||||
log.info("Validating platform credential attributes");
|
||||
AppraisalStatus result = CredentialValidator.
|
||||
validatePlatformCredentialAttributes(pc, deviceInfoReport, ec);
|
||||
switch (result.getAppStatus()) {
|
||||
case PASS:
|
||||
return buildValidationRecord(validationType, AppraisalStatus.Status.PASS,
|
||||
result.getMessage(), pc, Level.INFO);
|
||||
case FAIL:
|
||||
if (!result.getAdditionalInfo().isEmpty()) {
|
||||
pc.setComponentFailures(result.getAdditionalInfo());
|
||||
pc.setComponentFailureMessage(result.getMessage());
|
||||
certificateRepository.save(pc);
|
||||
for (ComponentResult componentResult
|
||||
: CertificateAttributeScvValidator.getComponentResultList()) {
|
||||
componentResultRepository.save(componentResult);
|
||||
}
|
||||
}
|
||||
return buildValidationRecord(validationType, AppraisalStatus.Status.FAIL,
|
||||
result.getMessage(), pc, Level.WARN);
|
||||
case ERROR:
|
||||
default:
|
||||
return buildValidationRecord(validationType, AppraisalStatus.Status.ERROR,
|
||||
result.getMessage(), pc, Level.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public static SupplyChainValidation evaluateDeltaAttributesStatus(
|
||||
final PlatformCredential delta,
|
||||
final DeviceInfoReport deviceInfoReport,
|
||||
final PlatformCredential base,
|
||||
final Map<PlatformCredential, SupplyChainValidation> deltaMapping,
|
||||
final CertificateRepository certificateRepository) {
|
||||
final SupplyChainValidation.ValidationType validationType
|
||||
= SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES;
|
||||
|
||||
if (delta == null) {
|
||||
log.error("No delta certificate to validate");
|
||||
return buildValidationRecord(validationType,
|
||||
AppraisalStatus.Status.FAIL, "Delta platform certificate is missing",
|
||||
null, Level.ERROR);
|
||||
}
|
||||
log.info("Validating delta platform certificate attributes");
|
||||
AppraisalStatus result = CertificateAttributeScvValidator.
|
||||
validateDeltaPlatformCredentialAttributes(delta, deviceInfoReport,
|
||||
base, deltaMapping);
|
||||
switch (result.getAppStatus()) {
|
||||
case PASS:
|
||||
return buildValidationRecord(validationType, AppraisalStatus.Status.PASS,
|
||||
result.getMessage(), delta, Level.INFO);
|
||||
case FAIL:
|
||||
if (!result.getAdditionalInfo().isEmpty()) {
|
||||
base.setComponentFailures(result.getAdditionalInfo());
|
||||
base.setComponentFailureMessage(result.getMessage());
|
||||
certificateRepository.save(base);
|
||||
}
|
||||
// we are adding things to componentFailures
|
||||
certificateRepository.save(delta);
|
||||
return buildValidationRecord(validationType, AppraisalStatus.Status.FAIL,
|
||||
result.getMessage(), delta, Level.WARN);
|
||||
case ERROR:
|
||||
default:
|
||||
return buildValidationRecord(validationType, AppraisalStatus.Status.ERROR,
|
||||
result.getMessage(), delta, Level.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public static SupplyChainValidation evaluateFirmwareStatus(
|
||||
final Device device,
|
||||
final PolicySettings policySettings, final ReferenceManifestRepository rimRepo,
|
||||
final ReferenceDigestValueRepository rdvRepo,
|
||||
final CACredentialRepository caRepo) {
|
||||
final SupplyChainValidation.ValidationType validationType
|
||||
= SupplyChainValidation.ValidationType.FIRMWARE;
|
||||
|
||||
AppraisalStatus result = FirmwareScvValidator.validateFirmware(device, policySettings,
|
||||
rimRepo, rdvRepo, caRepo);
|
||||
Level logLevel;
|
||||
|
||||
switch (result.getAppStatus()) {
|
||||
case PASS:
|
||||
logLevel = Level.INFO;
|
||||
break;
|
||||
case FAIL:
|
||||
logLevel = Level.WARN;
|
||||
break;
|
||||
case ERROR:
|
||||
default:
|
||||
logLevel = Level.ERROR;
|
||||
}
|
||||
return buildValidationRecord(validationType, result.getAppStatus(),
|
||||
result.getMessage(), null, logLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a supply chain validation record and logs the validation message
|
||||
* at the specified log level.
|
||||
*
|
||||
* @param validationType the type of validation
|
||||
* @param result the appraisal status
|
||||
* @param message the validation message to include in the summary and log
|
||||
* @param archivableEntity the archivableEntity associated with the
|
||||
* validation
|
||||
* @param logLevel the log level
|
||||
* @return a SupplyChainValidation
|
||||
*/
|
||||
public static SupplyChainValidation buildValidationRecord(
|
||||
final SupplyChainValidation.ValidationType validationType,
|
||||
final AppraisalStatus.Status result, final String message,
|
||||
final ArchivableEntity archivableEntity, final Level logLevel) {
|
||||
List<ArchivableEntity> aeList = new ArrayList<>();
|
||||
if (archivableEntity != null) {
|
||||
aeList.add(archivableEntity);
|
||||
}
|
||||
|
||||
log.log(logLevel, message);
|
||||
return new SupplyChainValidation(validationType, result, aeList, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to retrieve the entire CA chain (up to a trusted
|
||||
* self-signed certificate) for the given certificate. This method will look
|
||||
* up CA certificates that have a matching issuer organization as the given
|
||||
* certificate, and will perform that operation recursively until all
|
||||
* certificates for all relevant organizations have been retrieved. For that
|
||||
* reason, the returned set of certificates may be larger than the the
|
||||
* single trust chain for the queried certificate, but is guaranteed to
|
||||
* include the trust chain if it exists in this class' CertificateManager.
|
||||
* Returns the certificate authority credentials in a KeyStore.
|
||||
*
|
||||
* @param certificate the credential whose CA chain should be retrieved
|
||||
* @param caCredentialRepository db service to get CA Certs
|
||||
* @return A keystore containing all relevant CA credentials to the given
|
||||
* certificate's organization or null if the keystore can't be assembled
|
||||
*/
|
||||
public static KeyStore getCaChain(final Certificate certificate,
|
||||
final CACredentialRepository caCredentialRepository) {
|
||||
KeyStore caKeyStore = null;
|
||||
try {
|
||||
caKeyStore = caCertSetToKeystore(getCaChainRec(certificate, Collections.emptySet(),
|
||||
caCredentialRepository));
|
||||
} catch (KeyStoreException | IOException e) {
|
||||
log.error("Unable to assemble CA keystore", e);
|
||||
}
|
||||
return caKeyStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a recursive method which is used to retrieve the entire CA chain
|
||||
* (up to a trusted self-signed certificate) for the given certificate. This
|
||||
* method will look up CA certificates that have a matching issuer
|
||||
* organization as the given certificate, and will perform that operation
|
||||
* recursively until all certificates for all relevant organizations have
|
||||
* been retrieved. For that reason, the returned set of certificates may be
|
||||
* larger than the the single trust chain for the queried certificate, but
|
||||
* is guaranteed to include the trust chain if it exists in this class'
|
||||
* CertificateManager.
|
||||
* <p>
|
||||
* Implementation notes: 1. Queries for CA certs with a subject org matching
|
||||
* the given (argument's) issuer org 2. Add that org to
|
||||
* queriedOrganizations, so we don't search for that organization again 3.
|
||||
* For each returned CA cert, add that cert to the result set, and recurse
|
||||
* with that as the argument (to go up the chain), if and only if we haven't
|
||||
* already queried for that organization (which prevents infinite loops on
|
||||
* certs with an identical subject and issuer org)
|
||||
*
|
||||
* @param credential the credential whose CA chain should be retrieved
|
||||
* @param previouslyQueriedSubjects a list of organizations to refrain
|
||||
* from querying
|
||||
* @return a Set containing all relevant CA credentials to the given
|
||||
* certificate's organization
|
||||
*/
|
||||
public static Set<CertificateAuthorityCredential> getCaChainRec(
|
||||
final Certificate credential,
|
||||
final Set<String> previouslyQueriedSubjects,
|
||||
final CACredentialRepository caCredentialRepository) {
|
||||
CertificateAuthorityCredential skiCA = null;
|
||||
List<CertificateAuthorityCredential> certAuthsWithMatchingIssuer = new LinkedList<>();
|
||||
if (credential.getAuthorityKeyIdentifier() != null
|
||||
&& !credential.getAuthorityKeyIdentifier().isEmpty()) {
|
||||
byte[] bytes = Hex.decode(credential.getAuthorityKeyIdentifier());
|
||||
skiCA = caCredentialRepository.findBySubjectKeyIdentifier(bytes);
|
||||
}
|
||||
|
||||
if (skiCA == null) {
|
||||
if (credential.getIssuerSorted() == null
|
||||
|| credential.getIssuerSorted().isEmpty()) {
|
||||
certAuthsWithMatchingIssuer = caCredentialRepository.findBySubject(credential.getIssuer());
|
||||
} else {
|
||||
//Get certificates by subject organization
|
||||
certAuthsWithMatchingIssuer = caCredentialRepository.findBySubjectSorted(credential.getIssuerSorted());
|
||||
}
|
||||
} else {
|
||||
certAuthsWithMatchingIssuer.add(skiCA);
|
||||
}
|
||||
Set<String> queriedOrganizations = new HashSet<>(previouslyQueriedSubjects);
|
||||
queriedOrganizations.add(credential.getIssuer());
|
||||
|
||||
HashSet<CertificateAuthorityCredential> caCreds = new HashSet<>();
|
||||
for (CertificateAuthorityCredential cred : certAuthsWithMatchingIssuer) {
|
||||
caCreds.add(cred);
|
||||
if (!BouncyCastleUtils.x500NameCompare(cred.getIssuer(),
|
||||
cred.getSubject())) {
|
||||
caCreds.addAll(getCaChainRec(cred, queriedOrganizations, caCredentialRepository));
|
||||
}
|
||||
}
|
||||
return caCreds;
|
||||
}
|
||||
|
||||
public static KeyStore caCertSetToKeystore(final Set<CertificateAuthorityCredential> certs)
|
||||
throws KeyStoreException, IOException {
|
||||
KeyStore keyStore = KeyStore.getInstance("JKS");
|
||||
try {
|
||||
keyStore.load(null, "".toCharArray());
|
||||
for (Certificate cert : certs) {
|
||||
keyStore.setCertificateEntry(cert.getId().toString(), cert.getX509Certificate());
|
||||
}
|
||||
} catch (IOException | CertificateException | NoSuchAlgorithmException e) {
|
||||
throw new IOException("Could not create and populate keystore", e);
|
||||
}
|
||||
|
||||
return keyStore;
|
||||
}
|
||||
}
|
1125
HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
Normal file
1125
HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java
Normal file
File diff suppressed because it is too large
Load Diff
258
HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java
Normal file
258
HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java
Normal file
@ -0,0 +1,258 @@
|
||||
package hirs.attestationca.persist.validation;
|
||||
|
||||
import hirs.attestationca.persist.entity.manager.CACredentialRepository;
|
||||
import hirs.attestationca.persist.entity.manager.CertificateRepository;
|
||||
import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository;
|
||||
import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository;
|
||||
import hirs.attestationca.persist.entity.userdefined.Device;
|
||||
import hirs.attestationca.persist.entity.userdefined.PolicySettings;
|
||||
import hirs.attestationca.persist.entity.userdefined.ReferenceManifest;
|
||||
import hirs.attestationca.persist.entity.userdefined.SupplyChainValidation;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential;
|
||||
import hirs.attestationca.persist.entity.userdefined.rim.BaseReferenceManifest;
|
||||
import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements;
|
||||
import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue;
|
||||
import hirs.attestationca.persist.enums.AppraisalStatus;
|
||||
import hirs.attestationca.persist.service.ValidationManager;
|
||||
import hirs.utils.SwidResource;
|
||||
import hirs.utils.tpm.eventlog.TCGEventLog;
|
||||
import hirs.utils.tpm.eventlog.TpmPcrEvent;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.apache.logging.log4j.Level;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static hirs.attestationca.persist.enums.AppraisalStatus.Status.FAIL;
|
||||
import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS;
|
||||
|
||||
@Log4j2
|
||||
public class FirmwareScvValidator extends SupplyChainCredentialValidator {
|
||||
|
||||
private static PcrValidator pcrValidator;
|
||||
|
||||
@SuppressWarnings("methodlength")
|
||||
public static AppraisalStatus validateFirmware(
|
||||
final Device device, final PolicySettings policySettings,
|
||||
final ReferenceManifestRepository referenceManifestRepository,
|
||||
final ReferenceDigestValueRepository referenceDigestValueRepository,
|
||||
final CACredentialRepository caCredentialRepository) {
|
||||
boolean passed = true;
|
||||
String[] baseline = new String[Integer.SIZE];
|
||||
AppraisalStatus fwStatus = null;
|
||||
String manufacturer = device.getDeviceInfo()
|
||||
.getHardwareInfo().getManufacturer();
|
||||
String model = device.getDeviceInfo()
|
||||
.getHardwareInfo().getProductName();
|
||||
ReferenceManifest validationObject;
|
||||
List<BaseReferenceManifest> baseReferenceManifests = null;
|
||||
BaseReferenceManifest baseReferenceManifest = null;
|
||||
ReferenceManifest supportReferenceManifest = null;
|
||||
EventLogMeasurements measurement = null;
|
||||
|
||||
baseReferenceManifests = referenceManifestRepository.findAllBaseRims();
|
||||
|
||||
for (BaseReferenceManifest bRim : baseReferenceManifests) {
|
||||
if (bRim.getPlatformManufacturer().equals(manufacturer)
|
||||
&& !bRim.isSwidSupplemental() && !bRim.isSwidPatch()) {
|
||||
baseReferenceManifest = bRim;
|
||||
}
|
||||
}
|
||||
|
||||
String failedString = "";
|
||||
if (baseReferenceManifest == null) {
|
||||
failedString = "Base Reference Integrity Manifest\n";
|
||||
passed = false;
|
||||
} else {
|
||||
measurement = (EventLogMeasurements) referenceManifestRepository.findByHexDecHash(
|
||||
baseReferenceManifest.getEventLogHash());
|
||||
|
||||
if (measurement == null) {
|
||||
measurement = referenceManifestRepository.getLogByModel(
|
||||
baseReferenceManifest.getPlatformModel());
|
||||
}
|
||||
}
|
||||
|
||||
if (measurement == null) {
|
||||
failedString += "Bios measurement";
|
||||
passed = false;
|
||||
}
|
||||
validationObject = measurement;
|
||||
|
||||
if (passed) {
|
||||
List<SwidResource> resources =
|
||||
((BaseReferenceManifest) baseReferenceManifest).getFileResources();
|
||||
fwStatus = new AppraisalStatus(PASS,
|
||||
SupplyChainCredentialValidator.FIRMWARE_VALID);
|
||||
|
||||
// verify signatures
|
||||
ReferenceManifestValidator referenceManifestValidator =
|
||||
new ReferenceManifestValidator();
|
||||
referenceManifestValidator.setRim(baseReferenceManifest);
|
||||
|
||||
//Validate signing cert
|
||||
List<CertificateAuthorityCredential> allCerts = caCredentialRepository.findAll();
|
||||
CertificateAuthorityCredential signingCert = null;
|
||||
for (CertificateAuthorityCredential cert : allCerts) {
|
||||
signingCert = cert;
|
||||
KeyStore keyStore = ValidationManager.getCaChain(signingCert,
|
||||
caCredentialRepository);
|
||||
if (referenceManifestValidator.validateXmlSignature(signingCert)) {
|
||||
try {
|
||||
if (!SupplyChainCredentialValidator.verifyCertificate(
|
||||
signingCert.getX509Certificate(), keyStore)) {
|
||||
passed = false;
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
"Firmware validation failed: invalid certificate path.");
|
||||
validationObject = baseReferenceManifest;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Error getting X509 cert from manager: " + e.getMessage());
|
||||
} catch (SupplyChainValidatorException e) {
|
||||
log.error("Error validating cert against keystore: " + e.getMessage());
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
"Firmware validation failed: invalid certificate path.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (SwidResource swidRes : resources) {
|
||||
supportReferenceManifest = referenceManifestRepository.findByHexDecHash(
|
||||
swidRes.getHashValue());
|
||||
if (supportReferenceManifest != null) {
|
||||
// Removed the filename check from this if statement
|
||||
referenceManifestValidator.validateSupportRimHash(
|
||||
supportReferenceManifest.getRimBytes(), swidRes.getHashValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (passed && signingCert == null) {
|
||||
passed = false;
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
"Firmware validation failed: signing cert not found.");
|
||||
}
|
||||
|
||||
if (passed && supportReferenceManifest == null) {
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
"Support Reference Integrity Manifest can not be found");
|
||||
passed = false;
|
||||
}
|
||||
|
||||
if (passed && !referenceManifestValidator.isSignatureValid()) {
|
||||
passed = false;
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
"Firmware validation failed: Signature validation "
|
||||
+ "failed for Base RIM.");
|
||||
}
|
||||
|
||||
if (passed && !referenceManifestValidator.isSupportRimValid()) {
|
||||
passed = false;
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
"Firmware validation failed: Hash validation "
|
||||
+ "failed for Support RIM.");
|
||||
}
|
||||
|
||||
if (passed) {
|
||||
TCGEventLog logProcessor;
|
||||
try {
|
||||
logProcessor = new TCGEventLog(supportReferenceManifest.getRimBytes());
|
||||
baseline = logProcessor.getExpectedPCRValues();
|
||||
} catch (CertificateException cEx) {
|
||||
log.error(cEx);
|
||||
} catch (NoSuchAlgorithmException noSaEx) {
|
||||
log.error(noSaEx);
|
||||
} catch (IOException ioEx) {
|
||||
log.error(ioEx);
|
||||
}
|
||||
|
||||
// part 1 of firmware validation check: PCR baseline match
|
||||
pcrValidator = new PcrValidator(baseline);
|
||||
|
||||
if (baseline.length > 0) {
|
||||
String pcrContent = "";
|
||||
pcrContent = new String(device.getDeviceInfo().getTpmInfo().getPcrValues());
|
||||
|
||||
if (pcrContent.isEmpty()) {
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
"Firmware validation failed: Client did not "
|
||||
+ "provide pcr values.");
|
||||
log.warn(String.format(
|
||||
"Firmware validation failed: Client (%s) did not "
|
||||
+ "provide pcr values.", device.getName()));
|
||||
} else {
|
||||
// we have a full set of PCR values
|
||||
//int algorithmLength = baseline[0].length();
|
||||
//String[] storedPcrs = buildStoredPcrs(pcrContent, algorithmLength);
|
||||
//pcrPolicy.validatePcrs(storedPcrs);
|
||||
|
||||
// part 2 of firmware validation check: bios measurements
|
||||
// vs baseline tcg event log
|
||||
// find the measurement
|
||||
TCGEventLog tcgMeasurementLog;
|
||||
LinkedList<TpmPcrEvent> tpmPcrEvents = new LinkedList<>();
|
||||
List<ReferenceDigestValue> eventValue;
|
||||
HashMap<String, ReferenceDigestValue> eventValueMap = new HashMap<>();
|
||||
try {
|
||||
if (measurement.getPlatformManufacturer().equals(manufacturer)) {
|
||||
tcgMeasurementLog = new TCGEventLog(measurement.getRimBytes());
|
||||
eventValue = referenceDigestValueRepository
|
||||
.findValuesByBaseRimId(baseReferenceManifest.getId());
|
||||
for (ReferenceDigestValue rdv : eventValue) {
|
||||
eventValueMap.put(rdv.getDigestValue(), rdv);
|
||||
}
|
||||
|
||||
tpmPcrEvents.addAll(pcrValidator.validateTpmEvents(
|
||||
tcgMeasurementLog, eventValueMap, policySettings));
|
||||
}
|
||||
} catch (CertificateException cEx) {
|
||||
log.error(cEx);
|
||||
} catch (NoSuchAlgorithmException noSaEx) {
|
||||
log.error(noSaEx);
|
||||
} catch (IOException ioEx) {
|
||||
log.error(ioEx);
|
||||
}
|
||||
|
||||
if (!tpmPcrEvents.isEmpty()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
validationObject = measurement;
|
||||
sb.append(String.format("%d digest(s) were not found:%n",
|
||||
tpmPcrEvents.size()));
|
||||
for (TpmPcrEvent tpe : tpmPcrEvents) {
|
||||
sb.append(String.format("PCR Index %d - %s%n",
|
||||
tpe.getPcrIndex(),
|
||||
tpe.getEventTypeStr()));
|
||||
}
|
||||
if (fwStatus.getAppStatus().equals(FAIL)) {
|
||||
fwStatus = new AppraisalStatus(FAIL, String.format("%s%n%s",
|
||||
fwStatus.getMessage(), sb.toString()));
|
||||
} else {
|
||||
fwStatus = new AppraisalStatus(FAIL, sb.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fwStatus = new AppraisalStatus(FAIL, "The RIM baseline could not be found.");
|
||||
}
|
||||
}
|
||||
|
||||
EventLogMeasurements eventLog = measurement;
|
||||
eventLog.setOverallValidationResult(fwStatus.getAppStatus());
|
||||
referenceManifestRepository.save(eventLog);
|
||||
} else {
|
||||
fwStatus = new AppraisalStatus(FAIL, String.format("Firmware Validation failed: "
|
||||
+ "%s for %s can not be found", failedString, manufacturer));
|
||||
if (measurement != null) {
|
||||
measurement.setOverallValidationResult(fwStatus.getAppStatus());
|
||||
referenceManifestRepository.save(measurement);
|
||||
}
|
||||
}
|
||||
|
||||
return fwStatus;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user