Merge branch 'master' into issue-462

This commit is contained in:
chubtub 2022-08-25 13:01:39 -04:00
commit 20903c6bea
33 changed files with 678 additions and 350 deletions

View File

@ -1,8 +1,18 @@
FROM hirs/hirs-ci:centos7 FROM centos:7
# Install packages for installing HIRS ACA # Install packages for installing HIRS ACA
RUN yum -y update && yum clean all RUN yum -y update && yum clean all
RUN yum install -y mariadb-server openssl tomcat java-1.8.0 rpmdevtools coreutils initscripts chkconfig sed grep firewalld policycoreutils && yum clean all # install build tools for TPM2 provisioner
RUN yum install -y epel-release cmake make git gcc-c++ doxygen graphviz protobuf-compiler cppcheck python libssh2-devel openssl libcurl-devel log4cplus-devel protobuf-devel re2-devel tpm2-tss-devel tpm2-abrmd-devel && yum clean all
# install build tools for ACA
RUN yum install -y sudo yum install java-1.8.0-openjdk-devel protobuf-compiler rpm-build epel-release cmake make git gcc-c++ doxygen graphviz cppcheck python libssh2-devel openssl libcurl-devel log4cplus-devel protobuf-devel re2-devel tpm2-tss-devel tpm2-abrmd-devel trousers-devel && yum clean all
# install run time dependencies
RUN yum install -y mariadb-server openssl tomcat java-1.8.0-openjdk-headless rpmdevtools coreutils initscripts chkconfig sed grep wget which firewalld policycoreutils net-tools git rpm-build && yum clean all
# Remove TLSv1, TLSv1.1, references to prevent java security from stopping tomcat launch
RUN sed -i 's/TLSv1,//' /usr/lib/jvm/java-1.8.0-openjdk-1.8.0*/jre/lib/security/java.security
RUN sed -i 's/TLSv1.1,//' /usr/lib/jvm/java-1.8.0-openjdk-1.8.0*/jre/lib/security/java.security
# Expose ACA Port # Expose ACA Port
EXPOSE 8443 EXPOSE 8443

View File

@ -1,12 +1,19 @@
FROM hirs/hirs-ci:centos7 FROM centos:7
# Install packages for installing HIRS TPM2 Provisioner # Install packages for installing HIRS TPM2 Provisioner
RUN yum -y update && yum clean all RUN yum -y update && yum clean all
RUN yum install -y tpm2-tools libcurl procps-ng wget dbus python-requests python2-future python36-future && yum clean all
# install build dependencies
RUN yum install -y epel-release cmake make git gcc-c++ doxygen graphviz protobuf-compiler cppcheck python libssh2-devel openssl libcurl-devel log4cplus-devel protobuf-devel re2-devel tpm2-tss-devel tpm2-abrmd-devel && yum clean all
# install run time dependencies
RUN yum install -y java-1.8.0 wget util-linux chkconfig sed initscripts coreutils dmidecode trousers tpm-tools && yum clean all
# Install PACCOR for Device Info Gathering # Install PACCOR for Device Info Gathering
RUN mkdir paccor && pushd paccor && wget https://github.com/nsacyber/paccor/releases/download/v1.1.4r2/paccor-1.1.4-2.noarch.rpm && yum -y install paccor-*.rpm && popd RUN mkdir paccor && pushd paccor && wget https://github.com/nsacyber/paccor/releases/download/v1.1.4r2/paccor-1.1.4-2.noarch.rpm && yum -y install paccor-*.rpm && popd
# Install Software TPM for Provisioning # Install Software TPM for Provisioning
RUN mkdir ibmtpm && pushd ibmtpm && wget https://downloads.sourceforge.net/project/ibmswtpm2/ibmtpm1332.tar.gz && tar -zxvf ibmtpm1332.tar.gz && cd src && make -j5 && popd RUN mkdir ibmtpm && pushd ibmtpm && wget --no-check-certificate https://downloads.sourceforge.net/project/ibmswtpm2/ibmtpm1332.tar.gz && tar -zxvf ibmtpm1332.tar.gz && cd src && make -j5 && popd
# Install TSS for TPM setup
RUN mkdir ibmtss && pushd ibmtss && wget --no-check-certificate https://downloads.sourceforge.net/project/ibmtpm20tss/ibmtss1.6.0.tar.gz && tar -zxvf ibmtss1.6.0.tar.gz && cd utils && make -f makefiletpmc && popd

View File

@ -2,14 +2,14 @@ version: "3.1"
services: services:
aca: aca:
image: hirs/hirs-ci:aca image: ghcr.io/nsacyber/hirs/aca-ci:latest
container_name: hirs-aca1 container_name: hirs-aca1
volumes: volumes:
- ../../:/HIRS - ../../:/HIRS
ports: ports:
- "${HIRS_ACA_PORTAL_PORT}:${HIRS_ACA_PORTAL_CONTAINER_PORT}" - "${HIRS_ACA_PORTAL_PORT}:${HIRS_ACA_PORTAL_CONTAINER_PORT}"
entrypoint: /bin/bash -c entrypoint: /bin/bash -c
command: [HIRS/.ci/setup/container/setup_aca.sh] command: [tail -f /dev/null;]
hostname: ${HIRS_ACA_HOSTNAME} hostname: ${HIRS_ACA_HOSTNAME}
networks: networks:
hirs_aca_system_tests: hirs_aca_system_tests:
@ -18,7 +18,7 @@ services:
- ${HIRS_ACA_HOSTNAME} - ${HIRS_ACA_HOSTNAME}
tpmprovisioner: tpmprovisioner:
image: hirs/hirs-ci:tpm2provisioner image: ghcr.io/nsacyber/hirs/tpm2provisioner-ci:latest
container_name: hirs-provisioner1-tpm2 container_name: hirs-provisioner1-tpm2
depends_on: depends_on:
- aca - aca

View File

@ -6,11 +6,22 @@ set -e
# Prevent rebuild of packages if they already exist # Prevent rebuild of packages if they already exist
cd /HIRS cd /HIRS
echo "Building and packaging the ACA"
if [ ! -d package/rpm/RPMS ]; then if [ ! -d package/rpm/RPMS ]; then
./package/package.centos.sh mkdir -p /HIRS/logs/aca/
sh package/package.centos.sh &> /HIRS/logs/aca/aca_build.log
fi fi
yum install -y package/rpm/RPMS/noarch/HIRS_AttestationCA*.el7.noarch.rpm echo "Building and packaging the ACA completed"
echo "Installing the ACA"
echo "ACA Loaded!" yum install -y package/rpm/RPMS/noarch/HIRS_AttestationCA*.el7.noarch.rpm &> /HIRS/logs/aca/aca_install.log
filename=package/rpm/RPMS/noarch/HIRS_AttestationCA*.el7.noarch.rpm
tail -f /dev/null echo "================================================================================"
echo "Installing:"
echo " HIRS_AttestationCA"
echo " $filename"
echo ""
echo "Transaction Summary"
echo "================================================================================"
echo "Install 1 Package"
echo ""
echo "********************* End of ACA installation *********************"m

View File

