[#896] Add basic Platform Certificate Class Registry support to the ACA (#898)
Some checks failed
Dotnet Provisioner Unit Tests / Restore and Run Unit Tests (ubuntu-20.04) (push) Has been cancelled
Dotnet Provisioner Unit Tests / Restore and Run Unit Tests (windows-2022) (push) Has been cancelled
HIRS Build and Unit Test / ACA_Provisioner_Unit_Tests (push) Has been cancelled
HIRS System Tests / DockerTests (push) Has been cancelled
Dotnet Provisioner Unit Tests / Evaluate Tests (push) Has been cancelled

* issue_896: first cut at changing the logic on the validator

* issue_896: Added more javadocs, still going through the process and figuring out places where this will work. Can successfully debug provisioner+aca.

* issue_896: slowly introducing component identifier v2 into multiple spots throughout out the app. Seems like we need to ensure that when we try to parse the pc from the identity claim, it needs to recognize the new kind of identifier.

* issue_896: deleted abstract plat form config class, replaced it with plat config v1 (which already exists), moved attribuutes associated with v2 to the v2 class, when validating the aca will now verify if the platform config associated with the cert is v1 or v2. Made corrections to attributes names to better align with tcg docs.

* issue_896:Added a new property to component info, made some more spelling corrections, deleted unused classes that were being referenced by componentinfo. pretty much done with the aca side of things.

* issue_896:I believe I have finished the issue. Further testing needs to be done. Will put in a WIP PR for now.

* issue_896: Made some more changes after viewing PR

* issue_896: Changed v3 to v4 in the github actions yaml files.

* issue_896: Fixed issues in one of the test classes, can now test other aspects of the SupplyChainCredentialValidator class. Will add more tests as more issues get fixed.

* issue_896: Hopefully GITHUB actions will be more forgiving.

* issue_896: Placed test task in the root build.gradle. Made more fixes to the test classes.

* issue_896: Realized there might be more work needed for the validation part. Started adding more logic to validation.

* issue_896: Last change before the long weekend. Hoping these changes will make github actions happy.

* issue_896: Verifying that this part works. We will need to figure out a smart/efficient way of comparing the components from platform cert and device info report.

* testing

* v3_issue_896: Should work for this PR.

* v3_issue_821: fixed the NPE issue we were getting during provisioning for missing component info.

* v3_issue_896: my copy/paste skills need work. Fixed the issue that was causing the docker tests to fail.

* v3_issue_896: trying to see if reverting the return call null will make a difference.

* v3_issue_896: should fix issues with pc found on certain devices

* v3_issue_896: part ii of should fix issues with pc found on certain devices
This commit is contained in:
ThatSilentCoder 2025-04-01 09:18:21 -04:00 committed by iadgovuser29
parent 2d89f7b20e
commit 0b7a72805a
52 changed files with 2413 additions and 1924 deletions

View File

@ -1,3 +1,4 @@
# Updated: 02/11/2025
name: Create ACA Docker Image
on:
release:
@ -17,7 +18,7 @@ env:
PUBLIC_IMAGE_NAME: ghcr.io/nsacyber/hirs/aca
PUBLIC_IMAGE_TAG_LATEST: ghcr.io/nsacyber/hirs/aca:latest
TAG_LATEST: ${{ github.event_name == 'release' || inputs.also_tag_latest }} # The public docker image will be tagged 'latest' for releases, or if this option is manually selected.
jobs:
jobs:
setup:
runs-on: ubuntu-latest
outputs:
@ -27,44 +28,44 @@ jobs:
WINDOWS_COMPAT_IMAGE_TAG: ${{ steps.setenv.outputs.WINDOWS_COMPAT_IMAGE_TAG }}
PUBLIC_IMAGE_TAG: ${{ steps.setenv.outputs.PUBLIC_IMAGE_TAG }}
steps:
- name: Set env
id: setenv
shell: bash
run: |
# Parse docker image tag from GitHub tag if available
if [ "${{ github.ref_type }}" = "tag" ]; then
# tags start with refs/tags/. Also remove v if it exists.
export IMAGE_TAG_VAR=${GITHUB_REF:10}
export IMAGE_TAG_VAR=${IMAGE_TAG_VAR//v/}
else
# Not a tag, use the commit hash. Do not tag as latest.
export IMAGE_TAG_VAR=${GITHUB_SHA:0:7}
fi
# To lowercase
export IMAGE_TAG_VAR=${IMAGE_TAG_VAR,,}
# Save to output
echo "IMAGE_TAG=$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
echo "ROCKY_IMAGE_TAG=$IMAGE_NAME_ROCKY:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
echo "WINDOWS_IMAGE_TAG=$IMAGE_NAME_WINDOWS:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
echo "WINDOWS_COMPAT_IMAGE_TAG=$IMAGE_NAME_WINDOWS_COMPAT:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
echo "PUBLIC_IMAGE_TAG=$PUBLIC_IMAGE_NAME:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
- name: Print env
run: |
echo GITHUB_REF_NAME=${{ github.ref_name }}
echo DOCKERFILE_ROCKY=$DOCKERFILE_ROCKY
echo DOCKERFILE_WINDOWS=$DOCKERFILE_WINDOWS
echo IMAGE_NAME_ROCKY=$IMAGE_NAME_ROCKY
echo IMAGE_NAME_WINDOWS=$IMAGE_NAME_WINDOWS
echo IMAGE_NAME_WINDOWS_COMPAT=$IMAGE_NAME_WINDOWS_COMPAT
echo PUBLIC_IMAGE_NAME=$PUBLIC_IMAGE_NAME
echo PUBLIC_IMAGE_TAG_LATEST=$PUBLIC_IMAGE_TAG_LATEST
echo TAG_LATEST=$TAG_LATEST
echo IMAGE_TAG=${{ steps.setenv.outputs.IMAGE_TAG }}
echo ROCKY_IMAGE_TAG=${{ steps.setenv.outputs.ROCKY_IMAGE_TAG }}
echo WINDOWS_IMAGE_TAG=${{ steps.setenv.outputs.WINDOWS_IMAGE_TAG }}
echo WINDOWS_COMPAT_IMAGE_TAG=${{ steps.setenv.outputs.WINDOWS_COMPAT_IMAGE_TAG }}
echo PUBLIC_IMAGE_TAG=${{ steps.setenv.outputs.PUBLIC_IMAGE_TAG }}
- name: Set env
id: setenv
shell: bash
run: |
# Parse docker image tag from GitHub tag if available
if [ "${{ github.ref_type }}" = "tag" ]; then
# tags start with refs/tags/. Also remove v if it exists.
export IMAGE_TAG_VAR=${GITHUB_REF:10}
export IMAGE_TAG_VAR=${IMAGE_TAG_VAR//v/}
else
# Not a tag, use the commit hash. Do not tag as latest.
export IMAGE_TAG_VAR=${GITHUB_SHA:0:7}
fi
# To lowercase
export IMAGE_TAG_VAR=${IMAGE_TAG_VAR,,}
# Save to output
echo "IMAGE_TAG=$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
echo "ROCKY_IMAGE_TAG=$IMAGE_NAME_ROCKY:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
echo "WINDOWS_IMAGE_TAG=$IMAGE_NAME_WINDOWS:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
echo "WINDOWS_COMPAT_IMAGE_TAG=$IMAGE_NAME_WINDOWS_COMPAT:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
echo "PUBLIC_IMAGE_TAG=$PUBLIC_IMAGE_NAME:$IMAGE_TAG_VAR" >> "$GITHUB_OUTPUT"
- name: Print env
run: |
echo GITHUB_REF_NAME=${{ github.ref_name }}
echo DOCKERFILE_ROCKY=$DOCKERFILE_ROCKY
echo DOCKERFILE_WINDOWS=$DOCKERFILE_WINDOWS
echo IMAGE_NAME_ROCKY=$IMAGE_NAME_ROCKY
echo IMAGE_NAME_WINDOWS=$IMAGE_NAME_WINDOWS
echo IMAGE_NAME_WINDOWS_COMPAT=$IMAGE_NAME_WINDOWS_COMPAT
echo PUBLIC_IMAGE_NAME=$PUBLIC_IMAGE_NAME
echo PUBLIC_IMAGE_TAG_LATEST=$PUBLIC_IMAGE_TAG_LATEST
echo TAG_LATEST=$TAG_LATEST
echo IMAGE_TAG=${{ steps.setenv.outputs.IMAGE_TAG }}
echo ROCKY_IMAGE_TAG=${{ steps.setenv.outputs.ROCKY_IMAGE_TAG }}
echo WINDOWS_IMAGE_TAG=${{ steps.setenv.outputs.WINDOWS_IMAGE_TAG }}
echo WINDOWS_COMPAT_IMAGE_TAG=${{ steps.setenv.outputs.WINDOWS_COMPAT_IMAGE_TAG }}
echo PUBLIC_IMAGE_TAG=${{ steps.setenv.outputs.PUBLIC_IMAGE_TAG }}
rocky-image:
needs: setup
@ -72,78 +73,78 @@ jobs:
env:
TAG: ${{ needs.setup.outputs.ROCKY_IMAGE_TAG }}
steps:
- name: Checkout main
uses: actions/checkout@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push a release Docker image for ${{ github.repository }}
uses: docker/build-push-action@v5
with:
context: "{{defaultContext}}:.ci/docker"
file: Dockerfile.${{env.DOCKERFILE_ROCKY}}
build-args: REF=${{ github.ref_name }}
tags: ${{env.TAG}}
push: true
- name: Checkout main
uses: actions/checkout@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push a release Docker image for ${{ github.repository }}
uses: docker/build-push-action@v5
with:
context: "{{defaultContext}}:.ci/docker"
file: Dockerfile.${{env.DOCKERFILE_ROCKY}}
build-args: REF=${{ github.ref_name }}
tags: ${{env.TAG}}
push: true
windows-11-image:
needs: setup
runs-on: windows-latest
env:
TAG: ${{ needs.setup.outputs.WINDOWS_IMAGE_TAG }}
steps:
- name: Checkout main
uses: actions/checkout@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout main
uses: actions/checkout@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build the docker image for ${{ github.repository }}
run: |
cd ./.ci/docker
docker build --build-arg REF=${{ github.ref_name }} -f ./Dockerfile.${{env.DOCKERFILE_WINDOWS}} -t ${{env.TAG}} .
- name: Push the docker image
run: |
docker push ${{env.TAG}}
- name: Build the docker image for ${{ github.repository }}
run: |
cd ./.ci/docker
docker build --build-arg REF=${{ github.ref_name }} -f ./Dockerfile.${{env.DOCKERFILE_WINDOWS}} -t ${{env.TAG}} .
- name: Push the docker image
run: |
docker push ${{env.TAG}}
windows-compat-image: # This job uses a different runner and build arg than the other windows job.
needs: setup
runs-on: windows-2019
env:
TAG: ${{ needs.setup.outputs.WINDOWS_COMPAT_IMAGE_TAG }}
steps:
- name: Checkout main
uses: actions/checkout@v4
- name: Checkout main
uses: actions/checkout@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build the docker image for ${{ github.repository }}
run: |
cd ./.ci/docker
docker build --build-arg REF=${{ github.ref_name }} -f ./Dockerfile.${{env.DOCKERFILE_WINDOWS}} -t ${{env.TAG}} --build-arg BASE_IMAGE_TAG=lts-windowsservercore-1809 .
- name: Push the docker image
run: |
docker push ${{env.TAG}}
- name: Build the docker image for ${{ github.repository }}
run: |
cd ./.ci/docker
docker build --build-arg REF=${{ github.ref_name }} -f ./Dockerfile.${{env.DOCKERFILE_WINDOWS}} -t ${{env.TAG}} --build-arg BASE_IMAGE_TAG=lts-windowsservercore-1809 .
- name: Push the docker image
run: |
docker push ${{env.TAG}}
manifest:
needs: [setup, rocky-image, windows-11-image, windows-compat-image]
needs: [ setup, rocky-image, windows-11-image, windows-compat-image ]
runs-on: ubuntu-latest
env:
IMAGE1: ${{ needs.setup.outputs.ROCKY_IMAGE_TAG }}
@ -151,34 +152,34 @@ jobs:
IMAGE3: ${{ needs.setup.outputs.WINDOWS_COMPAT_IMAGE_TAG }}
PUB: ${{ needs.setup.outputs.PUBLIC_IMAGE_TAG }}
steps:
- name: Print env
run: |
echo IMAGE1=${{env.IMAGE1}}
echo IMAGE2=${{env.IMAGE2}}
echo IMAGE3=${{env.IMAGE3}}
echo PUB=${{env.PUB}}
- name: Checkout main
uses: actions/checkout@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create a new manifest
run: |
docker manifest create ${{env.PUB}} --amend ${{env.IMAGE1}} --amend ${{env.IMAGE2}} --amend ${{env.IMAGE3}}
- name: Push the new manifest
run: |
docker manifest push ${{env.PUB}}
- name: Create and push manifest latest if selected
if: env.TAG_LATEST != 'false'
run: |
docker manifest create $PUBLIC_IMAGE_TAG_LATEST --amend $IMAGE1 --amend $IMAGE2 --amend $IMAGE3
docker manifest push $PUBLIC_IMAGE_TAG_LATEST
- name: Print env
run: |
echo IMAGE1=${{env.IMAGE1}}
echo IMAGE2=${{env.IMAGE2}}
echo IMAGE3=${{env.IMAGE3}}
echo PUB=${{env.PUB}}
- name: Checkout main
uses: actions/checkout@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create a new manifest
run: |
docker manifest create ${{env.PUB}} --amend ${{env.IMAGE1}} --amend ${{env.IMAGE2}} --amend ${{env.IMAGE3}}
- name: Push the new manifest
run: |
docker manifest push ${{env.PUB}}
- name: Create and push manifest latest if selected
if: env.TAG_LATEST != 'false'
run: |
docker manifest create $PUBLIC_IMAGE_TAG_LATEST --amend $IMAGE1 --amend $IMAGE2 --amend $IMAGE3
docker manifest push $PUBLIC_IMAGE_TAG_LATEST

View File

@ -1,8 +1,9 @@
# Updated: 02/11/2025
name: Dotnet Provisioner Unit Tests
on: push
env:
DOTNET_VERSION: '6.0'
DOTNET_VERSION: '8.0'
jobs:
dotnet_provisioner_unit_tests:
name: Restore and Run Unit Tests
@ -97,7 +98,7 @@ jobs:
Evaluator:
name: Evaluate Tests
needs: [dotnet_provisioner_unit_tests]
needs: [ dotnet_provisioner_unit_tests ]
runs-on: ubuntu-latest
continue-on-error: false
steps:

View File

@ -1,3 +1,4 @@
# Updated: 02/11/2025
name: HIRS build and packages for Linux
on:
push:
@ -8,34 +9,34 @@ on:
jobs:
# run the package script for HIRS ACA, Provisioners, tcg_rim_tool, and tcg_eventlog_tool
Package_linux:
Package_linux:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
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: directory setup
run: |
mkdir -p artifacts/jars
mkdir -p artifacts/win
mkdir -p artifacts/win/hirstools
- name: install dependencies
run: |
sudo apt-get update
sudo apt-get install git curl nano cron mariadb-server
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- name: Execute Gradle build
run: |
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
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: directory setup
run: |
mkdir -p artifacts/jars
mkdir -p artifacts/win
mkdir -p artifacts/win/hirstools
- name: install dependencies
run: |
sudo apt-get update
sudo apt-get install git curl nano cron mariadb-server
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Execute Gradle build
run: |
./gradlew build;
./gradlew bootWar;
./gradlew buildDeb;
@ -48,35 +49,35 @@ jobs:
cp tools/tcg_rim_tool/build/distributions/*.zip artifacts/win
cp tools/tcg_eventlog_tool/build/distributions/*.zip artifacts/win
cp package/win/tcg-rim-tool/* artifacts/win/hirstools
- name: Archive RPM files
uses: actions/upload-artifact@v4
with:
name: RPM_Files
path: HIRS_AttestationCAPortal/build/distributions/*.rpm
if-no-files-found: error
- name: Archive DEB files
uses: actions/upload-artifact@v4
with:
name: DEB_Files
path: HIRS_AttestationCAPortal/build/distributions/*.deb
if-no-files-found: error
- name: War files
uses: actions/upload-artifact@v4
with:
name: WAR_Files
path: HIRS_AttestationCAPortal/build/libs/HIRS_AttestationCAPortal.war
if-no-files-found: error
- name: JAR_Files
uses: actions/upload-artifact@v4
with:
name: JAR_Files
path: artifacts/jars/
if-no-files-found: error
- name: ZIP_Files
uses: actions/upload-artifact@v4
with:
name: ZIP_Files
path: artifacts/win/
if-no-files-found: error
- name: Archive RPM files
uses: actions/upload-artifact@v4
with:
name: RPM_Files
path: HIRS_AttestationCAPortal/build/distributions/*.rpm
if-no-files-found: error
- name: Archive DEB files
uses: actions/upload-artifact@v4
with:
name: DEB_Files
path: HIRS_AttestationCAPortal/build/distributions/*.deb
if-no-files-found: error
- name: War files
uses: actions/upload-artifact@v4
with:
name: WAR_Files
path: HIRS_AttestationCAPortal/build/libs/HIRS_AttestationCAPortal.war
if-no-files-found: error
- name: JAR_Files
uses: actions/upload-artifact@v4
with:
name: JAR_Files
path: artifacts/jars/
if-no-files-found: error
- name: ZIP_Files
uses: actions/upload-artifact@v4
with:
name: ZIP_Files
path: artifacts/win/
if-no-files-found: error

View File

@ -1,6 +1,5 @@
# This workflow will build HIRS, run unit tests, and create HIRS artifacts
# Updated: 8/15/23
# Updated: 02/11/2025
name: HIRS Build and Unit Test
on:
@ -17,82 +16,82 @@ jobs:
ACA_Provisioner_Unit_Tests:
runs-on: ubuntu-latest # Configures the job to run on the latest version of an Ubuntu Linux runner
steps:
- uses: actions/checkout@v3 # run v3 of actions/checkout action, which checks out your repository onto the runner
# Build will archive build reports and will create a failedFile if build is not successful
- name: Directory setup
run: |
mkdir -p artifacts/githubActionsResults
mkdir -p artifacts/upload_reports/HIRS_AttestationCA
mkdir -p artifacts/upload_reports/HIRS_AttestationCAPortal
mkdir -p artifacts/upload_reports/HIRS_Provisioner
mkdir -p artifacts/upload_reports/HIRS_ProvisionerTPM2
mkdir -p artifacts/upload_reports/HIRS_Structs
mkdir -p artifacts/upload_reports/HIRS_Utils
mkdir -p artifacts/upload_reports/tcg_rim_tool
mkdir -p artifacts/upload_reports/tcg_eventlog_tool
# Run the provisioner and ACA unit tests via gradle build in a Rocky Docker container
- name: Build HIRS and run unit tests
run: |
# log into and run docker (note: must set up secrets in github for ghcr username and access_token)
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u $ --password-stdin
# docker run options:
# create a mount between curr directory on the runner and the HIRS folder created by the cloning of HIRS repo
# -v $(pwd):/HIRS
# image used for the container, given by <repository>:<tag_name>
# rocky8: ghcr.io/nsacyber/hirs/hirs-rocky8-ci:latest [repo: https://github.com/orgs/nsacyber/packages]
# bash commands to clean/build/test each subproject
# /bin/bash -c '<commands>'
docker run --rm \
-v $(pwd):/HIRS \
ghcr.io/nsacyber/hirs/hirs-rocky8-ci:latest /bin/bash -c \
'pushd /HIRS
gradle_status=0
# git added a feature that gives error if user is not owner of the top-level directory; need to override this
git config --global --add safe.directory /HIRS
# clean, build and run unit tests on all sub-projects; copy build reports to an artifacts directory
./gradlew :HIRS_AttestationCA:clean :HIRS_AttestationCA:build :HIRS_AttestationCA:test
if (( $? != "0" )) ; then gradle_status=1; fi
cp -r /HIRS/HIRS_AttestationCA/build/reports/ /HIRS/artifacts/upload_reports/HIRS_AttestationCA/.
./gradlew :HIRS_AttestationCAPortal:clean :HIRS_AttestationCAPortal:build :HIRS_AttestationCAPortal:test
if (( $? != "0" )) ; then gradle_status=1; fi
cp -r /HIRS/HIRS_AttestationCAPortal/build/reports/ /HIRS/artifacts/upload_reports/HIRS_AttestationCAPortal/.
#./gradlew :HIRS_Provisioner:clean :HIRS_Provisioner:build :HIRS_Provisioner:test
#if (( $? != "0" )) ; then gradle_status=1; fi
#cp -r /HIRS/HIRS_Provisioner/build/reports/ /HIRS/artifacts/upload_reports/HIRS_Provisioner/.
#./gradlew :HIRS_ProvisionerTPM2:clean :HIRS_ProvisionerTPM2:build :HIRS_ProvisionerTPM2:test
#if (( $? != "0" )) ; then gradle_status=1; fi
#cp -r /HIRS/HIRS_ProvisionerTPM2/docs/ /HIRS/artifacts/upload_reports/HIRS_ProvisionerTPM2/.
./gradlew :HIRS_Structs:clean :HIRS_Structs:build :HIRS_Structs:test
if (( $? != "0" )) ; then gradle_status=1; fi
cp -r /HIRS/HIRS_Structs/build/reports/ /HIRS/artifacts/upload_reports/HIRS_Structs/.
./gradlew :HIRS_Utils:clean :HIRS_Utils:build :HIRS_Utils:test
if (( $? != "0" )) ; then gradle_status=1; fi
cp -r /HIRS/HIRS_Utils/build/reports/ /HIRS/artifacts/upload_reports/HIRS_Utils/.
#./gradlew :TPM_Utils:clean :TPM_Utils:build :TPM_Utils:test
#if (( $? != "0" )) ; then gradle_status=1; fi
# Create "fail file" to fail the Build ACA tests if gradle exited with anything other than 0
if (( $gradle_status == "0" )) ; then
echo "In docker: Build Passed"
else
echo "In docker: Build Failed"
touch /HIRS/artifacts/githubActionsResults/buildFailed.txt
fi; popd;'
# Upload build report files
- name: Archive report files
uses: actions/upload-artifact@v4
with:
name: HIRS_Build_Reports
path: artifacts/upload_reports/*
if-no-files-found: ignore
# If buildFailed file exists, use that to fail the ACA unit tests
- name: Check if build/test passed or failed
if: ${{ hashFiles('artifacts/githubActionsResults/buildFailed.txt') != '' }}
uses: actions/github-script@v6
with:
script: |
core.setFailed('Build or Unit Test Failed')
- uses: actions/checkout@v4 # run v4 of actions/checkout action, which checks out your repository onto the runner
# Build will archive build reports and will create a failedFile if build is not successful
- name: Directory setup
run: |
mkdir -p artifacts/githubActionsResults
mkdir -p artifacts/upload_reports/HIRS_AttestationCA
mkdir -p artifacts/upload_reports/HIRS_AttestationCAPortal
mkdir -p artifacts/upload_reports/HIRS_Provisioner
mkdir -p artifacts/upload_reports/HIRS_ProvisionerTPM2
mkdir -p artifacts/upload_reports/HIRS_Structs
mkdir -p artifacts/upload_reports/HIRS_Utils
mkdir -p artifacts/upload_reports/tcg_rim_tool
mkdir -p artifacts/upload_reports/tcg_eventlog_tool
# Run the provisioner and ACA unit tests via gradle build in a Rocky Docker container
- name: Build HIRS and run unit tests
run: |
# log into and run docker (note: must set up secrets in github for ghcr username and access_token)
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u $ --password-stdin
# docker run options:
# create a mount between curr directory on the runner and the HIRS folder created by the cloning of HIRS repo
# -v $(pwd):/HIRS
# image used for the container, given by <repository>:<tag_name>
# rocky8: ghcr.io/nsacyber/hirs/hirs-rocky8-ci:latest [repo: https://github.com/orgs/nsacyber/packages]
# bash commands to clean/build/test each subproject
# /bin/bash -c '<commands>'
docker run --rm \
-v $(pwd):/HIRS \
ghcr.io/nsacyber/hirs/hirs-rocky8-ci:latest /bin/bash -c \
'pushd /HIRS
gradle_status=0
# git added a feature that gives error if user is not owner of the top-level directory; need to override this
git config --global --add safe.directory /HIRS
# clean, build and run unit tests on all sub-projects; copy build reports to an artifacts directory
./gradlew :HIRS_AttestationCA:clean :HIRS_AttestationCA:build :HIRS_AttestationCA:test
if (( $? != "0" )) ; then gradle_status=1; fi
cp -r /HIRS/HIRS_AttestationCA/build/reports/ /HIRS/artifacts/upload_reports/HIRS_AttestationCA/.
./gradlew :HIRS_AttestationCAPortal:clean :HIRS_AttestationCAPortal:build :HIRS_AttestationCAPortal:test
if (( $? != "0" )) ; then gradle_status=1; fi
cp -r /HIRS/HIRS_AttestationCAPortal/build/reports/ /HIRS/artifacts/upload_reports/HIRS_AttestationCAPortal/.
#./gradlew :HIRS_Provisioner:clean :HIRS_Provisioner:build :HIRS_Provisioner:test
#if (( $? != "0" )) ; then gradle_status=1; fi
#cp -r /HIRS/HIRS_Provisioner/build/reports/ /HIRS/artifacts/upload_reports/HIRS_Provisioner/.
#./gradlew :HIRS_ProvisionerTPM2:clean :HIRS_ProvisionerTPM2:build :HIRS_ProvisionerTPM2:test
#if (( $? != "0" )) ; then gradle_status=1; fi
#cp -r /HIRS/HIRS_ProvisionerTPM2/docs/ /HIRS/artifacts/upload_reports/HIRS_ProvisionerTPM2/.
./gradlew :HIRS_Structs:clean :HIRS_Structs:build :HIRS_Structs:test
if (( $? != "0" )) ; then gradle_status=1; fi
cp -r /HIRS/HIRS_Structs/build/reports/ /HIRS/artifacts/upload_reports/HIRS_Structs/.
./gradlew :HIRS_Utils:clean :HIRS_Utils:build :HIRS_Utils:test
if (( $? != "0" )) ; then gradle_status=1; fi
cp -r /HIRS/HIRS_Utils/build/reports/ /HIRS/artifacts/upload_reports/HIRS_Utils/.
#./gradlew :TPM_Utils:clean :TPM_Utils:build :TPM_Utils:test
#if (( $? != "0" )) ; then gradle_status=1; fi
# Create "fail file" to fail the Build ACA tests if gradle exited with anything other than 0
if (( $gradle_status == "0" )) ; then
echo "In docker: Build Passed"
else
echo "In docker: Build Failed"
touch /HIRS/artifacts/githubActionsResults/buildFailed.txt
fi; popd;'
# Upload build report files
- name: Archive report files
uses: actions/upload-artifact@v4
with:
name: HIRS_Build_Reports
path: artifacts/upload_reports/*
if-no-files-found: ignore
# If buildFailed file exists, use that to fail the ACA unit tests
- name: Check if build/test passed or failed
if: ${{ hashFiles('artifacts/githubActionsResults/buildFailed.txt') != '' }}
uses: actions/github-script@v6
with:
script: |
core.setFailed('Build or Unit Test Failed')

View File

@ -1,4 +1,5 @@
# workflow is used to run RIM tests
# Updated: 02/11/2025
name: RIM Test
on:
push:
@ -28,7 +29,7 @@ jobs:
sudo apt-get update
sudo apt-get install git curl nano cron mariadb-server
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
uses: gradle/actions/setup-gradle@v4
- name: Execute Gradle build
run: |
./gradlew build;
@ -37,7 +38,7 @@ jobs:
run: |
sudo dpkg -i tools/tcg_rim_tool/build/distributions/tcg-rim-tool*.deb
- name: RIM tests
run: |
run: |
./.ci/tcg-rim-tool/scripts/run_all_tests.sh --verbose

View File

@ -1,6 +1,5 @@
# This workflow will build HIRS, run system tests, and create artifacts consisting of ACA and Provisioner logs.
# Updated: 06/05/2024
#
# Updated: 02/11/2025
name: HIRS System Tests
on:
push:

View File

@ -65,8 +65,4 @@ sourceSets {
srcDir '../HIRS_Provisioner.NET/hirs/Resources'
}
}
}
test {
useJUnitPlatform()
}
}

View File

@ -108,7 +108,7 @@ public class RestfulAttestationCertificateAuthority extends AttestationCertifica
* the client's desired attestation key, if the correct nonce is supplied.
*
* @param certificateRequest request containing nonce from earlier identity
* * claim handshake
* claim handshake
* @return The response to the client provisioner.
*/
@Override

View File

@ -98,7 +98,7 @@ public class ComponentResult extends ArchivableEntity {
*
* @param boardSerialNumber associated platform certificate serial number.
* @param certificateSerialNumber unique number associated with header info.
* @param certificateType parameter holds version 1.2 or 2.0.
* @param certificateType type of certificate. parameter holds version 1.2 or 2.0.
* @param componentIdentifier object with information from the platform certificate components.
*/
public ComponentResult(final String boardSerialNumber, final String certificateSerialNumber,
@ -116,28 +116,51 @@ public class ComponentResult extends ArchivableEntity {
}
StringBuilder sb = new StringBuilder();
for (ComponentAddress element : componentIdentifier.getComponentAddress()) {
for (ComponentAddress element : componentIdentifier.getComponentAddresses()) {
sb.append(String.format("%s:%s;", element.getAddressTypeValue(),
element.getAddressValue().toString()));
}
componentAddress = sb.toString();
}
/**
* @param boardSerialNumber associated platform certificate serial number
* @param certificateSerialNumber unique number associated with header info
* @param certificateType type of certificate. Parameter holds version 1.2 or 2.0.
* @param componentIdentifierV2 version 2 component identifier
*/
public ComponentResult(final String boardSerialNumber, final String certificateSerialNumber,
final String certificateType,
final ComponentIdentifierV2 componentIdentifierV2) {
this.boardSerialNumber = boardSerialNumber;
this.certificateSerialNumber = certificateSerialNumber;
this.certificateType = certificateType;
this.manufacturer = componentIdentifierV2.getComponentManufacturer().toString();
this.model = componentIdentifierV2.getComponentModel().toString();
this.serialNumber = componentIdentifierV2.getComponentSerial().toString();
this.revisionNumber = componentIdentifierV2.getComponentRevision().toString();
if (componentIdentifierV2.getFieldReplaceable() != null) {
this.fieldReplaceable = componentIdentifierV2.getFieldReplaceable().isTrue();
}
StringBuilder sb = new StringBuilder();
for (ComponentAddress element : componentIdentifierV2.getComponentAddresses()) {
sb.append(String.format("%s:%s;", element.getAddressTypeValue(),
element.getAddressValue().toString()));
}
componentAddress = sb.toString();
// V2 fields
if (componentIdentifier.isVersion2()
&& componentIdentifier instanceof ComponentIdentifierV2 ciV2) {
// this is a downside of findbugs, the code is set up to indicate if a CI is V2 or not
// but find bugs is throwing a flag because instanceof isn't being used.
this.componentClassValue = ciV2.getComponentClass().getComponentIdentifier();
this.componentClassStr = ciV2.getComponentClass().toString();
this.componentClassType = ciV2.getComponentClass().getRegistryType();
this.attributeStatus = ciV2.getAttributeStatus();
this.version2 = true;
if (ciV2.getCertificateIdentifier() != null) {
this.issuerDN = ciV2.getCertificateIdentifier().getIssuerDN().toString();
if (ciV2.getComponentPlatformUri() != null) {
this.uniformResourceIdentifier = ciV2.getComponentPlatformUri()
.getUniformResourceIdentifier().toString();
}
this.componentClassValue = componentIdentifierV2.getComponentClass().getComponentIdentifier();
this.componentClassStr = componentIdentifierV2.getComponentClass().toString();
this.componentClassType = componentIdentifierV2.getComponentClass().getRegistryType();
this.attributeStatus = componentIdentifierV2.getAttributeStatus();
this.version2 = true;
if (componentIdentifierV2.getComponentPlatformCert() != null) {
this.issuerDN = componentIdentifierV2.getComponentPlatformCert().getIssuerDN().toString();
if (componentIdentifierV2.getComponentPlatformCertUri() != null) {
this.uniformResourceIdentifier = componentIdentifierV2.getComponentPlatformCertUri()
.getUniformResourceIdentifier().toString();
}
}
}

View File

@ -2,10 +2,10 @@ package hirs.attestationca.persist.entity.userdefined.certificate;
import com.google.common.base.Preconditions;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfiguration;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfigurationV1;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.TBBSecurityAssertion;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.URIReference;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.PlatformConfigurationV2;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
@ -64,25 +64,30 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
* TCPA Trusted Platform Endorsement.
*/
public static final String CERTIFICATE_TYPE_1_2 = "TCPA Trusted Platform Endorsement";
/**
* TCG Trusted Platform Endorsement.
*/
public static final String CERTIFICATE_TYPE_2_0 = "TCG Trusted Platform Endorsement";
private static final int TCG_SPECIFICATION_LENGTH = 3;
// These are Object Identifiers (OIDs) for sections in the credentials
private static final String POLICY_QUALIFIER_CPSURI = "1.3.6.1.5.5.7.2.1";
private static final String POLICY_QUALIFIER_USER_NOTICE = "1.3.6.1.5.5.7.2.2";
// OID for TCG Attributes
private static final String PLATFORM_MANUFACTURER = "2.23.133.2.4";
private static final String PLATFORM_MODEL = "2.23.133.2.5";
private static final String PLATFORM_VERSION = "2.23.133.2.6";
private static final String PLATFORM_SERIAL = "2.23.133.2.23";
private static final String PLATFORM_BASEBOARD_CHASSIS_COMBINED = "2.23.133.5.1.6";
// OID for TCG Platform Class Common Attributes
private static final String PLATFORM_MANUFACTURER_2_0 = "2.23.133.5.1.1";
private static final String PLATFORM_MODEL_2_0 = "2.23.133.5.1.4";
private static final String PLATFORM_VERSION_2_0 = "2.23.133.5.1.5";
private static final String PLATFORM_SERIAL_2_0 = "2.23.133.5.1.6";
// OID for Certificate Attributes
private static final String TCG_PLATFORM_SPECIFICATION = "2.23.133.2.17";
private static final String TPM_SECURITY_ASSERTION = "2.23.133.2.18";
@ -255,8 +260,8 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
/**
* Verify if the AlgorithmIdentifiers are equal.
*
* @param id1 AlgorithIdentifier one
* @param id2 AlgorithIdentifier two
* @param id1 Algorithm Identifier one
* @param id2 Algorithm Identifier two
* @return True if are the same, False if not
*/
public static boolean isAlgIdEqual(final AlgorithmIdentifier id1,
@ -349,6 +354,9 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
return verifier.verify(attCert.getSignatureValue().getOctets());
}
/**
* Parses the Platform Certificate fields.
*/
private void parseFields() throws IOException {
AttributeCertificateInfo certificate = getAttributeCertificate().getAcinfo();
Map<String, String> policyQualifier = getPolicyQualifier(certificate);
@ -403,7 +411,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
}
/**
* Parse a 1.2 Platform Certificate (Attribute Certificate).
* Parses a 1.2 Platform Certificate (Attribute Certificate).
*
* @param certificate Attribute Certificate
*/
@ -456,7 +464,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
}
/**
* Parse a 2.0 Platform Certificate (Attribute Certificate).
* Parses a 2.0 Platform Certificate (Attribute Certificate).
*
* @param certificate Attribute Certificate
*/
@ -505,7 +513,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
}
/**
* Get the x509 Platform Certificate version.
* Retrieves the x509 Platform Certificate version.
*
* @return a big integer representing the certificate version.
*/
@ -524,7 +532,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
}
/**
* Get the cPSuri from the Certificate Policies.
* Retrieves the cPSuri from the Certificate Policies.
*
* @return cPSuri from the CertificatePolicies.
* @throws IOException when reading the certificate.
@ -540,7 +548,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
}
/**
* Get the Platform Configuration Attribute from the Platform Certificate.
* Retrieves the Platform Configuration Attribute from the Platform Certificate.
*
* @return a map with all the attributes
* @throws IllegalArgumentException when there is a parsing error
@ -550,8 +558,11 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
throws IllegalArgumentException, IOException {
Map<String, Object> attributes = new HashMap<>();
ASN1Sequence attributeSequence;
ASN1Encodable[] asn1EncodableArray = getAttributeCertificate().getAcinfo().getAttributes().toArray();
// Check all attributes for Platform Configuration
for (ASN1Encodable enc : getAttributeCertificate().getAcinfo().getAttributes().toArray()) {
for (ASN1Encodable enc : asn1EncodableArray) {
Attribute attr = Attribute.getInstance(enc);
attributeSequence
= ASN1Sequence.getInstance(attr.getAttrValues().getObjectAt(0));
@ -582,8 +593,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
break;
default:
// No class defined for this attribute
log.warn("No class defined for attribute with OID: "
+ attr.getAttrType().getId());
log.warn("No class defined for attribute with OID: {}", attr.getAttrType().getId());
break;
}
}
@ -610,12 +620,30 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
* @throws IllegalArgumentException when there is a parsing error
* @throws IOException when reading the certificate.
*/
public PlatformConfiguration getPlatformConfiguration()
public PlatformConfigurationV1 getPlatformConfigurationV1()
throws IllegalArgumentException, IOException {
if (getAttribute("platformConfiguration") != null
&& getAttribute("platformConfiguration") instanceof PlatformConfiguration) {
return (PlatformConfiguration) getAttribute("platformConfiguration");
&& getAttribute("platformConfiguration") instanceof PlatformConfigurationV1) {
return (PlatformConfigurationV1) getAttribute("platformConfiguration");
}
return null;
}
/**
* Get the Version 2 Platform Configuration Attribute from the Platform Certificate.
*
* @return a map with the Version 2 Platform Configuration information.
* @throws IllegalArgumentException when there is a parsing error
* @throws IOException when reading the certificate.
*/
public PlatformConfigurationV2 getPlatformConfigurationV2()
throws IllegalArgumentException, IOException {
if (getAttribute("platformConfiguration") != null
&& getAttribute("platformConfiguration") instanceof PlatformConfigurationV2) {
return (PlatformConfigurationV2) getAttribute("platformConfiguration");
}
return null;
@ -684,20 +712,39 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
}
/**
* Get the list of component identifiers if there are any.
* Retrieves the list of component identifiers if there are any.
*
* @return the list of component identifiers if there are any
*/
public List<ComponentIdentifier> getComponentIdentifiers() {
try {
PlatformConfiguration platformConfig = getPlatformConfiguration();
PlatformConfigurationV1 platformConfig = getPlatformConfigurationV1();
if (platformConfig != null) {
return platformConfig.getComponentIdentifier();
return platformConfig.getComponentIdentifiers();
}
} catch (IOException e) {
log.error("Unable to parse Platform Configuration from Credential or find"
log.error("Unable to parse Platform Configuration from Platform Credential or find"
+ "component identifiers");
}
return Collections.emptyList();
}
/**
* Retrieves the list of version 2 component identifiers if there are any.
*
* @return the list of version 2 component identifiers if there are any
*/
public List<ComponentIdentifierV2> getComponentIdentifiersV2() {
try {
PlatformConfigurationV2 platformConfigV2 = getPlatformConfigurationV2();
if (platformConfigV2 != null) {
return platformConfigV2.getComponentIdentifiers();
}
} catch (IOException e) {
log.error("Unable to parse Platform Configuration Version 2 from Platform Credential or find"
+ "version 2 component identifiers");
}
return Collections.emptyList();
}
}

View File

@ -8,7 +8,7 @@ import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1UTF8String;
/**
* Basic class that handle component addresses from the component identifier.
* Basic class that represents the component addresses from the component identifier object.
* <pre>
* componentAddress ::= SEQUENCE {
* addressType AddressType,

View File

@ -33,6 +33,10 @@ ComponentClass {
private static final String SMBIOS_COMPONENT_REGISTRY = "2.23.133.18.3.3";
private static final String PCIE_BASED_COMPONENT_REGISTRY = "2.23.133.18.3.4";
private static final String STORAGE_COMPONENT_REGISTRY = "2.23.133.18.3.5";
private static final Path WINDOWS_JSON_PATH = FileSystems.getDefault().getPath(
"C:/", "ProgramData", "hirs", "aca", "default-properties", "component-class.json");
@ -122,6 +126,8 @@ ComponentClass {
this.registryType = switch (registryOid) {
case TCG_COMPONENT_REGISTRY -> "TCG";
case SMBIOS_COMPONENT_REGISTRY -> "SMBIOS";
case PCIE_BASED_COMPONENT_REGISTRY -> "PCIE";
case STORAGE_COMPONENT_REGISTRY -> "STORAGE";
default -> UNKNOWN_STRING;
};

View File

@ -16,8 +16,8 @@ import java.util.List;
import java.util.stream.Collectors;
/**
* Basic class that handle component identifiers from the Platform Configuration
* Attribute.
* Basic class that represents version 1 of the component identifiers from the Version 1
* Platform Configuration Attribute.
* <pre>
* ComponentIdentifier ::= SEQUENCE {
* componentManufacturer UTF8String (SIZE (1..STRMAX)),
@ -26,7 +26,7 @@ import java.util.stream.Collectors;
* componentRevision [1] IMPLICIT UTF8String (SIZE (1..STRMAX)) OPTIONAL,
* componentManufacturerId [2] IMPLICIT PrivateEnterpriseNumber OPTIONAL,
* fieldReplaceable [3] IMPLICIT BOOLEAN OPTIONAL,
* componentAddress [4] IMPLICIT
* componentAddresses [4] IMPLICIT
* SEQUENCE(SIZE(1..CONFIGMAX)) OF ComponentAddress OPTIONAL}
* where STRMAX is 256, CONFIGMAX is 32
* </pre>
@ -80,7 +80,7 @@ public class ComponentIdentifier {
private ASN1Boolean fieldReplaceable;
private List<ComponentAddress> componentAddress;
private List<ComponentAddress> componentAddresses;
private boolean validationResult = true;
@ -94,7 +94,7 @@ public class ComponentIdentifier {
componentRevision = new DERUTF8String(NOT_SPECIFIED_COMPONENT);
componentManufacturerId = null;
fieldReplaceable = null;
componentAddress = new ArrayList<>();
componentAddresses = new ArrayList<>();
}
/**
@ -106,7 +106,7 @@ public class ComponentIdentifier {
* @param componentRevision represents the component revision
* @param componentManufacturerId represents the component manufacturer ID
* @param fieldReplaceable represents if the component is replaceable
* @param componentAddress represents a list of addresses
* @param componentAddresses represents a list of addresses
*/
public ComponentIdentifier(final DERUTF8String componentManufacturer,
final DERUTF8String componentModel,
@ -114,14 +114,14 @@ public class ComponentIdentifier {
final DERUTF8String componentRevision,
final ASN1ObjectIdentifier componentManufacturerId,
final ASN1Boolean fieldReplaceable,
final List<ComponentAddress> componentAddress) {
final List<ComponentAddress> componentAddresses) {
this.componentManufacturer = componentManufacturer;
this.componentModel = componentModel;
this.componentSerial = componentSerial;
this.componentRevision = componentRevision;
this.componentManufacturerId = componentManufacturerId;
this.fieldReplaceable = fieldReplaceable;
this.componentAddress = componentAddress.stream().toList();
this.componentAddresses = componentAddresses.stream().toList();
}
/**
@ -160,7 +160,7 @@ public class ComponentIdentifier {
break;
case COMPONENT_ADDRESS:
ASN1Sequence addressesSequence = ASN1Sequence.getInstance(taggedObj, false);
componentAddress = retrieveComponentAddress(addressesSequence);
componentAddresses = retrieveComponentAddress(addressesSequence);
break;
default:
throw new IllegalArgumentException("Component identifier contains "
@ -229,14 +229,16 @@ public class ComponentIdentifier {
if (fieldReplaceable != null) {
sb.append(fieldReplaceable);
}
sb.append(", componentAddress=");
if (!componentAddress.isEmpty()) {
sb.append(componentAddress
sb.append(", componentAddresses=");
if (!componentAddresses.isEmpty()) {
sb.append(componentAddresses
.stream()
.map(Object::toString)
.collect(Collectors.joining(",")));
}
sb.append(", certificateIdentifier=");
if (sb.charAt(sb.length() - 1) == ',') {
sb.deleteCharAt(sb.length() - 1);
}
sb.append("}");
return sb.toString();

View File

@ -1,108 +0,0 @@
package hirs.attestationca.persist.entity.userdefined.certificate.attributes;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Abstract class that provides base info for Platform Configuration of
* the Platform Certificate Attribute.
*/
@AllArgsConstructor
public abstract class PlatformConfiguration {
private ArrayList<ComponentIdentifier> componentIdentifier = new ArrayList<>();
@Getter
@Setter
private URIReference componentIdentifierUri;
private ArrayList<PlatformProperty> platformProperties = new ArrayList<>();
@Getter
@Setter
private URIReference platformPropertiesUri;
/**
* Default constructor.
*/
public PlatformConfiguration() {
this.componentIdentifier = new ArrayList<>();
this.componentIdentifierUri = null;
this.platformProperties = new ArrayList<>();
this.platformPropertiesUri = null;
}
/**
* Constructor given the Platform Configuration values.
*
* @param componentIdentifier list containing all the components inside the
* Platform Configuration.
* @param platformProperties list containing all the properties inside the
* Platform Configuration.
* @param platformPropertiesUri object containing the URI Reference
*/
public PlatformConfiguration(final List<ComponentIdentifier> componentIdentifier,
final List<PlatformProperty> platformProperties,
final URIReference platformPropertiesUri) {
this.componentIdentifier = new ArrayList<>(componentIdentifier);
this.platformProperties = new ArrayList<>(platformProperties);
this.platformPropertiesUri = platformPropertiesUri;
}
/**
* @return the componentIdentifier
*/
public List<ComponentIdentifier> getComponentIdentifier() {
return Collections.unmodifiableList(componentIdentifier);
}
/**
* @param componentIdentifier the componentIdentifier to set
*/
public void setComponentIdentifier(final List<ComponentIdentifier> componentIdentifier) {
this.componentIdentifier = new ArrayList<>(componentIdentifier);
}
/**
* Add function for the component identifier array.
*
* @param componentIdentifier object to add
* @return status of the add, if successful or not
*/
protected boolean add(final ComponentIdentifier componentIdentifier) {
if (this.componentIdentifier != null) {
return this.componentIdentifier.add(componentIdentifier);
}
return false;
}
/**
* @return the platformProperties
*/
public List<PlatformProperty> getPlatformProperties() {
return Collections.unmodifiableList(platformProperties);
}
/**
* @param platformProperties the platformProperties to set
*/
public void setPlatformProperties(final List<PlatformProperty> platformProperties) {
this.platformProperties = new ArrayList<>(platformProperties);
}
/**
* Add function for the platform property array.
*
* @param platformProperty property object to add
* @return status of the add, if successful or not
*/
protected boolean add(final PlatformProperty platformProperty) {
if (this.platformProperties != null) {
return this.platformProperties.add(platformProperty);
}
return false;
}
}

View File

@ -1,28 +1,53 @@
package hirs.attestationca.persist.entity.userdefined.certificate.attributes;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* Basic class that handle Platform Configuration for the Platform Certificate
* Basic class that represents the Version 1 Platform Configuration used for the Platform Certificate
* Attribute.
* <pre>
* PlatformConfiguration ::= SEQUENCE {
* componentIdentifier [0] IMPLICIT SEQUENCE(SIZE(1..CONFIGMAX)) OF
* componentIdentifiers [0] IMPLICIT SEQUENCE(SIZE(1..CONFIGMAX)) OF
* ComponentIdentifier OPTIONAL,
* platformProperties [1] IMPLICIT SEQUENCE(SIZE(1..CONFIGMAX)) OF Properties OPTIONAL,
* platformPropertiesUri [2] IMPLICIT URIReference OPTIONAL }
* </pre>
*/
public class PlatformConfigurationV1 extends PlatformConfiguration {
@AllArgsConstructor
public class PlatformConfigurationV1 {
private static final int COMPONENT_IDENTIFIER = 0;
private static final int PLATFORM_PROPERTIES = 1;
private static final int PLATFORM_PROPERTIES_URI = 2;
private List<ComponentIdentifier> componentIdentifiers;
private List<PlatformProperty> platformProperties;
@Getter
@Setter
private URIReference platformPropertiesUri;
/**
* Default constructor.
*/
public PlatformConfigurationV1() {
componentIdentifiers = new ArrayList<>();
platformProperties = new ArrayList<>();
platformPropertiesUri = null;
}
/**
* Constructor given the SEQUENCE that contains Platform Configuration.
*
@ -32,7 +57,7 @@ public class PlatformConfigurationV1 extends PlatformConfiguration {
public PlatformConfigurationV1(final ASN1Sequence sequence) throws IllegalArgumentException {
//Default values
setComponentIdentifier(new ArrayList<>());
setComponentIdentifiers(new ArrayList<>());
setPlatformProperties(new ArrayList<>());
setPlatformPropertiesUri(null);
@ -42,7 +67,7 @@ public class PlatformConfigurationV1 extends PlatformConfiguration {
//Set information based on the set tagged
switch (taggedSequence.getTagNo()) {
case COMPONENT_IDENTIFIER:
//Get componentIdentifier
//Get componentIdentifiers
ASN1Sequence componentConfiguration
= ASN1Sequence.getInstance(taggedSequence, false);
@ -77,6 +102,62 @@ public class PlatformConfigurationV1 extends PlatformConfiguration {
}
}
/**
* @return list of version 1 component identifiers
*/
public List<ComponentIdentifier> getComponentIdentifiers() {
return Collections.unmodifiableList(componentIdentifiers);
}
/**
* @param componentIdentifiers list of version 1 component identifiers
*/
public void setComponentIdentifiers(final List<ComponentIdentifier> componentIdentifiers) {
this.componentIdentifiers = new ArrayList<>(componentIdentifiers);
}
/**
* Add function for the version 1 component identifier array.
*
* @param componentIdentifier object to add
* @return status of the add, if successful or not
*/
protected boolean add(final ComponentIdentifier componentIdentifier) {
if (this.componentIdentifiers != null) {
return this.componentIdentifiers.add(componentIdentifier);
}
return false;
}
/**
* @return the platformProperties
*/
public List<PlatformProperty> getPlatformProperties() {
return Collections.unmodifiableList(platformProperties);
}
/**
* @param platformProperties the platformProperties to set
*/
public void setPlatformProperties(final List<PlatformProperty> platformProperties) {
this.platformProperties = new ArrayList<>(platformProperties);
}
/**
* Add function for the platform property array.
*
* @param platformProperty property object to add
* @return status of the add, if successful or not
*/
protected boolean add(final PlatformProperty platformProperty) {
if (this.platformProperties != null) {
return this.platformProperties.add(platformProperty);
}
return false;
}
/**
* Creates a string representation of the Platform Configuration V1 object.
*
@ -86,15 +167,15 @@ public class PlatformConfigurationV1 extends PlatformConfiguration {
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("PlatformConfiguration{");
sb.append("componentIdentifier=");
if (getComponentIdentifier().size() > 0) {
sb.append(getComponentIdentifier()
sb.append("componentIdentifiers=");
if (!getComponentIdentifiers().isEmpty()) {
sb.append(getComponentIdentifiers()
.stream()
.map(Object::toString)
.collect(Collectors.joining(",")));
}
sb.append(", platformProperties=");
if (getPlatformProperties().size() > 0) {
if (!getPlatformProperties().isEmpty()) {
sb.append(getPlatformProperties()
.stream()
.map(Object::toString)

View File

@ -16,6 +16,7 @@ import org.apache.commons.lang3.StringUtils;
* removed (2) }
* </pre>
*/
@Getter
@AllArgsConstructor
public enum AttributeStatus {
/**
@ -35,6 +36,5 @@ public enum AttributeStatus {
*/
EMPTY_STATUS(StringUtils.EMPTY);
@Getter
private final String value;
}

View File

@ -76,6 +76,12 @@ public class CertificateIdentifier {
}
}
/**
* Helper method that parses the attribute certificate id from the provided attribute
* certificate ASN1 Sequence.
*
* @param attrCertSeq ASN1 attribute certificate sequence
*/
private void parseAttributeCertId(final ASN1Sequence attrCertSeq) {
//Check if it have a valid number of identifiers
if (attrCertSeq.size() != SEQUENCE_NUMBER) {
@ -87,6 +93,11 @@ public class CertificateIdentifier {
hashSigValue = attrCertSeq.getObjectAt(1).toString();
}
/**
* Helper method that parses the generic certificate id from the provided issuer serial ASN1 sequence.
*
* @param issuerSerialSeq ASN1 issuer serial sequence
*/
private void parseGenericCertId(final ASN1Sequence issuerSerialSeq) {
//Check if it have a valid number of identifiers
if (issuerSerialSeq.size() != SEQUENCE_NUMBER) {

View File

@ -20,17 +20,18 @@ import java.util.List;
import java.util.stream.Collectors;
/**
* Basic class that handle component identifiers from the Platform Configuration
* Attribute.
* Basic class that represents version 2 of the component identifiers from the Version 2
* Platform Configuration Attribute.
* <pre>
* ComponentIdentifier ::= SEQUENCE {
* componentClass ComponentClass
* componentManufacturer UTF8String (SIZE (1..STRMAX)),
* componentModel UTF8String (SIZE (1..STRMAX)),
* componentSerial[0] IMPLICIT UTF8String (SIZE (1..STRMAX)) OPTIONAL,
* componentRevision [1] IMPLICIT UTF8String (SIZE (1..STRMAX)) OPTIONAL,
* componentManufacturerId [2] IMPLICIT PrivateEnterpriseNumber OPTIONAL,
* fieldReplaceable [3] IMPLICIT BOOLEAN OPTIONAL,
* componentAddress [4] IMPLICIT
* componentAddresses [4] IMPLICIT
* SEQUENCE(SIZE(1..CONFIGMAX)) OF ComponentAddress OPTIONAL
* componentPlatformCert [5] IMPLICIT CertificateIdentifier OPTIONAL,
* componentPlatformCertUri [6] IMPLICIT URIReference OPTIONAL,
@ -48,15 +49,15 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
// Additional optional identifiers for version 2
private static final int COMPONENT_PLATFORM_CERT = 5;
private static final int COMPONENT_PLATFORM_URI = 6;
private static final int COMPONENT_PLATFORM_CERT_URI = 6;
private static final int ATTRIBUTE_STATUS = 7;
private ComponentClass componentClass;
private CertificateIdentifier certificateIdentifier;
private CertificateIdentifier componentPlatformCert;
private URIReference componentPlatformUri;
private URIReference componentPlatformCertUri;
private AttributeStatus attributeStatus;
@ -66,25 +67,25 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
public ComponentIdentifierV2() {
super();
componentClass = new ComponentClass();
certificateIdentifier = null;
componentPlatformUri = null;
componentPlatformCert = null;
componentPlatformCertUri = null;
attributeStatus = AttributeStatus.EMPTY_STATUS;
}
/**
* Constructor given the components values.
*
* @param componentClass represent the component type
* @param componentManufacturer represents the component manufacturer
* @param componentModel represents the component model
* @param componentSerial represents the component serial number
* @param componentRevision represents the component revision
* @param componentManufacturerId represents the component manufacturer ID
* @param fieldReplaceable represents if the component is replaceable
* @param componentAddress represents a list of addresses
* @param certificateIdentifier object representing certificate Id
* @param componentPlatformUri object containing the URI Reference
* @param attributeStatus object containing enumerated status
* @param componentClass represent the component type
* @param componentManufacturer represents the component manufacturer
* @param componentModel represents the component model
* @param componentSerial represents the component serial number
* @param componentRevision represents the component revision
* @param componentManufacturerId represents the component manufacturer ID
* @param fieldReplaceable represents if the component is replaceable
* @param componentAddress represents a list of addresses
* @param componentPlatformCert object representing certificate Id
* @param componentPlatformCertUri object containing the URI Reference
* @param attributeStatus object containing enumerated status
*/
public ComponentIdentifierV2(final ComponentClass componentClass,
final DERUTF8String componentManufacturer,
@ -94,16 +95,16 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
final ASN1ObjectIdentifier componentManufacturerId,
final ASN1Boolean fieldReplaceable,
final List<ComponentAddress> componentAddress,
final CertificateIdentifier certificateIdentifier,
final URIReference componentPlatformUri,
final CertificateIdentifier componentPlatformCert,
final URIReference componentPlatformCertUri,
final AttributeStatus attributeStatus) {
super(componentManufacturer, componentModel, componentSerial,
componentRevision, componentManufacturerId, fieldReplaceable,
componentAddress);
this.componentClass = componentClass;
// additional optional component identifiers
this.certificateIdentifier = certificateIdentifier;
this.componentPlatformUri = componentPlatformUri;
this.componentPlatformCert = componentPlatformCert;
this.componentPlatformCertUri = componentPlatformCertUri;
this.attributeStatus = attributeStatus;
}
@ -150,15 +151,15 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
break;
case COMPONENT_ADDRESS:
ASN1Sequence addressesSequence = ASN1Sequence.getInstance(taggedObj, false);
this.setComponentAddress(retrieveComponentAddress(addressesSequence));
this.setComponentAddresses(retrieveComponentAddress(addressesSequence));
break;
case COMPONENT_PLATFORM_CERT:
ASN1Sequence ciSequence = ASN1Sequence.getInstance(taggedObj, false);
certificateIdentifier = new CertificateIdentifier(ciSequence);
componentPlatformCert = new CertificateIdentifier(ciSequence);
break;
case COMPONENT_PLATFORM_URI:
case COMPONENT_PLATFORM_CERT_URI:
ASN1Sequence uriSequence = ASN1Sequence.getInstance(taggedObj, false);
this.componentPlatformUri = new URIReference(uriSequence);
this.componentPlatformCertUri = new URIReference(uriSequence);
break;
case ATTRIBUTE_STATUS:
ASN1Enumerated enumerated = ASN1Enumerated.getInstance(taggedObj, false);
@ -172,34 +173,6 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
}
}
/**
* @return true if the component has been modified.
*/
public final boolean isAdded() {
return getAttributeStatus() == AttributeStatus.ADDED;
}
/**
* @return true if the component has been modified.
*/
public final boolean isModified() {
return getAttributeStatus() == AttributeStatus.MODIFIED;
}
/**
* @return true if the component has been removed.
*/
public final boolean isRemoved() {
return getAttributeStatus() == AttributeStatus.REMOVED;
}
/**
* @return true if the component status wasn't set.
*/
public final boolean isEmpty() {
return (getAttributeStatus() == AttributeStatus.EMPTY_STATUS)
|| (getAttributeStatus() == null);
}
/**
* @return indicates the type of platform certificate.
@ -238,20 +211,20 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
if (getFieldReplaceable() != null) {
sb.append(getFieldReplaceable());
}
sb.append(", componentAddress=");
if (getComponentAddress().size() > 0) {
sb.append(getComponentAddress()
sb.append(", componentAddresses=");
if (!getComponentAddresses().isEmpty()) {
sb.append(getComponentAddresses()
.stream()
.map(Object::toString)
.collect(Collectors.joining(",")));
}
sb.append(", certificateIdentifier=");
if (certificateIdentifier != null) {
sb.append(certificateIdentifier);
sb.append(", componentPlatformCert=");
if (componentPlatformCert != null) {
sb.append(componentPlatformCert);
}
sb.append(", componentPlatformUri=");
if (componentPlatformUri != null) {
sb.append(componentPlatformUri);
sb.append(", componentPlatformCertUri=");
if (componentPlatformCertUri != null) {
sb.append(componentPlatformCertUri);
}
sb.append(", status=");
if (attributeStatus != null) {

View File

@ -1,15 +1,20 @@
package hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfiguration;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformProperty;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.URIReference;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* Basic class that handle Platform Configuration for the Platform Certificate
* Basic class that represents the Version 2 Platform Configuration used for the Platform Certificate
* Attribute.
* <pre>
* PlatformConfiguration ::= SEQUENCE {
@ -20,23 +25,49 @@ import java.util.stream.Collectors;
* platformPropertiesUri [3] IMPLICIT URIReference OPTIONAL }
* </pre>
*/
public class PlatformConfigurationV2 extends PlatformConfiguration {
@AllArgsConstructor
public class PlatformConfigurationV2 {
private static final int COMPONENT_IDENTIFIER = 0;
private static final int COMPONENT_IDENTIFIER_URI = 1;
private static final int PLATFORM_PROPERTIES = 2;
private static final int PLATFORM_PROPERTIES_URI = 3;
private List<ComponentIdentifierV2> componentIdentifiers;
@Getter
@Setter
private URIReference componentIdentifiersUri;
private List<PlatformProperty> platformProperties;
@Getter
@Setter
private URIReference platformPropertiesUri;
/**
* Constructor given the SEQUENCE that contains Platform Configuration.
* Default constructor.
*/
public PlatformConfigurationV2() {
componentIdentifiers = new ArrayList<>();
componentIdentifiersUri = null;
platformProperties = new ArrayList<>();
platformPropertiesUri = null;
}
/**
* Constructor given the SEQUENCE that contains version 2 Platform Configuration.
*
* @param sequence containing the the Platform Configuration.
* @throws IllegalArgumentException if there was an error on the parsing
* @param sequence containing the version 2 Platform Configuration.
* @throws IllegalArgumentException if there was an error while parsing
*/
public PlatformConfigurationV2(final ASN1Sequence sequence) throws IllegalArgumentException {
//Default values
setComponentIdentifier(new ArrayList<>());
setComponentIdentifierUri(null);
setComponentIdentifiers(new ArrayList<>());
setComponentIdentifiersUri(null);
setPlatformProperties(new ArrayList<>());
setPlatformPropertiesUri(null);
@ -62,7 +93,7 @@ public class PlatformConfigurationV2 extends PlatformConfiguration {
//Get componentIdentifierURI
ASN1Sequence componentUri = ASN1Sequence.getInstance(taggedSequence, false);
//Save Component Identifier URI
setComponentIdentifierUri(new URIReference(componentUri));
setComponentIdentifiersUri(new URIReference(componentUri));
break;
case PLATFORM_PROPERTIES:
//Get platformProperties
@ -87,6 +118,64 @@ public class PlatformConfigurationV2 extends PlatformConfiguration {
}
}
/**
* @return a collection of version 2 component identifiers.
*/
public List<ComponentIdentifierV2> getComponentIdentifiers() {
return Collections.unmodifiableList(componentIdentifiers);
}
/**
* @param componentIdentifiers list of version 2 component identifiers
*/
public void setComponentIdentifiers(
final List<ComponentIdentifierV2> componentIdentifiers) {
this.componentIdentifiers = new ArrayList<>(componentIdentifiers);
}
/**
* Add function for the component identifier array.
*
* @param componentIdentifierV2 object to add
* @return status of the add, if successful or not
*/
protected boolean add(final ComponentIdentifierV2 componentIdentifierV2) {
if (this.componentIdentifiers != null) {
return this.componentIdentifiers.add(componentIdentifierV2);
}
return false;
}
/**
* @return the platformProperties
*/
public List<PlatformProperty> getPlatformProperties() {
return Collections.unmodifiableList(platformProperties);
}
/**
* @param platformProperties the platformProperties to set
*/
public void setPlatformProperties(final List<PlatformProperty> platformProperties) {
this.platformProperties = new ArrayList<>(platformProperties);
}
/**
* Add function for the platform property array.
*
* @param platformProperty property object to add
* @return status of the add, if successful or not
*/
protected boolean add(final PlatformProperty platformProperty) {
if (this.platformProperties != null) {
return this.platformProperties.add(platformProperty);
}
return false;
}
/**
* Creates a string representation of the Platform Configuration V2 object.
*
@ -95,20 +184,20 @@ public class PlatformConfigurationV2 extends PlatformConfiguration {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("PlatformConfiguration{");
sb.append("componentIdentifier=");
if (getComponentIdentifier().size() > 0) {
sb.append(getComponentIdentifier()
sb.append("PlatformConfigurationV2{");
sb.append("componentIdentifiers=");
if (!getComponentIdentifiers().isEmpty()) {
sb.append(getComponentIdentifiers()
.stream()
.map(Object::toString)
.collect(Collectors.joining(",")));
}
sb.append(", componentIdentifierUri=");
if (getComponentIdentifierUri() != null) {
sb.append(getComponentIdentifierUri());
sb.append(", componentIdentifiersUri=");
if (getComponentIdentifiersUri() != null) {
sb.append(getComponentIdentifiersUri());
}
sb.append(", platformProperties=");
if (getPlatformProperties().size() > 0) {
if (!getPlatformProperties().isEmpty()) {
sb.append(getPlatformProperties()
.stream()
.map(Object::toString)

View File

@ -55,10 +55,14 @@ public class ComponentInfo extends ArchivableEntity {
@XmlElement
@Column
private String componentClass;
private String componentClassValue;
@XmlElement
@Column
private String componentClassRegistry;
/**
* Base constructor for children.
* Constructor.
*
* @param componentManufacturer Component Manufacturer (must not be null)
* @param componentModel Component Model (must not be null)
@ -87,24 +91,34 @@ public class ComponentInfo extends ArchivableEntity {
final String componentModel,
final String componentSerial,
final String componentRevision) {
if (isComplete(
componentManufacturer,
componentModel,
componentSerial,
componentRevision)) {
log.error("ComponentInfo: manufacturer and/or "
+ "model can not be null");
throw new NullPointerException("ComponentInfo: manufacturer and/or "
+ "model can not be null");
if (deviceName == null) {
log.error("Component Info's device name cannot be null.");
this.deviceName = "";
} else {
this.deviceName = deviceName;
}
this.deviceName = deviceName;
this.componentManufacturer = componentManufacturer.trim();
this.componentModel = componentModel.trim();
if (componentManufacturer == null) {
log.error("Component Info's manufacturer cannot be null.");
this.componentManufacturer = "";
} else {
this.componentManufacturer = componentManufacturer.trim();
}
if (componentModel == null) {
log.error("Component Info's model cannot be null.");
this.componentModel = "";
} else {
this.componentModel = componentModel.trim();
}
if (componentSerial != null) {
this.componentSerial = componentSerial.trim();
} else {
this.componentSerial = ComponentIdentifier.NOT_SPECIFIED_COMPONENT;
}
if (componentRevision != null) {
this.componentRevision = componentRevision.trim();
} else {
@ -115,44 +129,28 @@ public class ComponentInfo extends ArchivableEntity {
/**
* Constructor.
*
* @param deviceName the host machine associated with this component.
* @param componentManufacturer Component Manufacturer (must not be null)
* @param componentModel Component Model (must not be null)
* @param componentSerial Component Serial Number (can be null)
* @param componentRevision Component Revision or Version (can be null)
* @param componentClass Component Class (can be null)
* @param deviceName the host machine associated with this component.
* @param componentManufacturer Component Manufacturer (must not be null)
* @param componentModel Component Model (must not be null)
* @param componentSerial Component Serial Number (can be null)
* @param componentRevision Component Revision or Version (can be null)
* @param componentClassValue Component Class Value (can be null)
* @param componentClassRegistry Component Class Registry (can be null)
*/
public ComponentInfo(final String deviceName,
final String componentManufacturer,
final String componentModel,
final String componentSerial,
final String componentRevision,
final String componentClass) {
final String componentClassValue,
final String componentClassRegistry) {
this(deviceName, componentManufacturer, componentModel,
componentSerial, componentRevision);
this.componentClass = Objects.requireNonNullElse(componentClass, StringUtils.EMPTY);
this.componentClassValue = Objects.requireNonNullElse(componentClassValue, StringUtils.EMPTY);
this.componentClassRegistry = Objects.requireNonNullElse(componentClassRegistry, StringUtils.EMPTY);
}
/**
* Determines whether the given properties represent a
* ComponentInfo that will be useful in validation.
* Currently, only components which have a non-null
* manufacturer and model are considered valid.
*
* @param componentManufacturer a String containing a component's manufacturer
* @param componentModel a String representing a component's model
* @param componentSerial a String representing a component's serial number
* @param componentRevision a String representing a component's revision
* @return true if the component is valid, false if not
*/
public static boolean isComplete(final String componentManufacturer,
final String componentModel,
final String componentSerial,
final String componentRevision) {
return (StringUtils.isEmpty(componentManufacturer)
|| StringUtils.isEmpty(componentModel));
}
/**
* Returns a hash code that is associated with common fields for components.
@ -161,6 +159,6 @@ public class ComponentInfo extends ArchivableEntity {
*/
public int hashCommonElements() {
return Objects.hash(componentManufacturer, componentModel,
componentSerial, componentRevision, componentClass);
componentSerial, componentRevision, componentClassValue, componentClassRegistry);
}
}

View File

@ -19,11 +19,11 @@ import java.io.Serializable;
public class FirmwareInfo implements Serializable {
@XmlElement
@Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
@Column(nullable = false)
private final String biosVendor;
@XmlElement
@Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
@Column(nullable = false)
private final String biosVersion;
@XmlElement

View File

@ -22,11 +22,11 @@ import java.io.Serializable;
public class HardwareInfo implements Serializable {
@XmlElement
@Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
@Column(nullable = false)
private String manufacturer = DeviceInfoEnums.NOT_SPECIFIED;
@XmlElement
@Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
@Column(nullable = false)
private String productName = DeviceInfoEnums.NOT_SPECIFIED;
@XmlElement
@ -34,15 +34,15 @@ public class HardwareInfo implements Serializable {
private String version = DeviceInfoEnums.NOT_SPECIFIED;
@XmlElement
@Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
@Column(nullable = false)
private String systemSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
@XmlElement
@Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
@Column(nullable = false)
private String chassisSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
@XmlElement
@Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
@Column(nullable = false)
private String baseboardSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
/**

View File

@ -23,7 +23,7 @@ public class NetworkInfo implements Serializable {
@XmlElement
@Getter
@Column(length = DeviceInfoEnums.LONG_STRING_LENGTH)
@Column
private String hostname;
@XmlElement

View File

@ -21,11 +21,11 @@ import java.io.Serializable;
public class OSInfo implements Serializable {
@XmlElement
@Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
@Column(nullable = false)
private final String osName;
@XmlElement
@Column(length = DeviceInfoEnums.LONG_STRING_LENGTH, nullable = false)
@Column(nullable = false)
private final String osVersion;
@XmlElement
@ -33,11 +33,11 @@ public class OSInfo implements Serializable {
private final String osArch;
@XmlElement
@Column(length = DeviceInfoEnums.SHORT_STRING_LENGTH, nullable = true)
@Column(length = DeviceInfoEnums.SHORT_STRING_LENGTH)
private final String distribution;
@XmlElement
@Column(length = DeviceInfoEnums.SHORT_STRING_LENGTH, nullable = true)
@Column(length = DeviceInfoEnums.SHORT_STRING_LENGTH)
private final String distributionRelease;
/**

View File

@ -30,23 +30,23 @@ public class TPMInfo implements Serializable {
private static final int MAX_BLOB_SIZE = 65535;
@XmlElement
@Column(length = DeviceInfoEnums.MED_STRING_LENGTH, nullable = true)
@Column(length = DeviceInfoEnums.MED_STRING_LENGTH)
private String tpmMake;
@XmlElement
@Column(nullable = true)
@Column
private short tpmVersionMajor;
@XmlElement
@Column(nullable = true)
@Column
private short tpmVersionMinor;
@XmlElement
@Column(nullable = true)
@Column
private short tpmVersionRevMajor;
@XmlElement
@Column(nullable = true)
@Column
private short tpmVersionRevMinor;
/**
@ -60,13 +60,13 @@ public class TPMInfo implements Serializable {
@JsonIgnore
private X509Certificate identityCertificate;
@Column(nullable = true, columnDefinition = "blob")
@Column(columnDefinition = "blob")
private byte[] pcrValues;
@Column(nullable = true, columnDefinition = "blob")
@Column(columnDefinition = "blob")
private byte[] tpmQuoteHash;
@Column(nullable = true, columnDefinition = "blob")
@Column(columnDefinition = "blob")
private byte[] tpmQuoteSignature;
/**

View File

@ -1,30 +0,0 @@
package hirs.attestationca.persist.entity.userdefined.info.component;
import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import hirs.utils.enums.ComponentType;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import lombok.NoArgsConstructor;
/**
* Class to hold BIOS/UEFI Component information.
*/
@NoArgsConstructor
@Entity
@DiscriminatorValue(value = ComponentType.Values.BIOS_UEFI)
public class BIOSComponentInfo extends ComponentInfo {
/**
* Constructor.
*
* @param componentManufacturer Component Manufacturer (must not be null)
* @param componentModel Component Model (must not be null)
* @param componentRevision Component Revision or Version (can be null)
*/
public BIOSComponentInfo(final String componentManufacturer,
final String componentModel,
final String componentRevision) {
super(componentManufacturer, componentModel, null,
componentRevision);
}
}

View File

@ -1,32 +0,0 @@
package hirs.attestationca.persist.entity.userdefined.info.component;
import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import hirs.utils.enums.ComponentType;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import lombok.NoArgsConstructor;
/**
* Class to hold information about baseboard components.
*/
@NoArgsConstructor
@Entity
@DiscriminatorValue(value = ComponentType.Values.BASEBOARD)
public class BaseboardComponentInfo extends ComponentInfo {
/**
* Constructor.
*
* @param componentManufacturer Component Manufacturer (must not be null)
* @param componentModel Component Model (must not be null)
* @param componentSerial Component Serial Number (can be null)
* @param componentRevision Component Revision or Version (can be null)
*/
public BaseboardComponentInfo(final String componentManufacturer,
final String componentModel,
final String componentSerial,
final String componentRevision) {
super(componentManufacturer, componentModel, componentSerial,
componentRevision);
}
}

View File

@ -1,32 +0,0 @@
package hirs.attestationca.persist.entity.userdefined.info.component;
import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import hirs.utils.enums.ComponentType;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import lombok.NoArgsConstructor;
/**
* Class to hold chassis component information.
*/
@NoArgsConstructor
@Entity
@DiscriminatorValue(value = ComponentType.Values.CHASSIS)
public class ChassisComponentInfo extends ComponentInfo {
/**
* Constructor.
*
* @param componentManufacturer Component Manufacturer (must not be null)
* @param componentModel Component Model (must not be null)
* @param componentSerial Component Serial Number (can be null)
* @param componentRevision Component Revision or Version (can be null)
*/
public ChassisComponentInfo(final String componentManufacturer,
final String componentModel,
final String componentSerial,
final String componentRevision) {
super(componentManufacturer, componentModel,
componentSerial, componentRevision);
}
}

View File

@ -1,32 +0,0 @@
package hirs.attestationca.persist.entity.userdefined.info.component;
import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import hirs.utils.enums.ComponentType;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import lombok.NoArgsConstructor;
/**
* Class to hold hard drive component information.
*/
@NoArgsConstructor
@Entity
@DiscriminatorValue(value = ComponentType.Values.HARD_DRIVE)
public class HardDriveComponentInfo extends ComponentInfo {
/**
* Constructor.
*
* @param componentManufacturer Component Manufacturer (must not be null)
* @param componentModel Component Model (must not be null)
* @param componentSerial Component Serial Number (can be null)
* @param componentRevision Component Revision or Version (can be null)
*/
public HardDriveComponentInfo(final String componentManufacturer,
final String componentModel,
final String componentSerial,
final String componentRevision) {
super(componentManufacturer, componentModel,
componentSerial, componentRevision);
}
}

View File

@ -1,32 +0,0 @@
package hirs.attestationca.persist.entity.userdefined.info.component;
import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import hirs.utils.enums.ComponentType;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import lombok.NoArgsConstructor;
/**
* Class to hold memory component information.
*/
@NoArgsConstructor
@Entity
@DiscriminatorValue(value = ComponentType.Values.MEMORY)
public class MemoryComponentInfo extends ComponentInfo {
/**
* Constructor.
*
* @param componentManufacturer Component Manufacturer (must not be null)
* @param componentModel Component Model (must not be null)
* @param componentSerial Component Serial Number (can be null)
* @param componentRevision Component Revision or Version (can be null)
*/
public MemoryComponentInfo(final String componentManufacturer,
final String componentModel,
final String componentSerial,
final String componentRevision) {
super(componentManufacturer, componentModel,
componentSerial, componentRevision);
}
}

View File

@ -1,32 +0,0 @@
package hirs.attestationca.persist.entity.userdefined.info.component;
import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import hirs.utils.enums.ComponentType;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import lombok.NoArgsConstructor;
/**
* Class to hold Network Interface Card (NIC) component information.
*/
@NoArgsConstructor
@Entity
@DiscriminatorValue(value = ComponentType.Values.NIC)
public class NICComponentInfo extends ComponentInfo {
/**
* Constructor.
*
* @param componentManufacturer Component Manufacturer (must not be null)
* @param componentModel Component Model (must not be null)
* @param componentSerial Component Serial Number (can be null)
* @param componentRevision Component Revision or Version (can be null)
*/
public NICComponentInfo(final String componentManufacturer,
final String componentModel,
final String componentSerial,
final String componentRevision) {
super(componentManufacturer, componentModel,
componentSerial, componentRevision);
}
}

View File

@ -1,32 +0,0 @@
package hirs.attestationca.persist.entity.userdefined.info.component;
import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import hirs.utils.enums.ComponentType;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import lombok.NoArgsConstructor;
/**
* Class to hold processor component information.
*/
@NoArgsConstructor
@Entity
@DiscriminatorValue(value = ComponentType.Values.PROCESSOR)
public class ProcessorComponentInfo extends ComponentInfo {
/**
* Constructor.
*
* @param componentManufacturer Component Manufacturer (must not be null)
* @param componentModel Component Model (must not be null)
* @param componentSerial Component Serial Number (can be null)
* @param componentRevision Component Revision or Version (can be null)
*/
public ProcessorComponentInfo(final String componentManufacturer,
final String componentModel,
final String componentSerial,
final String componentRevision) {
super(componentManufacturer, componentModel,
componentSerial, componentRevision);
}
}

View File

@ -1 +0,0 @@
package hirs.attestationca.persist.entity.userdefined.info.component;

View File

@ -159,6 +159,7 @@ public class AbstractProcessor {
final ProvisionerTpm2.IdentityClaim identityClaim,
final PublicKey ekPub, final CertificateRepository certificateRepository) {
EndorsementCredential endorsementCredential = null;
if (identityClaim.hasEndorsementCredential()) {
endorsementCredential = CredentialManagementHelper.storeEndorsementCredential(
certificateRepository,
@ -172,6 +173,7 @@ public class AbstractProcessor {
log.warn("No endorsement credential was received in identity claim and no EK Public"
+ " Key was provided to check for uploaded certificates.");
}
return endorsementCredential;
}
@ -191,12 +193,21 @@ public class AbstractProcessor {
final EndorsementCredential endorsementCredential,
final CertificateRepository certificateRepository) {
List<PlatformCredential> platformCredentials = new LinkedList<>();
if (identityClaim.getPlatformCredentialCount() > 0) {
for (ByteString platformCredential : identityClaim.getPlatformCredentialList()) {
List<ByteString> platformCredentialList = identityClaim.getPlatformCredentialList();
for (ByteString platformCredential : platformCredentialList) {
if (!platformCredential.isEmpty()) {
platformCredentials.add(CredentialManagementHelper.storePlatformCredential(
certificateRepository, platformCredential.toByteArray(),
identityClaim.getDv().getNw().getHostname()));
PlatformCredential storedPlatformCredential =
CredentialManagementHelper.storePlatformCredential(
certificateRepository, platformCredential.toByteArray(),
identityClaim.getDv().getNw().getHostname());
if (storedPlatformCredential != null) {
platformCredentials.add(storedPlatformCredential);
}
}
}
} else if (endorsementCredential != null) {
@ -206,6 +217,7 @@ public class AbstractProcessor {
} else {
log.warn("No platform credential received in identity claim.");
}
return platformCredentials;
}
@ -219,7 +231,7 @@ public class AbstractProcessor {
private EndorsementCredential getEndorsementCredential(
final PublicKey ekPublicKey,
final CertificateRepository certificateRepository) {
log.debug("Searching for endorsement credential based on public key: " + ekPublicKey);
log.debug("Searching for endorsement credential based on public key: {}", ekPublicKey);
if (ekPublicKey == null) {
throw new IllegalArgumentException("Cannot look up an EC given a null public key");
@ -254,10 +266,8 @@ public class AbstractProcessor {
* @param endorsementCredential the endorsement credential used to generate the AC
* @param platformCredentials the platform credentials used to generate the AC
* @param device the device to which the attestation certificate is tied
* @param ldevID whether the certificate is a ldevid
* @param ldevID whether the certificate is a ldevid
* @return whether the certificate was saved successfully
* @throws {@link CertificateProcessingException} if error occurs in persisting the Attestation
* Certificate
*/
public boolean saveAttestationCertificate(final CertificateRepository certificateRepository,
final byte[] derEncodedAttestationCertificate,
@ -286,7 +296,7 @@ public class AbstractProcessor {
generateCertificate = ldevID ? policySettings.isIssueDevIdCertificate()
: policySettings.isIssueAttestationCertificate();
if (issuedAc != null && issuedAc.size() > 0
if (issuedAc != null && !issuedAc.isEmpty()
&& (ldevID ? policySettings.isDevIdExpirationFlag()
: policySettings.isGenerateOnExpiration())) {
if (issuedAc.get(0).getEndValidity().after(currentDate)) {
@ -322,13 +332,13 @@ public class AbstractProcessor {
if (ec == null) {
log.warn("Cannot look for platform credential(s). Endorsement credential was null.");
} else {
log.debug("Searching for platform credential(s) based on holder serial number: "
+ ec.getSerialNumber());
log.debug("Searching for platform credential(s) based on holder serial number: {}",
ec.getSerialNumber());
credentials = certificateRepository.getByHolderSerialNumber(ec.getSerialNumber());
if (credentials == null || credentials.isEmpty()) {
log.warn("No platform credential(s) found");
} else {
log.debug("Platform Credential(s) found: " + credentials.size());
log.debug("Platform Credential(s) found: {}", credentials.size());
}
}

View File

@ -20,6 +20,7 @@ import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import hirs.attestationca.persist.entity.userdefined.info.FirmwareInfo;
import hirs.attestationca.persist.entity.userdefined.info.HardwareInfo;
@ -156,6 +157,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
}
ByteString blobStr = ByteString.copyFrom(new byte[] {});
if (validationResult == AppraisalStatus.Status.PASS) {
RSAPublicKey akPub = ProvisionUtils.parsePublicKey(claim.getAkPublicArea().toByteArray());
byte[] nonce = ProvisionUtils.generateRandomBytes(NONCE_LENGTH);
@ -173,12 +175,14 @@ public class IdentityClaimProcessor extends AbstractProcessor {
if (policySettings != null && policySettings.isIgnoreImaEnabled()) {
pcrQuoteMask = PCR_QUOTE_MASK.replace("10,", "");
}
// Package response
ProvisionerTpm2.IdentityClaimResponse response
= ProvisionerTpm2.IdentityClaimResponse.newBuilder()
.setCredentialBlob(blobStr).setPcrMask(pcrQuoteMask)
.setStatus(ProvisionerTpm2.ResponseStatus.PASS)
.build();
return response.toByteArray();
} else {
log.error("Supply chain validation did not succeed. Result is: {}", validationResult);
@ -200,7 +204,8 @@ public class IdentityClaimProcessor extends AbstractProcessor {
* @return the {@link AppraisalStatus} of the supply chain validation
*/
private AppraisalStatus.Status doSupplyChainValidation(
final ProvisionerTpm2.IdentityClaim claim, final PublicKey ekPub) {
final ProvisionerTpm2.IdentityClaim claim, final PublicKey ekPub) throws IOException {
// attempt to find an endorsement credential to validate
EndorsementCredential endorsementCredential =
parseEcFromIdentityClaim(claim, ekPub, certificateRepository);
@ -215,6 +220,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
// device.getDeviceInfo().setPaccorOutputString(claim.getPaccorOutput());
handleDeviceComponents(device.getDeviceInfo().getNetworkInfo().getHostname(),
claim.getPaccorOutput());
// There are situations in which the claim is sent with no PCs
// or a PC from the tpm which will be deprecated
// this is to check what is in the platform object and pull
@ -230,16 +236,18 @@ public class IdentityClaimProcessor extends AbstractProcessor {
platformCredentials.addAll(tempList);
}
// store component results objects
for (PlatformCredential platformCredential : platformCredentials) {
List<ComponentResult> componentResults = componentResultRepository
.findByCertificateSerialNumberAndBoardSerialNumber(
platformCredential.getSerialNumber().toString(),
platformCredential.getPlatformSerial());
if (componentResults.isEmpty()) {
savePlatformComponents(platformCredential);
} else {
componentResults.stream().forEach((componentResult) -> {
componentResults.forEach((componentResult) -> {
componentResult.restore();
componentResult.resetCreateTime();
componentResultRepository.save(componentResult);
@ -252,13 +260,21 @@ public class IdentityClaimProcessor extends AbstractProcessor {
endorsementCredential, platformCredentials, device,
componentInfoRepository.findByDeviceName(device.getName()));
device.setSummaryId(summary.getId().toString());
// update the validation result in the device
AppraisalStatus.Status validationResult = summary.getOverallValidationResult();
device.setSupplyChainValidationStatus(validationResult);
this.deviceRepository.save(device);
return validationResult;
}
/**
* Helper method that utilizes the identity claim to produce a device info report.
*
* @param claim identity claim
* @return device info
*/
private Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) {
DeviceInfoReport deviceInfoReport = null;
@ -275,13 +291,16 @@ public class IdentityClaimProcessor extends AbstractProcessor {
}
log.info("Processing Device Info Report");
// store device and device info report.
Device device = null;
if (deviceInfoReport.getNetworkInfo() != null
&& deviceInfoReport.getNetworkInfo().getHostname() != null
&& !deviceInfoReport.getNetworkInfo().getHostname().isEmpty()) {
device = this.deviceRepository.findByName(deviceInfoReport.getNetworkInfo().getHostname());
}
if (device == null) {
device = new Device(deviceInfoReport);
}
@ -320,6 +339,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
macAddressBytes[i] = hex.byteValue();
}
}
NetworkInfo nw = new NetworkInfo(nwProto.getHostname(), ip, macAddressBytes);
// Get firmware info
@ -334,16 +354,19 @@ public class IdentityClaimProcessor extends AbstractProcessor {
// Get hardware info
ProvisionerTpm2.HardwareInfo hwProto = dv.getHw();
// Make sure chassis info has at least one chassis
String firstChassisSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
if (hwProto.getChassisInfoCount() > 0) {
firstChassisSerialNumber = hwProto.getChassisInfo(0).getSerialNumber();
}
// Make sure baseboard info has at least one baseboard
String firstBaseboardSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
if (hwProto.getBaseboardInfoCount() > 0) {
firstBaseboardSerialNumber = hwProto.getBaseboardInfo(0).getSerialNumber();
}
HardwareInfo hw = new HardwareInfo(hwProto.getManufacturer(), hwProto.getProductName(),
hwProto.getProductVersion(), hwProto.getSystemSerialNumber(),
firstChassisSerialNumber, firstBaseboardSerialNumber);
@ -609,6 +632,14 @@ public class IdentityClaimProcessor extends AbstractProcessor {
return dvReport;
}
/**
* Helper method that generates digest records using the provided device's manufacturer and model
* information.
*
* @param manufacturer device manufacturer
* @param model device model
* @return boolean that represents that status of the digest records generation
*/
private boolean generateDigestRecords(final String manufacturer, final String model) {
List<ReferenceDigestValue> rdValues = new LinkedList<>();
SupportReferenceManifest baseSupportRim = null;
@ -620,7 +651,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
.findByManufacturerAndModel(manufacturer, model);
Map<String, ReferenceDigestValue> digestValueMap = new HashMap<>();
expectedValues.stream().forEach((rdv) -> {
expectedValues.forEach((rdv) -> {
digestValueMap.put(rdv.getDigestValue(), rdv);
});
@ -709,35 +740,60 @@ public class IdentityClaimProcessor extends AbstractProcessor {
return true;
}
private void savePlatformComponents(final Certificate certificate) {
/**
* Helper method that saves the provided platform certificate's components in the database.
*
* @param certificate certificate
*/
private void savePlatformComponents(final Certificate certificate) throws IOException {
PlatformCredential platformCredential;
if (certificate instanceof PlatformCredential) {
platformCredential = (PlatformCredential) certificate;
ComponentResult componentResult;
for (ComponentIdentifier componentIdentifier : platformCredential
.getComponentIdentifiers()) {
componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
platformCredential.getSerialNumber().toString(),
platformCredential.getPlatformChainType(),
componentIdentifier);
componentResult.setFailedValidation(false);
componentResult.setDelta(!platformCredential.isPlatformBase());
componentResultRepository.save(componentResult);
if (platformCredential.getPlatformConfigurationV1() != null) {
for (ComponentIdentifier componentIdentifier : platformCredential
.getComponentIdentifiers()) {
componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
platformCredential.getSerialNumber().toString(),
platformCredential.getPlatformChainType(),
componentIdentifier);
componentResult.setFailedValidation(false);
componentResult.setDelta(!platformCredential.isPlatformBase());
componentResultRepository.save(componentResult);
}
} else if (platformCredential.getPlatformConfigurationV2() != null) {
for (ComponentIdentifierV2 componentIdentifierV2 : platformCredential
.getComponentIdentifiersV2()) {
componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
platformCredential.getSerialNumber().toString(),
platformCredential.getPlatformChainType(),
componentIdentifierV2);
componentResult.setFailedValidation(false);
componentResult.setDelta(!platformCredential.isPlatformBase());
componentResultRepository.save(componentResult);
}
}
}
}
private int handleDeviceComponents(final String hostName, final String paccorString) {
int deviceComponents = 0;
/**
* Helper method that attempts to find all the provided device's components.
*
* @param hostName device's host name
* @param paccorString string representation of the paccor tool output
*/
private void handleDeviceComponents(final String hostName, final String paccorString) {
Map<Integer, ComponentInfo> componentInfoMap = new HashMap<>();
try {
List<ComponentInfo> componentInfos = SupplyChainCredentialValidator
.getComponentInfoFromPaccorOutput(hostName, paccorString);
// check the DB for like component infos
List<ComponentInfo> dbComponentInfos = this.componentInfoRepository.findByDeviceName(hostName);
dbComponentInfos.stream().forEach((infos) -> {
dbComponentInfos.forEach((infos) -> {
componentInfoMap.put(infos.hashCode(), infos);
});
@ -753,7 +809,5 @@ public class IdentityClaimProcessor extends AbstractProcessor {
} catch (IOException ioEx) {
log.warn("Error parsing paccor string");
}
return deviceComponents;
}
}

View File

@ -16,7 +16,6 @@ import java.util.List;
public final class CredentialManagementHelper {
private CredentialManagementHelper() {
}
/**
@ -48,7 +47,7 @@ public final class CredentialManagementHelper {
);
}
log.info("Parsing Endorsement Credential of length " + endorsementBytes.length);
log.info("Parsing Endorsement Credential of length {}", endorsementBytes.length);
EndorsementCredential endorsementCredential;
try {
@ -58,16 +57,18 @@ public final class CredentialManagementHelper {
log.error(iae.getMessage());
throw iae;
}
int certificateHash = endorsementCredential.getCertificateHash();
EndorsementCredential existingCredential = (EndorsementCredential) certificateRepository
.findByCertificateHash(certificateHash);
if (existingCredential == null) {
log.info("No Endorsement Credential found with hash: " + certificateHash);
log.info("No Endorsement Credential found with hash: {}", certificateHash);
endorsementCredential.setDeviceName(deviceName);
return certificateRepository.save(endorsementCredential);
} else if (existingCredential.isArchived()) {
// if the EK is stored in the DB and it's archived, unarchive.
log.info("Unarchiving credential");
// if the EK is stored in the DB and it's archived, un-archive it.
log.info("Un-archiving endorsement credential");
existingCredential.restore();
existingCredential.resetCreateTime();
certificateRepository.save(existingCredential);
@ -89,28 +90,37 @@ public final class CredentialManagementHelper {
final byte[] platformBytes, final String deviceName) {
if (certificateRepository == null) {
log.error("The provided certificate repository is null.");
throw new IllegalArgumentException("null certificate manager");
}
if (platformBytes == null) {
log.error("The provided platform credential byte array is null.");
throw new IllegalArgumentException("null platform credential bytes");
}
if (platformBytes.length == 0) {
log.error("The provided platform credential byte array is null.");
throw new IllegalArgumentException(
"zero-length byte array given for platform credential"
);
}
log.info("Parsing Platform Credential of length " + platformBytes.length);
log.info("Parsing Platform Credential of length {}", platformBytes.length);
try {
PlatformCredential platformCredential =
PlatformCredential.parseWithPossibleHeader(platformBytes);
if (platformCredential == null) {
log.error("The platform credential that was parsed with the provided"
+ "byte array was null");
return null;
}
PlatformCredential existingCredential = (PlatformCredential) certificateRepository
.findByCertificateHash(platformCredential.getCertificateHash());
if (existingCredential == null) {
if (platformCredential.getPlatformSerial() != null) {
List<PlatformCredential> certificates = certificateRepository
@ -121,10 +131,10 @@ public final class CredentialManagementHelper {
if (pc.isPlatformBase() && platformCredential.isPlatformBase()) {
// found a base in the database associated with
// parsed certificate
log.error(String.format("Base certificate stored"
log.error("Base certificate stored"
+ " in database with same platform"
+ "serial number. (%s)",
platformCredential.getPlatformSerial()));
+ "serial number. ({})",
platformCredential.getPlatformSerial());
return null;
}
}
@ -133,8 +143,8 @@ public final class CredentialManagementHelper {
platformCredential.setDeviceName(deviceName);
return certificateRepository.save(platformCredential);
} else if (existingCredential.isArchived()) {
// if the PC is stored in the DB and it's archived, unarchive.
log.info("Unarchiving credential");
// if the PC is stored in the DB and it's archived, un-archive it.
log.info("Un-archiving platform credential");
existingCredential.restore();
certificateRepository.save(existingCredential);
return existingCredential;
@ -142,10 +152,14 @@ public final class CredentialManagementHelper {
return existingCredential;
} catch (DBManagerException dbEx) {
log.error("Error retrieving or saving platform credential", dbEx);
log.error("Error retrieving or saving platform credential to the database", dbEx);
} catch (Exception e) {
log.error("Error parsing platform credential", e);
}
log.error("Due to an exception being thrown while "
+ " attempting to store platform certificate(s) "
+ "this method will return a null platform certificate.");
return null;
}
}

View File

@ -32,6 +32,7 @@ import org.apache.logging.log4j.Level;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.HashMap;
@ -108,7 +109,8 @@ public class SupplyChainValidationService {
public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredential ec,
final List<PlatformCredential> pcs,
final Device device,
final List<ComponentInfo> componentInfos) {
final List<ComponentInfo> componentInfos)
throws IOException {
boolean acceptExpiredCerts = getPolicySettings().isExpiredCertificateValidationEnabled();
provisionSessionId = UUID.randomUUID();
PlatformCredential baseCredential = null;
@ -153,6 +155,7 @@ public class SupplyChainValidationService {
pcErrorMessage = String.format("%s%s%n", pcErrorMessage,
platformScv.getMessage());
}
// set the base credential
if (pc.isPlatformBase()) {
baseCredential = pc;
@ -407,9 +410,9 @@ public class SupplyChainValidationService {
}
/**
* Helper function to get a fresh load of the default policy from the DB.
* Helper function that retrieves the default policy settings from the database.
*
* @return The default Supply Chain Policy
* @return The default Supply Chain Policy Settings
*/
private PolicySettings getPolicySettings() {
PolicySettings defaultSettings = this.policyRepository.findByName("Default");

View File

@ -98,9 +98,10 @@ public final class ValidationService {
= SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL;
if (platformCredential == null) {
log.error("No platform credential to validate");
log.error("No platform credential to validate while evaluating platform credential status");
return buildValidationRecord(validationType,
AppraisalStatus.Status.FAIL, "Empty Platform credential", null, Level.ERROR);
AppraisalStatus.Status.FAIL, "Empty Platform credential", null,
Level.ERROR);
}
log.info("Validating Platform Credential");
@ -139,12 +140,13 @@ public final class ValidationService {
final ComponentResultRepository componentResultRepository,
final ComponentAttributeRepository componentAttributeRepository,
final List<ComponentInfo> componentInfos,
final UUID provisionSessionId, final boolean ignoreRevisionAttribute) {
final UUID provisionSessionId, final boolean ignoreRevisionAttribute) throws IOException {
final SupplyChainValidation.ValidationType validationType
= SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES;
if (platformCredential == null) {
log.error("No platform credential to validate");
log.error("No platform credential to validate while evaluating platform credential attributes "
+ "status");
return buildValidationRecord(validationType,
AppraisalStatus.Status.FAIL, "Platform credential is missing",
null, Level.ERROR);

View File

@ -110,9 +110,9 @@ public final class AcaPciIds {
component.getComponentRevision(),
component.getComponentManufacturerId(),
component.getFieldReplaceable(),
component.getComponentAddress(),
component.getCertificateIdentifier(),
component.getComponentPlatformUri(),
component.getComponentAddresses(),
component.getComponentPlatformCert(),
component.getComponentPlatformCertUri(),
component.getAttributeStatus());
}

View File

@ -6,6 +6,7 @@ import hirs.attestationca.persist.entity.userdefined.SupplyChainValidation;
import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentAttributeResult;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentClass;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.AttributeStatus;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
@ -23,6 +24,7 @@ import org.apache.logging.log4j.util.Strings;
import org.bouncycastle.asn1.ASN1UTF8String;
import org.bouncycastle.asn1.DERUTF8String;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@ -80,8 +82,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
deviceBaseboardSerialNumber = null;
} else {
deviceInfoSerialNumbers.put("board serial number", deviceBaseboardSerialNumber);
log.info("Using device board serial number for validation: "
+ deviceBaseboardSerialNumber);
log.info("Using device board serial number for validation: {}", deviceBaseboardSerialNumber);
}
if (StringUtils.isEmpty(deviceChassisSerialNumber)
@ -89,16 +90,15 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
log.error("Failed to retrieve device chassis serial number");
} else {
deviceInfoSerialNumbers.put("chassis serial number", deviceChassisSerialNumber);
log.info("Using device chassis serial number for validation: "
+ deviceChassisSerialNumber);
log.info("Using device chassis serial number for validation: {}", deviceChassisSerialNumber);
}
if (StringUtils.isEmpty(deviceSystemSerialNumber)
|| DeviceInfoEnums.NOT_SPECIFIED.equalsIgnoreCase(deviceSystemSerialNumber)) {
log.error("Failed to retrieve device system serial number");
} else {
deviceInfoSerialNumbers.put("system serial number", deviceSystemSerialNumber);
log.info("Using device system serial number for validation: "
+ deviceSystemSerialNumber);
log.info("Using device system serial number for validation: {}", deviceSystemSerialNumber);
}
AppraisalStatus status;
@ -169,7 +169,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
final ComponentResultRepository componentResultRepository,
final ComponentAttributeRepository componentAttributeRepository,
final List<ComponentInfo> componentInfos,
final UUID provisionSessionId, final boolean ignoreRevisionAttribute) {
final UUID provisionSessionId, final boolean ignoreRevisionAttribute) throws IOException {
boolean passesValidation = true;
StringBuilder resultMessage = new StringBuilder();
HardwareInfo hardwareInfo = deviceInfoReport.getHardwareInfo();
@ -233,29 +233,132 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
passesValidation &= fieldValidation;
// Retrieve the list of all components from the Platform Credential
List<ComponentIdentifier> allPcComponents
= new ArrayList<>(platformCredential.getComponentIdentifiers());
if (platformCredential.getPlatformConfigurationV1() != null) {
// All components listed in the Platform Credential must have a manufacturer and model
for (ComponentIdentifier pcComponent : allPcComponents) {
fieldValidation = !hasEmptyValueForRequiredField("componentManufacturer",
pcComponent.getComponentManufacturer());
// Retrieve the list of all version 1 component identifiers from the Platform Credential
List<ComponentIdentifier> allPcComponents
= new ArrayList<>(platformCredential.getComponentIdentifiers());
if (!fieldValidation) {
resultMessage.append("Component manufacturer is empty\n");
// All V1 components listed in the Platform Credential must have a manufacturer and model
for (ComponentIdentifier pcComponent : allPcComponents) {
fieldValidation = !isRequiredASN1StringFieldBlank("componentManufacturer",
pcComponent.getComponentManufacturer());
if (!fieldValidation) {
resultMessage.append("Component manufacturer is empty\n");
}
passesValidation &= fieldValidation;
fieldValidation = !isRequiredASN1StringFieldBlank("componentModel",
pcComponent.getComponentModel());
if (!fieldValidation) {
resultMessage.append("Component model is empty\n");
}
passesValidation &= fieldValidation;
}
passesValidation &= fieldValidation;
} else if (platformCredential.getPlatformConfigurationV2() != null) {
// Retrieve the list of all version 2 component identifiers from the Platform Credential
List<ComponentIdentifierV2> allV2PcComponents
= new ArrayList<>(platformCredential.getComponentIdentifiersV2());
fieldValidation = !hasEmptyValueForRequiredField("componentModel",
pcComponent.getComponentModel());
if (!fieldValidation) {
resultMessage.append("Component model is empty\n");
// All V2 components listed in the Platform Credential must have a manufacturer and model
for (ComponentIdentifierV2 pcComponent : allV2PcComponents) {
fieldValidation = !isRequiredASN1StringFieldBlank("componentManufacturer",
pcComponent.getComponentManufacturer());
if (!fieldValidation) {
resultMessage.append("Component manufacturer is empty\n");
}
passesValidation &= fieldValidation;
fieldValidation = !isRequiredASN1StringFieldBlank("componentModel",
pcComponent.getComponentModel());
if (!fieldValidation) {
resultMessage.append("Component model is empty\n");
}
passesValidation &= fieldValidation;
if (pcComponent.getComponentClass() == null) {
passesValidation = false;
} else {
ComponentClass pcComponentClass = pcComponent.getComponentClass();
// Component Class Registry Type field
fieldValidation = !isRequiredStringFieldBlank("registryType",
pcComponentClass.getRegistryType());
if (!fieldValidation) {
resultMessage.append("Component class registry type is empty or null\n");
}
passesValidation &= fieldValidation;
// Component Class Component Identifier field
fieldValidation = !isRequiredStringFieldBlank("componentIdentifier",
pcComponentClass.getComponentIdentifier());
if (!fieldValidation) {
resultMessage.append("Component class component identifier is empty or null\n");
}
passesValidation &= fieldValidation;
// Component Class category field
fieldValidation = !isRequiredStringFieldBlank("category",
pcComponentClass.getCategory());
if (!fieldValidation) {
resultMessage.append("Component class category is empty or null\n");
}
passesValidation &= fieldValidation;
// Component Class Category String field
fieldValidation = !isRequiredStringFieldBlank("categoryStr",
pcComponentClass.getCategoryStr());
if (!fieldValidation) {
resultMessage.append("Component class category string is empty or null\n");
}
passesValidation &= fieldValidation;
// Component Class Component String field
fieldValidation = !isRequiredStringFieldBlank("componentStr",
pcComponentClass.getComponentStr());
if (!fieldValidation) {
resultMessage.append("Component class string is empty or null\n");
}
passesValidation &= fieldValidation;
// Component Class Component field
fieldValidation = !isRequiredStringFieldBlank("component",
pcComponentClass.getComponent());
if (!fieldValidation) {
resultMessage.append("Component class component is empty or null\n");
}
passesValidation &= fieldValidation;
}
}
passesValidation &= fieldValidation;
}
// populate componentResults list
@ -263,18 +366,24 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
.findByCertificateSerialNumberAndBoardSerialNumber(
platformCredential.getSerialNumber().toString(),
platformCredential.getPlatformSerial());
// first create hash map based on hashCode
List<ComponentResult> remainingComponentResults = checkDeviceHashMap(
componentInfos, componentResults);
//this is used to get a unique count
List<UUID> componentIdList = new ArrayList<>();
int numOfAttributes = 0;
if (!remainingComponentResults.isEmpty()) {
List<ComponentAttributeResult> attributeResults = checkComponentClassMap(
componentInfos, remainingComponentResults);
numOfAttributes = attributeResults.size();
boolean saveAttributeResult;
for (ComponentAttributeResult componentAttributeResult : attributeResults) {
saveAttributeResult = true;
if (ignoreRevisionAttribute) {
@ -293,6 +402,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
}
StringBuilder additionalInfo = new StringBuilder();
if (numOfAttributes > 0) {
resultMessage.append(String.format("There are %d component(s) not matched%n "
+ "with %d total attributes mismatched.",
@ -435,7 +545,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
for (ComponentInfo cInfo : allDeviceInfoComponents) {
for (ComponentIdentifier cId : fullDeltaChainComponents) {
ciV2 = (ComponentIdentifierV2) cId;
if (cInfo.getComponentClass().contains(
if (cInfo.getComponentClassValue().contains(
ciV2.getComponentClass().getComponentIdentifier())
&& isMatch(cId, cInfo)) {
subCompIdList.remove(cId);
@ -455,7 +565,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
if (ci.isVersion2() && PciIds.DB.isReady()) {
ci = AcaPciIds.translate((ComponentIdentifierV2) ci);
}
log.error("Unmatched component: " + ci);
log.error("Unmatched component: {}", ci);
fullDeltaChainComponents.add(ci);
invalidPcIds.append(String.format(
"Manufacturer=%s, Model=%s, Serial=%s, Revision=%s;%n",
@ -513,25 +623,34 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
log.info("Validating the following Platform Cert components...");
pcComponents.forEach(component -> log.info(component.toString()));
log.info("...against the the following DeviceInfoReport components:");
allDeviceInfoComponents.forEach(component -> log.info(component.toString()));
Set<ASN1UTF8String> manufacturerSet = new HashSet<>();
// create a set of component manufacturers
pcComponents.forEach(pcComp -> manufacturerSet.add(pcComp.getComponentManufacturer()));
// Create a list for unmatched components across all manufacturers to display at the end.
List<ComponentIdentifier> pcUnmatchedComponents = new ArrayList<>();
for (ASN1UTF8String derUtf8Manufacturer : manufacturerSet) {
// look for all the component identifiers whose manufacturer matches that of the current
// manufacturer
List<ComponentIdentifier> pcComponentsFromManufacturer
= pcComponents.stream().filter(compIdentifier
-> compIdentifier.getComponentManufacturer().equals(derUtf8Manufacturer))
.collect(Collectors.toList());
String pcManufacturer = derUtf8Manufacturer.getString();
// look for all the component infos whose manufacturer matches that of the current
// manufacturer
String currentPCManufacturer = derUtf8Manufacturer.getString();
List<ComponentInfo> deviceInfoComponentsFromManufacturer
= allDeviceInfoComponents.stream().filter(componentInfo
-> componentInfo.getComponentManufacturer().equals(pcManufacturer))
-> componentInfo.getComponentManufacturer().equals(currentPCManufacturer))
.collect(Collectors.toList());
// For each component listed in the platform credential from this manufacturer
// find the ones that specify a serial number so we can match the most specific ones
// first.
@ -539,7 +658,8 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
= pcComponentsFromManufacturer.stream().filter(compIdentifier
-> compIdentifier.getComponentSerial() != null
&& StringUtils.isNotEmpty(compIdentifier.getComponentSerial().getString()))
.collect(Collectors.toList());
.toList();
// Now match up the components from the device info that are from the same
// manufacturer and have a serial number. As matches are found, remove them from
// both lists.
@ -560,6 +680,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
}
}
}
// For each component listed in the platform credential from this manufacturer
// find the ones that specify value for the revision field so we can match the most
// specific ones first.
@ -567,7 +688,8 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
= pcComponentsFromManufacturer.stream().filter(compIdentifier
-> compIdentifier.getComponentRevision() != null
&& StringUtils.isNotEmpty(compIdentifier.getComponentRevision().getString()))
.collect(Collectors.toList());
.toList();
// Now match up the components from the device info that are from the same
// manufacturer and specify a value for the revision field. As matches are found,
// remove them from both lists.
@ -608,8 +730,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
if (!pcUnmatchedComponents.isEmpty()) {
untrimmedPcComponents.clear();
StringBuilder sb = new StringBuilder();
log.error(String.format("Platform Credential contained %d unmatched components:",
pcUnmatchedComponents.size()));
log.error("Platform Credential contained {} unmatched components:", pcUnmatchedComponents.size());
int unmatchedComponentCounter = 1;
for (ComponentIdentifier unmatchedComponent : pcUnmatchedComponents) {
@ -617,8 +738,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
unmatchedComponent =
AcaPciIds.translate((ComponentIdentifierV2) unmatchedComponent);
}
log.error("Unmatched component " + unmatchedComponentCounter++ + ": "
+ unmatchedComponent);
log.error("Unmatched component {}: {}", unmatchedComponentCounter++, unmatchedComponent);
sb.append(String.format("Manufacturer=%s, Model=%s, Serial=%s, Revision=%s;%n",
unmatchedComponent.getComponentManufacturer(),
unmatchedComponent.getComponentModel(),
@ -670,7 +790,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
private static boolean isMatchOrEmptyInPlatformCert(
final String evidenceFromDevice,
final ASN1UTF8String valueInPlatformCert) {
if (valueInPlatformCert == null || StringUtils.isEmpty(valueInPlatformCert.getString())) {
if (StringUtils.isBlank(valueInPlatformCert.getString())) {
return true;
}
return valueInPlatformCert.getString().equals(evidenceFromDevice);
@ -756,7 +876,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
final String platformCredentialFieldName,
final String platformCredentialFieldValue,
final String otherValue) {
if (hasEmptyValueForRequiredField(platformCredentialFieldName,
if (isRequiredStringFieldBlank(platformCredentialFieldName,
platformCredentialFieldValue)) {
return false;
}
@ -794,11 +914,10 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
* @param fieldValue value of the field
* @return true if fieldValue is null or empty; false otherwise
*/
private static boolean hasEmptyValueForRequiredField(final String description,
final String fieldValue) {
if (StringUtils.isEmpty(fieldValue)) {
log.error("Required field was empty or null in Platform Credential: "
+ description);
private static boolean isRequiredStringFieldBlank(final String description,
final String fieldValue) {
if (StringUtils.isBlank(fieldValue)) {
log.error("Required string field was empty or null in Platform Credential: {}", description);
return true;
}
return false;
@ -829,15 +948,15 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
String trimmedOtherValue = otherValue.trim();
if (!trimmedFieldValue.equals(trimmedOtherValue)) {
log.debug(String.format("%s field in Platform Credential (%s) does not match "
+ "a related field in the DeviceInfoReport (%s)",
platformCredentialFieldName, trimmedFieldValue, trimmedOtherValue));
log.debug("{} field in Platform Credential ({}) does not match "
+ "a related field in the DeviceInfoReport ({})",
platformCredentialFieldName, trimmedFieldValue, trimmedOtherValue);
return false;
}
log.debug(String.format("%s field in Platform Credential matches "
+ "a related field in the DeviceInfoReport (%s)",
platformCredentialFieldName, trimmedFieldValue)
log.debug("{} field in Platform Credential matches "
+ "a related field in the DeviceInfoReport {}",
platformCredentialFieldName, trimmedFieldValue
);
return true;
@ -850,11 +969,10 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
* @param fieldValue value of the field
* @return true if fieldValue is null or empty; false otherwise
*/
private static boolean hasEmptyValueForRequiredField(final String description,
final ASN1UTF8String fieldValue) {
if (fieldValue == null || StringUtils.isEmpty(fieldValue.getString().trim())) {
log.error("Required field was empty or null in Platform Credential: "
+ description);
private static boolean isRequiredASN1StringFieldBlank(final String description,
final ASN1UTF8String fieldValue) {
if (fieldValue == null || StringUtils.isBlank(fieldValue.getString().trim())) {
log.error("Required ASN1 string field was empty or null in Platform Credential: {}", description);
return true;
}
return false;
@ -871,16 +989,17 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
final List<ComponentInfo> componentInfos,
final List<ComponentResult> compiledComponentList) {
Map<Integer, List<ComponentInfo>> deviceHashMap = new HashMap<>();
componentInfos.stream().forEach((componentInfo) -> {
List<ComponentInfo> innerList;
componentInfos.forEach((componentInfo) -> {
List<ComponentInfo> innerList = new ArrayList<>();
Integer compInfoHash = componentInfo.hashCommonElements();
if (deviceHashMap.containsKey(compInfoHash)) {
innerList = deviceHashMap.get(compInfoHash);
innerList.add(componentInfo);
} else {
innerList = new ArrayList<>(0);
innerList.add(componentInfo);
}
innerList.add(componentInfo);
deviceHashMap.put(compInfoHash, innerList);
});
@ -910,23 +1029,37 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
// continue down the options, move to a different method.
// create component class mapping to component info
Map<String, List<ComponentInfo>> componentDeviceMap = new HashMap<>();
componentInfos.stream().forEach((componentInfo) -> {
List<ComponentInfo> innerList;
String componentClass = componentInfo.getComponentClass();
componentInfos.forEach((componentInfo) -> {
List<ComponentInfo> innerList = new ArrayList<>();
String componentClass = componentInfo.getComponentClassValue();
if (componentDeviceMap.containsKey(componentClass)) {
innerList = componentDeviceMap.get(componentClass);
innerList.add(componentInfo);
} else {
innerList = new ArrayList<>(0);
innerList.add(componentInfo);
}
innerList.add(componentInfo);
componentDeviceMap.put(componentClass, innerList);
});
List<ComponentInfo> componentClassInfo;
List<ComponentAttributeResult> attributeResults = new ArrayList<>();
for (ComponentResult componentResult : remainingComponentResults) {
componentClassInfo = componentDeviceMap.get(componentResult.getComponentClassValue());
if (componentClassInfo == null) {
log.error("The retrieved list of component class info is null. The null list"
+ "is associated with the component result's component class value of {}",
componentResult.getComponentClassValue());
//move on to the next iteration since there is nothing we can do with the null
// component class info
continue;
}
if (componentClassInfo.size() == 1) {
attributeResults.addAll(generateComponentAttributeResults(
componentClassInfo.get(0), componentResult));
@ -1000,11 +1133,13 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
private static List<ComponentAttributeResult> findMismatchedValues(
final List<ComponentInfo> componentClassInfo,
final ComponentResult componentResult) {
// this list only has those of the same class type
Map<String, ComponentInfo> componentSerialMap = new HashMap<>();
componentClassInfo.stream().forEach((componentInfo) -> {
componentClassInfo.forEach((componentInfo) -> {
componentSerialMap.put(componentInfo.getComponentSerial(), componentInfo);
});
// see if the serial exists
ComponentInfo componentInfo = componentSerialMap.get(componentResult.getSerialNumber());

View File

@ -35,7 +35,7 @@ public class CredentialValidator extends SupplyChainCredentialValidator {
*
* @param ec the endorsement credential to verify.
* @param trustStore trust store holding trusted certificates.
* @param acceptExpired whether or not to accept expired and not yet valid certificates
* @param acceptExpired whether to accept expired and not yet valid certificates
* as valid.
* @return the result of the validation.
*/
@ -100,7 +100,7 @@ public class CredentialValidator extends SupplyChainCredentialValidator {
*
* @param pc The platform credential to verify.
* @param trustStore trust store holding trusted certificates.
* @param acceptExpired whether or not to accept expired certificates as valid.
* @param acceptExpired whether to accept expired certificates as valid.
* @return The result of the validation.
*/
public static AppraisalStatus validatePlatformCredential(final PlatformCredential pc,
@ -183,21 +183,24 @@ public class CredentialValidator extends SupplyChainCredentialValidator {
final ComponentResultRepository componentResultRepository,
final ComponentAttributeRepository componentAttributeRepository,
final List<ComponentInfo> componentInfos,
final UUID provisionSessionId, final boolean ignoreRevisionAttribute) {
final UUID provisionSessionId, final boolean ignoreRevisionAttribute) throws IOException {
final String baseErrorMessage = "Can't validate platform credential attributes without ";
String message;
if (platformCredential == null) {
message = baseErrorMessage + "a platform credential";
return new AppraisalStatus(FAIL, message);
}
if (deviceInfoReport == null) {
message = baseErrorMessage + "a device info report";
return new AppraisalStatus(FAIL, message);
}
if (endorsementCredential == null) {
message = baseErrorMessage + "an endorsement credential";
return new AppraisalStatus(FAIL, message);
}
if (componentInfos.isEmpty()) {
message = baseErrorMessage + "a list of device components";
return new AppraisalStatus(FAIL, message);

View File

@ -93,7 +93,9 @@ public class SupplyChainCredentialValidator {
throw new SupplyChainValidatorException("Truststore is empty");
}
} catch (KeyStoreException ksEx) {
log.error("Error accessing trust store: " + ksEx.getMessage());
log.error(
"Error accessing trust store while trying to verify the X509 Attribute"
+ " Certificate Holder: {}", ksEx.getMessage());
}
try {
@ -134,7 +136,8 @@ public class SupplyChainCredentialValidator {
throw new SupplyChainValidatorException("Truststore is empty");
}
} catch (KeyStoreException ksEx) {
log.error("Error accessing trust store: " + ksEx.getMessage());
log.error("Error accessing trust store while trying to verify the X509 Certificate: {}",
ksEx.getMessage());
}
try {
@ -147,8 +150,9 @@ public class SupplyChainCredentialValidator {
return validateCertChain(cert, trustedCerts).isEmpty();
} catch (KeyStoreException ksEx) {
log.error("Error accessing keystore", ksEx);
throw new SupplyChainValidatorException("Error with the trust store", ksEx);
log.error("Error accessing keystore while trying to verify the X509 Certificate", ksEx);
throw new SupplyChainValidatorException(
"Error accessing keystore while trying to verify the X509 Certificate", ksEx);
}
}
@ -191,7 +195,7 @@ public class SupplyChainCredentialValidator {
if (issuerMatchesSubject && signatureMatchesPublicKey) {
if (isSelfSigned(trustedCert)) {
log.info("CA Root found.");
log.info("CA Root found while validating the X509 Attribute Certificate Holder.");
return "";
} else {
foundRootOfCertChain = intCAError;
@ -244,7 +248,7 @@ public class SupplyChainCredentialValidator {
trustedCert);
if (issuerMatchesSubject && signatureMatchesPublicKey) {
if (isSelfSigned(trustedCert)) {
log.info("CA Root found.");
log.info("CA Root found while validating X509 Certificate.");
return "";
} else {
foundRootOfCertChain = intCAError;
@ -270,7 +274,7 @@ public class SupplyChainCredentialValidator {
* Parses the output from PACCOR's allcomponents.sh script into ComponentInfo objects.
*
* @param hostName the host machine associated with the component
* @param paccorOutput the output from PACCOR's allcomoponents.sh
* @param paccorOutput the output from PACCOR's allcomponents.sh
* @return a list of ComponentInfo objects built from paccorOutput
* @throws java.io.IOException if something goes wrong parsing the JSON
*/
@ -296,17 +300,23 @@ public class SupplyChainCredentialValidator {
getJSONNodeValueAsText(next, "REVISION")));
} else {
// version 2
String componentClass = StringUtils.EMPTY;
String componentClassValue = StringUtils.EMPTY;
String componentClassRegistry = StringUtils.EMPTY;
for (JsonNode subNode : compClassNodes) {
componentClass = getJSONNodeValueAsText(subNode,
componentClassValue = getJSONNodeValueAsText(subNode,
"COMPONENTCLASSVALUE");
componentClassRegistry = getJSONNodeValueAsText(subNode,
"COMPONENTCLASSREGISTRY");
}
componentInfoList.add(new ComponentInfo(hostName,
getJSONNodeValueAsText(next, "MANUFACTURER"),
getJSONNodeValueAsText(next, "MODEL"),
getJSONNodeValueAsText(next, "SERIAL"),
getJSONNodeValueAsText(next, "REVISION"),
componentClass));
componentClassValue,
componentClassRegistry));
}
}
}
@ -314,6 +324,13 @@ public class SupplyChainCredentialValidator {
return componentInfoList;
}
/**
* Helper method that attempts to retrieve the value as text from the provided Json Node.
*
* @param node json node
* @param fieldName field name
* @return string json node value
*/
private static String getJSONNodeValueAsText(final JsonNode node, final String fieldName) {
if (node.hasNonNull(fieldName)) {
return node.findValue(fieldName).textValue();
@ -398,8 +415,7 @@ public class SupplyChainCredentialValidator {
} catch (NoSuchProviderException e) {
log.info("Incorrect provider for cert signature validation");
} catch (SignatureException e) {
log.info(String.format("%s.verify(%s)", cert.getSubjectX500Principal(),
signingCert.getSubjectX500Principal()));
log.info("{}.verify({})", cert.getSubjectX500Principal(), signingCert.getSubjectX500Principal());
}
return false;
@ -444,8 +460,7 @@ public class SupplyChainCredentialValidator {
return cert.isSignatureValid(contentVerifierProvider);
} catch (OperatorCreationException | CertException e) {
log.info("Exception thrown while verifying certificate", e);
log.info(String.format("%s.isSignatureValid(%s)", cert.getSerialNumber(),
signingKey.getFormat()));
log.info("{}.isSignatureValid({})", cert.getSerialNumber(), signingKey.getFormat());
return false;
}
}

View File

@ -3,10 +3,11 @@ package hirs.attestationca.persist.entity.userdefined.certificate;
import hirs.attestationca.persist.entity.userdefined.AbstractUserdefinedEntityTest;
import hirs.attestationca.persist.entity.userdefined.Certificate;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfiguration;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfigurationV1;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformProperty;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.TBBSecurityAssertion;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.URIReference;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.PlatformConfigurationV2;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.util.encoders.Base64;
@ -439,10 +440,10 @@ public class PlatformCredentialTest extends AbstractUserdefinedEntityTest {
Path certPath = Paths.get(resource.toURI());
PlatformCredential platformCert = new PlatformCredential(certPath);
PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration();
PlatformConfigurationV1 platformConfigV1 = platformCert.getPlatformConfigurationV1();
//Check component identifier
List<ComponentIdentifier> allComponents = platformConfig.getComponentIdentifier();
List<ComponentIdentifier> allComponents = platformConfigV1.getComponentIdentifiers();
if (allComponents.isEmpty()) {
Assertions.fail("Component Identifier is empty.");
}
@ -472,14 +473,14 @@ public class PlatformCredentialTest extends AbstractUserdefinedEntityTest {
component = allComponents.get(component5Position);
Assertions.assertEquals("Ethernet Connection I219-LM", component.getComponentModel()
.getString());
Assertions.assertEquals("8c:0f:6f:72:c6:c5", component.getComponentAddress().get(0)
Assertions.assertEquals("8c:0f:6f:72:c6:c5", component.getComponentAddresses().get(0)
.getAddressValue()
.getString());
Assertions.assertEquals("ethernet mac", component.getComponentAddress().get(0)
Assertions.assertEquals("ethernet mac", component.getComponentAddresses().get(0)
.getAddressTypeValue());
//Check Platform Properties
List<PlatformProperty> platformProperties = platformConfig.getPlatformProperties();
List<PlatformProperty> platformProperties = platformConfigV1.getPlatformProperties();
if (platformProperties.isEmpty()) {
Assertions.fail("Platform Properties is empty.");
}
@ -499,7 +500,7 @@ public class PlatformCredentialTest extends AbstractUserdefinedEntityTest {
Assertions.assertEquals("true", property.getPropertyValue().getString());
//Check Platform Properties URI
URIReference platformPropertyUri = platformConfig.getPlatformPropertiesUri();
URIReference platformPropertyUri = platformConfigV1.getPlatformPropertiesUri();
Assertions.assertNotNull(platformPropertyUri);
Assertions.assertEquals("https://www.intel.com/platformproperties.xml",
@ -522,13 +523,13 @@ public class PlatformCredentialTest extends AbstractUserdefinedEntityTest {
Path certPath = Paths.get(resource.toURI());
PlatformCredential platformCert = new PlatformCredential(certPath);
PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration();
PlatformConfigurationV1 platformConfigV1 = platformCert.getPlatformConfigurationV1();
//Check component identifier
List<ComponentIdentifier> allComponents = platformConfig.getComponentIdentifier();
List<ComponentIdentifier> allComponents = platformConfigV1.getComponentIdentifiers();
Assertions.assertTrue(allComponents.isEmpty());
List<PlatformProperty> platformProperties = platformConfig.getPlatformProperties();
List<PlatformProperty> platformProperties = platformConfigV1.getPlatformProperties();
if (platformProperties.isEmpty()) {
Assertions.fail("Platform Properties is empty.");
}
@ -560,10 +561,10 @@ public class PlatformCredentialTest extends AbstractUserdefinedEntityTest {
Path certPath = Paths.get(resource.toURI());
PlatformCredential platformCert = new PlatformCredential(certPath);
PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration();
PlatformConfigurationV1 platformConfigV1 = platformCert.getPlatformConfigurationV1();
//Check component identifier
List<ComponentIdentifier> allComponents = platformConfig.getComponentIdentifier();
List<ComponentIdentifier> allComponents = platformConfigV1.getComponentIdentifiers();
if (allComponents.isEmpty()) {
Assertions.fail("Component Identifier is empty.");
}
@ -589,7 +590,7 @@ public class PlatformCredentialTest extends AbstractUserdefinedEntityTest {
.getString());
//Check Platform Properties
List<PlatformProperty> platformProperties = platformConfig.getPlatformProperties();
List<PlatformProperty> platformProperties = platformConfigV1.getPlatformProperties();
if (platformProperties.isEmpty()) {
Assertions.fail("Platform Properties is empty.");
}
@ -597,7 +598,7 @@ public class PlatformCredentialTest extends AbstractUserdefinedEntityTest {
Assertions.assertEquals(platformProperties.size(), 2);
//Check Platform Properties URI
URIReference platformPropertyUri = platformConfig.getPlatformPropertiesUri();
URIReference platformPropertyUri = platformConfigV1.getPlatformPropertiesUri();
Assertions.assertNotNull(platformPropertyUri);
Assertions.assertEquals("https://www.intel.com/platformproperties.xml",
@ -629,10 +630,10 @@ public class PlatformCredentialTest extends AbstractUserdefinedEntityTest {
Path certPath = Paths.get(resource.toURI());
PlatformCredential platformCert = new PlatformCredential(certPath);
PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration();
PlatformConfigurationV1 platformConfigV1 = platformCert.getPlatformConfigurationV1();
//Check component identifier
List<ComponentIdentifier> allComponents = platformConfig.getComponentIdentifier();
List<ComponentIdentifier> allComponents = platformConfigV1.getComponentIdentifiers();
if (allComponents.isEmpty()) {
Assertions.fail("Component Identifier is empty.");
}
@ -651,15 +652,15 @@ public class PlatformCredentialTest extends AbstractUserdefinedEntityTest {
//Check component #7
final int component7Position = 6;
component = allComponents.get(component7Position);
Assertions.assertTrue(component.getComponentAddress().size() > 0);
Assertions.assertEquals("8c:0f:6f:72:c6:c5", component.getComponentAddress().get(0)
Assertions.assertFalse(component.getComponentAddresses().isEmpty());
Assertions.assertEquals("8c:0f:6f:72:c6:c5", component.getComponentAddresses().get(0)
.getAddressValue()
.getString());
Assertions.assertEquals("ethernet mac", component.getComponentAddress().get(0)
Assertions.assertEquals("ethernet mac", component.getComponentAddresses().get(0)
.getAddressTypeValue());
//Check Platform Properties
List<PlatformProperty> platformProperties = platformConfig.getPlatformProperties();
List<PlatformProperty> platformProperties = platformConfigV1.getPlatformProperties();
if (platformProperties.isEmpty()) {
Assertions.fail("Platform Properties is empty.");
}
@ -667,7 +668,7 @@ public class PlatformCredentialTest extends AbstractUserdefinedEntityTest {
Assertions.assertEquals(platformProperties.size(), 2);
//Check Platform Properties URI
URIReference platformPropertyUri = platformConfig.getPlatformPropertiesUri();
URIReference platformPropertyUri = platformConfigV1.getPlatformPropertiesUri();
Assertions.assertNotNull(platformPropertyUri);
Assertions.assertEquals("https://www.intel.com/platformproperties.xml",
@ -700,17 +701,17 @@ public class PlatformCredentialTest extends AbstractUserdefinedEntityTest {
Path certPath = Paths.get(resource.toURI());
PlatformCredential platformCert = new PlatformCredential(certPath);
PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration();
PlatformConfigurationV2 platformConfigV2 = platformCert.getPlatformConfigurationV2();
//Check component identifier
List<ComponentIdentifier> allComponents = platformConfig.getComponentIdentifier();
List<ComponentIdentifierV2> allComponents = platformConfigV2.getComponentIdentifiers();
Assertions.assertFalse(allComponents.isEmpty());
final int component6Position = 5;
ComponentIdentifier component = allComponents.get(component6Position);
ComponentIdentifierV2 component = allComponents.get(component6Position);
Assertions.assertTrue(component.isVersion2());
List<PlatformProperty> platformProperties = platformConfig.getPlatformProperties();
List<PlatformProperty> platformProperties = platformConfigV2.getPlatformProperties();
if (platformProperties.isEmpty()) {
Assertions.fail("Platform Properties is empty.");
}
@ -749,15 +750,15 @@ public class PlatformCredentialTest extends AbstractUserdefinedEntityTest {
Path certPath = Paths.get(resource.toURI());
PlatformCredential platformCert = new PlatformCredential(certPath);
PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration();
PlatformConfigurationV2 platformConfigV2 = platformCert.getPlatformConfigurationV2();
Assertions.assertInstanceOf(PlatformConfigurationV2.class, platformConfig);
Assertions.assertEquals(platformConfig.getPlatformPropertiesUri()
Assertions.assertInstanceOf(PlatformConfigurationV2.class, platformConfigV2);
Assertions.assertEquals(platformConfigV2.getPlatformPropertiesUri()
.getUniformResourceIdentifier().toString(),
"https://www.intel.com/platformproperties.xml");
// Assertions.assertNotNull(platformConfig.getComponentIdentifierUri());
// Assertions.assertNotNull(platformConfigV1.getComponentIdentifiersUri());
// Assertions.assertEquals(platformConfig.getComponentIdentifierUri()
// Assertions.assertEquals(platformConfigV1.getComponentIdentifiersUri()
// .getUniformResourceIdentifier().toString(),
// "https://www.intel.com/platformidentifiers.xml");

View File

@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@ -16,292 +17,313 @@ public class ComponentClassTest {
private static final String JSON_FILE = "/config/component-class.json";
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentNoneUNK() throws URISyntaxException {
String componentIdentifier = "00000001";
final String componentIdentifier = "00000001";
ComponentClass instance = new ComponentClass("TCG",
Paths.get(this.getClass().getResource(JSON_FILE).toURI()),
Paths.get(Objects.requireNonNull(this.getClass().getResource(JSON_FILE)).toURI()),
componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertEquals("Unknown", resultComponent);
assertEquals("None", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentNoneOther() throws URISyntaxException {
String componentIdentifier = "00000000";
final String componentIdentifier = "00000000";
ComponentClass instance = new ComponentClass("TCG", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertEquals("Unknown", resultComponent);
assertEquals("None", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentBlank() throws URISyntaxException {
String componentIdentifier = "";
final String componentIdentifier = "";
ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertEquals("Unknown", resultComponent);
assertEquals("None", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentNFEx() throws URISyntaxException {
String componentIdentifier = "99999999";
final String componentIdentifier = "99999999";
ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertEquals("Unknown", resultComponent);
assertEquals("None", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentNull() throws URISyntaxException {
String componentIdentifier = null;
final String componentIdentifier = null;
ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertEquals("Unknown", resultComponent);
assertEquals("None", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class where the
* registry type is of type TCG.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentStandardQueryTCG() throws URISyntaxException {
String componentIdentifier = "0x00040002";
final String componentIdentifier = "0x00040002";
ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertEquals("SAS Bridgeboard", resultComponent);
assertEquals("Modules", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class where the
* registry type is of type SMBIOS.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentStandardQuerySMBIOS() throws URISyntaxException {
String componentIdentifier = "0x00040003";
ComponentClass instance = new ComponentClass("2.23.133.18.3.3", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String componentIdentifier = "0x00040003";
ComponentClass instance = new ComponentClass("2.23.133.18.3.3", Paths.get(
Objects.requireNonNull(this.getClass()
.getResource(JSON_FILE)).toURI()), componentIdentifier);
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
final String resultRegistry = instance.getRegistryType();
assertEquals("SMBIOS", resultRegistry);
assertEquals("Central Processor", resultComponent);
assertEquals("Processor", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Test of getComponent method, of class ComponentClass where the
* registry type is of type PCIE.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentStandardQueryIntTCG() throws URISyntaxException {
String componentIdentifier = "0x00040002";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
assertEquals("SAS Bridgeboard", resultComponent);
assertEquals("Modules", resultCategory);
public void testGetComponentStandardQueryPCIE() throws URISyntaxException {
final String componentIdentifier = "0x00080004"; // TODO placeholder for now
ComponentClass instance = new ComponentClass("2.23.133.18.3.4", Paths.get(
Objects.requireNonNull(this.getClass()
.getResource(JSON_FILE)).toURI()), componentIdentifier);
final String resultRegistry = instance.getRegistryType();
assertEquals("PCIE", resultRegistry);
//TODO Once the component-class.json file is updated to reflect the two new component
// registries, we will then write tests that test the component class' category/component
// properties.
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class where the
* registry type is of type STORAGE.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentStandardQueryIntSMBIOS() throws URISyntaxException {
String componentIdentifier = "0x00040003";
ComponentClass instance = new ComponentClass("2.23.133.18.3.3", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
assertEquals("Central Processor", resultComponent);
assertEquals("Processor", resultCategory);
public void testGetComponentStandardQuerySTORAGE() throws URISyntaxException {
final String componentIdentifier = "0x00080004"; // TODO placeholder for now
ComponentClass instance = new ComponentClass("2.23.133.18.3.5", Paths.get(
Objects.requireNonNull(this.getClass()
.getResource(JSON_FILE)).toURI()), componentIdentifier);
final String resultRegistry = instance.getRegistryType();
assertEquals("STORAGE", resultRegistry);
//TODO Once the component-class.json file is updated to reflect the two new component
// registries, we will then write tests that test the component class' category/component
// properties.
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentStandardQueryIntOther() throws URISyntaxException {
String componentIdentifier = "0x00040000";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String componentIdentifier = "0x00040000";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(
Objects.requireNonNull(this.getClass()
.getResource(JSON_FILE)).toURI()), componentIdentifier);
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertEquals("Other", resultComponent);
assertEquals("Modules", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentStandardQueryIntUnk() throws URISyntaxException {
String componentIdentifier = "0x00040001";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String componentIdentifier = "0x00040001";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(
Objects.requireNonNull(this.getClass()
.getResource(JSON_FILE)).toURI()), componentIdentifier);
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertEquals("Unknown", resultComponent);
assertEquals("Modules", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentStandardQuery2() throws URISyntaxException {
String componentIdentifier = "0x00060015";
ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String componentIdentifier = "0x00060015";
ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
.getResource(JSON_FILE)).toURI()), componentIdentifier);
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertEquals("DDR3 Memory", resultComponent);
assertEquals("Memory", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentStandardQueryUNK() throws URISyntaxException {
String componentIdentifier = "0x00060001";
ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String componentIdentifier = "0x00060001";
ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
.getResource(JSON_FILE)).toURI()), componentIdentifier);
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertEquals("Unknown", resultComponent);
assertEquals("Memory", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentNonStandardQuery() throws URISyntaxException {
String componentIdentifier = "0x00040002";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String componentIdentifier = "0x00040002";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(
Objects.requireNonNull(this.getClass()
.getResource(JSON_FILE)).toURI()), componentIdentifier);
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertEquals("SAS Bridgeboard", resultComponent);
assertEquals("Modules", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentNonStandardQuery2() throws URISyntaxException {
String componentIdentifier = "0x00040002";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String componentIdentifier = "0x00040002";
ComponentClass instance = new ComponentClass("2.23.133.18.3.1", Paths.get(
Objects.requireNonNull(this.getClass()
.getResource(JSON_FILE)).toURI()), componentIdentifier);
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertEquals("SAS Bridgeboard", resultComponent);
assertEquals("Modules", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentNonExistentValue() throws URISyntaxException {
String componentIdentifier = "0x00040014";
ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String componentIdentifier = "0x00040014";
ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
.getResource(JSON_FILE)).toURI()), componentIdentifier);
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertNotNull(resultComponent);
assertEquals("Unknown", resultComponent);
assertEquals("Modules", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentNonExistentValue2() throws URISyntaxException {
String componentIdentifier = "0x0004FF14";
ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String componentIdentifier = "0x0004FF14";
ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
.getResource(JSON_FILE)).toURI()), componentIdentifier);
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertNotNull(resultComponent);
assertEquals("Unknown", resultComponent);
assertEquals("Modules", resultCategory);
}
/**
* Test of getComponent method, of class ComponentClass.
* Tests the getComponent method from the ComponentClass class.
*
* @throws URISyntaxException if there is a problem constructing the URI
*/
@Test
public void testGetComponentNonExistentCategory() throws URISyntaxException {
String componentIdentifier = "0x0015FF14";
ComponentClass instance = new ComponentClass(Paths.get(this.getClass()
.getResource(JSON_FILE).toURI()), componentIdentifier);
String resultCategory = instance.getCategoryStr();
String resultComponent = instance.getComponentStr();
final String componentIdentifier = "0x0015FF14";
ComponentClass instance = new ComponentClass(Paths.get(Objects.requireNonNull(this.getClass()
.getResource(JSON_FILE)).toURI()), componentIdentifier);
final String resultCategory = instance.getCategoryStr();
final String resultComponent = instance.getComponentStr();
assertEquals("Unknown", resultComponent);
assertEquals("None", resultCategory);
}

View File

@ -83,10 +83,6 @@ dependencies {
testImplementation libs.xmlunit.core
}
test {
useJUnitPlatform()
}
task buildVersion() {
doLast {
def verFile = new File(projectDir, "build/VERSION")

View File

@ -19,6 +19,7 @@ import hirs.attestationca.persist.entity.userdefined.certificate.IDevIDCertifica
import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
import hirs.attestationca.persist.util.CredentialHelper;
import hirs.attestationca.portal.datatables.DataTableInput;
import hirs.attestationca.portal.datatables.DataTableResponse;
@ -348,7 +349,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
records.setRecordsFiltered(caCredentialRepository.findByArchiveFlag(false).size());
log.debug("Returning the size of the list of certificate trust chains: {}", records.size());
log.debug("Returning the size of the list of trust chain certificates: {}", records.size());
return new DataTableResponse<>(records, input);
}
case ISSUEDCERTIFICATES -> {
@ -957,7 +958,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
}
this.certificateRepository.save(certificate);
handlePlatformComponents(certificate);
parseAndSaveComponentResults(certificate);
final String successMsg
= String.format("New certificate successfully uploaded (%s): ", fileName);
@ -971,6 +972,11 @@ public class CertificatePageController extends PageController<NoPageParams> {
messages.addError(failMessage + dbsEx.getMessage());
log.error(failMessage, dbsEx);
return;
} catch (IOException ioException) {
final String ioExceptionMessage = "Failed to save component results in the database";
messages.addError(ioExceptionMessage + ioException.getMessage());
log.error(ioExceptionMessage, ioException);
return;
}
try {
@ -1019,7 +1025,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
*
* @param certificate certificate
*/
private void handlePlatformComponents(final Certificate certificate) {
private void parseAndSaveComponentResults(final Certificate certificate) throws IOException {
PlatformCredential platformCredential;
if (certificate instanceof PlatformCredential) {
@ -1028,19 +1034,38 @@ public class CertificatePageController extends PageController<NoPageParams> {
.findByCertificateSerialNumberAndBoardSerialNumber(
platformCredential.getSerialNumber().toString(),
platformCredential.getPlatformSerial());
if (componentResults.isEmpty()) {
ComponentResult componentResult;
List<ComponentIdentifier> componentIdentifiers = platformCredential.getComponentIdentifiers();
if (platformCredential.getPlatformConfigurationV1() != null) {
for (ComponentIdentifier componentIdentifier : componentIdentifiers) {
componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
platformCredential.getSerialNumber().toString(),
platformCredential.getPlatformChainType(),
componentIdentifier);
componentResult.setFailedValidation(false);
componentResult.setDelta(!platformCredential.isPlatformBase());
componentResultRepository.save(componentResult);
List<ComponentIdentifier> componentIdentifiers =
platformCredential.getComponentIdentifiers();
for (ComponentIdentifier componentIdentifier : componentIdentifiers) {
componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
platformCredential.getSerialNumber().toString(),
platformCredential.getPlatformChainType(),
componentIdentifier);
componentResult.setFailedValidation(false);
componentResult.setDelta(!platformCredential.isPlatformBase());
componentResultRepository.save(componentResult);
}
} else if (platformCredential.getPlatformConfigurationV2() != null) {
List<ComponentIdentifierV2> componentIdentifiersV2 =
platformCredential.getComponentIdentifiersV2();
for (ComponentIdentifierV2 componentIdentifierV2 : componentIdentifiersV2) {
componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
platformCredential.getSerialNumber().toString(),
platformCredential.getPlatformChainType(),
componentIdentifierV2);
componentResult.setFailedValidation(false);
componentResult.setDelta(!platformCredential.isPlatformBase());
componentResultRepository.save(componentResult);
}
}
} else {
for (ComponentResult componentResult : componentResults) {

View File

@ -11,7 +11,9 @@ import hirs.attestationca.persist.entity.userdefined.certificate.IDevIDCertifica
import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfiguration;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfigurationV1;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.PlatformConfigurationV2;
import hirs.attestationca.persist.util.AcaPciIds;
import hirs.utils.BouncyCastleUtils;
import hirs.utils.PciIds;
@ -401,22 +403,39 @@ public final class CertificateStringMapBuilder {
data.put("componentResults", compResults);
//Get platform Configuration values and set map with it
PlatformConfiguration platformConfiguration = certificate.getPlatformConfiguration();
if (platformConfiguration != null) {
//Component Identifier - attempt to translate hardware IDs
List<ComponentIdentifier> comps = platformConfiguration.getComponentIdentifier();
if (certificate.getPlatformConfigurationV1() != null) {
PlatformConfigurationV1 platformConfigurationV1 = certificate.getPlatformConfigurationV1();
List<ComponentIdentifier> componentIdentifiersV1 =
platformConfigurationV1.getComponentIdentifiers();
if (PciIds.DB.isReady()) {
comps = AcaPciIds.translate(comps);
componentIdentifiersV1 = AcaPciIds.translate(componentIdentifiersV1);
}
data.put("componentsIdentifier", comps);
//Component Identifier URI
data.put("componentsIdentifierURI", platformConfiguration
.getComponentIdentifierUri());
//Component Identifiers
data.put("componentsIdentifier", componentIdentifiersV1);
//Platform Properties
data.put("platformProperties", platformConfiguration.getPlatformProperties());
data.put("platformProperties", platformConfigurationV1.getPlatformProperties());
//Platform Properties URI
data.put("platformPropertiesURI", platformConfiguration.getPlatformPropertiesUri());
data.put("platformPropertiesURI", platformConfigurationV1.getPlatformPropertiesUri());
} else if (certificate.getPlatformConfigurationV2() != null) {
PlatformConfigurationV2 platformConfigurationV2 = certificate.getPlatformConfigurationV2();
//Component Identifiers
List<ComponentIdentifierV2> componentIdentifiersV2 =
platformConfigurationV2.getComponentIdentifiers();
data.put("componentsIdentifier", componentIdentifiersV2);
//Component Identifier URI
data.put("componentsIdentifierURI", platformConfigurationV2
.getComponentIdentifiersUri());
//Platform Properties
data.put("platformProperties", platformConfigurationV2.getPlatformProperties());
//Platform Properties URI
data.put("platformPropertiesURI", platformConfigurationV2.getPlatformPropertiesUri());
}
//TBB Security Assertion
data.put("tbbSecurityAssertion", certificate.getTBBSecurityAssertion());

View File

@ -16,10 +16,6 @@ dependencies {
testAnnotationProcessor libs.lombok
}
test {
useJUnitPlatform()
}
//publishing {
// publications {
// maven(MavenPublication) {

View File

@ -42,10 +42,6 @@ dependencies {
testAnnotationProcessor libs.lombok
}
test {
useJUnitPlatform()
}
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest {

View File

@ -9,6 +9,7 @@ plugins {
id 'com.github.spotbugs' version '6.0.13' apply false
id 'org.owasp.dependencycheck' version '11.1.1'
id 'java'
id 'jacoco'
}
// Global checkstyle file
@ -19,6 +20,7 @@ subprojects {
apply plugin: "java"
apply plugin: "checkstyle"
apply plugin: "org.owasp.dependencycheck"
apply plugin: "jacoco"
repositories {
flatDir { dirs "lib" }
@ -31,6 +33,20 @@ subprojects {
}
}
jacoco {
toolVersion = '0.8.12'
}
if (project.name != 'tcg_rim_tool') // run tests on every subproject except for rim_tools
test {
useJUnitPlatform() // Use JUnit platform
finalizedBy jacocoTestReport // Generate the JaCoCo report after running tests
}
jacocoTestReport {
dependsOn test // tests are required to run before generating the report
}
checkstyle {
toolVersion = '10.20.0'
configFile file("${rootDir}/config/checkstyle/checkstyle.xml")
@ -61,7 +77,6 @@ subprojects {
}
}
dependencies {
repositories {
// Use Maven Central for resolving dependencies.

View File

@ -1,45 +1,56 @@
package hirs.swid;
import hirs.utils.rim.ReferenceManifestValidator;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.test.context.event.annotation.AfterTestClass;
import org.springframework.test.context.event.annotation.BeforeTestClass;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertTrue;
//TODO tests are broken
public class TestSwidTagGateway {
private static final String ATTRIBUTES_FILE = Objects.requireNonNull(
TestSwidTagGateway.class.getClassLoader()
.getResource("rim_fields.json")).getPath();
private static final String CA_CHAIN_FILE = Objects.requireNonNull(
TestSwidTagGateway.class.getClassLoader()
.getResource("RimCertChain.pem")).getPath();
private static final String SUPPORT_RIM_FILE = Objects.requireNonNull(
TestSwidTagGateway.class.getClassLoader()
.getResource("TpmLog.bin")).getPath();
private static SwidTagGateway gateway;
private static ReferenceManifestValidator validator;
private final String DEFAULT_OUTPUT = "generated_swidTag.swidtag";
private final String BASE_USER_CERT = "generated_user_cert.swidtag";
private final String BASE_USER_CERT_EMBED = "generated_user_cert_embed.swidtag";
private final String BASE_DEFAULT_CERT = "generated_default_cert.swidtag";
private final String BASE_RFC3339_TIMESTAMP = "generated_timestamp_rfc3339.swidtag";
private final String BASE_RFC3852_TIMESTAMP = "generated_timestamp_rfc3852.swidtag";
private final String ATTRIBUTES_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("rim_fields.json").getPath();
private final String JKS_KEYSTORE_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("keystore.jks").getPath();
private final String SIGNING_CERT_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("RimSignCert.pem").getPath();
private final String PRIVATE_KEY_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("privateRimKey.pem").getPath();
private final String CA_CHAIN_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("RimCertChain.pem").getPath();
private final String SUPPORT_RIM_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("TpmLog.bin").getPath();
private final String RFC3852_COUNTERSIGNATURE_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("counterSignature.file").getPath();
private SwidTagGateway gateway;
private ReferenceManifestValidator validator;
private final String JKS_KEYSTORE_FILE = Objects.requireNonNull(TestSwidTagGateway.class.getClassLoader()
.getResource("keystore.jks")).getPath();
private final String SIGNING_CERT_FILE = Objects.requireNonNull(TestSwidTagGateway.class.getClassLoader()
.getResource("RimSignCert.pem")).getPath();
private final String PRIVATE_KEY_FILE = Objects.requireNonNull(TestSwidTagGateway.class.getClassLoader()
.getResource("privateRimKey.pem")).getPath();
private final String RFC3852_COUNTERSIGNATURE_FILE = Objects.requireNonNull(
TestSwidTagGateway.class.getClassLoader()
.getResource("counterSignature.file")).getPath();
private InputStream expectedFile;
@BeforeTestClass
public void setUp() throws Exception {
@BeforeAll
public static void setUp() {
gateway = new SwidTagGateway();
gateway.setRimEventLog(SUPPORT_RIM_FILE);
gateway.setAttributesFile(ATTRIBUTES_FILE);
@ -48,7 +59,7 @@ public class TestSwidTagGateway {
validator.setTrustStoreFile(CA_CHAIN_FILE);
}
@AfterTestClass
@AfterEach
public void tearDown() throws Exception {
if (expectedFile != null) {
expectedFile.close();
@ -87,6 +98,7 @@ public class TestSwidTagGateway {
gateway.setPemPrivateKeyFile(PRIVATE_KEY_FILE);
gateway.setEmbeddedCert(true);
gateway.generateSwidTag(DEFAULT_OUTPUT);
final String BASE_USER_CERT_EMBED = "generated_user_cert_embed.swidtag";
expectedFile = TestSwidTagGateway.class.getClassLoader()
.getResourceAsStream(BASE_USER_CERT_EMBED);
assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
@ -103,6 +115,7 @@ public class TestSwidTagGateway {
gateway.setDefaultCredentials(true);
gateway.setJksTruststoreFile(JKS_KEYSTORE_FILE);
gateway.generateSwidTag(DEFAULT_OUTPUT);
final String BASE_DEFAULT_CERT = "generated_default_cert.swidtag";
expectedFile = TestSwidTagGateway.class.getClassLoader()
.getResourceAsStream(BASE_DEFAULT_CERT);
assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
@ -121,6 +134,7 @@ public class TestSwidTagGateway {
gateway.setTimestampFormat("RFC3339");
gateway.setTimestampArgument("2023-01-01T00:00:00Z");
gateway.generateSwidTag(DEFAULT_OUTPUT);
final String BASE_RFC3339_TIMESTAMP = "generated_timestamp_rfc3339.swidtag";
expectedFile = TestSwidTagGateway.class.getClassLoader()
.getResourceAsStream(BASE_RFC3339_TIMESTAMP);
assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
@ -139,6 +153,7 @@ public class TestSwidTagGateway {
gateway.setTimestampFormat("RFC3852");
gateway.setTimestampArgument(RFC3852_COUNTERSIGNATURE_FILE);
gateway.generateSwidTag(DEFAULT_OUTPUT);
final String BASE_RFC3852_TIMESTAMP = "generated_timestamp_rfc3852.swidtag";
expectedFile = TestSwidTagGateway.class.getClassLoader()
.getResourceAsStream(BASE_RFC3852_TIMESTAMP);
assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
@ -150,10 +165,10 @@ public class TestSwidTagGateway {
* This test corresponds to the arguments:
* -v <path>
*/
public void testvalidateSwidtagFile() {
String filepath = TestSwidTagGateway.class.getClassLoader()
.getResource(BASE_USER_CERT).getPath();
@Test
public void testValidateSwidtagFile() {
final String filepath = Objects.requireNonNull(TestSwidTagGateway.class.getClassLoader()
.getResource(BASE_USER_CERT)).getPath();
System.out.println("Validating file at " + filepath);
validator.setRim(DEFAULT_OUTPUT);
assertTrue(validator.validateRim(SIGNING_CERT_FILE));
@ -178,13 +193,7 @@ public class TestSwidTagGateway {
return false;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
} catch (NullPointerException e) {
} catch (IOException | NullPointerException e) {
e.printStackTrace();
return false;
} finally {