This is a checkout of some changes to the resource management for swid tags so that the file name listed is associated with the stored support RIMS.

This commit is contained in:
Cyrus 2021-03-30 06:35:14 -04:00
parent a6c6fbfb31
commit 4911742c7a
4 changed files with 138 additions and 203 deletions

View File

@ -94,9 +94,11 @@ import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -706,6 +708,8 @@ public abstract class AbstractAttestationCertificateAuthority
return (RSAPublicKey) assemblePublicKey(modulus);
}
private static final int NUM_OF_VARIABLES = 5;
/**
* Converts a protobuf DeviceInfo object to a HIRS Utils DeviceInfoReport object.
* @param claim the protobuf serialized identity claim containing the device info
@ -774,12 +778,56 @@ public abstract class AbstractAttestationCertificateAuthority
dv.getHw().getProductName());
ReferenceManifest dbBaseRim = null;
ReferenceManifest support;
EventLogMeasurements measurements;
String tagId = "";
String fileName = "";
Pattern pattern = Pattern.compile("([^\\s]+(\\.(?i)(rimpcr|rimel|bin|log))$)");
Matcher matcher;
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
/**
* We need to do a series of things when getting swid/log files from client
* 1. Store what is sent if, it doesn't exist
* and if it does exist, update if needed
* 2. take the file name from the swid file and update the support RIMs
* 3. Update the support rim with swid tag information
*/
if (dv.getLogfileCount() > 0) {
for (ByteString logFile : dv.getLogfileList()) {
try {
support = SupportReferenceManifest.select(referenceManifestManager)
.includeArchived()
.byHashCode(Hex.encodeHexString(messageDigest.digest(
logFile.toByteArray())))
.getRIM();
if (support == null) {
support = new SupportReferenceManifest(
String.format("%s.rimel",
clientName),
logFile.toByteArray());
support.setPlatformManufacturer(dv.getHw().getManufacturer());
support.setPlatformModel(dv.getHw().getProductName());
support.setFileName(String.format("%s_[%s].rimel", clientName,
support.getRimHash().substring(
support.getRimHash().length() - NUM_OF_VARIABLES)));
this.referenceManifestManager.save(support);
} else {
LOG.info("Client provided Support RIM already loaded in database.");
support.restore();
support.resetCreateTime();
this.referenceManifestManager.update(support);
}
} catch (IOException ioEx) {
LOG.error(ioEx);
}
}
} else {
LOG.warn("Device did not send support RIM file...");
}
List<String> archie = new ArrayList<>();
if (dv.getSwidfileCount() > 0) {
for (ByteString swidFile : dv.getSwidfileList()) {
try {
@ -809,12 +857,34 @@ public abstract class AbstractAttestationCertificateAuthority
String.format("%s.swidtag",
clientName),
swidFile.toByteArray());
break;
}
// now update support rim
SupportReferenceManifest dbSupport = SupportReferenceManifest
.select(referenceManifestManager)
.byRimHash(swid.getHashValue()).getRIM();
if (dbSupport == null) {
LOG.error("Why is this happening?");
// I could do this, and then when the actual
// support comes in just update the byte field
}
if (dbSupport != null && !dbSupport.isUpdated()) {
LOG.error("We found the old support");
dbSupport.setFileName(swid.getName());
dbSupport.setSwidTagVersion(base.getSwidTagVersion());
// I might create a get for the bytes of the swidtag file
// so that I can set that instead of the rim ID
dbSupport.setTagId(base.getTagId());
dbSupport.setSwidPatch(dbBaseRim.isSwidPatch());
dbSupport.setSwidSupplemental(dbBaseRim.isSwidSupplemental());
// might want to expand so that the record digest value know
// if it was a patch or supplemental
dbSupport.setUpdated(true);
this.referenceManifestManager.update(dbSupport);
}
}
this.referenceManifestManager.save(dbBaseRim);
} else {
LOG.info("Client provided Base RIM already loaded in database.");
LOG.error("Client provided Base RIM already loaded in database.");
dbBaseRim.restore();
dbBaseRim.resetCreateTime();
this.referenceManifestManager.update(dbBaseRim);
@ -825,88 +895,64 @@ public abstract class AbstractAttestationCertificateAuthority
LOG.error(ioEx);
}
}
for (ByteString swidFile : dv.getSwidfileList()) {
String hashStr = swidFile.toString();
LOG.error(SupportReferenceManifest.select(referenceManifestManager)
.includeArchived()
.byHashCode(Hex.encodeHexString(messageDigest.digest(
swidFile.toByteArray())))
.getRIM());
}
} else {
LOG.warn("Device did not send swid tag file...");
}
if (dv.getLogfileCount() > 0) {
for (ByteString logFile : dv.getLogfileList()) {
try {
support = SupportReferenceManifest.select(referenceManifestManager)
.includeArchived()
.byHashCode(Hex.encodeHexString(messageDigest.digest(
logFile.toByteArray())))
.getRIM();
if (true) {
Set<SupportReferenceManifest> dbSupportRims = SupportReferenceManifest
.select(referenceManifestManager).getRIMs();
if (support == null) {
/**
* This has to change, each log file can't have the same name
*/
support = new SupportReferenceManifest(
String.format("%s.rimel",
clientName),
logFile.toByteArray());
support.setPlatformManufacturer(dv.getHw().getManufacturer());
support.setPlatformModel(dv.getHw().getProductName());
support.setTagId(tagId);
this.referenceManifestManager.save(support);
} else {
LOG.info("Client provided Support RIM already loaded in database.");
if (dbBaseRim != null) {
support.setPlatformManufacturer(dbBaseRim.getPlatformManufacturer());
support.setPlatformModel(dbBaseRim.getPlatformModel());
support.setSwidTagVersion(dbBaseRim.getSwidTagVersion());
support.setAssociatedRim(dbBaseRim.getId());
support.setTagId(dbBaseRim.getTagId());
for (SupportReferenceManifest dbSupport : dbSupportRims) {
// all of this has to be moved somewhere else
/**
* Because the log file we get isn't promised to be the baseline support rim.
* If it is a patch of supplemental we have to check that the baseline
* has been done
* and those entries can't become the baseline
*
* However, we don't know which log file is what until we link them to a swidtag
*/
ReferenceDigestRecord dbObj = new ReferenceDigestRecord(dbSupport,
hw.getManufacturer(), hw.getProductName());
// this is where we update or create the log
ReferenceDigestRecord rdr = this.referenceDigestManager.getRecord(dbObj);
// Handle baseline digest records
// is there already a baseline?
if (rdr == null) {
// doesn't exist, store
rdr = referenceDigestManager.saveRecord(dbObj);
} // right now this will not deal with updating
if (this.referenceEventManager.getValuesByRecordId(rdr).isEmpty()) {
try {
TCGEventLog logProcessor = new TCGEventLog(dbSupport.getRimBytes());
ReferenceDigestValue rdv;
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
rdv = new ReferenceDigestValue(rdr.getId(), tpe.getEventNumber(),
tpe.getEventDigestStr(), tpe.getEventTypeStr(), false);
this.referenceEventManager.saveValue(rdv);
}
support.restore();
support.resetCreateTime();
this.referenceManifestManager.update(support);
} catch (CertificateException cEx) {
LOG.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOG.error(noSaEx);
} catch (IOException e) {
e.printStackTrace();
}
// all of this has to be moved somewhere else
/**
* Because the log file we get isn't promised to be the baseline support rim.
* If it is a patch of supplemental we have to check that the baseline
* has been done
* and those entires can't become the baseline
*
* However, we don't know which log file is what until we link them to a swidtag
*/
ReferenceDigestRecord dbObj = new ReferenceDigestRecord(support,
hw.getManufacturer(), hw.getProductName());
// this is where we update or create the log
ReferenceDigestRecord rdr = this.referenceDigestManager.getRecord(dbObj);
// Handle baseline digest records
// is there already a baseline?
if (rdr == null) {
// doesn't exist, store
rdr = referenceDigestManager.saveRecord(dbObj);
} // right now this will not deal with updating
if (this.referenceEventManager.getValuesByRecordId(rdr).isEmpty()) {
try {
TCGEventLog logProcessor = new TCGEventLog(support.getRimBytes());
ReferenceDigestValue rdv;
for (TpmPcrEvent tpe : logProcessor.getEventList()) {
rdv = new ReferenceDigestValue(rdr.getId(), tpe.getEventNumber(),
tpe.getEventDigestStr(), tpe.getEventTypeStr(), false);
this.referenceEventManager.saveValue(rdv);
}
} catch (CertificateException cEx) {
LOG.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
LOG.error(noSaEx);
}
}
} catch (IOException ioEx) {
LOG.error(ioEx);
}
}
} else {
LOG.warn("Device did not send support RIM file...");
}
if (dv.hasLivelog()) {
@ -915,19 +961,19 @@ public abstract class AbstractAttestationCertificateAuthority
clientName);
try {
// find previous version. If it exists, delete it
support = EventLogMeasurements.select(referenceManifestManager)
measurements = EventLogMeasurements.select(referenceManifestManager)
.byManufacturer(dv.getHw().getManufacturer())
.includeArchived().getRIM();
if (support != null) {
if (measurements != null) {
LOG.info("Previous bios measurement log found and being replaced...");
this.referenceManifestManager.delete(support);
this.referenceManifestManager.delete(measurements);
}
support = new EventLogMeasurements(fileName,
measurements = new EventLogMeasurements(fileName,
dv.getLivelog().toByteArray());
support.setPlatformManufacturer(dv.getHw().getManufacturer());
support.setPlatformModel(dv.getHw().getProductName());
support.setTagId(tagId);
this.referenceManifestManager.save(support);
measurements.setPlatformManufacturer(dv.getHw().getManufacturer());
measurements.setPlatformModel(dv.getHw().getProductName());
measurements.setTagId(tagId);
this.referenceManifestManager.save(measurements);
} catch (IOException ioEx) {
LOG.error(ioEx);
}

View File

@ -28,7 +28,6 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
@ -225,12 +224,12 @@ public class ReferenceManifestDetailsPageController
.getRIM();
if (support != null) {
baseRim.setAssociatedRim(support.getId());
logProcessor = new TCGEventLog(support.getRimBytes());
// logProcessor = new TCGEventLog(support.getRimBytes());
}
} else {
support = SupportReferenceManifest.select(referenceManifestManager)
.byEntityId(baseRim.getAssociatedRim()).getRIM();
logProcessor = new TCGEventLog(support.getRimBytes());
// 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
@ -244,11 +243,7 @@ public class ReferenceManifestDetailsPageController
} else {
data.put("supportRimHashValid", false);
}
swidRes.setPcrValues(Arrays.asList(
logProcessor.getExpectedPCRValues()));
break;
} else {
swidRes.setPcrValues(new ArrayList<>());
}
}

View File

@ -367,7 +367,8 @@ public abstract class ReferenceManifest extends ArchivableEntity {
@Override
public String toString() {
return String.format("Filename->%s%nPlatform Manufacturer->%s%n"
+ "Platform Model->%s%nRIM Type->%s", this.getFileName(),
this.platformManufacturer, this.platformModel, this.getRimType());
+ "Platform Model->%s%nRIM Type->%s%nRIM Hash->%s", this.getFileName(),
this.platformManufacturer, this.platformModel, this.getRimType(),
this.getRimHash());
}
}

View File

@ -3,27 +3,14 @@ package hirs.data.persist;
import com.google.common.base.Preconditions;
import hirs.data.persist.baseline.TpmWhiteListBaseline;
import hirs.data.persist.enums.DigestAlgorithm;
import hirs.tpm.eventlog.TCGEventLog;
import hirs.utils.xjc.File;
import java.io.IOException;
import java.util.Map;
import java.util.List;
import java.util.LinkedHashMap;
import java.util.Collections;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.text.DecimalFormat;
import java.util.Arrays;
import javax.xml.namespace.QName;
import org.apache.commons.codec.DecoderException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.xml.namespace.QName;
import java.math.BigInteger;
import java.util.Map;
/**
* This object is used to represent the content of a Swid Tags Directory
* section.
@ -32,20 +19,8 @@ public class SwidResource {
private static final Logger LOGGER = LogManager.getLogger(SwidResource.class);
private static final String CATALINA_HOME = System.getProperty("catalina.base");
private static final String TOMCAT_UPLOAD_DIRECTORY
= "/webapps/HIRS_AttestationCAPortal/upload/";
/**
* String holder for location for storing binaries.
*/
public static final String RESOURCE_UPLOAD_FOLDER
= CATALINA_HOME + TOMCAT_UPLOAD_DIRECTORY;
private String name, size;
private String rimFormat, rimType, rimUriGlobal, hashValue;
private List<String> pcrValues;
private TpmWhiteListBaseline tpmWhiteList;
private DigestAlgorithm digest = DigestAlgorithm.SHA1;
private boolean validFileSize = false;
@ -60,7 +35,6 @@ public class SwidResource {
rimType = null;
rimUriGlobal = null;
hashValue = null;
pcrValues = null;
}
/**
@ -102,23 +76,7 @@ public class SwidResource {
}
this.digest = digest;
parsePcrValues();
tpmWhiteList = new TpmWhiteListBaseline(this.name);
if (!pcrValues.isEmpty()) {
int i = 0;
for (String pcr : pcrValues) {
if (this.digest == null) {
// determine by length of pcr value
this.digest = AbstractDigest.getDigestAlgorithm(pcr);
}
try {
tpmWhiteList.addToBaseline(
new TPMMeasurementRecord(i++, pcr));
} catch (DecoderException deEx) {
LOGGER.error(deEx);
}
}
}
}
/**
@ -175,24 +133,6 @@ public class SwidResource {
return hashValue;
}
/**
* Getter for the list of PCR Values.
*
* @return an unmodifiable list
*/
public List<String> getPcrValues() {
return Collections.unmodifiableList(pcrValues);
}
/**
* Setter for the list of associated PCR Values.
*
* @param pcrValues a collection of PCRs
*/
public void setPcrValues(final List<String> pcrValues) {
this.pcrValues = pcrValues;
}
/**
* flag for if the file sizes match with the swidtag.
* @return true if they match
@ -200,51 +140,4 @@ public class SwidResource {
public boolean isValidFileSize() {
return validFileSize;
}
/**
* Getter for a generated map of the PCR values.
*
* @return mapping of PCR# to the actual value.
*/
public LinkedHashMap<String, String> getPcrMap() {
LinkedHashMap<String, String> innerMap = new LinkedHashMap<>();
DecimalFormat df = new DecimalFormat("00");
if (!this.pcrValues.isEmpty()) {
long iterate = 0;
String pcrNum;
for (String string : this.pcrValues) {
pcrNum = df.format(iterate++);
innerMap.put(String.format("PCR%s:", pcrNum), string);
}
}
return innerMap;
}
private void parsePcrValues() {
TCGEventLog logProcessor = new TCGEventLog();
try {
Path logPath = Paths.get(String.format("%s/%s",
SwidResource.RESOURCE_UPLOAD_FOLDER,
this.getName()));
if (Files.exists(logPath)) {
logProcessor = new TCGEventLog(
Files.readAllBytes(logPath));
}
this.setPcrValues(Arrays.asList(
logProcessor.getExpectedPCRValues()));
} catch (NoSuchFileException nsfEx) {
LOGGER.error(String.format("File Not found!: %s",
this.getName()));
LOGGER.error(nsfEx);
} catch (IOException ioEx) {
LOGGER.error(ioEx);
} catch (CertificateException cEx) {
LOGGER.error(cEx);
} catch (NoSuchAlgorithmException naEx) {
LOGGER.error(naEx);
}
}
}