@ -18,14 +18,9 @@ function installProvisioner {
# use ibm tss to properly clear tpm pcr values # use ibm tss to properly clear tpm pcr values
function setTpmPcrValues { function setTpmPcrValues {
mkdir /ibmtss
pushd /ibmtss > /dev/null pushd /ibmtss > /dev/null
echo "Installing IBM TSS to set the TPM simulator intial values correctly..." echo "Starting IBM TSS to set the TPM simulator initial values correctly..."
wget --no-check-certificate https://downloads.sourceforge.net/project/ibmtpm20tss/ibmtss1.6.0.tar.gz > /dev/null
tar -zxvf ibmtss1.6.0.tar.gz > /dev/null
cd utils cd utils
make -f makefiletpmc > /dev/null
cd ../utils
./startup ./startup
popd > /dev/null popd > /dev/null
} }

View File

@ -27,11 +27,14 @@ popd > /dev/null
pushd .ci/system-tests > /dev/null pushd .ci/system-tests > /dev/null
source sys_test_common.sh source sys_test_common.sh
# Build, Package, and Install HIRS ACA (2+ minutes) then wait for systems tests...
docker exec $aca_container sh -c "/HIRS/.ci/setup/container/setup_aca.sh"
echo "ACA Loaded!"
echo "ACA Container info: $(checkContainerStatus $aca_container)"; echo "ACA Container info: $(checkContainerStatus $aca_container)";
echo "TPM2 Provisioner Container info: $(checkContainerStatus $tpm2_container)";
# Install HIRS provioner and setup tpm2 emulator # Install HIRS provioner and setup tpm2 emulator
docker exec $tpm2_container /HIRS/.ci/setup/container/setup_tpm2provisioner.sh docker exec $tpm2_container /HIRS/.ci/setup/container/setup_tpm2provisioner.sh
echo "TPM2 Provisioner Container info: $(checkContainerStatus $tpm2_container)";
# ********* Execute system tests here, add tests as needed ************* # ********* Execute system tests here, add tests as needed *************
echo "******** Setup Complete Begin HIRS System Tests ******** " echo "******** Setup Complete Begin HIRS System Tests ******** "

View File

@ -21,34 +21,34 @@ fi
# clear all policy settings # clear all policy settings
setPolicyNone() { setPolicyNone() {
docker exec $aca_container mysql -u root -D hirs_db -e "Update SupplyChainPolicy set enableEcValidation=0, enablePcAttributeValidation=0, enablePcValidation=0, docker exec $aca_container mysql -u root -proot -D hirs_db -e "Update SupplyChainPolicy set enableEcValidation=0, enablePcAttributeValidation=0, enablePcValidation=0,
enableUtcValidation=0, enableFirmwareValidation=0, enableExpiredCertificateValidation=0, enableIgnoreGpt=0, enableIgnoreIma=0, enableIgnoretBoot=0;" enableUtcValidation=0, enableFirmwareValidation=0, enableExpiredCertificateValidation=0, enableIgnoreGpt=0, enableIgnoreIma=0, enableIgnoretBoot=0;"
} }
# Policy Settings for tests ... # Policy Settings for tests ...
setPolicyEkOnly() { setPolicyEkOnly() {
docker exec $aca_container mysql -u root -D hirs_db -e "Update SupplyChainPolicy set enableEcValidation=1, enablePcAttributeValidation=0, enablePcValidation=0, docker exec $aca_container mysql -u root -proot -D hirs_db -e "Update SupplyChainPolicy set enableEcValidation=1, enablePcAttributeValidation=0, enablePcValidation=0,
enableUtcValidation=0, enableFirmwareValidation=0, enableExpiredCertificateValidation=0, enableIgnoreGpt=0, enableIgnoreIma=0, enableIgnoretBoot=0;" enableUtcValidation=0, enableFirmwareValidation=0, enableExpiredCertificateValidation=0, enableIgnoreGpt=0, enableIgnoreIma=0, enableIgnoretBoot=0;"
} }
setPolicyEkPc_noAttCheck() { setPolicyEkPc_noAttCheck() {
docker exec $aca_container mysql -u root -D hirs_db -e "Update SupplyChainPolicy set enableEcValidation=1, enablePcAttributeValidation=0, enablePcValidation=1, docker exec $aca_container mysql -u root -proot -D hirs_db -e "Update SupplyChainPolicy set enableEcValidation=1, enablePcAttributeValidation=0, enablePcValidation=1,
enableUtcValidation=0, enableFirmwareValidation=0, enableExpiredCertificateValidation=0, enableIgnoreGpt=0, enableIgnoreIma=0, enableIgnoretBoot=0;" enableUtcValidation=0, enableFirmwareValidation=0, enableExpiredCertificateValidation=0, enableIgnoreGpt=0, enableIgnoreIma=0, enableIgnoretBoot=0;"
} }
setPolicyEkPc() { setPolicyEkPc() {
docker exec $aca_container mysql -u root -D hirs_db -e "Update SupplyChainPolicy set enableEcValidation=1, enablePcAttributeValidation=1, enablePcValidation=1, docker exec $aca_container mysql -u root -proot -D hirs_db -e "Update SupplyChainPolicy set enableEcValidation=1, enablePcAttributeValidation=1, enablePcValidation=1,
enableUtcValidation=0, enableFirmwareValidation=0, enableExpiredCertificateValidation=0, enableIgnoreGpt=0, enableIgnoreIma=0, enableIgnoretBoot=0;" enableUtcValidation=0, enableFirmwareValidation=0, enableExpiredCertificateValidation=0, enableIgnoreGpt=0, enableIgnoreIma=0, enableIgnoretBoot=0;"
} }
setPolicyEkPcFw() { setPolicyEkPcFw() {
docker exec $aca_container mysql -u root -D hirs_db -e "Update SupplyChainPolicy set enableEcValidation=1, enablePcAttributeValidation=1, enablePcValidation=1, docker exec $aca_container mysql -u root -proot -D hirs_db -e "Update SupplyChainPolicy set enableEcValidation=1, enablePcAttributeValidation=1, enablePcValidation=1,
enableUtcValidation=0, enableFirmwareValidation=1, enableExpiredCertificateValidation=0, enableIgnoreGpt=0, enableIgnoreIma=1, enableIgnoretBoot=0;" enableUtcValidation=0, enableFirmwareValidation=1, enableExpiredCertificateValidation=0, enableIgnoreGpt=0, enableIgnoreIma=1, enableIgnoretBoot=0;"
} }
# Clear all ACA DB items including policy # Clear all ACA DB items including policy
clearAcaDb() { clearAcaDb() {
docker exec $aca_container mysql -u root -e "use hirs_db; set foreign_key_checks=0; truncate Alert;truncate AlertBaselineIds;truncate docker exec $aca_container mysql -u root -proot -e "use hirs_db; set foreign_key_checks=0; truncate Alert;truncate AlertBaselineIds;truncate
AppraisalResult;truncate Certificate;truncate Certificate_Certificate;truncate CertificatesUsedToValidate;truncate AppraisalResult;truncate Certificate;truncate Certificate_Certificate;truncate CertificatesUsedToValidate;truncate
ComponentInfo;truncate Device;truncate DeviceInfoReport;truncate IMADeviceState;truncate IMAMeasurementRecord;truncate ComponentInfo;truncate Device;truncate DeviceInfoReport;truncate IMADeviceState;truncate IMAMeasurementRecord;truncate
ImaBlacklistRecord;truncate ImaIgnoreSetRecord;truncate IntegrityReport;truncate IntegrityReports_Reports_Join;truncate ImaBlacklistRecord;truncate ImaIgnoreSetRecord;truncate IntegrityReport;truncate IntegrityReports_Reports_Join;truncate

View File

@ -16,19 +16,15 @@ jobs:
packages: write packages: write
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Set up JDK 8
uses: actions/setup-java@v2
with:
java-version: '8'
distribution: 'adopt'
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
- name: ACA TPM2 Tests - name: ACA TPM2 Tests
continue-on-error: true continue-on-error: true
shell: bash shell: bash
run: | run: |
sudo apt-get install -y curl sudo apt-get install -y curl
echo ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} | docker login -u ${{ secrets.DOCKER_HUB_USERNAME }} --password-stdin export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0*/jre/bin"
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin
# comment out the line above and uncomment the line below to run in a forked repo.
#echo "${{ secrets.PKG_PWD }}" | docker login ghcr.io -u $ --password-stdin
bash .ci/system-tests/run_system_tests.sh bash .ci/system-tests/run_system_tests.sh
- name: Archive System Test Log files - name: Archive System Test Log files
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
@ -43,4 +39,4 @@ jobs:
exit 0; exit 0;
else else
exit 1; exit 1;
fi fi

View File

@ -445,6 +445,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
passed = false; passed = false;
fwStatus = new AppraisalStatus(FAIL, fwStatus = new AppraisalStatus(FAIL,
"Firmware validation failed: invalid certificate path."); "Firmware validation failed: invalid certificate path.");
validationObject = baseReferenceManifest;
} }
} catch (IOException e) { } catch (IOException e) {
LOGGER.error("Error getting X509 cert from manager: " + e.getMessage()); LOGGER.error("Error getting X509 cert from manager: " + e.getMessage());
@ -467,7 +468,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
} }
} }
if (signingCert == null) { if (passed && signingCert == null) {
passed = false; passed = false;
fwStatus = new AppraisalStatus(FAIL, fwStatus = new AppraisalStatus(FAIL,
"Firmware validation failed: signing cert not found."); "Firmware validation failed: signing cert not found.");

View File

@ -70,7 +70,7 @@
<h3> <h3>
<a href="${portal}/rim-database"><img src="${icons}/ic_devices_black_24dp.png" /> RIM Database</a> <a href="${portal}/rim-database"><img src="${icons}/ic_devices_black_24dp.png" /> RIM Database</a>
</h3> </h3>
<h4>View a list of TPM events </h4> <h4>View a list of Reference Integrity Measurements</h4>
</div> </div>
</div> </div>
</div> </div>

View File

@ -13,10 +13,12 @@
<jsp:attribute name="pageHeaderTitle"> <jsp:attribute name="pageHeaderTitle">
<c:choose> <c:choose>
<c:when test="${initialData.rimType=='Measurement'}"> <c:when test="${initialData.rimType=='Measurement'}">
TCG Event Log <c:if test="${initialData.validationResult=='PASS'}">
<a href="${portal}/reference-manifests/download?id=${param.id}"> TCG Log events
<img src="${icons}/ic_file_download_black_24dp.png" title="Download ${initialData.rimType} RIM"> </c:if>
</a> <c:if test="${initialData.validationResult=='FAIL'}">
TCG Log event(s) not found in the RIM DB
</c:if>
</c:when> </c:when>
<c:otherwise> <c:otherwise>
${initialData.rimType} Reference Integrity Manifest ${initialData.rimType} Reference Integrity Manifest
@ -38,19 +40,19 @@
<c:when test="${initialData.rimType=='Support' || (initialData.rimType=='Measurement' && initialData.validationResult=='PASS')}"> <c:when test="${initialData.rimType=='Support' || (initialData.rimType=='Measurement' && initialData.validationResult=='PASS')}">
<div class="row"> <div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Additional<br />RIM Info</span></div> <div class="col-md-1 col-md-offset-1"><span class="colHeader">Additional<br />RIM Info</span></div>
<div id="baseRim" class="col col-md-8"> <div class="col col-md-8">
<c:choose> <c:choose>
<c:when test="${not empty initialData.associatedRim}"> <c:when test="${not empty initialData.associatedRim}">
<a href="${portal}/rim-details?id=${initialData.associatedRim}"> <a href="${portal}/rim-details?id=${initialData.associatedRim}">
${initialData.tagId} ${initialData.tagId}
</a> </a>
<c:if test="${not empty initialData.hostName}"> <c:if test="${not empty initialData.hostName}">
<div>Device:&nbsp;<span>${initialData.hostName}</span></div> <div>Device:&nbsp;<span>${initialData.hostName}</span></div>
</c:if> </c:if>
<c:if test="${not empty initialData.supportId}"> <c:if test="${not empty initialData.supportId}">
<div>Support:&nbsp;<span><a href="${portal}/rim-details?id=${initialData.supportId}">${initialData.supportFilename}</a></span> <div>Support:&nbsp;<span><a href="${portal}/rim-details?id=${initialData.supportId}">${initialData.supportFilename}</a></span>
</div> </div>
</c:if> </c:if>
</c:when> </c:when>
<c:otherwise> <c:otherwise>
<div class="component col col-md-10" style="color: red; padding-left: 20px">RIM not uploaded from the ACA RIM Page</div> <div class="component col col-md-10" style="color: red; padding-left: 20px">RIM not uploaded from the ACA RIM Page</div>
@ -272,6 +274,13 @@
<div class="row"> <div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">Base/Support</span></div> <div class="col-md-1 col-md-offset-1"><span class="colHeader">Base/Support</span></div>
<div id="measurements" class="col col-md-8"> <div id="measurements" class="col col-md-8">
<div>Download Measurement:&nbsp;
<span>
<a href="${portal}/reference-manifests/download?id=${param.id}">
BIOS Measurements
</a>
</span>
</div>
<c:if test="${not empty initialData.hostName}"> <c:if test="${not empty initialData.hostName}">
<div>Device:&nbsp;<span>${initialData.hostName}</span> <div>Device:&nbsp;<span>${initialData.hostName}</span>
</div> </div>
@ -306,7 +315,7 @@
</div> </div>
<div style="display: flex;"> <div style="display: flex;">
<div class="mappedButton"> <div class="mappedButton">
Baseline Events of Type:<br /> Expected Events from RIM DB:<br />
<span style="word-wrap: break-word"><a role="button" data-toggle="collapse" href="#eventContent${iterator}">${lEvent.getEventTypeString()}</a></span> <span style="word-wrap: break-word"><a role="button" data-toggle="collapse" href="#eventContent${iterator}">${lEvent.getEventTypeString()}</a></span>
</div> </div>
<div id="eventContent${iterator}" class="panel-collapse collapse in" style="flex: 2"> <div id="eventContent${iterator}" class="panel-collapse collapse in" style="flex: 2">

View File

@ -68,7 +68,7 @@ public final class ProvisionerApplication {
} }
// enable TLS 1.1 and 1.2 // enable TLS 1.1 and 1.2
System.setProperty("https.protocols", "TLSv1.2,TLSv1.1"); System.setProperty("https.protocols", "TLSv1.2");
// initialize the context // initialize the context
new AnnotationConfigApplicationContext(ProvisionerConfiguration.class); new AnnotationConfigApplicationContext(ProvisionerConfiguration.class);

View File

@ -121,10 +121,11 @@ public class TpmPcrEvent {
* This can be SHA1 for older event structures or any algorithm for newer structure. * This can be SHA1 for older event structures or any algorithm for newer structure.
* *
* @param digestData cryptographic hash * @param digestData cryptographic hash
* @param digestLength length of the cryptographic hash
*/ */
protected void setEventDigest(final byte[] digestData) { protected void setEventDigest(final byte[] digestData, final int digestLength) {
digest = new byte[digestLength]; digest = new byte[digestLength];
System.arraycopy(digestData, 0, digest, 0, this.digestLength); System.arraycopy(digestData, 0, digest, 0, digestLength);
} }
/** /**
@ -469,23 +470,31 @@ public class TpmPcrEvent {
* @param event the byte array holding the event data. * @param event the byte array holding the event data.
* @param eventContent the byte array holding the event content. * @param eventContent the byte array holding the event content.
* @param eventNumber event position within the event log. * @param eventNumber event position within the event log.
* @param hashName name of the hash algorithm used by the event log
* @return String description of the event. * @return String description of the event.
* @throws CertificateException if the event contains an event that cannot be processed. * @throws CertificateException if the event contains an event that cannot be processed.
* @throws NoSuchAlgorithmException if an event contains an unsupported algorithm. * @throws NoSuchAlgorithmException if an event contains an unsupported algorithm.
* @throws IOException if the event cannot be parsed. * @throws IOException if the event cannot be parsed.
*/ */
public String processEvent(final byte[] event, final byte[] eventContent, final int eventNumber) public String processEvent(final byte[] event, final byte[] eventContent, final int eventNumber,
throws CertificateException, NoSuchAlgorithmException, IOException { final String hashName)
throws CertificateException, NoSuchAlgorithmException, IOException {
int eventID = (int) eventType; int eventID = (int) eventType;
this.eventNumber = eventNumber; this.eventNumber = eventNumber;
description += "Event# " + eventNumber + ": "; description += "Event# " + eventNumber + ": ";
description += "Index PCR[" + getPcrIndex() + "]\n"; description += "Index PCR[" + getPcrIndex() + "]\n";
description += "Event Type: 0x" + Long.toHexString(eventType) + " " + eventString(eventID); description += "Event Type: 0x" + Long.toHexString(eventType) + " " + eventString(eventID);
description += "\n"; description += "\n";
if (logFormat == 1) { // Digest if (hashName.compareToIgnoreCase("TPM_ALG_SHA1") == 0) { // Digest
description += "digest (SHA-1): " + Hex.encodeHexString(this.digest); description += "digest (SHA-1): " + Hex.encodeHexString(this.digest);
} else { } else if (hashName.compareToIgnoreCase("TPM_ALG_SHA256") == 0) { // Digest
description += "digest (SHA256): " + Hex.encodeHexString(this.digest); description += "digest (SHA256): " + Hex.encodeHexString(this.digest);
} else if (hashName.compareToIgnoreCase("TPM_ALG_SHA384") == 0) { // Digest
description += "digest (SHA384): " + Hex.encodeHexString(this.digest);
} else if (hashName.compareToIgnoreCase("TPM_ALG_SHA512") == 0) { // Digest
description += "digest (SHA512): " + Hex.encodeHexString(this.digest);
} else {
description += "Unsupported Hash Algorithm encoutered";
} }
if (eventID != UefiConstants.SIZE_4) { if (eventID != UefiConstants.SIZE_4) {
description += "\n"; description += "\n";

View File

@ -49,15 +49,16 @@ public class TpmPcrEvent1 extends TpmPcrEvent {
byte[] rawEventSize = new byte[UefiConstants.SIZE_4]; byte[] rawEventSize = new byte[UefiConstants.SIZE_4];
byte[] eventDigest = new byte[EvConstants.SHA1_LENGTH]; byte[] eventDigest = new byte[EvConstants.SHA1_LENGTH];
byte[] eventContent = null; byte[] eventContent = null;
int digestSize = EvConstants.SHA1_LENGTH;
int eventSize = 0; int eventSize = 0;
String hashName = "TPM_ALG_SHA1";
if (is.available() > UefiConstants.SIZE_32) { if (is.available() > UefiConstants.SIZE_32) {
is.read(rawIndex); is.read(rawIndex);
setPcrIndex(rawIndex); setPcrIndex(rawIndex);
is.read(rawType); is.read(rawType);
setEventType(rawType); setEventType(rawType);
is.read(eventDigest); is.read(eventDigest);
setEventDigest(eventDigest); setEventDigest(eventDigest, digestSize);
is.read(rawEventSize); is.read(rawEventSize);
eventSize = HexUtils.leReverseInt(rawEventSize); eventSize = HexUtils.leReverseInt(rawEventSize);
eventContent = new byte[eventSize]; eventContent = new byte[eventSize];
@ -78,7 +79,7 @@ public class TpmPcrEvent1 extends TpmPcrEvent {
offset += rawEventSize.length; offset += rawEventSize.length;
setEventData(event); setEventData(event);
//System.arraycopy(eventContent, 0, event, offset, eventContent.length); //System.arraycopy(eventContent, 0, event, offset, eventContent.length);
this.processEvent(event, eventContent, eventNumber); this.processEvent(event, eventContent, eventNumber, hashName);
} }
} }
} }

View File

@ -78,12 +78,14 @@ public class TpmPcrEvent2 extends TpmPcrEvent {
setDigestLength(EvConstants.SHA256_LENGTH); setDigestLength(EvConstants.SHA256_LENGTH);
setLogFormat(2); setLogFormat(2);
/** Event data. */ /** Event data. */
int eventDigestLength = 0;
String hashName = "";
byte[] event; byte[] event;
byte[] rawIndex = new byte[UefiConstants.SIZE_4]; byte[] rawIndex = new byte[UefiConstants.SIZE_4];
byte[] algCountBytes = new byte[UefiConstants.SIZE_4]; byte[] algCountBytes = new byte[UefiConstants.SIZE_4];
byte[] rawType = new byte[UefiConstants.SIZE_4]; byte[] rawType = new byte[UefiConstants.SIZE_4];
byte[] rawEventSize = new byte[UefiConstants.SIZE_4]; byte[] rawEventSize = new byte[UefiConstants.SIZE_4];
byte[] eventDigest = new byte[EvConstants.SHA256_LENGTH]; byte[] eventDigest = null;
byte[] eventContent = null; byte[] eventContent = null;
TcgTpmtHa hashAlg = null; TcgTpmtHa hashAlg = null;
int eventSize = 0; int eventSize = 0;
@ -99,10 +101,10 @@ public class TpmPcrEvent2 extends TpmPcrEvent {
// Process TPMT_HA, // Process TPMT_HA,
for (int i = 0; i < algCount; i++) { for (int i = 0; i < algCount; i++) {
hashAlg = new TcgTpmtHa(is); hashAlg = new TcgTpmtHa(is);
hashName = hashAlg.getHashName();
hashlist.add(hashAlg); hashlist.add(hashAlg);
if (hashAlg.getHashName().compareToIgnoreCase("TPM_ALG_SHA256") == 0) { eventDigest = new byte[hashAlg.getHashLength()];
setEventDigest(hashAlg.getDigest()); setEventDigest(hashAlg.getDigest(), hashAlg.getHashLength());
}
} }
is.read(rawEventSize); is.read(rawEventSize);
eventSize = HexUtils.leReverseInt(rawEventSize); eventSize = HexUtils.leReverseInt(rawEventSize);
@ -126,7 +128,8 @@ public class TpmPcrEvent2 extends TpmPcrEvent {
offset += rawEventSize.length; offset += rawEventSize.length;
//System.arraycopy(eventContent, 0, event, offset, eventContent.length); //System.arraycopy(eventContent, 0, event, offset, eventContent.length);
setEventData(event); setEventData(event);
this.processEvent(event, eventContent, eventNumber); //setDigestLength(eventDigestLength);
this.processEvent(event, eventContent, eventNumber, hashName);
} }
} }
} }

