Merge branch 'master' into vendor-table-refactor

This commit is contained in:
Cyrus 2020-10-27 13:05:48 -04:00
commit 1a86012e72
18 changed files with 798 additions and 338 deletions

View File

@ -9,10 +9,12 @@ import hirs.attestationca.exceptions.UnexpectedServerException;
import hirs.attestationca.service.SupplyChainValidationService;
import hirs.data.persist.AppraisalStatus;
import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.EventLogMeasurements;
import hirs.data.persist.Device;
import hirs.data.persist.DeviceInfoReport;
import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.SupportReferenceManifest;
import hirs.data.persist.SwidResource;
import hirs.data.persist.info.FirmwareInfo;
import hirs.data.persist.info.HardwareInfo;
import hirs.data.persist.info.NetworkInfo;
@ -39,7 +41,6 @@ import hirs.structs.elements.tpm.IdentityProof;
import hirs.structs.elements.tpm.IdentityRequest;
import hirs.structs.elements.tpm.SymmetricKey;
import hirs.structs.elements.tpm.SymmetricKeyParams;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.utils.HexUtils;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.ArrayUtils;
@ -86,10 +87,13 @@ import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Provides base implementation of common tasks of an ACA that are required for attestation of an
@ -672,6 +676,7 @@ public abstract class AbstractAttestationCertificateAuthority
* @param claim the protobuf serialized identity claim containing the device info
* @return a HIRS Utils DeviceInfoReport representation of device info
*/
@SuppressWarnings("methodlength")
private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) {
ProvisionerTpm2.DeviceInfo dv = claim.getDv();
@ -728,49 +733,72 @@ public abstract class AbstractAttestationCertificateAuthority
}
// check for RIM Base and Support files, if they don't exists in the database, load them
String clientName;
if (dv.hasLogfile()) {
String clientName = String.format("%s_%s",
dv.getHw().getManufacturer(),
dv.getHw().getProductName());
ReferenceManifest dbBaseRim;
ReferenceManifest support;
String tagId = "";
String fileName = "";
Pattern pattern = Pattern.compile("([^\\s]+(\\.(?i)(rimpcr|rimel|bin|log))$)");
Matcher matcher;
if (dv.hasSwidfile()) {
try {
ReferenceManifest support = ReferenceManifest.select(referenceManifestManager)
dbBaseRim = BaseReferenceManifest.select(referenceManifestManager)
.includeArchived()
.byHashCode(dv.getSwidfile().hashCode())
.byHashCode(Arrays.hashCode(dv.getSwidfile().toByteArray()))
.getRIM();
if (support == null) {
clientName = String.format("%s_%s.rimel",
dv.getHw().getManufacturer(),
dv.getHw().getProductName());
this.referenceManifestManager.save(
new SupportReferenceManifest(clientName,
dv.getLogfile().toByteArray()));
if (dbBaseRim == null) {
dbBaseRim = new BaseReferenceManifest(
String.format("%s.swidtag",
clientName),
dv.getSwidfile().toByteArray());
BaseReferenceManifest base = (BaseReferenceManifest) dbBaseRim;
for (SwidResource swid : base.parseResource()) {
matcher = pattern.matcher(swid.getName());
if (matcher.matches()) {
//found the file name
int dotIndex = swid.getName().lastIndexOf(".");
clientName = swid.getName().substring(0, dotIndex);
dbBaseRim = new BaseReferenceManifest(
String.format("%s.swidtag",
clientName),
dv.getSwidfile().toByteArray());
break;
}
}
this.referenceManifestManager.save(dbBaseRim);
} else {
LOG.info("Client provided Support RIM already loaded in database.");
LOG.info("Client provided Base RIM already loaded in database.");
}
TCGEventLog tcgEventLog = new TCGEventLog(dv.getLogfile().toByteArray());
LOG.error(tcgEventLog.toString(true, true, true));
} catch (CertificateException cEx) {
LOG.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOG.error(noSaEx);
tagId = dbBaseRim.getTagId();
} catch (IOException ioEx) {
LOG.error(ioEx);
}
}
if (dv.hasSwidfile()) {
if (dv.hasLogfile()) {
try {
ReferenceManifest baseRim = ReferenceManifest.select(referenceManifestManager)
support = SupportReferenceManifest.select(referenceManifestManager)
.includeArchived()
.byHashCode(dv.getSwidfile().hashCode())
.byHashCode(Arrays.hashCode(dv.getLogfile().toByteArray()))
.getRIM();
if (baseRim == null) {
clientName = String.format("%s_%s.swidtag",
dv.getHw().getManufacturer(),
dv.getHw().getProductName());
this.referenceManifestManager.save(
new BaseReferenceManifest(clientName,
dv.getSwidfile().toByteArray()));
if (support == null) {
support = new SupportReferenceManifest(
String.format("%s.rimel",
clientName),
dv.getLogfile().toByteArray());
support.setPlatformManufacturer(dv.getHw().getManufacturer());
support.setPlatformModel(dv.getHw().getProductName());
support.setTagId(tagId);
this.referenceManifestManager.save(support);
} else {
LOG.info("Client provided Base RIM already loaded in database.");
LOG.info("Client provided Support RIM already loaded in database.");
}
} catch (IOException ioEx) {
LOG.error(ioEx);
@ -778,7 +806,25 @@ public abstract class AbstractAttestationCertificateAuthority
}
if (dv.hasLivelog()) {
LOG.error("Live Log Exists");
fileName = String.format("%s.measurement",
clientName);
try {
// find previous version. If it exists, delete it
support = EventLogMeasurements.select(referenceManifestManager)
.byManufacturer(dv.getHw().getManufacturer())
.includeArchived().getRIM();
if (support != null) {
this.referenceManifestManager.delete(support);
}
support = new EventLogMeasurements(fileName,
dv.getLivelog().toByteArray());
support.setPlatformManufacturer(dv.getHw().getManufacturer());
support.setPlatformModel(dv.getHw().getProductName());
support.setTagId(tagId);
this.referenceManifestManager.save(support);
} catch (IOException ioEx) {
LOG.error(ioEx);
}
}
// Get TPM info, currently unimplemented

View File

@ -7,18 +7,20 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.EventLogMeasurements;
import hirs.data.persist.SupportReferenceManifest;
import hirs.data.persist.TPMMeasurementRecord;
import hirs.data.persist.SwidResource;
import hirs.data.persist.PCRPolicy;
import hirs.data.persist.ArchivableEntity;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.tpm.eventlog.TpmPcrEvent;
import hirs.validation.SupplyChainCredentialValidator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@ -28,6 +30,7 @@ import java.util.Set;
import java.util.LinkedList;
import java.util.UUID;
import java.util.stream.Collectors;
import org.apache.logging.log4j.Level;
import hirs.appraiser.Appraiser;
import hirs.appraiser.SupplyChainAppraiser;
@ -82,20 +85,19 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
/**
* Constructor.
*
* @param policyManager the policy manager
* @param appraiserManager the appraiser manager
* @param certificateManager the cert manager
* @param referenceManifestManager the RIM manager
* @param policyManager the policy manager
* @param appraiserManager the appraiser manager
* @param certificateManager the cert manager
* @param referenceManifestManager the RIM manager
* @param supplyChainValidatorSummaryManager the summary manager
* @param supplyChainCredentialValidator the credential validator
* @param supplyChainCredentialValidator the credential validator
*/
@Autowired
public SupplyChainValidationServiceImpl(final PolicyManager policyManager,
final AppraiserManager appraiserManager,
final CertificateManager certificateManager,
final ReferenceManifestManager referenceManifestManager,
final CrudManager<SupplyChainValidationSummary> supplyChainValidatorSummaryManager,
final CredentialValidator supplyChainCredentialValidator) {
final AppraiserManager appraiserManager, final CertificateManager certificateManager,
final ReferenceManifestManager referenceManifestManager,
final CrudManager<SupplyChainValidationSummary> supplyChainValidatorSummaryManager,
final CredentialValidator supplyChainCredentialValidator) {
this.policyManager = policyManager;
this.appraiserManager = appraiserManager;
this.certificateManager = certificateManager;
@ -109,15 +111,16 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
* an identity request and validates the supply chain in accordance to the
* current supply chain policy.
*
* @param ec The endorsement credential from the identity request.
* @param pcs The platform credentials from the identity request.
* @param ec The endorsement credential from the identity request.
* @param pcs The platform credentials from the identity request.
* @param device The device to be validated.
* @return A summary of the validation results.
*/
@Override
@SuppressWarnings("methodlength")
public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredential ec,
final Set<PlatformCredential> pcs,
final Device device) {
final Set<PlatformCredential> pcs,
final Device device) {
final Appraiser supplyChainAppraiser = appraiserManager.getAppraiser(
SupplyChainAppraiser.NAME);
SupplyChainPolicy policy = (SupplyChainPolicy) policyManager.getDefaultPolicy(
@ -185,7 +188,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL,
AppraisalStatus.Status.FAIL,
"Platform credential(s) missing."
+ " Cannot validate attributes",
+ " Cannot validate attributes",
null, Level.ERROR));
} else {
Iterator<PlatformCredential> it = pcs.iterator();
@ -268,7 +271,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
* on the specific multibase validation check for a delta chain. This method
* also includes the check for delta certificate CA validation as well.
*
* @param pc The platform credential getting checked
* @param pc The platform credential getting checked
* @param platformScv The validation record
* @return The validation record
*/
@ -319,58 +322,62 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
return subPlatformScv;
}
@SuppressWarnings("methodlength")
private SupplyChainValidation validateFirmware(final Device device,
final PCRPolicy pcrPolicy) {
final PCRPolicy pcrPolicy) {
boolean passed = true;
String[] baseline = new String[Integer.SIZE];
Level level = Level.ERROR;
AppraisalStatus fwStatus = null;
String manufacturer = device.getDeviceInfo()
.getHardwareInfo().getManufacturer();
String model = device.getDeviceInfo().getHardwareInfo().getProductName();
ReferenceManifest baseRim = null;
Set<ReferenceManifest> rims = ReferenceManifest
.select(referenceManifestManager).getRIMs();
ReferenceManifest baseReferenceManifest = null;
ReferenceManifest supportReferenceManifest = null;
ReferenceManifest measurement = null;
for (ReferenceManifest rim : rims) {
if (rim instanceof BaseReferenceManifest
&& rim.getPlatformManufacturer().equals(manufacturer)) {
baseRim = rim;
}
baseReferenceManifest = BaseReferenceManifest.select(referenceManifestManager)
.byManufacturer(manufacturer).getRIM();
supportReferenceManifest = SupportReferenceManifest.select(referenceManifestManager)
.byManufacturer(manufacturer).getRIM();
measurement = EventLogMeasurements.select(referenceManifestManager)
.byManufacturer(manufacturer).includeArchived().getRIM();
String failedString = "";
if (baseReferenceManifest == null) {
failedString = "Base Reference Integrity Manifest%n";
passed = false;
}
if (supportReferenceManifest == null) {
failedString += "Support Reference Integrity Manifest%n";
passed = false;
}
if (measurement == null) {
failedString += "Bios measurement";
passed = false;
}
fwStatus = new AppraisalStatus(PASS,
SupplyChainCredentialValidator.FIRMWARE_VALID);
if (baseRim != null) {
BaseReferenceManifest bRim = (BaseReferenceManifest) baseRim;
List<SwidResource> swids = bRim.parseResource();
if (passed) {
fwStatus = new AppraisalStatus(PASS,
SupplyChainCredentialValidator.FIRMWARE_VALID);
TCGEventLog logProcessor;
for (SwidResource swid : swids) {
ReferenceManifest dbRim = ReferenceManifest.select(
referenceManifestManager).byFileName(swid.getName()).getRIM();
if (dbRim != null) {
try {
logProcessor = new TCGEventLog(dbRim.getRimBytes());
baseline = logProcessor.getExpectedPCRValues();
} catch (CertificateException cEx) {
LOGGER.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOGGER.error(noSaEx);
} catch (IOException ioEx) {
LOGGER.error(ioEx);
}
}
try {
logProcessor = new TCGEventLog(supportReferenceManifest.getRimBytes());
baseline = logProcessor.getExpectedPCRValues();
} catch (CertificateException cEx) {
LOGGER.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOGGER.error(noSaEx);
} catch (IOException ioEx) {
LOGGER.error(ioEx);
}
// part 1 of firmware validation check: PCR baseline match
pcrPolicy.setBaselinePcrs(baseline);
if (device != null) {
if (baseline.length > 0) {
String pcrContent = "";
try {
pcrContent = new String(device.getDeviceInfo().getTPMInfo().getPcrValues());
} catch (NullPointerException npEx) {
LOGGER.error(npEx);
}
pcrContent = new String(device.getDeviceInfo().getTPMInfo().getPcrValues());
if (pcrContent.isEmpty()) {
fwStatus = new AppraisalStatus(FAIL,
@ -400,20 +407,58 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
level = Level.INFO;
}
}
// part 2 of firmware validation check: bios measurements
// vs baseline tcg event log
// find the measurement
TCGEventLog tcgEventLog;
TCGEventLog tcgMeasurementLog;
LinkedList<TpmPcrEvent> tpmPcrEvents = new LinkedList<>();
try {
if (measurement.getPlatformManufacturer().equals(manufacturer)) {
tcgMeasurementLog = new TCGEventLog(measurement.getRimBytes());
tcgEventLog = new TCGEventLog(
supportReferenceManifest.getRimBytes());
for (TpmPcrEvent tpe : tcgEventLog.getEventList()) {
if (!tpe.eventCompare(
tcgMeasurementLog.getEventByNumber(
tpe.getEventNumber()))) {
tpmPcrEvents.add(tpe);
}
}
}
} catch (CertificateException cEx) {
LOGGER.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOGGER.error(noSaEx);
} catch (IOException ioEx) {
LOGGER.error(ioEx);
}
if (!tpmPcrEvents.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (TpmPcrEvent tpe : tpmPcrEvents) {
sb.append(String.format("Event %s - %s%n",
tpe.getEventNumber(),
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, "Associated Issued Attestation"
+ " Certificate can not be found.");
fwStatus = new AppraisalStatus(FAIL, "The RIM baseline could not be found.");
}
} else {
fwStatus = new AppraisalStatus(FAIL,
String.format("Firmware validation failed: "
+ "No associated RIM file could be found for %s:%s",
manufacturer, model));
fwStatus = new AppraisalStatus(FAIL, String.format("Firmware Validation failed: "
+ "%s for %s can not be found", failedString, manufacturer));
}
return buildValidationRecord(SupplyChainValidation.ValidationType.FIRMWARE,
fwStatus.getAppStatus(), fwStatus.getMessage(), baseRim, level);
fwStatus.getAppStatus(), fwStatus.getMessage(), baseReferenceManifest, level);
}
/**
@ -442,15 +487,9 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
.getHardwareInfo().getManufacturer();
try {
// need to get pcrs
Set<ReferenceManifest> rims = ReferenceManifest.select(
this.referenceManifestManager).getRIMs();
for (ReferenceManifest r : rims) {
if (r instanceof SupportReferenceManifest
&& r.getPlatformManufacturer().equals(manufacturer)) {
sRim = (SupportReferenceManifest) r;
}
}
sRim = SupportReferenceManifest.select(
this.referenceManifestManager)
.byManufacturer(manufacturer).getRIM();
if (sRim == null) {
fwStatus = new AppraisalStatus(FAIL,
@ -514,7 +553,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
}
private SupplyChainValidation validateEndorsementCredential(final EndorsementCredential ec,
final boolean acceptExpiredCerts) {
final boolean acceptExpiredCerts) {
final SupplyChainValidation.ValidationType validationType
= SupplyChainValidation.ValidationType.ENDORSEMENT_CREDENTIAL;
LOGGER.info("Validating endorsement credential");
@ -543,8 +582,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
}
private SupplyChainValidation validatePlatformCredential(final PlatformCredential pc,
final KeyStore trustedCertificateAuthority,
final boolean acceptExpiredCerts) {
final KeyStore trustedCertificateAuthority, final boolean acceptExpiredCerts) {
final SupplyChainValidation.ValidationType validationType
= SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL;
@ -570,8 +608,8 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
}
}
private SupplyChainValidation validatePlatformCredentialAttributes(final PlatformCredential pc,
final DeviceInfoReport deviceInfoReport,
private SupplyChainValidation validatePlatformCredentialAttributes(
final PlatformCredential pc, final DeviceInfoReport deviceInfoReport,
final EndorsementCredential ec) {
final SupplyChainValidation.ValidationType validationType
= SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL;
@ -635,12 +673,12 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
* 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 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
* validation
* @param logLevel the log level
* @return a SupplyChainValidation
*/
private SupplyChainValidation buildValidationRecord(
@ -691,7 +729,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
* 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.
@ -700,9 +738,9 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
* 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 credential the credential whose CA chain should be retrieved
* @param previouslyQueriedOrganizations a list of organizations to refrain
* from querying
* from querying
* @return a Set containing all relevant CA credentials to the given
* certificate's organization
*/

View File

@ -4,6 +4,7 @@ import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.SupportReferenceManifest;
import hirs.data.persist.SwidResource;
import hirs.persist.DBManagerException;
import hirs.persist.ReferenceManifestManager;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.attestationca.portal.page.Page;
@ -18,7 +19,6 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
import org.apache.logging.log4j.LogManager;
@ -118,7 +118,7 @@ public class ReferenceManifestDetailsPageController
CertificateException, NoSuchAlgorithmException {
HashMap<String, Object> data = new HashMap<>();
ReferenceManifest rim = ReferenceManifest
ReferenceManifest rim = BaseReferenceManifest
.select(referenceManifestManager)
.byEntityId(uuid).getRIM();
@ -171,24 +171,26 @@ public class ReferenceManifestDetailsPageController
data.put("rimType", bRim.getRimType());
List<SwidResource> resources = bRim.parseResource();
String resourceFilename = null;
TCGEventLog logProcessor;
TCGEventLog logProcessor = null;
ReferenceManifest support = null;
if (bRim.getAssociatedRim() == null) {
support = SupportReferenceManifest.select(referenceManifestManager)
.byManufacturer(bRim.getPlatformManufacturer())
.getRIM();
if (support != null) {
bRim.setAssociatedRim(support.getId());
logProcessor = new TCGEventLog(support.getRimBytes());
}
}
// going to have to pull the filename and grab that from the DB
// to get the id to make the link
for (SwidResource swidRes : resources) {
resourceFilename = swidRes.getName();
ReferenceManifest dbRim = ReferenceManifest.select(
referenceManifestManager).byFileName(resourceFilename).getRIM();
if (dbRim != null) {
logProcessor = new TCGEventLog(dbRim.getRimBytes());
if (support != null && swidRes.getName()
.equals(support.getFileName())) {
swidRes.setPcrValues(Arrays.asList(
logProcessor.getExpectedPCRValues()));
if (bRim.getAssociatedRim() == null) {
bRim.setAssociatedRim(dbRim.getId());
}
break;
} else {
swidRes.setPcrValues(new ArrayList<>());
}
@ -196,17 +198,20 @@ public class ReferenceManifestDetailsPageController
data.put("associatedRim", bRim.getAssociatedRim());
data.put("swidFiles", resources);
} else if (rim instanceof SupportReferenceManifest) {
SupportReferenceManifest sRim = (SupportReferenceManifest) rim;
} else {
SupportReferenceManifest sRim = SupportReferenceManifest
.select(referenceManifestManager)
.byEntityId(uuid).getRIM();
if (sRim.getAssociatedRim() == null) {
Set<ReferenceManifest> rims = ReferenceManifest
.select(referenceManifestManager).getRIMs();
for (ReferenceManifest dbRim : rims) {
if (dbRim instanceof BaseReferenceManifest
&& dbRim.getTagId().equals(sRim.getTagId())) {
sRim.setAssociatedRim(dbRim.getId());
break;
ReferenceManifest baseRim = BaseReferenceManifest.select(referenceManifestManager)
.byManufacturer(sRim.getPlatformManufacturer()).getRIM();
if (baseRim != null) {
sRim.setAssociatedRim(baseRim.getId());
try {
referenceManifestManager.update(sRim);
} catch (DBManagerException ex) {
LOGGER.error("Failed to update Support RIM", ex);
}
}
}
@ -217,9 +222,6 @@ public class ReferenceManifestDetailsPageController
TCGEventLog logProcessor = new TCGEventLog(sRim.getRimBytes());
data.put("events", logProcessor.getEventList());
} else {
LOGGER.error(String.format("Unable to find Reference Integrity "
+ "Manifest with ID: %s", uuid));
}
return data;

View File

@ -191,6 +191,8 @@ public class ReferenceManifestPageController
Pattern pattern;
Matcher matcher;
boolean supportRIM = false;
BaseReferenceManifest base;
SupportReferenceManifest support;
// loop through the files
for (MultipartFile file : files) {
@ -201,45 +203,50 @@ public class ReferenceManifestPageController
//Parse reference manifests
ReferenceManifest rim = parseRIM(file, supportRIM, messages);
// look for associated base/support
Set<ReferenceManifest> rims = ReferenceManifest
.select(referenceManifestManager).getRIMs();
// update information for associated support rims
for (ReferenceManifest element : rims) {
if (supportRIM) {
if (element instanceof BaseReferenceManifest) {
BaseReferenceManifest bRim = (BaseReferenceManifest) element;
for (SwidResource swid : bRim.parseResource()) {
if (swid.getName().equals(rim.getFileName())) {
rim.setSwidTagVersion(bRim.getSwidTagVersion());
rim.setPlatformManufacturer(bRim.getPlatformManufacturer());
rim.setPlatformModel(bRim.getPlatformModel());
rim.setTagId(bRim.getTagId());
rim.setAssociatedRim(bRim.getId());
break;
}
if (supportRIM) {
// look for associated base/support
Set<BaseReferenceManifest> rims = BaseReferenceManifest
.select(referenceManifestManager).getRIMs();
support = (SupportReferenceManifest) rim;
// update information for associated support rim
for (BaseReferenceManifest dbRim : rims) {
for (SwidResource swid : dbRim.parseResource()) {
if (swid.getName().equals(rim.getFileName())) {
support.setSwidTagVersion(dbRim.getSwidTagVersion());
support.setPlatformManufacturer(dbRim.getPlatformManufacturer());
support.setPlatformModel(dbRim.getPlatformModel());
support.setTagId(dbRim.getTagId());
support.setAssociatedRim(dbRim.getId());
support.setUpdated(true);
break;
}
}
} else {
BaseReferenceManifest bRim = (BaseReferenceManifest) rim;
for (SwidResource swid : bRim.parseResource()) {
if (element instanceof SupportReferenceManifest) {
SupportReferenceManifest sRim = (SupportReferenceManifest) element;
if (swid.getName().equals(sRim.getFileName())) {
sRim.setPlatformManufacturer(bRim.getPlatformManufacturer());
sRim.setPlatformModel(bRim.getPlatformModel());
sRim.setSwidTagVersion(bRim.getSwidTagVersion());
sRim.setTagId(bRim.getTagId());
rim.setAssociatedRim(sRim.getId());
try {
referenceManifestManager.update(sRim);
} catch (DBManagerException dbmEx) {
LOGGER.error(String.format("Couldn't update Support RIM "
+ "%s with associated UUID %s", rim.getTagId(),
sRim.getId()), dbmEx);
}
break;
}
} else {
base = (BaseReferenceManifest) rim;
for (SwidResource swid : base.parseResource()) {
support = SupportReferenceManifest.select(referenceManifestManager)
.byFileName(swid.getName()).getRIM();
if (support != null) {
base.setAssociatedRim(support.getId());
if (support.isUpdated()) {
// this is separate because I want to break if we found it
// instead of finding it, it is uptodate but still search
break;
} else {
support.setSwidTagVersion(base.getSwidTagVersion());
support.setPlatformManufacturer(base.getPlatformManufacturer());
support.setPlatformModel(base.getPlatformModel());
support.setTagId(base.getTagId());
support.setUpdated(true);
try {
referenceManifestManager.update(support);
} catch (DBManagerException dbmEx) {
LOGGER.error(String.format("Couldn't update Support RIM "
+ "%s with associated UUID %s", rim.getTagId(),
support.getId()), dbmEx);
}
}
}
@ -251,7 +258,7 @@ public class ReferenceManifestPageController
storeManifest(file.getOriginalFilename(),
messages,
rim,
referenceManifestManager);
supportRIM);
}
}
@ -371,10 +378,15 @@ public class ReferenceManifestPageController
*/
private ReferenceManifest getRimFromDb(final String id) throws IllegalArgumentException {
UUID uuid = UUID.fromString(id);
return ReferenceManifest
.select(referenceManifestManager)
ReferenceManifest rim = BaseReferenceManifest.select(referenceManifestManager)
.byEntityId(uuid).getRIM();
if (rim == null) {
rim = SupportReferenceManifest.select(referenceManifestManager)
.byEntityId(uuid).getRIM();
}
return rim;
}
/**
@ -427,24 +439,32 @@ public class ReferenceManifestPageController
* @param fileName name of the file given
* @param messages message object for user display of statuses
* @param referenceManifest the object to store
* @param referenceManifestManager the class that handles the storage
* @param supportRim boolean flag indicating if this is a support RIM
* process.
*/
private void storeManifest(
final String fileName,
final PageMessages messages,
final ReferenceManifest referenceManifest,
final ReferenceManifestManager referenceManifestManager) {
final boolean supportRim) {
ReferenceManifest existingManifest;
// look for existing manifest in the database
try {
existingManifest = ReferenceManifest
.select(referenceManifestManager)
.includeArchived()
.byHashCode(referenceManifest.getRimHash())
.getRIM();
if (supportRim) {
existingManifest = SupportReferenceManifest
.select(referenceManifestManager)
.includeArchived()
.byHashCode(referenceManifest.getRimHash())
.getRIM();
} else {
existingManifest = BaseReferenceManifest
.select(referenceManifestManager)
.includeArchived()
.byHashCode(referenceManifest.getRimHash())
.getRIM();
}
} catch (DBManagerException e) {
final String failMessage = String.format("Querying for existing certificate "
+ "failed (%s): ", fileName);
@ -458,14 +478,14 @@ public class ReferenceManifestPageController
if (existingManifest == null) {
referenceManifestManager.save(referenceManifest);
final String successMsg = String.format("New RIM successfully uploaded (%s): ",
final String successMsg = String.format("RIM successfully uploaded (%s): ",
fileName);
messages.addSuccess(successMsg);
LOGGER.info(successMsg);
return;
}
} catch (DBManagerException dbmEx) {
final String failMessage = String.format("Storing new RIM failed (%s): ", fileName);
final String failMessage = String.format("Storing RIM failed (%s): ", fileName);
messages.addError(failMessage + dbmEx.getMessage());
LOGGER.error(failMessage, dbmEx);
return;

View File

@ -60,7 +60,7 @@
var html = '';
html += rimDetailsLink(full.id);
html += rimDownloadLink(full.id, pagePath);
html += certificateDeleteLink(full.id, pagePath);
html += rimDeleteLink(full.id, pagePath);
return html;
}

View File

@ -43,6 +43,17 @@ function handleDeleteRequest(id) {
}
}
/**
* Handles user request to delete a cert. Prompts user to confirm.
* Upon confirmation, submits the delete form which is required to make
* a POST call to delete the reference integrity manifest.
*/
function handleRimDeleteRequest(id) {
if (confirm("Delete RIM?")) {
$('#deleteForm' + id).submit();
}
}
/**
* Set the data tables using the columns definition, the ajax URL and
* the ID of the table.
@ -133,8 +144,24 @@ function rimDetailsLink(id){
function certificateDeleteLink(id, pagePath){
var icon = icons + '/ic_delete_black_24dp.png';
var formURL = pagePath + "/delete";
var html = '<a href="#!" onclick="handleDeleteRequest(\'' + id + '\')">'
var html = '<a href="#!" onclick="handleDeleteRequest(\'' + id + '\')">'
+ '<img src="' + icon + '" title="Delete"></a>'
+ '<form id="deleteForm' + id + '" action="' + formURL + '" method="post">'
+ '<input name="id" type="hidden" value="' + id + '"></form>';
return html;
}
/**
* Create a RIM delete link for the specified ID
* @param id of the RIM
* @param pagePath path to the link
*/
function rimDeleteLink(id, pagePath){
var icon = icons + '/ic_delete_black_24dp.png';
var formURL = pagePath + "/delete";
var html = '<a href="#!" onclick="handleRimDeleteRequest(\'' + id + '\')">'
+ '<img src="' + icon + '" title="Delete"></a>'
+ '<form id="deleteForm' + id + '" action="' + formURL + '" method="post">'
+ '<input name="id" type="hidden" value="' + id + '"></form>';

View File

@ -1,5 +1,6 @@
package hirs.attestationca.portal.page.controllers;
import hirs.data.persist.BaseReferenceManifest;
import hirs.data.persist.ReferenceManifest;
import hirs.persist.ReferenceManifestManager;
import hirs.attestationca.portal.page.Page;
@ -65,7 +66,7 @@ public class ReferenceManifestPageControllerTest extends PageControllerTest {
.andReturn();
Set<ReferenceManifest> records
= referenceManifestManager.get(ReferenceManifest
= referenceManifestManager.get(BaseReferenceManifest
.select(referenceManifestManager).includeArchived());
Assert.assertEquals(records.size(), 1);
@ -135,7 +136,7 @@ public class ReferenceManifestPageControllerTest extends PageControllerTest {
"Pre-existing RIM found and unarchived (generated_good.swidtag): ");
// verify the cert was actually stored
Set<ReferenceManifest> records = referenceManifestManager.get(ReferenceManifest.select(
Set<ReferenceManifest> records = referenceManifestManager.get(BaseReferenceManifest.select(
referenceManifestManager));
Assert.assertEquals(records.size(), 1);
@ -162,7 +163,8 @@ public class ReferenceManifestPageControllerTest extends PageControllerTest {
// verify the cert was actually stored
Set<ReferenceManifest> records
= referenceManifestManager.get(ReferenceManifest.select(referenceManifestManager));
= referenceManifestManager.get(BaseReferenceManifest
.select(referenceManifestManager));
Assert.assertEquals(records.size(), 1);
ReferenceManifest rim = records.iterator().next();
@ -180,7 +182,7 @@ public class ReferenceManifestPageControllerTest extends PageControllerTest {
.andReturn();
Set<ReferenceManifest> records
= referenceManifestManager.get(ReferenceManifest
= referenceManifestManager.get(BaseReferenceManifest
.select(referenceManifestManager).includeArchived());
Assert.assertEquals(records.size(), 1);

View File

@ -1,6 +1,8 @@
package hirs.data.persist;
import hirs.persist.DBReferenceManifestManager;
import hirs.persist.ReferenceManifestManager;
import hirs.persist.ReferenceManifestSelector;
import hirs.utils.xjc.BaseElement;
import hirs.utils.xjc.Directory;
import hirs.utils.xjc.FilesystemItem;
@ -76,6 +78,56 @@ public class BaseReferenceManifest extends ReferenceManifest {
private String linkHref = null;
private String linkRel = null;
/**
* This class enables the retrieval of BaseReferenceManifest by their attributes.
*/
public static class Selector extends ReferenceManifestSelector<BaseReferenceManifest> {
/**
* Construct a new ReferenceManifestSelector that will use
* the given (@link ReferenceManifestManager}
* to retrieve one or may BaseReferenceManifest.
*
* @param referenceManifestManager the reference manifest manager to be used to retrieve
* reference manifests.
*/
public Selector(final ReferenceManifestManager referenceManifestManager) {
super(referenceManifestManager, BaseReferenceManifest.class);
}
/**
* Specify the platform manufacturer that rims must have to be considered
* as matching.
* @param manufacturer string for the manufacturer
* @return this instance
*/
public Selector byManufacturer(final String manufacturer) {
setFieldValue(PLATFORM_MANUFACTURER, manufacturer);
return this;
}
/**
* Specify the platform manufacturer id that rims must have to be considered
* as matching.
* @param manufacturerId string for the id of the manufacturer
* @return this instance
*/
public Selector byManufacturerId(final String manufacturerId) {
setFieldValue(PLATFORM_MANUFACTURER_ID, manufacturerId);
return this;
}
/**
* Specify the platform model that rims must have to be considered
* as matching.
* @param model string for the model
* @return this instance
*/
public Selector byModel(final String model) {
setFieldValue(PLATFORM_MODEL, model);
return this;
}
}
/**
* Support constructor for the RIM object.
*
@ -162,6 +214,17 @@ public class BaseReferenceManifest extends ReferenceManifest {
}
/**
* Get a Selector for use in retrieving ReferenceManifest.
*
* @param rimMan the ReferenceManifestManager to be used to retrieve
* persisted RIMs
* @return a Selector instance to use for retrieving RIMs
*/
public static Selector select(final ReferenceManifestManager rimMan) {
return new Selector(rimMan);
}
/**
* This method and code is pulled and adopted from the TCG Tool. Since this
* is taking in an file stored in memory through http, this was changed from

View File

@ -0,0 +1,185 @@
package hirs.data.persist;
import com.fasterxml.jackson.annotation.JsonIgnore;
import hirs.persist.ReferenceManifestManager;
import hirs.persist.ReferenceManifestSelector;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.tpm.eventlog.TpmPcrEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.persistence.Column;
import javax.persistence.Entity;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
/**
* Sub class that will just focus on PCR Values and Events.
* Similar to {@link hirs.data.persist.SupportReferenceManifest}
* however this is the live log from the client.
*/
@Entity
public class EventLogMeasurements extends ReferenceManifest {
private static final Logger LOGGER = LogManager.getLogger(EventLogMeasurements.class);
@Column
@JsonIgnore
private int pcrHash = 0;
/**
* This class enables the retrieval of SupportReferenceManifest by their attributes.
*/
public static class Selector extends ReferenceManifestSelector<EventLogMeasurements> {
/**
* Construct a new ReferenceManifestSelector that
* will use the given (@link ReferenceManifestManager}
* to retrieve one or may SupportReferenceManifest.
*
* @param referenceManifestManager the reference manifest manager to be used to retrieve
* reference manifests.
*/
public Selector(final ReferenceManifestManager referenceManifestManager) {
super(referenceManifestManager, EventLogMeasurements.class, false);
}
/**
* Specify the platform manufacturer that rims must have to be considered
* as matching.
* @param manufacturer string for the manufacturer
* @return this instance
*/
public Selector byManufacturer(final String manufacturer) {
setFieldValue(PLATFORM_MANUFACTURER, manufacturer);
return this;
}
/**
* Specify the platform manufacturer id that rims must have to be considered
* as matching.
* @param manufacturerId string for the id of the manufacturer
* @return this instance
*/
public Selector byManufacturerId(final String manufacturerId) {
setFieldValue(PLATFORM_MANUFACTURER_ID, manufacturerId);
return this;
}
/**
* Specify the platform model that rims must have to be considered
* as matching.
* @param model string for the model
* @return this instance
*/
public Selector byModel(final String model) {
setFieldValue(PLATFORM_MODEL, model);
return this;
}
}
/**
* Support constructor for the RIM object.
*
* @param rimBytes byte array representation of the RIM
* @throws java.io.IOException if unable to unmarshal the string
*/
public EventLogMeasurements(final byte[] rimBytes) throws IOException {
this("blank.measurement", rimBytes);
}
/**
* Support constructor for the RIM object.
*
* @param fileName - string representation of the uploaded file.
* @param rimBytes byte array representation of the RIM
* @throws java.io.IOException if unable to unmarshal the string
*/
public EventLogMeasurements(final String fileName,
final byte[] rimBytes
) throws IOException {
super(rimBytes);
this.setFileName(fileName);
this.setRimType(MEASUREMENT_RIM);
this.archive("Measurement event log");
this.pcrHash = 0;
}
/**
* Default constructor necessary for Hibernate.
*/
protected EventLogMeasurements() {
super();
this.pcrHash = 0;
}
/**
* Get a Selector for use in retrieving ReferenceManifest.
*
* @param rimMan the ReferenceManifestManager to be used to retrieve
* persisted RIMs
* @return a Selector instance to use for retrieving RIMs
*/
public static Selector select(final ReferenceManifestManager rimMan) {
return new Selector(rimMan);
}
/**
* Getter method for the expected PCR values contained within the support
* RIM.
* @return a string array of the pcr values.
*/
public String[] getExpectedPCRList() {
try {
TCGEventLog logProcessor = new TCGEventLog(this.getRimBytes());
this.pcrHash = Arrays.hashCode(logProcessor.getExpectedPCRValues());
return logProcessor.getExpectedPCRValues();
} catch (CertificateException cEx) {
LOGGER.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOGGER.error(noSaEx);
} catch (IOException ioEx) {
LOGGER.error(ioEx);
}
return new String[0];
}
/**
* Getter method for the event log that should be present in the support RIM.
*
* @return list of TPM PCR Events for display
*/
public Collection<TpmPcrEvent> getEventLog() {
TCGEventLog logProcessor = null;
try {
logProcessor = new TCGEventLog(this.getRimBytes());
return logProcessor.getEventList();
} catch (CertificateException cEx) {
LOGGER.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOGGER.error(noSaEx);
} catch (IOException ioEx) {
LOGGER.error(ioEx);
}
return new ArrayList<>();
}
/**
* Getter for the PCR Hash contained in the support RIM.
* @return hash in int form
*/
public int getPcrHash() {
return pcrHash;
}
/**
* Setter for the PCR Hash.
* @param pcrHash hash in int form
*/
public void setPcrHash(final int pcrHash) {
this.pcrHash = pcrHash;
}
}

View File

@ -9,8 +9,6 @@ import javax.persistence.Entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.base.Preconditions;
import hirs.persist.ReferenceManifestManager;
import hirs.persist.ReferenceManifestSelector;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.annotations.Type;
@ -39,6 +37,10 @@ public abstract class ReferenceManifest extends ArchivableEntity {
* String for display of a Support RIM.
*/
public static final String SUPPORT_RIM = "Support";
/**
* String for display of a Support RIM.
*/
public static final String MEASUREMENT_RIM = "Measurement";
/**
* String for the xml schema ios standard.
@ -60,26 +62,6 @@ public abstract class ReferenceManifest extends ArchivableEntity {
private static final Logger LOGGER = LogManager.getLogger(ReferenceManifest.class);
/**
* This class enables the retrieval of PlatformCredentials by their
* attributes.
*/
public static class Selector
extends ReferenceManifestSelector<ReferenceManifest> {
/**
* Construct a new ReferenceManifestSelector that will use the given
* {@link ReferenceManifestManager} to retrieve one or many Reference
* Integrity Manifest.
*
* @param referenceManifestManager the RIM manager to be used to
* retrieve RIMs
*/
public Selector(final ReferenceManifestManager referenceManifestManager) {
super(referenceManifestManager);
}
}
/**
* Holds the name of the 'rimHash' field.
*/
@ -108,17 +90,6 @@ public abstract class ReferenceManifest extends ArchivableEntity {
@Column
private UUID associatedRim;
/**
* Get a Selector for use in retrieving ReferenceManifest.
*
* @param rimMan the ReferenceManifestManager to be used to retrieve
* persisted RIMs
* @return a ReferenceManifest.Selector instance to use for retrieving RIMs
*/
public static Selector select(final ReferenceManifestManager rimMan) {
return new Selector(rimMan);
}
/**
* Default constructor necessary for Hibernate.
*/

View File

@ -1,6 +1,8 @@
package hirs.data.persist;
import com.fasterxml.jackson.annotation.JsonIgnore;
import hirs.persist.ReferenceManifestManager;
import hirs.persist.ReferenceManifestSelector;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.tpm.eventlog.TpmPcrEvent;
import org.apache.logging.log4j.LogManager;
@ -13,8 +15,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Collection;
/**
* Sub class that will just focus on PCR Values and Events.
@ -26,9 +27,62 @@ public class SupportReferenceManifest extends ReferenceManifest {
@Column
@JsonIgnore
private int pcrHash = 0;
@Column
private boolean updated = false;
/**
* Support constructor for the RIM object.
* This class enables the retrieval of SupportReferenceManifest by their attributes.
*/
public static class Selector extends ReferenceManifestSelector<SupportReferenceManifest> {
/**
* Construct a new ReferenceManifestSelector that will
* use the given (@link ReferenceManifestManager}
* to retrieve one or may SupportReferenceManifest.
*
* @param referenceManifestManager the reference manifest manager to be used to retrieve
* reference manifests.
*/
public Selector(final ReferenceManifestManager referenceManifestManager) {
super(referenceManifestManager, SupportReferenceManifest.class);
}
/**
* Specify the platform manufacturer that rims must have to be considered
* as matching.
* @param manufacturer string for the manufacturer
* @return this instance
*/
public Selector byManufacturer(final String manufacturer) {
setFieldValue(PLATFORM_MANUFACTURER, manufacturer);
return this;
}
/**
* Specify the platform manufacturer id that rims must have to be considered
* as matching.
* @param manufacturerId string for the id of the manufacturer
* @return this instance
*/
public Selector byManufacturerId(final String manufacturerId) {
setFieldValue(PLATFORM_MANUFACTURER_ID, manufacturerId);
return this;
}
/**
* Specify the platform model that rims must have to be considered
* as matching.
* @param model string for the model
* @return this instance
*/
public Selector byModel(final String model) {
setFieldValue(PLATFORM_MODEL, model);
return this;
}
}
/**
* Main constructor for the RIM object. This takes in a byte array of a
* valid swidtag file and parses the information.
*
* @param fileName - string representation of the uploaded file.
* @param rimBytes byte array representation of the RIM
@ -36,9 +90,10 @@ public class SupportReferenceManifest extends ReferenceManifest {
*/
public SupportReferenceManifest(final String fileName,
final byte[] rimBytes) throws IOException {
this(rimBytes);
this.setRimType(SUPPORT_RIM);
super(rimBytes);
this.setFileName(fileName);
this.setRimType(SUPPORT_RIM);
this.pcrHash = 0;
}
/**
@ -49,9 +104,7 @@ public class SupportReferenceManifest extends ReferenceManifest {
* @throws IOException if unable to unmarshal the string
*/
public SupportReferenceManifest(final byte[] rimBytes) throws IOException {
super(rimBytes);
this.setRimType(SUPPORT_RIM);
this.pcrHash = 0;
this("blank.rimel", rimBytes);
}
/**
@ -62,6 +115,17 @@ public class SupportReferenceManifest extends ReferenceManifest {
this.pcrHash = 0;
}
/**
* Get a Selector for use in retrieving ReferenceManifest.
*
* @param rimMan the ReferenceManifestManager to be used to retrieve
* persisted RIMs
* @return a Selector instance to use for retrieving RIMs
*/
public static Selector select(final ReferenceManifestManager rimMan) {
return new Selector(rimMan);
}
/**
* Getter method for the expected PCR values contained within the support
* RIM.
@ -88,11 +152,11 @@ public class SupportReferenceManifest extends ReferenceManifest {
*
* @return list of TPM PCR Events for display
*/
public List<TpmPcrEvent> getEventLog() {
public Collection<TpmPcrEvent> getEventLog() {
TCGEventLog logProcessor = null;
try {
logProcessor = new TCGEventLog(this.getRimBytes());
return Collections.unmodifiableList(logProcessor.getEventList());
return logProcessor.getEventList();
} catch (CertificateException cEx) {
LOGGER.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
@ -119,4 +183,20 @@ public class SupportReferenceManifest extends ReferenceManifest {
public void setPcrHash(final int pcrHash) {
this.pcrHash = pcrHash;
}
/**
* Indicates if the support rim has updated information from the base.
* @return flag indicating that it is up to date
*/
public boolean isUpdated() {
return updated;
}
/**
* Setter for the support RIM flag status.
* @param updated updated flag status
*/
public void setUpdated(final boolean updated) {
this.updated = updated;
}
}

View File

@ -86,10 +86,11 @@ public class DBReferenceManifestManager extends DBManager<ReferenceManifest>
*/
@Override
@SuppressWarnings("unchecked")
public Set<ReferenceManifest> get(final ReferenceManifestSelector referenceManifestSelector) {
public <T extends ReferenceManifest> Set<T> get(
final ReferenceManifestSelector referenceManifestSelector) {
LOGGER.info("Getting the full set of Reference Manifest files.");
return new HashSet<>(
(List<ReferenceManifest>) getWithCriteria(
(List<T>) getWithCriteria(
referenceManifestSelector.getReferenceManifestClass(),
Collections.singleton(referenceManifestSelector.getCriterion())
)

View File

@ -28,10 +28,11 @@ public interface ReferenceManifestManager extends OrderedListQuerier<ReferenceMa
/**
* Retrieve RIMs according to the given {@link ReferenceManifestSelector}.
*
* @param <T> the type of reference manifest that will be retrieved
* @param referenceManifestSelector a {@link ReferenceManifestSelector} to use for querying
* @return a Set of matching RIMs, which may be empty
*/
Set<ReferenceManifest> get(ReferenceManifestSelector referenceManifestSelector);
<T extends ReferenceManifest> Set<T> get(ReferenceManifestSelector referenceManifestSelector);
/**
* Delete the given RIM.

View File

@ -1,6 +1,7 @@
package hirs.persist;
import com.google.common.base.Preconditions;
import hirs.data.persist.ReferenceManifest;
import hirs.data.persist.certificate.Certificate;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
@ -21,16 +22,26 @@ import java.util.UUID;
* with a {@link ReferenceManifestManager}. To make use of this object,
* use (some ReferenceManifest).select(ReferenceManifestManager).
*
* @param <ReferenceManifest> the type of referenceManifest that will be retrieved
* @param <T> the type of Reference Integrity Manifest that will be retrived.
*/
public abstract class ReferenceManifestSelector<ReferenceManifest> {
private static final String PLATFORM_MANUFACTURER = "platformManufacturer";
private static final String PLATFORM_MANUFACTURER_ID = "platformManufacturerId";
private static final String PLATFORM_MODEL = "platformModel";
public abstract class ReferenceManifestSelector<T extends ReferenceManifest> {
/**
* String representing the database field for the manufacturer.
*/
public static final String PLATFORM_MANUFACTURER = "platformManufacturer";
/**
* String representing the database field for the manufacturer id.
*/
public static final String PLATFORM_MANUFACTURER_ID = "platformManufacturerId";
/**
* String representing the database field for the model.
*/
public static final String PLATFORM_MODEL = "platformModel";
private static final String RIM_TYPE_FIELD = "rimType";
private static final String RIM_FILENAME_FIELD = "fileName";
private final ReferenceManifestManager referenceManifestManager;
private final Class<T> referenceTypeClass;
private final Map<String, Object> fieldValueSelections;
private boolean excludeArchivedRims;
@ -39,25 +50,35 @@ public abstract class ReferenceManifestSelector<ReferenceManifest> {
* Default Constructor.
*
* @param referenceManifestManager the RIM manager to be used to retrieve RIMs
* @param referenceTypeClass the type of Reference Manifest to process.
*/
public ReferenceManifestSelector(final ReferenceManifestManager referenceManifestManager) {
this(referenceManifestManager, true);
public ReferenceManifestSelector(final ReferenceManifestManager referenceManifestManager,
final Class<T> referenceTypeClass) {
this(referenceManifestManager, referenceTypeClass, true);
}
/**
* Standard Constructor for the Selector.
*
* @param referenceManifestManager the RIM manager to be used to retrieve RIMs
* @param referenceTypeClass the type of Reference Manifest to process.
* @param excludeArchivedRims true if excluding archived RIMs
*/
public ReferenceManifestSelector(final ReferenceManifestManager referenceManifestManager,
final Class<T> referenceTypeClass,
final boolean excludeArchivedRims) {
Preconditions.checkArgument(
referenceManifestManager != null,
"reference manifest manager cannot be null"
);
Preconditions.checkArgument(
referenceTypeClass != null,
"type cannot be null"
);
this.referenceManifestManager = referenceManifestManager;
this.referenceTypeClass = referenceTypeClass;
this.excludeArchivedRims = excludeArchivedRims;
this.fieldValueSelections = new HashMap<>();
}
@ -68,51 +89,18 @@ public abstract class ReferenceManifestSelector<ReferenceManifest> {
* @param uuid the UUID to query
* @return this instance (for chaining further calls)
*/
public ReferenceManifestSelector byEntityId(final UUID uuid) {
public ReferenceManifestSelector<T> byEntityId(final UUID uuid) {
setFieldValue(Certificate.ID_FIELD, uuid);
return this;
}
/**
* Specify the platform manufacturer that rims must have to be considered
* as matching.
* @param manufacturer string for the manufacturer
* @return this instance
*/
public ReferenceManifestSelector byManufacturer(final String manufacturer) {
setFieldValue(PLATFORM_MANUFACTURER, manufacturer);
return this;
}
/**
* Specify the platform manufacturer id that rims must have to be considered
* as matching.
* @param manufacturerId string for the id of the manufacturer
* @return this instance
*/
public ReferenceManifestSelector byManufacturerId(final String manufacturerId) {
setFieldValue(PLATFORM_MANUFACTURER_ID, manufacturerId);
return this;
}
/**
* Specify the platform model that rims must have to be considered
* as matching.
* @param model string for the model
* @return this instance
*/
public ReferenceManifestSelector byModel(final String model) {
setFieldValue(PLATFORM_MODEL, model);
return this;
}
/**
* Specify the hash code of the bytes that rim must match.
*
* @param rimHash the hash code of the bytes to query for
* @return this instance (for chaining further calls)
*/
public ReferenceManifestSelector byHashCode(final int rimHash) {
public ReferenceManifestSelector<T> byHashCode(final int rimHash) {
setFieldValue(hirs.data.persist.ReferenceManifest.RIM_HASH_FIELD, rimHash);
return this;
}
@ -122,7 +110,7 @@ public abstract class ReferenceManifestSelector<ReferenceManifest> {
* @param fileName the name of the file associated with the rim
* @return instance of the manifest in relation to the filename.
*/
public ReferenceManifestSelector byFileName(final String fileName) {
public ReferenceManifestSelector<T> byFileName(final String fileName) {
setFieldValue(RIM_FILENAME_FIELD, fileName);
return this;
}
@ -132,7 +120,7 @@ public abstract class ReferenceManifestSelector<ReferenceManifest> {
* @param rimType the type of rim
* @return this instance
*/
public ReferenceManifestSelector byRimType(final String rimType) {
public ReferenceManifestSelector<T> byRimType(final String rimType) {
setFieldValue(RIM_TYPE_FIELD, rimType);
return this;
}
@ -181,8 +169,8 @@ public abstract class ReferenceManifestSelector<ReferenceManifest> {
*
* @return a matching RIM or null if none is found
*/
public hirs.data.persist.ReferenceManifest getRIM() {
Set<hirs.data.persist.ReferenceManifest> rims = execute();
public T getRIM() {
Set<T> rims = execute();
if (rims.isEmpty()) {
return null;
}
@ -198,7 +186,7 @@ public abstract class ReferenceManifestSelector<ReferenceManifest> {
*
* @return a Set of matching RIMs, possibly empty
*/
public Set<hirs.data.persist.ReferenceManifest> getRIMs() {
public Set<T> getRIMs() {
return Collections.unmodifiableSet(new HashSet<>(execute()));
}
@ -226,13 +214,13 @@ public abstract class ReferenceManifestSelector<ReferenceManifest> {
/**
* @return the rim class that this instance will query
*/
public Class<hirs.data.persist.ReferenceManifest> getReferenceManifestClass() {
return hirs.data.persist.ReferenceManifest.class;
public Class<T> getReferenceManifestClass() {
return this.referenceTypeClass;
}
// construct and execute query
private Set<hirs.data.persist.ReferenceManifest> execute() {
Set<hirs.data.persist.ReferenceManifest> results = this.referenceManifestManager.get(this);
private Set<T> execute() {
Set<T> results = this.referenceManifestManager.get(this);
return results;
}
@ -241,7 +229,7 @@ public abstract class ReferenceManifestSelector<ReferenceManifest> {
*
* @return the selector
*/
public ReferenceManifestSelector<ReferenceManifest> includeArchived() {
public ReferenceManifestSelector<T> includeArchived() {
this.excludeArchivedRims = false;
return this;
}

View File

@ -7,7 +7,8 @@ import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
@ -22,6 +23,7 @@ import hirs.tpm.eventlog.uefi.UefiConstants;
import hirs.utils.HexUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* Class for handling different formats of TCG Event logs.
*/
@ -60,7 +62,7 @@ public final class TCGEventLog {
/** 2 dimensional array holding the PCR values. */
private byte[][] pcrList;
/** List of parsed events within the log. */
private ArrayList<TpmPcrEvent> eventList = new ArrayList<>();
private LinkedHashMap<Integer, TpmPcrEvent> eventList = new LinkedHashMap<>();
/** Length of PCR. Indicates which hash algorithm is used. */
private int pcrLength;
/** Name of hash algorithm. */
@ -138,14 +140,14 @@ public final class TCGEventLog {
bHexEvent = bHexEventFlag;
ByteArrayInputStream is = new ByteArrayInputStream(rawlog);
// Process the 1st entry as a SHA1 format (per the spec)
eventList.add(new TpmPcrEvent1(is, eventNumber++));
eventList.put(eventNumber, new TpmPcrEvent1(is, eventNumber++));
// put all events into an event list for further processing
while (is.available() > 0) {
if (bCryptoAgile) {
eventList.add(new TpmPcrEvent2(is, eventNumber++));
eventList.put(eventNumber, new TpmPcrEvent2(is, eventNumber++));
} else {
eventList.add(new TpmPcrEvent1(is, eventNumber++));
eventList.put(eventNumber, new TpmPcrEvent1(is, eventNumber++));
}
}
calculatePcrValues();
@ -204,7 +206,7 @@ public final class TCGEventLog {
private void calculatePcrValues() {
byte[] extendedPCR;
initPcrList();
for (TpmPcrEvent currentEvent : eventList) {
for (TpmPcrEvent currentEvent : eventList.values()) {
if (currentEvent.getPcrIndex() >= 0) { // Ignore NO_EVENTS which can have a PCR=-1
try {
if (currentEvent.getEventType() != NO_ACTION_EVENT) {
@ -271,8 +273,18 @@ public final class TCGEventLog {
* Returns a list of event found in the Event Log.
* @return an arraylist of event.
*/
public ArrayList<TpmPcrEvent> getEventList() {
return eventList;
public Collection<TpmPcrEvent> getEventList() {
return eventList.values();
}
/**
* Returns a specific element of the Event Log that corresponds to the requested
* event number.
* @param eventNumber specific event to find in the list.
* @return TPM Event in the position of the list
*/
public TpmPcrEvent getEventByNumber(final int eventNumber) {
return eventList.get(eventNumber);
}
/**
@ -291,7 +303,7 @@ public final class TCGEventLog {
*/
public String toString() {
StringBuilder sb = new StringBuilder();
for (TpmPcrEvent event : eventList) {
for (TpmPcrEvent event : eventList.values()) {
sb.append(event.toString(bEvent, bHexEvent, bContent));
}
sb.append("Event Log processing completed.\n");

View File

@ -55,6 +55,7 @@ public class TpmPcrEvent {
private static final int INDENT_3 = 3;
/**
* Log format. SHA1=1, Crytpo agile=2.
* this can be refactored out
*/
private int logFormat = -1;
/**
@ -102,6 +103,7 @@ public class TpmPcrEvent {
*/
private byte[] eventDataSha256hash;
private EvPostCode evPostCode;
private int eventNumber;
/**
* Constructor.
@ -248,6 +250,22 @@ public class TpmPcrEvent {
return java.util.Arrays.copyOf(event, event.length);
}
/**
* Getter for the event number for this event.
* @return the # for this event
*/
public int getEventNumber() {
return eventNumber;
}
/**
* Setter for the event number.
* @param eventNumber position in the list
*/
public final void setEventNumber(final int eventNumber) {
this.eventNumber = eventNumber;
}
/**
* Sets the event content after processing.
*
@ -450,6 +468,7 @@ public class TpmPcrEvent {
public String processEvent(final byte[] event, final byte[] eventContent, final int eventNumber)
throws CertificateException, NoSuchAlgorithmException, IOException {
int eventID = (int) eventType;
this.eventNumber = eventNumber;
description += "Event# " + eventNumber + ": ";
description += "Index PCR[" + getPcrIndex() + "]\n";
description += "Event Type: 0x" + Long.toHexString(eventType) + " " + eventString(eventID);
@ -686,6 +705,19 @@ public class TpmPcrEvent {
return result;
}
/**
* This method takes in an event and compares the hashes to verify that they match.
* @param tpmPcrEvent an event to match.
* @return true if the event # matches and the hash is correct.
*/
public boolean eventCompare(final TpmPcrEvent tpmPcrEvent) {
if (tpmPcrEvent.getPcrIndex() != this.getPcrIndex()) {
return false;
}
return Arrays.equals(this.digest, tpmPcrEvent.getEventDigest());
}
/**
* Checks a byte array for all zeros.
*

View File

@ -31,14 +31,14 @@ public class TpmPcrEvent1 extends TpmPcrEvent {
/**
* Constructor.
*
* @param is ByteArrayInputStream holding the TCG Log event.
* @param is ByteArrayInputStream holding the TCG Log event.
* @param eventNumber event position within the event log.
* @throws IOException if an error occurs in parsing the event.
* @throws IOException if an error occurs in parsing the event.
* @throws NoSuchAlgorithmException if an undefined algorithm is encountered.
* @throws CertificateException If a certificate within an event can't be processed.
* @throws CertificateException If a certificate within an event can't be processed.
*/
public TpmPcrEvent1(final ByteArrayInputStream is, final int eventNumber)
throws IOException, CertificateException, NoSuchAlgorithmException {
throws IOException, CertificateException, NoSuchAlgorithmException {
super(is);
setDigestLength(EvConstants.SHA1_LENGTH);
setLogFormat(1);
@ -63,22 +63,22 @@ public class TpmPcrEvent1 extends TpmPcrEvent {
eventContent = new byte[eventSize];
is.read(eventContent);
setEventContent(eventContent);
// copy entire event into a byte array for processing
int eventLength = rawIndex.length + rawType.length + eventDigest.length
+ rawEventSize.length;
int offset = 0;
event = new byte[eventLength];
System.arraycopy(rawIndex, 0, event, offset, rawIndex.length);
offset += rawIndex.length;
System.arraycopy(rawType, 0, event, offset, rawType.length);
offset += rawType.length;
System.arraycopy(eventDigest, 0, event, offset, eventDigest.length);
offset += eventDigest.length;
System.arraycopy(rawEventSize, 0, event, offset, rawEventSize.length);
offset += rawEventSize.length;
setEventData(event);
//System.arraycopy(eventContent, 0, event, offset, eventContent.length);
this.processEvent(event, eventContent, eventNumber);
// copy entire event into a byte array for processing
int eventLength = rawIndex.length + rawType.length + eventDigest.length
+ rawEventSize.length;
int offset = 0;
event = new byte[eventLength];
System.arraycopy(rawIndex, 0, event, offset, rawIndex.length);
offset += rawIndex.length;
System.arraycopy(rawType, 0, event, offset, rawType.length);
offset += rawType.length;
System.arraycopy(eventDigest, 0, event, offset, eventDigest.length);
offset += eventDigest.length;
System.arraycopy(rawEventSize, 0, event, offset, rawEventSize.length);
offset += rawEventSize.length;
setEventData(event);
//System.arraycopy(eventContent, 0, event, offset, eventContent.length);
this.processEvent(event, eventContent, eventNumber);
}
}
}
}

View File

@ -66,14 +66,14 @@ public class TpmPcrEvent2 extends TpmPcrEvent {
/**
* Constructor.
*
* @param is ByteArrayInputStream holding the TCG Log event
* @param is ByteArrayInputStream holding the TCG Log event
* @param eventNumber event position within the event log.
* @throws IOException if an error occurs in parsing the event
* @throws IOException if an error occurs in parsing the event
* @throws NoSuchAlgorithmException if an undefined algorithm is encountered.
* @throws CertificateException If a certificate within an event can't be processed.
* @throws CertificateException If a certificate within an event can't be processed.
*/
public TpmPcrEvent2(final ByteArrayInputStream is, final int eventNumber)
throws IOException, CertificateException, NoSuchAlgorithmException {
throws IOException, CertificateException, NoSuchAlgorithmException {
super(is);
setDigestLength(EvConstants.SHA256_LENGTH);
setLogFormat(2);
@ -110,9 +110,9 @@ public class TpmPcrEvent2 extends TpmPcrEvent {
is.read(eventContent);
setEventContent(eventContent);
int eventLength = rawIndex.length + rawType.length + eventDigest.length
+ rawEventSize.length;
+ rawEventSize.length;
int offset = 0;
for (TcgTpmtHa hash:hashlist) {
for (TcgTpmtHa hash : hashlist) {
eventLength += hash.getBuffer().length;
}
event = new byte[eventLength];
@ -129,12 +129,4 @@ public class TpmPcrEvent2 extends TpmPcrEvent {
this.processEvent(event, eventContent, eventNumber);
}
}
/**
* Returns a list of digests within this event.
* @return a list of digests.
*/
public ArrayList<TcgTpmtHa> getHashList() {
return hashlist;
}
}