mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-02-20 17:52:47 +00:00
Merge branch 'master' into aic-policy-rule
This commit is contained in:
commit
e64c6cf772
@ -421,8 +421,12 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
// parse the EK Public key from the IdentityClaim once for use in supply chain validation
|
||||
// and later tpm20MakeCredential function
|
||||
RSAPublicKey ekPub = parsePublicKey(claim.getEkPublicArea().toByteArray());
|
||||
|
||||
AppraisalStatus.Status validationResult = doSupplyChainValidation(claim, ekPub);
|
||||
AppraisalStatus.Status validationResult = AppraisalStatus.Status.FAIL;
|
||||
try {
|
||||
validationResult = doSupplyChainValidation(claim, ekPub);
|
||||
} catch (Exception ex) {
|
||||
LOG.error(ex);
|
||||
}
|
||||
if (validationResult == AppraisalStatus.Status.PASS) {
|
||||
|
||||
RSAPublicKey akPub = parsePublicKey(claim.getAkPublicArea().toByteArray());
|
||||
@ -752,76 +756,99 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
String clientName = String.format("%s_%s",
|
||||
dv.getHw().getManufacturer(),
|
||||
dv.getHw().getProductName());
|
||||
ReferenceManifest dbBaseRim;
|
||||
ReferenceManifest dbBaseRim = null;
|
||||
ReferenceManifest support;
|
||||
String tagId = "";
|
||||
String fileName = "";
|
||||
Pattern pattern = Pattern.compile("([^\\s]+(\\.(?i)(rimpcr|rimel|bin|log))$)");
|
||||
Matcher matcher;
|
||||
|
||||
if (dv.hasSwidfile()) {
|
||||
try {
|
||||
dbBaseRim = BaseReferenceManifest.select(referenceManifestManager)
|
||||
.includeArchived()
|
||||
.byHashCode(Arrays.hashCode(dv.getSwidfile().toByteArray()))
|
||||
.getRIM();
|
||||
if (dv.getSwidfileCount() > 0) {
|
||||
for (ByteString swidFile : dv.getSwidfileList()) {
|
||||
try {
|
||||
dbBaseRim = BaseReferenceManifest.select(referenceManifestManager)
|
||||
.includeArchived()
|
||||
.byHashCode(Arrays.hashCode(swidFile.toByteArray()))
|
||||
.getRIM();
|
||||
|
||||
if (dbBaseRim == null) {
|
||||
dbBaseRim = new BaseReferenceManifest(
|
||||
String.format("%s.swidtag",
|
||||
clientName),
|
||||
dv.getSwidfile().toByteArray());
|
||||
if (dbBaseRim == null) {
|
||||
dbBaseRim = new BaseReferenceManifest(
|
||||
String.format("%s.swidtag",
|
||||
clientName),
|
||||
swidFile.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;
|
||||
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),
|
||||
swidFile.toByteArray());
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.referenceManifestManager.save(dbBaseRim);
|
||||
} else {
|
||||
LOG.info("Client provided Base RIM already loaded in database.");
|
||||
dbBaseRim.restore();
|
||||
dbBaseRim.resetCreateTime();
|
||||
this.referenceManifestManager.update(dbBaseRim);
|
||||
}
|
||||
this.referenceManifestManager.save(dbBaseRim);
|
||||
} else {
|
||||
LOG.info("Client provided Base RIM already loaded in database.");
|
||||
}
|
||||
|
||||
tagId = dbBaseRim.getTagId();
|
||||
} catch (IOException ioEx) {
|
||||
LOG.error(ioEx);
|
||||
tagId = dbBaseRim.getTagId();
|
||||
} catch (IOException ioEx) {
|
||||
LOG.error(ioEx);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG.warn("Device did not send swid tag file...");
|
||||
}
|
||||
|
||||
if (dv.hasLogfile()) {
|
||||
try {
|
||||
support = SupportReferenceManifest.select(referenceManifestManager)
|
||||
.includeArchived()
|
||||
.byHashCode(Arrays.hashCode(dv.getLogfile().toByteArray()))
|
||||
.getRIM();
|
||||
if (dv.getLogfileCount() > 0) {
|
||||
for (ByteString logFile : dv.getLogfileList()) {
|
||||
try {
|
||||
support = SupportReferenceManifest.select(referenceManifestManager)
|
||||
.includeArchived()
|
||||
.byHashCode(Arrays.hashCode(logFile.toByteArray()))
|
||||
.getRIM();
|
||||
|
||||
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 Support RIM already loaded in database.");
|
||||
if (support == null) {
|
||||
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());
|
||||
}
|
||||
|
||||
support.restore();
|
||||
support.resetCreateTime();
|
||||
this.referenceManifestManager.update(support);
|
||||
}
|
||||
} catch (IOException ioEx) {
|
||||
LOG.error(ioEx);
|
||||
}
|
||||
} catch (IOException ioEx) {
|
||||
LOG.error(ioEx);
|
||||
}
|
||||
} else {
|
||||
LOG.warn("Device did not send support RIM file...");
|
||||
}
|
||||
|
||||
if (dv.hasLivelog()) {
|
||||
LOG.info("Device sent bios measurement log...");
|
||||
fileName = String.format("%s.measurement",
|
||||
clientName);
|
||||
try {
|
||||
@ -830,6 +857,7 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
.byManufacturer(dv.getHw().getManufacturer())
|
||||
.includeArchived().getRIM();
|
||||
if (support != null) {
|
||||
LOG.info("Previous bios measurement log found and being replaced...");
|
||||
this.referenceManifestManager.delete(support);
|
||||
}
|
||||
support = new EventLogMeasurements(fileName,
|
||||
@ -841,6 +869,8 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
} catch (IOException ioEx) {
|
||||
LOG.error(ioEx);
|
||||
}
|
||||
} else {
|
||||
LOG.warn("Device did not send bios measurement log...");
|
||||
}
|
||||
|
||||
// Get TPM info, currently unimplemented
|
||||
|
@ -84,6 +84,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
|
||||
private static final Logger LOGGER
|
||||
= LogManager.getLogger(SupplyChainValidationServiceImpl.class);
|
||||
private static final int VALUE_INDEX = 1;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -249,7 +250,8 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
String.format("%s%n%s", platformScv.getMessage(),
|
||||
attributeScv.getMessage())));
|
||||
}
|
||||
componentFailures = attributeScv.getMessage();
|
||||
componentFailures = updateUnmatchedComponents(
|
||||
attributeScv.getMessage());
|
||||
}
|
||||
|
||||
pc.setDevice(device);
|
||||
@ -281,6 +283,29 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
return summary;
|
||||
}
|
||||
|
||||
private String updateUnmatchedComponents(final String unmatchedString) {
|
||||
StringBuilder updatedFailures = new StringBuilder();
|
||||
String manufacturer = "";
|
||||
String model = "";
|
||||
for (String rows : unmatchedString.split(";")) {
|
||||
for (String str : rows.split(",")) {
|
||||
String[] manufacturerSplit;
|
||||
String[] modelSplit;
|
||||
if (str.contains("Manufacturer")) {
|
||||
manufacturerSplit = str.split("=");
|
||||
manufacturer = manufacturerSplit[VALUE_INDEX];
|
||||
}
|
||||
if (str.contains("Model")) {
|
||||
modelSplit = str.split("=");
|
||||
model = modelSplit[VALUE_INDEX];
|
||||
}
|
||||
}
|
||||
updatedFailures.append(String.format("%s%s;", manufacturer, model));
|
||||
}
|
||||
|
||||
return updatedFailures.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a sub set of the validate supply chain method and focuses
|
||||
* on the specific multibase validation check for a delta chain. This method
|
||||
@ -355,19 +380,17 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
.byManufacturer(manufacturer).getRIM();
|
||||
supportReferenceManifest = SupportReferenceManifest.select(referenceManifestManager)
|
||||
.byManufacturer(manufacturer).getRIM();
|
||||
List<SwidResource> resources =
|
||||
((BaseReferenceManifest) baseReferenceManifest).parseResource();
|
||||
measurement = EventLogMeasurements.select(referenceManifestManager)
|
||||
.byManufacturer(manufacturer).includeArchived().getRIM();
|
||||
|
||||
validationObject = baseReferenceManifest;
|
||||
String failedString = "";
|
||||
if (baseReferenceManifest == null) {
|
||||
failedString = "Base Reference Integrity Manifest%n";
|
||||
failedString = "Base Reference Integrity Manifest\n";
|
||||
passed = false;
|
||||
}
|
||||
if (supportReferenceManifest == null) {
|
||||
failedString += "Support Reference Integrity Manifest%n";
|
||||
failedString += "Support Reference Integrity Manifest\n";
|
||||
passed = false;
|
||||
}
|
||||
if (measurement == null) {
|
||||
@ -376,6 +399,8 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
}
|
||||
|
||||
if (passed) {
|
||||
List<SwidResource> resources =
|
||||
((BaseReferenceManifest) baseReferenceManifest).parseResource();
|
||||
fwStatus = new AppraisalStatus(PASS,
|
||||
SupplyChainCredentialValidator.FIRMWARE_VALID);
|
||||
|
||||
|
@ -5,7 +5,6 @@ import hirs.data.persist.EventLogMeasurements;
|
||||
import hirs.data.persist.ReferenceManifest;
|
||||
import hirs.data.persist.SupportReferenceManifest;
|
||||
import hirs.data.persist.SwidResource;
|
||||
import hirs.data.persist.certificate.Certificate;
|
||||
import hirs.data.persist.certificate.CertificateAuthorityCredential;
|
||||
import hirs.persist.CertificateManager;
|
||||
import hirs.persist.DBManagerException;
|
||||
@ -26,6 +25,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import hirs.tpm.eventlog.TpmPcrEvent;
|
||||
@ -102,6 +102,7 @@ public class ReferenceManifestDetailsPageController
|
||||
LOGGER.error(uuidError, iaEx);
|
||||
} catch (Exception ioEx) {
|
||||
LOGGER.error(ioEx);
|
||||
LOGGER.trace(ioEx);
|
||||
}
|
||||
if (data.isEmpty()) {
|
||||
String notFoundMessage = "Unable to find RIM with ID: " + params.getId();
|
||||
@ -236,6 +237,10 @@ public class ReferenceManifestDetailsPageController
|
||||
baseRim.setAssociatedRim(support.getId());
|
||||
logProcessor = new TCGEventLog(support.getRimBytes());
|
||||
}
|
||||
} else {
|
||||
support = SupportReferenceManifest.select(referenceManifestManager)
|
||||
.byEntityId(baseRim.getAssociatedRim()).getRIM();
|
||||
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
|
||||
@ -262,17 +267,20 @@ public class ReferenceManifestDetailsPageController
|
||||
|
||||
RIM_VALIDATOR.validateXmlSignature(new ByteArrayInputStream(baseRim.getRimBytes()));
|
||||
data.put("signatureValid", RIM_VALIDATOR.isSignatureValid());
|
||||
if (RIM_VALIDATOR.isSignatureValid()) {
|
||||
LOGGER.info("Public key: " + RIM_VALIDATOR.getPublicKey().toString());
|
||||
try {
|
||||
Certificate certificate =
|
||||
CertificateAuthorityCredential.select(certificateManager)
|
||||
.byEncodedPublicKey(RIM_VALIDATOR.getPublicKey().getEncoded())
|
||||
.getCertificate();
|
||||
data.put("issuerID", certificate.getId().toString());
|
||||
} catch (NullPointerException e) {
|
||||
LOGGER.info("Unable to get signing certificate link: " + e.getMessage());
|
||||
data.put("skID", RIM_VALIDATOR.getSubjectKeyIdentifier());
|
||||
try {
|
||||
Set<CertificateAuthorityCredential> certificates =
|
||||
CertificateAuthorityCredential.select(certificateManager)
|
||||
.getCertificates();
|
||||
for (CertificateAuthorityCredential cert : certificates) {
|
||||
if (Arrays.equals(cert.getEncodedPublicKey(),
|
||||
RIM_VALIDATOR.getPublicKey().getEncoded())) {
|
||||
LOGGER.info("Found matching cert!");
|
||||
data.put("issuerID", cert.getId().toString());
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
LOGGER.error("Unable to link signing certificate: " + e.getMessage());
|
||||
}
|
||||
return data;
|
||||
}
|
||||
@ -293,8 +301,11 @@ public class ReferenceManifestDetailsPageController
|
||||
final ReferenceManifestManager referenceManifestManager)
|
||||
throws IOException, CertificateException, NoSuchAlgorithmException {
|
||||
HashMap<String, Object> data = new HashMap<>();
|
||||
EventLogMeasurements measurements = null;
|
||||
|
||||
if (support.getAssociatedRim() == null) {
|
||||
if (support.getAssociatedRim() == null
|
||||
&& (support.getPlatformManufacturer() != null
|
||||
&& !support.getPlatformManufacturer().isEmpty())) {
|
||||
ReferenceManifest baseRim = BaseReferenceManifest.select(referenceManifestManager)
|
||||
.byManufacturer(support.getPlatformManufacturer()).getRIM();
|
||||
if (baseRim != null) {
|
||||
@ -305,16 +316,16 @@ public class ReferenceManifestDetailsPageController
|
||||
LOGGER.error("Failed to update Support RIM", ex);
|
||||
}
|
||||
}
|
||||
measurements = EventLogMeasurements.select(referenceManifestManager)
|
||||
.byManufacturer(support.getPlatformManufacturer()).getRIM();
|
||||
}
|
||||
|
||||
data.put("baseRim", support.getTagId());
|
||||
data.put("associatedRim", support.getAssociatedRim());
|
||||
data.put("rimType", support.getRimType());
|
||||
data.put("tagId", support.getTagId());
|
||||
|
||||
TCGEventLog logProcessor = new TCGEventLog(support.getRimBytes());
|
||||
EventLogMeasurements measurements = EventLogMeasurements.select(referenceManifestManager)
|
||||
.byManufacturer(support.getPlatformManufacturer()).getRIM();
|
||||
|
||||
LinkedList<TpmPcrEvent> tpmPcrEvents = new LinkedList<>();
|
||||
TCGEventLog measurementsProcess;
|
||||
if (measurements != null) {
|
||||
@ -327,10 +338,11 @@ public class ReferenceManifestDetailsPageController
|
||||
}
|
||||
tpmPcrEvents.add(tpe);
|
||||
}
|
||||
data.put("events", tpmPcrEvents);
|
||||
} else {
|
||||
data.put("events", logProcessor.getEventList());
|
||||
}
|
||||
|
||||
data.put("events", tpmPcrEvents);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ public class ReferenceManifestPageController
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
PageMessages messages = new PageMessages();
|
||||
String fileName;
|
||||
Pattern pattern;
|
||||
Pattern logPattern = Pattern.compile(LOG_FILE_PATTERN);
|
||||
Matcher matcher;
|
||||
boolean supportRIM = false;
|
||||
BaseReferenceManifest base;
|
||||
@ -197,64 +197,63 @@ public class ReferenceManifestPageController
|
||||
// loop through the files
|
||||
for (MultipartFile file : files) {
|
||||
fileName = file.getOriginalFilename();
|
||||
pattern = Pattern.compile(LOG_FILE_PATTERN);
|
||||
matcher = pattern.matcher(fileName);
|
||||
matcher = logPattern.matcher(fileName);
|
||||
supportRIM = matcher.matches();
|
||||
|
||||
//Parse reference manifests
|
||||
ReferenceManifest rim = parseRIM(file, supportRIM, messages);
|
||||
|
||||
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;
|
||||
//Store only if it was parsed
|
||||
if (rim != null) {
|
||||
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 {
|
||||
base = (BaseReferenceManifest) rim;
|
||||
} 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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Store only if it was parsed
|
||||
if (rim != null) {
|
||||
storeManifest(file.getOriginalFilename(),
|
||||
messages,
|
||||
rim,
|
||||
|
@ -31,7 +31,6 @@ public final class CertificateStringMapBuilder {
|
||||
|
||||
private static final Logger LOGGER =
|
||||
LogManager.getLogger(CertificateStringMapBuilder.class);
|
||||
private static final int SERIAL_INDEX = 1;
|
||||
|
||||
private CertificateStringMapBuilder() {
|
||||
|
||||
@ -341,19 +340,7 @@ public final class CertificateStringMapBuilder {
|
||||
//CPSuri
|
||||
data.put("CPSuri", certificate.getCPSuri());
|
||||
//component failure
|
||||
StringBuilder savedFailures = new StringBuilder();
|
||||
String[] serialSplit;
|
||||
for (String s : certificate.getComponentFailures().split(",")) {
|
||||
if (s.contains("Serial")) {
|
||||
serialSplit = s.split("=");
|
||||
if (serialSplit.length > SERIAL_INDEX) {
|
||||
savedFailures.append(serialSplit[SERIAL_INDEX]);
|
||||
} else {
|
||||
savedFailures.append(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
data.put("failures", savedFailures.toString());
|
||||
data.put("failures", certificate.getComponentFailures());
|
||||
|
||||
//Get platform Configuration values and set map with it
|
||||
PlatformConfiguration platformConfiguration = certificate.getPlatformConfiguration();
|
||||
|
@ -614,10 +614,11 @@
|
||||
<div class="panel-body">
|
||||
<div id="componentIdentifier" class="row">
|
||||
<c:forEach items="${initialData.componentsIdentifier}" var="component">
|
||||
<c:set var="combined" value="${component.getComponentManufacturer()}${component.getComponentModel()}" scope="page"/>
|
||||
<div class="component col col-md-4">
|
||||
<div class="panel panel-default">
|
||||
<c:choose>
|
||||
<c:when test="${fn:contains(initialData.failures, component.getComponentSerial()) && not empty fn:trim(component.getComponentSerial())}">
|
||||
<c:when test="${fn:contains(initialData.failures, combined)}">
|
||||
<div class="panel-heading" style="background-color: red; color: white">
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
|
@ -335,15 +335,27 @@
|
||||
<c:choose>
|
||||
<c:when test="${initialData.signatureValid}">
|
||||
<img src="${passIcon}" title="${signatureValidText}"/>
|
||||
<c:if test="${not empty initialData.issuerID}">
|
||||
<div><a href="${portal}/certificate-details?id=${initialData.issuerID}&type=certificateauthority">Signing certificate</a></div>
|
||||
</c:if>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<img src="${failIcon}" title="${signatureInvalidText}"/>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</span></div>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>
|
||||
<c:if test="${not empty initialData.issuerID}">
|
||||
<div><a href="${portal}/certificate-details?id=${initialData.issuerID}&type=certificateauthority">Signing certificate</a></div>
|
||||
</c:if>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>
|
||||
<c:if test="${not empty initialData.skID}">
|
||||
<div>Subject Key Identifier: ${initialData.skID}</div>
|
||||
</c:if>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</c:otherwise>
|
||||
|
@ -5,6 +5,7 @@
|
||||
#define HIRS_PROVISIONERTPM2_INCLUDE_UTILS_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace hirs {
|
||||
|
||||
@ -32,6 +33,8 @@ namespace file_utils {
|
||||
|
||||
std::string getFileAsOneLineOrEmptyString(const std::string& filename);
|
||||
|
||||
std::vector<std::string> search_directory(const std::string& directory);
|
||||
|
||||
void writeBinaryFile(const std::string& bytes,
|
||||
const std::string& filename);
|
||||
|
||||
|
@ -41,22 +41,30 @@ fi
|
||||
ln -s -f /etc/hirs/provisioner/hirs-provisioner.sh /usr/sbin/hirs-provisioner
|
||||
|
||||
TCG_BOOT_FILE="/etc/hirs/tcg_boot.properties"
|
||||
MAINFEST_DIRECTORY="/boot/tcg/manifest"
|
||||
LOG_FILE_LOCATION="$MAINFEST_DIRECTORY/rim/"
|
||||
TAG_FILE_LOCATION="$MAINFEST_DIRECTORY/swidtag/"
|
||||
TCG_DIRECTORY="/boot/tcg"
|
||||
RIM_FILE_LOCATION="$TCG_DIRECTORY/manifest/rim/"
|
||||
SWIDTAG_FILE_LOCATION="$TCG_DIRECTORY/manifest/swidtag/"
|
||||
CREDENTIALS_LOCATION="$TCG_DIRECTORY/cert/platform/"
|
||||
BINARY_BIOS_MEASUREMENTS="/sys/kernel/security/tpm0/binary_bios_measurements"
|
||||
|
||||
if [ ! -f "$TCG_BOOT_FILE" ]; then
|
||||
touch "$TCG_BOOT_FILE"
|
||||
fi
|
||||
|
||||
if [ -d "$LOG_FILE_LOCATION" ]; then
|
||||
RIM_FILE=$(find "$LOG_FILE_LOCATION" -name '*.rimel' -or -name '*.bin' -or -name '*.rimpcr' -or -name '*.log')
|
||||
echo "tcg.rim.file=$RIM_FILE" > "$TCG_BOOT_FILE"
|
||||
if [ -d "$RIM_FILE_LOCATION" ]; then
|
||||
echo "tcg.rim.dir=$RIM_FILE_LOCATION" > "$TCG_BOOT_FILE"
|
||||
fi
|
||||
|
||||
if [ -d "$TAG_FILE_LOCATION" ]; then
|
||||
SWID_FILE=$(find "$TAG_FILE_LOCATION" -name '*.swidtag')
|
||||
echo "tcg.swidtag.file=$SWID_FILE" >> "$TCG_BOOT_FILE"
|
||||
if [ -d "$SWIDTAG_FILE_LOCATION" ]; then
|
||||
echo "tcg.swidtag.dir=$SWIDTAG_FILE_LOCATION" >> "$TCG_BOOT_FILE"
|
||||
fi
|
||||
|
||||
if [ -d "$CREDENTIALS_LOCATION" ]; then
|
||||
echo "tcg.cert.dir=$CREDENTIALS_LOCATION" >> "$TCG_BOOT_FILE"
|
||||
fi
|
||||
|
||||
if [ -f "$BINARY_BIOS_MEASUREMENTS" ]; then
|
||||
echo "tcg.event.file=$BINARY_BIOS_MEASUREMENTS" >> "$TCG_BOOT_FILE"
|
||||
fi
|
||||
|
||||
chmod -w "$TCG_BOOT_FILE"
|
||||
|
@ -58,8 +58,8 @@ message DeviceInfo {
|
||||
required NetworkInfo nw = 3;
|
||||
required OsInfo os = 4;
|
||||
optional bytes pcrslist = 5;
|
||||
optional bytes logfile = 6;
|
||||
optional bytes swidfile = 7;
|
||||
repeated bytes logfile = 6;
|
||||
repeated bytes swidfile = 7;
|
||||
optional bytes livelog = 8;
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ int provision() {
|
||||
Logger logger = Logger::getDefaultLogger();
|
||||
|
||||
CommandTpm2 tpm2;
|
||||
Properties props("/etc/hirs/tcg_boot.properties");
|
||||
tpm2.setAuthData();
|
||||
|
||||
// get endorsement credential and endorsement key
|
||||
@ -62,21 +63,54 @@ int provision() {
|
||||
cout << "----> Collecting platform credential from TPM" << endl;
|
||||
string platformCredential = tpm2.getPlatformCredentialDefault();
|
||||
std::vector<string> platformCredentials;
|
||||
platformCredentials.push_back(platformCredential);
|
||||
|
||||
// if platformCredential is empty, not in TPM
|
||||
// pull from properties file
|
||||
if (platformCredential.empty()) {
|
||||
const std::string& cert_dir = props.get("tcg.cert.dir", "");
|
||||
try {
|
||||
platformCredentials =
|
||||
hirs::file_utils::search_directory(cert_dir);
|
||||
} catch (HirsRuntimeException& hirsRuntimeException) {
|
||||
logger.error(hirsRuntimeException.what());
|
||||
}
|
||||
} else {
|
||||
platformCredentials.push_back(platformCredential);
|
||||
}
|
||||
|
||||
// collect device info
|
||||
cout << "----> Collecting device information" << endl;
|
||||
hirs::pb::DeviceInfo dv = DeviceInfoCollector::collectDeviceInfo();
|
||||
dv.set_pcrslist(tpm2.getPcrList());
|
||||
// collect TCG Boot files
|
||||
Properties props("/etc/hirs/tcg_boot.properties");
|
||||
const std::string& rim_file = props.get("tcg.rim.file", "");
|
||||
const std::string& swid_file = props.get("tcg.swidtag.file", "");
|
||||
std::vector<string> rim_files;
|
||||
std::vector<string> swidtag_files;
|
||||
const std::string& rim_dir = props.get("tcg.rim.dir", "");
|
||||
const std::string& swid_dir = props.get("tcg.swidtag.dir", "");
|
||||
const std::string& live_log_file = props.get("tcg.event.file", "");
|
||||
|
||||
try {
|
||||
dv.set_logfile(hirs::file_utils::fileToString(rim_file));
|
||||
dv.set_swidfile(hirs::file_utils::fileToString(swid_file));
|
||||
dv.set_livelog(hirs::file_utils::fileToString(
|
||||
"/sys/kernel/security/tpm0/binary_bios_measurements"));
|
||||
rim_files = hirs::file_utils::search_directory(rim_dir);
|
||||
for (const auto& rims : rim_files) {
|
||||
if (rims != "") {
|
||||
dv.add_logfile(rims);
|
||||
}
|
||||
}
|
||||
} catch (HirsRuntimeException& hirsRuntimeException) {
|
||||
logger.error(hirsRuntimeException.what());
|
||||
}
|
||||
try {
|
||||
swidtag_files = hirs::file_utils::search_directory(swid_dir);
|
||||
for (const auto& swidtag : swidtag_files) {
|
||||
if (swidtag != "") {
|
||||
dv.add_swidfile(swidtag);
|
||||
}
|
||||
}
|
||||
} catch (HirsRuntimeException& hirsRuntimeException) {
|
||||
logger.error(hirsRuntimeException.what());
|
||||
}
|
||||
try {
|
||||
dv.set_livelog(hirs::file_utils::fileToString(live_log_file));
|
||||
} catch (HirsRuntimeException& hirsRuntimeException) {
|
||||
logger.error(hirsRuntimeException.what());
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <re2/re2.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
@ -118,6 +119,30 @@ namespace file_utils {
|
||||
return string_utils::trimNewLines(fileToString(filename, ""));
|
||||
}
|
||||
|
||||
vector<string> search_directory(const string& directory) {
|
||||
DIR *dr;
|
||||
std::vector<string> files;
|
||||
dr = opendir(directory.c_str());
|
||||
|
||||
if (dr) {
|
||||
struct dirent *en;
|
||||
while ((en = readdir(dr)) != NULL) {
|
||||
stringstream ss;
|
||||
ss << directory.c_str();
|
||||
ss << en->d_name;
|
||||
try {
|
||||
files.push_back(fileToString(ss.str()));
|
||||
} catch (HirsRuntimeException& hirsRuntimeException) {
|
||||
std::cout << hirsRuntimeException.what();
|
||||
}
|
||||
}
|
||||
// close directory
|
||||
closedir(dr);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a byte string and writes the contents to a file of the given name.
|
||||
* @param bytes string bytes to write
|
||||
|
@ -23,6 +23,7 @@ import javax.xml.crypto.dsig.XMLSignatureException;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
import javax.xml.crypto.dsig.dom.DOMValidateContext;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyValue;
|
||||
import javax.xml.crypto.dsig.keyinfo.X509Data;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
@ -36,6 +37,7 @@ import javax.xml.validation.SchemaFactory;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.Key;
|
||||
import java.security.KeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
@ -64,6 +66,7 @@ public class ReferenceManifestValidator {
|
||||
private Unmarshaller unmarshaller;
|
||||
private PublicKey publicKey;
|
||||
private Schema schema;
|
||||
private String subjectKeyIdentifier;
|
||||
private boolean signatureValid, supportRimValid;
|
||||
|
||||
/**
|
||||
@ -93,6 +96,14 @@ public class ReferenceManifestValidator {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for subjectKeyIdentifier.
|
||||
* @return subjectKeyIdentifier
|
||||
*/
|
||||
public String getSubjectKeyIdentifier() {
|
||||
return subjectKeyIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* This default constructor creates the Schema object from SCHEMA_URL immediately to save
|
||||
* time during validation calls later.
|
||||
@ -106,6 +117,7 @@ public class ReferenceManifestValidator {
|
||||
signatureValid = false;
|
||||
supportRimValid = false;
|
||||
publicKey = null;
|
||||
subjectKeyIdentifier = "";
|
||||
} catch (SAXException e) {
|
||||
LOGGER.warn("Error setting schema for validation!");
|
||||
}
|
||||
@ -192,22 +204,21 @@ public class ReferenceManifestValidator {
|
||||
if (nodes.getLength() == 0) {
|
||||
throw new Exception("Signature element not found!");
|
||||
}
|
||||
NodeList embeddedCert = doc.getElementsByTagName("X509Data");
|
||||
if (embeddedCert.getLength() > 0) {
|
||||
X509KeySelector keySelector = new ReferenceManifestValidator.X509KeySelector();
|
||||
context = new DOMValidateContext(keySelector, nodes.item(0));
|
||||
XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
|
||||
XMLSignature signature = sigFactory.unmarshalXMLSignature(context);
|
||||
isValid = signature.validate(context);
|
||||
publicKey = keySelector.getPublicKey();
|
||||
} else {
|
||||
LOGGER.info("Signing certificate not found for validation!");
|
||||
}
|
||||
} catch (MarshalException | XMLSignatureException e) {
|
||||
LOGGER.warn(e.getMessage());
|
||||
X509KeySelector keySelector = new ReferenceManifestValidator.X509KeySelector();
|
||||
context = new DOMValidateContext(keySelector, nodes.item(0));
|
||||
XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
|
||||
XMLSignature signature = sigFactory.unmarshalXMLSignature(context);
|
||||
isValid = signature.validate(context);
|
||||
publicKey = keySelector.getPublicKey();
|
||||
subjectKeyIdentifier = getKeyName(doc);
|
||||
} catch (MarshalException e) {
|
||||
LOGGER.warn("Error while unmarshalling XML signature: " + e.getMessage());
|
||||
} catch (XMLSignatureException e) {
|
||||
LOGGER.warn("Error while validating XML signature: " + e.getMessage());
|
||||
} catch (KeySelectorException e) {
|
||||
LOGGER.warn("Public key not found in XML signature: " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn(e.getMessage());
|
||||
LOGGER.info(e.getMessage());
|
||||
}
|
||||
|
||||
return isValid;
|
||||
@ -222,7 +233,12 @@ public class ReferenceManifestValidator {
|
||||
private PublicKey publicKey;
|
||||
|
||||
/**
|
||||
* This method selects an X509 cert based on the provided algorithm.
|
||||
* This method selects a public key for validation.
|
||||
* PKs are parsed preferentially from the following elements:
|
||||
* - X509Data
|
||||
* - KeyValue
|
||||
* The parsed PK is then verified based on the provided algorithm before
|
||||
* being returned in a KeySelectorResult.
|
||||
*
|
||||
* @param keyinfo object containing the cert.
|
||||
* @param purpose purpose.
|
||||
@ -246,15 +262,23 @@ public class ReferenceManifestValidator {
|
||||
Object object = dataItr.next();
|
||||
if (object instanceof X509Certificate) {
|
||||
publicKey = ((X509Certificate) object).getPublicKey();
|
||||
if (areAlgorithmsEqual(algorithm.getAlgorithm(),
|
||||
publicKey.getAlgorithm())) {
|
||||
return new ReferenceManifestValidator.X509KeySelector
|
||||
.RIMKeySelectorResult(publicKey);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (element instanceof KeyValue) {
|
||||
try {
|
||||
publicKey = ((KeyValue) element).getPublicKey();
|
||||
} catch (KeyException e) {
|
||||
LOGGER.warn("KeyException thrown while getting PK from KeyValue: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (areAlgorithmsEqual(algorithm.getAlgorithm(),
|
||||
publicKey.getAlgorithm())) {
|
||||
return new ReferenceManifestValidator.X509KeySelector
|
||||
.RIMKeySelectorResult(publicKey);
|
||||
}
|
||||
|
||||
throw new KeySelectorException("No key found!");
|
||||
}
|
||||
@ -295,6 +319,21 @@ public class ReferenceManifestValidator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method parses the subject key identifier from the KeyName element of a signature.
|
||||
*
|
||||
* @param doc
|
||||
* @return SKID if found, or an empty string.
|
||||
*/
|
||||
private String getKeyName(final Document doc) {
|
||||
NodeList keyName = doc.getElementsByTagName("KeyName");
|
||||
if (keyName.getLength() > 0) {
|
||||
return keyName.item(0).getTextContent();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method validates the Document against the schema.
|
||||
*
|
||||
|
@ -168,12 +168,12 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
}
|
||||
try {
|
||||
if (trustStore == null || trustStore.size() == 0) {
|
||||
message = baseErrorMessage + "a trust store\n";
|
||||
message = baseErrorMessage + "an Issuer Cert in the Trust Store\n";
|
||||
LOGGER.error(message);
|
||||
return new AppraisalStatus(FAIL, message);
|
||||
}
|
||||
} catch (KeyStoreException e) {
|
||||
message = baseErrorMessage + "an intitialized trust store";
|
||||
message = baseErrorMessage + "an initialized trust store";
|
||||
LOGGER.error(message);
|
||||
return new AppraisalStatus(FAIL, message);
|
||||
}
|
||||
@ -852,11 +852,11 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
||||
LOGGER.error(String.format("Platform Credential contained %d unmatched components:",
|
||||
pcUnmatchedComponents.size()));
|
||||
|
||||
int umatchedComponentCounter = 1;
|
||||
int unmatchedComponentCounter = 1;
|
||||
for (ComponentIdentifier unmatchedComponent : pcUnmatchedComponents) {
|
||||
LOGGER.error("Unmatched component " + umatchedComponentCounter++ + ": "
|
||||
LOGGER.error("Unmatched component " + unmatchedComponentCounter++ + ": "
|
||||
+ unmatchedComponent);
|
||||
sb.append(String.format("Manufacturer=%s, Model=%s, Serial=%s, Revision=%s%n",
|
||||
sb.append(String.format("Manufacturer=%s, Model=%s, Serial=%s, Revision=%s;%n",
|
||||
unmatchedComponent.getComponentManufacturer(),
|
||||
unmatchedComponent.getComponentModel(),
|
||||
unmatchedComponent.getComponentSerial(),
|
||||
|
@ -6,7 +6,7 @@ apply plugin: 'nebula.ospackage'
|
||||
version = '1.0'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -38,21 +38,21 @@ findbugs {
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes("Main-Class": "hirs.tcg_eventlog.Main",
|
||||
"Class-Path": configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
|
||||
)
|
||||
}
|
||||
from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {}
|
||||
exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
|
||||
manifest {
|
||||
attributes("Main-Class": "hirs.tcg_eventlog.Main",
|
||||
"Class-Path": configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
|
||||
)
|
||||
}
|
||||
from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {}
|
||||
exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
|
||||
}
|
||||
|
||||
uploadArchives {
|
||||
repositories {
|
||||
flatDir {
|
||||
dirs "${buildDir}"
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
flatDir {
|
||||
dirs "${buildDir}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildscript {
|
||||
@ -66,15 +66,15 @@ buildscript {
|
||||
|
||||
// Produce packages
|
||||
ospackage {
|
||||
packageName='tcg_eventlog_tool'
|
||||
os=LINUX
|
||||
arch=NOARCH
|
||||
version='1.0.0'
|
||||
release='1'
|
||||
packageName = 'tcg_eventlog_tool'
|
||||
os = LINUX
|
||||
arch = NOARCH
|
||||
version = '2.0.0'
|
||||
release = '1'
|
||||
|
||||
into '/opt/hirs/eventlog'
|
||||
user 'root'
|
||||
fileMode=0755
|
||||
fileMode = 0755
|
||||
|
||||
from(jar.outputs.files) {
|
||||
into 'lib'
|
||||
@ -88,29 +88,38 @@ ospackage {
|
||||
from('scripts') {
|
||||
exclude {
|
||||
FileTreeElement details ->
|
||||
details.file.name.endsWith('.bat')
|
||||
details.file.name.endsWith('.bat')
|
||||
}
|
||||
into 'scripts'
|
||||
}
|
||||
from('docs') {
|
||||
exclude {
|
||||
FileTreeElement details ->
|
||||
details.file.name.endsWith('.odt')
|
||||
details.file.name.endsWith('.odt')
|
||||
}
|
||||
into 'docs'
|
||||
}
|
||||
from('./') {
|
||||
include {
|
||||
FileTreeElement details ->
|
||||
details.file.name.endsWith('.md')
|
||||
details.file.name.endsWith('.md')
|
||||
}
|
||||
into './'
|
||||
link("/usr/local/bin/elt","/opt/hirs/eventlog/scripts/eventlog.sh",0x755 )
|
||||
link("/usr/local/bin/elt", "/opt/hirs/eventlog/scripts/eventlog.sh", 0x755)
|
||||
}
|
||||
|
||||
into('/opt/hirs/default-properties/') {
|
||||
fileMode 0664
|
||||
from ('../../HIRS_Utils/src/main/resources/vendor-table.json') {
|
||||
addParentDirs true
|
||||
createDirectoryEntry true
|
||||
}
|
||||
}
|
||||
|
||||
buildRpm {
|
||||
arch = I386
|
||||
}
|
||||
buildDeb {
|
||||
arch = I386
|
||||
}
|
||||
buildRpm {
|
||||
arch = I386
|
||||
}
|
||||
buildDeb {
|
||||
arch = I386
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import hirs.tpm.eventlog.TCGEventLog;
|
||||
import hirs.tpm.eventlog.TpmPcrEvent;
|
||||
@ -135,14 +136,16 @@ final class Main {
|
||||
|| commander.getPcrNumber() == -1) {
|
||||
if (bHexFlag) {
|
||||
if (bEventFlag || bHexEvent) {
|
||||
writeOut(HexUtils.byteArrayToHexString(event.getEvent()) + "\n");
|
||||
writeOut(HexUtils.byteArrayToHexString(event.getEvent())
|
||||
+ "\n");
|
||||
}
|
||||
if (bContentFlag) {
|
||||
writeOut(HexUtils.byteArrayToHexString(event.getEventContent())
|
||||
+ "\n");
|
||||
}
|
||||
} else {
|
||||
writeOut(event.toString(bEventFlag, bContentFlag, bHexEvent) + "\n");
|
||||
writeOut(event.toString(bEventFlag, bContentFlag, bHexEvent)
|
||||
+ "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -291,8 +294,9 @@ final class Main {
|
||||
* @param pcr used as a filter. Use -1 to check all pcrs.
|
||||
* @return array list of strings. Null of no events mismatched.
|
||||
*/
|
||||
public static ArrayList<TpmPcrEvent> diffEventLogs(final ArrayList<TpmPcrEvent> eventList,
|
||||
final ArrayList<TpmPcrEvent> eventList2, final int pcr) {
|
||||
public static ArrayList<TpmPcrEvent> diffEventLogs(final Collection<TpmPcrEvent> eventList,
|
||||
final Collection<TpmPcrEvent> eventList2,
|
||||
final int pcr) {
|
||||
ArrayList<TpmPcrEvent> results = new ArrayList<TpmPcrEvent>();
|
||||
for (TpmPcrEvent event2 : eventList2) {
|
||||
if (pcr >= 0) {
|
||||
@ -317,7 +321,7 @@ final class Main {
|
||||
* @param event single event to match.
|
||||
* @return
|
||||
*/
|
||||
private static boolean digestMatch(final ArrayList<TpmPcrEvent> eventLog,
|
||||
private static boolean digestMatch(final Collection<TpmPcrEvent> eventLog,
|
||||
final TpmPcrEvent event) {
|
||||
boolean matchFound = false;
|
||||
for (TpmPcrEvent event2 : eventLog) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
apply plugin: 'java'
|
||||
version = '1.0'
|
||||
version = '2.0.0'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
@ -3,6 +3,6 @@
|
||||
# Calls the the_tcg_rim_tool and passes in parameters
|
||||
scriptDir=$(dirname -- "$(readlink -f -- "${BASH_SOURCE[0]}")")
|
||||
baseDir=${scriptDir%/*}
|
||||
jar="tcg_rim_tool-1.0.jar";
|
||||
jar="tcg_rim_tool-2.0.0.jar";
|
||||
java -jar $baseDir/$jar "$@"
|
||||
|
||||
|
@ -50,9 +50,9 @@ public class CredentialParser {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
public void parseJKSCredentials() {
|
||||
public void parseJKSCredentials(String jksKeystore) {
|
||||
KeyStore.PrivateKeyEntry privateKeyEntry =
|
||||
parseKeystorePrivateKey(SwidTagConstants.DEFAULT_KEYSTORE_PATH,
|
||||
parseKeystorePrivateKey(jksKeystore,
|
||||
SwidTagConstants.DEFAULT_PRIVATE_KEY_ALIAS,
|
||||
SwidTagConstants.DEFAULT_KEYSTORE_PASSWORD);
|
||||
certificate = (X509Certificate) privateKeyEntry.getCertificate();
|
||||
|
@ -47,6 +47,7 @@ public class Main {
|
||||
System.out.println(commander.toString());
|
||||
String createType = commander.getCreateType().toUpperCase();
|
||||
String attributesFile = commander.getAttributesFile();
|
||||
String jksKeystoreFile = commander.getKeystoreFile();
|
||||
String certificateFile = commander.getPublicCertificate();
|
||||
String privateKeyFile = commander.getPrivateKeyFile();
|
||||
String rimEventLog = commander.getRimEventLog();
|
||||
@ -55,10 +56,16 @@ public class Main {
|
||||
if (!attributesFile.isEmpty()) {
|
||||
gateway.setAttributesFile(attributesFile);
|
||||
}
|
||||
if (!certificateFile.isEmpty() && !privateKeyFile.isEmpty()) {
|
||||
if (!jksKeystoreFile.isEmpty()) {
|
||||
gateway.setDefaultCredentials(true);
|
||||
gateway.setJksKeystoreFile(jksKeystoreFile);
|
||||
} else if (!certificateFile.isEmpty() && !privateKeyFile.isEmpty()) {
|
||||
gateway.setDefaultCredentials(false);
|
||||
gateway.setPemCertificateFile(certificateFile);
|
||||
gateway.setPemPrivateKeyFile(privateKeyFile);
|
||||
} else {
|
||||
gateway.setDefaultCredentials(true);
|
||||
gateway.setJksKeystoreFile(SwidTagConstants.DEFAULT_KEYSTORE_FILE);
|
||||
}
|
||||
if (rimEventLog.isEmpty()) {
|
||||
System.out.println("Error: a support RIM is required!");
|
||||
|
@ -12,7 +12,7 @@ import javax.xml.namespace.QName;
|
||||
*/
|
||||
public class SwidTagConstants {
|
||||
|
||||
public static final String DEFAULT_KEYSTORE_PATH = "keystore.jks";
|
||||
public static final String DEFAULT_KEYSTORE_FILE = "/opt/hirs/rimtool/keystore.jks";
|
||||
public static final String DEFAULT_KEYSTORE_PASSWORD = "password";
|
||||
public static final String DEFAULT_PRIVATE_KEY_ALIAS = "selfsigned";
|
||||
public static final String DEFAULT_ATTRIBUTES_FILE = "rim_fields.json";
|
||||
|
@ -4,7 +4,13 @@ import com.eclipsesource.json.Json;
|
||||
import com.eclipsesource.json.JsonObject;
|
||||
import com.eclipsesource.json.ParseException;
|
||||
import hirs.swid.utils.HashSwid;
|
||||
import hirs.swid.xjc.*;
|
||||
import hirs.swid.xjc.Directory;
|
||||
import hirs.swid.xjc.Entity;
|
||||
import hirs.swid.xjc.Link;
|
||||
import hirs.swid.xjc.ObjectFactory;
|
||||
import hirs.swid.xjc.ResourceCollection;
|
||||
import hirs.swid.xjc.SoftwareIdentity;
|
||||
import hirs.swid.xjc.SoftwareMeta;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
@ -13,24 +19,47 @@ import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import javax.xml.crypto.MarshalException;
|
||||
import javax.xml.crypto.XMLStructure;
|
||||
import javax.xml.crypto.dsig.*;
|
||||
import javax.xml.crypto.dsig.CanonicalizationMethod;
|
||||
import javax.xml.crypto.dsig.DigestMethod;
|
||||
import javax.xml.crypto.dsig.Reference;
|
||||
import javax.xml.crypto.dsig.SignedInfo;
|
||||
import javax.xml.crypto.dsig.Transform;
|
||||
import javax.xml.crypto.dsig.XMLSignature;
|
||||
import javax.xml.crypto.dsig.XMLSignatureException;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
import javax.xml.crypto.dsig.dom.DOMSignContext;
|
||||
import javax.xml.crypto.dsig.keyinfo.*;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyName;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyValue;
|
||||
import javax.xml.crypto.dsig.keyinfo.X509Data;
|
||||
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.*;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.*;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.*;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.KeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
@ -51,6 +80,7 @@ public class SwidTagGateway {
|
||||
private Marshaller marshaller;
|
||||
private String attributesFile;
|
||||
private boolean defaultCredentials;
|
||||
private String jksKeystoreFile;
|
||||
private String pemPrivateKeyFile;
|
||||
private String pemCertificateFile;
|
||||
private String rimEventLog;
|
||||
@ -88,6 +118,12 @@ public class SwidTagGateway {
|
||||
this.defaultCredentials = defaultCredentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for JKS keystore file
|
||||
* @param jksKeystoreFile
|
||||
*/
|
||||
public void setJksKeystoreFile(String jksKeystoreFile) { this.jksKeystoreFile = jksKeystoreFile; }
|
||||
|
||||
/**
|
||||
* Setter for private key file in PEM format
|
||||
* @param pemPrivateKeyFile
|
||||
@ -404,7 +440,7 @@ public class SwidTagGateway {
|
||||
PublicKey publicKey;
|
||||
CredentialParser cp = new CredentialParser();
|
||||
if (defaultCredentials) {
|
||||
cp.parseJKSCredentials();
|
||||
cp.parseJKSCredentials(jksKeystoreFile);
|
||||
privateKey = cp.getPrivateKey();
|
||||
publicKey = cp.getPublicKey();
|
||||
KeyName keyName = kiFactory.newKeyName(cp.getCertificateSubjectKeyIdentifier());
|
||||
|
@ -10,20 +10,29 @@ import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.UnmarshalException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.AlgorithmMethod;
|
||||
import javax.xml.crypto.KeySelector;
|
||||
import javax.xml.crypto.KeySelectorException;
|
||||
import javax.xml.crypto.KeySelectorResult;
|
||||
import javax.xml.crypto.MarshalException;
|
||||
import javax.xml.crypto.XMLCryptoContext;
|
||||
import javax.xml.crypto.XMLStructure;
|
||||
import javax.xml.crypto.dsig.XMLSignature;
|
||||
import javax.xml.crypto.dsig.XMLSignatureException;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
import javax.xml.crypto.dsig.dom.DOMValidateContext;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
|
||||
import javax.xml.crypto.dsig.keyinfo.X509Data;
|
||||
import javax.xml.transform.*;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.Key;
|
||||
@ -31,6 +40,9 @@ import java.security.PublicKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* This class handles validating base Reference Integrity Manifest files.
|
||||
*/
|
||||
public class SwidTagValidator {
|
||||
private Unmarshaller unmarshaller;
|
||||
private String rimEventLog;
|
||||
|
@ -7,6 +7,7 @@ import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import hirs.swid.SwidTagConstants;
|
||||
|
||||
/**
|
||||
* Commander is a class that handles the command line arguments for the SWID
|
||||
@ -28,14 +29,17 @@ public class Commander {
|
||||
@Parameter(names = {"-v", "--verify <path>"}, order = 3,
|
||||
description = "Specify a RIM file to verify.")
|
||||
private String verifyFile = "";
|
||||
@Parameter(names = {"-k", "--privateKeyFile <path>"}, order = 4,
|
||||
@Parameter(names = {"--keystore <path>"}, order = 4,
|
||||
description = "JKS keystore containing a private key to sign the base RIM created by the create function.")
|
||||
private String keystoreFile = "";
|
||||
@Parameter(names = {"-k", "--privateKeyFile <path>"}, order = 5,
|
||||
description = "File containing the private key used to sign the base RIM created by the create function.")
|
||||
private String privateKeyFile = "";
|
||||
@Parameter(names = {"-p", "--publicCertificate <path>"}, order = 5,
|
||||
@Parameter(names = {"-p", "--publicCertificate <path>"}, order = 6,
|
||||
description = "The public key certificate used to verify a RIM file or to embed in a signed RIM. " +
|
||||
"A signed RIM generated by this tool by default will not show the signing certificate without this parameter present.")
|
||||
private String publicCertificate = "";
|
||||
@Parameter(names = {"-l", "--rimel <path>"}, order = 6,
|
||||
@Parameter(names = {"-l", "--rimel <path>"}, order = 7,
|
||||
description = "The TCG eventlog file to use as a support RIM. By default the last system eventlog will be used.")
|
||||
private String rimEventLog = "";
|
||||
/*
|
||||
@ -69,6 +73,8 @@ public class Commander {
|
||||
return verifyFile;
|
||||
}
|
||||
|
||||
public String getKeystoreFile() { return keystoreFile; }
|
||||
|
||||
public String getPrivateKeyFile() {
|
||||
return privateKeyFile;
|
||||
}
|
||||
@ -110,13 +116,21 @@ public class Commander {
|
||||
}
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Creating: " + getCreateType() + System.lineSeparator());
|
||||
sb.append("Using attributes file: " + getAttributesFile() + System.lineSeparator());
|
||||
sb.append("Write to: " + getOutFile() + System.lineSeparator());
|
||||
sb.append("Verify file: " + getVerifyFile() + System.lineSeparator());
|
||||
sb.append("Private key file: " + getPrivateKeyFile() + System.lineSeparator());
|
||||
sb.append("Public certificate: " + getPublicCertificate() + System.lineSeparator());
|
||||
sb.append("Event log support RIM: " + getRimEventLog() + System.lineSeparator());
|
||||
sb.append("Creating: " + this.getCreateType() + System.lineSeparator());
|
||||
sb.append("Using attributes file: " + this.getAttributesFile() + System.lineSeparator());
|
||||
sb.append("Write to: " + this.getOutFile() + System.lineSeparator());
|
||||
sb.append("Verify file: " + this.getVerifyFile() + System.lineSeparator());
|
||||
if (!this.getKeystoreFile().isEmpty()) {
|
||||
sb.append("Keystore file: " + this.getKeystoreFile() + System.lineSeparator());
|
||||
} else if (!this.getPrivateKeyFile().isEmpty() &&
|
||||
!this.getPublicCertificate().isEmpty()) {
|
||||
sb.append("Private key file: " + this.getPrivateKeyFile() + System.lineSeparator());
|
||||
sb.append("Public certificate: " + this.getPublicCertificate() + System.lineSeparator());
|
||||
} else {
|
||||
sb.append("Keystore file: default (" + SwidTagConstants.DEFAULT_KEYSTORE_FILE + ")"
|
||||
+ System.lineSeparator());
|
||||
}
|
||||
sb.append("Event log support RIM: " + this.getRimEventLog() + System.lineSeparator());
|
||||
/*
|
||||
sb.append("TPM PCRs support RIM: " + getRimPcrs() + System.lineSeparator());
|
||||
sb.append("Base RIM to be signed: " + getToBeSigned() + System.lineSeparator());
|
||||
|
@ -21,6 +21,7 @@ public class TestSwidTagGateway {
|
||||
private final String DEFAULT_WITH_CERT = "generated_with_cert.swidtag";
|
||||
private final String DEFAULT_NO_CERT = "generated_no_cert.swidtag";
|
||||
private final String ATTRIBUTES_FILE = TestSwidTagGateway.class.getClassLoader().getResource("rim_fields.json").getPath();
|
||||
private final String JKS_KEYSTORE_FILE = TestSwidTagGateway.class.getClassLoader().getResource("keystore.jks").getPath();
|
||||
private final String SIGNING_CERT_FILE = TestSwidTagGateway.class.getClassLoader().getResource("RimSignCert.pem").getPath();
|
||||
private final String PRIVATE_KEY_FILE = TestSwidTagGateway.class.getClassLoader().getResource("privateRimKey.pem").getPath();
|
||||
private final String SUPPORT_RIM_FILE = TestSwidTagGateway.class.getClassLoader().getResource("TpmLog.bin").getPath();
|
||||
@ -48,12 +49,12 @@ public class TestSwidTagGateway {
|
||||
* where RimSignCert.pem has the AIA extension.
|
||||
*/
|
||||
@Test
|
||||
public void testCreateBaseWithCert() throws URISyntaxException {
|
||||
public void testCreateBaseWithCert() {
|
||||
gateway.setDefaultCredentials(false);
|
||||
gateway.setPemCertificateFile(SIGNING_CERT_FILE);
|
||||
gateway.setPemPrivateKeyFile(PRIVATE_KEY_FILE);
|
||||
gateway.generateSwidTag(DEFAULT_OUTPUT);
|
||||
expectedFile = (InputStream) TestSwidTagGateway.class.getClassLoader().getResourceAsStream(DEFAULT_WITH_CERT);
|
||||
expectedFile = TestSwidTagGateway.class.getClassLoader().getResourceAsStream(DEFAULT_WITH_CERT);
|
||||
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
|
||||
}
|
||||
|
||||
@ -64,8 +65,9 @@ public class TestSwidTagGateway {
|
||||
@Test
|
||||
public void testCreateBaseWithoutCert() {
|
||||
gateway.setDefaultCredentials(true);
|
||||
gateway.setJksKeystoreFile(JKS_KEYSTORE_FILE);
|
||||
gateway.generateSwidTag(DEFAULT_OUTPUT);
|
||||
expectedFile = (InputStream) TestSwidTagGateway.class.getClassLoader().getResourceAsStream(DEFAULT_NO_CERT);
|
||||
expectedFile = TestSwidTagGateway.class.getClassLoader().getResourceAsStream(DEFAULT_NO_CERT);
|
||||
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
|
||||
}
|
||||
|
||||
|
BIN
tools/tcg_rim_tool/src/test/resources/keystore.jks
Normal file
BIN
tools/tcg_rim_tool/src/test/resources/keystore.jks
Normal file
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
Name: tcg_rim_tool
|
||||
Version: 1.0
|
||||
Version: 2.0.0
|
||||
Release: 1%{?dist}
|
||||
Summary: A java command-line tool to create PC client root RIM
|
||||
|
||||
@ -39,6 +39,8 @@ ln -sf /opt/hirs/rimtool/scripts/rimtool.sh %{buildroot}/usr/local/bin/rim
|
||||
%attr(755, root, root) /opt/hirs/rimtool/scripts/rimtool.sh
|
||||
|
||||
%changelog
|
||||
* Tue Nov 10 2020 chubtub
|
||||
- Second release
|
||||
* Mon Jun 15 2020 chubtub
|
||||
- First release
|
||||
* Mon Jan 6 2020 chubtub
|
||||
|
Loading…
x
Reference in New Issue
Block a user