View File

@ -21,6 +21,8 @@ public final class EvConstants {
public static final int SHA1_LENGTH = 20; public static final int SHA1_LENGTH = 20;
/** Event Type (byte array). */ /** Event Type (byte array). */
public static final int SHA256_LENGTH = 32; public static final int SHA256_LENGTH = 32;
/** Event Type (byte array). */
public static final int SHA384_LENGTH = 48;
/** Each PCR bank holds 24 registers. */ /** Each PCR bank holds 24 registers. */
public static final int PCR_COUNT = 24; public static final int PCR_COUNT = 24;
// Event IDs // Event IDs

View File

@ -1,6 +1,6 @@
# Properties used to create JDBC connection # Properties used to create JDBC connection
# WARNING: DO NOT USE "disableSslHostnameVerification=true" FOR A REMOTE DATABASE # WARNING: DO NOT USE "disableSslHostnameVerification=true" FOR A REMOTE DATABASE
persistence.db.url = jdbc:mariadb://localhost/hirs_db?autoReconnect=true&useSSL=true&requireSSL=true&amp;enabledSslProtocolSuites=TLSv1&disableSslHostnameVerification=true persistence.db.url = jdbc:mariadb://localhost/hirs_db?autoReconnect=true&useSSL=true&requireSSL=true&amp;enabledSslProtocolSuites=TLSv1.2&disableSslHostnameVerification=true
persistence.db.username = hirs_db persistence.db.username = hirs_db
persistence.db.password = hirs_db persistence.db.password = hirs_db
persistence.db.driverClass = org.mariadb.jdbc.Driver persistence.db.driverClass = org.mariadb.jdbc.Driver

View File

@ -37,4 +37,5 @@ else
exit 1 exit 1
fi fi
mysql -u root < $DB_CREATE_SCRIPT mysql -fu root < $DB_CREATE_SCRIPT
mysql -fu root < /opt/hirs/scripts/common/secure_mysql.sql

View File

@ -0,0 +1,6 @@
UPDATE mysql.user SET Password=PASSWORD('root') WHERE User='root';
DELETE FROM mysql.user WHERE User='';
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
FLUSH PRIVILEGES

View File

@ -137,10 +137,10 @@ if [[ $1 = "server" ]]; then
VERCMP_STATUS=$? VERCMP_STATUS=$?
if [[ $VERCMP_STATUS -eq 0 ]] || [[ $VERCMP_STATUS -eq 12 ]]; then if [[ $VERCMP_STATUS -eq 0 ]] || [[ $VERCMP_STATUS -eq 12 ]]; then
# Tomcat v 6.0.38 or newer # Tomcat v 6.0.38 or newer
sed -i "s/.*<\/Service>/<Connector port=\"8443\" protocol=\"HTTP\/1.1\" compression=\"on\" compressionMinSize=\"2048\" compressableMimeType=\"text\/html, text\/xml\" SSLEnabled=\"true\" maxThreads=\"150\" scheme=\"https\" secure=\"true\" clientAuth=\"want\" sslProtocol=\"TLS\" sslEnabledProtocols=\"TLSv1.1,TLSv1.2\" ciphers=\"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA\" keystoreFile=\"${CA_CERT_DIR_ESCAPED}\/keyStore.jks\" keystorePass=\"$P12_PASSWORD\" truststoreFile=\"${CA_CERT_DIR_ESCAPED}\/TrustStore.jks\" truststorePass=\"password\" \/><\/Service>/" $CATALINA_HOME/conf/server.xml sed -i "s/.*<\/Service>/<Connector port=\"8443\" protocol=\"HTTP\/1.1\" compression=\"on\" compressionMinSize=\"2048\" compressableMimeType=\"text\/html, text\/xml\" SSLEnabled=\"true\" maxThreads=\"150\" scheme=\"https\" secure=\"true\" clientAuth=\"want\" sslProtocol=\"TLS\" sslEnabledProtocols=\"TLSv1.2\" ciphers=\"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384\" keystoreFile=\"${CA_CERT_DIR_ESCAPED}\/keyStore.jks\" keystorePass=\"$P12_PASSWORD\" truststoreFile=\"${CA_CERT_DIR_ESCAPED}\/TrustStore.jks\" truststorePass=\"password\" \/><\/Service>/" $CATALINA_HOME/conf/server.xml
elif [[ $VERCMP_STATUS -eq 11 ]]; then elif [[ $VERCMP_STATUS -eq 11 ]]; then
# Older than Tomcat 6.0.38 # Older than Tomcat 6.0.38
sed -i "s/.*<\/Service>/<Connector port=\"8443\" label=\"HIRS\" protocol=\"HTTP\/1.1\" compression=\"on\" compressionMinSize=\"2048\" compressableMimeType=\"text\/html, text\/xml\" SSLEnabled=\"true\" maxThreads=\"150\" scheme=\"https\" secure=\"true\" clientAuth=\"want\" sslProtocol=\"TLS\" protocols=\"TLSv1.1,TLSv1.2\" ciphers=\"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA\" SSLDisableCompression=\"true\" keystoreFile=\"${CA_CERT_DIR_ESCAPED}\/keyStore.jks\" keystorePass=\"$P12_PASSWORD\" truststoreFile=\"${CA_CERT_DIR_ESCAPED}\/TrustStore.jks\" truststorePass=\"password\" \/><\/Service>/" $CATALINA_HOME/conf/server.xml sed -i "s/.*<\/Service>/<Connector port=\"8443\" label=\"HIRS\" protocol=\"HTTP\/1.1\" compression=\"on\" compressionMinSize=\"2048\" compressableMimeType=\"text\/html, text\/xml\" SSLEnabled=\"true\" maxThreads=\"150\" scheme=\"https\" secure=\"true\" clientAuth=\"want\" sslProtocol=\"TLS\" protocols=\"TLSv1.2\" ciphers=\"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384\" SSLDisableCompression=\"true\" keystoreFile=\"${CA_CERT_DIR_ESCAPED}\/keyStore.jks\" keystorePass=\"$P12_PASSWORD\" truststoreFile=\"${CA_CERT_DIR_ESCAPED}\/TrustStore.jks\" truststorePass=\"password\" \/><\/Service>/" $CATALINA_HOME/conf/server.xml
else else
echo "Unknown rpmdev-vercmp exit code: ${VERCMP_STATUS}" echo "Unknown rpmdev-vercmp exit code: ${VERCMP_STATUS}"
exit 1 exit 1

View File

@ -65,11 +65,12 @@ buildscript {
// Produce packages // Produce packages
ospackage { ospackage {
def gitCommitHash = 'git rev-parse --verify --short HEAD'.execute().text.trim()
packageName = 'tcg_eventlog_tool' packageName = 'tcg_eventlog_tool'
os = LINUX os = LINUX
arch = NOARCH arch = X86_64
version = '2.1.0' version = '2.1.0'
release = '1' release = gitCommitHash
into '/opt/hirs/eventlog' into '/opt/hirs/eventlog'
user 'root' user 'root'
@ -104,7 +105,7 @@ ospackage {
details.file.name.endsWith('.md') details.file.name.endsWith('.md')
} }
into './' into './'
link("/usr/local/bin/elt", "/opt/hirs/eventlog/scripts/eventlog.sh", 0x755) link("/usr/bin/elt", "/opt/hirs/eventlog/scripts/eventlog.sh", 0x755)
} }
into('/tmp/') { into('/tmp/') {
@ -118,9 +119,9 @@ ospackage {
postInstall file('scripts/vendor-table.sh') postInstall file('scripts/vendor-table.sh')
buildRpm { buildRpm {
arch = I386 arch = X86_64
} }
buildDeb { buildDeb {
arch = I386 arch = X86_64
} }
} }

View File

@ -23,7 +23,7 @@ public class Commander {
private static final String PCR_STRING = "pcr"; private static final String PCR_STRING = "pcr";
private static final String VERIFY_STRING = "Verify"; private static final String VERIFY_STRING = "Verify";
private static final String VERSION_STRING = "version"; private static final String VERSION_STRING = "version";
private static final String VERSION_NUMBER = "1.0"; private static final String VERSION_NUMBER = "2.1";
private static final String REGEX = "[0-9]+"; private static final String REGEX = "[0-9]+";
private boolean hasArguments = false; private boolean hasArguments = false;
@ -63,7 +63,6 @@ public class Commander {
defualtArgs[0] = "-e"; defualtArgs[0] = "-e";
hasArguments = true; hasArguments = true;
parseArguments(defualtArgs); parseArguments(defualtArgs);
// printHelp("");
} }
} }
@ -75,15 +74,16 @@ public class Commander {
*/ */
public final void parseArguments(final String[] args) { public final void parseArguments(final String[] args) {
String tempValue; String tempValue;
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
tempValue = args[i]; tempValue = args[i];
if (bDone) {
break;
}
if (args.length == 0) { // Process default params if none were given if (args.length == 0) { // Process default params if none were given
bEventIds = true; bEventIds = true;
} else { } else {
switch (tempValue) { switch (tempValue) {
case FULL_COMMAND_PREFIX + CONTENT_STRING:
case FULL_COMMAND_PREFIX + EVENTIDS_STRING: case FULL_COMMAND_PREFIX + EVENTIDS_STRING:
case COMMAND_PREFIX + "e": case COMMAND_PREFIX + "e":
if (i < args.length - 1) { // Check for a filter following the -e if (i < args.length - 1) { // Check for a filter following the -e
@ -92,12 +92,16 @@ public class Commander {
if (eventFilter.matches(REGEX)) { if (eventFilter.matches(REGEX)) {
eventNumber = Integer.parseInt(eventFilter); eventNumber = Integer.parseInt(eventFilter);
} else { } else {
System.out.println("invalid parameter following -e: " + eventFilter); printHelp("Invalid parameter following -e: " + eventFilter
+ "\n");
bValidArgs = false;
bDone = true;
} }
} }
} }
bEventIds = true; bEventIds = true;
break; break;
case FULL_COMMAND_PREFIX + CONTENT_STRING:
case COMMAND_PREFIX + "ec": case COMMAND_PREFIX + "ec":
bContentHex = true; bContentHex = true;
break; break;
@ -109,10 +113,10 @@ public class Commander {
case COMMAND_PREFIX + "d": case COMMAND_PREFIX + "d":
if ((args.length < i + 2 + 1) || (args[i + 1].charAt(0) == '-') if ((args.length < i + 2 + 1) || (args[i + 1].charAt(0) == '-')
|| (args[i + 2].charAt(0) == '-')) { || (args[i + 2].charAt(0) == '-')) {
System.out.print("tcg_eventlog_tool command line error:" printHelp("tcg_eventlog_tool command line error:"
+ " 2 or 3 parameters needed for -diff.\n"); + " 2 parameters needed for -diff." + "\n");
System.out.print("usage: elt -d logFile1 logFile2 pcr#");
bValidArgs = false; bValidArgs = false;
bDone = true;
} else { } else {
inFile = args[i++ + 1]; inFile = args[i++ + 1];
inFile2 = args[i++ + 1]; inFile2 = args[i++ + 1];
@ -121,18 +125,36 @@ public class Commander {
break; break;
case FULL_COMMAND_PREFIX + FILE_STRING: case FULL_COMMAND_PREFIX + FILE_STRING:
case COMMAND_PREFIX + "f": case COMMAND_PREFIX + "f":
bFile = true; if (i == args.length - 1) {
inFile = args[++i]; printHelp("No output file specified with the " + tempValue
+ " option" + "\n");
bValidArgs = false;
bDone = true;
} else if (args[i + 1].charAt(0) == '-') {
printHelp("No output file specified with the " + tempValue
+ "option" + "\n");
bValidArgs = false;
bDone = true;
} else {
bFile = true;
inFile = args[++i];
}
break; break;
case FULL_COMMAND_PREFIX + OUTPUT_STRING: case FULL_COMMAND_PREFIX + OUTPUT_STRING:
case COMMAND_PREFIX + "o": case COMMAND_PREFIX + "o":
if (i < args.length - 1) { // Check for a filter following the -o if (i == args.length - 1) {
if (!args[i + 1].startsWith("-")) { printHelp("No output file specified with the " + tempValue
outFile = args[i++ + 1]; + " option" + "\n");
} else { bValidArgs = false;
System.out.print("no output file specified with -o option"); bDone = true;
bValidArgs = false; } else {
} outFile = args[i++ + 1];
if (outFile.isEmpty()) {
printHelp("No output file specified with the " + tempValue
+ "option" + "\n");
bValidArgs = false;
bDone = true;
}
} }
bOutput = true; bOutput = true;
break; break;
@ -144,7 +166,10 @@ public class Commander {
if (pcrFilter.matches(REGEX)) { if (pcrFilter.matches(REGEX)) {
pcrNumber = Integer.parseInt(pcrFilter); pcrNumber = Integer.parseInt(pcrFilter);
} else { } else {
System.out.println("invalid parameter following -p: " + pcrFilter); printHelp("Invalid parameter following -p: "
+ pcrFilter + "\n");
bValidArgs = false;
bDone = true;
} }
} }
} }
@ -168,11 +193,15 @@ public class Commander {
bHelp = true; bHelp = true;
break; break;
default: default:
printHelp(""); //System.out.print("Unknown option: " + tempValue + "\n");
bValidArgs = false; bValidArgs = false;
bDone = true;
printHelp("Unknown option: " + tempValue + "\n");
} }
} }
} }
checkForInvalidOptions();
checkDefaults();
} }
/** /**
@ -316,6 +345,41 @@ public class Commander {
public final int getPcrNumber() { public final int getPcrNumber() {
return pcrNumber; return pcrNumber;
} }
/**
* Setter for the input associated with the EventIds flag.
*/
public final void setEventIdsFlag() {
bEventIds = true;
}
/**
* Check for invalid option combinations.
* @return false is an invalid combination was found
*/
public final boolean checkForInvalidOptions() {
if (!bEventIds && (bEventHex || bContentHex)) {
bValidArgs = false;
} else if (bHex && (bEventHex || bContentHex)) {
bValidArgs = false;
} else {
bValidArgs = true;
}
return bValidArgs;
}
/**
* Check for situations where default values need to be set.
*/
public final void checkDefaults() {
if (bFile) {
if (!bHex && !bEventIds && !bContentHex && !bPCRs) {
bEventIds = true;
}
}
if (bOutput) {
if (!bHex && !bEventIds && !bContentHex && !bPCRs) {
bEventIds = true;
}
}
}
/** /**
* This method is used to inform the user of the allowed functionality of the program. * This method is used to inform the user of the allowed functionality of the program.
* @param message message caller specific message to print before listing the help. * @param message message caller specific message to print before listing the help.
@ -324,70 +388,52 @@ public class Commander {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
String os = System.getProperty("os.name").toLowerCase(); String os = System.getProperty("os.name").toLowerCase();
if ((message != null) && (!message.isEmpty())) { if ((message != null) && (!message.isEmpty())) {
sb.append("\n\n" + message); sb.append("\n" + message);
} }
sb.append("\nTCG Log Parser "); sb.append("\nTCG Log Parser ");
if (os.compareToIgnoreCase("linux") == 0) { if (os.compareToIgnoreCase("linux") == 0) {
sb.append("Usage: sh elt.sh [OPTION]...-f [FILE]...\n"); sb.append("Usage: elt [OPTION]... [OPTION]... and Options\n");
} else { } else {
sb.append("Usage: ./elt.ps1 [OPTION]...-f [FILE]...\n"); sb.append("Usage: ./elt.ps1 [OPTION]... [OPTION]...\n");
} }
sb.append("Options:\n" sb.append("\nOptions:\n"
+ " -f\t--file\t\t Use specific Event Log file. " + " -f\t--file\t\t Use a specific Event Log file. "
+ "\n\t\t\t Following parameter MUST be a path and file name." + "\n\t\t\t example: elt [-f|--file] /path/to/eventlogfile\n"
+ "\n\t\t\t The local Event Log file will be used if this option is not present." + " -e\t--event\t\t Display all event details for a specific event"
+ "\n\t\t\t Note: Access to the local Event Log may require admin privileges.\n" + "\n\t\t\t example: elt [-e|--event] 30"
+ " -e\t--event\t Display event descriptions (including event content) in " + "\n\t\t\t No event specified will default to all events"
+ "human readable form." + "\n\t\t\t example: elt [-e|--event]\n"
+ "\n\t\t\t Following optional parameter is a single event number used to filter" + " -ec\t--contenthex\t Include event content in hex format."
+ " the output." + " Only valid with -e option.\n"
+ "\n\t\t\t All events will be displayed if the optional parameter is not +" + " -ex\t--eventhex\t Include event only (no content) in hex format."
+ "provided.\n" + " Only valid with -e option.\n"
+ " -ec\t--contenthex\t Displays event content" + " -d\t--diff\t\t Compares two TCG Event Logs and displays events from second"
+ " in eventhex format when -event is used.\n" + " file that do not match."
+ " -ex\t--eventhex\t Displays event in hex format when -event is used.\n" + "\n\t\t\t example: elt [-d|--diff] /path/to/eventlogfile1 "
+ " -d\t--diff\t\t Compares two TCG Event Logs and outputs a list of events" + "/path/to/eventlogfile2\n"
+ " of the second log that differred.\n" + " -o\t--output\t Redirect output to a specified path/file."
+ " -o\t--output\t Output to a file. " + "\n\t\t\t example: elt [-o|--output] /path/to/outputfile\n"
+ "\n\t\t\t Following parameter MUST be a relative path and file name.\n" + " -p\t--pcr\t\t Display all expected PCR values calculated from the TCG Log "
+ " -p\t--pcr\t\t Output expected PCR value calculated from the " + "(for PCR Replay)."
+ "TCG Log (for PCR Replay)." + "\n\t\t\t Specify a PCR number to filter on a single PCR."
+ "\n\t\t\t Following parameter MAY be a PCR number used to specify a single pcr." + "\n\t\t\t example: elt [-p|--pcr] 5\n"
+ "\n\t\t\t No following parameters will display all PCRs.\n" + " -v\t--version\t Version info.\n"
+ " -v\t--version\t Parser Version.\n" + " -x\t--hex\t\t Event only (no content) in hex format."
// + " -V\t--Verify\t Attempts to verify the log file against values."
+ " -x\t--hex\t\t Displays event in hex format. Use with -ec to get content."
+ "\n\t\t\t Use -e -ec and -ex options to filter output."
+ "\n\t\t\t All output will be human readble form if not present."
+ "\n\n"); + "\n\n");
if (os.compareToIgnoreCase("linux") == 0) { if (os.compareToIgnoreCase("linux") == 0) {
sb.append("\nIf no FILE parameter is provided then the standard Linux TCGEventLog path " sb.append("\nTo run this tool it may require root privileges due to the permissions set "
+ "\n(/sys/kernel/security/tpm0/binary_bios_measurements) is used." + "on the event log file. \nRun without options to display all event details for "
+ "\n Note admin privileges may be required (e.g. use sudo when running the " + "/sys/kernel/security/tpm0/binary_bios_measurements. "
+ " script).\n" + "\nAll options must be separated by a space delimiter as concatenation of "
+ "All OPTIONS must be seperated by a space delimiter, no concatenation" + "options is currently not supported.\n"
+ " of OPTIONS is currently supported.\n"
+ "\nExamples: (run from the script directory)\n"
+ "1. Display all events from the binary_bios_measurements.bin test pattern:\n"
+ " sh elt.sh -f ../test/testdata/binary_bios_measurements_Dell_Fedora30.bin "
+ " -e\n"
+ "2. Display only the event with an index of 0 (e.g event that extend PCR 0):\n"
+ " sh scripts/elt.sh -f "
+ "../test/testdata/binary_bios_measurements_Dell_Fedora30.bin -p 0\n"
); );
} else { //windows } else { //windows
sb.append("\nIf no FILE parameter is provided then the " sb.append("\nIf no file parameter is provided then the "
+ "standard Windows TCGEventLog path (C:\\Windows\\Logs\\MeasuredBoot) is used" + "standard Windows TCGEventLog path (C:\\Windows\\Logs\\MeasuredBoot) is used"
+ "\nIf no parameter is given then the -e option will be used as default."
+ "\n Note admin privileges may be required (e.g. run as Administrator).\n" + "\n Note admin privileges may be required (e.g. run as Administrator).\n"
+ "All OPTIONS must be seperated by a space delimiter, " + "All OPTIONS must be seperated by a space delimiter, "
+ "no concatenation of OPTIONS is currently supported.\n" + "no concatenation of options is not supported.\n"
+ "\nExamples:(run from the script directory)\n"
+ "1. Display all events from the binary_bios_measurements.bin test pattern:\n"
+ " ./elt.ps1 -f "
+ "..\\test\\testdata\\binary_bios_measurements_Dell_Fedora30.bin -e\n"
+ "2. Display only the event with an index of 0 (e.g event that extend PCR 0):\n"
+ " ./elt.ps1 -f "
+ "..\\test\\testdata\\binary_bios_measurements_Dell_Fedora30.bin -p 0\n"
); );
} }
System.out.println(sb.toString()); System.out.println(sb.toString());

View File

@ -1,6 +1,5 @@
package hirs.tcg_eventlog; package hirs.tcg_eventlog;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -12,7 +11,6 @@ import java.security.cert.CertificateException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import hirs.tpm.eventlog.TCGEventLog; import hirs.tpm.eventlog.TCGEventLog;
import hirs.tpm.eventlog.TpmPcrEvent; import hirs.tpm.eventlog.TpmPcrEvent;
import hirs.utils.HexUtils; import hirs.utils.HexUtils;
@ -35,9 +33,10 @@ final class Main {
public static void main(final String[] args) { public static void main(final String[] args) {
commander = new Commander(args); commander = new Commander(args);
if (!commander.getValidityFlag()) { if (!commander.getValidityFlag()) {
System.out.print("Program exiting without processs due to issues with" System.out.print("\nProgram exiting without processs due to issues with"
+ " parameters provided."); + " parameters provided.\n");
System.exit(1); commander.printHelp("");
System.exit(0);
} }
if (commander.hasArguments()) { if (commander.hasArguments()) {
if (commander.getDoneFlag()) { if (commander.getDoneFlag()) {
@ -50,15 +49,14 @@ final class Main {
if (commander.getOutputFlag()) { if (commander.getOutputFlag()) {
try { try {
outputStream = new FileOutputStream(commander.getOutputFileName()); outputStream = new FileOutputStream(commander.getOutputFileName());
} catch (FileNotFoundException e) { System.out.print("Writing to output file: " + commander.getOutputFileName()
+ "\n");
} catch (Exception e) {
System.out.print("Error opening output file" + commander.getOutputFileName() System.out.print("Error opening output file" + commander.getOutputFileName()
+ "\nError was " + e.getMessage()); + "\nError was " + e.getMessage());
System.exit(1); System.exit(1);
} }
} }
if (commander.getFileFlag()) {
eventLog = openLog(commander.getInFileName());
}
if (commander.getContentFlag()) { if (commander.getContentFlag()) {
bContentFlag = true; bContentFlag = true;
} }
@ -91,10 +89,8 @@ final class Main {
} // End commander processing } // End commander processing
try { try {
if (eventLog == null) { eventLog = openLog(commander.getInFileName());
eventLog = openLog(""); // Main Event processing
}
// Main Event processing
TCGEventLog evLog = new TCGEventLog(eventLog, bEventFlag, bContentFlag, bHexEvent); TCGEventLog evLog = new TCGEventLog(eventLog, bEventFlag, bContentFlag, bHexEvent);
if (bPcrFlag) { if (bPcrFlag) {
String[] pcrs = evLog.getExpectedPCRValues(); String[] pcrs = evLog.getExpectedPCRValues();
@ -116,9 +112,8 @@ final class Main {
writeOut("\n----------------- End PCR Values ----------------- \n\n"); writeOut("\n----------------- End PCR Values ----------------- \n\n");
} }
} }
// General event log output // General event log output
if (bEventFlag) { if ((bEventFlag || bHexFlag) && !bPcrFlag) {
if (!bHexFlag) { if (!bHexFlag) {
if (evLog.isCryptoAgile()) { if (evLog.isCryptoAgile()) {
writeOut("\nEvent Log follows the \"Crypto Agile\" format and has " writeOut("\nEvent Log follows the \"Crypto Agile\" format and has "
@ -135,7 +130,7 @@ final class Main {
if ((commander.getPcrNumber() == event.getPcrIndex()) if ((commander.getPcrNumber() == event.getPcrIndex())
|| commander.getPcrNumber() == -1) { || commander.getPcrNumber() == -1) {
if (bHexFlag) { if (bHexFlag) {
if (bEventFlag || bHexEvent) { if (bHexFlag || bHexEvent) {
writeOut(HexUtils.byteArrayToHexString(event.getEvent()) writeOut(HexUtils.byteArrayToHexString(event.getEvent())
+ "\n"); + "\n");
} }
@ -178,7 +173,6 @@ final class Main {
boolean bDefault = false; boolean bDefault = false;
bHexFlag = commander.getHexFlag(); bHexFlag = commander.getHexFlag();
try { try {
if (fileName.isEmpty()) { if (fileName.isEmpty()) {
if (os.compareToIgnoreCase("linux") == 0) { // need to find Windows path if (os.compareToIgnoreCase("linux") == 0) { // need to find Windows path
fName = "/sys/kernel/security/tpm0/binary_bios_measurements"; fName = "/sys/kernel/security/tpm0/binary_bios_measurements";
@ -196,9 +190,9 @@ final class Main {
} catch (Exception e) { } catch (Exception e) {
String error = "Error reading event Log File: " + e.toString(); String error = "Error reading event Log File: " + e.toString();
if (bDefault) { if (bDefault) {
error += "\nTry using the -f option to specify an Event Log File"; error += "\nTry using the -f option to specify an Event Log File\n";
} }
writeOut(error); System.out.print(error);
System.exit(1); System.exit(1);
} }
return rawLog; return rawLog;
@ -218,6 +212,8 @@ final class Main {
System.out.print(dataNoNull); // output to the console System.out.print(dataNoNull); // output to the console
} }
} catch (IOException e) { } catch (IOException e) {
System.out.print("Error writing to output file: " + commander.getOutputFileName()
+ "\n error was: " + e.toString() + "\n");
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -247,7 +243,8 @@ final class Main {
ArrayList<TpmPcrEvent> errors = diffEventLogs(eventLog1.getEventList(), ArrayList<TpmPcrEvent> errors = diffEventLogs(eventLog1.getEventList(),
eventLog2.getEventList(), commander.getPcrNumber()); eventLog2.getEventList(), commander.getPcrNumber());
if (errors.isEmpty() && !bHexFlag) { if (errors.isEmpty() && !bHexFlag) {
sb.append("\nEvent Log " + logFileName1 + " MATCHED EventLog " + logFileName2); sb.append("\nEvent Log " + logFileName1 + " MATCHED EventLog " + logFileName2
+ "\n");
} else { } else {
if (!errors.isEmpty() && !bHexFlag) { if (!errors.isEmpty() && !bHexFlag) {
sb.append("\nEvent Log " + logFileName1 sb.append("\nEvent Log " + logFileName1
@ -332,4 +329,15 @@ final class Main {
} }
return matchFound; return matchFound;
} }
/**
* Diagnostic method for detecting flag settings.
*/
public static void dumpFlags() {
System.out.print("Event Flag is " + commander.getEventIdsFlag() + "\n");
System.out.print("Hex Flag is " + commander.getEventHexFlag() + "\n");
System.out.print("Context Flag is " + commander.getContentFlag() + "\n");
System.out.print("PCR Flag is " + commander.getPCRFlag() + "\n");
System.out.print("Output File Flag is " + commander.getFileFlag() + "\n");
System.out.print("Output Flag is " + commander.getOutputFlag() + "\n");
}
} }

