diff --git a/.github/workflows/create_aca_images.yml b/.github/workflows/create_aca_images.yml index 12677cb2f..35322ddb4 100644 --- a/.github/workflows/create_aca_images.yml +++ b/.github/workflows/create_aca_images.yml @@ -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: 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: 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}} + 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: Login to GitHub Container Registry - uses: docker/login-action@v3 - 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: 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}} --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 diff --git a/.github/workflows/dotnet_provisioner_unit_tests.yml b/.github/workflows/dotnet_provisioner_unit_tests.yml index 603e4b311..6fa613dc0 100644 --- a/.github/workflows/dotnet_provisioner_unit_tests.yml +++ b/.github/workflows/dotnet_provisioner_unit_tests.yml @@ -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: diff --git a/.github/workflows/hirs_package_linux.yml b/.github/workflows/hirs_package_linux.yml index b8f04b069..5b7b5ca07 100644 --- a/.github/workflows/hirs_package_linux.yml +++ b/.github/workflows/hirs_package_linux.yml @@ -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 diff --git a/.github/workflows/hirs_unit_tests.yml b/.github/workflows/hirs_unit_tests.yml index 240edef95..09b979014 100644 --- a/.github/workflows/hirs_unit_tests.yml +++ b/.github/workflows/hirs_unit_tests.yml @@ -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 : - # 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 '' - 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 : + # 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 '' + 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') \ No newline at end of file diff --git a/.github/workflows/rim_tests.yml b/.github/workflows/rim_tests.yml index 11799391b..c45e6d348 100644 --- a/.github/workflows/rim_tests.yml +++ b/.github/workflows/rim_tests.yml @@ -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 diff --git a/.github/workflows/system_test.yml b/.github/workflows/system_test.yml index cb8b44e0f..ab5167bbf 100644 --- a/.github/workflows/system_test.yml +++ b/.github/workflows/system_test.yml @@ -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: diff --git a/HIRS_AttestationCA/build.gradle b/HIRS_AttestationCA/build.gradle index dfe5a908e..88f242800 100644 --- a/HIRS_AttestationCA/build.gradle +++ b/HIRS_AttestationCA/build.gradle @@ -65,8 +65,4 @@ sourceSets { srcDir '../HIRS_Provisioner.NET/hirs/Resources' } } -} - -test { - useJUnitPlatform() -} +} \ No newline at end of file diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java index db00267de..1cc403028 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java @@ -108,7 +108,7 @@ public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim) * 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 diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ComponentResult.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ComponentResult.java index 01eef415a..5ce0127e5 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ComponentResult.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ComponentResult.java @@ -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 ComponentResult(final String boardSerialNumber, final String certificateS } 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(); } } } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java index e11ab1463..4a7d654f8 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java @@ -2,10 +2,10 @@ 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 static PlatformCredential parseWithPossibleHeader(final byte[] certificat /** * 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 boolean isSignatureValid(final ContentVerifierProvider verifierProvider) return verifier.verify(attCert.getSignatureValue().getOctets()); } + /** + * Parses the Platform Certificate fields. + */ private void parseFields() throws IOException { AttributeCertificateInfo certificate = getAttributeCertificate().getAcinfo(); Map policyQualifier = getPolicyQualifier(certificate); @@ -403,7 +411,7 @@ private void parseFields() throws IOException { } /** - * Parse a 1.2 Platform Certificate (Attribute Certificate). + * Parses a 1.2 Platform Certificate (Attribute Certificate). * * @param certificate Attribute Certificate */ @@ -456,7 +464,7 @@ private void parseAttributeCert(final AttributeCertificateInfo certificate) { } /** - * Parse a 2.0 Platform Certificate (Attribute Certificate). + * Parses a 2.0 Platform Certificate (Attribute Certificate). * * @param certificate Attribute Certificate */ @@ -505,7 +513,7 @@ private void parseAttributeCert2(final AttributeCertificateInfo certificate) } /** - * 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 int getX509CredentialVersion() { } /** - * 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 String getCPSuri() throws IOException { } /** - * 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 Map getAllAttributes() throws IllegalArgumentException, IOException { Map 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 Map getAllAttributes() 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 Object getAttribute(final String attributeName) * @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 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 PlatformConfiguration) { - return (PlatformConfiguration) getAttribute("platformConfiguration"); + && getAttribute("platformConfiguration") instanceof PlatformConfigurationV2) { + return (PlatformConfigurationV2) getAttribute("platformConfiguration"); } return null; @@ -684,20 +712,39 @@ private void getTCGCredentialSpecification(final ASN1Sequence attributeSequence) } /** - * 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 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 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(); + } } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentAddress.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentAddress.java index 2f9f82a93..7284b08d1 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentAddress.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentAddress.java @@ -8,7 +8,7 @@ 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. *
  * componentAddress ::= SEQUENCE {
  *      addressType AddressType,
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java
index ab4683d1a..95684d3aa 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java
@@ -33,6 +33,10 @@
 
     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 @@ public ComponentClass(final String registryOid,
         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;
         };
 
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java
index 7b56a2838..d0549c9e6 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentIdentifier.java
@@ -16,8 +16,8 @@
 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.
  * 
  * ComponentIdentifier ::= SEQUENCE {
  *      componentManufacturer UTF8String (SIZE (1..STRMAX)),
@@ -26,7 +26,7 @@
  *      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
  * 
@@ -80,7 +80,7 @@ public class ComponentIdentifier { private ASN1Boolean fieldReplaceable; - private List componentAddress; + private List componentAddresses; private boolean validationResult = true; @@ -94,7 +94,7 @@ public ComponentIdentifier() { componentRevision = new DERUTF8String(NOT_SPECIFIED_COMPONENT); componentManufacturerId = null; fieldReplaceable = null; - componentAddress = new ArrayList<>(); + componentAddresses = new ArrayList<>(); } /** @@ -106,7 +106,7 @@ public 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 ComponentIdentifier(final DERUTF8String componentManufacturer, final DERUTF8String componentRevision, final ASN1ObjectIdentifier componentManufacturerId, final ASN1Boolean fieldReplaceable, - final List componentAddress) { + final List 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 ComponentIdentifier(final ASN1Sequence sequence) throws IllegalArgumentEx 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 String toString() { 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(); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfiguration.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfiguration.java deleted file mode 100644 index 9680dc926..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfiguration.java +++ /dev/null @@ -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 = new ArrayList<>(); - @Getter - @Setter - private URIReference componentIdentifierUri; - private ArrayList 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, - final List platformProperties, - final URIReference platformPropertiesUri) { - this.componentIdentifier = new ArrayList<>(componentIdentifier); - this.platformProperties = new ArrayList<>(platformProperties); - this.platformPropertiesUri = platformPropertiesUri; - } - - /** - * @return the componentIdentifier - */ - public List getComponentIdentifier() { - return Collections.unmodifiableList(componentIdentifier); - } - - /** - * @param componentIdentifier the componentIdentifier to set - */ - public void setComponentIdentifier(final List 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 getPlatformProperties() { - return Collections.unmodifiableList(platformProperties); - } - - /** - * @param platformProperties the platformProperties to set - */ - public void setPlatformProperties(final List 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; - } -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfigurationV1.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfigurationV1.java index c0dd0df62..757660b33 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfigurationV1.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/PlatformConfigurationV1.java @@ -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. *
  * 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 }
  * 
*/ -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 componentIdentifiers; + + private List 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 PlatformConfigurationV1(final ASN1Sequence sequence) throws IllegalArgume //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 PlatformConfigurationV1(final ASN1Sequence sequence) throws IllegalArgume } } + /** + * @return list of version 1 component identifiers + */ + public List getComponentIdentifiers() { + return Collections.unmodifiableList(componentIdentifiers); + } + + /** + * @param componentIdentifiers list of version 1 component identifiers + */ + public void setComponentIdentifiers(final List 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 getPlatformProperties() { + return Collections.unmodifiableList(platformProperties); + } + + /** + * @param platformProperties the platformProperties to set + */ + public void setPlatformProperties(final List 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 PlatformConfigurationV1(final ASN1Sequence sequence) throws IllegalArgume 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) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/AttributeStatus.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/AttributeStatus.java index 5a5b9b032..d9ea0999a 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/AttributeStatus.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/AttributeStatus.java @@ -16,6 +16,7 @@ * removed (2) } *
*/ +@Getter @AllArgsConstructor public enum AttributeStatus { /** @@ -35,6 +36,5 @@ public enum AttributeStatus { */ EMPTY_STATUS(StringUtils.EMPTY); - @Getter private final String value; } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/CertificateIdentifier.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/CertificateIdentifier.java index 2512d4981..2a00f9ca1 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/CertificateIdentifier.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/CertificateIdentifier.java @@ -76,6 +76,12 @@ public CertificateIdentifier(final ASN1Sequence sequence) { } } + /** + * 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 @@ private void parseAttributeCertId(final ASN1Sequence attrCertSeq) { 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) { diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java index e7b4aa5b9..88dbceab7 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/ComponentIdentifierV2.java @@ -20,17 +20,18 @@ 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. *
  * 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 ComponentIdentifierV2(final ComponentClass componentClass,
                                  final ASN1ObjectIdentifier componentManufacturerId,
                                  final ASN1Boolean fieldReplaceable,
                                  final List 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 ComponentIdentifierV2(final ASN1Sequence sequence)
                     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 ComponentIdentifierV2(final ASN1Sequence sequence)
         }
     }
 
-    /**
-     * @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 String toString() {
         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) {
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java
index 58dd341d1..58c2f4543 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/V2/PlatformConfigurationV2.java
@@ -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.
  * 
  * PlatformConfiguration ::= SEQUENCE {
@@ -20,23 +25,49 @@
  *      platformPropertiesUri [3] IMPLICIT URIReference OPTIONAL }
  * 
*/ -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 componentIdentifiers; + + @Getter + @Setter + private URIReference componentIdentifiersUri; + + private List platformProperties; + + @Getter + @Setter + private URIReference platformPropertiesUri; + + /** + * Default constructor. + */ + public PlatformConfigurationV2() { + componentIdentifiers = new ArrayList<>(); + componentIdentifiersUri = null; + platformProperties = new ArrayList<>(); + platformPropertiesUri = null; + } + /** - * Constructor given the SEQUENCE that contains Platform Configuration. + * 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 PlatformConfigurationV2(final ASN1Sequence sequence) throws IllegalArgume //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 PlatformConfigurationV2(final ASN1Sequence sequence) throws IllegalArgume } } + /** + * @return a collection of version 2 component identifiers. + */ + public List getComponentIdentifiers() { + return Collections.unmodifiableList(componentIdentifiers); + } + + /** + * @param componentIdentifiers list of version 2 component identifiers + */ + public void setComponentIdentifiers( + final List 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 getPlatformProperties() { + return Collections.unmodifiableList(platformProperties); + } + + /** + * @param platformProperties the platformProperties to set + */ + public void setPlatformProperties(final List 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 PlatformConfigurationV2(final ASN1Sequence sequence) throws IllegalArgume @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) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/ComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/ComponentInfo.java index aa98f2828..7ab181118 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/ComponentInfo.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/ComponentInfo.java @@ -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,26 @@ public ComponentInfo(final String deviceName, final String componentModel, final String componentSerial, final String componentRevision) { - if (isComplete( - componentManufacturer, - componentModel, - componentSerial, - componentRevision)) { - log.error("ComponentInfo: manufacturer and/or " + + if ((StringUtils.isEmpty(componentManufacturer) + || StringUtils.isEmpty(componentModel))) { + + log.error("Component Info's manufacturer and/or " + "model can not be null"); throw new NullPointerException("ComponentInfo: manufacturer and/or " + "model can not be null"); } + this.deviceName = deviceName; this.componentManufacturer = componentManufacturer.trim(); 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 +121,28 @@ public ComponentInfo(final String deviceName, /** * 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 +151,6 @@ public static boolean isComplete(final String componentManufacturer, */ public int hashCommonElements() { return Objects.hash(componentManufacturer, componentModel, - componentSerial, componentRevision, componentClass); + componentSerial, componentRevision, componentClassValue, componentClassRegistry); } } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/FirmwareInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/FirmwareInfo.java index 8921c1088..784199226 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/FirmwareInfo.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/FirmwareInfo.java @@ -19,11 +19,11 @@ 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 diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/HardwareInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/HardwareInfo.java index 35a9bd7fa..b9b379b17 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/HardwareInfo.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/HardwareInfo.java @@ -22,11 +22,11 @@ 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; /** diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/NetworkInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/NetworkInfo.java index 73ec8d801..8993d3be8 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/NetworkInfo.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/NetworkInfo.java @@ -23,7 +23,7 @@ public class NetworkInfo implements Serializable { @XmlElement @Getter - @Column(length = DeviceInfoEnums.LONG_STRING_LENGTH) + @Column private String hostname; @XmlElement diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/OSInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/OSInfo.java index 285682df4..218ce6978 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/OSInfo.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/OSInfo.java @@ -21,11 +21,11 @@ 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; /** diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/TPMInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/TPMInfo.java index 5ca240ff4..55ec2b9e8 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/TPMInfo.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/TPMInfo.java @@ -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; /** diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BIOSComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BIOSComponentInfo.java deleted file mode 100644 index c74fe65be..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BIOSComponentInfo.java +++ /dev/null @@ -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); - } -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BaseboardComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BaseboardComponentInfo.java deleted file mode 100644 index af9750610..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/BaseboardComponentInfo.java +++ /dev/null @@ -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); - } -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ChassisComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ChassisComponentInfo.java deleted file mode 100644 index b26a3f18c..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ChassisComponentInfo.java +++ /dev/null @@ -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); - } -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/HardDriveComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/HardDriveComponentInfo.java deleted file mode 100644 index fe5f0846a..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/HardDriveComponentInfo.java +++ /dev/null @@ -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); - } -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/MemoryComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/MemoryComponentInfo.java deleted file mode 100644 index 5e794601d..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/MemoryComponentInfo.java +++ /dev/null @@ -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); - } -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/NICComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/NICComponentInfo.java deleted file mode 100644 index 8f15c72cc..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/NICComponentInfo.java +++ /dev/null @@ -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); - } -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ProcessorComponentInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ProcessorComponentInfo.java deleted file mode 100644 index a2d53f254..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/ProcessorComponentInfo.java +++ /dev/null @@ -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); - } -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/package-info.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/package-info.java deleted file mode 100644 index a7f241713..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/component/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package hirs.attestationca.persist.entity.userdefined.info.component; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java index 087f4be1b..9b56ba374 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java @@ -159,6 +159,7 @@ protected EndorsementCredential parseEcFromIdentityClaim( final ProvisionerTpm2.IdentityClaim identityClaim, final PublicKey ekPub, final CertificateRepository certificateRepository) { EndorsementCredential endorsementCredential = null; + if (identityClaim.hasEndorsementCredential()) { endorsementCredential = CredentialManagementHelper.storeEndorsementCredential( certificateRepository, @@ -172,6 +173,7 @@ protected EndorsementCredential parseEcFromIdentityClaim( 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,6 +193,7 @@ protected List parsePcsFromIdentityClaim( final EndorsementCredential endorsementCredential, final CertificateRepository certificateRepository) { List platformCredentials = new LinkedList<>(); + if (identityClaim.getPlatformCredentialCount() > 0) { for (ByteString platformCredential : identityClaim.getPlatformCredentialList()) { if (!platformCredential.isEmpty()) { @@ -206,6 +209,7 @@ protected List parsePcsFromIdentityClaim( } else { log.warn("No platform credential received in identity claim."); } + return platformCredentials; } @@ -219,7 +223,7 @@ protected List parsePcsFromIdentityClaim( 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 +258,8 @@ private EndorsementCredential getEndorsementCredential( * @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 +288,7 @@ public boolean saveAttestationCertificate(final CertificateRepository certificat 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 +324,13 @@ private List getPlatformCredentials(final CertificateReposit 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()); } } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java index cbe87597d..1850a1cda 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java @@ -20,6 +20,7 @@ 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 byte[] processIdentityClaimTpm2(final byte[] identityClaim) { } 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 byte[] processIdentityClaimTpm2(final byte[] identityClaim) { 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 byte[] processIdentityClaimTpm2(final byte[] identityClaim) { * @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 @@ private AppraisalStatus.Status doSupplyChainValidation( // 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 @@ private AppraisalStatus.Status doSupplyChainValidation( platformCredentials.addAll(tempList); } + // store component results objects for (PlatformCredential platformCredential : platformCredentials) { List 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 @@ private AppraisalStatus.Status doSupplyChainValidation( 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 @@ private Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) { } 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 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim cla macAddressBytes[i] = hex.byteValue(); } } + NetworkInfo nw = new NetworkInfo(nwProto.getHostname(), ip, macAddressBytes); // Get firmware info @@ -334,16 +354,19 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim cla // 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 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim cla 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 rdValues = new LinkedList<>(); SupportReferenceManifest baseSupportRim = null; @@ -620,7 +651,7 @@ private boolean generateDigestRecords(final String manufacturer, final String mo .findByManufacturerAndModel(manufacturer, model); Map digestValueMap = new HashMap<>(); - expectedValues.stream().forEach((rdv) -> { + expectedValues.forEach((rdv) -> { digestValueMap.put(rdv.getDigestValue(), rdv); }); @@ -709,35 +740,60 @@ private boolean generateDigestRecords(final String manufacturer, final String mo 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 componentInfoMap = new HashMap<>(); + try { List componentInfos = SupplyChainCredentialValidator .getComponentInfoFromPaccorOutput(hostName, paccorString); // check the DB for like component infos List dbComponentInfos = this.componentInfoRepository.findByDeviceName(hostName); - dbComponentInfos.stream().forEach((infos) -> { + dbComponentInfos.forEach((infos) -> { componentInfoMap.put(infos.hashCode(), infos); }); @@ -753,7 +809,5 @@ private int handleDeviceComponents(final String hostName, final String paccorStr } catch (IOException ioEx) { log.warn("Error parsing paccor string"); } - - return deviceComponents; } } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java index ae22d14ab..77f6a1f55 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java @@ -16,7 +16,6 @@ public final class CredentialManagementHelper { private CredentialManagementHelper() { - } /** @@ -48,7 +47,7 @@ public static EndorsementCredential storeEndorsementCredential( ); } - 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 static EndorsementCredential storeEndorsementCredential( 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); @@ -102,15 +103,19 @@ public static PlatformCredential storePlatformCredential( ); } - 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) { return null; } + PlatformCredential existingCredential = (PlatformCredential) certificateRepository .findByCertificateHash(platformCredential.getCertificateHash()); + if (existingCredential == null) { if (platformCredential.getPlatformSerial() != null) { List certificates = certificateRepository @@ -121,10 +126,10 @@ public static PlatformCredential storePlatformCredential( 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 +138,8 @@ public static PlatformCredential storePlatformCredential( 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; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java index 61120b1a0..3375f175e 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java @@ -32,6 +32,7 @@ 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 SupplyChainValidationService( public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredential ec, final List pcs, final Device device, - final List componentInfos) { + final List componentInfos) + throws IOException { boolean acceptExpiredCerts = getPolicySettings().isExpiredCertificateValidationEnabled(); provisionSessionId = UUID.randomUUID(); PlatformCredential baseCredential = null; @@ -153,6 +155,7 @@ public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredent pcErrorMessage = String.format("%s%s%n", pcErrorMessage, platformScv.getMessage()); } + // set the base credential if (pc.isPlatformBase()) { baseCredential = pc; @@ -407,9 +410,9 @@ public SupplyChainValidationSummary validateQuote(final Device device) { } /** - * 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"); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java index 76efb8df8..26ceb8f83 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java @@ -98,9 +98,10 @@ public static SupplyChainValidation evaluatePlatformCredentialStatus( = 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 static SupplyChainValidation evaluatePCAttributesStatus( final ComponentResultRepository componentResultRepository, final ComponentAttributeRepository componentAttributeRepository, final List 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); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/AcaPciIds.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/AcaPciIds.java index 73e90f12f..777cfe26e 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/AcaPciIds.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/AcaPciIds.java @@ -110,9 +110,9 @@ public static ComponentIdentifierV2 translate(final ComponentIdentifierV2 compon component.getComponentRevision(), component.getComponentManufacturerId(), component.getFieldReplaceable(), - component.getComponentAddress(), - component.getCertificateIdentifier(), - component.getComponentPlatformUri(), + component.getComponentAddresses(), + component.getComponentPlatformCert(), + component.getComponentPlatformCertUri(), component.getAttributeStatus()); } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java index af9464ca2..88d179220 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java @@ -6,6 +6,7 @@ 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.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 static AppraisalStatus validatePlatformCredentialAttributesV1p2( 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 static AppraisalStatus validatePlatformCredentialAttributesV1p2( 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 static AppraisalStatus validatePlatformCredentialAttributesV2p0( final ComponentResultRepository componentResultRepository, final ComponentAttributeRepository componentAttributeRepository, final List 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 static AppraisalStatus validatePlatformCredentialAttributesV2p0( passesValidation &= fieldValidation; - // Retrieve the list of all components from the Platform Credential - List 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 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) { - passesValidation &= fieldValidation; + fieldValidation = !isRequiredASN1StringFieldBlank("componentManufacturer", + pcComponent.getComponentManufacturer()); - fieldValidation = !hasEmptyValueForRequiredField("componentModel", - pcComponent.getComponentModel()); + if (!fieldValidation) { + resultMessage.append("Component manufacturer is empty\n"); + } - if (!fieldValidation) { - resultMessage.append("Component model 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 allV2PcComponents + = new ArrayList<>(platformCredential.getComponentIdentifiersV2()); + + + // 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; + } + } } // populate componentResults list @@ -263,18 +366,24 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0( .findByCertificateSerialNumberAndBoardSerialNumber( platformCredential.getSerialNumber().toString(), platformCredential.getPlatformSerial()); + // first create hash map based on hashCode List remainingComponentResults = checkDeviceHashMap( componentInfos, componentResults); + //this is used to get a unique count List componentIdList = new ArrayList<>(); + int numOfAttributes = 0; + if (!remainingComponentResults.isEmpty()) { List attributeResults = checkComponentClassMap( componentInfos, remainingComponentResults); numOfAttributes = attributeResults.size(); + boolean saveAttributeResult; + for (ComponentAttributeResult componentAttributeResult : attributeResults) { saveAttributeResult = true; if (ignoreRevisionAttribute) { @@ -293,6 +402,7 @@ public static AppraisalStatus validatePlatformCredentialAttributesV2p0( } 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 @@ private static String validateV2PlatformCredentialAttributes( 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 @@ && isMatch(cId, cInfo)) { 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 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc 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 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 pcUnmatchedComponents = new ArrayList<>(); for (ASN1UTF8String derUtf8Manufacturer : manufacturerSet) { + + // look for all the component identifiers whose manufacturer matches that of the current + // manufacturer List 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 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 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc = 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 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc } } } + // 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 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc = 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 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc 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 @@ private static String validateV2p0PlatformCredentialComponentsExpectingExactMatc 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 static boolean isMatch(final ComponentIdentifier pcComponent, 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 @@ private static boolean requiredPlatformCredentialFieldIsNonEmptyAndMatches( final String platformCredentialFieldName, final String platformCredentialFieldValue, final String otherValue) { - if (hasEmptyValueForRequiredField(platformCredentialFieldName, + if (isRequiredStringFieldBlank(platformCredentialFieldName, platformCredentialFieldValue)) { return false; } @@ -794,11 +914,10 @@ private static boolean optionalPlatformCredentialFieldNullOrMatches( * @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 @@ private static boolean platformCredentialFieldMatches( 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 @@ private static boolean platformCredentialFieldMatches( * @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,7 +989,7 @@ private static List checkDeviceHashMap( final List componentInfos, final List compiledComponentList) { Map> deviceHashMap = new HashMap<>(); - componentInfos.stream().forEach((componentInfo) -> { + componentInfos.forEach((componentInfo) -> { List innerList; Integer compInfoHash = componentInfo.hashCommonElements(); if (deviceHashMap.containsKey(compInfoHash)) { @@ -910,9 +1028,9 @@ private static List checkComponentClassMap( // continue down the options, move to a different method. // create component class mapping to component info Map> componentDeviceMap = new HashMap<>(); - componentInfos.stream().forEach((componentInfo) -> { + componentInfos.forEach((componentInfo) -> { List innerList; - String componentClass = componentInfo.getComponentClass(); + String componentClass = componentInfo.getComponentClassValue(); if (componentDeviceMap.containsKey(componentClass)) { innerList = componentDeviceMap.get(componentClass); innerList.add(componentInfo); @@ -1000,11 +1118,13 @@ private static List generateComponentAttributeResults( private static List findMismatchedValues( final List componentClassInfo, final ComponentResult componentResult) { + // this list only has those of the same class type Map 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()); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java index 722f9b486..1913ccd58 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java @@ -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 static AppraisalStatus validateEndorsementCredential(final EndorsementCre * * @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 static AppraisalStatus validatePlatformCredentialAttributes( final ComponentResultRepository componentResultRepository, final ComponentAttributeRepository componentAttributeRepository, final List 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); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java index 914ac968c..040c30d36 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java @@ -270,7 +270,7 @@ public static String validateCertChain(final X509Certificate cert, * 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 +296,23 @@ public static List getComponentInfoFromPaccorOutput(final String 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)); } } } diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredentialTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredentialTest.java index 355fa9037..6ab46e530 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredentialTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredentialTest.java @@ -3,10 +3,11 @@ 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 final void testPlatformConfiguration() throws IOException, URISyntaxExcep Path certPath = Paths.get(resource.toURI()); PlatformCredential platformCert = new PlatformCredential(certPath); - PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + PlatformConfigurationV1 platformConfigV1 = platformCert.getPlatformConfigurationV1(); //Check component identifier - List allComponents = platformConfig.getComponentIdentifier(); + List allComponents = platformConfigV1.getComponentIdentifiers(); if (allComponents.isEmpty()) { Assertions.fail("Component Identifier is empty."); } @@ -472,14 +473,14 @@ public final void testPlatformConfiguration() throws IOException, URISyntaxExcep 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 platformProperties = platformConfig.getPlatformProperties(); + List platformProperties = platformConfigV1.getPlatformProperties(); if (platformProperties.isEmpty()) { Assertions.fail("Platform Properties is empty."); } @@ -499,7 +500,7 @@ public final void testPlatformConfiguration() throws IOException, URISyntaxExcep 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 final void testPlatformConfiguration2() throws IOException, URISyntaxExce Path certPath = Paths.get(resource.toURI()); PlatformCredential platformCert = new PlatformCredential(certPath); - PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + PlatformConfigurationV1 platformConfigV1 = platformCert.getPlatformConfigurationV1(); //Check component identifier - List allComponents = platformConfig.getComponentIdentifier(); + List allComponents = platformConfigV1.getComponentIdentifiers(); Assertions.assertTrue(allComponents.isEmpty()); - List platformProperties = platformConfig.getPlatformProperties(); + List platformProperties = platformConfigV1.getPlatformProperties(); if (platformProperties.isEmpty()) { Assertions.fail("Platform Properties is empty."); } @@ -560,10 +561,10 @@ public final void testPlatformConfiguration3() throws IOException, URISyntaxExce Path certPath = Paths.get(resource.toURI()); PlatformCredential platformCert = new PlatformCredential(certPath); - PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + PlatformConfigurationV1 platformConfigV1 = platformCert.getPlatformConfigurationV1(); //Check component identifier - List allComponents = platformConfig.getComponentIdentifier(); + List allComponents = platformConfigV1.getComponentIdentifiers(); if (allComponents.isEmpty()) { Assertions.fail("Component Identifier is empty."); } @@ -589,7 +590,7 @@ public final void testPlatformConfiguration3() throws IOException, URISyntaxExce .getString()); //Check Platform Properties - List platformProperties = platformConfig.getPlatformProperties(); + List platformProperties = platformConfigV1.getPlatformProperties(); if (platformProperties.isEmpty()) { Assertions.fail("Platform Properties is empty."); } @@ -597,7 +598,7 @@ public final void testPlatformConfiguration3() throws IOException, URISyntaxExce 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 final void testPlatformConfiguration4() throws IOException, URISyntaxExce Path certPath = Paths.get(resource.toURI()); PlatformCredential platformCert = new PlatformCredential(certPath); - PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + PlatformConfigurationV1 platformConfigV1 = platformCert.getPlatformConfigurationV1(); //Check component identifier - List allComponents = platformConfig.getComponentIdentifier(); + List allComponents = platformConfigV1.getComponentIdentifiers(); if (allComponents.isEmpty()) { Assertions.fail("Component Identifier is empty."); } @@ -651,15 +652,15 @@ public final void testPlatformConfiguration4() throws IOException, URISyntaxExce //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 platformProperties = platformConfig.getPlatformProperties(); + List platformProperties = platformConfigV1.getPlatformProperties(); if (platformProperties.isEmpty()) { Assertions.fail("Platform Properties is empty."); } @@ -667,7 +668,7 @@ public final void testPlatformConfiguration4() throws IOException, URISyntaxExce 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 final void testPlatformConfiguration5() throws IOException, URISyntaxExce Path certPath = Paths.get(resource.toURI()); PlatformCredential platformCert = new PlatformCredential(certPath); - PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + PlatformConfigurationV2 platformConfigV2 = platformCert.getPlatformConfigurationV2(); //Check component identifier - List allComponents = platformConfig.getComponentIdentifier(); + List 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 platformProperties = platformConfig.getPlatformProperties(); + List platformProperties = platformConfigV2.getPlatformProperties(); if (platformProperties.isEmpty()) { Assertions.fail("Platform Properties is empty."); } @@ -749,15 +750,15 @@ public final void testPlatformConfiguration6() throws IOException, URISyntaxExce 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"); diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClassTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClassTest.java index 8dc543583..0bd1c0f25 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClassTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClassTest.java @@ -4,6 +4,7 @@ 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.assertNull; @@ -16,290 +17,311 @@ 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(resultComponent, "Unknown"); assertEquals(resultCategory, "None"); } /** - * 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"; - ComponentClass instance = new ComponentClass("TCG", Paths.get(this.getClass() - .getResource(JSON_FILE).toURI()), componentIdentifier); - String resultCategory = instance.getCategoryStr(); - String resultComponent = instance.getComponentStr(); + final String componentIdentifier = "00000000"; + ComponentClass instance = new ComponentClass("TCG", Paths.get(Objects.requireNonNull(this.getClass() + .getResource(JSON_FILE)).toURI()), componentIdentifier); + final String resultCategory = instance.getCategoryStr(); + final String resultComponent = instance.getComponentStr(); assertEquals(resultComponent, "Unknown"); assertEquals(resultCategory, "None"); } /** - * 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 = ""; - ComponentClass instance = new ComponentClass(Paths.get(this.getClass() - .getResource(JSON_FILE).toURI()), componentIdentifier); - String resultCategory = instance.getCategoryStr(); - String resultComponent = instance.getComponentStr(); + final String componentIdentifier = ""; + 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(resultComponent, "Unknown"); assertEquals(resultCategory, "None"); } /** - * 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"; - ComponentClass instance = new ComponentClass(Paths.get(this.getClass() - .getResource(JSON_FILE).toURI()), componentIdentifier); - String resultCategory = instance.getCategoryStr(); - String resultComponent = instance.getComponentStr(); + final String componentIdentifier = "99999999"; + 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(resultComponent, "Unknown"); assertEquals(resultCategory, "None"); } /** - * 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; - ComponentClass instance = new ComponentClass(Paths.get(this.getClass() - .getResource(JSON_FILE).toURI()), componentIdentifier); - String resultCategory = instance.getCategoryStr(); - String resultComponent = instance.getComponentStr(); + final String componentIdentifier = null; + 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(resultComponent, "Unknown"); assertEquals(resultCategory, "None"); } /** - * 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"; - ComponentClass instance = new ComponentClass(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(Paths.get(Objects.requireNonNull(this.getClass() + .getResource(JSON_FILE)).toURI()), componentIdentifier); + final String resultCategory = instance.getCategoryStr(); + final String resultComponent = instance.getComponentStr(); assertEquals(resultComponent, "SAS Bridgeboard"); assertEquals(resultCategory, "Modules"); } /** - * 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(resultComponent, "SAS Bridgeboard"); - assertEquals(resultCategory, "Modules"); + 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(resultComponent, "SAS Bridgeboard"); assertEquals(resultCategory, "Modules"); } /** - * 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(resultComponent, "SAS Bridgeboard"); assertEquals(resultCategory, "Modules"); } /** - * 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(); assertNull(resultComponent); assertEquals(resultCategory, "Modules"); } /** - * 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(); assertNull(resultComponent); assertEquals(resultCategory, "Modules"); } /** - * 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(resultComponent, "Unknown"); assertEquals(resultCategory, "None"); } diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java index 7384e4b5f..83feb0306 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java @@ -1,17 +1,25 @@ package hirs.attestationca.persist.validation; +import hirs.attestationca.persist.entity.manager.ComponentAttributeRepository; +import hirs.attestationca.persist.entity.manager.ComponentResultRepository; import hirs.attestationca.persist.entity.userdefined.Certificate; import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential; import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; +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.PlatformConfigurationV1; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.URIReference; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.AttributeStatus; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.CertificateIdentifier; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.PlatformConfigurationV2; import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo; import hirs.attestationca.persist.entity.userdefined.info.FirmwareInfo; import hirs.attestationca.persist.entity.userdefined.info.HardwareInfo; import hirs.attestationca.persist.entity.userdefined.info.NetworkInfo; import hirs.attestationca.persist.entity.userdefined.info.OSInfo; import hirs.attestationca.persist.entity.userdefined.info.TPMInfo; -import hirs.attestationca.persist.entity.userdefined.info.component.NICComponentInfo; import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport; import hirs.attestationca.persist.enums.AppraisalStatus; import hirs.utils.enums.DeviceInfoEnums; @@ -34,8 +42,12 @@ import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import java.io.BufferedReader; import java.io.File; @@ -201,12 +213,21 @@ public class SupplyChainCredentialValidatorTest { private static final String NEW_NUC1 = "/validation/platform_credentials/Intel_pc3.cer"; - private static HardwareInfo hardwareInfo; - private static KeyStore keyStore; private static KeyStore emptyKeyStore; + @Mock + private ComponentResultRepository componentResultRepository; + + @Mock + private ComponentAttributeRepository componentAttributeRepository; + + /** + * Holds the AutoCloseable instance returned by openMocks. + */ + private AutoCloseable mocks; + /** * Sets up a KeyStore for testing. * @@ -246,183 +267,38 @@ public static void tearDown() { } } - private static DeviceInfoReport setupDeviceInfoReport() { - hardwareInfo = new HardwareInfo( - "ACME", - "anvil", - "3.0", - "1234", - "567", - "890"); - - DeviceInfoReport deviceInfoReport = mock(DeviceInfoReport.class); - when(deviceInfoReport.getHardwareInfo()).thenReturn(hardwareInfo); - return deviceInfoReport; - } - - private static DeviceInfoReport setupDeviceInfoReportWithComponents() throws IOException { - return setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_TXT); - } - - private static DeviceInfoReport setupDeviceInfoReportWithNotSpecifiedComponents() - throws IOException { - return setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_NOT_SPECIFIED_TXT); - } - - private static DeviceInfoReport setupDeviceInfoReportWithComponents( - final String paccorOutputResource) throws IOException { - DeviceInfoReport deviceInfoReport = setupDeviceInfoReport(); - URL url = SupplyChainCredentialValidator.class.getResource(paccorOutputResource); - String paccorOutputString = IOUtils.toString(url, StandardCharsets.UTF_8); - when(deviceInfoReport.getPaccorOutputString()).thenReturn(paccorOutputString); - return deviceInfoReport; - } - - /** - * Creates a new RSA 1024-bit KeyPair using a Bouncy Castle Provider. - * - * @return new KeyPair - */ - private static KeyPair createKeyPair() { - final int keySize = 1024; - KeyPairGenerator gen; - KeyPair keyPair = null; - try { - gen = KeyPairGenerator.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME); - gen.initialize(keySize, SECURE_RANDOM); - keyPair = gen.generateKeyPair(); - } catch (NoSuchAlgorithmException | NoSuchProviderException e) { - fail("Error occurred while generating key pair", e); - } - return keyPair; - } - - /** - * Create a new X.509 attribute certificate given the holder cert, the signing cert, and the - * signing key. - * - * @param targetCert X509Certificate that will be the holder of the attribute cert - * @param signingCert X509Certificate used to sign the new attribute cert - * @param caPrivateKey PrivateKey used to sign the new attribute cert - * @return new X509AttributeCertificate - */ - private static X509AttributeCertificateHolder createAttributeCert( - final X509Certificate targetCert, final X509Certificate signingCert, - final PrivateKey caPrivateKey) { - X509AttributeCertificateHolder cert = null; - try { - final int timeRange = 50000; - AttributeCertificateHolder holder = - new AttributeCertificateHolder(new X509CertificateHolder( - targetCert.getEncoded())); - AttributeCertificateIssuer issuer = - new AttributeCertificateIssuer(new X500Name(signingCert - .getSubjectX500Principal().getName())); - BigInteger serialNumber = BigInteger.ONE; - Date notBefore = new Date(System.currentTimeMillis() - timeRange); - Date notAfter = new Date(System.currentTimeMillis() + timeRange); - X509v2AttributeCertificateBuilder builder = - new X509v2AttributeCertificateBuilder(holder, issuer, serialNumber, notBefore, - notAfter); - - ContentSigner signer = - new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC") - .build(caPrivateKey); - - cert = builder.build(signer); - } catch (CertificateEncodingException | IOException | OperatorCreationException e) { - fail("Exception occurred while creating a cert", e); - } - - return cert; - - } - /** - * Create a new X.509 public-key certificate signed by the given certificate. - * - * @param keyPair KeyPair to create the cert for - * @param signingKey PrivateKey of the signing cert - * @param signingCert signing cert - * @return new X509Certificate + * Setup mocks. */ - private static X509Certificate createCertSignedByAnotherCert(final KeyPair keyPair, - final PrivateKey signingKey, - final X509Certificate signingCert) { - final int timeRange = 10000; - X509Certificate cert = null; - try { - - X500Name issuerName = new X500Name(signingCert.getSubjectX500Principal().getName()); - X500Name subjectName = new X500Name("CN=Test V3 Certificate"); - BigInteger serialNumber = BigInteger.ONE; - Date notBefore = new Date(System.currentTimeMillis() - timeRange); - Date notAfter = new Date(System.currentTimeMillis() + timeRange); - X509v3CertificateBuilder builder = - new JcaX509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter, - subjectName, keyPair.getPublic()); - ContentSigner signer = - new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC").build(signingKey); - return new JcaX509CertificateConverter().setProvider("BC").getCertificate( - builder.build(signer)); - } catch (Exception e) { - fail("Exception occurred while creating a cert", e); - } - return cert; + @BeforeEach + public void setUpBeforeEach() { + mocks = MockitoAnnotations.openMocks(this); } /** - * Creates a self-signed X.509 public-key certificate. + * Tears down the mock instances. * - * @param pair KeyPair to create the cert for - * @return self-signed X509Certificate + * @throws Exception if there are any issues closing down mock instances */ - private static X509Certificate createSelfSignedCertificate(final KeyPair pair) { - Security.addProvider(new BouncyCastleProvider()); - final int timeRange = 10000; - X509Certificate cert = null; - try { - - X500Name issuerName = new X500Name("CN=Test Self-Signed V3 Certificate"); - X500Name subjectName = new X500Name("CN=Test Self-Signed V3 Certificate"); - BigInteger serialNumber = BigInteger.ONE; - Date notBefore = new Date(System.currentTimeMillis() - timeRange); - Date notAfter = new Date(System.currentTimeMillis() + timeRange); - X509v3CertificateBuilder builder = - new JcaX509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter, - subjectName, pair.getPublic()); - ContentSigner signer = - new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC").build( - pair.getPrivate()); - return new JcaX509CertificateConverter().setProvider("BC").getCertificate( - builder.build(signer)); - } catch (Exception e) { - fail("Exception occurred while creating a cert", e); + @AfterEach + public void tearDownAfterEach() throws Exception { + if (mocks != null) { + mocks.close(); } - return cert; } - private static InetAddress getTestIpAddress() { - try { - final byte[] byteAddress = new byte[] {127, 0, 0, 1}; - return InetAddress.getByAddress(byteAddress); - } catch (UnknownHostException e) { - return null; - } - } /** * Checks if the ST Micro Endorsement Credential can be validated against the * ST/GlobalSIgn Certificate Chain. * - * @throws IOException if error occurs while reading files - * @throws URISyntaxException if error occurs while reading files - * @throws CertificateException if error occurs while processing X509 Certs - * @throws KeyStoreException if error occurs while processing Keystore + * @throws IOException if error occurs while reading files + * @throws URISyntaxException if error occurs while reading files + * @throws KeyStoreException if error occurs while processing Keystore */ @Test public final void testValidateEndorsementCredential() - throws URISyntaxException, IOException, CertificateException, KeyStoreException { + throws URISyntaxException, IOException, KeyStoreException { EndorsementCredential ekcert = new EndorsementCredential(Files.readAllBytes( Paths.get(Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI())) @@ -455,14 +331,13 @@ public final void testValidateEndorsementCredential() * Validates a generated cert chain pretending to be from Intel. Credential was generated * with an intermediate CA. This tests the entire chain of validation back to the root CA. * - * @throws IOException if error occurs while reading files - * @throws KeyStoreException if there's an issue string certs to the keystore - * @throws CertificateException if error occurs while ingesting a certificate - * @throws URISyntaxException if a URI can't be processed + * @throws IOException if error occurs while reading files + * @throws KeyStoreException if there's an issue string certs to the keystore + * @throws URISyntaxException if a URI can't be processed */ @Test public final void validateIntelPlatformCredentials() - throws URISyntaxException, IOException, CertificateException, KeyStoreException { + throws URISyntaxException, IOException, KeyStoreException { Certificate intermediatecacert = new CertificateAuthorityCredential(Files.readAllBytes(Paths.get( @@ -502,7 +377,7 @@ public final void validateIntelPlatformCredentials() * * @throws Exception If there are errors. */ -// @Test + @Test public final void validateIntelPlatformCredentialAttributes() throws Exception { @@ -512,7 +387,7 @@ public final void validateIntelPlatformCredentialAttributes() PlatformCredential pc = new PlatformCredential(certBytes); - DeviceInfoReport deviceInfoReport = buildReport( + DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo( new HardwareInfo(PLATFORM_MANUFACTURER, PLATFORM_MODEL, PLATFORM_VERSION, TEST_BOARD_SERIAL_NUMBER, TEST_CHASSIS_SERIAL_NUMBER, TEST_BOARD_SERIAL_NUMBER)); @@ -520,25 +395,28 @@ public final void validateIntelPlatformCredentialAttributes() EndorsementCredential ec = new EndorsementCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI()))); + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = CredentialValidator.validatePlatformCredentialAttributes(pc, - deviceInfoReport, ec, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, ec, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); } + /** * Checks if the Platform Credential contains the serial number from * the device in the platform serial number field. * * @throws Exception If there are errors. */ -// @Test + @Test public final void validatePlatformCredentialWithDeviceBaseboard() throws Exception { - DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo( + DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(new HardwareInfo( DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, TEST_BOARD_SERIAL_NUMBER)); @@ -552,10 +430,12 @@ public final void validatePlatformCredentialWithDeviceBaseboard() EndorsementCredential ec = new EndorsementCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI()))); + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = CredentialValidator.validatePlatformCredentialAttributes(pc, - deviceInfoReport, ec, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, ec, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); @@ -565,11 +445,11 @@ public final void validatePlatformCredentialWithDeviceBaseboard() * Checks if the Platform Credential contains the serial number from * the device in the chassis serial number field. */ -// @Test + @Test public final void validatePlatformCredentialWithDeviceChassis() throws Exception { - DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo( + DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(new HardwareInfo( DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, TEST_CHASSIS_SERIAL_NUMBER, DeviceInfoEnums.NOT_SPECIFIED)); @@ -583,10 +463,12 @@ public final void validatePlatformCredentialWithDeviceChassis() EndorsementCredential ec = new EndorsementCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI()))); + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = CredentialValidator.validatePlatformCredentialAttributes(pc, - deviceInfoReport, ec, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, ec, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); @@ -598,11 +480,11 @@ public final void validatePlatformCredentialWithDeviceChassis() * * @throws Exception If there are errors. */ -// @Test + @Test public final void validatePlatformCredentialWithDeviceSystemSerialNumber() throws Exception { - DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo( + DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(new HardwareInfo( DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, TEST_BOARD_SERIAL_NUMBER, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED)); @@ -616,10 +498,12 @@ public final void validatePlatformCredentialWithDeviceSystemSerialNumber() EndorsementCredential ec = new EndorsementCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI()))); + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = CredentialValidator.validatePlatformCredentialAttributes(pc, - deviceInfoReport, ec, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, ec, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); @@ -629,11 +513,11 @@ public final void validatePlatformCredentialWithDeviceSystemSerialNumber() * Checks if validation occurs when the Platform Credential baseboard * serial number is in the device chassis serial number field. */ -// @Test + @Test public final void validatePlatformCredentialCombinedWithChassisSerialNumbersMatchedBaseboard() throws Exception { - DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo( + DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(new HardwareInfo( DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, TEST_BOARD_SERIAL_NUMBER, DeviceInfoEnums.NOT_SPECIFIED)); @@ -648,10 +532,12 @@ public final void validatePlatformCredentialCombinedWithChassisSerialNumbersMatc Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI()))); + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = CredentialValidator.validatePlatformCredentialAttributes(pc, - deviceInfoReport, ec, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, ec, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); @@ -661,11 +547,11 @@ public final void validatePlatformCredentialCombinedWithChassisSerialNumbersMatc * Checks if validation occurs when the Platform Credential chassis * serial number is in the device baseboard serial number field. */ -// @Test + @Test public final void validatePlatformCredentialCombinedWithBaseboardSerialNumbersMatchedChassis() throws Exception { - DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo( + DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(new HardwareInfo( DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, TEST_CHASSIS_SERIAL_NUMBER)); @@ -679,10 +565,12 @@ public final void validatePlatformCredentialCombinedWithBaseboardSerialNumbersMa EndorsementCredential ec = new EndorsementCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI()))); + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = CredentialValidator.validatePlatformCredentialAttributes(pc, - deviceInfoReport, ec, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, ec, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); @@ -692,11 +580,11 @@ public final void validatePlatformCredentialCombinedWithBaseboardSerialNumbersMa * Checks if validation occurs when the Platform Credential chassis * serial number is in the device system serial number field. */ -// @Test + @Test public final void validatePlatformCredentialCombinedWithSystemSerialNumbersMatchedChassis() throws Exception { - DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo( + DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo(new HardwareInfo( DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, TEST_CHASSIS_SERIAL_NUMBER, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED)); @@ -710,10 +598,12 @@ public final void validatePlatformCredentialCombinedWithSystemSerialNumbersMatch EndorsementCredential ec = new EndorsementCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(TEST_EK_CERT)).toURI()))); + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = CredentialValidator.validatePlatformCredentialAttributes(pc, - deviceInfoReport, ec, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, ec, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); @@ -725,11 +615,11 @@ public final void validatePlatformCredentialCombinedWithSystemSerialNumbersMatch * * @throws Exception If there are errors. */ -// @Test + @Test public final void validatePlatformCredentialWithNoDeviceSerialNumbers() throws Exception { - DeviceInfoReport deviceInfoReport = buildReport( + DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo( new HardwareInfo(PLATFORM_MANUFACTURER, PLATFORM_MODEL, PLATFORM_VERSION, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED)); @@ -746,10 +636,12 @@ public final void validatePlatformCredentialWithNoDeviceSerialNumbers() String expectedMessage = "Platform serial did not match device info"; + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = CredentialValidator.validatePlatformCredentialAttributes( - pc, deviceInfoReport, ec, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + pc, deviceInfoReport, ec, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); assertEquals(expectedMessage, result.getMessage()); } @@ -760,11 +652,11 @@ public final void validatePlatformCredentialWithNoDeviceSerialNumbers() * * @throws Exception If there are errors. */ -// @Test + @Test public final void validatePlatformCredentialCombinedWithNoMatchedDeviceSerialNumbers() throws Exception { - DeviceInfoReport deviceInfoReport = buildReport( + DeviceInfoReport deviceInfoReport = buildDeviceInfoReportUsingHardwareInfo( new HardwareInfo(DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, "zzz", "aaa", "bbb")); @@ -780,10 +672,12 @@ public final void validatePlatformCredentialCombinedWithNoMatchedDeviceSerialNum String expectedMessage = "Platform serial did not match device info"; + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = CredentialValidator.validatePlatformCredentialAttributes( - pc, deviceInfoReport, ec, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + pc, deviceInfoReport, ec, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); assertEquals(expectedMessage, result.getMessage()); } @@ -855,7 +749,7 @@ public final void verifyX509AttributeCertificateAgainstIntermediate() KeyPair caKeyPair = createKeyPair(); KeyPair intermediateKeyPair = createKeyPair(); KeyPair targetKeyPair = createKeyPair(); - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); X509Certificate caCert = createSelfSignedCertificate(caKeyPair); X509Certificate intermediateCert = @@ -899,7 +793,7 @@ public final void verifyX509AttributeCertificateFailsIfSigningCertNotInList() KeyPair caKeyPair = createKeyPair(); KeyPair intermediateKeyPair = createKeyPair(); KeyPair targetKeyPair = createKeyPair(); - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); X509Certificate caCert = createSelfSignedCertificate(caKeyPair); X509Certificate intermediateCert = @@ -938,7 +832,7 @@ public final void verifyX509AttributeCertificateAgainstCA() throws SupplyChainValidatorException { KeyPair caKeyPair = createKeyPair(); KeyPair targetKeyPair = createKeyPair(); - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); X509Certificate caCert = createSelfSignedCertificate(caKeyPair); X509Certificate targetCert = @@ -977,7 +871,7 @@ public final void verifyX509CertificateAgainstIntermediate() KeyPair caKeyPair = createKeyPair(); KeyPair intermediateKeyPair = createKeyPair(); KeyPair targetKeyPair = createKeyPair(); - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); X509Certificate caCert = createSelfSignedCertificate(caKeyPair); X509Certificate intermediateCert = @@ -1017,7 +911,7 @@ public final void verifyX509CertificateFailsIfSigningCertNotInList() KeyPair caKeyPair = createKeyPair(); KeyPair intermediateKeyPair = createKeyPair(); KeyPair targetKeyPair = createKeyPair(); - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); X509Certificate caCert = createSelfSignedCertificate(caKeyPair); X509Certificate intermediateCert = @@ -1051,7 +945,7 @@ public final void verifyX509CertificateFailsIfSigningCertNotInList() public final void verifyX509CertificateAgainstCA() throws SupplyChainValidatorException { KeyPair caKeyPair = createKeyPair(); KeyPair targetKeyPair = createKeyPair(); - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); X509Certificate caCert = createSelfSignedCertificate(caKeyPair); X509Certificate targetCert = @@ -1147,7 +1041,7 @@ public final void verifyPlatformCredentialNullKeyStore() * @throws IOException an error occurs when parsing the certificate * @throws URISyntaxException an error occurs parsing the certificate file path */ -// @Test + @Test public final void verifyPlatformCredentialNullDeviceInfoReport() throws URISyntaxException, IOException { byte[] certBytes = Files.readAllBytes(Paths.get( @@ -1162,9 +1056,12 @@ public final void verifyPlatformCredentialNullDeviceInfoReport() String expectedMessage = "Can't validate platform credential attributes without a " + "device info report"; + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = - CredentialValidator.validatePlatformCredentialAttributes(pc, null, ec, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + CredentialValidator.validatePlatformCredentialAttributes(pc, null, ec, + componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); assertEquals(expectedMessage, result.getMessage()); } @@ -1175,13 +1072,12 @@ public final void verifyPlatformCredentialNullDeviceInfoReport() * * @throws URISyntaxException failed to read certificate * @throws IOException failed to read certificate - * @throws KeyStoreException failed to read key store * @throws SupplyChainValidatorException missing credential */ @Test public final void testPlatformDnEquals() throws URISyntaxException, IOException, - KeyStoreException, SupplyChainValidatorException { + SupplyChainValidatorException { Certificate signingCert; signingCert = new CertificateAuthorityCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(INTEL_SIGNING_KEY)).toURI())) @@ -1207,12 +1103,11 @@ public final void testPlatformDnEquals() throws URISyntaxException, IOException, * * @throws URISyntaxException failed to read certificate * @throws IOException failed to read certificate - * @throws KeyStoreException failed to read key store * @throws SupplyChainValidatorException missing credential */ @Test public final void testPlatformDnNotEquals() throws URISyntaxException, IOException, - KeyStoreException, SupplyChainValidatorException { + SupplyChainValidatorException { Certificate signingCert; signingCert = new CertificateAuthorityCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(INTEL_INT_CA)).toURI())) @@ -1237,12 +1132,11 @@ public final void testPlatformDnNotEquals() throws URISyntaxException, IOExcepti * * @throws URISyntaxException failed to read certificate * @throws IOException failed to read certificate - * @throws KeyStoreException failed to read key store * @throws SupplyChainValidatorException missing credential */ @Test public final void testEndorsementDnEquals() throws URISyntaxException, IOException, - KeyStoreException, SupplyChainValidatorException { + SupplyChainValidatorException { Certificate signingCert; signingCert = new CertificateAuthorityCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(INT_CA_CERT02)).toURI())) @@ -1268,12 +1162,11 @@ public final void testEndorsementDnEquals() throws URISyntaxException, IOExcepti * * @throws URISyntaxException failed to read certificate * @throws IOException failed to read certificate - * @throws KeyStoreException failed to read key store * @throws SupplyChainValidatorException missing credential */ @Test public final void testEndorsementDnNotEquals() throws URISyntaxException, IOException, - KeyStoreException, SupplyChainValidatorException { + SupplyChainValidatorException { Certificate signingCert; signingCert = new CertificateAuthorityCredential(Files.readAllBytes(Paths.get( Objects.requireNonNull(getClass().getResource(INTEL_INT_CA)).toURI())) @@ -1298,7 +1191,7 @@ public final void testEndorsementDnNotEquals() throws URISyntaxException, IOExce */ @Test public void testMatcher() { - NICComponentInfo nicComponentInfo = new NICComponentInfo("Intel Corporation", + ComponentInfo nicComponentInfo = new ComponentInfo("Intel Corporation", "Ethernet Connection I217-V", "23:94:17:ba:86:5e", "00"); @@ -1334,66 +1227,23 @@ public void testMatcher() { ); } - private PlatformCredential setupMatchingPlatformCredential( - final DeviceInfoReport deviceInfoReport) throws IOException { - PlatformCredential platformCredential = mock(PlatformCredential.class); - - when(platformCredential.getCredentialType()).thenReturn( - PlatformCredential.CERTIFICATE_TYPE_2_0); - when(platformCredential.getManufacturer()) - .thenReturn(hardwareInfo.getManufacturer()); - when(platformCredential.getModel()) - .thenReturn(hardwareInfo.getProductName()); - when(platformCredential.getPlatformSerial()) - .thenReturn(hardwareInfo.getBaseboardSerialNumber()); - when(platformCredential.getVersion()) - .thenReturn(hardwareInfo.getVersion()); - - List deviceInfoComponents - = SupplyChainCredentialValidator.getComponentInfoFromPaccorOutput( - deviceInfoReport.getNetworkInfo().getHostname(), - deviceInfoReport.getPaccorOutputString()); - List componentIdentifierList = new ArrayList<>(); - for (ComponentInfo deviceInfoComponent : deviceInfoComponents) { - DERUTF8String serial = null; - DERUTF8String revision = null; - if (deviceInfoComponent.getComponentSerial() != null) { - serial = new DERUTF8String(deviceInfoComponent.getComponentSerial()); - } - if (deviceInfoComponent.getComponentRevision() != null) { - revision = new DERUTF8String(deviceInfoComponent.getComponentRevision()); - } - componentIdentifierList.add(new ComponentIdentifier( - new DERUTF8String(deviceInfoComponent.getComponentManufacturer()), - new DERUTF8String(deviceInfoComponent.getComponentModel()), - serial, - revision, - null, - ASN1Boolean.TRUE, - Collections.emptyList() - )); - - } - - when(platformCredential.getComponentIdentifiers()).thenReturn(componentIdentifierList); - - return platformCredential; - } - /** * Tests that TPM 2.0 Platform Credentials validate correctly against the device info report * when there are no components. * * @throws IOException if unable to set up DeviceInfoReport from resource file */ -// @Test + @Test public final void testValidatePlatformCredentialAttributesV2p0NoComponentsPass() throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReport(); - PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + + PlatformCredential platformCredential = + setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); AppraisalStatus appraisalStatus = CertificateAttributeScvValidator - .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, null, null, + .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, + componentResultRepository, componentAttributeRepository, Collections.emptyList(), UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, appraisalStatus.getAppStatus()); @@ -1407,15 +1257,20 @@ public final void testValidatePlatformCredentialAttributesV2p0NoComponentsPass() * * @throws IOException if unable to set up DeviceInfoReport from resource file */ -// @Test + @Test public final void testValidatePlatformCredentialAttributesV2p0WithComponentsPass() throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); - PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + + PlatformCredential platformCredential = + setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); + + List componentInfoList = retrieveListOfComponentInfos(); AppraisalStatus appraisalStatus = CertificateAttributeScvValidator - .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, + componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, appraisalStatus.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, appraisalStatus.getMessage()); @@ -1428,42 +1283,52 @@ public final void testValidatePlatformCredentialAttributesV2p0WithComponentsPass * * @throws IOException if unable to set up DeviceInfoReport from resource file */ -// @Test + @Test public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSystemSerial() throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); - PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + + PlatformCredential platformCredential = + setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); + + List componentInfoList = retrieveListOfComponentInfos(); + when(platformCredential.getPlatformSerial()) - .thenReturn(hardwareInfo.getSystemSerialNumber()); + .thenReturn(deviceInfoReport.getHardwareInfo().getSystemSerialNumber()); AppraisalStatus appraisalStatus = CertificateAttributeScvValidator - .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, + componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, appraisalStatus.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, appraisalStatus.getMessage()); } /** - * Tests that TPM 2.0 Platform Credentials validate correctly against the device info report - * when there are components present, and when the PlatformSerial field holds the system's + * Second test that tests that TPM 2.0 Platform Credentials validate correctly against the device info + * report when there are components present, and when the PlatformSerial field holds the system's * serial number instead of the baseboard serial number. * * @throws IOException if unable to set up DeviceInfoReport from resource file * @throws URISyntaxException failed to read certificate */ -// @Test + @Test public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSystemSerial2() throws IOException, URISyntaxException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithNotSpecifiedComponents(); + PlatformCredential platformCredential = new PlatformCredential( Files.readAllBytes(Paths.get( Objects.requireNonNull(SupplyChainCredentialValidator.class.getResource( SAMPLE_TEST_PACCOR_CERT)).toURI()))); + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus appraisalStatus = CertificateAttributeScvValidator - .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + .validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, + componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, appraisalStatus.getAppStatus()); } @@ -1472,79 +1337,86 @@ public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSys * * @throws IOException if unable to set up DeviceInfoReport from resource file */ -// @Test + @Test public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull() throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); - PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + PlatformCredential platformCredential = + setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); + + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); + assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); + assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); + when(platformCredential.getManufacturer()).thenReturn(null); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); assertEquals("Platform manufacturer did not match\n", result.getMessage()); - platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); when(platformCredential.getModel()).thenReturn(null); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(result.getAppStatus(), AppraisalStatus.Status.FAIL); assertEquals(result.getMessage(), "Platform model did not match\n"); - platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); when(platformCredential.getPlatformSerial()).thenReturn(null); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); - platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); when(platformCredential.getVersion()).thenReturn(null); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); - platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); @@ -1554,16 +1426,16 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull when(platformCredential.getComponentIdentifiers()).thenReturn(modifiedComponentIdentifiers); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); assertEquals("Component manufacturer is empty\n", result.getMessage()); - platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); @@ -1572,8 +1444,8 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull when(platformCredential.getComponentIdentifiers()).thenReturn(modifiedComponentIdentifiers); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); assertEquals("Component model is empty\n", result.getMessage()); @@ -1585,133 +1457,151 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull * * @throws IOException if unable to set up DeviceInfoReport from resource file */ -// @Test + @Test public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpty() throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); - PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + PlatformCredential platformCredential = + setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); + + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); + assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); + + // Part II: Testing using an empty platform manufacturer string when(platformCredential.getManufacturer()).thenReturn(""); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); assertEquals("Platform manufacturer did not match\n", result.getMessage()); - platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); + + // Part III: Testing using an empty platform model string when(platformCredential.getModel()).thenReturn(""); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); assertEquals("Platform model did not match\n", result.getMessage()); - platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); + + // Part IV: Testing using an empty platform serial number when(platformCredential.getPlatformSerial()).thenReturn(""); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); assertEquals("Platform serial did not match\n", result.getMessage()); - platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); + + // Part V: Testing using an empty platform version string when(platformCredential.getVersion()).thenReturn(""); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); assertEquals("Platform version did not match\n", result.getMessage()); - platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); + + // Part VI: Testing using an empty computer manufacturer string List modifiedComponentIdentifiers = platformCredential.getComponentIdentifiers(); modifiedComponentIdentifiers.get(0).setComponentManufacturer(new DERUTF8String("")); when(platformCredential.getComponentIdentifiers()).thenReturn(modifiedComponentIdentifiers); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); - assertEquals("Component manufacturer is empty\n" - + "There are unmatched components:\n" - + "Manufacturer=, Model=Core i7, Serial=Not Specified," - + " Revision=Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz;\n", + assertEquals("Component manufacturer is empty\n", result.getMessage()); - platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); + + // Part VII: Testing using an empty computer model string modifiedComponentIdentifiers = platformCredential.getComponentIdentifiers(); modifiedComponentIdentifiers.get(0).setComponentModel(new DERUTF8String("")); when(platformCredential.getComponentIdentifiers()).thenReturn(modifiedComponentIdentifiers); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); assertEquals("Component model is empty\n", result.getMessage()); } /** - * Tests that {@link SupplyChainCredentialValidator} failes when a component exists in the + * Tests that {@link SupplyChainCredentialValidator} fails when a component exists in the * platform credential, but not in the device info report. * * @throws IOException if unable to set up DeviceInfoReport from resource file */ -// @Test + //@Test public final void testValidatePlatformCredentialAttributesV2p0MissingComponentInDeviceInfo() throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); - PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + PlatformCredential platformCredential = + setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); + + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); @@ -1727,12 +1617,14 @@ public final void testValidatePlatformCredentialAttributesV2p0MissingComponentIn ASN1Boolean.FALSE, Collections.emptyList() )); + when(platformCredential.getComponentIdentifiers()).thenReturn( modifiedComponentIdentifiers ); + result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, + deviceInfoReport, componentResultRepository, componentAttributeRepository, Collections.emptyList(), UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); assertEquals("There are unmatched components:\n" @@ -1747,28 +1639,30 @@ public final void testValidatePlatformCredentialAttributesV2p0MissingComponentIn * * @throws IOException if unable to set up DeviceInfoReport from resource file */ -// @Test + @Test public final void testValidatePlatformCredentialAttributesV2p0ExtraComponentInDeviceInfo() throws IOException { - PlatformCredential platformCredential = setupMatchingPlatformCredential( + PlatformCredential platformCredential = setupMockPlatformCredentialWithPlatformConfigV1( setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_TXT)); // The device info report will contain one extra component. DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents( SAMPLE_PACCOR_OUTPUT_WITH_EXTRA_COMPONENT_TXT); + List componentInfoList = retrieveListOfComponentInfos(); + AppraisalStatus result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); @@ -1780,15 +1674,17 @@ public final void testValidatePlatformCredentialAttributesV2p0ExtraComponentInDe * * @throws IOException if unable to set up DeviceInfoReport from resource file */ -// @Test + @Test public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentFieldEmpty() throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); - PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + PlatformCredential platformCredential = + setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); + AppraisalStatus result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, + deviceInfoReport, componentResultRepository, componentAttributeRepository, Collections.emptyList(), UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, @@ -1801,19 +1697,16 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentF result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, + deviceInfoReport, componentResultRepository, componentAttributeRepository, Collections.emptyList(), UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); - assertEquals("Component manufacturer is empty\n" - + "There are unmatched components:\n" - + "Manufacturer=, Model=Core i7, Serial=Not Specified," - + " Revision=Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz;\n", + assertEquals("Component manufacturer is empty\n", result.getMessage()); - platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + platformCredential = setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, + deviceInfoReport, componentResultRepository, componentAttributeRepository, Collections.emptyList(), UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, @@ -1825,7 +1718,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentF result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, + deviceInfoReport, componentResultRepository, componentAttributeRepository, Collections.emptyList(), UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus()); assertEquals("Component model is empty\n", result.getMessage()); @@ -1837,11 +1730,12 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentF * * @throws IOException if unable to set up DeviceInfoReport from resource file */ -// @Test + @Test public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentNoSerial() throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); - PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + PlatformCredential platformCredential = + setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); ArrayList modifiedIdentifiers = new ArrayList<>(); for (ComponentIdentifier identifier : platformCredential.getComponentIdentifiers()) { @@ -1856,7 +1750,7 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentN AppraisalStatus result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, + deviceInfoReport, componentResultRepository, componentAttributeRepository, Collections.emptyList(), UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, @@ -1869,11 +1763,15 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentN * * @throws IOException if unable to set up DeviceInfoReport from resource file */ -// @Test + @Test public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentNoRevision() throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); - PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + + PlatformCredential platformCredential = + setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); + + List componentInfoList = retrieveListOfComponentInfos(); ArrayList modifiedIdentifiers = new ArrayList<>(); for (ComponentIdentifier identifier : platformCredential.getComponentIdentifiers()) { @@ -1888,8 +1786,8 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentN AppraisalStatus result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); @@ -1902,11 +1800,15 @@ public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentN * * @throws IOException if unable to set up DeviceInfoReport from resource file */ -// @Test + @Test public final void testValPlatCredentialAttributesV2p0RequiredComponentNoSerialOrRevision() throws IOException { DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(); - PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport); + + PlatformCredential platformCredential = + setupMockPlatformCredentialWithPlatformConfigV1(deviceInfoReport); + + List componentInfoList = retrieveListOfComponentInfos(); ArrayList modifiedIdentifiers = new ArrayList<>(); for (ComponentIdentifier identifier : platformCredential.getComponentIdentifiers()) { @@ -1922,19 +1824,405 @@ public final void testValPlatCredentialAttributesV2p0RequiredComponentNoSerialOr AppraisalStatus result = CertificateAttributeScvValidator .validatePlatformCredentialAttributesV2p0(platformCredential, - deviceInfoReport, null, null, - Collections.emptyList(), UUID.randomUUID(), false); + deviceInfoReport, componentResultRepository, componentAttributeRepository, + componentInfoList, UUID.randomUUID(), false); assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus()); assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID, result.getMessage()); } + /** + * Create a new X.509 attribute certificate given the holder cert, the signing cert, and the + * signing key. + * + * @param targetCert X509Certificate that will be the holder of the attribute cert + * @param signingCert X509Certificate used to sign the new attribute cert + * @param caPrivateKey PrivateKey used to sign the new attribute cert + * @return new X509AttributeCertificate + */ + private X509AttributeCertificateHolder createAttributeCert( + final X509Certificate targetCert, final X509Certificate signingCert, + final PrivateKey caPrivateKey) { + X509AttributeCertificateHolder cert = null; + try { + final int timeRange = 50000; + AttributeCertificateHolder holder = + new AttributeCertificateHolder(new X509CertificateHolder( + targetCert.getEncoded())); + AttributeCertificateIssuer issuer = + new AttributeCertificateIssuer(new X500Name(signingCert + .getSubjectX500Principal().getName())); + BigInteger serialNumber = BigInteger.ONE; + Date notBefore = new Date(System.currentTimeMillis() - timeRange); + Date notAfter = new Date(System.currentTimeMillis() + timeRange); + X509v2AttributeCertificateBuilder builder = + new X509v2AttributeCertificateBuilder(holder, issuer, serialNumber, notBefore, + notAfter); + + ContentSigner signer = + new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC") + .build(caPrivateKey); + + cert = builder.build(signer); + } catch (CertificateEncodingException | IOException | OperatorCreationException e) { + fail("Exception occurred while creating a cert", e); + } + + return cert; + + } + + /** + * Create a new X.509 public-key certificate signed by the given certificate. + * + * @param keyPair KeyPair to create the cert for + * @param signingKey PrivateKey of the signing cert + * @param signingCert signing cert + * @return new X509Certificate + */ + private X509Certificate createCertSignedByAnotherCert(final KeyPair keyPair, + final PrivateKey signingKey, + final X509Certificate signingCert) { + final int timeRange = 10000; + X509Certificate cert = null; + try { + + X500Name issuerName = new X500Name(signingCert.getSubjectX500Principal().getName()); + X500Name subjectName = new X500Name("CN=Test V3 Certificate"); + BigInteger serialNumber = BigInteger.ONE; + Date notBefore = new Date(System.currentTimeMillis() - timeRange); + Date notAfter = new Date(System.currentTimeMillis() + timeRange); + X509v3CertificateBuilder builder = + new JcaX509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter, + subjectName, keyPair.getPublic()); + ContentSigner signer = + new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC").build(signingKey); + return new JcaX509CertificateConverter().setProvider("BC").getCertificate( + builder.build(signer)); + } catch (Exception e) { + fail("Exception occurred while creating a cert", e); + } + return cert; + } + + /** + * Creates a self-signed X.509 public-key certificate. + * + * @param pair KeyPair to create the cert for + * @return self-signed X509Certificate + */ + private X509Certificate createSelfSignedCertificate(final KeyPair pair) { + Security.addProvider(new BouncyCastleProvider()); + final int timeRange = 10000; + X509Certificate cert = null; + try { + + X500Name issuerName = new X500Name("CN=Test Self-Signed V3 Certificate"); + X500Name subjectName = new X500Name("CN=Test Self-Signed V3 Certificate"); + BigInteger serialNumber = BigInteger.ONE; + Date notBefore = new Date(System.currentTimeMillis() - timeRange); + Date notAfter = new Date(System.currentTimeMillis() + timeRange); + X509v3CertificateBuilder builder = + new JcaX509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter, + subjectName, pair.getPublic()); + ContentSigner signer = + new JcaContentSignerBuilder("SHA1WithRSA").setProvider("BC").build( + pair.getPrivate()); + return new JcaX509CertificateConverter().setProvider("BC").getCertificate( + builder.build(signer)); + } catch (Exception e) { + fail("Exception occurred while creating a cert", e); + } + return cert; + } + + + /** + * Creates a new RSA 1024-bit KeyPair using a Bouncy Castle Provider. + * + * @return new KeyPair + */ + private KeyPair createKeyPair() { + final int keySize = 1024; + KeyPairGenerator gen; + KeyPair keyPair = null; + try { + gen = KeyPairGenerator.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME); + gen.initialize(keySize, SECURE_RANDOM); + keyPair = gen.generateKeyPair(); + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { + fail("Error occurred while generating key pair", e); + } + return keyPair; + } + + /** + * Helper method that creates a device info report. + * + * @return device info report + */ + private DeviceInfoReport setupDeviceInfoReport() throws UnknownHostException { + + // setup network info + final byte[] byteAddress = new byte[] {127, 0, 0, 1}; + InetAddress inetAddress = InetAddress.getByAddress(byteAddress); + NetworkInfo networkInfo = new NetworkInfo("the-device", inetAddress, new byte[] {1, 0, 1, 0, 1, 0}); + + // setup os info + OSInfo osInfo = new OSInfo("Windows", "11.0", "Not Specified", + "Not Specified", "Not Specified"); + + // setup firmware info + FirmwareInfo firmwareInfo = new FirmwareInfo("Dell Inc", "A11", + "03/12/2013"); + + // setup hardware info + HardwareInfo hardwareInfo = new HardwareInfo( + "ACME", + "anvil", + "3.0", + "1234", + "567", + "890"); + + TPMInfo tpmInfo = new TPMInfo(); + + return new DeviceInfoReport(networkInfo, osInfo, firmwareInfo, hardwareInfo, tpmInfo); + } + + /** + * Helper method that creates a device info report that contains the provided components. + * + * @return device info report that contains provided components + * @throws IOException is thrown if issues arise from parsing out the paccor output + */ + private DeviceInfoReport setupDeviceInfoReportWithComponents() throws IOException { + return setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_TXT); + } + + /** + * Helper method that creates a device info report that contains the provided non-specified components. + * + * @return device info report that contains not specified components + * @throws IOException is thrown if issues arise from parsing out the paccor output + */ + private DeviceInfoReport setupDeviceInfoReportWithNotSpecifiedComponents() + throws IOException { + return setupDeviceInfoReportWithComponents(SAMPLE_PACCOR_OUTPUT_NOT_SPECIFIED_TXT); + } + + /** + * Helper method that generates a device info report using the provided sample paccor output. + * + * @param paccorOutputResource sample paccor output text + * @return device info report + * @throws IOException is thrown if issues arise from parsing out the paccor output + */ + private DeviceInfoReport setupDeviceInfoReportWithComponents( + final String paccorOutputResource) throws IOException { + DeviceInfoReport deviceInfoReport = setupDeviceInfoReport(); + URL url = SupplyChainCredentialValidator.class.getResource(paccorOutputResource); + String paccorOutputString = IOUtils.toString(url, StandardCharsets.UTF_8); + deviceInfoReport.setPaccorOutputString(paccorOutputString); + return deviceInfoReport; + } + + /** + * Helper method that generates a collection of component info that can be used + * for this class' test methods. + * + * @return a generic list of component info + */ + private List retrieveListOfComponentInfos() { + + return List.of( + new ComponentInfo("the-device", "Dell Inc", "11", + "9ZLUO9", "Not Specified", "020000123", + "2.23.133.18.3.1"), + new ComponentInfo("the-device", "9090", "AE12", + "Not Specified", "Not Specified", "00070700", + "2.23.133.18.3.4"), + new ComponentInfo("the-device", "Not Specified", "109 NVM", + "1110_1100_2230_0000_8CE3_8E10_0164_9CC7.", "Not Specified", + "00060001", "2.23.133.18.3.5")); + } + + /** + * Helper method that returns an IP Address. + * + * @return IP address + */ + private InetAddress getTestIpAddress() { + try { + final byte[] byteAddress = new byte[] {127, 0, 0, 1}; + return InetAddress.getByAddress(byteAddress); + } catch (UnknownHostException e) { + return null; + } + } + + /** + * Helper method that mocks out the Platform Credential object (that uses information derived from + * platform configuration V!) used for this class' test methods. + * + * @param deviceInfoReport device info report + * @return mocked out Platform Credential (associated with Platform Configuration V1) + * @throws IOException is thrown if there are any issues using the provided device info report's + * information + */ + private PlatformCredential setupMockPlatformCredentialWithPlatformConfigV1( + final DeviceInfoReport deviceInfoReport) throws IOException { + PlatformCredential platformCredential = mock(PlatformCredential.class); + + when(platformCredential.getCredentialType()).thenReturn( + PlatformCredential.CERTIFICATE_TYPE_2_0); + + when(platformCredential.getManufacturer()) + .thenReturn(deviceInfoReport.getHardwareInfo().getManufacturer()); + + when(platformCredential.getModel()) + .thenReturn(deviceInfoReport.getHardwareInfo().getProductName()); + + when(platformCredential.getPlatformSerial()) + .thenReturn(deviceInfoReport.getHardwareInfo().getBaseboardSerialNumber()); + + when(platformCredential.getVersion()) + .thenReturn(deviceInfoReport.getHardwareInfo().getVersion()); + + when(platformCredential.getSerialNumber()).thenReturn( + new BigInteger(deviceInfoReport.getHardwareInfo().getSystemSerialNumber())); + + when(platformCredential.getPlatformConfigurationV1()).thenReturn(new PlatformConfigurationV1()); + + List deviceInfoComponents = retrieveListOfComponentInfos(); + + List componentIdentifierList = new ArrayList<>(); + for (ComponentInfo deviceInfoComponent : deviceInfoComponents) { + DERUTF8String serial = null; + DERUTF8String revision = null; + if (deviceInfoComponent.getComponentSerial() != null) { + serial = new DERUTF8String(deviceInfoComponent.getComponentSerial()); + } + if (deviceInfoComponent.getComponentRevision() != null) { + revision = new DERUTF8String(deviceInfoComponent.getComponentRevision()); + } + componentIdentifierList.add(new ComponentIdentifier( + new DERUTF8String(deviceInfoComponent.getComponentManufacturer()), + new DERUTF8String(deviceInfoComponent.getComponentModel()), + serial, + revision, + null, + ASN1Boolean.TRUE, + Collections.emptyList() + )); + + } + + when(platformCredential.getComponentIdentifiers()).thenReturn(componentIdentifierList); + + return platformCredential; + } + + /** + * Helper method that mocks out the Platform Credential object (that uses information derived from + * platform configuration V2) used for this class' test methods. + * + * @param deviceInfoReport device info report + * @return mocked out Platform Credential (associated with Platform Configuration V2) + * @throws IOException is thrown if there are any issues using the provided device info report's + * information + */ + private PlatformCredential setupMockPlatformCredentialWithPlatformConfigV2( + final DeviceInfoReport deviceInfoReport) throws IOException { + + PlatformCredential platformCredential = mock(PlatformCredential.class); + + when(platformCredential.getCredentialType()).thenReturn( + PlatformCredential.CERTIFICATE_TYPE_2_0); + + when(platformCredential.getManufacturer()) + .thenReturn(deviceInfoReport.getHardwareInfo().getManufacturer()); + + when(platformCredential.getModel()) + .thenReturn(deviceInfoReport.getHardwareInfo().getProductName()); + + when(platformCredential.getPlatformSerial()) + .thenReturn(deviceInfoReport.getHardwareInfo().getBaseboardSerialNumber()); + + when(platformCredential.getVersion()) + .thenReturn(deviceInfoReport.getHardwareInfo().getVersion()); + + when(platformCredential.getSerialNumber()).thenReturn( + new BigInteger(deviceInfoReport.getHardwareInfo().getSystemSerialNumber())); + + when(platformCredential.getPlatformConfigurationV2()).thenReturn(new PlatformConfigurationV2()); + + List deviceInfoComponents + = retrieveListOfComponentInfos(); + + List componentIdentifierV2List = new ArrayList<>(); + + for (ComponentInfo deviceInfoComponent : deviceInfoComponents) { + DERUTF8String componentSerial = null; + DERUTF8String componentRevision = null; + + ComponentClass componentClass = + new ComponentClass(deviceInfoComponent.getComponentClassValue(), ""); + + if (deviceInfoComponent.getComponentSerial() != null) { + componentSerial = new DERUTF8String(deviceInfoComponent.getComponentSerial()); + } + + if (deviceInfoComponent.getComponentRevision() != null) { + componentRevision = new DERUTF8String(deviceInfoComponent.getComponentRevision()); + } + + componentIdentifierV2List.add(new ComponentIdentifierV2( + componentClass, + new DERUTF8String(deviceInfoComponent.getComponentManufacturer()), + new DERUTF8String(deviceInfoComponent.getComponentModel()), + componentSerial, + componentRevision, + null, + ASN1Boolean.TRUE, + Collections.emptyList(), + new CertificateIdentifier(), + new URIReference(), + AttributeStatus.ADDED + )); + + } + + when(platformCredential.getComponentIdentifiersV2()).thenReturn(componentIdentifierV2List); + + return platformCredential; + } + + /** + * Helper method that uses the provided hardware info to create a device info report. + * + * @param givenHardwareInfo hardware info + * @return device info report + */ + private DeviceInfoReport buildDeviceInfoReportUsingHardwareInfo(final HardwareInfo givenHardwareInfo) { + final InetAddress ipAddress = getTestIpAddress(); + final byte[] macAddress = new byte[] {11, 22, 33, 44, 55, 66}; + + OSInfo osInfo = new OSInfo(); + NetworkInfo networkInfo = new NetworkInfo("test", ipAddress, macAddress); + FirmwareInfo firmwareInfo = new FirmwareInfo(); + TPMInfo tpmInfo = new TPMInfo(); + + return new DeviceInfoReport(networkInfo, osInfo, + firmwareInfo, givenHardwareInfo, tpmInfo); + } + /** * Tests that SupplyChainCredentialValidator passes with a base and delta certificate where * the base serial number and delta holder serial number match. * - * @throws java.io.IOException Reading file for the certificates - * @throws java.net.URISyntaxException when loading certificates bytes + * @throws IOException Reading file for the certificates + * @throws URISyntaxException when loading certificates bytes */ // @Test public final void testValidateDeltaPlatformCredentialAttributes() @@ -1990,22 +2278,22 @@ public final void testValidateDeltaPlatformCredentialAttributes() // ComponentIdentifierV2 ciV21Faulty = new ComponentIdentifierV2(); // ComponentIdentifierV2 ciV22Faulty = new ComponentIdentifierV2(); // ciV21Faulty.setComponentManufacturer(compId2.getComponentManufacturer()); -// ciV21Faulty.setComponentClass(compId2.getComponentClass()); +// ciV21Faulty.setComponentClass(compId2.getComponentClassValue()); // ciV21Faulty.setComponentModel(compId2.getComponentModel()); // ciV21Faulty.setComponentSerial(compId2.getComponentSerial()); // ciV21Faulty.setComponentRevision(compId2.getComponentRevision()); // ciV21Faulty.setComponentManufacturerId(compId2.getComponentManufacturerId()); // ciV21Faulty.setFieldReplaceable(compId2.getFieldReplaceable()); -// ciV21Faulty.setComponentAddress(compId2.getComponentAddress()); +// ciV21Faulty.setComponentAddresses(compId2.getComponentAddresses()); // ciV21Faulty.setAttributeStatus(AttributeStatus.REMOVED); // ciV22Faulty.setComponentManufacturer(compId3.getComponentManufacturer()); -// ciV22Faulty.setComponentClass(compId3.getComponentClass()); +// ciV22Faulty.setComponentClass(compId3.getComponentClassValue()); // ciV22Faulty.setComponentModel(compId3.getComponentModel()); // ciV22Faulty.setComponentSerial(compId3.getComponentSerial()); // ciV22Faulty.setComponentRevision(compId3.getComponentRevision()); // ciV22Faulty.setComponentManufacturerId(compId3.getComponentManufacturerId()); // ciV22Faulty.setFieldReplaceable(compId3.getFieldReplaceable()); -// ciV22Faulty.setComponentAddress(compId3.getComponentAddress()); +// ciV22Faulty.setComponentAddresses(compId3.getComponentAddresses()); // ciV22Faulty.setAttributeStatus(AttributeStatus.REMOVED); // // List compList = new ArrayList<>(3); @@ -2070,8 +2358,8 @@ public final void testValidateDeltaPlatformCredentialAttributes() * Tests that SupplyChainCredentialValidator fails when a component needs to * be replaced but hasn't been by a delta certificate. * - * @throws java.io.IOException Reading file for the certificates - * @throws java.net.URISyntaxException when loading certificates bytes + * @throws IOException Reading file for the certificates + * @throws URISyntaxException when loading certificates bytes */ // @Test public final void testValidateChainFailure() @@ -2123,7 +2411,7 @@ public final void testValidateChainFailure() // ciV21Faulty.setComponentRevision(compId2.getComponentRevision()); // ciV21Faulty.setComponentManufacturerId(compId2.getComponentManufacturerId()); // ciV21Faulty.setFieldReplaceable(compId2.getFieldReplaceable()); -// ciV21Faulty.setComponentAddress(compId2.getComponentAddress()); +// ciV21Faulty.setComponentAddresses(compId2.getComponentAddresses()); // ciV21Faulty.setAttributeStatus(AttributeStatus.REMOVED); // ciV22Faulty.setComponentManufacturer(compId3.getComponentManufacturer()); // ciV22Faulty.setComponentModel(compId3.getComponentModel()); @@ -2131,7 +2419,7 @@ public final void testValidateChainFailure() // ciV22Faulty.setComponentRevision(compId3.getComponentRevision()); // ciV22Faulty.setComponentManufacturerId(compId3.getComponentManufacturerId()); // ciV22Faulty.setFieldReplaceable(compId3.getFieldReplaceable()); -// ciV22Faulty.setComponentAddress(compId3.getComponentAddress()); +// ciV22Faulty.setComponentAddresses(compId3.getComponentAddresses()); // ciV22Faulty.setAttributeStatus(AttributeStatus.REMOVED); // // List compList = new ArrayList<>(3); @@ -2180,16 +2468,5 @@ public final void testValidateChainFailure() // result.getMessage()); } - private DeviceInfoReport buildReport(final HardwareInfo givenHardwareInfo) { - final InetAddress ipAddress = getTestIpAddress(); - final byte[] macAddress = new byte[] {11, 22, 33, 44, 55, 66}; - - OSInfo osInfo = new OSInfo(); - NetworkInfo networkInfo = new NetworkInfo("test", ipAddress, macAddress); - FirmwareInfo firmwareInfo = new FirmwareInfo(); - TPMInfo tpmInfo = new TPMInfo(); - return new DeviceInfoReport(networkInfo, osInfo, - firmwareInfo, givenHardwareInfo, tpmInfo); - } } diff --git a/HIRS_AttestationCAPortal/build.gradle b/HIRS_AttestationCAPortal/build.gradle index 855ab51e7..47911ead5 100644 --- a/HIRS_AttestationCAPortal/build.gradle +++ b/HIRS_AttestationCAPortal/build.gradle @@ -83,10 +83,6 @@ dependencies { testImplementation libs.xmlunit.core } -test { - useJUnitPlatform() -} - task buildVersion() { doLast { def verFile = new File(projectDir, "build/VERSION") diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java index 9db752596..6dad22a24 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java @@ -19,6 +19,7 @@ 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; @@ -165,21 +166,15 @@ private static Page getCertificatePage(final String certificateType) { * @return the certificate class type */ private static Class getCertificateClass(final String certificateType) { - switch (certificateType) { - case PLATFORMCREDENTIAL: - return PlatformCredential.class; - case ENDORSEMENTCREDENTIAL: - return EndorsementCredential.class; - case ISSUEDCERTIFICATES: - return IssuedAttestationCertificate.class; - case IDEVIDCERTIFICATE: - return IDevIDCertificate.class; - case TRUSTCHAIN: - return CertificateAuthorityCredential.class; - default: - throw new IllegalArgumentException( - String.format("Unknown certificate type: %s", certificateType)); - } + return switch (certificateType) { + case PLATFORMCREDENTIAL -> PlatformCredential.class; + case ENDORSEMENTCREDENTIAL -> EndorsementCredential.class; + case ISSUEDCERTIFICATES -> IssuedAttestationCertificate.class; + case IDEVIDCERTIFICATE -> IDevIDCertificate.class; + case TRUSTCHAIN -> CertificateAuthorityCredential.class; + default -> throw new IllegalArgumentException( + String.format("Unknown certificate type: %s", certificateType)); + }; } /** @@ -288,107 +283,115 @@ public void modify(final CriteriaQuery criteriaQuery) { // special parsing for platform credential // Add the EndorsementCredential for each PlatformCredential based on the // serial number. (pc.HolderSerialNumber = ec.SerialNumber) - if (certificateType.equals(PLATFORMCREDENTIAL)) { - FilteredRecordsList records = new FilteredRecordsList<>(); - org.springframework.data.domain.Page pagedResult = - this.platformCertificateRepository.findByArchiveFlag(false, paging); - - if (pagedResult.hasContent()) { - records.addAll(pagedResult.getContent()); - records.setRecordsTotal(pagedResult.getContent().size()); - } else { - records.setRecordsTotal(input.getLength()); - } + switch (certificateType) { + case PLATFORMCREDENTIAL -> { + FilteredRecordsList records = new FilteredRecordsList<>(); + org.springframework.data.domain.Page pagedResult = + this.platformCertificateRepository.findByArchiveFlag(false, paging); + + if (pagedResult.hasContent()) { + records.addAll(pagedResult.getContent()); + records.setRecordsTotal(pagedResult.getContent().size()); + } else { + records.setRecordsTotal(input.getLength()); + } - records.setRecordsFiltered(platformCertificateRepository.findByArchiveFlag(false).size()); - EndorsementCredential associatedEC; + records.setRecordsFiltered(platformCertificateRepository.findByArchiveFlag(false).size()); + EndorsementCredential associatedEC; - if (!records.isEmpty()) { - // loop all the platform certificates - for (int i = 0; i < records.size(); i++) { - PlatformCredential pc = records.get(i); - // find the EC using the PC's "holder serial number" - associatedEC = this.endorsementCredentialRepository - .findBySerialNumber(pc.getHolderSerialNumber()); + if (!records.isEmpty()) { + // loop all the platform certificates + for (PlatformCredential pc : records) { + // find the EC using the PC's "holder serial number" + associatedEC = this.endorsementCredentialRepository + .findBySerialNumber(pc.getHolderSerialNumber()); - if (associatedEC != null) { - log.debug("EC ID for holder s/n " + pc - .getHolderSerialNumber() + " = " + associatedEC.getId()); - } + if (associatedEC != null) { + log.debug("EC ID for holder s/n {} = {}", pc + .getHolderSerialNumber(), associatedEC.getId()); + } - pc.setEndorsementCredential(associatedEC); + pc.setEndorsementCredential(associatedEC); + } } - } - log.debug("Returning list of size: " + records.size()); - return new DataTableResponse<>(records, input); - } else if (certificateType.equals(ENDORSEMENTCREDENTIAL)) { - FilteredRecordsList records = new FilteredRecordsList<>(); - org.springframework.data.domain.Page pagedResult = - this.endorsementCredentialRepository.findByArchiveFlag(false, paging); - - if (pagedResult.hasContent()) { - records.addAll(pagedResult.getContent()); - records.setRecordsTotal(pagedResult.getContent().size()); - } else { - records.setRecordsTotal(input.getLength()); + log.debug("Returning the size of the list of platform credentials: {}", records.size()); + return new DataTableResponse<>(records, input); } + case ENDORSEMENTCREDENTIAL -> { + FilteredRecordsList records = new FilteredRecordsList<>(); + org.springframework.data.domain.Page pagedResult = + this.endorsementCredentialRepository.findByArchiveFlag(false, paging); + + if (pagedResult.hasContent()) { + records.addAll(pagedResult.getContent()); + records.setRecordsTotal(pagedResult.getContent().size()); + } else { + records.setRecordsTotal(input.getLength()); + } - records.setRecordsFiltered(endorsementCredentialRepository.findByArchiveFlag(false).size()); - - log.debug("Returning list of size: " + records.size()); - return new DataTableResponse<>(records, input); - } else if (certificateType.equals(TRUSTCHAIN)) { - FilteredRecordsList records = new FilteredRecordsList<>(); - org.springframework.data.domain.Page pagedResult = - this.caCredentialRepository.findByArchiveFlag(false, paging); + records.setRecordsFiltered(endorsementCredentialRepository.findByArchiveFlag(false).size()); - if (pagedResult.hasContent()) { - records.addAll(pagedResult.getContent()); - records.setRecordsTotal(pagedResult.getContent().size()); - } else { - records.setRecordsTotal(input.getLength()); + log.debug("Returning the size of the list of endorsement credentials: {}", records.size()); + return new DataTableResponse<>(records, input); } + case TRUSTCHAIN -> { + FilteredRecordsList records = new FilteredRecordsList<>(); + org.springframework.data.domain.Page pagedResult = + this.caCredentialRepository.findByArchiveFlag(false, paging); + + if (pagedResult.hasContent()) { + records.addAll(pagedResult.getContent()); + records.setRecordsTotal(pagedResult.getContent().size()); + } else { + records.setRecordsTotal(input.getLength()); + } - records.setRecordsFiltered(caCredentialRepository.findByArchiveFlag(false).size()); - - log.debug("Returning list of size: " + records.size()); - return new DataTableResponse<>(records, input); - } else if (certificateType.equals(ISSUEDCERTIFICATES)) { - FilteredRecordsList records = new FilteredRecordsList<>(); - org.springframework.data.domain.Page pagedResult = - this.issuedCertificateRepository.findByArchiveFlag(false, paging); + records.setRecordsFiltered(caCredentialRepository.findByArchiveFlag(false).size()); - if (pagedResult.hasContent()) { - records.addAll(pagedResult.getContent()); - records.setRecordsTotal(pagedResult.getContent().size()); - } else { - records.setRecordsTotal(input.getLength()); + log.debug("Returning the size of the list of certificate trust chains: {}", records.size()); + return new DataTableResponse<>(records, input); } + case ISSUEDCERTIFICATES -> { + FilteredRecordsList records = new FilteredRecordsList<>(); + org.springframework.data.domain.Page pagedResult = + this.issuedCertificateRepository.findByArchiveFlag(false, paging); + + if (pagedResult.hasContent()) { + records.addAll(pagedResult.getContent()); + records.setRecordsTotal(pagedResult.getContent().size()); + } else { + records.setRecordsTotal(input.getLength()); + } - records.setRecordsFiltered(issuedCertificateRepository.findByArchiveFlag(false).size()); - - log.debug("Returning list of size: " + records.size()); - return new DataTableResponse<>(records, input); - } else if (certificateType.equals(IDEVIDCERTIFICATE)) { - FilteredRecordsList records = new FilteredRecordsList(); - org.springframework.data.domain.Page pagedResult = - this.iDevIDCertificateRepository.findByArchiveFlag(false, paging); + records.setRecordsFiltered(issuedCertificateRepository.findByArchiveFlag(false).size()); - if (pagedResult.hasContent()) { - records.addAll(pagedResult.getContent()); - records.setRecordsTotal(pagedResult.getContent().size()); - } else { - records.setRecordsTotal(input.getLength()); + log.debug("Returning the size of the list of issued certificates: {}", records.size()); + return new DataTableResponse<>(records, input); } + case IDEVIDCERTIFICATE -> { + FilteredRecordsList records = new FilteredRecordsList(); + org.springframework.data.domain.Page pagedResult = + this.iDevIDCertificateRepository.findByArchiveFlag(false, paging); + + if (pagedResult.hasContent()) { + records.addAll(pagedResult.getContent()); + records.setRecordsTotal(pagedResult.getContent().size()); + } else { + records.setRecordsTotal(input.getLength()); + } - records.setRecordsFiltered(iDevIDCertificateRepository.findByArchiveFlag(false).size()); + records.setRecordsFiltered(iDevIDCertificateRepository.findByArchiveFlag(false).size()); - log.debug("Returning list of size: " + records.size()); - return new DataTableResponse<>(records, input); + log.debug("Returning the size of the list of IDEVID certificates: {}", records.size()); + return new DataTableResponse<>(records, input); + } + default -> { + log.error("Cannot provide the size of the records because the" + + "provided certificate type does not exist."); + return new DataTableResponse<>(new FilteredRecordsList<>(), input); + } } - - return new DataTableResponse<>(new FilteredRecordsList<>(), input); } /** @@ -443,7 +446,7 @@ public RedirectView delete( @PathVariable("certificateType") final String certificateType, @RequestParam final String id, final RedirectAttributes attr) throws URISyntaxException { - log.info("Handling request to delete " + id); + log.info("Handling request to delete {}", id); Map model = new HashMap<>(); PageMessages messages = new PageMessages(); @@ -506,7 +509,7 @@ public RedirectView delete( * @param id the UUID of the cert to download * @param response the response object (needed to update the header with the * file name) - * @throws java.io.IOException when writing to response output stream + * @throws IOException when writing to response output stream */ @RequestMapping(value = "/{certificateType}/download", method = RequestMethod.GET) public void download( @@ -514,7 +517,7 @@ public void download( @RequestParam final String id, final HttpServletResponse response) throws IOException { - log.info("Handling request to download " + id); + log.info("Handling request to download {}", id); try { UUID uuid = UUID.fromString(id); @@ -552,7 +555,7 @@ public void download( * * @param response the response object (needed to update the header with the * file name) - * @throws java.io.IOException when writing to response output stream + * @throws IOException when writing to response output stream */ @ResponseBody @RequestMapping(value = "/trust-chain/download-aca-cert", method = RequestMethod.GET) @@ -573,7 +576,7 @@ public void downloadAcaCertificate(final HttpServletResponse response) * * @param response the response object (needed to update the header with the * file name) - * @throws java.io.IOException when writing to response output stream + * @throws IOException when writing to response output stream */ @RequestMapping(value = "/trust-chain/bulk", method = RequestMethod.GET) public void caBulkDownload(final HttpServletResponse response) @@ -605,7 +608,7 @@ public void caBulkDownload(final HttpServletResponse response) * * @param response the response object (needed to update the header with the * file name) - * @throws java.io.IOException when writing to response output stream + * @throws IOException when writing to response output stream */ @RequestMapping(value = "/platform-credentials/bulk", method = RequestMethod.GET) public void pcBulkDownload(final HttpServletResponse response) @@ -637,7 +640,7 @@ public void pcBulkDownload(final HttpServletResponse response) * * @param response the response object (needed to update the header with the * file name) - * @throws java.io.IOException when writing to response output stream + * @throws IOException when writing to response output stream */ @RequestMapping(value = "/issued-certificates/bulk", method = RequestMethod.GET) public void icBulkDownload(final HttpServletResponse response) @@ -670,7 +673,7 @@ public void icBulkDownload(final HttpServletResponse response) * * @param response the response object (needed to update the header with the * file name) - * @throws java.io.IOException when writing to response output stream + * @throws IOException when writing to response output stream */ @RequestMapping(value = "/endorsement-key-credentials/bulk", method = RequestMethod.GET) public void ekBulkDownload(final HttpServletResponse response) @@ -696,6 +699,15 @@ public void ekBulkDownload(final HttpServletResponse response) } } + /** + * Helper method that packages a collection of certificates into a zip file. + * + * @param zipOut zip outputs stream + * @param certificates collection of certificates + * @param singleFileName zip file name + * @return zip outputs stream + * @throws IOException if there are any issues packaging or downloading the zip file + */ private ZipOutputStream bulkDownload(final ZipOutputStream zipOut, final List certificates, final String singleFileName) throws IOException { @@ -727,9 +739,8 @@ private ZipOutputStream bulkDownload(final ZipOutputStream zipOut, * table, false otherwise. */ private boolean hasDeviceTableToJoin(final String certificateType) { - boolean hasDevice = !certificateType.equals(TRUSTCHAIN); // Trust_Chain Credential do not contain the device table to join. - return hasDevice; + return !certificateType.equals(TRUSTCHAIN); } /** @@ -744,26 +755,21 @@ private Certificate getCertificateByHash( final String certificateType, final int certificateHash) { - switch (certificateType) { - case PLATFORMCREDENTIAL: - return this.certificateRepository - .findByCertificateHash(certificateHash, - "PlatformCredential"); - case ENDORSEMENTCREDENTIAL: - return this.certificateRepository - .findByCertificateHash(certificateHash, - "EndorsementCredential"); - case TRUSTCHAIN: - return this.certificateRepository - .findByCertificateHash(certificateHash, - "CertificateAuthorityCredential"); - case IDEVIDCERTIFICATE: - return this.certificateRepository - .findByCertificateHash(certificateHash, - "IDevIDCertificate"); - default: - return null; - } + return switch (certificateType) { + case PLATFORMCREDENTIAL -> this.certificateRepository + .findByCertificateHash(certificateHash, + "PlatformCredential"); + case ENDORSEMENTCREDENTIAL -> this.certificateRepository + .findByCertificateHash(certificateHash, + "EndorsementCredential"); + case TRUSTCHAIN -> this.certificateRepository + .findByCertificateHash(certificateHash, + "CertificateAuthorityCredential"); + case IDEVIDCERTIFICATE -> this.certificateRepository + .findByCertificateHash(certificateHash, + "IDevIDCertificate"); + default -> null; + }; } /** @@ -779,11 +785,9 @@ private List getCertificateByBoardSN( List associatedCertificates = new LinkedList<>(); if (serialNumber != null) { - switch (certificateType) { - case PLATFORMCREDENTIAL: - associatedCertificates.addAll(this.certificateRepository - .byBoardSerialNumber(serialNumber)); - default: + if (certificateType.equals(PLATFORMCREDENTIAL)) { + associatedCertificates.addAll(this.certificateRepository + .byBoardSerialNumber(serialNumber)); } } @@ -954,7 +958,7 @@ private void storeCertificate( } this.certificateRepository.save(certificate); - handlePlatformComponents(certificate); + parseAndSaveComponentResults(certificate); final String successMsg = String.format("New certificate successfully uploaded (%s): ", fileName); @@ -968,6 +972,11 @@ private void storeCertificate( 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 { @@ -1010,7 +1019,13 @@ private void storeCertificate( log.error(failMessage); } - private void handlePlatformComponents(final Certificate certificate) { + /** + * Helper method that utilizes the components of the provided platform certificate to generate + * a collection of component results and subsequently stores these results in the database. + * + * @param certificate certificate + */ + private void parseAndSaveComponentResults(final Certificate certificate) throws IOException { PlatformCredential platformCredential; if (certificate instanceof PlatformCredential) { @@ -1019,17 +1034,32 @@ private void handlePlatformComponents(final Certificate certificate) { .findByCertificateSerialNumberAndBoardSerialNumber( platformCredential.getSerialNumber().toString(), platformCredential.getPlatformSerial()); + if (componentResults.isEmpty()) { 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); + } } } else { for (ComponentResult componentResult : componentResults) { @@ -1041,6 +1071,11 @@ private void handlePlatformComponents(final Certificate certificate) { } } + /** + * Helper method that deletes component results based on the provided platform serial number. + * + * @param platformSerial platform serial number + */ private void deleteComponentResults(final String platformSerial) { List componentResults = componentResultRepository .findByBoardSerialNumber(platformSerial); diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java index 30d11444a..51d340bd3 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java @@ -11,7 +11,9 @@ 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 static HashMap getPlatformInformation(final UUID uuid, 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 comps = platformConfiguration.getComponentIdentifier(); + if (certificate.getPlatformConfigurationV1() != null) { + PlatformConfigurationV1 platformConfigurationV1 = certificate.getPlatformConfigurationV1(); + + List componentIdentifiersV1 = + platformConfigurationV1.getComponentIdentifiers(); + if (PciIds.DB.isReady()) { - comps = AcaPciIds.translate(comps); + componentIdentifiersV1 = AcaPciIds.translate(componentIdentifiersV1); } - data.put("componentsIdentifier", comps); + //Component Identifiers + data.put("componentsIdentifier", componentIdentifiersV1); + + //Platform Properties + data.put("platformProperties", platformConfigurationV1.getPlatformProperties()); + //Platform Properties URI + data.put("platformPropertiesURI", platformConfigurationV1.getPlatformPropertiesUri()); + + } else if (certificate.getPlatformConfigurationV2() != null) { + PlatformConfigurationV2 platformConfigurationV2 = certificate.getPlatformConfigurationV2(); + //Component Identifiers + List componentIdentifiersV2 = + platformConfigurationV2.getComponentIdentifiers(); + + data.put("componentsIdentifier", componentIdentifiersV2); //Component Identifier URI - data.put("componentsIdentifierURI", platformConfiguration - .getComponentIdentifierUri()); + data.put("componentsIdentifierURI", platformConfigurationV2 + .getComponentIdentifiersUri()); //Platform Properties - data.put("platformProperties", platformConfiguration.getPlatformProperties()); + data.put("platformProperties", platformConfigurationV2.getPlatformProperties()); //Platform Properties URI - data.put("platformPropertiesURI", platformConfiguration.getPlatformPropertiesUri()); + data.put("platformPropertiesURI", platformConfigurationV2.getPlatformPropertiesUri()); } + //TBB Security Assertion data.put("tbbSecurityAssertion", certificate.getTBBSecurityAssertion()); diff --git a/HIRS_Structs/build.gradle b/HIRS_Structs/build.gradle index 8bc6d11bb..271ea1df5 100644 --- a/HIRS_Structs/build.gradle +++ b/HIRS_Structs/build.gradle @@ -16,10 +16,6 @@ dependencies { testAnnotationProcessor libs.lombok } -test { - useJUnitPlatform() -} - //publishing { // publications { // maven(MavenPublication) { diff --git a/HIRS_Utils/build.gradle b/HIRS_Utils/build.gradle index 8ba2e5c2a..cd9811b21 100644 --- a/HIRS_Utils/build.gradle +++ b/HIRS_Utils/build.gradle @@ -42,10 +42,6 @@ dependencies { testAnnotationProcessor libs.lombok } -test { - useJUnitPlatform() -} - jar { duplicatesStrategy = DuplicatesStrategy.EXCLUDE manifest { diff --git a/build.gradle b/build.gradle index 73f8a56c1..40406567b 100644 --- a/build.gradle +++ b/build.gradle @@ -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. diff --git a/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java b/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java index 06254b4ce..f34fa75c7 100644 --- a/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java +++ b/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java @@ -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 void setUp() throws Exception { validator.setTrustStoreFile(CA_CHAIN_FILE); } - @AfterTestClass + @AfterEach public void tearDown() throws Exception { if (expectedFile != null) { expectedFile.close(); @@ -87,6 +98,7 @@ public void testCreateBaseUserCertEmbedded() { 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 void testCreateBaseDefaultCert() { 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 void testCreateTimestampRfc3339() { 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 void testCreateTimestampRfc3852() { 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 void testCreateTimestampRfc3852() { * This test corresponds to the arguments: * -v */ - - 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 @@ private boolean compareFileBytesToExpectedFile(String file) { 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 {