View File

@ -49,6 +49,7 @@ public class Main {
String jksTruststoreFile = commander.getTruststoreFile(); String jksTruststoreFile = commander.getTruststoreFile();
String certificateFile = commander.getPublicCertificate(); String certificateFile = commander.getPublicCertificate();
String privateKeyFile = commander.getPrivateKeyFile(); String privateKeyFile = commander.getPrivateKeyFile();
boolean embeddedCert = commander.isEmbedded();
boolean defaultKey = commander.isDefaultKey(); boolean defaultKey = commander.isDefaultKey();
String rimEventLog = commander.getRimEventLog(); String rimEventLog = commander.getRimEventLog();
switch (createType) { switch (createType) {
@ -63,6 +64,9 @@ public class Main {
gateway.setDefaultCredentials(false); gateway.setDefaultCredentials(false);
gateway.setPemCertificateFile(certificateFile); gateway.setPemCertificateFile(certificateFile);
gateway.setPemPrivateKeyFile(privateKeyFile); gateway.setPemPrivateKeyFile(privateKeyFile);
if (embeddedCert) {
gateway.setEmbeddedCert(true);
}
} else if (defaultKey){ } else if (defaultKey){
gateway.setDefaultCredentials(true); gateway.setDefaultCredentials(true);
gateway.setJksTruststoreFile(SwidTagConstants.DEFAULT_KEYSTORE_FILE); gateway.setJksTruststoreFile(SwidTagConstants.DEFAULT_KEYSTORE_FILE);

View File

@ -15,7 +15,7 @@ public class SwidTagConstants {
public static final String DEFAULT_KEYSTORE_FILE = "/opt/hirs/rimtool/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_KEYSTORE_PASSWORD = "password";
public static final String DEFAULT_PRIVATE_KEY_ALIAS = "selfsigned"; public static final String DEFAULT_PRIVATE_KEY_ALIAS = "selfsigned";
public static final String DEFAULT_ATTRIBUTES_FILE = "rim_fields.json"; public static final String DEFAULT_ATTRIBUTES_FILE = "/opt/hirs/rimtool/rim_fields.json";
public static final String DEFAULT_ENGLISH = "en"; public static final String DEFAULT_ENGLISH = "en";
public static final String SIGNATURE_ALGORITHM_RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; public static final String SIGNATURE_ALGORITHM_RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";

View File

@ -54,6 +54,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.KeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
@ -77,6 +78,7 @@ public class SwidTagGateway {
private String jksTruststoreFile; private String jksTruststoreFile;
private String pemPrivateKeyFile; private String pemPrivateKeyFile;
private String pemCertificateFile; private String pemCertificateFile;
private boolean embeddedCert;
private String rimEventLog; private String rimEventLog;
private String errorRequiredFields; private String errorRequiredFields;
@ -90,6 +92,7 @@ public class SwidTagGateway {
attributesFile = SwidTagConstants.DEFAULT_ATTRIBUTES_FILE; attributesFile = SwidTagConstants.DEFAULT_ATTRIBUTES_FILE;
defaultCredentials = true; defaultCredentials = true;
pemCertificateFile = ""; pemCertificateFile = "";
embeddedCert = false;
rimEventLog = ""; rimEventLog = "";
errorRequiredFields = ""; errorRequiredFields = "";
} catch (JAXBException e) { } catch (JAXBException e) {
@ -102,7 +105,7 @@ public class SwidTagGateway {
* *
* @param attributesFile * @param attributesFile
*/ */
public void setAttributesFile(String attributesFile) { public void setAttributesFile(final String attributesFile) {
this.attributesFile = attributesFile; this.attributesFile = attributesFile;
} }
@ -112,7 +115,7 @@ public class SwidTagGateway {
* @param defaultCredentials * @param defaultCredentials
* @return * @return
*/ */
public void setDefaultCredentials(boolean defaultCredentials) { public void setDefaultCredentials(final boolean defaultCredentials) {
this.defaultCredentials = defaultCredentials; this.defaultCredentials = defaultCredentials;
} }
@ -121,7 +124,7 @@ public class SwidTagGateway {
* *
* @param jksTruststoreFile * @param jksTruststoreFile
*/ */
public void setJksTruststoreFile(String jksTruststoreFile) { public void setJksTruststoreFile(final String jksTruststoreFile) {
this.jksTruststoreFile = jksTruststoreFile; this.jksTruststoreFile = jksTruststoreFile;
} }
@ -130,7 +133,7 @@ public class SwidTagGateway {
* *
* @param pemPrivateKeyFile * @param pemPrivateKeyFile
*/ */
public void setPemPrivateKeyFile(String pemPrivateKeyFile) { public void setPemPrivateKeyFile(final String pemPrivateKeyFile) {
this.pemPrivateKeyFile = pemPrivateKeyFile; this.pemPrivateKeyFile = pemPrivateKeyFile;
} }
@ -139,16 +142,25 @@ public class SwidTagGateway {
* *
* @param pemCertificateFile * @param pemCertificateFile
*/ */
public void setPemCertificateFile(String pemCertificateFile) { public void setPemCertificateFile(final String pemCertificateFile) {
this.pemCertificateFile = pemCertificateFile; this.pemCertificateFile = pemCertificateFile;
} }
/**
* Setter to embed certificate file in signature block
*
* @param embeddedCert
*/
public void setEmbeddedCert(final boolean embeddedCert) {
this.embeddedCert = embeddedCert;
}
/** /**
* Setter for event log support RIM * Setter for event log support RIM
* *
* @param rimEventLog * @param rimEventLog
*/ */
public void setRimEventLog(String rimEventLog) { public void setRimEventLog(final String rimEventLog) {
this.rimEventLog = rimEventLog; this.rimEventLog = rimEventLog;
} }
@ -224,7 +236,7 @@ public class SwidTagGateway {
* *
* @param swidTag * @param swidTag
*/ */
public void writeSwidTagFile(Document swidTag, String output) { public void writeSwidTagFile(final Document swidTag, final String output) {
try { try {
TransformerFactory tf = TransformerFactory.newInstance(); TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer(); Transformer transformer = tf.newTransformer();
@ -252,7 +264,7 @@ public class SwidTagGateway {
* @param jsonObject the Properties object containing parameters from file * @param jsonObject the Properties object containing parameters from file
* @return SoftwareIdentity object created from the properties * @return SoftwareIdentity object created from the properties
*/ */
private SoftwareIdentity createSwidTag(JsonObject jsonObject) { private SoftwareIdentity createSwidTag(final JsonObject jsonObject) {
SoftwareIdentity swidTag = objectFactory.createSoftwareIdentity(); SoftwareIdentity swidTag = objectFactory.createSoftwareIdentity();
if (jsonObject == null) { if (jsonObject == null) {
errorRequiredFields += SwidTagConstants.SOFTWARE_IDENTITY + ", "; errorRequiredFields += SwidTagConstants.SOFTWARE_IDENTITY + ", ";
@ -289,7 +301,7 @@ public class SwidTagGateway {
* @param jsonObject the Properties object containing parameters from file * @param jsonObject the Properties object containing parameters from file
* @return Entity object created from the properties * @return Entity object created from the properties
*/ */
private Entity createEntity(JsonObject jsonObject) { private Entity createEntity(final JsonObject jsonObject) {
boolean isTagCreator = false; boolean isTagCreator = false;
Entity entity = objectFactory.createEntity(); Entity entity = objectFactory.createEntity();
if (jsonObject == null) { if (jsonObject == null) {
@ -332,7 +344,7 @@ public class SwidTagGateway {
* @param jsonObject the Properties object containing parameters from file * @param jsonObject the Properties object containing parameters from file
* @return Link element created from the properties * @return Link element created from the properties
*/ */
private Link createLink(JsonObject jsonObject) { private Link createLink(final JsonObject jsonObject) {
Link link = objectFactory.createLink(); Link link = objectFactory.createLink();
String href = jsonObject.getString(SwidTagConstants.HREF, ""); String href = jsonObject.getString(SwidTagConstants.HREF, "");
if (!href.isEmpty()) { if (!href.isEmpty()) {
@ -353,7 +365,7 @@ public class SwidTagGateway {
* @param jsonObject the Properties object containing parameters from file * @param jsonObject the Properties object containing parameters from file
* @return the Meta element created from the properties * @return the Meta element created from the properties
*/ */
private SoftwareMeta createSoftwareMeta(JsonObject jsonObject) { private SoftwareMeta createSoftwareMeta(final JsonObject jsonObject) {
SoftwareMeta softwareMeta = objectFactory.createSoftwareMeta(); SoftwareMeta softwareMeta = objectFactory.createSoftwareMeta();
Map<QName, String> attributes = softwareMeta.getOtherAttributes(); Map<QName, String> attributes = softwareMeta.getOtherAttributes();
addNonNullAttribute(attributes, SwidTagConstants._COLLOQUIAL_VERSION, addNonNullAttribute(attributes, SwidTagConstants._COLLOQUIAL_VERSION,
@ -402,7 +414,7 @@ public class SwidTagGateway {
* @param jsonObject the Properties object containing parameters from file * @param jsonObject the Properties object containing parameters from file
* @return the Payload object created * @return the Payload object created
*/ */
private ResourceCollection createPayload(JsonObject jsonObject) { private ResourceCollection createPayload(final JsonObject jsonObject) {
ResourceCollection payload = objectFactory.createResourceCollection(); ResourceCollection payload = objectFactory.createResourceCollection();
Map<QName, String> attributes = payload.getOtherAttributes(); Map<QName, String> attributes = payload.getOtherAttributes();
if (jsonObject == null) { if (jsonObject == null) {
@ -425,7 +437,7 @@ public class SwidTagGateway {
* @param jsonObject the Properties object containing parameters from file * @param jsonObject the Properties object containing parameters from file
* @return Directory object created from the properties * @return Directory object created from the properties
*/ */
private Directory createDirectory(JsonObject jsonObject) { private Directory createDirectory(final JsonObject jsonObject) {
Directory directory = objectFactory.createDirectory(); Directory directory = objectFactory.createDirectory();
directory.setName(jsonObject.getString(SwidTagConstants.NAME, "")); directory.setName(jsonObject.getString(SwidTagConstants.NAME, ""));
Map<QName, String> attributes = directory.getOtherAttributes(); Map<QName, String> attributes = directory.getOtherAttributes();
@ -497,7 +509,8 @@ public class SwidTagGateway {
* @param key * @param key
* @param value * @param value
*/ */
private void addNonNullAttribute(Map<QName, String> attributes, QName key, String value) { private void addNonNullAttribute(final Map<QName, String> attributes,
final QName key, String value) {
if (!value.isEmpty()) { if (!value.isEmpty()) {
attributes.put(key, value); attributes.put(key, value);
} }
@ -514,13 +527,16 @@ public class SwidTagGateway {
Reference reference = sigFactory.newReference( Reference reference = sigFactory.newReference(
"", "",
sigFactory.newDigestMethod(DigestMethod.SHA256, null), sigFactory.newDigestMethod(DigestMethod.SHA256, null),
Collections.singletonList(sigFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)), Collections.singletonList(sigFactory.newTransform(Transform.ENVELOPED,
(TransformParameterSpec) null)),
null, null,
null null
); );
SignedInfo signedInfo = sigFactory.newSignedInfo( SignedInfo signedInfo = sigFactory.newSignedInfo(
sigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), sigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
sigFactory.newSignatureMethod(SwidTagConstants.SIGNATURE_ALGORITHM_RSA_SHA256, null), (C14NMethodParameterSpec) null),
sigFactory.newSignatureMethod(SwidTagConstants.SIGNATURE_ALGORITHM_RSA_SHA256,
null),
Collections.singletonList(reference) Collections.singletonList(reference)
); );
List<XMLStructure> keyInfoElements = new ArrayList<XMLStructure>(); List<XMLStructure> keyInfoElements = new ArrayList<XMLStructure>();
@ -537,11 +553,15 @@ public class SwidTagGateway {
cp.parsePEMCredentials(pemCertificateFile, pemPrivateKeyFile); cp.parsePEMCredentials(pemCertificateFile, pemPrivateKeyFile);
X509Certificate certificate = cp.getCertificate(); X509Certificate certificate = cp.getCertificate();
privateKey = cp.getPrivateKey(); privateKey = cp.getPrivateKey();
ArrayList<Object> x509Content = new ArrayList<Object>(); if (embeddedCert) {
x509Content.add(certificate.getSubjectX500Principal().getName()); ArrayList<Object> x509Content = new ArrayList<Object>();
x509Content.add(certificate); x509Content.add(certificate.getSubjectX500Principal().getName());
X509Data data = kiFactory.newX509Data(x509Content); x509Content.add(certificate);
keyInfoElements.add(data); X509Data data = kiFactory.newX509Data(x509Content);
keyInfoElements.add(data);
} else {
keyInfoElements.add(kiFactory.newKeyValue(certificate.getPublicKey()));
}
} }
KeyInfo keyinfo = kiFactory.newKeyInfo(keyInfoElements); KeyInfo keyinfo = kiFactory.newKeyInfo(keyInfoElements);
@ -563,6 +583,9 @@ public class SwidTagGateway {
System.out.println("Error marshaling signed swidtag: " + e.getMessage()); System.out.println("Error marshaling signed swidtag: " + e.getMessage());
} catch (MarshalException | XMLSignatureException e) { } catch (MarshalException | XMLSignatureException e) {
System.out.println("Error while signing SoftwareIdentity: " + e.getMessage()); System.out.println("Error while signing SoftwareIdentity: " + e.getMessage());
} catch (KeyException e) {
System.out.println("Public key algorithm not recognized or supported: "
+ e.getMessage());
} }
return doc; return doc;

View File

@ -24,6 +24,7 @@ import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.XMLSignatureFactory; import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMValidateContext; import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo; import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import javax.xml.crypto.dsig.keyinfo.X509Data; import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.transform.Source; import javax.xml.transform.Source;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
@ -59,6 +60,7 @@ public class SwidTagValidator {
private String rimEventLog; private String rimEventLog;
private String certificateFile; private String certificateFile;
private String trustStoreFile; private String trustStoreFile;
private List<X509Certificate> trustStore;
/** /**
* Ensure that BouncyCastle is configured as a javax.security.Security provider, as this * Ensure that BouncyCastle is configured as a javax.security.Security provider, as this
@ -157,40 +159,49 @@ public class SwidTagValidator {
DOMValidateContext context; DOMValidateContext context;
CredentialParser cp = new CredentialParser(); CredentialParser cp = new CredentialParser();
X509Certificate signingCert = null; X509Certificate signingCert = null;
List<X509Certificate> trustStore = cp.parseCertsFromPEM(trustStoreFile); trustStore = cp.parseCertsFromPEM(trustStoreFile);
X509KeySelector keySelector = new X509KeySelector();
NodeList nodes = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); NodeList nodes = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
if (nodes.getLength() == 0) { if (nodes.getLength() == 0) {
throw new Exception("Signature element not found!"); throw new Exception("Signature element not found!");
}
NodeList embeddedCert = doc.getElementsByTagName("X509Certificate");
if (embeddedCert.getLength() > 0) {
context = new DOMValidateContext(new X509KeySelector(), nodes.item(0));
signingCert = cp.parseCertFromPEMString(embeddedCert.item(0).getTextContent());
} else { } else {
String skId = doc.getElementsByTagName("KeyName").item(0).getTextContent(); context = new DOMValidateContext(keySelector, nodes.item(0));
for (X509Certificate trustedCert : trustStore) { }
String trustedSkId = cp.getCertificateSubjectKeyIdentifier(trustedCert); NodeList keyName = doc.getElementsByTagName("KeyName");
if (skId.equals(trustedSkId)) { if (keyName.getLength() > 0) {
signingCert = trustedCert; String skId = keyName.item(0).getTextContent();
break; if (skId != null && !skId.isEmpty()) {
for (X509Certificate trustedCert : trustStore) {
String trustedSkId = cp.getCertificateSubjectKeyIdentifier(trustedCert);
if (skId.equals(trustedSkId)) {
signingCert = trustedCert;
break;
}
} }
} if (signingCert != null) {
if (signingCert == null) { context = new DOMValidateContext(signingCert.getPublicKey(),
System.out.println("Issuer certificate with subject key identifier = " nodes.item(0));
+ skId + " not found"); } else {
System.out.println("Issuer certificate with subject key identifier = "
+ skId + " not found");
System.exit(1);
}
} else {
System.out.println("Base RIM must have a non-empty, non-null " +
"Subject Key Identifier (SKID) in the <KeyName> element");
System.exit(1); System.exit(1);
} }
context = new DOMValidateContext(signingCert.getPublicKey(), nodes.item(0));
} }
cp.setCertificate(signingCert);
System.out.println(cp.getCertificateAuthorityInfoAccess());
XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM"); XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
XMLSignature signature = sigFactory.unmarshalXMLSignature(context); XMLSignature signature = sigFactory.unmarshalXMLSignature(context);
boolean signatureIsValid = signature.validate(context); boolean signatureIsValid = signature.validate(context);
boolean certChainIsValid = validateCertChain(signingCert, trustStore);
System.out.println("Signature validity: " + signatureIsValid); System.out.println("Signature validity: " + signatureIsValid);
System.out.println("Cert chain validity: " + certChainIsValid); if (signingCert == null) {
return signatureIsValid && certChainIsValid; signingCert = keySelector.getSigningCert();
}
cp.setCertificate(signingCert);
System.out.println(System.lineSeparator() + cp.getCertificateAuthorityInfoAccess());
return signatureIsValid;
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
System.out.println("Error parsing truststore: " + e.getMessage()); System.out.println("Error parsing truststore: " + e.getMessage());
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
@ -207,112 +218,21 @@ public class SwidTagValidator {
return false; return false;
} }
/**
* This method validates the cert chain for a given certificate. The truststore is iterated
* over until a root CA is found, otherwise an error is returned.
* @param cert the certificate at the start of the chain
* @param trustStore from which to find the chain of intermediate and root CAs
* @return true if the chain is valid
* @throws Exception if a valid chain is not found in the truststore
*/
private boolean validateCertChain(final X509Certificate cert,
final List<X509Certificate> trustStore)
throws Exception {
if (cert == null || trustStore == null) {
throw new Exception("Null certificate or truststore received");
} else if (trustStore.size() == 0) {
throw new Exception("Truststore is empty");
}
final String INT_CA_ERROR = "Intermediate CA found, searching for root CA";
String errorMessage = "";
X509Certificate startOfChain = cert;
do {
for (X509Certificate trustedCert : trustStore) {
boolean isIssuer = areYouMyIssuer(startOfChain, trustedCert);
boolean isSigner = areYouMySigner(startOfChain, trustedCert);
if (isIssuer && isSigner) {
if (isSelfSigned(trustedCert)) {
return true;
} else {
startOfChain = trustedCert;
errorMessage = INT_CA_ERROR;
break;
}
} else {
if (!isIssuer) {
errorMessage = "Issuer cert not found";
} else if (!isSigner) {
errorMessage = "Signing cert not found";
}
}
}
} while (errorMessage.equals(INT_CA_ERROR));
throw new Exception("Error while validating cert chain: " + errorMessage);
}
/**
* This method checks if cert's issuerDN matches issuer's subjectDN.
* @param cert the signed certificate
* @param issuer the signing certificate
* @return true if they match, false if not
* @throws Exception if either argument is null
*/
private boolean areYouMyIssuer(final X509Certificate cert, final X509Certificate issuer)
throws Exception {
if (cert == null || issuer == null) {
throw new Exception("Cannot verify issuer, null certificate received");
}
X500Principal issuerDN = new X500Principal(cert.getIssuerX500Principal().getName());
return issuer.getSubjectX500Principal().equals(issuerDN);
}
/**
* This method checks if cert's signature matches signer's public key.
* @param cert the signed certificate
* @param signer the signing certificate
* @return true if they match
* @throws Exception if an error occurs or there is no match
*/
private boolean areYouMySigner(final X509Certificate cert, final X509Certificate signer)
throws Exception {
if (cert == null || signer == null) {
throw new Exception("Cannot verify signature, null certificate received");
}
try {
cert.verify(signer.getPublicKey(), BouncyCastleProvider.PROVIDER_NAME);
return true;
} catch (NoSuchAlgorithmException e) {
throw new Exception("Signing algorithm in signing cert not supported");
} catch (InvalidKeyException e) {
throw new Exception("Signing certificate key does not match signature");
} catch (NoSuchProviderException e) {
throw new Exception("Error with BouncyCastleProvider: " + e.getMessage());
} catch (SignatureException e) {
String error = "Error with signature: " + e.getMessage()
+ System.lineSeparator()
+ "Certificate needed for verification is missing: "
+ signer.getSubjectX500Principal().getName();
throw new Exception(error);
} catch (CertificateException e) {
throw new Exception("Encoding error: " + e.getMessage());
}
}
/**
* This method checks if a given certificate is self signed or not.
* @param cert the cert to check
* @return true if self signed, false if not
*/
private boolean isSelfSigned(final X509Certificate cert) {
return cert.getIssuerX500Principal().equals(cert.getSubjectX500Principal());
}
/** /**
* This internal class handles parsing the public key from a KeyInfo element. * This internal class handles parsing the public key from a KeyInfo element.
*/ */
public class X509KeySelector extends KeySelector { public class X509KeySelector extends KeySelector {
PublicKey publicKey;
X509Certificate signingCert;
public PublicKey getPublicKey() {
return publicKey;
}
public X509Certificate getSigningCert() {
return signingCert;
}
/** /**
* This method extracts a public key from either an X509Certificate element * This method extracts a public key from either an X509Certificate element
* or a KeyValue element. If the public key's algorithm matches the declared * or a KeyValue element. If the public key's algorithm matches the declared
@ -338,12 +258,41 @@ public class SwidTagValidator {
while (dataItr.hasNext()) { while (dataItr.hasNext()) {
Object object = dataItr.next(); Object object = dataItr.next();
if (object instanceof X509Certificate) { if (object instanceof X509Certificate) {
final PublicKey publicKey = ((X509Certificate) object).getPublicKey(); X509Certificate embeddedCert = (X509Certificate) object;
if (areAlgorithmsEqual(algorithm.getAlgorithm(), publicKey.getAlgorithm())) { try {
return new SwidTagValidator.X509KeySelector.RIMKeySelectorResult(publicKey); if (isCertChainValid(embeddedCert)) {
publicKey = ((X509Certificate) embeddedCert).getPublicKey();
signingCert = embeddedCert;
System.out.println("Certificate chain validity: true");
}
} catch (Exception e) {
System.out.println("Certificate chain invalid: "
+ e.getMessage());
} }
} }
} }
} else if (element instanceof KeyValue) {
try {
PublicKey pk = ((KeyValue) element).getPublicKey();
if (isPublicKeyTrusted(pk)) {
publicKey = pk;
try {
System.out.println("Certificate chain validity: "
+ isCertChainValid(signingCert));
} catch (Exception e) {
System.out.println("Certificate chain invalid: "
+ e.getMessage());
}
}
} catch (KeyException e) {
System.out.println("Unable to convert KeyValue data to PK.");
}
}
if (publicKey != null) {
if (areAlgorithmsEqual(algorithm.getAlgorithm(), publicKey.getAlgorithm())) {
return new
SwidTagValidator.X509KeySelector.RIMKeySelectorResult(publicKey);
}
} }
} }
throw new KeySelectorException("No key found!"); throw new KeySelectorException("No key found!");
@ -360,6 +309,123 @@ public class SwidTagValidator {
&& name.equalsIgnoreCase("RSA"); && name.equalsIgnoreCase("RSA");
} }
/**
* This method validates the cert chain for a given certificate. The truststore is iterated
* over until a root CA is found, otherwise an error is returned.
* @param cert the certificate at the start of the chain
* @return true if the chain is valid
* @throws Exception if a valid chain is not found in the truststore
*/
private boolean isCertChainValid(final X509Certificate cert)
throws Exception {
if (cert == null || trustStore == null) {
throw new Exception("Null certificate or truststore received");
} else if (trustStore.size() == 0) {
throw new Exception("Truststore is empty");
}
final String INT_CA_ERROR = "Intermediate CA found, searching for root CA";
String errorMessage = "";
X509Certificate startOfChain = cert;
do {
for (X509Certificate trustedCert : trustStore) {
boolean isIssuer = areYouMyIssuer(startOfChain, trustedCert);
boolean isSigner = areYouMySigner(startOfChain, trustedCert);
if (isIssuer && isSigner) {
if (isSelfSigned(trustedCert)) {
return true;
} else {
startOfChain = trustedCert;
errorMessage = INT_CA_ERROR;
break;
}
} else {
if (!isIssuer) {
errorMessage = "Issuer cert not found";
} else if (!isSigner) {
errorMessage = "Signing cert not found";
}
}
}
} while (errorMessage.equals(INT_CA_ERROR));
throw new Exception("Error while validating cert chain: " + errorMessage);
}
/**
* This method checks if cert's issuerDN matches issuer's subjectDN.
* @param cert the signed certificate
* @param issuer the signing certificate
* @return true if they match, false if not
* @throws Exception if either argument is null
*/
private boolean areYouMyIssuer(final X509Certificate cert, final X509Certificate issuer)
throws Exception {
if (cert == null || issuer == null) {
throw new Exception("Cannot verify issuer, null certificate received");
}
X500Principal issuerDN = new X500Principal(cert.getIssuerX500Principal().getName());
return issuer.getSubjectX500Principal().equals(issuerDN);
}
/**
* This method checks if cert's signature matches signer's public key.
* @param cert the signed certificate
* @param signer the signing certificate
* @return true if they match
* @throws Exception if an error occurs or there is no match
*/
private boolean areYouMySigner(final X509Certificate cert, final X509Certificate signer)
throws Exception {
if (cert == null || signer == null) {
throw new Exception("Cannot verify signature, null certificate received");
}
try {
cert.verify(signer.getPublicKey(), BouncyCastleProvider.PROVIDER_NAME);
return true;
} catch (NoSuchAlgorithmException e) {
throw new Exception("Signing algorithm in signing cert not supported");
} catch (InvalidKeyException e) {
throw new Exception("Signing certificate key does not match signature");
} catch (NoSuchProviderException e) {
throw new Exception("Error with BouncyCastleProvider: " + e.getMessage());
} catch (SignatureException e) {
String error = "Error with signature: " + e.getMessage()
+ System.lineSeparator()
+ "Certificate needed for verification is missing: "
+ signer.getSubjectX500Principal().getName();
throw new Exception(error);
} catch (CertificateException e) {
throw new Exception("Encoding error: " + e.getMessage());
}
}
/**
* This method checks if a given certificate is self signed or not.
* @param cert the cert to check
* @return true if self signed, false if not
*/
private boolean isSelfSigned(final X509Certificate cert) {
return cert.getIssuerX500Principal().equals(cert.getSubjectX500Principal());
}
/**
* This method compares a public key against those in the truststore.
* @param pk a public key
* @return true if pk is found in the trust store, false otherwise
*/
private boolean isPublicKeyTrusted(final PublicKey pk) {
for (X509Certificate trustedCert : trustStore) {
if (Arrays.equals(trustedCert.getPublicKey().getEncoded(),
pk.getEncoded())) {
signingCert = trustedCert;
return true;
}
}
return false;
}
private class RIMKeySelectorResult implements KeySelectorResult { private class RIMKeySelectorResult implements KeySelectorResult {
private Key key; private Key key;

View File

@ -36,10 +36,13 @@ public class Commander {
description = "The public key certificate to embed in the base RIM created by " description = "The public key certificate to embed in the base RIM created by "
+ "this tool.") + "this tool.")
private String publicCertificate = ""; private String publicCertificate = "";
@Parameter(names = {"-d", "--default-key"}, @Parameter(names = {"-e", "--embed-cert"}, order = 7,
description = "Embed the provided certificate in the signed swidtag.")
private boolean embedded = false;
@Parameter(names = {"-d", "--default-key"}, order = 8,
description = "Use default signing credentials.") description = "Use default signing credentials.")
private boolean defaultKey = false; private boolean defaultKey = false;
@Parameter(names = {"-l", "--rimel <path>"}, order = 7, @Parameter(names = {"-l", "--rimel <path>"}, order = 9,
description = "The TCG eventlog file to use as a support RIM.") description = "The TCG eventlog file to use as a support RIM.")
private String rimEventLog = ""; private String rimEventLog = "";
@ -73,6 +76,8 @@ public class Commander {
return publicCertificate; return publicCertificate;
} }
public boolean isEmbedded() { return embedded; }
public boolean isDefaultKey() { return defaultKey; } public boolean isDefaultKey() { return defaultKey; }
public String getRimEventLog() { return rimEventLog; } public String getRimEventLog() { return rimEventLog; }
@ -82,11 +87,12 @@ public class Commander {
sb.append("Create a base RIM using the values in attributes.json; " + sb.append("Create a base RIM using the values in attributes.json; " +
"sign it with the default keystore; "); "sign it with the default keystore; ");
sb.append("and write the data to base_rim.swidtag:\n\n"); sb.append("and write the data to base_rim.swidtag:\n\n");
sb.append("\t\t-c base -a attributes.json -d -l support_rim.bin -o base_rim.swidtag\n\n\n"); sb.append("\t\t-c base -a attributes.json -d -l support_rim.bin -o base_rim.swidtag" +
"\n\n\n");
sb.append("Create a base RIM using the default attribute values; "); sb.append("Create a base RIM using the default attribute values; ");
sb.append("sign it using privateKey.pem; embed cert.pem in the signature block; "); sb.append("sign it using privateKey.pem; embed cert.pem in the signature block; ");
sb.append("and write the data to console output:\n\n"); sb.append("and write the data to console output:\n\n");
sb.append("\t\t-c base -l support_rim.bin -k privateKey.pem -p cert.pem\n\n\n"); sb.append("\t\t-c base -l support_rim.bin -k privateKey.pem -p cert.pem -e\n\n\n");
sb.append("Validate a base RIM using an external support RIM to override the "); sb.append("Validate a base RIM using an external support RIM to override the ");
sb.append("payload file:\n\n"); sb.append("payload file:\n\n");
sb.append("\t\t-v base_rim.swidtag -l support_rim.bin\n\n\n"); sb.append("\t\t-v base_rim.swidtag -l support_rim.bin\n\n\n");
@ -107,7 +113,9 @@ public class Commander {
} else if (!this.getPrivateKeyFile().isEmpty() && } else if (!this.getPrivateKeyFile().isEmpty() &&
!this.getPublicCertificate().isEmpty()) { !this.getPublicCertificate().isEmpty()) {
sb.append("Private key file: " + this.getPrivateKeyFile() + System.lineSeparator()); sb.append("Private key file: " + this.getPrivateKeyFile() + System.lineSeparator());
sb.append("Public certificate: " + this.getPublicCertificate() + System.lineSeparator()); sb.append("Public certificate: " + this.getPublicCertificate()
+ System.lineSeparator());
sb.append("Embedded certificate: " + this.isEmbedded() + System.lineSeparator());
} else if (this.isDefaultKey()){ } else if (this.isDefaultKey()){
sb.append("Truststore file: default (" + SwidTagConstants.DEFAULT_KEYSTORE_FILE + ")" sb.append("Truststore file: default (" + SwidTagConstants.DEFAULT_KEYSTORE_FILE + ")"
+ System.lineSeparator()); + System.lineSeparator());

View File

@ -14,13 +14,21 @@ public class TestSwidTagGateway {
private SwidTagGateway gateway; private SwidTagGateway gateway;
private SwidTagValidator validator; private SwidTagValidator validator;
private final String DEFAULT_OUTPUT = "generated_swidTag.swidtag"; private final String DEFAULT_OUTPUT = "generated_swidTag.swidtag";
private final String DEFAULT_WITH_CERT = "generated_with_cert.swidtag"; private final String BASE_USER_CERT = "generated_user_cert.swidtag";
private final String DEFAULT_NO_CERT = "generated_no_cert.swidtag"; private final String BASE_USER_CERT_EMBED = "generated_user_cert_embed.swidtag";
private final String ATTRIBUTES_FILE = TestSwidTagGateway.class.getClassLoader().getResource("rim_fields.json").getPath(); private final String BASE_DEFAULT_CERT = "generated_default_cert.swidtag";
private final String JKS_KEYSTORE_FILE = TestSwidTagGateway.class.getClassLoader().getResource("keystore.jks").getPath(); private final String ATTRIBUTES_FILE = TestSwidTagGateway.class.getClassLoader()
private final String SIGNING_CERT_FILE = TestSwidTagGateway.class.getClassLoader().getResource("RimSignCert.pem").getPath(); .getResource("rim_fields.json").getPath();
private final String PRIVATE_KEY_FILE = TestSwidTagGateway.class.getClassLoader().getResource("privateRimKey.pem").getPath(); private final String JKS_KEYSTORE_FILE = TestSwidTagGateway.class.getClassLoader()
private final String SUPPORT_RIM_FILE = TestSwidTagGateway.class.getClassLoader().getResource("TpmLog.bin").getPath(); .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 CA_CHAIN_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("RimCertChain.pem").getPath();
private final String SUPPORT_RIM_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("TpmLog.bin").getPath();
private InputStream expectedFile; private InputStream expectedFile;
@BeforeClass @BeforeClass
@ -30,6 +38,7 @@ public class TestSwidTagGateway {
gateway.setAttributesFile(ATTRIBUTES_FILE); gateway.setAttributesFile(ATTRIBUTES_FILE);
validator = new SwidTagValidator(); validator = new SwidTagValidator();
validator.setRimEventLog(SUPPORT_RIM_FILE); validator.setRimEventLog(SUPPORT_RIM_FILE);
validator.setTrustStoreFile(CA_CHAIN_FILE);
} }
@AfterClass @AfterClass
@ -45,13 +54,35 @@ public class TestSwidTagGateway {
* where RimSignCert.pem has the AIA extension. * where RimSignCert.pem has the AIA extension.
*/ */
@Test @Test
public void testCreateBaseWithCert() { public void testCreateBaseUserCertNotEmbedded() {
gateway.setDefaultCredentials(false); gateway.setDefaultCredentials(false);
gateway.setPemCertificateFile(SIGNING_CERT_FILE); gateway.setPemCertificateFile(SIGNING_CERT_FILE);
gateway.setPemPrivateKeyFile(PRIVATE_KEY_FILE); gateway.setPemPrivateKeyFile(PRIVATE_KEY_FILE);
gateway.setEmbeddedCert(false);
gateway.generateSwidTag(DEFAULT_OUTPUT); gateway.generateSwidTag(DEFAULT_OUTPUT);
expectedFile = TestSwidTagGateway.class.getClassLoader().getResourceAsStream(DEFAULT_WITH_CERT); expectedFile = TestSwidTagGateway.class.getClassLoader()
.getResourceAsStream(BASE_USER_CERT);
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT)); Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT));
}
/**
* This test creates the following base RIM:
* -c base -l TpmLog.bin -k privateRimKey.pem -p RimSignCert.pem -e
* And then validates it:
* -v [base RIM] -l TpmLog.bin -t RimCertChain.pem
*/
@Test
public void testCreateBaseUserCertEmbedded() {
gateway.setDefaultCredentials(false);
gateway.setPemCertificateFile(SIGNING_CERT_FILE);
gateway.setPemPrivateKeyFile(PRIVATE_KEY_FILE);
gateway.setEmbeddedCert(true);
gateway.generateSwidTag(DEFAULT_OUTPUT);
expectedFile = TestSwidTagGateway.class.getClassLoader()
.getResourceAsStream(BASE_USER_CERT_EMBED);
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT));
} }
/** /**
@ -59,21 +90,24 @@ public class TestSwidTagGateway {
* -c base -l TpmLog.bin * -c base -l TpmLog.bin
*/ */
@Test @Test
public void testCreateBaseWithoutCert() { public void testCreateBaseDefaultCert() {
gateway.setDefaultCredentials(true); gateway.setDefaultCredentials(true);
gateway.setJksTruststoreFile(JKS_KEYSTORE_FILE); gateway.setJksTruststoreFile(JKS_KEYSTORE_FILE);
gateway.generateSwidTag(DEFAULT_OUTPUT); gateway.generateSwidTag(DEFAULT_OUTPUT);
expectedFile = TestSwidTagGateway.class.getClassLoader().getResourceAsStream(DEFAULT_NO_CERT); expectedFile = TestSwidTagGateway.class.getClassLoader()
.getResourceAsStream(BASE_DEFAULT_CERT);
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT)); Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT));
} }
/** /**
* This test corresponds to the arguments: * This test corresponds to the arguments:
* -v <path> * -v <path>
*/ */
@Test
public void testValidateSwidTag() { public void testValidateSwidTag() {
String filepath = TestSwidTagGateway.class.getClassLoader().getResource(DEFAULT_WITH_CERT).getPath(); String filepath = TestSwidTagGateway.class.getClassLoader()
.getResource(BASE_USER_CERT).getPath();
System.out.println("Validating file at " + filepath); System.out.println("Validating file at " + filepath);
Assert.assertTrue(validator.validateSwidTag(filepath)); Assert.assertTrue(validator.validateSwidTag(filepath));
} }

View File

@ -0,0 +1,43 @@
-----BEGIN CERTIFICATE-----
MIIDjDCCAnSgAwIBAgIJALEA1Q472tZoMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV
BAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwI
UENDbGllbnQxEjAQBgNVBAMMCUV4YW1wbGVDQTAeFw0yMDAyMTAxNzI2MDdaFw0y
OTEyMTkxNzI2MDdaMFMxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UE
CgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxEjAQBgNVBAMMCUV4YW1wbGVD
QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPN0k+ULqFxdHZ14CCio
HAvn56T1Ca4t3ClmZoHSAiKsqzLV+rErk5SbMTIdi0vHQ+3sPYf9Opy0EeUXzh4J
g6CeGdDn247has1k135KBD9iJCaErJfZPnJ22CjKey8rvJM8fH3CAR7M/5uwYcPH
yRICwGAJMA/Qss4nsMRQpfZg4ReKVW+kAoa9eekG3q1sLu/QlCb0NC766X0ANP+8
AuGuHJmNV22fjvwSNfWbsJElcMrLbK4kliPyy05YVs19p+cBM1ADxGw2fJqsNsUy
34SXL1ATqOp7VCslRR5TJBzhxfM56xZbszry7BaqTSFDRGn1FuMw/4+qtPMAB88u
eXECAwEAAaNjMGEwHQYDVR0OBBYEFEahuO3bpnFf0NLneoo8XW6aw5Y4MB8GA1Ud
IwQYMBaAFEahuO3bpnFf0NLneoo8XW6aw5Y4MA8GA1UdEwEB/wQFMAMBAf8wDgYD
VR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IBAQCwCUSV6VjOR+v85z18q5UX
bla0gEsfbc2mx0kGtNqi2im2Xt8UoSJDnfMXzfQq3IP3en943mqgIeYUl3f9UQBT
KgGfyHNbEfa0FzqfKpxJdT37C9ilSQ85GtThffc4I50QgBHaRXOvwBdrGpU2O11V
x35VLyYoycIlg+CizVywEX53aoMil1hEbv0TPtbNnFZGwM/fxvere65GeQld9gEP
9krGtSXYlMktvr66cqPzmG0ciA6dMBZN8dpTgUopmYNz8HVoHDq/KBmXYA7CMzrX
pVNx4kMW/KxA+XAHT82xE7PCiLIJx4z9uPn0O4PBDw0tQ0mxuDpeoi1i9PuBfe6Y
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDoTCCAomgAwIBAgIJAIKly+6bklZlMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV
BAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwI
UENDbGllbnQxEjAQBgNVBAMMCUV4YW1wbGVDQTAeFw0yMDA2MTExNjUzMDFaFw0z
MDA0MjAxNjUzMDFaMFwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UE
CgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNVBAMMEmV4YW1wbGUu
UklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1lWGk
SRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44
/nBaccZDOjdfIxIUCMfwhGXjxCaqZbgTucNsExDnu4arTGraoAwzHg0cVLiKT/Cx
j9NL4dcMgxRXsPdHfXb0923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQ
ZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY2hq+z82x/rqwr2hmyizD6FpFSyIABPEM
PfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0Hh4mNFSKD4pP41VSKY1n
us83mdkuukPy5o0CAwEAAaNvMG0wHQYDVR0OBBYEFC/euOfQMKIgnaoBhhqWT+3s
8rzBMB8GA1UdIwQYMBaAFEahuO3bpnFf0NLneoo8XW6aw5Y4MAkGA1UdEwQCMAAw
CwYDVR0PBAQDAgbAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUA
A4IBAQC1mG0naE0W4E9vujPhygf7LXHMFkMPs5uWyvkxe4zWgTg0RHTClbOFJQJ+
pGLOcthSG6vIC6xYJxT5EKtB9rzRlEYHOi4MxuwXz9rLWQhA2zdbSo54Fb/BPoca
5K9kxvAanRltEfqEFhCcRmqIX1i6mpOWiZsrdMs7IflHKBsylUTn+v636BAz3p2H
8/lpJbF4LUFUxFU5FWB3tLuasxYTsbeE6YyNAnQIS95ML7c5H8z2aEQs5TCNHZJD
yc0PZT2aPOuEj5lGv9oyBHbYDitszUWSVxF7z86uVGmYR/2oTIj6tqb+IwuvFtnO
wiXFRS5ctLCdESr3SjdQF5wmIN4n
-----END CERTIFICATE-----

View File

@ -3,7 +3,7 @@
<Entity name="Example Inc" regid="http://Example.com" role="softwareCreator tagCreator"/> <Entity name="Example Inc" regid="http://Example.com" role="softwareCreator tagCreator"/>
<Link href="https://Example.com/support/ProductA/firmware/installfiles" rel="installationmedia"/> <Link href="https://Example.com/support/ProductA/firmware/installfiles" rel="installationmedia"/>
<Meta xmlns:n8060="http://csrc.nist.gov/ns/swid/2015-extensions/1.0" xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" n8060:colloquialVersion="Firmware_2019" n8060:edition="12" n8060:product="ProductA" n8060:revision="r2" rim:BindingSpec="PC Client RIM" rim:BindingSpecVersion="1.2" rim:PayloadType="direct" rim:firmwareManufacturerId="00213022" rim:firmwareManufacturerStr="BIOSVendorA" rim:firmwareModel="A0" rim:firmwareVersion="12" rim:pcURIGlobal="https://Example.com/support/ProductA/" rim:pcURILocal="/boot/tcg/manifest/switag/" rim:platformManufacturerId="00201234" rim:platformManufacturerStr="Example.com" rim:platformModel="ProductA" rim:platformVersion="01"/> <Meta xmlns:n8060="http://csrc.nist.gov/ns/swid/2015-extensions/1.0" xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" n8060:colloquialVersion="Firmware_2019" n8060:edition="12" n8060:product="ProductA" n8060:revision="r2" rim:BindingSpec="PC Client RIM" rim:BindingSpecVersion="1.2" rim:PayloadType="direct" rim:firmwareManufacturerId="00213022" rim:firmwareManufacturerStr="BIOSVendorA" rim:firmwareModel="A0" rim:firmwareVersion="12" rim:pcURIGlobal="https://Example.com/support/ProductA/" rim:pcURILocal="/boot/tcg/manifest/switag/" rim:platformManufacturerId="00201234" rim:platformManufacturerStr="Example.com" rim:platformModel="ProductA" rim:platformVersion="01"/>
<Payload> <Payload xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" rim:supportRIMFormat="TCG_EventLog_Assertion" rim:supportRIMURIGlobal="https://Example.com/support/ProductA/firmware/rims/">
<Directory name="rim"> <Directory name="rim">
<File xmlns:SHA256="http://www.w3.org/2001/04/xmlenc#sha256" SHA256:hash="4479ca722623f8c47b703996ced3cbd981b06b1ae8a897db70137e0b7c546848" name="Example.com.BIOS.01.rimel" size="7549"/> <File xmlns:SHA256="http://www.w3.org/2001/04/xmlenc#sha256" SHA256:hash="4479ca722623f8c47b703996ced3cbd981b06b1ae8a897db70137e0b7c546848" name="Example.com.BIOS.01.rimel" size="7549"/>
</Directory> </Directory>
@ -17,14 +17,14 @@
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms> </Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>K3XoBeYvgJBAKl8z273sL7z38qLLVBKLfUPt/gPUzBI=</DigestValue> <DigestValue>97uWB7zSsO5WaGbrcQrlKd1Bju0aDTjK1/ktUYBje8A=</DigestValue>
</Reference> </Reference>
</SignedInfo> </SignedInfo>
<SignatureValue>cIl1gPsUyEj2gDv3HTWNFDVxtcBjz4Revxxf2LJejtOXQW8mGepZH8CnvgO7zCAbZYlYUZXjYZ9M&#13; <SignatureValue>N1YtTeo2Ryuj+CtlXIpICEay+ni7vt8+4J7tAsYpa3efnLwtea69PIqEylPWm9LdA8Eo8XDdpgxV&#13;
jONVv8dcsAjVHRnP6YHywFfmSm8LUCwxsfuZQqn5jClqzu5VaqLzBhuJYvCpiEdIDJwDINQuORUB&#13; 7h3hi2LTOU+Wxq3bLiLamo99T1EtIwl+ZPcOv8bsfEkmShHdMC0dlfcj6r7x4tc0XkNAhhJgfRNz&#13;
nzul1CWc3Sm1Ms2wjlIq5ctWWJcddhdyIOjl8/oD4EC5E2rOSfNcRMZxldXtie9iinFGVbr0YNE+&#13; FsmPWKJb6FYcsHFbHO/Uw1hSokbAGcWWTshEOqvKHMa8UVkrFMUPnrnMtdyJqZlhDBrZHNi4rWth&#13;
+lQ7hAU+SyV8RMx9tGnnsO8otwV4ddF+OfemcbzWGYBenLs3A8ZqWZyTvWphCgGqDUbOLssYciCC&#13; 8TjlUnQVSCF9s9I04FxJ1cUAdeVMHtXKM8Pvjv68PaJMJK73dW5Yd3SbcgoKLesf/HPWeeZL0rr4&#13;
mnYm5QOeh4QcE9H2kqTgZvcyCgPL/hDC7xhyjQ==</SignatureValue> TNjlqJ/wq61Ons45MFG9bIscVbnd+XxFHx8Skw==</SignatureValue>
<KeyInfo> <KeyInfo>
<KeyName>2fdeb8e7d030a2209daa01861a964fedecf2bcc1</KeyName> <KeyName>2fdeb8e7d030a2209daa01861a964fedecf2bcc1</KeyName>
</KeyInfo> </KeyInfo>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SoftwareIdentity xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" corpus="false" name="Example.com BIOS" patch="false" supplemental="false" tagId="94f6b457-9ac9-4d35-9b3f-78804173b65as" tagVersion="0" version="01" versionScheme="multipartnumeric" xml:lang="en">
<Entity name="Example Inc" regid="http://Example.com" role="softwareCreator tagCreator"/>
<Link href="https://Example.com/support/ProductA/firmware/installfiles" rel="installationmedia"/>
<Meta xmlns:n8060="http://csrc.nist.gov/ns/swid/2015-extensions/1.0" xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" n8060:colloquialVersion="Firmware_2019" n8060:edition="12" n8060:product="ProductA" n8060:revision="r2" rim:BindingSpec="PC Client RIM" rim:BindingSpecVersion="1.2" rim:PayloadType="direct" rim:firmwareManufacturerId="00213022" rim:firmwareManufacturerStr="BIOSVendorA" rim:firmwareModel="A0" rim:firmwareVersion="12" rim:pcURIGlobal="https://Example.com/support/ProductA/" rim:pcURILocal="/boot/tcg/manifest/switag/" rim:platformManufacturerId="00201234" rim:platformManufacturerStr="Example.com" rim:platformModel="ProductA" rim:platformVersion="01"/>
<Payload xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" rim:supportRIMFormat="TCG_EventLog_Assertion" rim:supportRIMURIGlobal="https://Example.com/support/ProductA/firmware/rims/">
<Directory name="rim">
<File xmlns:SHA256="http://www.w3.org/2001/04/xmlenc#sha256" SHA256:hash="4479ca722623f8c47b703996ced3cbd981b06b1ae8a897db70137e0b7c546848" name="Example.com.BIOS.01.rimel" size="7549"/>
</Directory>
</Payload>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>97uWB7zSsO5WaGbrcQrlKd1Bju0aDTjK1/ktUYBje8A=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>N1YtTeo2Ryuj+CtlXIpICEay+ni7vt8+4J7tAsYpa3efnLwtea69PIqEylPWm9LdA8Eo8XDdpgxV&#13;
7h3hi2LTOU+Wxq3bLiLamo99T1EtIwl+ZPcOv8bsfEkmShHdMC0dlfcj6r7x4tc0XkNAhhJgfRNz&#13;
FsmPWKJb6FYcsHFbHO/Uw1hSokbAGcWWTshEOqvKHMa8UVkrFMUPnrnMtdyJqZlhDBrZHNi4rWth&#13;
8TjlUnQVSCF9s9I04FxJ1cUAdeVMHtXKM8Pvjv68PaJMJK73dW5Yd3SbcgoKLesf/HPWeeZL0rr4&#13;
TNjlqJ/wq61Ons45MFG9bIscVbnd+XxFHx8Skw==</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx&#13;
xkM6N18jEhQIx/CEZePEJqpluBO5w2wTEOe7hqtMatqgDDMeDRxUuIpP8LGP00vh1wyDFFew90d9&#13;
dvT3bcLvFh3a3ap9bTm6aBqPup5CXpzrwIU2wZfgkDytYVBm+8bHkMaUrgpNyM+5BAg2zl/Fqw0q&#13;
otjaGr7PzbH+urCvaGbKLMPoWkVLIgAE8Qw98HTfoYSFHC7VYQySrzIinaOBFSgViR72kHemH2lW&#13;
jDQeHiY0VIoPik/jVVIpjWe6zzeZ2S66Q/LmjQ==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
</SoftwareIdentity>

View File

@ -3,7 +3,7 @@
<Entity name="Example Inc" regid="http://Example.com" role="softwareCreator tagCreator"/> <Entity name="Example Inc" regid="http://Example.com" role="softwareCreator tagCreator"/>
<Link href="https://Example.com/support/ProductA/firmware/installfiles" rel="installationmedia"/> <Link href="https://Example.com/support/ProductA/firmware/installfiles" rel="installationmedia"/>
<Meta xmlns:n8060="http://csrc.nist.gov/ns/swid/2015-extensions/1.0" xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" n8060:colloquialVersion="Firmware_2019" n8060:edition="12" n8060:product="ProductA" n8060:revision="r2" rim:BindingSpec="PC Client RIM" rim:BindingSpecVersion="1.2" rim:PayloadType="direct" rim:firmwareManufacturerId="00213022" rim:firmwareManufacturerStr="BIOSVendorA" rim:firmwareModel="A0" rim:firmwareVersion="12" rim:pcURIGlobal="https://Example.com/support/ProductA/" rim:pcURILocal="/boot/tcg/manifest/switag/" rim:platformManufacturerId="00201234" rim:platformManufacturerStr="Example.com" rim:platformModel="ProductA" rim:platformVersion="01"/> <Meta xmlns:n8060="http://csrc.nist.gov/ns/swid/2015-extensions/1.0" xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" n8060:colloquialVersion="Firmware_2019" n8060:edition="12" n8060:product="ProductA" n8060:revision="r2" rim:BindingSpec="PC Client RIM" rim:BindingSpecVersion="1.2" rim:PayloadType="direct" rim:firmwareManufacturerId="00213022" rim:firmwareManufacturerStr="BIOSVendorA" rim:firmwareModel="A0" rim:firmwareVersion="12" rim:pcURIGlobal="https://Example.com/support/ProductA/" rim:pcURILocal="/boot/tcg/manifest/switag/" rim:platformManufacturerId="00201234" rim:platformManufacturerStr="Example.com" rim:platformModel="ProductA" rim:platformVersion="01"/>
<Payload> <Payload xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" rim:supportRIMFormat="TCG_EventLog_Assertion" rim:supportRIMURIGlobal="https://Example.com/support/ProductA/firmware/rims/">
<Directory name="rim"> <Directory name="rim">
<File xmlns:SHA256="http://www.w3.org/2001/04/xmlenc#sha256" SHA256:hash="4479ca722623f8c47b703996ced3cbd981b06b1ae8a897db70137e0b7c546848" name="Example.com.BIOS.01.rimel" size="7549"/> <File xmlns:SHA256="http://www.w3.org/2001/04/xmlenc#sha256" SHA256:hash="4479ca722623f8c47b703996ced3cbd981b06b1ae8a897db70137e0b7c546848" name="Example.com.BIOS.01.rimel" size="7549"/>
</Directory> </Directory>
@ -17,14 +17,14 @@
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms> </Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>K3XoBeYvgJBAKl8z273sL7z38qLLVBKLfUPt/gPUzBI=</DigestValue> <DigestValue>97uWB7zSsO5WaGbrcQrlKd1Bju0aDTjK1/ktUYBje8A=</DigestValue>
</Reference> </Reference>
</SignedInfo> </SignedInfo>
<SignatureValue>cIl1gPsUyEj2gDv3HTWNFDVxtcBjz4Revxxf2LJejtOXQW8mGepZH8CnvgO7zCAbZYlYUZXjYZ9M&#13; <SignatureValue>N1YtTeo2Ryuj+CtlXIpICEay+ni7vt8+4J7tAsYpa3efnLwtea69PIqEylPWm9LdA8Eo8XDdpgxV&#13;
jONVv8dcsAjVHRnP6YHywFfmSm8LUCwxsfuZQqn5jClqzu5VaqLzBhuJYvCpiEdIDJwDINQuORUB&#13; 7h3hi2LTOU+Wxq3bLiLamo99T1EtIwl+ZPcOv8bsfEkmShHdMC0dlfcj6r7x4tc0XkNAhhJgfRNz&#13;
nzul1CWc3Sm1Ms2wjlIq5ctWWJcddhdyIOjl8/oD4EC5E2rOSfNcRMZxldXtie9iinFGVbr0YNE+&#13; FsmPWKJb6FYcsHFbHO/Uw1hSokbAGcWWTshEOqvKHMa8UVkrFMUPnrnMtdyJqZlhDBrZHNi4rWth&#13;
+lQ7hAU+SyV8RMx9tGnnsO8otwV4ddF+OfemcbzWGYBenLs3A8ZqWZyTvWphCgGqDUbOLssYciCC&#13; 8TjlUnQVSCF9s9I04FxJ1cUAdeVMHtXKM8Pvjv68PaJMJK73dW5Yd3SbcgoKLesf/HPWeeZL0rr4&#13;
mnYm5QOeh4QcE9H2kqTgZvcyCgPL/hDC7xhyjQ==</SignatureValue> TNjlqJ/wq61Ons45MFG9bIscVbnd+XxFHx8Skw==</SignatureValue>
<KeyInfo> <KeyInfo>
<X509Data> <X509Data>
<X509SubjectName>CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US</X509SubjectName> <X509SubjectName>CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US</X509SubjectName>